summaryrefslogtreecommitdiff
path: root/tools/net/sunrpc
AgeCommit message (Collapse)Author
2026-10-04xdrgen: Update the aggregate_members comment for optional-data listsChuck Lever
check_aggregate_directives() records an optional-data list member in aggregate_members alongside a variable-length array member, but the comment on the set still describes only the array form. Name both member forms. Signed-off-by: Chuck Lever <cel@kernel.org>
2026-10-04xdrgen: Document that aggregate members of a struct share an element typeChuck Lever
check_aggregate_directives() rejects a second marked member whose element type differs from the first, because one hook set serves every marked member of a struct and its item hook takes a single element type. The README says the members share a hook set but never states the restriction that follows from it, so a spec author learns of it only from the diagnostic. State the restriction where the shared hook set is described. Signed-off-by: Chuck Lever <cel@kernel.org>
2026-10-04xdrgen: Report unsupported client-side directives without a tracebackChuck Lever
The struct and union emitters raise NotImplementedError when a "pragma pages" or "pragma aggregate" member is generated for the client peer. The source subcommand catches the parse and semantic errors but not that one, so a client generation request for such a specification emits partial output and then a Python traceback, which buries the one line that says what is unsupported. Catch the exception in the source subcommand and report its message on stderr the way the other diagnostics are reported. Signed-off-by: Chuck Lever <cel@kernel.org>
2026-10-04xdrgen: Reject a "pragma pages" union arm declared as an opaqueChuck Lever
check_pages_directives() rejects a union arm declared directly as a string, with a diagnostic pointing at the directive, but accepts one declared directly as a variable-length opaque. The union generator has no arm representation for a direct opaque, so generation fails with an AttributeError from emit_union_case_spec_definition() instead. A direct opaque arm was never generated correctly, marked or not, but the pages validation exists to report such a directive at its source position. Extend the union-arm check to a direct variable-length opaque, so both forms draw the same diagnostic. Signed-off-by: Chuck Lever <cel@kernel.org>
2026-10-04xdrgen: Stream optional-data aggregate lists during encodeChuck Lever
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>
2026-10-04xdrgen: Extend the aggregate codec to optional-data list membersChuck Lever
The hook-driven aggregate codec emits only the counted-array wire form. XDR list types built on the optional-data idiom ("type *name") carry no count and cannot be expressed that way. NFSv2 READDIR's entry list is one such type. Accept an optional-data member under "pragma aggregate" and emit value-follows framing in place of the counted array. The element type's existing single-node encoder already writes its own value-follows boolean, so the loop calls it once per element and once more with a NULL element to write the terminator. The struct C definitions are untouched; only the marked member's framing changes. The generated decoder fails outright. Decoding a value-follows list needs a presence-reporting element decoder, which this change does not add, and a decoder that consumed nothing would leave the stream at the list data for the next member to misread. NFSv2 READDIR only encodes its entry list, so the decode path is never exercised. Acked-by: Jeff Layton <jlayton@kernel.org> Link: https://patch.msgid.link/20260908134234.512312-10-cel@kernel.org Signed-off-by: Chuck Lever <cel@kernel.org>
2026-10-04xdrgen: Add hook-driven aggregate codec for variable-length arraysChuck Lever
A generated variable-length array codec stages the wire array as a C array and walks it. When the in-kernel object is not that array, building that array is wasted memory traffic. The NFS_ACLv2 secattr aclent<> list is one such case: it is a Solaris wire form of the kernel's posix_acl. The hand-rolled codec that performs that transform forces its containing types to keep external linkage (pragma public), and that linkage collides at link time with the same generated types in a sibling program. Add a per-member "pragma aggregate <struct> <member>" directive. For a marked member the generated code owns only the wire framing and calls hand-written begin, item, and end hooks that handle one element at a time. Interior codec signatures do not change. The framing-owned loop follows xdr_encode_array2(), whose only remaining user is fs/nfs_common/nfsacl.c, and seq_file's start/show/stop, where a guaranteed stop() releases what start() took. Those APIs take an ops vtable because one loop serves consumers chosen at run time. Here the consumer is known at generation time, so the hooks bind by name at link time, as the ASN.1 compiler's actions do. A missing hook is a link error, the emitted prototypes enforce the element type, and no indirect call is added per element. The item hooks return only success or failure, with no early "no more elements" return, so that the same hook contract can later frame the RFC 4506 optional-data idiom, where the application pushes entries into generated framing. The front end resolves each marker against the specification and reports one it cannot honor against its own source position, rather than degrading silently to the array-walking codec or surfacing as a traceback from whichever emitter reached it. Absent the marker the generator emits byte-identical output. Acked-by: Jeff Layton <jlayton@kernel.org> Link: https://patch.msgid.link/20260908134234.512312-9-cel@kernel.org Signed-off-by: Chuck Lever <cel@kernel.org>
2026-10-04xdrgen: Extend the pages directive to page-resident argumentsChuck Lever
The pages directive so far drives only the encoder. A bulk argument such as the payload of an NFS WRITE arrives in the pages of the server's Receive buffer, but the generated opaque decoder copies it into a contiguous data pointer. The copy wastes memory bandwidth and forces the containing procedure decoder to be hand-rolled. Let the directive drive the decoder as well. Whether a marked member is decoded in place or encoded by reference follows from whether its containing type is reachable from an RPC procedure argument. Record that set during parsing, then close it over nested aggregates and typedef aliases before the directives are checked. A decoded page-resident member is represented as a struct xdr_buf so that the payload can be handed on without a copy. A marked union arm of an argument type is rejected, since the union generator still emits only the copying decoder. A marked type reachable from both an argument and a result is rejected as well: the two representations differ, and a type carries only one. Acked-by: Jeff Layton <jlayton@kernel.org> Link: https://patch.msgid.link/20260908134234.512312-8-cel@kernel.org Signed-off-by: Chuck Lever <cel@kernel.org>
2026-10-04xdrgen: Add a "pragma pages" directiveChuck Lever
The generated encoder for a variable-length opaque or string member copies its content into the Reply buffer via xdr_stream_encode_opaque(). A bulk payload such as an NFS READ result never resides at the member's data pointer: the server deposits it directly in the pages of the Reply buffer. Until now the containing procedure encoder had to be hand-rolled. Add a per-member directive that makes the emitted encoder call svcxdr_encode_opaque_payload() for the marked member. The README documents its syntax and the members it may name. Beyond the struct and union cases described there, the directive also applies to a member of a self-referential struct, which xdrgen generates as an XDR pointer type. A directive that binds to nothing would degrade silently to the copying encoder, so the front end rejects one that names an undeclared type or member, or a member that cannot carry a payload. It also rejects a second marked member of the same type, and a type whose members reach more than one marked member: svcxdr_encode_opaque_payload() consumes the whole page vector and moves the stream into the tail, so one encoder carries at most one payload. An array of a marked type counts as reaching it more than once, since the array encoder emits the element once per entry. Generated code is unchanged until a specification applies the directive. Acked-by: Jeff Layton <jlayton@kernel.org> Link: https://patch.msgid.link/20260908134234.512312-6-cel@kernel.org Signed-off-by: Chuck Lever <cel@kernel.org>
2026-10-04xdrgen: Pass the containing struct name to member codec emittersChuck Lever
A per-member code generation directive keyed on the (struct, member) pair needs the name of the containing struct, but emit_struct_member_encoder() and emit_struct_member_decoder() receive only the member declaration. Pass the containing struct's name to emit_struct_member_encoder() and emit_struct_member_decoder(), and to the matching emitters in pointer.py, as a required argument. A struct whose last field refers to its own type is an _XdrPointer rather than an _XdrStruct, so pointer.py takes the same argument. No emitter renders the new value yet, so generated output is byte-identical. A subsequent patch keys the "pragma pages" encoder on it. Acked-by: Jeff Layton <jlayton@kernel.org> Link: https://patch.msgid.link/20260908134234.512312-5-cel@kernel.org Signed-off-by: Chuck Lever <cel@kernel.org>
2026-08-10xdrgen: Reject out-of-range program, version, and procedure numbersChuck Lever
RFC 5531 assigns only unsigned constants to program, version, and procedure numbers (Section 12.3) and encodes each as an unsigned 32-bit integer (Section 9), so a valid number falls within [0, 2**32 - 1]. RFC 4506 Section 6.2 permits a signed decimal constant for XDR constants in general and sets no ceiling on magnitude, so the grammar accepts an out-of-range value without complaint. It reaches generated code -- a negative procedure number emerges as an enumerator such as "FOO = -5", valid C that compiles cleanly even though the wire field is an unsigned 32-bit integer. Thus the xdrgen front end is the only place that can reject the malformed value. Extend the semantic checks to require each program, version, and procedure number to fall within [0, 2**32 - 1]. Link: https://patch.msgid.link/20260712203451.124902-6-cel@kernel.org Signed-off-by: Chuck Lever <cel@kernel.org>
2026-08-10xdrgen: Enforce RFC 5531 name and number scoping for RPC programsChuck Lever
The duplicate-identifier check enforces the RFC 4506 name space for XDR type and constant identifiers but ignores what an RPC program definition adds. RFC 5531 Section 12.3 completes the model: a program identifier shares the specification-wide name space with constant and type identifiers, a version name and number are unique within their program, and a procedure name and number are unique within their version. xdrgen currently accepts a specification that breaks any of these rules, and the symptom depends on which rule. A duplicate procedure name reaches the generated header as a redeclared enumerator, which the C compiler rejects. A duplicate procedure number is more dangerous because it is silent: the two procedures emit enumerators of equal value -- valid C that compiles cleanly -- leaving a dispatch collision to surface only at run time. A duplicate program name shares the specification-wide name space with constants and types and is caught alongside them. Extend the check to enforce RFC 5531 scoping in full. Link: https://patch.msgid.link/20260712203451.124902-5-cel@kernel.org Signed-off-by: Chuck Lever <cel@kernel.org>
2026-08-10xdrgen: Reject specifications that define a name twiceChuck Lever
When an RPC specification defines the same type or constant name more than once, currently xdrgen emits every definition without complaint. The duplication surfaces later as a C compiler error about a redefined struct or function that points at generated code instead of the actual offending line in the .x source. RFC 4506 Section 6.4 places constant and type identifiers in a single name space that must be unique within a specification. Add a semantic check that enforces this rule. Link: https://patch.msgid.link/20260712203451.124902-4-cel@kernel.org Signed-off-by: Chuck Lever <cel@kernel.org>
2026-08-10xdrgen: Record the source position of each declared identifierChuck Lever
In preparation for semantic checks that reject a malformed specification, record where each declared identifier appears in the source so a diagnostic can point at the name in error. The transformer keeps each identifier's spelling but discards its position, retaining only the position of the enclosing definition. A caret built from that position falls on the definition keyword rather than on the identifier, because the definition production begins at the keyword. Store the identifier's own line and column on every named construct: constants, enumerated types and their enumerators, structs, unions, pointers, typedef declarations, and RPC program, version, and procedure names. The fields live on the AST base node and are keyword-only, so lark's positional construction of each node is unaffected; a construct whose position is not recorded leaves them zero. Link: https://patch.msgid.link/20260712203451.124902-3-cel@kernel.org Signed-off-by: Chuck Lever <cel@kernel.org>
2026-08-10xdrgen: Align the error caret under tab-indented sourceChuck Lever
When xdrgen reports a parse or transform error, it prints the offending source line followed by a caret marking the column. The source line is emitted with its tab characters intact, but the caret offset is computed from a tab-expanded copy of the text ahead of the column. A terminal expands the line's leading tabs relative to the four-space output indent, while the caret math expands the same tabs from column zero, so the two disagree whenever the line is indented with tabs and the caret lands past the token it should mark. Render the displayed line with its tabs already expanded so the line and the caret share one tab origin and the four-space indent cancels. Fold the now-identical line-and-caret formatting out of both error handlers into a single helper, so every caller reports the same aligned output. Link: https://patch.msgid.link/20260712203451.124902-2-cel@kernel.org Signed-off-by: Chuck Lever <cel@kernel.org>
2026-08-10xdrgen: Fix opaque and string encoders for unbounded membersChuck Lever
The variable-length opaque and string encoder templates emit an unconditional bound check, "if (value->NAME.len > MAXSIZE) return false". XDR represents an unbounded specifier (opaque foo<>, string foo<>) as a maxsize of 0, so for an unbounded member the check degenerates to "len > 0" and the generated encoder refuses every non-empty value. The decoder does not share this defect. It delegates to xdrgen_decode_opaque() and xdrgen_decode_string(), which treat a maxlen of 0 as unbounded and skip the length check. The sibling variable-length array templates already guard their bound check with maxsize != "0". Guard the bound check the same way in each affected template -- the struct and pointer forms of both the opaque and string encoders -- so an unbounded member encodes a payload of any length while a bounded member keeps its limit. An explicit zero-length bound (foo<0>) parses to the same maxsize of 0 and so also skips the check; xdrgen does not distinguish it from the unbounded form, matching the decoder and the array encoders. Fixes: 4b132aacb076 ("tools: Add xdrgen") Link: https://patch.msgid.link/20260712193122.116845-6-cel@kernel.org Signed-off-by: Chuck Lever <cel@kernel.org>
2026-08-10xdrgen: Do not declare union XDR functions in the definitions headerChuck Lever
Unlike the struct, enum, typedef, and pointer templates, the union definitions template also emits xdrgen_decode_*() and xdrgen_encode_*() prototypes for a public union into that header. Those prototypes name struct xdr_stream, which the definitions header neither includes nor forward-declares, so any translation unit that includes the definitions header without xdr.h already in scope draws -Wvisibility warnings. The same public prototypes are emitted into the declarations header, which does include <linux/sunrpc/xdr.h>, making the definitions-header copies redundant. Drop the prototype emission from the union definitions template so it matches the other type templates. Public unions keep their encode and decode prototypes through the declarations header. Fixes: 4b132aacb076 ("tools: Add xdrgen") Link: https://patch.msgid.link/20260712193122.116845-4-cel@kernel.org Signed-off-by: Chuck Lever <cel@kernel.org>
2026-08-10xdrgen: Share void RPC procedure handlers across programsChuck Lever
The generated server-side decoder and encoder for a void procedure argument or result are named after the RPC program (for example, nfs_svc_decode_void). xdrgen derives that prefix from the program name alone, not the version, so two versions of one program built into the same module emit the identical symbol. NFSv2 and NFSv3 both declare program NFS_PROGRAM; once both are converted, fs/nfsd fails to link with multiple definitions of nfs_svc_decode_void and nfs_svc_encode_void. A void handler carries no program- or version-specific behavior: each merely forwards to xdrgen_decode_void() or xdrgen_encode_void(). Define one shared pair, xdrgen_svc_decode_void() and xdrgen_svc_encode_void(), in the xdrgen builtins, and stop the program generator from emitting a per-program void handler. lockd is the one in-tree consumer that already emits per-program void handlers, so regenerate the NLMv3 and NLMv4 XDR code to drop nlm_svc_{decode,encode}_void() and nlm4_svc_{decode,encode}_void() and point both procedure tables at the shared handlers. The shared handlers are identical to the generated ones they replace, so no wire behavior changes. Only the server (svc) handlers are affected. The client-side void stubs remain static and per-program, so they do not collide. Link: https://patch.msgid.link/20260712193122.116845-3-cel@kernel.org Signed-off-by: Chuck Lever <cel@kernel.org>
2026-08-10xdrgen: Emit a blank line ahead of enum declarationsChuck Lever
Clean up. The declaration templates for structs, pointers, and typedefs each begin with a blank line, which keeps successive declarations and the include block above them visually separated. The enum declaration template omits that blank line. trim_blocks collapses the template's lone comment line to nothing, so the omission stayed invisible as long as every generated header happened to lead with a non-enum declaration. Fixes: 4329010ad9c3 ("xdrgen: Address some checkpatch whitespace complaints") Link: https://patch.msgid.link/20260712193122.116845-2-cel@kernel.org Signed-off-by: Chuck Lever <cel@kernel.org>
2026-01-29xdrgen: Implement pass-through lines in specificationsChuck Lever
XDR specification files can contain lines prefixed with '%' that pass through unchanged to generated output. Traditional rpcgen removes the '%' and emits the remainder verbatim, allowing direct insertion of C includes, pragma directives, or other language- specific content into the generated code. Until now, xdrgen silently discarded these lines during parsing. This prevented specifications from including necessary headers or preprocessor directives that might be required for the generated code to compile correctly. The grammar now captures pass-through lines instead of ignoring them. A new AST node type represents pass-through content, and the AST transformer strips the leading '%' character. Definition and source generators emit pass-through content in document order, preserving the original placement within the specification. This brings xdrgen closer to feature parity with traditional rpcgen while maintaining the existing document-order processing model. Existing generated xdrgen source code has been regenerated. Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-01-26xdrgen: Add enum value validation to generated decodersChuck Lever
XDR enum decoders generated by xdrgen do not verify that incoming values are valid members of the enum. Incoming out-of-range values from malicious or buggy peers propagate through the system unchecked. Add validation logic to generated enum decoders using a switch statement that explicitly lists valid enumerator values. The compiler optimizes this to a simple range check when enum values are dense (contiguous), while correctly rejecting invalid values for sparse enums with gaps in their value ranges. The --no-enum-validation option on the source subcommand disables this validation when not needed. The minimum and maximum fields in _XdrEnum, which were previously unused placeholders for a range-based validation approach, have been removed since the switch-based validation handles both dense and sparse enums correctly. Because the new mechanism results in substantive changes to generated code, existing .x files are regenerated. Unrelated white space and semicolon changes in the generated code are due to recent commit 1c873a2fd110 ("xdrgen: Don't generate unnecessary semicolon") and commit 38c4df91242b ("xdrgen: Address some checkpatch whitespace complaints"). Reviewed-by: NeilBrown <neil@brown.name> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-01-26xdrgen: Emit a max_arg_sz macroChuck Lever
struct svc_service has a .vs_xdrsize field that is filled in by servers for each of their RPC programs. This field is supposed to contain the size of the largest procedure argument in the RPC program. This value is also sometimes used to size network transport buffers. Currently, server implementations must manually calculate and hard-code this value, which is error-prone and requires updates when procedure arguments change. Update xdrgen to determine which procedure argument structure is largest, and emit a macro with a well-known name that contains the size of that structure. Server code then uses this macro when initializing the .vs_xdrsize field. For NLM version 4, xdrgen now emits: #define NLM4_MAX_ARGS_SZ (NLM4_nlm4_lockargs_sz) Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-01-26xdrgen: Extend error reporting to AST transformation phaseChuck Lever
Commit 277df18d7df9 ("xdrgen: Improve parse error reporting") added clean, compiler-style error messages for syntax errors detected during parsing. However, semantic errors discovered during AST transformation still produce verbose Python stack traces. When an XDR specification references an undefined type, the transformer raises a VisitError wrapping a KeyError. Before this change: Traceback (most recent call last): File ".../lark/visitors.py", line 124, in _call_userfunc return f(children) ... KeyError: 'fsh4_mode' ... lark.exceptions.VisitError: Error trying to process rule "basic": 'fsh4_mode' After this change: file.x:156:2: semantic error Undefined type 'fsh4_mode' fsh4_mode mode; ^ The new handle_transform_error() function extracts position information from the Lark tree node metadata and formats the error consistently with parse error messages. Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-01-26xdrgen: Improve parse error reportingChuck Lever
The current verbose Lark exception output makes it difficult to quickly identify and fix syntax errors in XDR specifications. Users must wade through hundreds of lines of cascading errors to find the root cause. Replace this with concise, compiler-style error messages showing file, line, column, the unexpected token, and the source line with a caret pointing to the error location. Before: Unexpected token Token('__ANON_1', '+1') at line 14, column 35. Expected one of: * SEMICOLON Previous tokens: [Token('__ANON_0', 'LM_MAXSTRLEN')] [hundreds more cascading errors...] After: file.x:14:35: parse error Unexpected number '+1' const LM_MAXNAMELEN = LM_MAXSTRLEN+1; ^ The error handler now raises XdrParseError on the first error, preventing cascading messages that obscure the root cause. Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-01-26xdrgen: Remove inclusion of nlm4.h headerChuck Lever
The client-side source code template mistakenly includes the nlm4.h header file, which is specific to the NLM protocol and should not be present in the generic template that generates client stubs for all XDR-based protocols. Fixes: 903a7d37d9ea ("xdrgen: Update the files included in client-side source code") Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-01-26xdrgen: Implement short (16-bit) integer typesChuck Lever
"short" and "unsigned short" types are not defined in RFC 4506, but are supported by the rpcgen program. An upcoming protocol specification includes at least one "unsigned short" field, so xdrgen needs to implement support for these types. Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-01-26xdrgen: Emit the program number definitionChuck Lever
"xdrgen definitions" was not providing a definition of a symbolic constant for the RPC program number being defined. Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-01-26xdrgen: Fix struct prefix for typedef types in program wrappersChuck Lever
The program templates for decoder/argument.j2 and encoder/result.j2 unconditionally add 'struct' prefix to all types. This is incorrect when an RPC protocol specification lists a typedef'd basic type or an enum as a procedure argument or result (e.g., NFSv2's fhandle or stat), resulting in compiler errors when building generated C code. Fixes: 4b132aacb076 ("tools: Add xdrgen") Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-01-26xdrgen: Address some checkpatch whitespace complaintsChuck Lever
This is a roll-up of three template fixes that eliminate noise from checkpatch output so that it's easier to spot non-trivial problems. To follow conventional kernel C style, when a union declaration is marked with "pragma public", there should be a blank line between the emitted "union xxx { ... };" and the decoder and encoder function declarations. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-01-26xdrgen: Generate "if" instead of "switch" for boolean union enumeratorsChuck Lever
Eliminate this warning in code generated by xdrgen: fs/nfsd/nfs3xdr_gen.c:220:2: warning: switch condition has boolean value [-Wswitch-bool] 220 | switch (ptr->attributes_follow) { | ^ ~~~~~~~~~~~~~~~~~~~~~~ No more -Wswitch-bool warnings when compiling with W=1. The generated code is functionally equivalent but somewhat more idiomatic. Reported-by: kernel test robot <lkp@intel.com> Closes: https://lore.kernel.org/oe-kbuild-all/202511172336.Y75zj4v6-lkp@intel.com/ Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-01-26xdrgen: improve error reporting for invalid void declarationsKhushal Chitturi
RFC 4506 defines void as a zero-length type that may appear only as union arms or as program argument/result types. It cannot be declared with an identifier, so constructs like "typedef void temp;" are not valid XDR. Previously, xdrgen raised a NotImplementedError when it encountered a void declaration in a typedef. Which was misleading, as the problem is an invalid RPC specification rather than missing functionality in xdrgen. This patch replaces the NotImplementedError for _XdrVoid in typedef handling with a clearer ValueError that specifies incorrect use of void in the XDR input, making it clear that the issue lies in the RPC specification being parsed. Signed-off-by: Khushal Chitturi <kc9282016@gmail.com> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2025-11-25xdrgen: Don't generate unnecessary semicolonChuck Lever
The Jinja2 templates add a semicolon at the end of every function. The C language does not require this punctuation. Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2025-11-25xdrgen: Fix union declarationsChuck Lever
Add a missing template file. This file is used when a union is defined as a public API (ie, "pragma public <union name>;"). Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2025-11-25xdrgen: handle _XdrString in union encoder/decoderKhushal Chitturi
Running xdrgen on xdrgen/tests/test.x fails when generating encoder or decoder functions for union members of type _XdrString. It was because _XdrString does not have a spec attribute like _XdrBasic, leading to AttributeError. This patch updates emit_union_case_spec_definition and emit_union_case_spec_decoder/encoder to handle _XdrString by assigning type_name = "char *" and avoiding referencing to spec. Testing: Fixed xdrgen tool was run on originally failing test file (tools/net/sunrpc/xdrgen/tests/test.x) and now completes without AttributeError. Modified xdrgen tool was also run against nfs4_1.x (Documentation/sunrpc/xdr/nfs4_1.x). The output header file matches with nfs4_1.h (include/linux/sunrpc/xdrgen/nfs4_1.h). This validates the patch for all XDR input files currently within the kernel. Changes since v2: - Moved the shebang to the first line - Removed SPDX header to match style of current xdrgen files Changes since v1: - Corrected email address in Signed-off-by. - Wrapped patch description lines to 72 characters. Signed-off-by: Khushal Chitturi <kc9282016@gmail.com> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2025-11-25xdrgen: Fix the variable-length opaque field decoder templateChuck Lever
Ensure that variable-length opaques are decoded into the named field, and do not overwrite the structure itself. Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2025-11-25xdrgen: Make the xdrgen script location-independentChuck Lever
The @pythondir@ placeholder is meant for build-time substitution, such as with autoconf. autoconf is not used in the kernel. Let's replace that mechanism with one that better enables the xdrgen script to be run from any directory. Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2025-11-25xdrgen: Generalize/harden pathname constructionChuck Lever
Use Python's built-in Path constructor to find the Jinja templates. This provides better error checking, proper use of path component separators, and more reliable location of the template files. Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2025-09-21sunrpc: Change ret code of xdr_stream_decode_opaque_fixedSergey Bashirov
Since the opaque is fixed in size, the caller already knows how many bytes were decoded, on success. Thus, xdr_stream_decode_opaque_fixed() doesn't need to return that value. And, xdr_stream_decode_u32 and _u64 both return zero on success. This patch simplifies the caller's error checking to avoid potential integer promotion issues. Suggested-by: Dan Carpenter <dan.carpenter@linaro.org> Signed-off-by: Sergey Bashirov <sergeybashirov@gmail.com> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2025-05-16xdrgen: Fix code generated for counted arraysChuck Lever
When an XDR counted array has a maximum element count, xdrgen adds a bounds check to the encoder or decoder for that type. But in cases where the .x provides no maximum element count, such as struct notify4 { /* composed from notify_type4 or notify_deviceid_type4 */ bitmap4 notify_mask; notifylist4 notify_vals; }; struct CB_NOTIFY4args { stateid4 cna_stateid; nfs_fh4 cna_fh; notify4 cna_changes<>; }; xdrgen is supposed to omit that bounds check. Some of the Jinja2 templates handle that correctly, but a few are incorrect and leave the bounds check in place with a maximum of zero, which causes encoding/decoding of that type to fail unconditionally. Reported-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2024-11-18xdrgen: Remove program_stat_to_errno() call sitesChuck Lever
Refactor: Translating an on-the-wire value to a local host errno is architecturally a job for the proc function, not the XDR decoder. Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2024-11-18xdrgen: Update the files included in client-side source codeChuck Lever
In particular, client-side source code needs the definition of "struct rpc_procinfo" and does not want header files that pull in "struct svc_rqst". Otherwise, the source does not compile. Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2024-11-18xdrgen: Remove check for "nfs_ok" in C templatesChuck Lever
Obviously, "nfs_ok" is defined only for NFS protocols. Other XDR protocols won't know "nfs_ok" from Adam. Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2024-11-18xdrgen: Remove tracepoint call siteChuck Lever
This tracepoint was a "note to self" and is not operational. It is added only to client-side code, which so far we haven't needed. It will cause immediate breakage once we start generating client code, though, so remove it now. Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2024-11-18xdrgen: Add a utility for extracting XDR from RFCsChuck Lever
For convenience, copy the XDR extraction script from RFC Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2024-11-11xdrgen: emit maxsize macrosChuck Lever
Add "definitions" subcommand logic to emit maxsize macros in generated code. Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2024-11-11xdrgen: Add generator code for XDR width macrosChuck Lever
Introduce logic in the code generators to emit maxsize (XDR width) definitions. In C, these are pre-processor macros. Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2024-11-11xdrgen: XDR width for union typesChuck Lever
Not yet complete. The tool doesn't do any math yet. Thus, even though the maximum XDR width of a union is the width of the union enumerator plus the width of its largest arm, we're using the sum of all the elements of the union for the moment. This means that buffer size requirements are overestimated, and that the generated maxsize macro cannot yet be used for determining data element alignment in the XDR buffer. Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2024-11-11xdrgen: XDR width for pointer typesChuck Lever
The XDR width of a pointer type is the sum of the widths of each of the struct's fields, except for the last field. The width of the implicit boolean "value follows" field is added as well. Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2024-11-11xdrgen: XDR width for struct typesChuck Lever
The XDR width of a struct type is the sum of the widths of each of the struct's fields. Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2024-11-11xdrgen: XDR width for typedefChuck Lever
The XDR width of a typedef is the same as the width of the base type. Signed-off-by: Chuck Lever <chuck.lever@oracle.com>