summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 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;
}