aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorNikita Danilov <nikita@clusterfs.com>2006-08-09 13:53:47 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-08-24 15:48:46 -0400
commitddeff520f02b92128132c282c350fa72afffb84a (patch)
tree238a720ece47a2f1e07b4d4cc53dff10860bbacb /fs/nfs
parentef7d1b244fa6c94fb76d5f787b8629df64ea4046 (diff)
NFS: Fix a potential deadlock in nfs_release_page
nfs_wb_page() waits on request completion and, as a result, is not safe to be called from nfs_release_page() invoked by VM scanner as part of GFP_NOFS allocation. Fix possible deadlock by analyzing gfp mask and refusing to release page if __GFP_FS is not set. Signed-off-by: Nikita Danilov <danilov@gmail.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> (cherry picked from 374d969debfb290bafcb41d28918dc6f7e43ce31 commit)
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/file.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index cc2b874ad5a4..48e892880d5b 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -312,7 +312,13 @@ static void nfs_invalidate_page(struct page *page, unsigned long offset)
312 312
313static int nfs_release_page(struct page *page, gfp_t gfp) 313static int nfs_release_page(struct page *page, gfp_t gfp)
314{ 314{
315 return !nfs_wb_page(page->mapping->host, page); 315 if (gfp & __GFP_FS)
316 return !nfs_wb_page(page->mapping->host, page);
317 else
318 /*
319 * Avoid deadlock on nfs_wait_on_request().
320 */
321 return 0;
316} 322}
317 323
318const struct address_space_operations nfs_file_aops = { 324const struct address_space_operations nfs_file_aops = {