Commit 07e9a632 authored by Chuck Lever's avatar Chuck Lever
Browse files

SUNRPC: Add helpers for decoding list discriminators symbolically



Use these helpers in a few spots to demonstrate their use.

The remaining open-coded discriminator checks in rpcrdma will be
addressed in subsequent patches.

Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent 0b8dc1b6
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -474,6 +474,32 @@ xdr_stream_encode_uint32_array(struct xdr_stream *xdr,
	return ret;
}

/**
 * xdr_item_is_absent - symbolically handle XDR discriminators
 * @p: pointer to undecoded discriminator
 *
 * Return values:
 *   %true if the following XDR item is absent
 *   %false if the following XDR item is present
 */
static inline bool xdr_item_is_absent(const __be32 *p)
{
	return *p == xdr_zero;
}

/**
 * xdr_item_is_present - symbolically handle XDR discriminators
 * @p: pointer to undecoded discriminator
 *
 * Return values:
 *   %true if the following XDR item is present
 *   %false if the following XDR item is absent
 */
static inline bool xdr_item_is_present(const __be32 *p)
{
	return *p != xdr_zero;
}

/**
 * xdr_stream_decode_u32 - Decode a 32-bit integer
 * @xdr: pointer to xdr_stream
+6 −6
Original line number Diff line number Diff line
@@ -1133,11 +1133,11 @@ rpcrdma_is_bcall(struct rpcrdma_xprt *r_xprt, struct rpcrdma_rep *rep)
	p = xdr_inline_decode(xdr, 0);

	/* Chunk lists */
	if (*p++ != xdr_zero)
	if (xdr_item_is_present(p++))
		return false;
	if (*p++ != xdr_zero)
	if (xdr_item_is_present(p++))
		return false;
	if (*p++ != xdr_zero)
	if (xdr_item_is_present(p++))
		return false;

	/* RPC header */
@@ -1215,7 +1215,7 @@ static int decode_read_list(struct xdr_stream *xdr)
	p = xdr_inline_decode(xdr, sizeof(*p));
	if (unlikely(!p))
		return -EIO;
	if (unlikely(*p != xdr_zero))
	if (unlikely(xdr_item_is_present(p)))
		return -EIO;
	return 0;
}
@@ -1234,7 +1234,7 @@ static int decode_write_list(struct xdr_stream *xdr, u32 *length)
		p = xdr_inline_decode(xdr, sizeof(*p));
		if (unlikely(!p))
			return -EIO;
		if (*p == xdr_zero)
		if (xdr_item_is_absent(p))
			break;
		if (!first)
			return -EIO;
@@ -1256,7 +1256,7 @@ static int decode_reply_chunk(struct xdr_stream *xdr, u32 *length)
		return -EIO;

	*length = 0;
	if (*p != xdr_zero)
	if (xdr_item_is_present(p))
		if (decode_write_chunk(xdr, length))
			return -EIO;
	return 0;
+8 −9
Original line number Diff line number Diff line
@@ -419,7 +419,7 @@ static bool xdr_check_read_list(struct svc_rdma_recv_ctxt *rctxt)

	len = 0;
	first = true;
	while (*p != xdr_zero) {
	while (xdr_item_is_present(p)) {
		p = xdr_inline_decode(&rctxt->rc_stream,
				      rpcrdma_readseg_maxsz * sizeof(*p));
		if (!p)
@@ -500,7 +500,7 @@ static bool xdr_check_write_list(struct svc_rdma_recv_ctxt *rctxt)
	if (!p)
		return false;
	rctxt->rc_write_list = p;
	while (*p != xdr_zero) {
	while (xdr_item_is_present(p)) {
		if (!xdr_check_write_chunk(rctxt, MAX_BYTES_WRITE_CHUNK))
			return false;
		++chcount;
@@ -532,12 +532,11 @@ static bool xdr_check_reply_chunk(struct svc_rdma_recv_ctxt *rctxt)
	p = xdr_inline_decode(&rctxt->rc_stream, sizeof(*p));
	if (!p)
		return false;
	rctxt->rc_reply_chunk = p;
	if (*p != xdr_zero) {
	rctxt->rc_reply_chunk = NULL;
	if (xdr_item_is_present(p)) {
		if (!xdr_check_write_chunk(rctxt, MAX_BYTES_SPECIAL_CHUNK))
			return false;
	} else {
		rctxt->rc_reply_chunk = NULL;
		rctxt->rc_reply_chunk = p;
	}
	return true;
}
@@ -568,7 +567,7 @@ static void svc_rdma_get_inv_rkey(struct svcxprt_rdma *rdma,
	p += rpcrdma_fixed_maxsz;

	/* Read list */
	while (*p++ != xdr_zero) {
	while (xdr_item_is_present(p++)) {
		p++;	/* position */
		if (inv_rkey == xdr_zero)
			inv_rkey = *p;
@@ -578,7 +577,7 @@ static void svc_rdma_get_inv_rkey(struct svcxprt_rdma *rdma,
	}

	/* Write list */
	while (*p++ != xdr_zero) {
	while (xdr_item_is_present(p++)) {
		segcount = be32_to_cpup(p++);
		for (i = 0; i < segcount; i++) {
			if (inv_rkey == xdr_zero)
@@ -590,7 +589,7 @@ static void svc_rdma_get_inv_rkey(struct svcxprt_rdma *rdma,
	}

	/* Reply chunk */
	if (*p++ != xdr_zero) {
	if (xdr_item_is_present(p++)) {
		segcount = be32_to_cpup(p++);
		for (i = 0; i < segcount; i++) {
			if (inv_rkey == xdr_zero)