summaryrefslogtreecommitdiffstats
path: root/xlators/nfs/lib
diff options
context:
space:
mode:
authorShehjar Tikoo <shehjart@gluster.com>2011-03-11 01:48:57 +0000
committerVijay Bellur <vijay@dev.gluster.com>2011-03-12 05:10:21 -0800
commit40a5e452bea79d1c7c78af480354e16ef970ca63 (patch)
treea60383dc48a5917b6219c6400654bddbd6811638 /xlators/nfs/lib
parent57d4551c05cdc17d2a9d687aca66802ce7af53f0 (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/nfs/lib')
-rw-r--r--xlators/nfs/lib/src/rpcsvc.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/xlators/nfs/lib/src/rpcsvc.c b/xlators/nfs/lib/src/rpcsvc.c
index 987c24080fd..ea75332008e 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;
}