summaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorTrond Myklebust2009-12-10 15:05:55 +0100
committerTrond Myklebust2009-12-10 15:05:55 +0100
commit190f38e5cedc910940b1da9015f00458c18f97b4 (patch)
tree3b13c1cd5c536b6187b3196610b97e70a0ba0372 /fs/nfs
parentrpc: remove unneeded function parameter in gss_add_msg() (diff)
downloadkernel-qcow2-linux-190f38e5cedc910940b1da9015f00458c18f97b4.tar.gz
kernel-qcow2-linux-190f38e5cedc910940b1da9015f00458c18f97b4.tar.xz
kernel-qcow2-linux-190f38e5cedc910940b1da9015f00458c18f97b4.zip
NFS: Fix nfs_migrate_page()
The call to migrate_page() will cause the page->private field to be cleared. Also fix up the locking around the page->private transfer, so that we ensure that calls to nfs_page_find_request() don't end up racing. Finally, fix up a double free bug: nfs_unlock_request() already calls nfs_release_request() for us... Reported-by: Wu Fengguang <fengguang.wu@intel.com> Tested-by: Andi Kleen <andi@firstfloor.org> Cc: stable@kernel.org Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/write.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index a28123be08a6..6d40a538e3db 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -1611,15 +1611,16 @@ int nfs_migrate_page(struct address_space *mapping, struct page *newpage,
if (ret)
goto out_unlock;
page_cache_get(newpage);
+ spin_lock(&mapping->host->i_lock);
req->wb_page = newpage;
SetPagePrivate(newpage);
- set_page_private(newpage, page_private(page));
+ set_page_private(newpage, (unsigned long)req);
ClearPagePrivate(page);
set_page_private(page, 0);
+ spin_unlock(&mapping->host->i_lock);
page_cache_release(page);
out_unlock:
nfs_clear_page_tag_locked(req);
- nfs_release_request(req);
out:
return ret;
}