]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
xdrgen: Keep track of on-the-wire data type widths
authorChuck Lever <chuck.lever@oracle.com>
Thu, 3 Oct 2024 18:54:33 +0000 (14:54 -0400)
committerChuck Lever <chuck.lever@oracle.com>
Mon, 11 Nov 2024 18:42:01 +0000 (13:42 -0500)
The generic parts of the RPC layer need to know the widths (in
XDR_UNIT increments) of the XDR data types defined for each
protocol.

As a first step, add dictionaries to keep track of the symbolic and
actual maximum XDR width of XDR types.

This makes it straightforward to look up the width of a type by its
name. The built-in dictionaries are pre-loaded with the widths of
the built-in XDR types as defined in RFC 4506.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
include/linux/sunrpc/xdrgen/_defs.h
tools/net/sunrpc/xdrgen/xdr_ast.py

index be9e623717588fc026df7778d3e56dae98b35cf6..20c7270aa64d256554058d5814970c6e74ca5d57 100644 (file)
@@ -23,4 +23,13 @@ typedef struct {
        u8 *data;
 } opaque;
 
+#define XDR_void               (0)
+#define XDR_bool               (1)
+#define XDR_int                        (1)
+#define XDR_unsigned_int       (1)
+#define XDR_long               (1)
+#define XDR_unsigned_long      (1)
+#define XDR_hyper              (2)
+#define XDR_unsigned_hyper     (2)
+
 #endif /* _SUNRPC_XDRGEN__DEFS_H_ */
index b7df45f47707b7f774dcb67b65ac6f9f2765e113..f1d93a1d0ed8a8d6729c7bbadcfbf6a94bf6c549 100644 (file)
@@ -21,6 +21,31 @@ pass_by_reference = set()
 
 constants = {}
 
+symbolic_widths = {
+    "void": ["XDR_void"],
+    "bool": ["XDR_bool"],
+    "int": ["XDR_int"],
+    "unsigned_int": ["XDR_unsigned_int"],
+    "long": ["XDR_long"],
+    "unsigned_long": ["XDR_unsigned_long"],
+    "hyper": ["XDR_hyper"],
+    "unsigned_hyper": ["XDR_unsigned_hyper"],
+}
+
+# Numeric XDR widths are tracked in a dictionary that is keyed
+# by type_name because sometimes a caller has nothing more than
+# the type_name to use to figure out the numeric width.
+max_widths = {
+    "void": 0,
+    "bool": 1,
+    "int": 1,
+    "unsigned_int": 1,
+    "long": 1,
+    "unsigned_long": 1,
+    "hyper": 2,
+    "unsigned_hyper": 2,
+}
+
 
 @dataclass
 class _XdrAst(ast_utils.Ast):
@@ -60,15 +85,24 @@ class _XdrTypeSpecifier(_XdrAst):
 class _XdrDefinedType(_XdrTypeSpecifier):
     """Corresponds to a type defined by the input specification"""
 
+    def symbolic_width(self) -> List:
+        """Return list containing XDR width of type's components"""
+        return [get_header_name().upper() + "_" + self.type_name + "_sz"]
+
     def __post_init__(self):
         if self.type_name in structs:
             self.c_classifier = "struct "
+        symbolic_widths[self.type_name] = self.symbolic_width()
 
 
 @dataclass
 class _XdrBuiltInType(_XdrTypeSpecifier):
     """Corresponds to a built-in XDR type"""
 
+    def symbolic_width(self) -> List:
+        """Return list containing XDR width of type's components"""
+        return symbolic_widths[self.type_name]
+
 
 @dataclass
 class _XdrDeclaration(_XdrAst):
@@ -148,8 +182,17 @@ class _XdrBasic(_XdrDeclaration):
 class _XdrVoid(_XdrDeclaration):
     """A void declaration"""
 
+    name: str = "void"
     template: str = "void"
 
+    def max_width(self) -> int:
+        """Return width of type in XDR_UNITS"""
+        return 0
+
+    def symbolic_width(self) -> List:
+        """Return list containing XDR width of type's components"""
+        return []
+
 
 @dataclass
 class _XdrConstant(_XdrAst):