diff mbox series

[RFC,2/2] NFSD: Create an initial nfs4_1.x file

Message ID 20240820144600.189744-3-cel@kernel.org (mailing list archive)
State New
Headers show
Series xdrgen - machine-generated XDR functions | expand

Commit Message

Chuck Lever Aug. 20, 2024, 2:46 p.m. UTC
From: Chuck Lever <chuck.lever@oracle.com>

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@oracle.com>
---
 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

Comments

Jeff Layton Aug. 21, 2024, 2:22 p.m. UTC | #1
On Tue, 2024-08-20 at 10:46 -0400, cel@kernel.org wrote:
> From: Chuck Lever <chuck.lever@oracle.com>
> 
> 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@oracle.com>
> ---
>  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 */
Chuck Lever III Aug. 21, 2024, 2:38 p.m. UTC | #2
On Wed, Aug 21, 2024 at 10:22:15AM -0400, Jeff Layton wrote:
> On Tue, 2024-08-20 at 10:46 -0400, cel@kernel.org wrote:
> > From: Chuck Lever <chuck.lever@oracle.com>
> > 
> > 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@oracle.com>
> > ---
> >  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.

That header is shared with the client, so I consider it immutable
for our purposes here.

One option would be to namespace the generated data items. Eg, name
them:

	XG_FATTR4_TIME_DELEG_ACCESS
	XG_FATTR4_TIME_DELEG_MODIFY

That way they don't conflict with existing definitions.


> 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).

The decoders are passed structs by reference already, fwiw. I had
been considering the same for the encoder functions, for efficiency.
I can give it a try.
Christoph Hellwig Aug. 21, 2024, 3 p.m. UTC | #3
On Wed, Aug 21, 2024 at 10:22:15AM -0400, Jeff Layton wrote:
> I'm not sure of the best way to work around this, unless we want to try
> to split up nfs4.h.

Can we just replace the structure definitions with the generated ones
ASAP in one big patch?  And then only do the marshalling code piece by
piece as needed/wanted?

> 
> 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).

Yes.  Probably marked const to clarify that it isn't supposed to be
modified.
Jeff Layton Aug. 21, 2024, 3:59 p.m. UTC | #4
On Wed, 2024-08-21 at 08:00 -0700, Christoph Hellwig wrote:
> On Wed, Aug 21, 2024 at 10:22:15AM -0400, Jeff Layton wrote:
> > I'm not sure of the best way to work around this, unless we want to
> > try
> > to split up nfs4.h.
> 
> Can we just replace the structure definitions with the generated ones
> ASAP in one big patch?  And then only do the marshalling code piece
> by
> piece as needed/wanted?
> 

I'll have a look. That probably means that we'll need to split nfs4.h,
as not everything in there is defined by the protocol headers.

> > 
> > 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).
> 
> Yes.  Probably marked const to clarify that it isn't supposed to be
> modified.
> 
> 

Definitely, on the encoding side. Obviously, we can't on the decoding
side.
Jeff Layton Aug. 21, 2024, 4:51 p.m. UTC | #5
On Wed, 2024-08-21 at 10:38 -0400, Chuck Lever wrote:
> On Wed, Aug 21, 2024 at 10:22:15AM -0400, Jeff Layton wrote:
> > On Tue, 2024-08-20 at 10:46 -0400, cel@kernel.org wrote:
> > > From: Chuck Lever <chuck.lever@oracle.com>
> > > 
> > > 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@oracle.com>
> > > ---
> > >  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.
> 
> That header is shared with the client, so I consider it immutable
> for our purposes here.
> 
>
> One option would be to namespace the generated data items. Eg, name
> them:
> 
> 	XG_FATTR4_TIME_DELEG_ACCESS
> 	XG_FATTR4_TIME_DELEG_MODIFY
> 
> That way they don't conflict with existing definitions.
> 

