> On Aug 22, 2024, at 12:34 PM, Jeff Layton <jlayton@xxxxxxxxxx> wrote: > > 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 >> >> 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); >> > > Question: why does xdrgen generate the above prototype functions for > the encoder and decoder for that typedef, but no corresponding > prototypes for the nfstime4 ones below? Because I added a "pragma public" in the .x file for the fattr4_open_arguments type. You can add a "pragma public" for nfstime4 as well. Have a look in the README for examples. But I don't think you need one unless you have code that wants to call xdrgen_encode_nfstime4(). >> + >> +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@xxxxxxxxxxxxxxx> > > -- > Jeff Layton <jlayton@xxxxxxxxxx> -- Chuck Lever