mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-26 19:00:25 +00:00
NFS: Ensure that we free the rpc_task after read and write cleanups are done
This patch ensures that we free the rpc_task after the cleanup callbacks are done in order to avoid a deadlock problem that can be triggered if the callback needs to wait for another workqueue item to complete. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> Cc: Weston Andros Adamson <dros@netapp.com> Cc: Tejun Heo <tj@kernel.org> Cc: Bruce Fields <bfields@fieldses.org> Cc: stable@vger.kernel.org [>= 3.5]
This commit is contained in:
parent
c6567ed140
commit
6db6dd7d3f
2 changed files with 14 additions and 6 deletions
|
@ -91,12 +91,16 @@ void nfs_readdata_release(struct nfs_read_data *rdata)
|
|||
put_nfs_open_context(rdata->args.context);
|
||||
if (rdata->pages.pagevec != rdata->pages.page_array)
|
||||
kfree(rdata->pages.pagevec);
|
||||
if (rdata != &read_header->rpc_data)
|
||||
kfree(rdata);
|
||||
else
|
||||
if (rdata == &read_header->rpc_data) {
|
||||
rdata->header = NULL;
|
||||
rdata = NULL;
|
||||
}
|
||||
if (atomic_dec_and_test(&hdr->refcnt))
|
||||
hdr->completion_ops->completion(hdr);
|
||||
/* Note: we only free the rpc_task after callbacks are done.
|
||||
* See the comment in rpc_free_task() for why
|
||||
*/
|
||||
kfree(rdata);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_readdata_release);
|
||||
|
||||
|
|
|
@ -126,12 +126,16 @@ void nfs_writedata_release(struct nfs_write_data *wdata)
|
|||
put_nfs_open_context(wdata->args.context);
|
||||
if (wdata->pages.pagevec != wdata->pages.page_array)
|
||||
kfree(wdata->pages.pagevec);
|
||||
if (wdata != &write_header->rpc_data)
|
||||
kfree(wdata);
|
||||
else
|
||||
if (wdata == &write_header->rpc_data) {
|
||||
wdata->header = NULL;
|
||||
wdata = NULL;
|
||||
}
|
||||
if (atomic_dec_and_test(&hdr->refcnt))
|
||||
hdr->completion_ops->completion(hdr);
|
||||
/* Note: we only free the rpc_task after callbacks are done.
|
||||
* See the comment in rpc_free_task() for why
|
||||
*/
|
||||
kfree(wdata);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_writedata_release);
|
||||
|
||||
|
|
Loading…
Reference in a new issue