mirror of
https://github.com/torvalds/linux.git
synced 2026-09-24 06:24:02 +02:00
nfsd: apply the notify mask to the delegation when requested
If the client requests a directory delegation with notifications enabled, set the appropriate return mask in gddr_notification[0]. This will ensure the lease acquisition sets the appropriate ignore mask. Also store the granted mask in the delegation's dl_notify_mask field, so that the CB_NOTIFY encoder can later tell which notifications the client was granted. If the client doesn't set NOTIFY4_GFLAG_EXTEND, then don't offer any notifications, as nfsd won't provide directory offset information, and "classic" notifications require them. Similarly, if the client sets GFLAG_EXTEND | CFLAG_ORDER, then zero out the notification mask. The Linux server can't provide the necessary ordering info to those clients. Signed-off-by: Jeff Layton <jlayton@kernel.org> Link: https://patch.msgid.link/20260616-dir-deleg-v7-11-6cbc7eac0ade@kernel.org Signed-off-by: Chuck Lever <cel@kernel.org>
This commit is contained in:
parent
cb7444b27c
commit
53ba6518a6
|
|
@ -2552,12 +2552,18 @@ 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) | \
|
||||
BIT(NOTIFY4_GFLAG_EXTEND))
|
||||
|
||||
static __be32
|
||||
nfsd4_get_dir_delegation(struct svc_rqst *rqstp,
|
||||
struct nfsd4_compound_state *cstate,
|
||||
union nfsd4_op_u *u)
|
||||
{
|
||||
struct nfsd4_get_dir_delegation *gdd = &u->get_dir_delegation;
|
||||
u32 requested = gdd->gdda_notification_types[0];
|
||||
struct nfs4_delegation *dd;
|
||||
struct nfsd_file *nf;
|
||||
__be32 status;
|
||||
|
|
@ -2566,6 +2572,21 @@ nfsd4_get_dir_delegation(struct svc_rqst *rqstp,
|
|||
if (status != nfs_ok)
|
||||
return status;
|
||||
|
||||
/*
|
||||
* Offer no notifications to an order-aware client. RFC8881bis section
|
||||
* 16.2.13 defines order-aware as NOTIFY4_CFLAG_ORDER being set or
|
||||
* NOTIFY4_GFLAG_EXTEND being reset. Such a client expects cookie and
|
||||
* previous-entry information with its notifications (e.g. 27.4.5), and
|
||||
* nfsd does not track or emit directory offset information. Per
|
||||
* 16.2.11.3 the alternative would be to recall the delegation, so it's
|
||||
* simpler to just decline the notifications here.
|
||||
*/
|
||||
if (!(requested & BIT(NOTIFY4_GFLAG_EXTEND)) ||
|
||||
(requested & BIT(NOTIFY4_CFLAG_ORDER)))
|
||||
requested = 0;
|
||||
|
||||
gdd->gddr_notification[0] = requested & SUPPORTED_NOTIFY_MASK;
|
||||
|
||||
/*
|
||||
* RFC 8881, section 18.39.3 says:
|
||||
*
|
||||
|
|
|
|||
|
|
@ -10031,7 +10031,8 @@ nfsd_get_dir_deleg(struct nfsd4_compound_state *cstate,
|
|||
* 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];
|
||||
fl = nfs4_alloc_init_lease(dp, dp->dl_notify_mask);
|
||||
if (!fl)
|
||||
goto out_put_stid;
|
||||
|
||||
|
|
|
|||
|
|
@ -297,6 +297,9 @@ struct nfs4_delegation {
|
|||
struct timespec64 dl_atime;
|
||||
struct timespec64 dl_mtime;
|
||||
struct timespec64 dl_ctime;
|
||||
|
||||
/* For dir delegations */
|
||||
u32 dl_notify_mask;
|
||||
};
|
||||
|
||||
static inline bool deleg_is_read(u32 dl_type)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user