summaryrefslogtreecommitdiff
path: root/include/linux/sunrpc
diff options
context:
space:
mode:
authorChuck Lever <cel@kernel.org>2026-09-08 09:42:26 -0400
committerChuck Lever <cel@kernel.org>2026-10-04 21:15:29 -0400
commit4ab20626adfcabf9fb5bd6a2d6c10a026abcd23c (patch)
treee9610f1fbb72f5115aa6572cb1ef5b6a734426b1 /include/linux/sunrpc
parentde7c581708a749f037f8a620ed04b0d03e1ac75f (diff)
SUNRPC: Bind the svc_rqst to its XDR streams
A generated XDR codec function receives only an xdr_stream, but some codecs need the RPC transaction the stream belongs to: to reach the procedure's argument and result structures, or to mark a page-resident byte range as a result payload. A client stream already records its transaction in the rqst field; a server stream records nothing, so each generated codec that needs the svc_rqst would have to store it in xdrgen_ctx itself, and every such site would decide on its own what the pointer means. Store the svc_rqst in xdrgen_ctx from svcxdr_init_decode() and svcxdr_init_encode() instead, and read it back through svcxdr_rqst() so that no codec open-codes the cast from void *. A codec running on a stream either of those initialized reaches the transaction, and through it rq_argp and rq_resp. Every other initializer leaves xdrgen_ctx NULL, so svcxdr_rqst() returns NULL there and the guarantee is scoped to those two entry points; a codec that needs the svc_rqst names them in its Context: line. Acked-by: Jeff Layton <jlayton@kernel.org> Link: https://patch.msgid.link/20260908134234.512312-3-cel@kernel.org Signed-off-by: Chuck Lever <cel@kernel.org>
Diffstat (limited to 'include/linux/sunrpc')
-rw-r--r--include/linux/sunrpc/svc.h19
1 files changed, 18 insertions, 1 deletions
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index b80161b849ce..e69aeb864a8d 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -532,6 +532,8 @@ static inline void svc_reserve_auth(struct svc_rqst *rqstp, int space)
* svcxdr_init_decode - Prepare an xdr_stream for Call decoding
* @rqstp: controlling server RPC transaction context
*
+ * The stream records @rqstp, so a codec running on it reaches the
+ * transaction with svcxdr_rqst().
*/
static inline void svcxdr_init_decode(struct svc_rqst *rqstp)
{
@@ -544,12 +546,15 @@ static inline void svcxdr_init_decode(struct svc_rqst *rqstp)
xdr_init_decode(xdr, buf, argv->iov_base, NULL);
xdr_set_scratch_folio(xdr, rqstp->rq_scratch_folio);
+ xdr->xdrgen_ctx = rqstp;
}
/**
* svcxdr_init_encode - Prepare an xdr_stream for svc Reply encoding
* @rqstp: controlling server RPC transaction context
*
+ * The stream records @rqstp, so a codec running on it reaches the
+ * transaction with svcxdr_rqst().
*/
static inline void svcxdr_init_encode(struct svc_rqst *rqstp)
{
@@ -567,7 +572,19 @@ static inline void svcxdr_init_encode(struct svc_rqst *rqstp)
xdr->page_ptr = buf->pages - 1;
buf->buflen = PAGE_SIZE * (rqstp->rq_page_end - buf->pages);
xdr->rqst = NULL;
- xdr->xdrgen_ctx = NULL;
+ xdr->xdrgen_ctx = rqstp;
+}
+
+/**
+ * svcxdr_rqst - Retrieve the transaction bound to an xdr_stream
+ * @xdr: stream to query
+ *
+ * Return: the controlling svc_rqst when @xdr was initialized by
+ * svcxdr_init_decode() or svcxdr_init_encode(), otherwise NULL.
+ */
+static inline struct svc_rqst *svcxdr_rqst(struct xdr_stream *xdr)
+{
+ return xdr->xdrgen_ctx;
}
/**