Commit d16d4009 authored by Tom Tucker's avatar Tom Tucker

svcrdma: Return error from rdma_read_xdr so caller knows to free context

The rdma_read_xdr function did not discriminate between no read-list and
an error posting the read-list. This results in a leak of a page if there
is an error posting the read-list.
Signed-off-by: default avatarTom Tucker <tom@opengridcomputing.com>
parent 58e8f621
...@@ -260,11 +260,16 @@ static int rdma_read_max_sge(struct svcxprt_rdma *xprt, int sge_count) ...@@ -260,11 +260,16 @@ static int rdma_read_max_sge(struct svcxprt_rdma *xprt, int sge_count)
* On our side, we need to read into a pagelist. The first page immediately * On our side, we need to read into a pagelist. The first page immediately
* follows the RPC header. * follows the RPC header.
* *
* This function returns 1 to indicate success. The data is not yet in * This function returns:
* 0 - No error and no read-list found.
*
* 1 - Successful read-list processing. The data is not yet in
* the pagelist and therefore the RPC request must be deferred. The * the pagelist and therefore the RPC request must be deferred. The
* I/O completion will enqueue the transport again and * I/O completion will enqueue the transport again and
* svc_rdma_recvfrom will complete the request. * svc_rdma_recvfrom will complete the request.
* *
* <0 - Error processing/posting read-list.
*
* NOTE: The ctxt must not be touched after the last WR has been posted * NOTE: The ctxt must not be touched after the last WR has been posted
* because the I/O completion processing may occur on another * because the I/O completion processing may occur on another
* processor and free / modify the context. Ne touche pas! * processor and free / modify the context. Ne touche pas!
...@@ -398,7 +403,7 @@ next_sge: ...@@ -398,7 +403,7 @@ next_sge:
svc_rdma_put_context(head, 1); svc_rdma_put_context(head, 1);
head = ctxt; head = ctxt;
} }
return 0; return err;
} }
return 1; return 1;
...@@ -532,14 +537,18 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp) ...@@ -532,14 +537,18 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp)
goto close_out; goto close_out;
} }
/* Read read-list data. If we would need to wait, defer /* Read read-list data. */
* it. Not that in this case, we don't return the RQ credit ret = rdma_read_xdr(rdma_xprt, rmsgp, rqstp, ctxt);
* until after the read completes. if (ret > 0) {
*/ /* read-list posted, defer until data received from client. */
if (rdma_read_xdr(rdma_xprt, rmsgp, rqstp, ctxt)) {
svc_xprt_received(xprt); svc_xprt_received(xprt);
return 0; return 0;
} }
if (ret < 0) {
/* Post of read-list failed, free context. */
svc_rdma_put_context(ctxt, 1);
return 0;
}
ret = rqstp->rq_arg.head[0].iov_len ret = rqstp->rq_arg.head[0].iov_len
+ rqstp->rq_arg.page_len + rqstp->rq_arg.page_len
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment