On Tue, 2024-08-20 at 10:46 -0400, cel@xxxxxxxxxx wrote: > From: Chuck Lever <chuck.lever@xxxxxxxxxx> > > Build an NFSv4 protocol snippet to support the delstid extensions. > The new fs/nfsd/nfs4_1.x file can be added to over time as other > parts of NFSD's XDR functions are converted to machine-generated > code. > > Signed-off-by: Chuck Lever <chuck.lever@xxxxxxxxxx> > --- > fs/nfsd/nfs4_1.x | 164 +++++++++++++++++++++++++++++ > fs/nfsd/nfs4xdr_gen.c | 236 ++++++++++++++++++++++++++++++++++++++++++ > fs/nfsd/nfs4xdr_gen.h | 113 ++++++++++++++++++++ > 3 files changed, 513 insertions(+) > create mode 100644 fs/nfsd/nfs4_1.x > create mode 100644 fs/nfsd/nfs4xdr_gen.c > create mode 100644 fs/nfsd/nfs4xdr_gen.h > I see the patches in your lkxdrgen branch. I gave this a try and started rebasing my delstid work on top of it, but I hit the same symbol conflicts I hit before once I started trying to include the full-blown nfs4xdr_gen.h header: ------------------------8<--------------------------- In file included from fs/nfsd/nfs4xdr.c:58: fs/nfsd/nfs4xdr_gen.h:86:9: error: redeclaration of enumerator ‘FATTR4_OPEN_ARGUMENTS’ 86 | FATTR4_OPEN_ARGUMENTS = 86 | ^~~~~~~~~~~~~~~~~~~~~ In file included from fs/nfsd/nfsfh.h:15, from fs/nfsd/state.h:41, from fs/nfsd/xdr4.h:40, from fs/nfsd/nfs4xdr.c:51: ./include/linux/nfs4.h:518:9: note: previous definition of ‘FATTR4_OPEN_ARGUMENTS’ with type ‘enum <anonymous>’ 518 | FATTR4_OPEN_ARGUMENTS = 86, | ^~~~~~~~~~~~~~~~~~~~~ fs/nfsd/nfs4xdr_gen.h:102:9: error: redeclaration of enumerator ‘FATTR4_TIME_DELEG_ACCESS’ 102 | FATTR4_TIME_DELEG_ACCESS = 84 | ^~~~~~~~~~~~~~~~~~~~~~~~ ./include/linux/nfs4.h:516:9: note: previous definition of ‘FATTR4_TIME_DELEG_ACCESS’ with type ‘enum <anonymous>’ 516 | FATTR4_TIME_DELEG_ACCESS = 84, | ^~~~~~~~~~~~~~~~~~~~~~~~ fs/nfsd/nfs4xdr_gen.h:106:9: error: redeclaration of enumerator ‘FATTR4_TIME_DELEG_MODIFY’ 106 | FATTR4_TIME_DELEG_MODIFY = 85 | ^~~~~~~~~~~~~~~~~~~~~~~~ ./include/linux/nfs4.h:517:9: note: previous definition of ‘FATTR4_TIME_DELEG_MODIFY’ with type ‘enum <anonymous>’ 517 | FATTR4_TIME_DELEG_MODIFY = 85, | ^~~~~~~~~~~~~~~~~~~~~~~~ ------------------------8<--------------------------- I'm not sure of the best way to work around this, unless we want to try to split up nfs4.h. Also, as a side note: fs/nfsd/nfs4xdr.c: In function ‘nfsd4_encode_fattr4_open_arguments’: fs/nfsd/nfs4xdr.c:3446:55: error: incompatible type for argument 2 of ‘xdrgen_encode_fattr4_open_arguments’ 3446 | if (!xdrgen_encode_fattr4_open_arguments(xdr, &nfsd_open_arguments)) OPEN_ARGUMENTS4 is a large structure with 5 different bitmaps in it. We probably don't want to pass that by value. When the tool is dealing with a struct, we should have it generate functions that take a pointer instead (IMO). > diff --git a/fs/nfsd/nfs4_1.x b/fs/nfsd/nfs4_1.x > new file mode 100644 > index 000000000000..d2fde450de5e > --- /dev/null > +++ b/fs/nfsd/nfs4_1.x > @@ -0,0 +1,164 @@ > +/* > + * Copyright (c) 2010 IETF Trust and the persons identified > + * as the document authors. All rights reserved. > + * > + * The document authors are identified in RFC 3530 and > + * RFC 5661. > + * > + * Redistribution and use in source and binary forms, with > + * or without modification, are permitted provided that the > + * following conditions are met: > + * > + * - Redistributions of source code must retain the above > + * copyright notice, this list of conditions and the > + * following disclaimer. > + * > + * - Redistributions in binary form must reproduce the above > + * copyright notice, this list of conditions and the > + * following disclaimer in the documentation and/or other > + * materials provided with the distribution. > + * > + * - Neither the name of Internet Society, IETF or IETF > + * Trust, nor the names of specific contributors, may be > + * used to endorse or promote products derived from this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS > + * AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED > + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS > + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO > + * EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, > + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT > + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR > + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF > + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, > + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING > + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF > + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > + */ > + > +pragma header nfs4; > + > +/* > + * Basic typedefs for RFC 1832 data type definitions > + */ > +typedef hyper int64_t; > +typedef unsigned int uint32_t; > + > +/* > + * Basic data types > + */ > +typedef uint32_t bitmap4<>; > + > +/* > + * Timeval > + */ > +struct nfstime4 { > + int64_t seconds; > + uint32_t nseconds; > +}; > + > + > +/* > + * The following content was extracted from draft-ietf-nfsv4-delstid > + */ > + > +typedef bool fattr4_offline; > + > + > +const FATTR4_OFFLINE = 83; > + > + > +struct open_arguments4 { > + bitmap4 oa_share_access; > + bitmap4 oa_share_deny; > + bitmap4 oa_share_access_want; > + bitmap4 oa_open_claim; > + bitmap4 oa_create_mode; > +}; > + > + > +enum open_args_share_access4 { > + OPEN_ARGS_SHARE_ACCESS_READ = 1, > + OPEN_ARGS_SHARE_ACCESS_WRITE = 2, > + OPEN_ARGS_SHARE_ACCESS_BOTH = 3 > +}; > + > + > +enum open_args_share_deny4 { > + OPEN_ARGS_SHARE_DENY_NONE = 0, > + OPEN_ARGS_SHARE_DENY_READ = 1, > + OPEN_ARGS_SHARE_DENY_WRITE = 2, > + OPEN_ARGS_SHARE_DENY_BOTH = 3 > +}; > + > + > +enum open_args_share_access_want4 { > + OPEN_ARGS_SHARE_ACCESS_WANT_ANY_DELEG = 3, > + OPEN_ARGS_SHARE_ACCESS_WANT_NO_DELEG = 4, > + OPEN_ARGS_SHARE_ACCESS_WANT_CANCEL = 5, > + OPEN_ARGS_SHARE_ACCESS_WANT_SIGNAL_DELEG_WHEN_RESRC_AVAIL > + = 17, > + OPEN_ARGS_SHARE_ACCESS_WANT_PUSH_DELEG_WHEN_UNCONTENDED > + = 18, > + OPEN_ARGS_SHARE_ACCESS_WANT_DELEG_TIMESTAMPS = 20, > + OPEN_ARGS_SHARE_ACCESS_WANT_OPEN_XOR_DELEGATION = 21 > +}; > + > + > +enum open_args_open_claim4 { > + OPEN_ARGS_OPEN_CLAIM_NULL = 0, > + OPEN_ARGS_OPEN_CLAIM_PREVIOUS = 1, > + OPEN_ARGS_OPEN_CLAIM_DELEGATE_CUR = 2, > + OPEN_ARGS_OPEN_CLAIM_DELEGATE_PREV = 3, > + OPEN_ARGS_OPEN_CLAIM_FH = 4, > + OPEN_ARGS_OPEN_CLAIM_DELEG_CUR_FH = 5, > + OPEN_ARGS_OPEN_CLAIM_DELEG_PREV_FH = 6 > +}; > + > + > +enum open_args_createmode4 { > + OPEN_ARGS_CREATEMODE_UNCHECKED4 = 0, > + OPEN_ARGS_CREATE_MODE_GUARDED = 1, > + OPEN_ARGS_CREATEMODE_EXCLUSIVE4 = 2, > + OPEN_ARGS_CREATE_MODE_EXCLUSIVE4_1 = 3 > +}; > + > + > +typedef open_arguments4 fattr4_open_arguments; > +pragma public fattr4_open_arguments; > + > + > +%/* > +% * Determine what OPEN supports. > +% */ > +const FATTR4_OPEN_ARGUMENTS = 86; > + > + > +const OPEN4_SHARE_ACCESS_WANT_OPEN_XOR_DELEGATION = 0x200000; > + > + > +const OPEN4_RESULT_NO_OPEN_STATEID = 0x00000010; > + > + > +/* > + * attributes for the delegation times being > + * cached and served by the "client" > + */ > +typedef nfstime4 fattr4_time_deleg_access; > +typedef nfstime4 fattr4_time_deleg_modify; > + > + > +%/* > +% * New RECOMMENDED Attribute for > +% * delegation caching of times > +% */ > +const FATTR4_TIME_DELEG_ACCESS = 84; > +const FATTR4_TIME_DELEG_MODIFY = 85; > + > + > +const OPEN4_SHARE_ACCESS_WANT_DELEG_TIMESTAMPS = 0x100000; > + > diff --git a/fs/nfsd/nfs4xdr_gen.c b/fs/nfsd/nfs4xdr_gen.c > new file mode 100644 > index 000000000000..bb714859d6c6 > --- /dev/null > +++ b/fs/nfsd/nfs4xdr_gen.c > @@ -0,0 +1,236 @@ > +// SPDX-License-Identifier: GPL-2.0 > +// Generated by xdrgen. Manual edits will be lost. > +// XDR specification modification time: Mon Aug 19 23:28:23 2024 > + > +#include "nfs4xdr_gen.h" > + > +static bool __maybe_unused > +xdrgen_decode_int64_t(struct xdr_stream *xdr, int64_t *ptr) > +{ > + return xdrgen_decode_hyper(xdr, ptr); > +}; > + > +static bool __maybe_unused > +xdrgen_decode_uint32_t(struct xdr_stream *xdr, uint32_t *ptr) > +{ > + return xdrgen_decode_unsigned_int(xdr, ptr); > +}; > + > +static bool __maybe_unused > +xdrgen_decode_bitmap4(struct xdr_stream *xdr, bitmap4 *ptr) > +{ > + if (xdr_stream_decode_u32(xdr, &ptr->count) < 0) > + return false; > + for (u32 i = 0; i < ptr->count; i++) > + if (!xdrgen_decode_uint32_t(xdr, &ptr->element[i])) > + return false; > + return true; > +}; > + > +static bool __maybe_unused > +xdrgen_decode_nfstime4(struct xdr_stream *xdr, struct nfstime4 *ptr) > +{ > + if (!xdrgen_decode_int64_t(xdr, &ptr->seconds)) > + return false; > + if (!xdrgen_decode_uint32_t(xdr, &ptr->nseconds)) > + return false; > + return true; > +}; > + > +static bool __maybe_unused > +xdrgen_decode_fattr4_offline(struct xdr_stream *xdr, fattr4_offline *ptr) > +{ > + return xdrgen_decode_bool(xdr, ptr); > +}; > + > +static bool __maybe_unused > +xdrgen_decode_open_arguments4(struct xdr_stream *xdr, struct open_arguments4 *ptr) > +{ > + if (!xdrgen_decode_bitmap4(xdr, &ptr->oa_share_access)) > + return false; > + if (!xdrgen_decode_bitmap4(xdr, &ptr->oa_share_deny)) > + return false; > + if (!xdrgen_decode_bitmap4(xdr, &ptr->oa_share_access_want)) > + return false; > + if (!xdrgen_decode_bitmap4(xdr, &ptr->oa_open_claim)) > + return false; > + if (!xdrgen_decode_bitmap4(xdr, &ptr->oa_create_mode)) > + return false; > + return true; > +}; > + > +static bool __maybe_unused > +xdrgen_decode_open_args_share_access4(struct xdr_stream *xdr, enum open_args_share_access4 *ptr) > +{ > + u32 val; > + > + if (xdr_stream_decode_u32(xdr, &val) < 0) > + return false; > + *ptr = val; > + return true; > +} > + > +static bool __maybe_unused > +xdrgen_decode_open_args_share_deny4(struct xdr_stream *xdr, enum open_args_share_deny4 *ptr) > +{ > + u32 val; > + > + if (xdr_stream_decode_u32(xdr, &val) < 0) > + return false; > + *ptr = val; > + return true; > +} > + > +static bool __maybe_unused > +xdrgen_decode_open_args_share_access_want4(struct xdr_stream *xdr, enum open_args_share_access_want4 *ptr) > +{ > + u32 val; > + > + if (xdr_stream_decode_u32(xdr, &val) < 0) > + return false; > + *ptr = val; > + return true; > +} > + > +static bool __maybe_unused > +xdrgen_decode_open_args_open_claim4(struct xdr_stream *xdr, enum open_args_open_claim4 *ptr) > +{ > + u32 val; > + > + if (xdr_stream_decode_u32(xdr, &val) < 0) > + return false; > + *ptr = val; > + return true; > +} > + > +static bool __maybe_unused > +xdrgen_decode_open_args_createmode4(struct xdr_stream *xdr, enum open_args_createmode4 *ptr) > +{ > + u32 val; > + > + if (xdr_stream_decode_u32(xdr, &val) < 0) > + return false; > + *ptr = val; > + return true; > +} > + > +bool > +xdrgen_decode_fattr4_open_arguments(struct xdr_stream *xdr, fattr4_open_arguments *ptr) > +{ > + return xdrgen_decode_open_arguments4(xdr, ptr); > +}; > + > +static bool __maybe_unused > +xdrgen_decode_fattr4_time_deleg_access(struct xdr_stream *xdr, fattr4_time_deleg_access *ptr) > +{ > + return xdrgen_decode_nfstime4(xdr, ptr); > +}; > + > +static bool __maybe_unused > +xdrgen_decode_fattr4_time_deleg_modify(struct xdr_stream *xdr, fattr4_time_deleg_modify *ptr) > +{ > + return xdrgen_decode_nfstime4(xdr, ptr); > +}; > + > +static bool __maybe_unused > +xdrgen_encode_int64_t(struct xdr_stream *xdr, const int64_t value) > +{ > + return xdrgen_encode_hyper(xdr, value); > +}; > + > +static bool __maybe_unused > +xdrgen_encode_uint32_t(struct xdr_stream *xdr, const uint32_t value) > +{ > + return xdrgen_encode_unsigned_int(xdr, value); > +}; > + > +static bool __maybe_unused > +xdrgen_encode_bitmap4(struct xdr_stream *xdr, const bitmap4 value) > +{ > + if (xdr_stream_encode_u32(xdr, value.count) != XDR_UNIT) > + return false; > + for (u32 i = 0; i < value.count; i++) > + if (!xdrgen_encode_uint32_t(xdr, value.element[i])) > + return false; > + return true; > +}; > + > +static bool __maybe_unused > +xdrgen_encode_nfstime4(struct xdr_stream *xdr, const struct nfstime4 *value) > +{ > + if (!xdrgen_encode_int64_t(xdr, value->seconds)) > + return false; > + if (!xdrgen_encode_uint32_t(xdr, value->nseconds)) > + return false; > + return true; > +}; > + > +static bool __maybe_unused > +xdrgen_encode_fattr4_offline(struct xdr_stream *xdr, const fattr4_offline value) > +{ > + return xdrgen_encode_bool(xdr, value); > +}; > + > +static bool __maybe_unused > +xdrgen_encode_open_arguments4(struct xdr_stream *xdr, const struct open_arguments4 *value) > +{ > + if (!xdrgen_encode_bitmap4(xdr, value->oa_share_access)) > + return false; > + if (!xdrgen_encode_bitmap4(xdr, value->oa_share_deny)) > + return false; > + if (!xdrgen_encode_bitmap4(xdr, value->oa_share_access_want)) > + return false; > + if (!xdrgen_encode_bitmap4(xdr, value->oa_open_claim)) > + return false; > + if (!xdrgen_encode_bitmap4(xdr, value->oa_create_mode)) > + return false; > + return true; > +}; > + > +static bool __maybe_unused > +xdrgen_encode_open_args_share_access4(struct xdr_stream *xdr, enum open_args_share_access4 value) > +{ > + return xdr_stream_encode_u32(xdr, value) == XDR_UNIT; > +} > + > +static bool __maybe_unused > +xdrgen_encode_open_args_share_deny4(struct xdr_stream *xdr, enum open_args_share_deny4 value) > +{ > + return xdr_stream_encode_u32(xdr, value) == XDR_UNIT; > +} > + > +static bool __maybe_unused > +xdrgen_encode_open_args_share_access_want4(struct xdr_stream *xdr, enum open_args_share_access_want4 value) > +{ > + return xdr_stream_encode_u32(xdr, value) == XDR_UNIT; > +} > + > +static bool __maybe_unused > +xdrgen_encode_open_args_open_claim4(struct xdr_stream *xdr, enum open_args_open_claim4 value) > +{ > + return xdr_stream_encode_u32(xdr, value) == XDR_UNIT; > +} > + > +static bool __maybe_unused > +xdrgen_encode_open_args_createmode4(struct xdr_stream *xdr, enum open_args_createmode4 value) > +{ > + return xdr_stream_encode_u32(xdr, value) == XDR_UNIT; > +} > + > +bool > +xdrgen_encode_fattr4_open_arguments(struct xdr_stream *xdr, const fattr4_open_arguments value) > +{ > + return xdrgen_encode_open_arguments4(xdr, &value); > +}; > + > +static bool __maybe_unused > +xdrgen_encode_fattr4_time_deleg_access(struct xdr_stream *xdr, const fattr4_time_deleg_access value) > +{ > + return xdrgen_encode_nfstime4(xdr, &value); > +}; > + > +static bool __maybe_unused > +xdrgen_encode_fattr4_time_deleg_modify(struct xdr_stream *xdr, const fattr4_time_deleg_modify value) > +{ > + return xdrgen_encode_nfstime4(xdr, &value); > +}; > diff --git a/fs/nfsd/nfs4xdr_gen.h b/fs/nfsd/nfs4xdr_gen.h > new file mode 100644 > index 000000000000..27c601b36580 > --- /dev/null > +++ b/fs/nfsd/nfs4xdr_gen.h > @@ -0,0 +1,113 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* Generated by xdrgen. Manual edits will be lost. */ > +/* XDR specification modification time: Mon Aug 19 23:28:23 2024 */ > + > +#ifndef _LINUX_NFS4_XDRGEN_H > +#define _LINUX_NFS4_XDRGEN_H > + > +#include <linux/types.h> > +#include <linux/sunrpc/svc.h> > + > +#include <linux/sunrpc/xdrgen-builtins.h> > + > +typedef s64 int64_t; > + > +typedef u32 uint32_t; > + > +typedef struct { > + u32 count; > + uint32_t *element; > +} bitmap4; > + > +struct nfstime4 { > + int64_t seconds; > + uint32_t nseconds; > +}; > + > +typedef bool fattr4_offline; > + > +enum { > + FATTR4_OFFLINE = 83 > +}; > + > +struct open_arguments4 { > + bitmap4 oa_share_access; > + bitmap4 oa_share_deny; > + bitmap4 oa_share_access_want; > + bitmap4 oa_open_claim; > + bitmap4 oa_create_mode; > +}; > + > +enum open_args_share_access4 { > + OPEN_ARGS_SHARE_ACCESS_READ = 1, > + OPEN_ARGS_SHARE_ACCESS_WRITE = 2, > + OPEN_ARGS_SHARE_ACCESS_BOTH = 3, > +}; > + > +enum open_args_share_deny4 { > + OPEN_ARGS_SHARE_DENY_NONE = 0, > + OPEN_ARGS_SHARE_DENY_READ = 1, > + OPEN_ARGS_SHARE_DENY_WRITE = 2, > + OPEN_ARGS_SHARE_DENY_BOTH = 3, > +}; > + > +enum open_args_share_access_want4 { > + OPEN_ARGS_SHARE_ACCESS_WANT_ANY_DELEG = 3, > + OPEN_ARGS_SHARE_ACCESS_WANT_NO_DELEG = 4, > + OPEN_ARGS_SHARE_ACCESS_WANT_CANCEL = 5, > + OPEN_ARGS_SHARE_ACCESS_WANT_SIGNAL_DELEG_WHEN_RESRC_AVAIL = 17, > + OPEN_ARGS_SHARE_ACCESS_WANT_PUSH_DELEG_WHEN_UNCONTENDED = 18, > + OPEN_ARGS_SHARE_ACCESS_WANT_DELEG_TIMESTAMPS = 20, > + OPEN_ARGS_SHARE_ACCESS_WANT_OPEN_XOR_DELEGATION = 21, > +}; > + > +enum open_args_open_claim4 { > + OPEN_ARGS_OPEN_CLAIM_NULL = 0, > + OPEN_ARGS_OPEN_CLAIM_PREVIOUS = 1, > + OPEN_ARGS_OPEN_CLAIM_DELEGATE_CUR = 2, > + OPEN_ARGS_OPEN_CLAIM_DELEGATE_PREV = 3, > + OPEN_ARGS_OPEN_CLAIM_FH = 4, > + OPEN_ARGS_OPEN_CLAIM_DELEG_CUR_FH = 5, > + OPEN_ARGS_OPEN_CLAIM_DELEG_PREV_FH = 6, > +}; > + > +enum open_args_createmode4 { > + OPEN_ARGS_CREATEMODE_UNCHECKED4 = 0, > + OPEN_ARGS_CREATE_MODE_GUARDED = 1, > + OPEN_ARGS_CREATEMODE_EXCLUSIVE4 = 2, > + OPEN_ARGS_CREATE_MODE_EXCLUSIVE4_1 = 3, > +}; > + > +typedef struct open_arguments4 fattr4_open_arguments; > +bool xdrgen_decode_fattr4_open_arguments(struct xdr_stream *xdr, fattr4_open_arguments *ptr); > +bool xdrgen_encode_fattr4_open_arguments(struct xdr_stream *xdr, const fattr4_open_arguments value); > + > +enum { > + FATTR4_OPEN_ARGUMENTS = 86 > +}; > + > +enum { > + OPEN4_SHARE_ACCESS_WANT_OPEN_XOR_DELEGATION = 0x200000 > +}; > + > +enum { > + OPEN4_RESULT_NO_OPEN_STATEID = 0x00000010 > +}; > + > +typedef struct nfstime4 fattr4_time_deleg_access; > + > +typedef struct nfstime4 fattr4_time_deleg_modify; > + > +enum { > + FATTR4_TIME_DELEG_ACCESS = 84 > +}; > + > +enum { > + FATTR4_TIME_DELEG_MODIFY = 85 > +}; > + > +enum { > + OPEN4_SHARE_ACCESS_WANT_DELEG_TIMESTAMPS = 0x100000 > +}; > + > +#endif /* _LINUX_NFS4_XDRGEN_H */ -- Jeff Layton <jlayton@xxxxxxxxxx>