When requesting a directory lease, enable the FL_IGN_DIR_* bits that correspond to the requested notification types. Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx> --- fs/nfsd/nfs4proc.c | 3 +++ fs/nfsd/nfs4state.c | 27 +++++++++++++++++++++------ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index fa6f2980bcacd798c41387c71d55a59fdbc8043c..77b6d0363b9f4cfea96f3f1abd3e462fd2a77754 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -2292,6 +2292,8 @@ 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) + static __be32 nfsd4_get_dir_delegation(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, @@ -2330,6 +2332,7 @@ nfsd4_get_dir_delegation(struct svc_rqst *rqstp, gdd->gddrnf_status = GDD4_OK; memcpy(&gdd->gddr_stateid, &dd->dl_stid.sc_stateid, sizeof(gdd->gddr_stateid)); + gdd->gddr_notification[0] = gdd->gdda_notification_types[0] & SUPPORTED_NOTIFY_MASK; nfs4_put_stid(&dd->dl_stid); return nfs_ok; } diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 35b9e35f8b507cc9b3924fead3037433cd8f9371..a75179ffa6006868bae3931263830d7b7e1a8882 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -6075,14 +6075,14 @@ 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 struct file_lease *nfs4_alloc_init_lease(struct nfs4_delegation *dp, unsigned int ignore) { struct file_lease *fl; fl = locks_alloc_lease(); if (!fl) return NULL; - fl->c.flc_flags = FL_DELEG; + fl->c.flc_flags = FL_DELEG | ignore; 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; @@ -6299,7 +6299,7 @@ nfs4_set_delegation(struct nfsd4_open *open, struct nfs4_ol_stateid *stp, if (!dp) goto out_delegees; - fl = nfs4_alloc_init_lease(dp); + fl = nfs4_alloc_init_lease(dp, 0); if (!fl) goto out_clnt_odstate; @@ -9523,6 +9523,21 @@ nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp, struct dentry *dentry, return status; } +static unsigned int +nfsd_notify_to_ignore_mask(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; +} + /** * nfsd_get_dir_deleg - attempt to get a directory delegation * @cstate: compound state @@ -9569,12 +9584,12 @@ nfsd_get_dir_deleg(struct nfsd4_compound_state *cstate, if (!dp) goto out_delegees; - fl = nfs4_alloc_init_lease(dp); + fl = nfs4_alloc_init_lease(dp, + nfsd_notify_to_ignore_mask(gdd->gdda_notification_types[0])); if (!fl) goto out_put_stid; - status = kernel_setlease(nf->nf_file, - fl->c.flc_type, &fl, NULL); + status = kernel_setlease(nf->nf_file, fl->c.flc_type, &fl, NULL); if (fl) locks_free_lease(fl); if (status) -- 2.49.0