From: Linus Torvalds Date: Wed, 19 Dec 2007 22:05:13 +0000 (-0800) Subject: Do dirty page accounting when removing a page from the page cache X-Git-Tag: v2.6.24-rc6~16 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3a6927906f1b2adf5a31b789322d32eb8559ada0;p=linux-2.6 Do dirty page accounting when removing a page from the page cache Krzysztof Oledzki noticed a dirty page accounting leak on some of his machines, causing the machine to eventually lock up when the kernel decided that there was too much dirty data, but nobody could actually write anything out to fix it. The culprit turns out to be filesystems (cough ext3 with data=journal cough) that re-dirty the page when the "->invalidatepage()" callback is called. Fix it up by doing a final dirty page accounting check when we actually remove the page from the page cache. This fixes bugzilla entry 9182: http://bugzilla.kernel.org/show_bug.cgi?id=9182 Tested-by: Ingo Molnar Tested-by: Krzysztof Oledzki Cc: Andrew Morton Cc: Nick Piggin Cc: Peter Zijlstra Signed-off-by: Linus Torvalds --- diff --git a/mm/filemap.c b/mm/filemap.c index 188cf5fd3e..f4d0cded0e 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -124,6 +124,18 @@ void __remove_from_page_cache(struct page *page) mapping->nrpages--; __dec_zone_page_state(page, NR_FILE_PAGES); BUG_ON(page_mapped(page)); + + /* + * Some filesystems seem to re-dirty the page even after + * the VM has canceled the dirty bit (eg ext3 journaling). + * + * Fix it up by doing a final dirty accounting check after + * having removed the page entirely. + */ + if (PageDirty(page) && mapping_cap_account_dirty(mapping)) { + dec_zone_page_state(page, NR_FILE_DIRTY); + dec_bdi_stat(mapping->backing_dev_info, BDI_RECLAIMABLE); + } } void remove_from_page_cache(struct page *page)