Skip to content

Commit 3e67c09

Browse files
Andrew MortonLinus Torvalds
authored andcommitted
[PATCH] truncate: clear page dirtiness before running try_to_free_buffers()
truncate presently invalidates the dirty page's buffer_heads then shoots down the page. But try_to_free_buffers() will now bale out because the page is dirty. Net effect: the LRU gets filled with dirty pages which have invalidated buffer_heads attached. They have no ->mapping and hence cannot be cleaned. The machine leaks memory at an enormous rate. Fix this by cleaning the page before running try_to_free_buffers(), so try_to_free_buffers() can do its work. Also, remember to do dirty-page-acoounting in cancel_dirty_page() so the machine won't wedge up trying to write non-existent dirty pages. Probably still wrong, but now less so. Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
1 parent 9213202 commit 3e67c09

File tree

1 file changed

+5
-4
lines changed

1 file changed

+5
-4
lines changed

mm/truncate.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,12 @@ void cancel_dirty_page(struct page *page, unsigned int account_size)
6060
WARN_ON(++warncount < 5);
6161
}
6262

63-
if (TestClearPageDirty(page) && account_size)
63+
if (TestClearPageDirty(page) && account_size) {
64+
dec_zone_page_state(page, NR_FILE_DIRTY);
6465
task_io_account_cancelled_write(account_size);
66+
}
6567
}
6668

67-
6869
/*
6970
* If truncate cannot remove the fs-private metadata from the page, the page
7071
* becomes anonymous. It will be left on the LRU and may even be mapped into
@@ -81,11 +82,11 @@ truncate_complete_page(struct address_space *mapping, struct page *page)
8182
if (page->mapping != mapping)
8283
return;
8384

85+
cancel_dirty_page(page, PAGE_CACHE_SIZE);
86+
8487
if (PagePrivate(page))
8588
do_invalidatepage(page, 0);
8689

87-
cancel_dirty_page(page, PAGE_CACHE_SIZE);
88-
8990
ClearPageUptodate(page);
9091
ClearPageMappedToDisk(page);
9192
remove_from_page_cache(page);

0 commit comments

Comments
 (0)