diff options
author | Weston Andros Adamson <dros@primarydata.com> | 2014-07-11 10:20:49 -0400 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2014-07-12 17:35:47 -0400 |
commit | 3e2170451e91327bfa8a82040fea78043847533a (patch) | |
tree | c5361de58a9f15ff44b1ed58baeabc4bed04e751 /fs | |
parent | d458138353726ea6dcbc53ae3597e489d0432c25 (diff) |
nfs: handle multiple reqs in nfs_wb_page_cancel
Use nfs_lock_and_join_requests to merge all subrequests into the head request -
this cancels and dereferences all subrequests.
Signed-off-by: Weston Andros Adamson <dros@primarydata.com>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfs/write.c | 41 |
1 files changed, 21 insertions, 20 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 9f4424c464a0..bdc4db23951e 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -1799,27 +1799,28 @@ int nfs_wb_page_cancel(struct inode *inode, struct page *page) | |||
1799 | struct nfs_page *req; | 1799 | struct nfs_page *req; |
1800 | int ret = 0; | 1800 | int ret = 0; |
1801 | 1801 | ||
1802 | for (;;) { | 1802 | wait_on_page_writeback(page); |
1803 | wait_on_page_writeback(page); | 1803 | |
1804 | req = nfs_page_find_head_request(page); | 1804 | /* blocking call to cancel all requests and join to a single (head) |
1805 | if (req == NULL) | 1805 | * request */ |
1806 | break; | 1806 | req = nfs_lock_and_join_requests(page, false); |
1807 | if (nfs_lock_request(req)) { | 1807 | |
1808 | nfs_clear_request_commit(req); | 1808 | if (IS_ERR(req)) { |
1809 | nfs_inode_remove_request(req); | 1809 | ret = PTR_ERR(req); |
1810 | /* | 1810 | } else if (req) { |
1811 | * In case nfs_inode_remove_request has marked the | 1811 | /* all requests from this page have been cancelled by |
1812 | * page as being dirty | 1812 | * nfs_lock_and_join_requests, so just remove the head |
1813 | */ | 1813 | * request from the inode / page_private pointer and |
1814 | cancel_dirty_page(page, PAGE_CACHE_SIZE); | 1814 | * release it */ |
1815 | nfs_unlock_and_release_request(req); | 1815 | nfs_inode_remove_request(req); |
1816 | break; | 1816 | /* |
1817 | } | 1817 | * In case nfs_inode_remove_request has marked the |
1818 | ret = nfs_wait_on_request(req); | 1818 | * page as being dirty |
1819 | nfs_release_request(req); | 1819 | */ |
1820 | if (ret < 0) | 1820 | cancel_dirty_page(page, PAGE_CACHE_SIZE); |
1821 | break; | 1821 | nfs_unlock_and_release_request(req); |
1822 | } | 1822 | } |
1823 | |||
1823 | return ret; | 1824 | return ret; |
1824 | } | 1825 | } |
1825 | 1826 | ||