1
0
Fork 0

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>
hifive-unleashed-5.1
Weston Andros Adamson 2014-07-11 10:20:49 -04:00 committed by Trond Myklebust
parent d458138353
commit 3e2170451e
1 changed files with 21 additions and 20 deletions

View File

@ -1799,27 +1799,28 @@ int nfs_wb_page_cancel(struct inode *inode, struct page *page)
struct nfs_page *req;
int ret = 0;
for (;;) {
wait_on_page_writeback(page);
req = nfs_page_find_head_request(page);
if (req == NULL)
break;
if (nfs_lock_request(req)) {
nfs_clear_request_commit(req);
nfs_inode_remove_request(req);
/*
* In case nfs_inode_remove_request has marked the
* page as being dirty
*/
cancel_dirty_page(page, PAGE_CACHE_SIZE);
nfs_unlock_and_release_request(req);
break;
}
ret = nfs_wait_on_request(req);
nfs_release_request(req);
if (ret < 0)
break;
wait_on_page_writeback(page);
/* blocking call to cancel all requests and join to a single (head)
* request */
req = nfs_lock_and_join_requests(page, false);
if (IS_ERR(req)) {
ret = PTR_ERR(req);
} else if (req) {
/* all requests from this page have been cancelled by
* nfs_lock_and_join_requests, so just remove the head
* request from the inode / page_private pointer and
* release it */
nfs_inode_remove_request(req);
/*
* In case nfs_inode_remove_request has marked the
* page as being dirty
*/
cancel_dirty_page(page, PAGE_CACHE_SIZE);
nfs_unlock_and_release_request(req);
}
return ret;
}