X-Git-Url: http://pilppa.org/gitweb/?a=blobdiff_plain;f=mm%2Ftruncate.c;h=4a38dd1a4ce85efffaa8275ccaaf1b42251f0ae9;hb=0e859cacb0b01bdbe34b5200dd2457d4818248fa;hp=e07b1e682c38f5fca96436904eb1a9a262ce1426;hpb=6d03a68e6d5528630955452ec4b768dbde0dc00c;p=linux-2.6-omap-h63xx.git diff --git a/mm/truncate.c b/mm/truncate.c index e07b1e682c3..4a38dd1a4ce 100644 --- a/mm/truncate.c +++ b/mm/truncate.c @@ -13,6 +13,7 @@ #include #include #include +#include #include /* grr. try_to_release_page, do_invalidatepage */ @@ -50,6 +51,22 @@ static inline void truncate_partial_page(struct page *page, unsigned partial) do_invalidatepage(page, partial); } +void cancel_dirty_page(struct page *page, unsigned int account_size) +{ + /* If we're cancelling the page, it had better not be mapped any more */ + if (page_mapped(page)) { + static unsigned int warncount; + + WARN_ON(++warncount < 5); + } + + if (TestClearPageDirty(page) && account_size && + mapping_cap_account_dirty(page->mapping)) { + dec_zone_page_state(page, NR_FILE_DIRTY); + task_io_account_cancelled_write(account_size); + } +} + /* * If truncate cannot remove the fs-private metadata from the page, the page * becomes anonymous. It will be left on the LRU and may even be mapped into @@ -66,10 +83,11 @@ truncate_complete_page(struct address_space *mapping, struct page *page) if (page->mapping != mapping) return; + cancel_dirty_page(page, PAGE_CACHE_SIZE); + if (PagePrivate(page)) do_invalidatepage(page, 0); - clear_page_dirty(page); ClearPageUptodate(page); ClearPageMappedToDisk(page); remove_from_page_cache(page); @@ -348,7 +366,6 @@ int invalidate_inode_pages2_range(struct address_space *mapping, for (i = 0; !ret && i < pagevec_count(&pvec); i++) { struct page *page = pvec.pages[i]; pgoff_t page_index; - int was_dirty; lock_page(page); if (page->mapping != mapping) { @@ -384,12 +401,8 @@ int invalidate_inode_pages2_range(struct address_space *mapping, PAGE_CACHE_SIZE, 0); } } - was_dirty = test_clear_page_dirty(page); - if (!invalidate_complete_page2(mapping, page)) { - if (was_dirty) - set_page_dirty(page); + if (!invalidate_complete_page2(mapping, page)) ret = -EIO; - } unlock_page(page); } pagevec_release(&pvec);