* [PATCH v2 01/16] xdrgen: Refactor transformer arms
2024-10-03 18:54 [PATCH v2 00/16] xdrgen: Emit maxsize macros cel
@ 2024-10-03 18:54 ` cel
2024-10-03 18:54 ` [PATCH v2 02/16] xdrgen: Track constant values cel
` (14 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: cel @ 2024-10-03 18:54 UTC (permalink / raw)
To: Neil Brown, Jeff Layton, Olga Kornievskaia, Dai Ngo, Tom Talpey
Cc: linux-nfs, Chuck Lever
From: Chuck Lever <chuck.lever@oracle.com>
Clean up: Add a __post_init__ function to the data classes that
need to update the "structs" and "pass_by_reference" sets.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
tools/net/sunrpc/xdrgen/xdr_ast.py | 57 +++++++++++++++++-------------
1 file changed, 33 insertions(+), 24 deletions(-)
diff --git a/tools/net/sunrpc/xdrgen/xdr_ast.py b/tools/net/sunrpc/xdrgen/xdr_ast.py
index d5f0535ec84c..68f09945f2c4 100644
--- a/tools/net/sunrpc/xdrgen/xdr_ast.py
+++ b/tools/net/sunrpc/xdrgen/xdr_ast.py
@@ -51,13 +51,17 @@ class _XdrTypeSpecifier(_XdrAst):
"""Corresponds to 'type_specifier' in the XDR language grammar"""
type_name: str
- c_classifier: str
+ c_classifier: str = ""
@dataclass
class _XdrDefinedType(_XdrTypeSpecifier):
"""Corresponds to a type defined by the input specification"""
+ def __post_init__(self):
+ if self.type_name in structs:
+ self.c_classifier = "struct "
+
@dataclass
class _XdrBuiltInType(_XdrTypeSpecifier):
@@ -124,6 +128,10 @@ class _XdrOptionalData(_XdrDeclaration):
spec: _XdrTypeSpecifier
template: str = "optional_data"
+ def __post_init__(self):
+ structs.add(self.name)
+ pass_by_reference.add(self.name)
+
@dataclass
class _XdrBasic(_XdrDeclaration):
@@ -174,6 +182,10 @@ class _XdrStruct(_XdrAst):
name: str
fields: List[_XdrDeclaration]
+ def __post_init__(self):
+ structs.add(self.name)
+ pass_by_reference.add(self.name)
+
@dataclass
class _XdrPointer(_XdrAst):
@@ -182,6 +194,10 @@ class _XdrPointer(_XdrAst):
name: str
fields: List[_XdrDeclaration]
+ def __post_init__(self):
+ structs.add(self.name)
+ pass_by_reference.add(self.name)
+
@dataclass
class _XdrTypedef(_XdrAst):
@@ -189,6 +205,15 @@ class _XdrTypedef(_XdrAst):
declaration: _XdrDeclaration
+ def __post_init__(self):
+ if not isinstance(self.declaration, _XdrBasic):
+ return
+
+ new_type = self.declaration
+ if isinstance(new_type.spec, _XdrDefinedType):
+ if new_type.spec.type_name in pass_by_reference:
+ pass_by_reference.add(new_type.name)
+
@dataclass
class _XdrCaseSpec(_XdrAst):
@@ -216,6 +241,10 @@ class _XdrUnion(_XdrAst):
cases: List[_XdrCaseSpec]
default: _XdrDeclaration
+ def __post_init__(self):
+ structs.add(self.name)
+ pass_by_reference.add(self.name)
+
@dataclass
class _RpcProcedure(_XdrAst):
@@ -290,22 +319,13 @@ class ParseToAst(Transformer):
return _XdrConstantValue(value)
def type_specifier(self, children):
- """Instantiate one type_specifier object"""
- c_classifier = ""
+ """Instantiate one _XdrTypeSpecifier object"""
if isinstance(children[0], _XdrIdentifier):
name = children[0].symbol
- if name in structs:
- c_classifier = "struct "
- return _XdrDefinedType(
- type_name=name,
- c_classifier=c_classifier,
- )
+ return _XdrDefinedType(type_name=name)
name = children[0].data.value
- return _XdrBuiltInType(
- type_name=name,
- c_classifier=c_classifier,
- )
+ return _XdrBuiltInType(type_name=name)
def constant_def(self, children):
"""Instantiate one _XdrConstant object"""
@@ -380,8 +400,6 @@ class ParseToAst(Transformer):
"""Instantiate one _XdrOptionalData declaration object"""
spec = children[0]
name = children[1].symbol
- structs.add(name)
- pass_by_reference.add(name)
return _XdrOptionalData(name, spec)
@@ -400,8 +418,6 @@ class ParseToAst(Transformer):
def struct(self, children):
"""Instantiate one _XdrStruct object"""
name = children[0].symbol
- structs.add(name)
- pass_by_reference.add(name)
fields = children[1].children
last_field = fields[-1]
@@ -416,11 +432,6 @@ class ParseToAst(Transformer):
def typedef(self, children):
"""Instantiate one _XdrTypedef object"""
new_type = children[0]
- if isinstance(new_type, _XdrBasic) and isinstance(
- new_type.spec, _XdrDefinedType
- ):
- if new_type.spec.type_name in pass_by_reference:
- pass_by_reference.add(new_type.name)
return _XdrTypedef(new_type)
@@ -442,8 +453,6 @@ class ParseToAst(Transformer):
def union(self, children):
"""Instantiate one _XdrUnion object"""
name = children[0].symbol
- structs.add(name)
- pass_by_reference.add(name)
body = children[1]
discriminant = body.children[0].children[0]
--
2.46.2
^ permalink raw reply related [flat|nested] 17+ messages in thread* [PATCH v2 02/16] xdrgen: Track constant values
2024-10-03 18:54 [PATCH v2 00/16] xdrgen: Emit maxsize macros cel
2024-10-03 18:54 ` [PATCH v2 01/16] xdrgen: Refactor transformer arms cel
@ 2024-10-03 18:54 ` cel
2024-10-03 18:54 ` [PATCH v2 03/16] xdrgen: Keep track of on-the-wire data type widths cel
` (13 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: cel @ 2024-10-03 18:54 UTC (permalink / raw)
To: Neil Brown, Jeff Layton, Olga Kornievskaia, Dai Ngo, Tom Talpey
Cc: linux-nfs, Chuck Lever
From: Chuck Lever <chuck.lever@oracle.com>
In order to compute the numeric on-the-wire width of XDR types,
xdrgen needs to keep track of the numeric value of constants that
are defined in the input specification so it can perform
calculations with those values.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
tools/net/sunrpc/xdrgen/xdr_ast.py | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/tools/net/sunrpc/xdrgen/xdr_ast.py b/tools/net/sunrpc/xdrgen/xdr_ast.py
index 68f09945f2c4..b7df45f47707 100644
--- a/tools/net/sunrpc/xdrgen/xdr_ast.py
+++ b/tools/net/sunrpc/xdrgen/xdr_ast.py
@@ -19,6 +19,8 @@ public_apis = []
structs = set()
pass_by_reference = set()
+constants = {}
+
@dataclass
class _XdrAst(ast_utils.Ast):
@@ -156,6 +158,10 @@ class _XdrConstant(_XdrAst):
name: str
value: str
+ def __post_init__(self):
+ if self.value not in constants:
+ constants[self.name] = int(self.value, 0)
+
@dataclass
class _XdrEnumerator(_XdrAst):
@@ -164,6 +170,10 @@ class _XdrEnumerator(_XdrAst):
name: str
value: str
+ def __post_init__(self):
+ if self.value not in constants:
+ constants[self.name] = int(self.value, 0)
+
@dataclass
class _XdrEnum(_XdrAst):
--
2.46.2
^ permalink raw reply related [flat|nested] 17+ messages in thread* [PATCH v2 03/16] xdrgen: Keep track of on-the-wire data type widths
2024-10-03 18:54 [PATCH v2 00/16] xdrgen: Emit maxsize macros cel
2024-10-03 18:54 ` [PATCH v2 01/16] xdrgen: Refactor transformer arms cel
2024-10-03 18:54 ` [PATCH v2 02/16] xdrgen: Track constant values cel
@ 2024-10-03 18:54 ` cel
2024-10-03 18:54 ` [PATCH v2 04/16] xdrgen: XDR widths for enum types cel
` (12 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: cel @ 2024-10-03 18:54 UTC (permalink / raw)
To: Neil Brown, Jeff Layton, Olga Kornievskaia, Dai Ngo, Tom Talpey
Cc: linux-nfs, Chuck Lever
From: Chuck Lever <chuck.lever@oracle.com>
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 | 9 ++++++
tools/net/sunrpc/xdrgen/xdr_ast.py | 43 +++++++++++++++++++++++++++++
2 files changed, 52 insertions(+)
diff --git a/include/linux/sunrpc/xdrgen/_defs.h b/include/linux/sunrpc/xdrgen/_defs.h
index be9e62371758..20c7270aa64d 100644
--- a/include/linux/sunrpc/xdrgen/_defs.h
+++ b/include/linux/sunrpc/xdrgen/_defs.h
@@ -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_ */
diff --git a/tools/net/sunrpc/xdrgen/xdr_ast.py b/tools/net/sunrpc/xdrgen/xdr_ast.py
index b7df45f47707..f1d93a1d0ed8 100644
--- a/tools/net/sunrpc/xdrgen/xdr_ast.py
+++ b/tools/net/sunrpc/xdrgen/xdr_ast.py
@@ -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):
--
2.46.2
^ permalink raw reply related [flat|nested] 17+ messages in thread* [PATCH v2 04/16] xdrgen: XDR widths for enum types
2024-10-03 18:54 [PATCH v2 00/16] xdrgen: Emit maxsize macros cel
` (2 preceding siblings ...)
2024-10-03 18:54 ` [PATCH v2 03/16] xdrgen: Keep track of on-the-wire data type widths cel
@ 2024-10-03 18:54 ` cel
2024-10-03 18:54 ` [PATCH v2 05/16] xdrgen: XDR width for fixed-length opaque cel
` (11 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: cel @ 2024-10-03 18:54 UTC (permalink / raw)
To: Neil Brown, Jeff Layton, Olga Kornievskaia, Dai Ngo, Tom Talpey
Cc: linux-nfs, Chuck Lever
From: Chuck Lever <chuck.lever@oracle.com>
RFC 4506 says that an XDR enum is represented as a signed integer
on the wire; thus its width is 1 XDR_UNIT.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
tools/net/sunrpc/xdrgen/xdr_ast.py | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/tools/net/sunrpc/xdrgen/xdr_ast.py b/tools/net/sunrpc/xdrgen/xdr_ast.py
index f1d93a1d0ed8..fbee954c7f70 100644
--- a/tools/net/sunrpc/xdrgen/xdr_ast.py
+++ b/tools/net/sunrpc/xdrgen/xdr_ast.py
@@ -227,6 +227,18 @@ class _XdrEnum(_XdrAst):
maximum: int
enumerators: List[_XdrEnumerator]
+ def max_width(self) -> int:
+ """Return width of type in XDR_UNITS"""
+ return 1
+
+ def symbolic_width(self) -> List:
+ """Return list containing XDR width of type's components"""
+ return ["XDR_int"]
+
+ def __post_init__(self):
+ max_widths[self.name] = self.max_width()
+ symbolic_widths[self.name] = self.symbolic_width()
+
@dataclass
class _XdrStruct(_XdrAst):
--
2.46.2
^ permalink raw reply related [flat|nested] 17+ messages in thread* [PATCH v2 05/16] xdrgen: XDR width for fixed-length opaque
2024-10-03 18:54 [PATCH v2 00/16] xdrgen: Emit maxsize macros cel
` (3 preceding siblings ...)
2024-10-03 18:54 ` [PATCH v2 04/16] xdrgen: XDR widths for enum types cel
@ 2024-10-03 18:54 ` cel
2024-10-03 18:54 ` [PATCH v2 06/16] xdrgen: XDR width for variable-length opaque cel
` (10 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: cel @ 2024-10-03 18:54 UTC (permalink / raw)
To: Neil Brown, Jeff Layton, Olga Kornievskaia, Dai Ngo, Tom Talpey
Cc: linux-nfs, Chuck Lever
From: Chuck Lever <chuck.lever@oracle.com>
The XDR width for a fixed-length opaque is the byte size of the
opaque rounded up to the next XDR_UNIT, divided by XDR_UNIT.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
tools/net/sunrpc/xdrgen/xdr_ast.py | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/tools/net/sunrpc/xdrgen/xdr_ast.py b/tools/net/sunrpc/xdrgen/xdr_ast.py
index fbee954c7f70..9fe7fa688caa 100644
--- a/tools/net/sunrpc/xdrgen/xdr_ast.py
+++ b/tools/net/sunrpc/xdrgen/xdr_ast.py
@@ -21,6 +21,16 @@ pass_by_reference = set()
constants = {}
+
+def xdr_quadlen(val: str) -> int:
+ """Return integer XDR width of an XDR type"""
+ if val in constants:
+ octets = constants[val]
+ else:
+ octets = int(val)
+ return int((octets + 3) / 4)
+
+
symbolic_widths = {
"void": ["XDR_void"],
"bool": ["XDR_bool"],
@@ -117,6 +127,18 @@ class _XdrFixedLengthOpaque(_XdrDeclaration):
size: str
template: str = "fixed_length_opaque"
+ def max_width(self) -> int:
+ """Return width of type in XDR_UNITS"""
+ return xdr_quadlen(self.size)
+
+ def symbolic_width(self) -> List:
+ """Return list containing XDR width of type's components"""
+ return ["XDR_QUADLEN(" + self.size + ")"]
+
+ def __post_init__(self):
+ max_widths[self.name] = self.max_width()
+ symbolic_widths[self.name] = self.symbolic_width()
+
@dataclass
class _XdrVariableLengthOpaque(_XdrDeclaration):
--
2.46.2
^ permalink raw reply related [flat|nested] 17+ messages in thread* [PATCH v2 06/16] xdrgen: XDR width for variable-length opaque
2024-10-03 18:54 [PATCH v2 00/16] xdrgen: Emit maxsize macros cel
` (4 preceding siblings ...)
2024-10-03 18:54 ` [PATCH v2 05/16] xdrgen: XDR width for fixed-length opaque cel
@ 2024-10-03 18:54 ` cel
2024-10-03 18:54 ` [PATCH v2 07/16] xdrgen: XDR width for a string cel
` (9 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: cel @ 2024-10-03 18:54 UTC (permalink / raw)
To: Neil Brown, Jeff Layton, Olga Kornievskaia, Dai Ngo, Tom Talpey
Cc: linux-nfs, Chuck Lever
From: Chuck Lever <chuck.lever@oracle.com>
The byte size of a variable-length opaque is conveyed in an unsigned
integer. If there is a specified maximum size, that is included in
the type's widths list.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
tools/net/sunrpc/xdrgen/xdr_ast.py | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/tools/net/sunrpc/xdrgen/xdr_ast.py b/tools/net/sunrpc/xdrgen/xdr_ast.py
index 9fe7fa688caa..94cdcfb36e77 100644
--- a/tools/net/sunrpc/xdrgen/xdr_ast.py
+++ b/tools/net/sunrpc/xdrgen/xdr_ast.py
@@ -148,6 +148,21 @@ class _XdrVariableLengthOpaque(_XdrDeclaration):
maxsize: str
template: str = "variable_length_opaque"
+ def max_width(self) -> int:
+ """Return width of type in XDR_UNITS"""
+ return 1 + xdr_quadlen(self.maxsize)
+
+ def symbolic_width(self) -> List:
+ """Return list containing XDR width of type's components"""
+ widths = ["XDR_unsigned_int"]
+ if self.maxsize != "0":
+ widths.append("XDR_QUADLEN(" + self.maxsize + ")")
+ return widths
+
+ def __post_init__(self):
+ max_widths[self.name] = self.max_width()
+ symbolic_widths[self.name] = self.symbolic_width()
+
@dataclass
class _XdrString(_XdrDeclaration):
--
2.46.2
^ permalink raw reply related [flat|nested] 17+ messages in thread* [PATCH v2 07/16] xdrgen: XDR width for a string
2024-10-03 18:54 [PATCH v2 00/16] xdrgen: Emit maxsize macros cel
` (5 preceding siblings ...)
2024-10-03 18:54 ` [PATCH v2 06/16] xdrgen: XDR width for variable-length opaque cel
@ 2024-10-03 18:54 ` cel
2024-10-03 18:54 ` [PATCH v2 08/16] xdrgen: XDR width for fixed-length array cel
` (8 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: cel @ 2024-10-03 18:54 UTC (permalink / raw)
To: Neil Brown, Jeff Layton, Olga Kornievskaia, Dai Ngo, Tom Talpey
Cc: linux-nfs, Chuck Lever
From: Chuck Lever <chuck.lever@oracle.com>
A string works like a variable-length opaque. See Section 4.11 of
RFC 4506.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
tools/net/sunrpc/xdrgen/xdr_ast.py | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/tools/net/sunrpc/xdrgen/xdr_ast.py b/tools/net/sunrpc/xdrgen/xdr_ast.py
index 94cdcfb36e77..d5f48c094729 100644
--- a/tools/net/sunrpc/xdrgen/xdr_ast.py
+++ b/tools/net/sunrpc/xdrgen/xdr_ast.py
@@ -172,6 +172,21 @@ class _XdrString(_XdrDeclaration):
maxsize: str
template: str = "string"
+ def max_width(self) -> int:
+ """Return width of type in XDR_UNITS"""
+ return 1 + xdr_quadlen(self.maxsize)
+
+ def symbolic_width(self) -> List:
+ """Return list containing XDR width of type's components"""
+ widths = ["XDR_unsigned_int"]
+ if self.maxsize != "0":
+ widths.append("XDR_QUADLEN(" + self.maxsize + ")")
+ return widths
+
+ def __post_init__(self):
+ max_widths[self.name] = self.max_width()
+ symbolic_widths[self.name] = self.symbolic_width()
+
@dataclass
class _XdrFixedLengthArray(_XdrDeclaration):
--
2.46.2
^ permalink raw reply related [flat|nested] 17+ messages in thread* [PATCH v2 08/16] xdrgen: XDR width for fixed-length array
2024-10-03 18:54 [PATCH v2 00/16] xdrgen: Emit maxsize macros cel
` (6 preceding siblings ...)
2024-10-03 18:54 ` [PATCH v2 07/16] xdrgen: XDR width for a string cel
@ 2024-10-03 18:54 ` cel
2024-10-03 18:54 ` [PATCH v2 09/16] xdrgen: XDR width for variable-length array cel
` (7 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: cel @ 2024-10-03 18:54 UTC (permalink / raw)
To: Neil Brown, Jeff Layton, Olga Kornievskaia, Dai Ngo, Tom Talpey
Cc: linux-nfs, Chuck Lever
From: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
tools/net/sunrpc/xdrgen/xdr_ast.py | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/tools/net/sunrpc/xdrgen/xdr_ast.py b/tools/net/sunrpc/xdrgen/xdr_ast.py
index d5f48c094729..e9bc81e83b48 100644
--- a/tools/net/sunrpc/xdrgen/xdr_ast.py
+++ b/tools/net/sunrpc/xdrgen/xdr_ast.py
@@ -197,6 +197,19 @@ class _XdrFixedLengthArray(_XdrDeclaration):
size: str
template: str = "fixed_length_array"
+ def max_width(self) -> int:
+ """Return width of type in XDR_UNITS"""
+ return xdr_quadlen(self.size) * max_widths[self.spec.type_name]
+
+ def symbolic_width(self) -> List:
+ """Return list containing XDR width of type's components"""
+ item_width = " + ".join(symbolic_widths[self.spec.type_name])
+ return ["(" + self.size + " * (" + item_width + "))"]
+
+ def __post_init__(self):
+ max_widths[self.name] = self.max_width()
+ symbolic_widths[self.name] = self.symbolic_width()
+
@dataclass
class _XdrVariableLengthArray(_XdrDeclaration):
--
2.46.2
^ permalink raw reply related [flat|nested] 17+ messages in thread* [PATCH v2 09/16] xdrgen: XDR width for variable-length array
2024-10-03 18:54 [PATCH v2 00/16] xdrgen: Emit maxsize macros cel
` (7 preceding siblings ...)
2024-10-03 18:54 ` [PATCH v2 08/16] xdrgen: XDR width for fixed-length array cel
@ 2024-10-03 18:54 ` cel
2024-10-03 18:54 ` [PATCH v2 10/16] xdrgen: XDR width for optional_data type cel
` (6 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: cel @ 2024-10-03 18:54 UTC (permalink / raw)
To: Neil Brown, Jeff Layton, Olga Kornievskaia, Dai Ngo, Tom Talpey
Cc: linux-nfs, Chuck Lever
From: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
tools/net/sunrpc/xdrgen/xdr_ast.py | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/tools/net/sunrpc/xdrgen/xdr_ast.py b/tools/net/sunrpc/xdrgen/xdr_ast.py
index e9bc81e83b48..cb89d5d9987c 100644
--- a/tools/net/sunrpc/xdrgen/xdr_ast.py
+++ b/tools/net/sunrpc/xdrgen/xdr_ast.py
@@ -220,6 +220,22 @@ class _XdrVariableLengthArray(_XdrDeclaration):
maxsize: str
template: str = "variable_length_array"
+ def max_width(self) -> int:
+ """Return width of type in XDR_UNITS"""
+ return 1 + (xdr_quadlen(self.maxsize) * max_widths[self.spec.type_name])
+
+ def symbolic_width(self) -> List:
+ """Return list containing XDR width of type's components"""
+ widths = ["XDR_unsigned_int"]
+ if self.maxsize != "0":
+ item_width = " + ".join(symbolic_widths[self.spec.type_name])
+ widths.append("(" + self.maxsize + " * (" + item_width + "))")
+ return widths
+
+ def __post_init__(self):
+ max_widths[self.name] = self.max_width()
+ symbolic_widths[self.name] = self.symbolic_width()
+
@dataclass
class _XdrOptionalData(_XdrDeclaration):
--
2.46.2
^ permalink raw reply related [flat|nested] 17+ messages in thread* [PATCH v2 10/16] xdrgen: XDR width for optional_data type
2024-10-03 18:54 [PATCH v2 00/16] xdrgen: Emit maxsize macros cel
` (8 preceding siblings ...)
2024-10-03 18:54 ` [PATCH v2 09/16] xdrgen: XDR width for variable-length array cel
@ 2024-10-03 18:54 ` cel
2024-10-03 18:54 ` [PATCH v2 11/16] xdrgen: XDR width for typedef cel
` (5 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: cel @ 2024-10-03 18:54 UTC (permalink / raw)
To: Neil Brown, Jeff Layton, Olga Kornievskaia, Dai Ngo, Tom Talpey
Cc: linux-nfs, Chuck Lever
From: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
tools/net/sunrpc/xdrgen/xdr_ast.py | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/tools/net/sunrpc/xdrgen/xdr_ast.py b/tools/net/sunrpc/xdrgen/xdr_ast.py
index cb89d5d9987c..f2ef78654e36 100644
--- a/tools/net/sunrpc/xdrgen/xdr_ast.py
+++ b/tools/net/sunrpc/xdrgen/xdr_ast.py
@@ -245,9 +245,19 @@ class _XdrOptionalData(_XdrDeclaration):
spec: _XdrTypeSpecifier
template: str = "optional_data"
+ def max_width(self) -> int:
+ """Return width of type in XDR_UNITS"""
+ return 1
+
+ def symbolic_width(self) -> List:
+ """Return list containing XDR width of type's components"""
+ return ["XDR_bool"]
+
def __post_init__(self):
structs.add(self.name)
pass_by_reference.add(self.name)
+ max_widths[self.name] = self.max_width()
+ symbolic_widths[self.name] = self.symbolic_width()
@dataclass
--
2.46.2
^ permalink raw reply related [flat|nested] 17+ messages in thread* [PATCH v2 11/16] xdrgen: XDR width for typedef
2024-10-03 18:54 [PATCH v2 00/16] xdrgen: Emit maxsize macros cel
` (9 preceding siblings ...)
2024-10-03 18:54 ` [PATCH v2 10/16] xdrgen: XDR width for optional_data type cel
@ 2024-10-03 18:54 ` cel
2024-10-03 18:54 ` [PATCH v2 12/16] xdrgen: XDR width for struct types cel
` (4 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: cel @ 2024-10-03 18:54 UTC (permalink / raw)
To: Neil Brown, Jeff Layton, Olga Kornievskaia, Dai Ngo, Tom Talpey
Cc: linux-nfs, Chuck Lever
From: Chuck Lever <chuck.lever@oracle.com>
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>
---
tools/net/sunrpc/xdrgen/xdr_ast.py | 34 ++++++++++++++++++++++++------
1 file changed, 27 insertions(+), 7 deletions(-)
diff --git a/tools/net/sunrpc/xdrgen/xdr_ast.py b/tools/net/sunrpc/xdrgen/xdr_ast.py
index f2ef78654e36..8996f26cbd55 100644
--- a/tools/net/sunrpc/xdrgen/xdr_ast.py
+++ b/tools/net/sunrpc/xdrgen/xdr_ast.py
@@ -268,6 +268,18 @@ class _XdrBasic(_XdrDeclaration):
spec: _XdrTypeSpecifier
template: str = "basic"
+ def max_width(self) -> int:
+ """Return width of type in XDR_UNITS"""
+ return max_widths[self.spec.type_name]
+
+ def symbolic_width(self) -> List:
+ """Return list containing XDR width of type's components"""
+ return symbolic_widths[self.spec.type_name]
+
+ def __post_init__(self):
+ max_widths[self.name] = self.max_width()
+ symbolic_widths[self.name] = self.symbolic_width()
+
@dataclass
class _XdrVoid(_XdrDeclaration):
@@ -361,14 +373,22 @@ class _XdrTypedef(_XdrAst):
declaration: _XdrDeclaration
- def __post_init__(self):
- if not isinstance(self.declaration, _XdrBasic):
- return
+ def max_width(self) -> int:
+ """Return width of type in XDR_UNITS"""
+ return self.declaration.max_width()
- new_type = self.declaration
- if isinstance(new_type.spec, _XdrDefinedType):
- if new_type.spec.type_name in pass_by_reference:
- pass_by_reference.add(new_type.name)
+ def symbolic_width(self) -> List:
+ """Return list containing XDR width of type's components"""
+ return self.declaration.symbolic_width()
+
+ def __post_init__(self):
+ if isinstance(self.declaration, _XdrBasic):
+ new_type = self.declaration
+ if isinstance(new_type.spec, _XdrDefinedType):
+ if new_type.spec.type_name in pass_by_reference:
+ pass_by_reference.add(new_type.name)
+ max_widths[new_type.name] = self.max_width()
+ symbolic_widths[new_type.name] = self.symbolic_width()
@dataclass
--
2.46.2
^ permalink raw reply related [flat|nested] 17+ messages in thread* [PATCH v2 12/16] xdrgen: XDR width for struct types
2024-10-03 18:54 [PATCH v2 00/16] xdrgen: Emit maxsize macros cel
` (10 preceding siblings ...)
2024-10-03 18:54 ` [PATCH v2 11/16] xdrgen: XDR width for typedef cel
@ 2024-10-03 18:54 ` cel
2024-10-03 18:54 ` [PATCH v2 13/16] xdrgen: XDR width for pointer types cel
` (3 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: cel @ 2024-10-03 18:54 UTC (permalink / raw)
To: Neil Brown, Jeff Layton, Olga Kornievskaia, Dai Ngo, Tom Talpey
Cc: linux-nfs, Chuck Lever
From: Chuck Lever <chuck.lever@oracle.com>
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>
---
tools/net/sunrpc/xdrgen/xdr_ast.py | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/tools/net/sunrpc/xdrgen/xdr_ast.py b/tools/net/sunrpc/xdrgen/xdr_ast.py
index 8996f26cbd55..f34b147c8dfd 100644
--- a/tools/net/sunrpc/xdrgen/xdr_ast.py
+++ b/tools/net/sunrpc/xdrgen/xdr_ast.py
@@ -350,9 +350,25 @@ class _XdrStruct(_XdrAst):
name: str
fields: List[_XdrDeclaration]
+ def max_width(self) -> int:
+ """Return width of type in XDR_UNITS"""
+ width = 0
+ for field in self.fields:
+ width += field.max_width()
+ return width
+
+ def symbolic_width(self) -> List:
+ """Return list containing XDR width of type's components"""
+ widths = []
+ for field in self.fields:
+ widths += field.symbolic_width()
+ return widths
+
def __post_init__(self):
structs.add(self.name)
pass_by_reference.add(self.name)
+ max_widths[self.name] = self.max_width()
+ symbolic_widths[self.name] = self.symbolic_width()
@dataclass
--
2.46.2
^ permalink raw reply related [flat|nested] 17+ messages in thread* [PATCH v2 13/16] xdrgen: XDR width for pointer types
2024-10-03 18:54 [PATCH v2 00/16] xdrgen: Emit maxsize macros cel
` (11 preceding siblings ...)
2024-10-03 18:54 ` [PATCH v2 12/16] xdrgen: XDR width for struct types cel
@ 2024-10-03 18:54 ` cel
2024-10-03 18:54 ` [PATCH v2 14/16] xdrgen: XDR width for union types cel
` (2 subsequent siblings)
15 siblings, 0 replies; 17+ messages in thread
From: cel @ 2024-10-03 18:54 UTC (permalink / raw)
To: Neil Brown, Jeff Layton, Olga Kornievskaia, Dai Ngo, Tom Talpey
Cc: linux-nfs, Chuck Lever
From: Chuck Lever <chuck.lever@oracle.com>
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>
---
tools/net/sunrpc/xdrgen/xdr_ast.py | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/tools/net/sunrpc/xdrgen/xdr_ast.py b/tools/net/sunrpc/xdrgen/xdr_ast.py
index f34b147c8dfd..8d53c889eee8 100644
--- a/tools/net/sunrpc/xdrgen/xdr_ast.py
+++ b/tools/net/sunrpc/xdrgen/xdr_ast.py
@@ -378,9 +378,26 @@ class _XdrPointer(_XdrAst):
name: str
fields: List[_XdrDeclaration]
+ def max_width(self) -> int:
+ """Return width of type in XDR_UNITS"""
+ width = 1
+ for field in self.fields[0:-1]:
+ width += field.max_width()
+ return width
+
+ def symbolic_width(self) -> List:
+ """Return list containing XDR width of type's components"""
+ widths = []
+ widths += ["XDR_bool"]
+ for field in self.fields[0:-1]:
+ widths += field.symbolic_width()
+ return widths
+
def __post_init__(self):
structs.add(self.name)
pass_by_reference.add(self.name)
+ max_widths[self.name] = self.max_width()
+ symbolic_widths[self.name] = self.symbolic_width()
@dataclass
--
2.46.2
^ permalink raw reply related [flat|nested] 17+ messages in thread* [PATCH v2 14/16] xdrgen: XDR width for union types
2024-10-03 18:54 [PATCH v2 00/16] xdrgen: Emit maxsize macros cel
` (12 preceding siblings ...)
2024-10-03 18:54 ` [PATCH v2 13/16] xdrgen: XDR width for pointer types cel
@ 2024-10-03 18:54 ` cel
2024-10-03 18:54 ` [PATCH v2 15/16] xdrgen: Add generator code for XDR width macros cel
2024-10-03 18:54 ` [PATCH v2 16/16] xdrgen: emit maxsize macros cel
15 siblings, 0 replies; 17+ messages in thread
From: cel @ 2024-10-03 18:54 UTC (permalink / raw)
To: Neil Brown, Jeff Layton, Olga Kornievskaia, Dai Ngo, Tom Talpey
Cc: linux-nfs, Chuck Lever
From: Chuck Lever <chuck.lever@oracle.com>
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>
---
tools/net/sunrpc/xdrgen/xdr_ast.py | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/tools/net/sunrpc/xdrgen/xdr_ast.py b/tools/net/sunrpc/xdrgen/xdr_ast.py
index 8d53c889eee8..5233e73c7046 100644
--- a/tools/net/sunrpc/xdrgen/xdr_ast.py
+++ b/tools/net/sunrpc/xdrgen/xdr_ast.py
@@ -450,9 +450,35 @@ class _XdrUnion(_XdrAst):
cases: List[_XdrCaseSpec]
default: _XdrDeclaration
+ def max_width(self) -> int:
+ """Return width of type in XDR_UNITS"""
+ max_width = 0
+ for case in self.cases:
+ if case.arm.max_width() > max_width:
+ max_width = case.arm.max_width()
+ if self.default:
+ if self.default.arm.max_width() > max_width:
+ max_width = self.default.arm.max_width()
+ return 1 + max_width
+
+ def symbolic_width(self) -> List:
+ """Return list containing XDR width of type's components"""
+ max_width = 0
+ for case in self.cases:
+ if case.arm.max_width() > max_width:
+ max_width = case.arm.max_width()
+ width = case.arm.symbolic_width()
+ if self.default:
+ if self.default.arm.max_width() > max_width:
+ max_width = self.default.arm.max_width()
+ width = self.default.arm.symbolic_width()
+ return symbolic_widths[self.discriminant.name] + width
+
def __post_init__(self):
structs.add(self.name)
pass_by_reference.add(self.name)
+ max_widths[self.name] = self.max_width()
+ symbolic_widths[self.name] = self.symbolic_width()
@dataclass
--
2.46.2
^ permalink raw reply related [flat|nested] 17+ messages in thread* [PATCH v2 15/16] xdrgen: Add generator code for XDR width macros
2024-10-03 18:54 [PATCH v2 00/16] xdrgen: Emit maxsize macros cel
` (13 preceding siblings ...)
2024-10-03 18:54 ` [PATCH v2 14/16] xdrgen: XDR width for union types cel
@ 2024-10-03 18:54 ` cel
2024-10-03 18:54 ` [PATCH v2 16/16] xdrgen: emit maxsize macros cel
15 siblings, 0 replies; 17+ messages in thread
From: cel @ 2024-10-03 18:54 UTC (permalink / raw)
To: Neil Brown, Jeff Layton, Olga Kornievskaia, Dai Ngo, Tom Talpey
Cc: linux-nfs, Chuck Lever
From: Chuck Lever <chuck.lever@oracle.com>
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>
---
.../net/sunrpc/xdrgen/generators/__init__.py | 4 ++++
tools/net/sunrpc/xdrgen/generators/enum.py | 13 +++++++++++-
tools/net/sunrpc/xdrgen/generators/pointer.py | 18 ++++++++++++++++-
tools/net/sunrpc/xdrgen/generators/struct.py | 18 ++++++++++++++++-
tools/net/sunrpc/xdrgen/generators/typedef.py | 18 ++++++++++++++++-
tools/net/sunrpc/xdrgen/generators/union.py | 20 +++++++++++++++++--
.../xdrgen/templates/C/enum/maxsize/enum.j2 | 2 ++
.../templates/C/pointer/maxsize/pointer.j2 | 3 +++
.../templates/C/struct/maxsize/struct.j2 | 3 +++
.../templates/C/typedef/maxsize/basic.j2 | 3 +++
.../C/typedef/maxsize/fixed_length_opaque.j2 | 2 ++
.../templates/C/typedef/maxsize/string.j2 | 2 ++
.../typedef/maxsize/variable_length_array.j2 | 2 ++
.../typedef/maxsize/variable_length_opaque.j2 | 2 ++
.../xdrgen/templates/C/union/maxsize/union.j2 | 3 +++
15 files changed, 107 insertions(+), 6 deletions(-)
create mode 100644 tools/net/sunrpc/xdrgen/templates/C/enum/maxsize/enum.j2
create mode 100644 tools/net/sunrpc/xdrgen/templates/C/pointer/maxsize/pointer.j2
create mode 100644 tools/net/sunrpc/xdrgen/templates/C/struct/maxsize/struct.j2
create mode 100644 tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/basic.j2
create mode 100644 tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/fixed_length_opaque.j2
create mode 100644 tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/string.j2
create mode 100644 tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/variable_length_array.j2
create mode 100644 tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/variable_length_opaque.j2
create mode 100644 tools/net/sunrpc/xdrgen/templates/C/union/maxsize/union.j2
diff --git a/tools/net/sunrpc/xdrgen/generators/__init__.py b/tools/net/sunrpc/xdrgen/generators/__init__.py
index fd2457461274..b98574a36a4a 100644
--- a/tools/net/sunrpc/xdrgen/generators/__init__.py
+++ b/tools/net/sunrpc/xdrgen/generators/__init__.py
@@ -111,3 +111,7 @@ class SourceGenerator:
def emit_encoder(self, node: _XdrAst) -> None:
"""Emit one encoder function for this XDR type"""
raise NotImplementedError("Encoder generation not supported")
+
+ def emit_maxsize(self, node: _XdrAst) -> None:
+ """Emit one maxsize macro for this XDR type"""
+ raise NotImplementedError("Maxsize macro generation not supported")
diff --git a/tools/net/sunrpc/xdrgen/generators/enum.py b/tools/net/sunrpc/xdrgen/generators/enum.py
index e63f45b8eb74..e62f715d3996 100644
--- a/tools/net/sunrpc/xdrgen/generators/enum.py
+++ b/tools/net/sunrpc/xdrgen/generators/enum.py
@@ -4,7 +4,7 @@
"""Generate code to handle XDR enum types"""
from generators import SourceGenerator, create_jinja2_environment
-from xdr_ast import _XdrEnum, public_apis, big_endian
+from xdr_ast import _XdrEnum, public_apis, big_endian, get_header_name
class XdrEnumGenerator(SourceGenerator):
@@ -51,3 +51,14 @@ class XdrEnumGenerator(SourceGenerator):
else:
template = self.environment.get_template("encoder/enum.j2")
print(template.render(name=node.name))
+
+ def emit_maxsize(self, node: _XdrEnum) -> None:
+ """Emit one maxsize macro for an XDR enum type"""
+ macro_name = get_header_name().upper() + "_" + node.name + "_sz"
+ template = self.environment.get_template("maxsize/enum.j2")
+ print(
+ template.render(
+ macro=macro_name,
+ width=" + ".join(node.symbolic_width()),
+ )
+ )
diff --git a/tools/net/sunrpc/xdrgen/generators/pointer.py b/tools/net/sunrpc/xdrgen/generators/pointer.py
index 0aa3d35203f5..6dbda60ad2db 100644
--- a/tools/net/sunrpc/xdrgen/generators/pointer.py
+++ b/tools/net/sunrpc/xdrgen/generators/pointer.py
@@ -12,7 +12,7 @@ from xdr_ast import _XdrBasic, _XdrString
from xdr_ast import _XdrFixedLengthOpaque, _XdrVariableLengthOpaque
from xdr_ast import _XdrFixedLengthArray, _XdrVariableLengthArray
from xdr_ast import _XdrOptionalData, _XdrPointer, _XdrDeclaration
-from xdr_ast import public_apis
+from xdr_ast import public_apis, get_header_name
def emit_pointer_declaration(environment: Environment, node: _XdrPointer) -> None:
@@ -247,6 +247,18 @@ def emit_pointer_encoder(environment: Environment, node: _XdrPointer) -> None:
print(template.render())
+def emit_pointer_maxsize(environment: Environment, node: _XdrPointer) -> None:
+ """Emit one maxsize macro for an XDR pointer type"""
+ macro_name = get_header_name().upper() + "_" + node.name + "_sz"
+ template = get_jinja2_template(environment, "maxsize", "pointer")
+ print(
+ template.render(
+ macro=macro_name,
+ width=" + ".join(node.symbolic_width()),
+ )
+ )
+
+
class XdrPointerGenerator(SourceGenerator):
"""Generate source code for XDR pointer"""
@@ -270,3 +282,7 @@ class XdrPointerGenerator(SourceGenerator):
def emit_encoder(self, node: _XdrPointer) -> None:
"""Emit one encoder function for an XDR pointer type"""
emit_pointer_encoder(self.environment, node)
+
+ def emit_maxsize(self, node: _XdrPointer) -> None:
+ """Emit one maxsize macro for an XDR pointer type"""
+ emit_pointer_maxsize(self.environment, node)
diff --git a/tools/net/sunrpc/xdrgen/generators/struct.py b/tools/net/sunrpc/xdrgen/generators/struct.py
index 6dd7f4d7cd53..64911de46f62 100644
--- a/tools/net/sunrpc/xdrgen/generators/struct.py
+++ b/tools/net/sunrpc/xdrgen/generators/struct.py
@@ -12,7 +12,7 @@ from xdr_ast import _XdrBasic, _XdrString
from xdr_ast import _XdrFixedLengthOpaque, _XdrVariableLengthOpaque
from xdr_ast import _XdrFixedLengthArray, _XdrVariableLengthArray
from xdr_ast import _XdrOptionalData, _XdrStruct, _XdrDeclaration
-from xdr_ast import public_apis
+from xdr_ast import public_apis, get_header_name
def emit_struct_declaration(environment: Environment, node: _XdrStruct) -> None:
@@ -247,6 +247,18 @@ def emit_struct_encoder(environment: Environment, node: _XdrStruct) -> None:
print(template.render())
+def emit_struct_maxsize(environment: Environment, node: _XdrStruct) -> None:
+ """Emit one maxsize macro for an XDR struct type"""
+ macro_name = get_header_name().upper() + "_" + node.name + "_sz"
+ template = get_jinja2_template(environment, "maxsize", "struct")
+ print(
+ template.render(
+ macro=macro_name,
+ width=" + ".join(node.symbolic_width()),
+ )
+ )
+
+
class XdrStructGenerator(SourceGenerator):
"""Generate source code for XDR structs"""
@@ -270,3 +282,7 @@ class XdrStructGenerator(SourceGenerator):
def emit_encoder(self, node: _XdrStruct) -> None:
"""Emit one encoder function for an XDR struct type"""
emit_struct_encoder(self.environment, node)
+
+ def emit_maxsize(self, node: _XdrStruct) -> None:
+ """Emit one maxsize macro for an XDR struct type"""
+ emit_struct_maxsize(self.environment, node)
diff --git a/tools/net/sunrpc/xdrgen/generators/typedef.py b/tools/net/sunrpc/xdrgen/generators/typedef.py
index 6ea98445f5c8..fab72e9d6915 100644
--- a/tools/net/sunrpc/xdrgen/generators/typedef.py
+++ b/tools/net/sunrpc/xdrgen/generators/typedef.py
@@ -12,7 +12,7 @@ from xdr_ast import _XdrBasic, _XdrTypedef, _XdrString
from xdr_ast import _XdrFixedLengthOpaque, _XdrVariableLengthOpaque
from xdr_ast import _XdrFixedLengthArray, _XdrVariableLengthArray
from xdr_ast import _XdrOptionalData, _XdrVoid, _XdrDeclaration
-from xdr_ast import public_apis
+from xdr_ast import public_apis, get_header_name
def emit_typedef_declaration(environment: Environment, node: _XdrDeclaration) -> None:
@@ -230,6 +230,18 @@ def emit_typedef_encoder(environment: Environment, node: _XdrDeclaration) -> Non
raise NotImplementedError("typedef: type not recognized")
+def emit_typedef_maxsize(environment: Environment, node: _XdrDeclaration) -> None:
+ """Emit a maxsize macro for an XDR typedef"""
+ macro_name = get_header_name().upper() + "_" + node.name + "_sz"
+ template = get_jinja2_template(environment, "maxsize", node.template)
+ print(
+ template.render(
+ macro=macro_name,
+ width=" + ".join(node.symbolic_width()),
+ )
+ )
+
+
class XdrTypedefGenerator(SourceGenerator):
"""Generate source code for XDR typedefs"""
@@ -253,3 +265,7 @@ class XdrTypedefGenerator(SourceGenerator):
def emit_encoder(self, node: _XdrTypedef) -> None:
"""Emit one encoder function for an XDR typedef"""
emit_typedef_encoder(self.environment, node.declaration)
+
+ def emit_maxsize(self, node: _XdrTypedef) -> None:
+ """Emit one maxsize macro for an XDR typedef"""
+ emit_typedef_maxsize(self.environment, node.declaration)
diff --git a/tools/net/sunrpc/xdrgen/generators/union.py b/tools/net/sunrpc/xdrgen/generators/union.py
index 4522a5b7a943..2cca00e279cd 100644
--- a/tools/net/sunrpc/xdrgen/generators/union.py
+++ b/tools/net/sunrpc/xdrgen/generators/union.py
@@ -8,8 +8,8 @@ from jinja2 import Environment
from generators import SourceGenerator
from generators import create_jinja2_environment, get_jinja2_template
-from xdr_ast import _XdrBasic, _XdrUnion, _XdrVoid, big_endian
-from xdr_ast import _XdrDeclaration, _XdrCaseSpec, public_apis
+from xdr_ast import _XdrBasic, _XdrUnion, _XdrVoid, get_header_name
+from xdr_ast import _XdrDeclaration, _XdrCaseSpec, public_apis, big_endian
def emit_union_declaration(environment: Environment, node: _XdrUnion) -> None:
@@ -234,6 +234,18 @@ def emit_union_encoder(environment, node: _XdrUnion) -> None:
print(template.render())
+def emit_union_maxsize(environment: Environment, node: _XdrUnion) -> None:
+ """Emit one maxsize macro for an XDR union type"""
+ macro_name = get_header_name().upper() + "_" + node.name + "_sz"
+ template = get_jinja2_template(environment, "maxsize", "union")
+ print(
+ template.render(
+ macro=macro_name,
+ width=" + ".join(node.symbolic_width()),
+ )
+ )
+
+
class XdrUnionGenerator(SourceGenerator):
"""Generate source code for XDR unions"""
@@ -257,3 +269,7 @@ class XdrUnionGenerator(SourceGenerator):
def emit_encoder(self, node: _XdrUnion) -> None:
"""Emit one encoder function for an XDR union"""
emit_union_encoder(self.environment, node)
+
+ def emit_maxsize(self, node: _XdrUnion) -> None:
+ """Emit one maxsize macro for an XDR union"""
+ emit_union_maxsize(self.environment, node)
diff --git a/tools/net/sunrpc/xdrgen/templates/C/enum/maxsize/enum.j2 b/tools/net/sunrpc/xdrgen/templates/C/enum/maxsize/enum.j2
new file mode 100644
index 000000000000..45c1d4c21b22
--- /dev/null
+++ b/tools/net/sunrpc/xdrgen/templates/C/enum/maxsize/enum.j2
@@ -0,0 +1,2 @@
+{# SPDX-License-Identifier: GPL-2.0 #}
+#define {{ '{:<31}'.format(macro) }} ({{ width }})
diff --git a/tools/net/sunrpc/xdrgen/templates/C/pointer/maxsize/pointer.j2 b/tools/net/sunrpc/xdrgen/templates/C/pointer/maxsize/pointer.j2
new file mode 100644
index 000000000000..9f3bfb47d2f4
--- /dev/null
+++ b/tools/net/sunrpc/xdrgen/templates/C/pointer/maxsize/pointer.j2
@@ -0,0 +1,3 @@
+{# SPDX-License-Identifier: GPL-2.0 #}
+#define {{ '{:<31}'.format(macro) }} \
+ ({{ width }})
diff --git a/tools/net/sunrpc/xdrgen/templates/C/struct/maxsize/struct.j2 b/tools/net/sunrpc/xdrgen/templates/C/struct/maxsize/struct.j2
new file mode 100644
index 000000000000..9f3bfb47d2f4
--- /dev/null
+++ b/tools/net/sunrpc/xdrgen/templates/C/struct/maxsize/struct.j2
@@ -0,0 +1,3 @@
+{# SPDX-License-Identifier: GPL-2.0 #}
+#define {{ '{:<31}'.format(macro) }} \
+ ({{ width }})
diff --git a/tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/basic.j2 b/tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/basic.j2
new file mode 100644
index 000000000000..9f3bfb47d2f4
--- /dev/null
+++ b/tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/basic.j2
@@ -0,0 +1,3 @@
+{# SPDX-License-Identifier: GPL-2.0 #}
+#define {{ '{:<31}'.format(macro) }} \
+ ({{ width }})
diff --git a/tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/fixed_length_opaque.j2 b/tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/fixed_length_opaque.j2
new file mode 100644
index 000000000000..45c1d4c21b22
--- /dev/null
+++ b/tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/fixed_length_opaque.j2
@@ -0,0 +1,2 @@
+{# SPDX-License-Identifier: GPL-2.0 #}
+#define {{ '{:<31}'.format(macro) }} ({{ width }})
diff --git a/tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/string.j2 b/tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/string.j2
new file mode 100644
index 000000000000..45c1d4c21b22
--- /dev/null
+++ b/tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/string.j2
@@ -0,0 +1,2 @@
+{# SPDX-License-Identifier: GPL-2.0 #}
+#define {{ '{:<31}'.format(macro) }} ({{ width }})
diff --git a/tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/variable_length_array.j2 b/tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/variable_length_array.j2
new file mode 100644
index 000000000000..45c1d4c21b22
--- /dev/null
+++ b/tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/variable_length_array.j2
@@ -0,0 +1,2 @@
+{# SPDX-License-Identifier: GPL-2.0 #}
+#define {{ '{:<31}'.format(macro) }} ({{ width }})
diff --git a/tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/variable_length_opaque.j2 b/tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/variable_length_opaque.j2
new file mode 100644
index 000000000000..45c1d4c21b22
--- /dev/null
+++ b/tools/net/sunrpc/xdrgen/templates/C/typedef/maxsize/variable_length_opaque.j2
@@ -0,0 +1,2 @@
+{# SPDX-License-Identifier: GPL-2.0 #}
+#define {{ '{:<31}'.format(macro) }} ({{ width }})
diff --git a/tools/net/sunrpc/xdrgen/templates/C/union/maxsize/union.j2 b/tools/net/sunrpc/xdrgen/templates/C/union/maxsize/union.j2
new file mode 100644
index 000000000000..9f3bfb47d2f4
--- /dev/null
+++ b/tools/net/sunrpc/xdrgen/templates/C/union/maxsize/union.j2
@@ -0,0 +1,3 @@
+{# SPDX-License-Identifier: GPL-2.0 #}
+#define {{ '{:<31}'.format(macro) }} \
+ ({{ width }})
--
2.46.2
^ permalink raw reply related [flat|nested] 17+ messages in thread* [PATCH v2 16/16] xdrgen: emit maxsize macros
2024-10-03 18:54 [PATCH v2 00/16] xdrgen: Emit maxsize macros cel
` (14 preceding siblings ...)
2024-10-03 18:54 ` [PATCH v2 15/16] xdrgen: Add generator code for XDR width macros cel
@ 2024-10-03 18:54 ` cel
15 siblings, 0 replies; 17+ messages in thread
From: cel @ 2024-10-03 18:54 UTC (permalink / raw)
To: Neil Brown, Jeff Layton, Olga Kornievskaia, Dai Ngo, Tom Talpey
Cc: linux-nfs, Chuck Lever
From: Chuck Lever <chuck.lever@oracle.com>
Add "definitions" subcommand logic to emit maxsize macros in
generated code.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
.../net/sunrpc/xdrgen/subcmds/definitions.py | 24 ++++++++++++++++---
tools/net/sunrpc/xdrgen/subcmds/source.py | 3 +--
2 files changed, 22 insertions(+), 5 deletions(-)
diff --git a/tools/net/sunrpc/xdrgen/subcmds/definitions.py b/tools/net/sunrpc/xdrgen/subcmds/definitions.py
index 5cd13d53221f..c956e27f37c0 100644
--- a/tools/net/sunrpc/xdrgen/subcmds/definitions.py
+++ b/tools/net/sunrpc/xdrgen/subcmds/definitions.py
@@ -28,9 +28,7 @@ from xdr_parse import xdr_parser, set_xdr_annotate
logger.setLevel(logging.INFO)
-def emit_header_definitions(
- root: Specification, language: str, peer: str
-) -> None:
+def emit_header_definitions(root: Specification, language: str, peer: str) -> None:
"""Emit header definitions"""
for definition in root.definitions:
if isinstance(definition.value, _XdrConstant):
@@ -52,6 +50,25 @@ def emit_header_definitions(
gen.emit_definition(definition.value)
+def emit_header_maxsize(root: Specification, language: str, peer: str) -> None:
+ """Emit header maxsize macros"""
+ print("")
+ for definition in root.definitions:
+ if isinstance(definition.value, _XdrEnum):
+ gen = XdrEnumGenerator(language, peer)
+ elif isinstance(definition.value, _XdrPointer):
+ gen = XdrPointerGenerator(language, peer)
+ elif isinstance(definition.value, _XdrTypedef):
+ gen = XdrTypedefGenerator(language, peer)
+ elif isinstance(definition.value, _XdrStruct):
+ gen = XdrStructGenerator(language, peer)
+ elif isinstance(definition.value, _XdrUnion):
+ gen = XdrUnionGenerator(language, peer)
+ else:
+ continue
+ gen.emit_maxsize(definition.value)
+
+
def handle_parse_error(e: UnexpectedInput) -> bool:
"""Simple parse error reporting, no recovery attempted"""
print(e)
@@ -71,6 +88,7 @@ def subcmd(args: Namespace) -> int:
gen.emit_definition(args.filename, ast)
emit_header_definitions(ast, args.language, args.peer)
+ emit_header_maxsize(ast, args.language, args.peer)
gen = XdrHeaderBottomGenerator(args.language, args.peer)
gen.emit_definition(args.filename, ast)
diff --git a/tools/net/sunrpc/xdrgen/subcmds/source.py b/tools/net/sunrpc/xdrgen/subcmds/source.py
index 00c04ad15b89..2024954748f0 100644
--- a/tools/net/sunrpc/xdrgen/subcmds/source.py
+++ b/tools/net/sunrpc/xdrgen/subcmds/source.py
@@ -83,8 +83,7 @@ def generate_client_source(filename: str, root: Specification, language: str) ->
gen = XdrSourceTopGenerator(language, "client")
gen.emit_source(filename, root)
- # cel: todo: client needs XDR size macros
-
+ print("")
for definition in root.definitions:
emit_source_encoder(definition.value, language, "client")
for definition in root.definitions:
--
2.46.2
^ permalink raw reply related [flat|nested] 17+ messages in thread