Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -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
 */
+1 −1
Original line number Diff line number Diff line
@@ -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 *);
+26 −23
Original line number Diff line number Diff line
@@ -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)
+2 −1
Original line number Diff line number Diff line
@@ -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);