I'd rather avoid that if we can. Having things named exactly the same
as in the spec makes the code easier to read and understand.

What might be best is to autogenerate a header from a (combined)
nfs4.x, and then have the old nfs4.h file include it. Then we'd just
have to eliminate anything from nfs4.h that conflicts with the
autogenerated symbols.

That's definitely not treating include/linux/nfs4.h as immutable, but
we might still be able to avoid a lot of changes to the client code
that way.

We'd need Trond and Anna to buy in on that though.

> 
> > 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).
> 
> The decoders are passed structs by reference already, fwiw. I had
> been considering the same for the encoder functions, for efficiency.
> I can give it a try.
> 

Sounds good.
Chuck Lever III Aug. 21, 2024, 5:03 p.m. UTC | #6
On Wed, Aug 21, 2024 at 12:51:51PM -0400, Jeff Layton wrote:
> On Wed, 2024-08-21 at 10:38 -0400, Chuck Lever wrote:
> > On Wed, Aug 21, 2024 at 10:22:15AM -0400, Jeff Layton wrote:
> > > On Tue, 2024-08-20 at 10:46 -0400, cel@kernel.org wrote:
> > > > From: Chuck Lever <chuck.lever@oracle.com>
> > > > 
> > > > 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@oracle.com>
> > > > ---
> > > >  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.
> > 
> > That header is shared with the client, so I consider it immutable
> > for our purposes here.
> > 
> >
> > One option would be to namespace the generated data items. Eg, name
> > them:
> > 
> > 	XG_FATTR4_TIME_DELEG_ACCESS
> > 	XG_FATTR4_TIME_DELEG_MODIFY
> > 
> > That way they don't conflict with existing definitions.
> > 
> 
> I'd rather avoid that if we can. Having things named exactly the same
> as in the spec makes the code easier to read and understand.

Agreed, matching names is one of the reasons I started this work.

My thought was that the prefixed names could be fixed eventually
after the hand-rolled code has been replaced.


> What might be best is to autogenerate a header from a (combined)
> nfs4.x, and then have the old nfs4.h file include it. Then we'd just
> have to eliminate anything from nfs4.h that conflicts with the
> autogenerated symbols.
> 
> That's definitely not treating include/linux/nfs4.h as immutable, but
> we might still be able to avoid a lot of changes to the client code
> that way.

Include the current nfs4xdr_gen.h in nfs4.h, and then remove from
nfs4.h anything that has a naming conflict?

The downside of that is that approach mixes generated and
hand-rolled code. Not an objection from me, but it was something
that made Neil uncomfortable.


> We'd need Trond and Anna to buy in on that though.

Or the client can continue to use include/linux/nfs4.h and the
server can start using its own copy of that header.
Jeff Layton Aug. 21, 2024, 5:34 p.m. UTC | #7
On Wed, 2024-08-21 at 13:03 -0400, Chuck Lever wrote:
> On Wed, Aug 21, 2024 at 12:51:51PM -0400, Jeff Layton wrote:
> > On Wed, 2024-08-21 at 10:38 -0400, Chuck Lever wrote:
> > > On Wed, Aug 21, 2024 at 10:22:15AM -0400, Jeff Layton wrote:
> > > > On Tue, 2024-08-20 at 10:46 -0400, cel@kernel.org wrote:
> > > > > From: Chuck Lever <chuck.lever@oracle.com>
> > > > > 
> > > > > 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@oracle.com>
> > > > > ---
> > > > >  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.
> > > 
> > > That header is shared with the client, so I consider it immutable
> > > for our purposes here.
> > > 
> > > 
> > > One option would be to namespace the generated data items. Eg,
> > > name
> > > them:
> > > 
> > > 	XG_FATTR4_TIME_DELEG_ACCESS
> > > 	XG_FATTR4_TIME_DELEG_MODIFY
> > > 
> > > That way they don't conflict with existing definitions.
> > > 
> > 
> > I'd rather avoid that if we can. Having things named exactly the
> > same
> > as in the spec makes the code easier to read and understand.
> 
> Agreed, matching names is one of the reasons I started this work.
> 
> My thought was that the prefixed names could be fixed eventually
> after the hand-rolled code has been replaced.
> 
> 
> > What might be best is to autogenerate a header from a (combined)
> > nfs4.x, and then have the old nfs4.h file include it. Then we'd
> > just
> > have to eliminate anything from nfs4.h that conflicts with the
> > autogenerated symbols.
> > 
> > That's definitely not treating include/linux/nfs4.h as immutable,
> > but
> > we might still be able to avoid a lot of changes to the client code
> > that way.
> 
> Include the current nfs4xdr_gen.h in nfs4.h, and then remove from
> nfs4.h anything that has a naming conflict?
> 
> The downside of that is that approach mixes generated and
> hand-rolled code. Not an objection from me, but it was something
> that made Neil uncomfortable.
> 

