mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
SUNRPC: Add svcxdr_encode_opaque_payload()
The encoder functions that xdrgen emits handle a variable-length opaque with xdr_stream_encode_opaque(), which copies the opaque content into the RPC buffer. On the server, an NFS READ payload already resides in the pages of rqstp->rq_res, placed there by an underlying file system read. Copying that payload into the RPC Reply buffer adds a data copy on every READ and prevents a transport capable of direct data placement from conveying the payload separately from the rest of the Reply. Add a helper that encodes a page-resident opaque by reference: it encodes the length, inserts the payload pages into the XDR stream, then marks the byte range as a result payload. Generated code calls this helper, so its parameters are limited to the xdr_stream and the payload length. It recovers the svc_rqst with svcxdr_rqst(), and takes the reply's page array from the stream's buffer. Acked-by: Jeff Layton <jlayton@kernel.org> Link: https://patch.msgid.link/20260908134234.512312-4-cel@kernel.org Signed-off-by: Chuck Lever <cel@kernel.org>
This commit is contained in:
parent
4ab20626ad
commit
e679ac4bb8
|
|
@ -608,6 +608,41 @@ static inline void svcxdr_encode_opaque_pages(struct svc_rqst *rqstp,
|
|||
xdr->page_ptr = rqstp->rq_next_page - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* svcxdr_encode_opaque_payload - Encode a page-resident opaque data item
|
||||
* @xdr: xdr_stream to be updated
|
||||
* @len: number of octets of content in the data item
|
||||
*
|
||||
* Context: Process context. @xdr must have been initialized by
|
||||
* svcxdr_init_encode() and still be positioned in the reply
|
||||
* head.
|
||||
*
|
||||
* Return:
|
||||
* %true: Success
|
||||
* %false: The reply head cannot hold the length prefix and XDR
|
||||
* padding, or the transport could not accommodate the result payload
|
||||
*/
|
||||
static inline bool svcxdr_encode_opaque_payload(struct xdr_stream *xdr, u32 len)
|
||||
{
|
||||
struct svc_rqst *rqstp = svcxdr_rqst(xdr);
|
||||
struct xdr_buf *buf = xdr->buf;
|
||||
|
||||
/*
|
||||
* The length prefix and any pad word must land in the reply
|
||||
* head. A prefix that spills into the first Reply page lands
|
||||
* on the payload itself, and xdr_write_pages() BUGs when the
|
||||
* pad word does not fit.
|
||||
*/
|
||||
if ((xdr->end - xdr->p) * XDR_UNIT < XDR_UNIT + xdr_pad_size(len))
|
||||
return false;
|
||||
if (xdr_stream_encode_u32(xdr, len) < 0)
|
||||
return false;
|
||||
svcxdr_encode_opaque_pages(rqstp, xdr, buf->pages, buf->page_base, len);
|
||||
if (svc_encode_result_payload(rqstp, buf->head->iov_len, len) < 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* svcxdr_set_auth_slack -
|
||||
* @rqstp: RPC transaction
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user