summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChuck Lever <cel@kernel.org>2026-09-08 09:42:30 -0400
committerChuck Lever <cel@kernel.org>2026-10-04 21:15:29 -0400
commit712260f4c438664f407d77edca0a32459f625827 (patch)
treed50cdbe1b6e1f49f61b04022f74711abcd55a80d
parent9ac56a057364810ad0145c9b3f61c8aa50d3520d (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.h33
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