Skip to content

Commit

Permalink
nfs: handle multiple reqs in nfs_wb_page_cancel
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Weston Andros Adamson authored and Trond Myklebust committed Jul 12, 2014
1 parent d458138 commit 3e21704
Showing 1 changed file with 21 additions and 20 deletions.
41 changes: 21 additions & 20 deletions fs/nfs/write.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down

0 comments on commit 3e21704

Please sign in to comment.