From 8258d4a574d3a8c01f0ef68aa26b969398a0e140 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 11 Oct 2006 01:21:53 -0700 Subject: [PATCH] invalidate_inode_pages2_range() debug A failure in invalidate_inode_pages2_range() can result in unpleasant things happening in NFS (at least). Stick a WARN_ON_ONCE() in there so we can find out if it happens, and maybe why. (akpm: might be a -mm-only patch, we'll see..) Cc: Chuck Lever Cc: Trond Myklebust Cc: Steve Dickson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/truncate.c | 1 + 1 file changed, 1 insertion(+) (limited to 'mm/truncate.c') diff --git a/mm/truncate.c b/mm/truncate.c index f4edbc179d14..fca28839c46e 100644 --- a/mm/truncate.c +++ b/mm/truncate.c @@ -396,6 +396,7 @@ int invalidate_inode_pages2_range(struct address_space *mapping, pagevec_release(&pvec); cond_resched(); } + WARN_ON_ONCE(ret); return ret; } EXPORT_SYMBOL_GPL(invalidate_inode_pages2_range); -- cgit v1.2.3 From 887ed2f3aecde2ff24e06666932dc5f144745044 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 Oct 2006 01:21:58 -0700 Subject: [PATCH] VM: Fix the gfp_mask in invalidate_complete_page2 If try_to_release_page() is called with a zero gfp mask, then the filesystem is effectively denied the possibility of sleeping while attempting to release the page. There doesn't appear to be any valid reason why this should be banned, given that we're not calling this from a memory allocation context. For this reason, change the gfp_mask argument of the call to GFP_KERNEL. Signed-off-by: Trond Myklebust Cc: Steve Dickson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/truncate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'mm/truncate.c') diff --git a/mm/truncate.c b/mm/truncate.c index fca28839c46e..11ca480701dd 100644 --- a/mm/truncate.c +++ b/mm/truncate.c @@ -302,7 +302,7 @@ invalidate_complete_page2(struct address_space *mapping, struct page *page) if (page->mapping != mapping) return 0; - if (PagePrivate(page) && !try_to_release_page(page, 0)) + if (PagePrivate(page) && !try_to_release_page(page, GFP_KERNEL)) return 0; write_lock_irq(&mapping->tree_lock); -- cgit v1.2.3 From a649fd9271773dd0f78e2b9f347bcceecb8827f9 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 17 Oct 2006 00:09:36 -0700 Subject: [PATCH] invalidate: remove_mapping() fix If remove_mapping() failed to remove the page from its mapping, don't go and mark it not uptodate! Makes kernel go dead. (Actually, I don't think the ClearPageUptodate is needed there at all). Says Nick Piggin: "Right, it isn't needed because at this point the page is guaranteed by remove_mapping to have no references (except us) and cannot pick up any new ones because it is removed from pagecache. We can delete it." Signed-off-by: Andrew Morton Acked-by: Nick Piggin Signed-off-by: Linus Torvalds --- mm/truncate.c | 1 - mm/vmscan.c | 6 ++++++ 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'mm/truncate.c') diff --git a/mm/truncate.c b/mm/truncate.c index 11ca480701dd..e07b1e682c38 100644 --- a/mm/truncate.c +++ b/mm/truncate.c @@ -96,7 +96,6 @@ invalidate_complete_page(struct address_space *mapping, struct page *page) return 0; ret = remove_mapping(mapping, page); - ClearPageUptodate(page); return ret; } diff --git a/mm/vmscan.c b/mm/vmscan.c index eca70310adb2..af73c14f9d88 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -378,6 +378,12 @@ static pageout_t pageout(struct page *page, struct address_space *mapping) return PAGE_CLEAN; } +/* + * Attempt to detach a locked page from its ->mapping. If it is dirty or if + * someone else has a ref on the page, abort and return 0. If it was + * successfully detached, return 1. Assumes the caller has a single ref on + * this page. + */ int remove_mapping(struct address_space *mapping, struct page *page) { BUG_ON(!PageLocked(page)); -- cgit v1.2.3