Gitweb: http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=3e67c0987d7567ad666641164a153dca9a43b11d Commit: 3e67c0987d7567ad666641164a153dca9a43b11d Parent: 921320210bd2ec4f17053d283355b73048ac0e56 Author: Andrew Morton <[EMAIL PROTECTED]> AuthorDate: Thu Dec 21 11:00:33 2006 -0800 Committer: Linus Torvalds <[EMAIL PROTECTED]> CommitDate: Thu Dec 21 11:17:26 2006 -0800
[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 <[EMAIL PROTECTED]> Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]> --- mm/truncate.c | 9 +++++---- 1 files changed, 5 insertions(+), 4 deletions(-) diff --git a/mm/truncate.c b/mm/truncate.c index bf9e296..89a5c35 100644 --- a/mm/truncate.c +++ b/mm/truncate.c @@ -60,11 +60,12 @@ void cancel_dirty_page(struct page *page, unsigned int account_size) WARN_ON(++warncount < 5); } - if (TestClearPageDirty(page) && account_size) + if (TestClearPageDirty(page) && account_size) { + 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 @@ -81,11 +82,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); - cancel_dirty_page(page, PAGE_CACHE_SIZE); - ClearPageUptodate(page); ClearPageMappedToDisk(page); remove_from_page_cache(page); - To unsubscribe from this list: send the line "unsubscribe git-commits-head" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html