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>wifi-calibration
parent
053e324f67
commit
190f38e5ce
|
@ -1611,15 +1611,16 @@ int nfs_migrate_page(struct address_space *mapping, struct page *newpage,
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
page_cache_get(newpage);
|
page_cache_get(newpage);
|
||||||
|
spin_lock(&mapping->host->i_lock);
|
||||||
req->wb_page = newpage;
|
req->wb_page = newpage;
|
||||||
SetPagePrivate(newpage);
|
SetPagePrivate(newpage);
|
||||||
set_page_private(newpage, page_private(page));
|
set_page_private(newpage, (unsigned long)req);
|
||||||
ClearPagePrivate(page);
|
ClearPagePrivate(page);
|
||||||
set_page_private(page, 0);
|
set_page_private(page, 0);
|
||||||
|
spin_unlock(&mapping->host->i_lock);
|
||||||
page_cache_release(page);
|
page_cache_release(page);
|
||||||
out_unlock:
|
out_unlock:
|
||||||
nfs_clear_page_tag_locked(req);
|
nfs_clear_page_tag_locked(req);
|
||||||
nfs_release_request(req);
|
|
||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue