diff options
| author | Chuck Lever <cel@kernel.org> | 2026-09-08 09:42:34 -0400 |
|---|---|---|
| committer | Chuck Lever <cel@kernel.org> | 2026-10-04 21:15:29 -0400 |
| commit | 1e7f9d30d519d3df6953d4ab6a045063bb8b5896 (patch) | |
| tree | 1993130e79d3af3d6490d93d383e8810031f61b4 /include/linux | |
| parent | 9ebc61dfe93622ad1fc9d2323e3f9f8819fe142d (diff) | |
xdrgen: Stream optional-data aggregate lists during encode
The optional-data aggregate encoder loops cursor.count times, so the
begin hook must report the element count before the first element is
written. A producer that reads its elements while the reply is
encoded -- NFSv2 READDIR streaming directory entries straight into the
send buffer -- does not know that count in advance, and would have to
materialize the whole list just to satisfy the loop bound.
An optional-data list carries no count on the wire, so nothing forces
one on the encoder. Drive it from the item hook instead: a false
return ends the list, and the framing writes the terminator.
The counted-array form and its hook contract are unchanged. No
in-tree spec marks an optional-data member yet, so no generated code
changes here.
Acked-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260908134234.512312-11-cel@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/sunrpc/xdrgen/_defs.h | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/include/linux/sunrpc/xdrgen/_defs.h b/include/linux/sunrpc/xdrgen/_defs.h index f4375d73c5ca..d767206feea4 100644 --- a/include/linux/sunrpc/xdrgen/_defs.h +++ b/include/linux/sunrpc/xdrgen/_defs.h @@ -30,15 +30,24 @@ typedef struct { } opaque; /* - * Cursor a hook-driven aggregate codec hands to its application hooks, - * one element at a time, in place of a materialized C array. The - * generated framing owns it. @xdr is the RPC layer's stream; @ctx is - * that stream's xdrgen_ctx, the svc_rqst on the server. @index is - * the current element and @count the wire array length: a decoder - * fills @count from the wire before the begin hook runs, an - * encoder's begin hook sets it. @member_id selects among a type's - * marked members. The begin/item/end contract is under "Pragma - * aggregate" in tools/net/sunrpc/xdrgen/README. + * Cursor a hook-driven aggregate codec hands to its begin/item/end + * hooks, one element at a time, in place of a materialized C array. + * The generated framing owns it. @xdr is the RPC layer's stream and + * @ctx its xdrgen_ctx, the svc_rqst on the server. @index is the + * current element; @member_id selects among a type's marked members. + * For a counted array @count is the wire length: a decoder fills it + * before the begin hook runs, an encoder's begin hook sets it. The + * hook contract is under "Pragma aggregate" in + * tools/net/sunrpc/xdrgen/README. + * + * An optional-data list ("type *name") carries no count. Its encoder + * pulls elements until the item hook returns false. False ends the + * list rather than failing the encode: the framing writes the + * value-follows terminator, so a producer that stops early leaves a + * valid truncated list on the wire. A producer that stops for a + * mid-list error records it in the application state @ctx reaches, + * and either returns false from the end hook, which fails the + * encode, or reports it in the procedure status. */ struct xdrgen_aggregate_cursor { struct xdr_stream *xdr; |