Not exactly. The hand-rolled code would become dependent on the
generated headers, but we shouldn't need make changes to the generated
headers themselves.

> 
> > We'd need Trond and Anna to buy in on that though.
> 
> Or the client can continue to use include/linux/nfs4.h and the
> server can start using its own copy of that header.
> 

Sure, that would work too.
Chuck Lever III Aug. 21, 2024, 7:03 p.m. UTC | #8
On Wed, Aug 21, 2024 at 10:22:15AM -0400, Jeff Layton wrote:
> 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).

Meh. xdrgen already generates pass-by-reference encoders for
structs. The problem is actually this bit of nfs4_1.x:

   typedef open_arguments4 fattr4_open_arguments;

which generates:

bool
xdrgen_encode_fattr4_open_arguments(struct xdr_stream *xdr, const fattr4_open_arguments value)
{
        return xdrgen_encode_open_arguments4(xdr, &value);
};

So, it's a bug in the way that xdrgen handles /typedefs/ of structs,
not in the way that it handles the structs themselves.
Chuck Lever III Aug. 21, 2024, 9:14 p.m. UTC | #9
On Wed, Aug 21, 2024 at 03:03:33PM -0400, Chuck Lever wrote:
> On Wed, Aug 21, 2024 at 10:22:15AM -0400, Jeff Layton wrote:
> > 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).
> 
> Meh. xdrgen already generates pass-by-reference encoders for
> structs. The problem is actually this bit of nfs4_1.x:
> 
>    typedef open_arguments4 fattr4_open_arguments;
> 
> which generates:
> 
> bool
> xdrgen_encode_fattr4_open_arguments(struct xdr_stream *xdr, const fattr4_open_arguments value)
> {
>         return xdrgen_encode_open_arguments4(xdr, &value);
> };
> 
> So, it's a bug in the way that xdrgen handles /typedefs/ of structs,
> not in the way that it handles the structs themselves.

I've addressed this in the lkxdrgen branch on kernel.org. I'm sure
there are still bugs ;-)
Jeff Layton Aug. 22, 2024, 4:34 p.m. UTC | #10
On Tue, 2024-08-20 at 10:46 -0400, cel@kernel.org wrote:
> From: Chuck Lever <chuck.lever@oracle.com>
> 
> 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@oracle.com>
> ---
>  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?

> 
> +
> +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 */
Chuck Lever III Aug. 22, 2024, 5:47 p.m. UTC | #11
> On Aug 22, 2024, at 12:34 PM, Jeff Layton <jlayton@kernel.org> wrote:
> 
> On Tue, 2024-08-20 at 10:46 -0400, cel@kernel.org wrote:
>> From: Chuck Lever <chuck.lever@oracle.com>
>> 
>> 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@oracle.com>
>> ---
>> 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@poochiereds.net>
> 
> -- 
> Jeff Layton <jlayton@kernel.org>


--
Chuck Lever
diff mbox series

Patch

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 */