SUNRPC: Carry a generated-codec context pointer in struct xdr_stream

A generated XDR codec function receives only an xdr_stream, yet
some codecs need state that the stream does not carry. Passing
that state as an additional argument changes the signature of
every function on the path from the program entry point down to
the one that consumes it, and for generated code it makes each
function's argument list depend on an analysis of the entire
specification.

Add xdrgen_ctx to struct xdr_stream, a pointer that the layer
initializing the stream sets aside for generated codecs to find,
following the precedent of seq_file->private and
netlink_callback->data. Every xdr_stream initializer clears it, so
a codec never reads a residual value left in a stream that was
allocated on the stack or taken from a transport's free pool.

Acked-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: NeilBrown <neil@brown.name>
Link: https://patch.msgid.link/20260908134234.512312-2-cel@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
This commit is contained in:
Chuck Lever committed 2026-10-04 21:15:29 -04:00
1 parent e7a8721b7e
commit de7c581708
4 files changed
+6

No files matched your search

+1
View File
@@ -4609,6 +4609,7 @@ static void svcxdr_init_encode_from_buffer(struct xdr_stream *xdr,
xdr->p = p;
xdr->end = (void *)p + bytes;
buf->buflen = bytes;
xdr->xdrgen_ctx = NULL;
}
__be32 nfsd4_encode_fattr_to_buf(__be32 **p, int words,
+1
View File
@@ -567,6 +567,7 @@ 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;
}
/**
+1
View File
@@ -244,6 +244,7 @@ struct xdr_stream {
unsigned int nwords; /* Remaining decode buffer length */
struct rpc_rqst *rqst; /* For debugging */
void *xdrgen_ctx; /* Context for generated codecs */
};
/*
+3
View File
@@ -1161,6 +1161,7 @@ void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p,
iov->iov_len += len;
}
xdr->rqst = rqst;
xdr->xdrgen_ctx = NULL;
}
EXPORT_SYMBOL_GPL(xdr_init_encode);
@@ -1180,6 +1181,7 @@ void xdr_init_encode_pages(struct xdr_stream *xdr, struct xdr_buf *buf)
xdr->p = page_address(*xdr->page_ptr);
xdr->end = (void *)xdr->p + min_t(u32, buf->buflen, PAGE_SIZE);
xdr->rqst = NULL;
xdr->xdrgen_ctx = NULL;
}
EXPORT_SYMBOL_GPL(xdr_init_encode_pages);
@@ -1618,6 +1620,7 @@ void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p,
xdr->p = p;
}
xdr->rqst = rqst;
xdr->xdrgen_ctx = NULL;
}
EXPORT_SYMBOL_GPL(xdr_init_decode);