diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index e18f6efbeb95..6921504acc29 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -6133,7 +6133,22 @@ static bool nfsd4_cb_channel_good(struct nfs4_client *clp) return clp->cl_minorversion && clp->cl_cb_state == NFSD4_CB_UNKNOWN; } -static struct file_lease *nfs4_alloc_init_lease(struct nfs4_delegation *dp) +static unsigned int +nfsd_notify_to_ignore(u32 notify) +{ + unsigned int mask = 0; + + if (notify & BIT(NOTIFY4_REMOVE_ENTRY)) + mask |= FL_IGN_DIR_DELETE; + if (notify & BIT(NOTIFY4_ADD_ENTRY)) + mask |= FL_IGN_DIR_CREATE; + if (notify & BIT(NOTIFY4_RENAME_ENTRY)) + mask |= FL_IGN_DIR_RENAME; + + return mask; +} + +static struct file_lease *nfs4_alloc_init_lease(struct nfs4_delegation *dp, u32 notify) { struct file_lease *fl; @@ -6141,7 +6156,7 @@ static struct file_lease *nfs4_alloc_init_lease(struct nfs4_delegation *dp) if (!fl) return NULL; fl->fl_lmops = &nfsd_lease_mng_ops; - fl->c.flc_flags = FL_DELEG; + fl->c.flc_flags = FL_DELEG | nfsd_notify_to_ignore(notify); fl->c.flc_type = deleg_is_read(dp->dl_type) ? F_RDLCK : F_WRLCK; fl->c.flc_owner = (fl_owner_t)dp; fl->c.flc_pid = current->tgid; @@ -6358,7 +6373,7 @@ nfs4_set_delegation(struct nfsd4_open *open, struct nfs4_ol_stateid *stp, if (stp->st_stid.sc_export) dp->dl_stid.sc_export = exp_get(stp->st_stid.sc_export); - fl = nfs4_alloc_init_lease(dp); + fl = nfs4_alloc_init_lease(dp, 0); if (!fl) goto out_clnt_odstate; @@ -9793,7 +9808,11 @@ nfsd_get_dir_deleg(struct nfsd4_compound_state *cstate, dp->dl_stid.sc_export = exp_get(cstate->current_fh.fh_export); - fl = nfs4_alloc_init_lease(dp); + /* + * NB: gddr_notification[0] represents the notifications that + * will be granted to the client + */ + fl = nfs4_alloc_init_lease(dp, gdd->gddr_notification[0]); if (!fl) goto out_put_stid;