diff options
| author | Chuck Lever <cel@kernel.org> | 2026-09-08 09:42:30 -0400 |
|---|---|---|
| committer | Chuck Lever <cel@kernel.org> | 2026-10-04 21:15:29 -0400 |
| commit | 712260f4c438664f407d77edca0a32459f625827 (patch) | |
| tree | d50cdbe1b6e1f49f61b04022f74711abcd55a80d | |
| parent | 9ac56a057364810ad0145c9b3f61c8aa50d3520d (diff) | |
SUNRPC: Add svcxdr_decode_opaque_payload()
A bulk argument payload such as the content of an NFS WRITE request
arrives in the pages of the server's Receive buffer. Copying it into
a contiguous data pointer wastes memory bandwidth and defeats a
transport capable of direct data placement, so a server decodes such
an item in place: it reads the length prefix and captures the payload
octets by reference in an xdr_buf that later stages hand to the VFS.
svcxdr_encode_opaque_payload() already provides the encode-side
counterpart for a page-resident result payload. Add the decode-side
helper so a generated decoder can express the same in-place handling
for a page-resident argument.
Acked-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260908134234.512312-7-cel@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
| -rw-r--r-- | include/linux/sunrpc/svc.h | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index 7950a2ce0a27..24698856eb40 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h @@ -644,6 +644,39 @@ static inline bool svcxdr_encode_opaque_payload(struct xdr_stream *xdr, u32 len) } /** + * svcxdr_decode_opaque_payload - Decode a page-resident opaque data item + * @xdr: xdr_stream to be decoded + * @payload: on success, describes the octets of the data item's content + * @maxlen: largest data item length the caller will accept, or zero for + * no limit + * + * A bulk payload such as the content of an NFS WRITE request resides in + * the pages of the Receive buffer. Rather than copy it, set @payload to + * describe the item's content in place. + * + * Context: Process context. @xdr must have been initialized by + * svcxdr_init_decode(). + * + * Return: + * %true: @payload describes the item in place and @xdr has advanced + * past it + * %false: a bounds error occurred, or the length prefix exceeds + * @maxlen; @payload is undefined + */ +static inline bool svcxdr_decode_opaque_payload(struct xdr_stream *xdr, + struct xdr_buf *payload, + u32 maxlen) +{ + u32 len; + + if (xdr_stream_decode_u32(xdr, &len) < 0) + return false; + if (maxlen && len > maxlen) + return false; + return xdr_stream_subsegment(xdr, payload, len); +} + +/** * svcxdr_set_auth_slack - * @rqstp: RPC transaction * @slack: buffer space to reserve for the transaction's security flavor |
