svcrdma: Support multiple Write chunks in svc_rdma_send_reply_chunk
authorChuck Lever <chuck.lever@oracle.com>
Mon, 9 Mar 2020 17:29:28 +0000 (13:29 -0400)
committerChuck Lever <chuck.lever@oracle.com>
Mon, 30 Nov 2020 18:00:23 +0000 (13:00 -0500)
Refactor svc_rdma_send_reply_chunk() so that it Sends only the parts
of rq_res that do not contain a result payload.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
include/linux/sunrpc/svc_rdma.h
net/sunrpc/xprtrdma/svc_rdma_rw.c

index e09fafba00d7c8aece85eaa746b06bfbc66aff85..85fbec47d4b5ba92d1d018bc39071423b3c9c265 100644 (file)
@@ -200,7 +200,7 @@ extern int svc_rdma_send_write_chunk(struct svcxprt_rdma *rdma,
                                     const struct xdr_buf *xdr);
 extern int svc_rdma_send_reply_chunk(struct svcxprt_rdma *rdma,
                                     const struct svc_rdma_recv_ctxt *rctxt,
-                                    struct xdr_buf *xdr);
+                                    const struct xdr_buf *xdr);
 
 /* svc_rdma_sendto.c */
 extern void svc_rdma_send_ctxts_destroy(struct svcxprt_rdma *rdma);
index ed7def7b801b625e35b2e90885284afe83716fee..4a0ece9aa38583f16cc1e96813491bb466f3f7c0 100644 (file)
@@ -537,7 +537,7 @@ static int svc_rdma_pages_write(struct svc_rdma_write_info *info,
 /**
  * svc_rdma_xb_write - Construct RDMA Writes to write an xdr_buf
  * @xdr: xdr_buf to write
- * @info: pointer to write arguments
+ * @data: pointer to write arguments
  *
  * Returns:
  *   On succes, returns zero
@@ -545,9 +545,9 @@ static int svc_rdma_pages_write(struct svc_rdma_write_info *info,
  *   %-ENOMEM if a resource has been exhausted
  *   %-EIO if an rdma-rw error occurred
  */
-static int svc_rdma_xb_write(const struct xdr_buf *xdr,
-                            struct svc_rdma_write_info *info)
+static int svc_rdma_xb_write(const struct xdr_buf *xdr, void *data)
 {
+       struct svc_rdma_write_info *info = data;
        int ret;
 
        if (xdr->head[0].iov_len) {
@@ -627,11 +627,11 @@ out_err:
  */
 int svc_rdma_send_reply_chunk(struct svcxprt_rdma *rdma,
                              const struct svc_rdma_recv_ctxt *rctxt,
-                             struct xdr_buf *xdr)
+                             const struct xdr_buf *xdr)
 {
        struct svc_rdma_write_info *info;
        struct svc_rdma_chunk *chunk;
-       int consumed, ret;
+       int ret;
 
        if (pcl_is_empty(&rctxt->rc_reply_pcl))
                return 0;
@@ -641,35 +641,17 @@ int svc_rdma_send_reply_chunk(struct svcxprt_rdma *rdma,
        if (!info)
                return -ENOMEM;
 
-       ret = svc_rdma_iov_write(info, &xdr->head[0]);
+       ret = pcl_process_nonpayloads(&rctxt->rc_write_pcl, xdr,
+                                     svc_rdma_xb_write, info);
        if (ret < 0)
                goto out_err;
-       consumed = xdr->head[0].iov_len;
-
-       /* Send the page list in the Reply chunk only if the
-        * client did not provide Write chunks.
-        */
-       if (pcl_is_empty(&rctxt->rc_write_pcl) && xdr->page_len) {
-               ret = svc_rdma_pages_write(info, xdr, xdr->head[0].iov_len,
-                                          xdr->page_len);
-               if (ret < 0)
-                       goto out_err;
-               consumed += xdr->page_len;
-       }
-
-       if (xdr->tail[0].iov_len) {
-               ret = svc_rdma_iov_write(info, &xdr->tail[0]);
-               if (ret < 0)
-                       goto out_err;
-               consumed += xdr->tail[0].iov_len;
-       }
 
        ret = svc_rdma_post_chunk_ctxt(&info->wi_cc);
        if (ret < 0)
                goto out_err;
 
-       trace_svcrdma_send_reply_chunk(consumed);
-       return consumed;
+       trace_svcrdma_send_reply_chunk(xdr->len);
+       return xdr->len;
 
 out_err:
        svc_rdma_write_info_free(info);