aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/write.c36
1 files changed, 11 insertions, 25 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 46aa4389ce13..72813ede029e 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -1691,34 +1691,20 @@ out_error:
1691int nfs_migrate_page(struct address_space *mapping, struct page *newpage, 1691int nfs_migrate_page(struct address_space *mapping, struct page *newpage,
1692 struct page *page) 1692 struct page *page)
1693{ 1693{
1694 struct nfs_page *req; 1694 /*
1695 int ret; 1695 * If PagePrivate is set, then the page is currently associated with
1696 * an in-progress read or write request. Don't try to migrate it.
1697 *
1698 * FIXME: we could do this in principle, but we'll need a way to ensure
1699 * that we can safely release the inode reference while holding
1700 * the page lock.
1701 */
1702 if (PagePrivate(page))
1703 return -EBUSY;
1696 1704
1697 nfs_fscache_release_page(page, GFP_KERNEL); 1705 nfs_fscache_release_page(page, GFP_KERNEL);
1698 1706
1699 req = nfs_find_and_lock_request(page, false); 1707 return migrate_page(mapping, newpage, page);
1700 ret = PTR_ERR(req);
1701 if (IS_ERR(req))
1702 goto out;
1703
1704 ret = migrate_page(mapping, newpage, page);
1705 if (!req)
1706 goto out;
1707 if (ret)
1708 goto out_unlock;
1709 page_cache_get(newpage);
1710 spin_lock(&mapping->host->i_lock);
1711 req->wb_page = newpage;
1712 SetPagePrivate(newpage);
1713 set_page_private(newpage, (unsigned long)req);
1714 ClearPagePrivate(page);
1715 set_page_private(page, 0);
1716 spin_unlock(&mapping->host->i_lock);
1717 page_cache_release(page);
1718out_unlock:
1719 nfs_clear_page_tag_locked(req);
1720out:
1721 return ret;
1722} 1708}
1723#endif 1709#endif
1724 1710