Commit ae605ee9 authored by Chuck Lever's avatar Chuck Lever Committed by Trond Myklebust
Browse files

xprtrdma: Revert 586a0787



Commit 9ed5af26 ("SUNRPC: Clean up the handling of page padding
in rpc_prepare_reply_pages()") [Dec 2020] affects RPC Replies that
have a data payload (i.e., Write chunks).

rpcrdma_prepare_readch(), as its name suggests, sets up Read chunks
which are data payloads within RPC Calls. Those payloads are
constructed by xdr_write_pages(), which continues to stuff the call
buffer's tail kvec with the payload's XDR roundup. Thus removing
the tail buffer logic in rpcrdma_prepare_readch() was the wrong
thing to do.

Fixes: 586a0787 ("xprtrdma: Clean up rpcrdma_prepare_readch()")
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
parent e67afa7e
Loading
Loading
Loading
Loading
+18 −9
Original line number Diff line number Diff line
@@ -628,8 +628,9 @@ static bool rpcrdma_prepare_pagelist(struct rpcrdma_req *req,
	return false;
}

/* The tail iovec might not reside in the same page as the
 * head iovec.
/* The tail iovec may include an XDR pad for the page list,
 * as well as additional content, and may not reside in the
 * same page as the head iovec.
 */
static bool rpcrdma_prepare_tail_iov(struct rpcrdma_req *req,
				     struct xdr_buf *xdr,
@@ -747,19 +748,27 @@ static bool rpcrdma_prepare_readch(struct rpcrdma_xprt *r_xprt,
				   struct rpcrdma_req *req,
				   struct xdr_buf *xdr)
{
	struct kvec *tail = &xdr->tail[0];

	if (!rpcrdma_prepare_head_iov(r_xprt, req, xdr->head[0].iov_len))
		return false;

	/* If there is a Read chunk, the page list is handled
	/* If there is a Read chunk, the page list is being handled
	 * via explicit RDMA, and thus is skipped here.
	 */

	if (tail->iov_len) {
		if (!rpcrdma_prepare_tail_iov(req, xdr,
					      offset_in_page(tail->iov_base),
					      tail->iov_len))
	/* Do not include the tail if it is only an XDR pad */
	if (xdr->tail[0].iov_len > 3) {
		unsigned int page_base, len;

		/* If the content in the page list is an odd length,
		 * xdr_write_pages() adds a pad at the beginning of
		 * the tail iovec. Force the tail's non-pad content to
		 * land at the next XDR position in the Send message.
		 */
		page_base = offset_in_page(xdr->tail[0].iov_base);
		len = xdr->tail[0].iov_len;
		page_base += len & 3;
		len -= len & 3;
		if (!rpcrdma_prepare_tail_iov(req, xdr, page_base, len))
			return false;
		kref_get(&req->rl_kref);
	}