diff options
author | Nikita Danilov <nikita@clusterfs.com> | 2006-08-09 13:53:47 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-08-24 15:48:46 -0400 |
commit | ddeff520f02b92128132c282c350fa72afffb84a (patch) | |
tree | 238a720ece47a2f1e07b4d4cc53dff10860bbacb /fs | |
parent | ef7d1b244fa6c94fb76d5f787b8629df64ea4046 (diff) | |
download | op-kernel-dev-ddeff520f02b92128132c282c350fa72afffb84a.zip op-kernel-dev-ddeff520f02b92128132c282c350fa72afffb84a.tar.gz |
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')
-rw-r--r-- | fs/nfs/file.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index cc2b874..48e8928 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) static int nfs_release_page(struct page *page, gfp_t gfp) { - return !nfs_wb_page(page->mapping->host, page); + if (gfp & __GFP_FS) + return !nfs_wb_page(page->mapping->host, page); + else + /* + * Avoid deadlock on nfs_wait_on_request(). + */ + return 0; } const struct address_space_operations nfs_file_aops = { |