From: Trond Myklebust Date: Thu, 10 Dec 2009 14:05:55 +0000 (-0500) Subject: NFS: Fix nfs_migrate_page() X-Git-Tag: firefly_0821_release~11625^2~578 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=e4f676cea796e170fcd8561c8e2a234724d05f35;p=firefly-linux-kernel-4.4.55.git NFS: Fix nfs_migrate_page() commit 190f38e5cedc910940b1da9015f00458c18f97b4 upstream. 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 Tested-by: Andi Kleen Signed-off-by: Trond Myklebust Signed-off-by: Greg Kroah-Hartman --- diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 53eb26c16b50..6fc37762c495 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -1612,15 +1612,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; }