]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
xdrgen: Implement short (16-bit) integer types
authorChuck Lever <chuck.lever@oracle.com>
Tue, 16 Dec 2025 16:23:09 +0000 (11:23 -0500)
committerChuck Lever <chuck.lever@oracle.com>
Mon, 26 Jan 2026 15:10:58 +0000 (10:10 -0500)
"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>
include/linux/sunrpc/xdrgen/_builtins.h
tools/net/sunrpc/xdrgen/generators/__init__.py
tools/net/sunrpc/xdrgen/grammars/xdr.lark
tools/net/sunrpc/xdrgen/xdr_ast.py

index 66ca3ece951ab98816ec068ddb877778e1198540..52ed9a9151c44ec659f5adcab37aff7e1f375e75 100644 (file)
@@ -46,6 +46,66 @@ xdrgen_encode_bool(struct xdr_stream *xdr, bool val)
        return true;
 }
 
+/*
+ * De facto (non-standard but commonly implemented) signed short type:
+ *  - Wire sends sign-extended 32-bit value (e.g., 0xFFFFFFFF)
+ *  - be32_to_cpup() returns u32 (0xFFFFFFFF)
+ *  - Explicit (s16) cast truncates to 16 bits (0xFFFF = -1)
+ */
+static inline bool
+xdrgen_decode_short(struct xdr_stream *xdr, s16 *ptr)
+{
+       __be32 *p = xdr_inline_decode(xdr, XDR_UNIT);
+
+       if (unlikely(!p))
+               return false;
+       *ptr = (s16)be32_to_cpup(p);
+       return true;
+}
+
+/*
+ * De facto (non-standard but commonly implemented) signed short type:
+ *  - C integer promotion sign-extends s16 val to int before passing to
+ *    cpu_to_be32()
+ *  - This is well-defined: -1 as s16 -1 as int 0xFFFFFFFF on wire
+ */
+static inline bool
+xdrgen_encode_short(struct xdr_stream *xdr, s16 val)
+{
+       __be32 *p = xdr_reserve_space(xdr, XDR_UNIT);
+
+       if (unlikely(!p))
+               return false;
+       *p = cpu_to_be32(val);
+       return true;
+}
+
+/*
+ * De facto (non-standard but commonly implemented) unsigned short type:
+ * 16-bit integer zero-extended to fill one XDR_UNIT.
+ */
+static inline bool
+xdrgen_decode_unsigned_short(struct xdr_stream *xdr, u16 *ptr)
+{
+       __be32 *p = xdr_inline_decode(xdr, XDR_UNIT);
+
+       if (unlikely(!p))
+               return false;
+       *ptr = (u16)be32_to_cpup(p);
+       return true;
+}
+
+static inline bool
+xdrgen_encode_unsigned_short(struct xdr_stream *xdr, u16 val)
+{
+       __be32 *p = xdr_reserve_space(xdr, XDR_UNIT);
+
+       if (unlikely(!p))
+               return false;
+       *p = cpu_to_be32(val);
+       return true;
+}
+
 static inline bool
 xdrgen_decode_int(struct xdr_stream *xdr, s32 *ptr)
 {
index 1d577a986c6cf83d4eef00d763af8d6b20b000d0..5c3a4a47ded800bddd14bdedf9d831c2e78b0010 100644 (file)
@@ -59,6 +59,8 @@ def kernel_c_type(spec: _XdrTypeSpecifier) -> str:
     """Return name of C type"""
     builtin_native_c_type = {
         "bool": "bool",
+        "short": "s16",
+        "unsigned_short": "u16",
         "int": "s32",
         "unsigned_int": "u32",
         "long": "s32",
index 7c2c1b8c86d126618cedd90e5667f57b7c012220..b7c664f2acb7c83f5e96555c2e60fffc059ce462 100644 (file)
@@ -20,9 +20,11 @@ constant                : decimal_constant | hexadecimal_constant | octal_consta
 type_specifier          : unsigned_hyper
                         | unsigned_long
                         | unsigned_int
+                        | unsigned_short
                         | hyper
                         | long
                         | int
+                        | short
                         | float
                         | double
                         | quadruple
@@ -35,9 +37,11 @@ type_specifier          : unsigned_hyper
 unsigned_hyper          : "unsigned" "hyper"
 unsigned_long           : "unsigned" "long"
 unsigned_int            : "unsigned" "int"
+unsigned_short          : "unsigned" "short"
 hyper                   : "hyper"
 long                    : "long"
 int                     : "int"
+short                   : "short"
 float                   : "float"
 double                  : "double"
 quadruple               : "quadruple"
index 5233e73c7046a66821c15574ad99a2ccdb20adf5..2b5d160a0a60a16bf39c2f4dedf5004ef46a3dd0 100644 (file)
@@ -34,6 +34,8 @@ def xdr_quadlen(val: str) -> int:
 symbolic_widths = {
     "void": ["XDR_void"],
     "bool": ["XDR_bool"],
+    "short": ["XDR_short"],
+    "unsigned_short": ["XDR_unsigned_short"],
     "int": ["XDR_int"],
     "unsigned_int": ["XDR_unsigned_int"],
     "long": ["XDR_long"],
@@ -48,6 +50,8 @@ symbolic_widths = {
 max_widths = {
     "void": 0,
     "bool": 1,
+    "short": 1,
+    "unsigned_short": 1,
     "int": 1,
     "unsigned_int": 1,
     "long": 1,