aboutsummaryrefslogtreecommitdiffstats
path: root/mm/truncate.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/truncate.c')
-rw-r--r--mm/truncate.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/mm/truncate.c b/mm/truncate.c
index 9bfb8e853860..bf9e2965d666 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -51,6 +51,20 @@ static inline void truncate_partial_page(struct page *page, unsigned partial)
51 do_invalidatepage(page, partial); 51 do_invalidatepage(page, partial);
52} 52}
53 53
54void cancel_dirty_page(struct page *page, unsigned int account_size)
55{
56 /* If we're cancelling the page, it had better not be mapped any more */
57 if (page_mapped(page)) {
58 static unsigned int warncount;
59
60 WARN_ON(++warncount < 5);
61 }
62
63 if (TestClearPageDirty(page) && account_size)
64 task_io_account_cancelled_write(account_size);
65}
66
67
54/* 68/*
55 * If truncate cannot remove the fs-private metadata from the page, the page 69 * If truncate cannot remove the fs-private metadata from the page, the page
56 * becomes anonymous. It will be left on the LRU and may even be mapped into 70 * becomes anonymous. It will be left on the LRU and may even be mapped into
@@ -70,8 +84,8 @@ truncate_complete_page(struct address_space *mapping, struct page *page)
70 if (PagePrivate(page)) 84 if (PagePrivate(page))
71 do_invalidatepage(page, 0); 85 do_invalidatepage(page, 0);
72 86
73 if (test_clear_page_dirty(page)) 87 cancel_dirty_page(page, PAGE_CACHE_SIZE);
74 task_io_account_cancelled_write(PAGE_CACHE_SIZE); 88
75 ClearPageUptodate(page); 89 ClearPageUptodate(page);
76 ClearPageMappedToDisk(page); 90 ClearPageMappedToDisk(page);
77 remove_from_page_cache(page); 91 remove_from_page_cache(page);
@@ -350,7 +364,6 @@ int invalidate_inode_pages2_range(struct address_space *mapping,
350 for (i = 0; !ret && i < pagevec_count(&pvec); i++) { 364 for (i = 0; !ret && i < pagevec_count(&pvec); i++) {
351 struct page *page = pvec.pages[i]; 365 struct page *page = pvec.pages[i];
352 pgoff_t page_index; 366 pgoff_t page_index;
353 int was_dirty;
354 367
355 lock_page(page); 368 lock_page(page);
356 if (page->mapping != mapping) { 369 if (page->mapping != mapping) {
@@ -386,12 +399,8 @@ int invalidate_inode_pages2_range(struct address_space *mapping,
386 PAGE_CACHE_SIZE, 0); 399 PAGE_CACHE_SIZE, 0);
387 } 400 }
388 } 401 }
389 was_dirty = test_clear_page_dirty(page); 402 if (!invalidate_complete_page2(mapping, page))
390 if (!invalidate_complete_page2(mapping, page)) {
391 if (was_dirty)
392 set_page_dirty(page);
393 ret = -EIO; 403 ret = -EIO;
394 }
395 unlock_page(page); 404 unlock_page(page);
396 } 405 }
397 pagevec_release(&pvec); 406 pagevec_release(&pvec);