diff options
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; } |