Re: [PATCH v6 19/20] nfsd: track requested dir attributes

From: Chuck Lever

Date: Fri Jun 12 2026 - 14:22:21 EST




On Thu, Jun 11, 2026, at 1:50 PM, Jeff Layton wrote:
> Track the union of requested and supported dir attributes in the
> delegation. In a later patch this will be used to ensure that we
> only encode the attributes in that union when sending
> add/remove/rename updates.
>
> Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx>
> ---
> fs/nfsd/nfs4proc.c | 9 ++++++---
> fs/nfsd/nfs4state.c | 20 ++++++++++++++++----
> fs/nfsd/state.h | 2 ++
> 3 files changed, 24 insertions(+), 7 deletions(-)
>
> diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
> index caec82e77081..9e86f5907f06 100644
> --- a/fs/nfsd/nfs4proc.c
> +++ b/fs/nfsd/nfs4proc.c
> @@ -2530,9 +2530,10 @@ nfsd4_verify(struct svc_rqst *rqstp, struct
> nfsd4_compound_state *cstate,
> return status == nfserr_same ? nfs_ok : status;
> }
>
> -#define SUPPORTED_NOTIFY_MASK (BIT(NOTIFY4_REMOVE_ENTRY) | \
> - BIT(NOTIFY4_ADD_ENTRY) | \
> - BIT(NOTIFY4_RENAME_ENTRY) | \
> +#define SUPPORTED_NOTIFY_MASK (BIT(NOTIFY4_CHANGE_DIR_ATTRS) | \
> + BIT(NOTIFY4_REMOVE_ENTRY) | \
> + BIT(NOTIFY4_ADD_ENTRY) | \
> + BIT(NOTIFY4_RENAME_ENTRY) | \
> BIT(NOTIFY4_GFLAG_EXTEND))
>
> static __be32
> @@ -2579,6 +2580,8 @@ nfsd4_get_dir_delegation(struct svc_rqst *rqstp,
> memcpy(&gdd->gddr_stateid, &dd->dl_stid.sc_stateid,
> sizeof(gdd->gddr_stateid));
> gdd->gddr_child_attributes[0] = dd->dl_child_attrs[0];
> gdd->gddr_child_attributes[1] = dd->dl_child_attrs[1];
> + gdd->gddr_dir_attributes[0] = dd->dl_dir_attrs[0];
> + gdd->gddr_dir_attributes[1] = dd->dl_dir_attrs[1];
> nfs4_put_stid(&dd->dl_stid);
> return nfs_ok;
> }
> diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
> index 0e6e008c121e..12627afb604f 100644
> --- a/fs/nfsd/nfs4state.c
> +++ b/fs/nfsd/nfs4state.c
> @@ -9945,6 +9945,15 @@ nfsd4_deleg_getattr_conflict(struct svc_rqst
> *rqstp, struct dentry *dentry,
> FATTR4_WORD1_TIME_MODIFY | \
> FATTR4_WORD1_TIME_CREATE)
>
> +#define GDD_WORD0_DIR_ATTRS (FATTR4_WORD0_CHANGE | \
> + FATTR4_WORD0_SIZE)
> +
> +#define GDD_WORD1_DIR_ATTRS (FATTR4_WORD1_NUMLINKS | \
> + FATTR4_WORD1_SPACE_USED | \
> + FATTR4_WORD1_TIME_ACCESS | \
> + FATTR4_WORD1_TIME_METADATA | \
> + FATTR4_WORD1_TIME_MODIFY)
> +
> /**
> * nfsd_get_dir_deleg - attempt to get a directory delegation
> * @cstate: compound state
> @@ -10013,14 +10022,17 @@ nfsd_get_dir_deleg(struct
> nfsd4_compound_state *cstate,
> dp->dl_stid.sc_export =
> exp_get(cstate->current_fh.fh_export);
>
> - dp->dl_child_attrs[0] = gdd->gdda_child_attributes[0] & GDD_WORD0_CHILD_ATTRS;
> - dp->dl_child_attrs[1] = gdd->gdda_child_attributes[1] & GDD_WORD1_CHILD_ATTRS;
> -
> /*
> * NB: gddr_notification[0] represents the notifications that
> * will be granted to the client
> */
> - fl = nfs4_alloc_init_lease(dp, gdd->gddr_notification[0]);
> + dp->dl_notify_mask = gdd->gddr_notification[0];
> + dp->dl_child_attrs[0] = gdd->gdda_child_attributes[0] & GDD_WORD0_CHILD_ATTRS;
> + dp->dl_child_attrs[1] = gdd->gdda_child_attributes[1] & GDD_WORD1_CHILD_ATTRS;
> + dp->dl_dir_attrs[0] = gdd->gdda_dir_attributes[0] & GDD_WORD0_DIR_ATTRS;
> + dp->dl_dir_attrs[1] = gdd->gdda_dir_attributes[1] & GDD_WORD1_DIR_ATTRS;
> +
> + fl = nfs4_alloc_init_lease(dp, dp->dl_notify_mask);
> if (!fl)
> goto out_put_stid;
>
> diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
> index 0763893bfd48..17be4011740d 100644
> --- a/fs/nfsd/state.h
> +++ b/fs/nfsd/state.h
> @@ -299,7 +299,9 @@ struct nfs4_delegation {
> struct timespec64 dl_ctime;
>
> /* For dir delegations */
> + uint32_t dl_notify_mask;
> uint32_t dl_child_attrs[2];
> + uint32_t dl_dir_attrs[2];

Nit: Maybe these should be u32. uint32_t is a user space type.


> };
>
> static inline bool deleg_is_read(u32 dl_type)
>

Bisectability: After this patch is applied, a client that requests
NOTIFY4_CHANGE_DIR_ATTRS now gets that bit echoed in gddr_notification,
but the callback path still only maps/encodes add, remove, and rename
notifications (nfsd_notify_to_ignore(), nfsd_fsnotify_recalc_mask(),
and nfsd4_encode_notify_event() have no dir-attr case). That lets the
server grant a directory delegation while promising dir-attribute
CB_NOTIFYs it cannot send until the follow-up support lands, so this
bit should not be advertised in this patch.


--
Chuck Lever