3.7-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Trond Myklebust <[email protected]>

commit 6db6dd7d3fd8f7c765dabc376493d6791ab28bd6 upstream.

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 <[email protected]>
Cc: Weston Andros Adamson <[email protected]>
Cc: Tejun Heo <[email protected]>
Cc: Bruce Fields <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
 fs/nfs/read.c  |   10 +++++++---
 fs/nfs/write.c |   10 +++++++---
 2 files changed, 14 insertions(+), 6 deletions(-)

--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -91,12 +91,16 @@ void nfs_readdata_release(struct nfs_rea
        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);
 
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -126,12 +126,16 @@ void nfs_writedata_release(struct nfs_wr
        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);
 


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to