]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
svcrdma: Another sendto chunk list parsing update
authorChuck Lever <chuck.lever@oracle.com>
Tue, 7 Feb 2017 16:58:15 +0000 (11:58 -0500)
committerJ. Bruce Fields <bfields@redhat.com>
Wed, 8 Feb 2017 19:41:24 +0000 (14:41 -0500)
Commit 5fdca6531434 ("svcrdma: Renovate sendto chunk list parsing")
missed a spot. svc_rdma_xdr_get_reply_hdr_len() also assumes the
Write list has only one Write chunk. There's no harm in making this
code more general.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
include/linux/sunrpc/rpc_rdma.h
include/linux/sunrpc/svc_rdma.h
net/sunrpc/xprtrdma/svc_rdma_marshal.c
net/sunrpc/xprtrdma/svc_rdma_sendto.c

index cfda6adcf33cfcf3c28e46066ec294c6d2902389..245fc59b73247d744682c128bfcae1270e146c26 100644 (file)
@@ -109,6 +109,15 @@ struct rpcrdma_msg {
        } rm_body;
 };
 
+/*
+ * XDR sizes, in quads
+ */
+enum {
+       rpcrdma_fixed_maxsz     = 4,
+       rpcrdma_segment_maxsz   = 4,
+       rpcrdma_readchunk_maxsz = 2 + rpcrdma_segment_maxsz,
+};
+
 /*
  * Smallest RPC/RDMA header: rm_xid through rm_type, then rm_nochunks
  */
index 757fb963696c76b3ab24f754ff89424fb428fc79..551c518163529d4ae5ae46a5aa3136c0caf48aa5 100644 (file)
@@ -218,7 +218,7 @@ extern void svc_rdma_xdr_encode_reply_header(struct svcxprt_rdma *,
                                             struct rpcrdma_msg *,
                                             struct rpcrdma_msg *,
                                             enum rpcrdma_proc);
-extern int svc_rdma_xdr_get_reply_hdr_len(struct rpcrdma_msg *);
+extern unsigned int svc_rdma_xdr_get_reply_hdr_len(__be32 *rdma_resp);
 
 /* svc_rdma_recvfrom.c */
 extern int svc_rdma_recvfrom(struct svc_rqst *);
index 0ba9887f3e22bab9a1e3e809df5c4e2c23a510fe..4e7203439e2fde2158f04f2eb709af29d800bba4 100644 (file)
@@ -260,32 +260,35 @@ int svc_rdma_xdr_encode_error(struct svcxprt_rdma *xprt,
        return (int)((unsigned long)va - (unsigned long)startp);
 }
 
-int svc_rdma_xdr_get_reply_hdr_len(struct rpcrdma_msg *rmsgp)
+/**
+ * svc_rdma_xdr_get_reply_hdr_length - Get length of Reply transport header
+ * @rdma_resp: buffer containing Reply transport header
+ *
+ * Returns length of transport header, in bytes.
+ */
+unsigned int svc_rdma_xdr_get_reply_hdr_len(__be32 *rdma_resp)
 {
-       struct rpcrdma_write_array *wr_ary;
+       unsigned int nsegs;
+       __be32 *p;
 
-       /* There is no read-list in a reply */
+       p = rdma_resp;
 
-       /* skip write list */
-       wr_ary = (struct rpcrdma_write_array *)
-               &rmsgp->rm_body.rm_chunks[1];
-       if (wr_ary->wc_discrim)
-               wr_ary = (struct rpcrdma_write_array *)
-                       &wr_ary->wc_array[be32_to_cpu(wr_ary->wc_nchunks)].
-                       wc_target.rs_length;
-       else
-               wr_ary = (struct rpcrdma_write_array *)
-                       &wr_ary->wc_nchunks;
-
-       /* skip reply array */
-       if (wr_ary->wc_discrim)
-               wr_ary = (struct rpcrdma_write_array *)
-                       &wr_ary->wc_array[be32_to_cpu(wr_ary->wc_nchunks)];
-       else
-               wr_ary = (struct rpcrdma_write_array *)
-                       &wr_ary->wc_nchunks;
-
-       return (unsigned long) wr_ary - (unsigned long) rmsgp;
+       /* RPC-over-RDMA V1 replies never have a Read list. */
+       p += rpcrdma_fixed_maxsz + 1;
+
+       /* Skip Write list. */
+       while (*p++ != xdr_zero) {
+               nsegs = be32_to_cpup(p++);
+               p += nsegs * rpcrdma_segment_maxsz;
+       }
+
+       /* Skip Reply chunk. */
+       if (*p++ != xdr_zero) {
+               nsegs = be32_to_cpup(p++);
+               p += nsegs * rpcrdma_segment_maxsz;
+       }
+
+       return (unsigned long)p - (unsigned long)rdma_resp;
 }
 
 void svc_rdma_xdr_encode_write_list(struct rpcrdma_msg *rmsgp, int chunks)
index ad4d286a83c5195fe663dd581cd49a5c9f9a6166..ba76f1617965d449250b21c7767573950ee7bd16 100644 (file)
@@ -476,7 +476,8 @@ static int send_reply(struct svcxprt_rdma *rdma,
 
        /* Prepare the SGE for the RPCRDMA Header */
        ctxt->sge[0].lkey = rdma->sc_pd->local_dma_lkey;
-       ctxt->sge[0].length = svc_rdma_xdr_get_reply_hdr_len(rdma_resp);
+       ctxt->sge[0].length =
+           svc_rdma_xdr_get_reply_hdr_len((__be32 *)rdma_resp);
        ctxt->sge[0].addr =
            ib_dma_map_page(rdma->sc_cm_id->device, page, 0,
                            ctxt->sge[0].length, DMA_TO_DEVICE);