Commit cbaf5803 authored by Chuck Lever's avatar Chuck Lever Committed by J. Bruce Fields

svcrdma: Another sendto chunk list parsing update

Commit 5fdca653 ("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: default avatarChuck Lever <chuck.lever@oracle.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent b8800921
...@@ -109,6 +109,15 @@ struct rpcrdma_msg { ...@@ -109,6 +109,15 @@ struct rpcrdma_msg {
} rm_body; } 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 * Smallest RPC/RDMA header: rm_xid through rm_type, then rm_nochunks
*/ */
......
...@@ -218,7 +218,7 @@ extern void svc_rdma_xdr_encode_reply_header(struct svcxprt_rdma *, ...@@ -218,7 +218,7 @@ extern void svc_rdma_xdr_encode_reply_header(struct svcxprt_rdma *,
struct rpcrdma_msg *, struct rpcrdma_msg *,
struct rpcrdma_msg *, struct rpcrdma_msg *,
enum rpcrdma_proc); 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 */ /* svc_rdma_recvfrom.c */
extern int svc_rdma_recvfrom(struct svc_rqst *); extern int svc_rdma_recvfrom(struct svc_rqst *);
......
...@@ -260,32 +260,35 @@ int svc_rdma_xdr_encode_error(struct svcxprt_rdma *xprt, ...@@ -260,32 +260,35 @@ int svc_rdma_xdr_encode_error(struct svcxprt_rdma *xprt,
return (int)((unsigned long)va - (unsigned long)startp); 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 */ /* RPC-over-RDMA V1 replies never have a Read list. */
wr_ary = (struct rpcrdma_write_array *) p += rpcrdma_fixed_maxsz + 1;
&rmsgp->rm_body.rm_chunks[1];
if (wr_ary->wc_discrim) /* Skip Write list. */
wr_ary = (struct rpcrdma_write_array *) while (*p++ != xdr_zero) {
&wr_ary->wc_array[be32_to_cpu(wr_ary->wc_nchunks)]. nsegs = be32_to_cpup(p++);
wc_target.rs_length; p += nsegs * rpcrdma_segment_maxsz;
else }
wr_ary = (struct rpcrdma_write_array *)
&wr_ary->wc_nchunks; /* Skip Reply chunk. */
if (*p++ != xdr_zero) {
/* skip reply array */ nsegs = be32_to_cpup(p++);
if (wr_ary->wc_discrim) p += nsegs * rpcrdma_segment_maxsz;
wr_ary = (struct rpcrdma_write_array *) }
&wr_ary->wc_array[be32_to_cpu(wr_ary->wc_nchunks)];
else return (unsigned long)p - (unsigned long)rdma_resp;
wr_ary = (struct rpcrdma_write_array *)
&wr_ary->wc_nchunks;
return (unsigned long) wr_ary - (unsigned long) rmsgp;
} }
void svc_rdma_xdr_encode_write_list(struct rpcrdma_msg *rmsgp, int chunks) void svc_rdma_xdr_encode_write_list(struct rpcrdma_msg *rmsgp, int chunks)
......
...@@ -476,7 +476,8 @@ static int send_reply(struct svcxprt_rdma *rdma, ...@@ -476,7 +476,8 @@ static int send_reply(struct svcxprt_rdma *rdma,
/* Prepare the SGE for the RPCRDMA Header */ /* Prepare the SGE for the RPCRDMA Header */
ctxt->sge[0].lkey = rdma->sc_pd->local_dma_lkey; 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 = ctxt->sge[0].addr =
ib_dma_map_page(rdma->sc_cm_id->device, page, 0, ib_dma_map_page(rdma->sc_cm_id->device, page, 0,
ctxt->sge[0].length, DMA_TO_DEVICE); ctxt->sge[0].length, DMA_TO_DEVICE);
......
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