diff options
| author | Chuck Lever <cel@kernel.org> | 2026-09-08 09:42:26 -0400 |
|---|---|---|
| committer | Chuck Lever <cel@kernel.org> | 2026-10-04 21:15:29 -0400 |
| commit | 4ab20626adfcabf9fb5bd6a2d6c10a026abcd23c (patch) | |
| tree | e9610f1fbb72f5115aa6572cb1ef5b6a734426b1 /include/linux/sunrpc | |
| parent | de7c581708a749f037f8a620ed04b0d03e1ac75f (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.h | 19 |
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; } /** |
