diff options
author | Shehjar Tikoo <shehjart@gluster.com> | 2011-03-11 01:48:57 +0000 |
---|---|---|
committer | Vijay Bellur <vijay@dev.gluster.com> | 2011-03-12 05:10:35 -0800 |
commit | cacb35dcf70fa481a3f39ecfef1b5c46d6a174fd (patch) | |
tree | d343e8493e9234e7ac43cb2cfc177a980a5610d7 /xlators | |
parent | 609d5aa9c29e8af0b25c1922c8cdb2db2edbd481 (diff) |
nfs-rpc: Fix order of freeing request and connection objects
..to prevent segfaults due to double frees and dereferencing of freed
up memory.
Signed-off-by: Shehjar Tikoo <shehjart@gluster.com>
Signed-off-by: Vijay Bellur <vijay@dev.gluster.com>
BUG: 2504 ()
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=2504
Diffstat (limited to 'xlators')
-rw-r--r-- | xlators/nfs/lib/src/rpcsvc.c | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/xlators/nfs/lib/src/rpcsvc.c b/xlators/nfs/lib/src/rpcsvc.c index 515e8738fc9..363b94fbe13 100644 --- a/xlators/nfs/lib/src/rpcsvc.c +++ b/xlators/nfs/lib/src/rpcsvc.c @@ -1665,6 +1665,8 @@ nfs_rpcsvc_submit_generic (rpcsvc_request_t *req, struct iovec msgvec, struct iobuf *replyiob = NULL; struct iovec recordhdr = {0, }; rpcsvc_conn_t *conn = NULL; + int rpc_status = 0; + int rpc_error = 0; if ((!req) || (!req->conn)) return -1; @@ -1705,11 +1707,19 @@ disconnect_exit: * no actor was called, we will be losing the ref held for the RPC * layer. */ - if ((nfs_rpcsvc_request_accepted (req)) && - (nfs_rpcsvc_request_accepted_success (req))) - nfs_rpcsvc_conn_unref (conn); + /* If the request succeeded and was handed to the actor, then unref the + * conn. + */ + + rpc_status = req->rpc_stat; + rpc_error = req->rpc_err; + /* Must mem_put req back to rxpool before the possibility of destroying + * conn in conn_unref, where the rxpool itself is destroyed. + */ mem_put (conn->rxpool, req); + if ((rpc_status == MSG_ACCEPTED) && (rpc_error == SUCCESS)) + nfs_rpcsvc_conn_unref (conn); return ret; } @@ -1783,7 +1793,7 @@ nfs_rpcsvc_submit_vectors (rpcsvc_request_t *req) struct iobuf *replyiob = NULL; struct iovec recordhdr = {0, }; rpcsvc_txbuf_t *rpctxb = NULL; - void *rxpool = NULL; + rpcsvc_conn_t *conn = NULL; if ((!req) || (!req->conn)) return -1; @@ -1819,13 +1829,16 @@ disconnect_exit: * response to the ref that is performed on the conn when a request is * handed to the RPC program. */ - rxpool = req->conn->rxpool; + conn = req->conn; + /* Must mem_put req back to rxpool before the possibility of destroying + * conn in conn_unref, where the rxpool itself is destroyed. + */ + mem_put (conn->rxpool, req); - nfs_rpcsvc_conn_unref (req->conn); + nfs_rpcsvc_conn_unref (conn); if (ret == -1) iobuf_unref (replyiob); - mem_put (rxpool, req); return ret; } |