From nobody Sun Jun 21 04:17:36 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EB5743B6C10; Tue, 7 Apr 2026 13:22:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568145; cv=none; b=YTvV9FduT78XeHDF2JtMwiEfZP/igrTTJQdb34Dh08U7IH9o8vyFf9i/jvE1pHMuimGUs1bZAoKFUnouZ9BpItMuQoRtNrRwhWgzqMwtaXJAJE5xCS9eocft34R7BegKv5fn4yQ1Mbmyd2wljkpGQtoj6Y1aQSrmvkBZQ866Dfw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568145; c=relaxed/simple; bh=4QeHfiTNd6hAM54W0DZtZMvv0guE9uRnMT2hpLvnyhE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=lISoA1101sWFOmUA4v4Ak+GqDSjjoxF2uim4sUGAW8kNwBuzWLWcSn9qQP7L21VQe4OuxZrNoVahkU78NwvDK4JVq/Mo7MXTKk8yeP9zU+ei9K00iV46rLmuZUlEtqnjlsJmDG5vMeEIujJVKSSS0nAShPtqiJIwBRUbRgOrtak= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=LH40D6Ld; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="LH40D6Ld" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6139BC2BCAF; Tue, 7 Apr 2026 13:22:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775568144; bh=4QeHfiTNd6hAM54W0DZtZMvv0guE9uRnMT2hpLvnyhE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=LH40D6LdTLQzkyUyw8yfKTYLHTFK9MSE5ONIEUECBF2rJWlNNc5IoVjq6tZm/zVKj Ht9ERE/m/jOreI3ZQRtr2ZQCm6BB2elgdCuDTL9dfQZvSGSSV2uOrGLHnRtd7VugNS yoblOkUHBGzbf/SA7odcrCwUotGtGHVUzwLnaqvGha4M9o76Zsc9vofxAQUFjAE5BR oh6Jg+/s10OIfrcts+v6d56L0GEfeyxkiDG/WIIQMQKfMvoRpwTWNU6AFJJMxT0qvK bukEeFhF2Fk5UFTQToIZfiFQZ+at9mZlv5cOnzGdrgudq3uLFed5drTgHfJDKzyOTR H8d7P4SX4zngg== From: Jeff Layton Date: Tue, 07 Apr 2026 09:21:14 -0400 Subject: [PATCH 01/24] filelock: add support for ignoring deleg breaks for dir change events Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260407-dir-deleg-v1-1-aaf68c478abd@kernel.org> References: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> In-Reply-To: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Amir Goldstein Cc: Calum Mackay , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=14110; i=jlayton@kernel.org; h=from:subject:message-id; bh=4QeHfiTNd6hAM54W0DZtZMvv0guE9uRnMT2hpLvnyhE=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp1QUD48Cxvy7hrSh3w51rn/Vnc0eTro7iKkmiu fNVL6xGV2mJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCadUFAwAKCRAADmhBGVaC FZ+1EACZWYczShZfj4YGPjRF/EhTJDIjvHhR8oN5kJiA6X/b9ri33OIEAiVze+1fEaSKpE95Lhm ooNhb42MqgCubes4FxaCVJ9nrdpDq+yI7XtR6M7KjeuqcKi7A+aspvdKJ4/2p8KMT+nAeHZFlUW 9D33/b2VI3tBc/0q0xM7aRB8YGH/VKWR+1CI9ahlU4lpdovuysj+CnLEBbE+OypxB0vcw+dD63o GE4NXS8X8VCT1CPzwAisKkpCKnPyX43A9ssrdkkiz7Xrk6KSv6VgeTXJMqaJz2BeuHzxOTCOGcO 4RkdoU2b0qQMzlaY9Qvoyk31Bjs6mjrs017p7LWgJ0QY4zT8WgGCnvqMIga27yLeCxaWAG4KtL2 dKzeQdyjRPWyz6hSgf5UOGwopNN+rjlBaOjJ5oJyRaj69eEAg8A/4KhTIzElyj9ZUxMJeKU7030 bJF8iuf66khFxh1Z4cgZXHOB6GxOueryOtgRxozKqWOrpblwXfwGknR3YS7pC9TZeyOIM8BBcvT HzPIOWt+P2+grUe/z7gbHSqnSgbg4AU54uJHfX5k6NZ3DODbPib2lpu0QaZmkqwKrRCsMtIdZkI SH1QDqDnoNxwWkye2giLnWMueKojs6nzgbzM1T/8YOfCd98DATsetpJW9v+E43VWkL/MsUbQv77 9zciZWJZJSIHjXg== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 If a NFS client requests a directory delegation with a notification bitmask covering directory change events, the server shouldn't recall the delegation. Instead the client will be notified of the change after the fact. Add support for ignoring lease breaks on directory changes. Add a new flags parameter to try_break_deleg() and teach __break_lease how to ignore certain types of delegation break events. Signed-off-by: Jeff Layton Reviewed-by: Jan Kara --- fs/attr.c | 2 +- fs/locks.c | 55 +++++++++++++++++++++++++++++++++++--= ---- fs/namei.c | 31 ++++++++++++----------- fs/posix_acl.c | 4 +-- fs/xattr.c | 4 +-- include/linux/filelock.h | 53 +++++++++++++++++++++++++++----------= -- include/trace/events/filelock.h | 5 +++- 7 files changed, 110 insertions(+), 44 deletions(-) diff --git a/fs/attr.c b/fs/attr.c index e7d7c6d19fe9..28744f0e9ff4 100644 --- a/fs/attr.c +++ b/fs/attr.c @@ -547,7 +547,7 @@ int notify_change(struct mnt_idmap *idmap, struct dentr= y *dentry, * breaking the delegation in this case. */ if (!(ia_valid & ATTR_DELEG)) { - error =3D try_break_deleg(inode, delegated_inode); + error =3D try_break_deleg(inode, 0, delegated_inode); if (error) return error; } diff --git a/fs/locks.c b/fs/locks.c index 8e44b1f6c15a..dafa0752fdce 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1597,15 +1597,52 @@ any_leases_conflict(struct inode *inode, struct fil= e_lease *breaker) return false; } =20 +static bool +ignore_dir_deleg_break(struct file_lease *fl, unsigned int flags) +{ + if ((flags & LEASE_BREAK_DIR_CREATE) && (fl->c.flc_flags & FL_IGN_DIR_CRE= ATE)) + return true; + if ((flags & LEASE_BREAK_DIR_DELETE) && (fl->c.flc_flags & FL_IGN_DIR_DEL= ETE)) + return true; + if ((flags & LEASE_BREAK_DIR_RENAME) && (fl->c.flc_flags & FL_IGN_DIR_REN= AME)) + return true; + + return false; +} + +static bool +visible_leases_remaining(struct inode *inode, unsigned int flags) +{ + struct file_lock_context *ctx =3D locks_inode_context(inode); + struct file_lease *fl; + + lockdep_assert_held(&ctx->flc_lock); + + if (list_empty(&ctx->flc_lease)) + return false; + + if (!S_ISDIR(inode->i_mode)) + return true; + + list_for_each_entry(fl, &ctx->flc_lease, c.flc_list) { + if (!ignore_dir_deleg_break(fl, flags)) + return true; + } + return false; +} + /** - * __break_lease - revoke all outstanding leases on file - * @inode: the inode of the file to return - * @flags: LEASE_BREAK_* flags + * __break_lease - revoke all outstanding leases on file + * @inode: the inode of the file to return + * @flags: LEASE_BREAK_* flags * - * break_lease (inlined for speed) has checked there already is at least - * some kind of lock (maybe a lease) on this file. Leases are broken on - * a call to open() or truncate(). This function can block waiting for the - * lease break unless you specify LEASE_BREAK_NONBLOCK. + * break_lease (inlined for speed) has checked there already is at least + * some kind of lock (maybe a lease) on this file. Leases and Delegations + * are broken on a call to open() or truncate(). Delegations are also + * broken on any event that would change the ctime. Directory delegations + * are broken whenever the directory changes (unless the delegation is set + * up to ignore the event). This function can block waiting for the lease + * break unless you specify LEASE_BREAK_NONBLOCK. */ int __break_lease(struct inode *inode, unsigned int flags) { @@ -1655,6 +1692,8 @@ int __break_lease(struct inode *inode, unsigned int f= lags) list_for_each_entry_safe(fl, tmp, &ctx->flc_lease, c.flc_list) { if (!leases_conflict(&fl->c, &new_fl->c)) continue; + if (S_ISDIR(inode->i_mode) && ignore_dir_deleg_break(fl, flags)) + continue; if (want_write) { if (fl->c.flc_flags & FL_UNLOCK_PENDING) continue; @@ -1670,7 +1709,7 @@ int __break_lease(struct inode *inode, unsigned int f= lags) locks_delete_lock_ctx(&fl->c, &dispose); } =20 - if (list_empty(&ctx->flc_lease)) + if (!visible_leases_remaining(inode, flags)) goto out; =20 if (flags & LEASE_BREAK_NONBLOCK) { diff --git a/fs/namei.c b/fs/namei.c index 9e5500dad14f..e3cbd9f877bd 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -4176,7 +4176,7 @@ int vfs_create(struct mnt_idmap *idmap, struct dentry= *dentry, umode_t mode, error =3D security_inode_create(dir, dentry, mode); if (error) return error; - error =3D try_break_deleg(dir, di); + error =3D try_break_deleg(dir, LEASE_BREAK_DIR_CREATE, di); if (error) return error; error =3D dir->i_op->create(idmap, dir, dentry, mode, true); @@ -4475,7 +4475,7 @@ static struct dentry *lookup_open(struct nameidata *n= d, struct file *file, /* Negative dentry, just create the file */ if (!dentry->d_inode && (open_flag & O_CREAT)) { /* but break the directory lease first! */ - error =3D try_break_deleg(dir_inode, delegated_inode); + error =3D try_break_deleg(dir_inode, LEASE_BREAK_DIR_CREATE, delegated_i= node); if (error) goto out_dput; =20 @@ -5091,7 +5091,7 @@ int vfs_mknod(struct mnt_idmap *idmap, struct inode *= dir, if (error) return error; =20 - error =3D try_break_deleg(dir, delegated_inode); + error =3D try_break_deleg(dir, LEASE_BREAK_DIR_CREATE, delegated_inode); if (error) return error; =20 @@ -5232,7 +5232,7 @@ struct dentry *vfs_mkdir(struct mnt_idmap *idmap, str= uct inode *dir, if (max_links && dir->i_nlink >=3D max_links) goto err; =20 - error =3D try_break_deleg(dir, delegated_inode); + error =3D try_break_deleg(dir, LEASE_BREAK_DIR_CREATE, delegated_inode); if (error) goto err; =20 @@ -5337,7 +5337,7 @@ int vfs_rmdir(struct mnt_idmap *idmap, struct inode *= dir, if (error) goto out; =20 - error =3D try_break_deleg(dir, delegated_inode); + error =3D try_break_deleg(dir, LEASE_BREAK_DIR_DELETE, delegated_inode); if (error) goto out; =20 @@ -5467,10 +5467,10 @@ int vfs_unlink(struct mnt_idmap *idmap, struct inod= e *dir, else { error =3D security_inode_unlink(dir, dentry); if (!error) { - error =3D try_break_deleg(dir, delegated_inode); + error =3D try_break_deleg(dir, LEASE_BREAK_DIR_DELETE, delegated_inode); if (error) goto out; - error =3D try_break_deleg(target, delegated_inode); + error =3D try_break_deleg(target, 0, delegated_inode); if (error) goto out; error =3D dir->i_op->unlink(dir, dentry); @@ -5614,7 +5614,7 @@ int vfs_symlink(struct mnt_idmap *idmap, struct inode= *dir, if (error) return error; =20 - error =3D try_break_deleg(dir, delegated_inode); + error =3D try_break_deleg(dir, LEASE_BREAK_DIR_CREATE, delegated_inode); if (error) return error; =20 @@ -5745,9 +5745,9 @@ int vfs_link(struct dentry *old_dentry, struct mnt_id= map *idmap, else if (max_links && inode->i_nlink >=3D max_links) error =3D -EMLINK; else { - error =3D try_break_deleg(dir, delegated_inode); + error =3D try_break_deleg(dir, LEASE_BREAK_DIR_CREATE, delegated_inode); if (!error) - error =3D try_break_deleg(inode, delegated_inode); + error =3D try_break_deleg(inode, 0, delegated_inode); if (!error) error =3D dir->i_op->link(old_dentry, dir, new_dentry); } @@ -6011,21 +6011,24 @@ int vfs_rename(struct renamedata *rd) old_dir->i_nlink >=3D max_links) goto out; } - error =3D try_break_deleg(old_dir, delegated_inode); + error =3D try_break_deleg(old_dir, + old_dir =3D=3D new_dir ? LEASE_BREAK_DIR_RENAME : + LEASE_BREAK_DIR_DELETE, + delegated_inode); if (error) goto out; if (new_dir !=3D old_dir) { - error =3D try_break_deleg(new_dir, delegated_inode); + error =3D try_break_deleg(new_dir, LEASE_BREAK_DIR_CREATE, delegated_ino= de); if (error) goto out; } if (!is_dir) { - error =3D try_break_deleg(source, delegated_inode); + error =3D try_break_deleg(source, 0, delegated_inode); if (error) goto out; } if (target && !new_is_dir) { - error =3D try_break_deleg(target, delegated_inode); + error =3D try_break_deleg(target, 0, delegated_inode); if (error) goto out; } diff --git a/fs/posix_acl.c b/fs/posix_acl.c index 12591c95c925..b4bfe4ddf64e 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -1126,7 +1126,7 @@ int vfs_set_acl(struct mnt_idmap *idmap, struct dentr= y *dentry, if (error) goto out_inode_unlock; =20 - error =3D try_break_deleg(inode, &delegated_inode); + error =3D try_break_deleg(inode, 0, &delegated_inode); if (error) goto out_inode_unlock; =20 @@ -1234,7 +1234,7 @@ int vfs_remove_acl(struct mnt_idmap *idmap, struct de= ntry *dentry, if (error) goto out_inode_unlock; =20 - error =3D try_break_deleg(inode, &delegated_inode); + error =3D try_break_deleg(inode, 0, &delegated_inode); if (error) goto out_inode_unlock; =20 diff --git a/fs/xattr.c b/fs/xattr.c index 3e49e612e1ba..6b67a6e76eeb 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -288,7 +288,7 @@ __vfs_setxattr_locked(struct mnt_idmap *idmap, struct d= entry *dentry, if (error) goto out; =20 - error =3D try_break_deleg(inode, delegated_inode); + error =3D try_break_deleg(inode, 0, delegated_inode); if (error) goto out; =20 @@ -546,7 +546,7 @@ __vfs_removexattr_locked(struct mnt_idmap *idmap, if (error) goto out; =20 - error =3D try_break_deleg(inode, delegated_inode); + error =3D try_break_deleg(inode, 0, delegated_inode); if (error) goto out; =20 diff --git a/include/linux/filelock.h b/include/linux/filelock.h index 5f0a2fb31450..5a19cdb047da 100644 --- a/include/linux/filelock.h +++ b/include/linux/filelock.h @@ -4,19 +4,22 @@ =20 #include =20 -#define FL_POSIX 1 -#define FL_FLOCK 2 -#define FL_DELEG 4 /* NFSv4 delegation */ -#define FL_ACCESS 8 /* not trying to lock, just looking */ -#define FL_EXISTS 16 /* when unlocking, test for existence */ -#define FL_LEASE 32 /* lease held on this file */ -#define FL_CLOSE 64 /* unlock on close */ -#define FL_SLEEP 128 /* A blocking lock */ -#define FL_DOWNGRADE_PENDING 256 /* Lease is being downgraded */ -#define FL_UNLOCK_PENDING 512 /* Lease is being broken */ -#define FL_OFDLCK 1024 /* lock is "owned" by struct file */ -#define FL_LAYOUT 2048 /* outstanding pNFS layout */ -#define FL_RECLAIM 4096 /* reclaiming from a reboot server */ +#define FL_POSIX BIT(0) /* POSIX lock */ +#define FL_FLOCK BIT(1) /* BSD lock */ +#define FL_LEASE BIT(2) /* file lease */ +#define FL_DELEG BIT(3) /* NFSv4 delegation */ +#define FL_LAYOUT BIT(4) /* outstanding pNFS layout */ +#define FL_ACCESS BIT(5) /* not trying to lock, just looking */ +#define FL_EXISTS BIT(6) /* when unlocking, test for existence */ +#define FL_CLOSE BIT(7) /* unlock on close */ +#define FL_SLEEP BIT(8) /* A blocking lock */ +#define FL_DOWNGRADE_PENDING BIT(9) /* Lease is being downgraded */ +#define FL_UNLOCK_PENDING BIT(10) /* Lease is being broken */ +#define FL_OFDLCK BIT(11) /* POSIX lock "owned" by struct file */ +#define FL_RECLAIM BIT(12) /* reclaiming from a reboot server */ +#define FL_IGN_DIR_CREATE BIT(13) /* ignore DIR_CREATE events */ +#define FL_IGN_DIR_DELETE BIT(14) /* ignore DIR_DELETE events */ +#define FL_IGN_DIR_RENAME BIT(15) /* ignore DIR_RENAME events */ =20 #define FL_CLOSE_POSIX (FL_POSIX | FL_CLOSE) =20 @@ -222,6 +225,10 @@ struct file_lease *locks_alloc_lease(void); #define LEASE_BREAK_LAYOUT BIT(2) // break layouts only #define LEASE_BREAK_NONBLOCK BIT(3) // non-blocking break #define LEASE_BREAK_OPEN_RDONLY BIT(4) // readonly open event +#define LEASE_BREAK_DIR_CREATE BIT(6) // dir deleg create event +#define LEASE_BREAK_DIR_DELETE BIT(7) // dir deleg delete event +#define LEASE_BREAK_DIR_RENAME BIT(8) // dir deleg rename event + =20 int __break_lease(struct inode *inode, unsigned int flags); void lease_get_mtime(struct inode *, struct timespec64 *time); @@ -516,12 +523,26 @@ static inline bool is_delegated(struct delegated_inod= e *di) return di->di_inode; } =20 -static inline int try_break_deleg(struct inode *inode, +/** + * try_break_deleg - do a non-blocking delegation break + * @inode: inode that should have its delegations broken + * @flags: extra LEASE_BREAK_* flags to pass to break_deleg() + * @di: returns pointer to delegated inode (may be NULL) + * + * Break delegations in a non-blocking fashion. If there are + * outstanding delegations and @di is set, then an extra reference + * will be taken on @inode and @di->di_inode will be populated so + * that it may be waited upon. + * + * Returns 0 if there is no need to wait or an error. If -EWOULDBLOCK + * is returned, then @di will be populated (if non-NULL). + */ +static inline int try_break_deleg(struct inode *inode, unsigned int flags, struct delegated_inode *di) { int ret; =20 - ret =3D break_deleg(inode, LEASE_BREAK_NONBLOCK); + ret =3D break_deleg(inode, flags | LEASE_BREAK_NONBLOCK); if (ret =3D=3D -EWOULDBLOCK && di) { di->di_inode =3D inode; ihold(inode); @@ -574,7 +595,7 @@ static inline int break_deleg(struct inode *inode, unsi= gned int flags) return 0; } =20 -static inline int try_break_deleg(struct inode *inode, +static inline int try_break_deleg(struct inode *inode, unsigned int flags, struct delegated_inode *delegated_inode) { return 0; diff --git a/include/trace/events/filelock.h b/include/trace/events/fileloc= k.h index 370016c38a5b..ef4bb0afb86a 100644 --- a/include/trace/events/filelock.h +++ b/include/trace/events/filelock.h @@ -28,7 +28,10 @@ { FL_DOWNGRADE_PENDING, "FL_DOWNGRADE_PENDING" }, \ { FL_UNLOCK_PENDING, "FL_UNLOCK_PENDING" }, \ { FL_OFDLCK, "FL_OFDLCK" }, \ - { FL_RECLAIM, "FL_RECLAIM"}) + { FL_RECLAIM, "FL_RECLAIM" }, \ + { FL_IGN_DIR_CREATE, "FL_IGN_DIR_CREATE" }, \ + { FL_IGN_DIR_DELETE, "FL_IGN_DIR_DELETE" }, \ + { FL_IGN_DIR_RENAME, "FL_IGN_DIR_RENAME" }) =20 #define show_fl_type(val) \ __print_symbolic(val, \ --=20 2.53.0 From nobody Sun Jun 21 04:17:36 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 328CE3B774A; Tue, 7 Apr 2026 13:22:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568149; cv=none; b=RzyqYC5PUCreIR66n6Pj7hgBaaqfS4aMRMCnn20302Wl0SasjAJqUWsUlWQ+xW3bAhltHhYp1RaDt4+pZ+CenaLYp1VsJ6GYsQyQLrCH7a/7zu4dakYmKOVninQtOME0PkhNMIfeKw9tXzea8lv9ZeFAXWiLWUMTYUYPkOc4LT4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568149; c=relaxed/simple; bh=89SziWwM/FohwNGtd0INddyrZACS7OxAWEtzHYq9JF0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=JSPDHvvuIXjvCXOYRgCBXKZqvM3u0e59k7FxrDUkTvOWlb8R77MOy64VrJSR+nltRu9RwrlK1QWhKYPeFReHpa8R0fCaE88gygXblDLyZjo489aSdhxyXi9NwUQ2ZdM7wNtg16rOK6sT86ag9C/5+BBbPQpQrTjgEP2n5yZxmBk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=mt5cZ5+s; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="mt5cZ5+s" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C36A0C116C6; Tue, 7 Apr 2026 13:22:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775568146; bh=89SziWwM/FohwNGtd0INddyrZACS7OxAWEtzHYq9JF0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=mt5cZ5+sZ9gnYK7lz8RSkVdf8a4jNhv1uKTkp+t7rf2qvBxnQQKCnhquX/zrrKC0B s7JaTXk0QQSMNzaxyeRu23gGkMr6JLEyljkCnN+pX+sq5KxohNp3DWJCtFucjQKhfr 0oDrzykbur3yAPiJOKuzqt2nwgHiiRVtEVQ4U47QtX29YIg+Lo3YKFU+nWlYY7MV7b 1v7eyP9y1we23E+UsdsSKXums5bNhOSzBxlgc7h2TiD7JZBCOB6xFRjWoeO/zze++c AvhrTJrWPTpXU6FPKgXTj3h+KzxmZhlBlTY/8NVz0+L1iDoyVw4ibiCNCuif/lI7dO eX3trR0fscnfQ== From: Jeff Layton Date: Tue, 07 Apr 2026 09:21:15 -0400 Subject: [PATCH 02/24] filelock: add a tracepoint to start of break_lease() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260407-dir-deleg-v1-2-aaf68c478abd@kernel.org> References: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> In-Reply-To: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Amir Goldstein Cc: Calum Mackay , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=2122; i=jlayton@kernel.org; h=from:subject:message-id; bh=89SziWwM/FohwNGtd0INddyrZACS7OxAWEtzHYq9JF0=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp1QUD7iyMBq1mP3wPgmGDjbwr9A93+l1AzKJpZ 4PmXRCv5p6JAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCadUFAwAKCRAADmhBGVaC FcLQD/0Rc3WVDbMV0eDNFk3bz/P9dGF2SalFY46/r2PmSoDpyUIZPjHUXUCQlQBd5o9+pNVmNr4 EulSQJ+VUGCwqekueiUAoM6wccGc2IgW42bzIOmWPkCM7mBYUZMgMWoShyMXOqZYxYk3L0zm86h 405Tah93VgsAYAnircLpqIK0S/WxU7qMQ3MiBL+uIu35UBBAHaAYUwTWj/u6U7ZI+pFpQ2yCquD o+fnOlmqrmEtSwcfkxKVPsmzGIv4F8elJQ5vu/SlQL1gFIdijIwA46l6PZ798rwtSB/157pwjf+ x1+tHORBpOc7TkJFIzNFqNJksawEnAurxr9v/maV62oNAfOIIiEQSMa9Uvk3mJV3ks5Qk5oJ2j2 MKeMdkY9mEYA614r01MIBd57KLwxWkW004S4rCFCinEjOYP+7zLWbkvXVKRIWEU9lNb+VMYpQH7 1VlZA2NnTSJK/SaFFKZP7lAiaSiF1l2+2teBjFENI4Cp5C+vQVPyMaHm/mIIdZFg0wlg6dSjnWB vUG6FunqLtO8wqz9bBbfHqbBIqv7Mw8tm0ejiyej49EvEAVgkgrbOi5NQpkvmNkV8WgQIjAf8NW Oi7EvOXhrnaQnKmSL2Iecl47ig05lZU/tpTSLm6BZJ4m4aswNBsMqt3mzL3FHY4t6t8XzJgdL4t J/AjY9s46/AHFcg== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 ...mostly to show the LEASE_BREAK_* flags. Signed-off-by: Jeff Layton Reviewed-by: Jan Kara --- fs/locks.c | 2 ++ include/trace/events/filelock.h | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/fs/locks.c b/fs/locks.c index dafa0752fdce..5af6dca2d46c 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1654,6 +1654,8 @@ int __break_lease(struct inode *inode, unsigned int f= lags) bool want_write =3D !(flags & LEASE_BREAK_OPEN_RDONLY); int error =3D 0; =20 + trace_break_lease(inode, flags); + if (flags & LEASE_BREAK_LEASE) type =3D FL_LEASE; else if (flags & LEASE_BREAK_DELEG) diff --git a/include/trace/events/filelock.h b/include/trace/events/fileloc= k.h index ef4bb0afb86a..fff0ee2d452d 100644 --- a/include/trace/events/filelock.h +++ b/include/trace/events/filelock.h @@ -120,6 +120,39 @@ DEFINE_EVENT(filelock_lock, flock_lock_inode, TP_PROTO(struct inode *inode, struct file_lock *fl, int ret), TP_ARGS(inode, fl, ret)); =20 +#define show_lease_break_flags(val) \ + __print_flags(val, "|", \ + { LEASE_BREAK_LEASE, "LEASE" }, \ + { LEASE_BREAK_DELEG, "DELEG" }, \ + { LEASE_BREAK_LAYOUT, "LAYOUT" }, \ + { LEASE_BREAK_NONBLOCK, "NONBLOCK" }, \ + { LEASE_BREAK_OPEN_RDONLY, "OPEN_RDONLY" }, \ + { LEASE_BREAK_DIR_CREATE, "DIR_CREATE" }, \ + { LEASE_BREAK_DIR_DELETE, "DIR_DELETE" }, \ + { LEASE_BREAK_DIR_RENAME, "DIR_RENAME" }) + +TRACE_EVENT(break_lease, + TP_PROTO(struct inode *inode, unsigned int flags), + + TP_ARGS(inode, flags), + + TP_STRUCT__entry( + __field(unsigned long, i_ino) + __field(dev_t, s_dev) + __field(unsigned int, flags) + ), + + TP_fast_assign( + __entry->s_dev =3D inode->i_sb->s_dev; + __entry->i_ino =3D inode->i_ino; + __entry->flags =3D flags; + ), + + TP_printk("dev=3D0x%x:0x%x ino=3D0x%lx flags=3D%s", + MAJOR(__entry->s_dev), MINOR(__entry->s_dev), + __entry->i_ino, show_lease_break_flags(__entry->flags)) +); + DECLARE_EVENT_CLASS(filelock_lease, TP_PROTO(struct inode *inode, struct file_lease *fl), =20 --=20 2.53.0 From nobody Sun Jun 21 04:17:36 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8B5383B7769; Tue, 7 Apr 2026 13:22:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568149; cv=none; b=B1ZU68T3CNW9zUOJ4w8jqcbM8LIzTiu6PA/wLgX4aZthbZGFAJuBuSzGG+ZK/NEpdVs46Ogl1wAcwCeJ0HWKGJa7p20wj463NiD4kC1KumO7hAmi0MrMV0dZ8Jh8gYq12lPrWTIdELoqmazKAJc9CIc6C1qvYKtnp8bS5tOrd7c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568149; c=relaxed/simple; bh=nkFmX2Mfye18XQtESCi4FsaKjk012eRExu5WCQ+gHRU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=eRXYYJ9iXOilQZKb9ZO6CWjrbQ0TTfY43EDfppppGoYypQVsxq2d1ZTJMsqjxiSz1TF/61ci0luzoGV6+teDvnocEIwYbS+bfyIrGg5MKvsDSHsT908/hcWILxA/gH/80TcyW2xe+h9Sto0+md8E+Q0t4yQq2Ie+fcRuWaPnc58= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=SnCqLrjt; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="SnCqLrjt" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1A986C19424; Tue, 7 Apr 2026 13:22:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775568149; bh=nkFmX2Mfye18XQtESCi4FsaKjk012eRExu5WCQ+gHRU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=SnCqLrjtqLfN8EF1DqSGWjgSK9lo1fF9paPunJa97pz+zY/VfBAwooK/wSZK/ITTA XPfZP6a2Ekh7lePlVXB8AK6zn0+qykQXsX8zJ5Guq31TddluO3dlSdhR+nXUtoIvNS DmqdkfFRQzGnAROY22HBvN7eC9weVKdoy9ZHYurUT7nchAV5Ng3IPKnAQUMbaE3JBE nbTvPEiCDmg/ToYGYPwFBJQ7vTfB8NvIcIuDQ2s8geYq6E5TzlzAOxQoFB9UC9id5W My7c58SsGJEnBXWErudMc4FTfxGn42TH0hKBOfVkkGgznDJa5hw9r4ePLKtoKIKLgh BmqO17+flNJqw== From: Jeff Layton Date: Tue, 07 Apr 2026 09:21:16 -0400 Subject: [PATCH 03/24] filelock: add an inode_lease_ignore_mask helper Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260407-dir-deleg-v1-3-aaf68c478abd@kernel.org> References: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> In-Reply-To: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Amir Goldstein Cc: Calum Mackay , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=2204; i=jlayton@kernel.org; h=from:subject:message-id; bh=nkFmX2Mfye18XQtESCi4FsaKjk012eRExu5WCQ+gHRU=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp1QUDcEeGmoDoT17X1wAV27PrpJ2DbRi1NKDkZ ejuNiNVCimJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCadUFAwAKCRAADmhBGVaC FQ1SEACNKYjjMZ+e0reHSlZVaYMPM7jlMUjKTfnAKnR+SxwbZKILPqaxAw562KwFBqaCECYOcDX AvW8tmTXKXy3fhe+y6KBQIeLvYMqCTH43NgQK5asE/jyT/GLlc07ugnSfY80iFHT+32hggoQyRO KpG0qdbec76VZp8wOTZJ8q8uRftzwbH/YQj+n9KShCNt0HJfNTNzAk6k9/I1X0gExGS+WQSYdWl A63QUizH4DRbs6iaUM4OF/91nGhhA+bDVwF/aI0WblwbHs0JKh/7FgANZ0B0nITz/EMKhO04B8K JWjr9C/WIDiAHXkasx35+tDVpp2eXA72UGOJIYC/TetN+7TpjN2tgHDCupcPbyl7fEomjmM04MN sFYEDSUpBi9x9tYXgNNV+XOC7AMo8si9/LLvY64lGOcOvQZFwtzvdcl14/NIwX7OSM4WTK6gCDs 5KDKTC0jOJxtELKoxZw+TlyaEEgvNU3LDSyworjBqVgFSMF48OID7CwY9ra5GUtd5KOO4gyHYkY yulrSFo7ijZEuhAXHKodB+eXF2Dh8zd70Aezs195FGiKCI3gdZvLQPSWphAkqJJJidop9eweJQt phw0XarLTwrxWY1QmOCjDzwUtKHvlPm6PGhZRA9thmo8s1J4Me6itdDTovYMaHyPvQzRq3V7ZJ3 blC+nOeqQS9SHGg== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Add a new routine that returns a mask of all dir change events that are currently ignored by any leases. nfsd will use this to determine how to configure the fsnotify_mark mask. Signed-off-by: Jeff Layton Reviewed-by: Jan Kara --- fs/locks.c | 32 ++++++++++++++++++++++++++++++++ include/linux/filelock.h | 1 + 2 files changed, 33 insertions(+) diff --git a/fs/locks.c b/fs/locks.c index 5af6dca2d46c..04980b065734 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1597,6 +1597,38 @@ any_leases_conflict(struct inode *inode, struct file= _lease *breaker) return false; } =20 +#define IGNORE_MASK (FL_IGN_DIR_CREATE | FL_IGN_DIR_DELETE | FL_IGN_DIR_RE= NAME) + +/** + * inode_lease_ignore_mask - return union of all ignored inode events for = this inode + * @inode: inode of which to get ignore mask + * + * Walk the list of leases, and return the result of all of + * their FL_IGN_DIR_* bits or'ed together. + */ +u32 +inode_lease_ignore_mask(struct inode *inode) +{ + struct file_lock_context *ctx; + struct file_lock_core *flc; + u32 mask =3D 0; + + ctx =3D locks_inode_context(inode); + if (!ctx) + return 0; + + spin_lock(&ctx->flc_lock); + list_for_each_entry(flc, &ctx->flc_lease, flc_list) { + mask |=3D flc->flc_flags & IGNORE_MASK; + /* If we already have everything, we can stop */ + if (mask =3D=3D IGNORE_MASK) + break; + } + spin_unlock(&ctx->flc_lock); + return mask; +} +EXPORT_SYMBOL_GPL(inode_lease_ignore_mask); + static bool ignore_dir_deleg_break(struct file_lease *fl, unsigned int flags) { diff --git a/include/linux/filelock.h b/include/linux/filelock.h index 5a19cdb047da..416483b136f1 100644 --- a/include/linux/filelock.h +++ b/include/linux/filelock.h @@ -236,6 +236,7 @@ int generic_setlease(struct file *, int, struct file_le= ase **, void **priv); int kernel_setlease(struct file *, int, struct file_lease **, void **); int vfs_setlease(struct file *, int, struct file_lease **, void **); int lease_modify(struct file_lease *, int, struct list_head *); +u32 inode_lease_ignore_mask(struct inode *inode); =20 struct notifier_block; int lease_register_notifier(struct notifier_block *); --=20 2.53.0 From nobody Sun Jun 21 04:17:36 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E35F63B7B84; Tue, 7 Apr 2026 13:22:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568154; cv=none; b=s+IioLUAiZxNVzbp3IkJSOl5/E96lTjkmBtS+nQOh4lFrzVRIXwrqSV06ieErQBdjURPQOG7IE+U7zACh9AaOVwKI4E8rhAbhqy57E0Wo/Z2ptRulnCk1hsUuIaEwMvU3uXDVvNcPITvIw1cvVTmWsLH5thC8jwS5vcqpcnnrBY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568154; c=relaxed/simple; bh=yyB0NiTzw/pw7iObyO6el/c+tMbeiirPHQNO4+B3GvQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=K22bQ0VnBQuL4QhOsLmmcCjpdrzOtQP8hPQTO4DDmavBzVlBC5JFu1Ju24cyP+LHJEkiV610UsmPxe2Z9LghiMgF7a53CrZjF0AJbN+ET9cQRNOQpTEh58naDMvSMcURtdBx1Iz6dG6D+xhW31OFdA3iru0ZieV79LfOtzWdPqc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=VFQNN9t6; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="VFQNN9t6" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 64AF0C116C6; Tue, 7 Apr 2026 13:22:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775568151; bh=yyB0NiTzw/pw7iObyO6el/c+tMbeiirPHQNO4+B3GvQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=VFQNN9t6LSXk4SxsTPooJZTHANTQrAcO+kUKX+wxOYAZrgg8JdyS38DkzCL9Sg29Y nx8xwL37gRxKKCFC3xQXIdakzUwLNvYqMWRlzezLPlPfEJ1dnMqB1pHxUTYou01voN 1MBy71v4kMFdu+pxi1lo0EH2wMD+w0UdkSx3KIJSp8+B3lVOdktYzuLjEvm0pwEQIK WyarwBPYNa5llPupdif1dWuhWUBHv3s9ZsHAD7m+fzE1Zl3eq3iKhEMV//WqZuhXm1 wvkQa+3x8w9bEwnMaZjD/Kd4eGw6L49x4pOr5zcz11puWPZat7ptdIKB1sra1Vx3zI hdo52JFmyN5hQ== From: Jeff Layton Date: Tue, 07 Apr 2026 09:21:17 -0400 Subject: [PATCH 04/24] nfsd: add protocol support for CB_NOTIFY Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260407-dir-deleg-v1-4-aaf68c478abd@kernel.org> References: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> In-Reply-To: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Amir Goldstein Cc: Calum Mackay , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=49262; i=jlayton@kernel.org; h=from:subject:message-id; bh=yyB0NiTzw/pw7iObyO6el/c+tMbeiirPHQNO4+B3GvQ=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp1QUE5YTf73jqxT6dA40Tfs3aXlxg52rJ3SUHK CvrPMyA62+JAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCadUFBAAKCRAADmhBGVaC FfdfD/4pkt1e3yDvBpRy78Nj5ZiRv1kg4M32ZqHPCWvRB0VZmkGxf/BAhYPqVuKBaUrcr4Gu8ML /gBeNV5OuPNLfwCNklve8rtv3O/EZ/6tRYRPbPxxmzZzcGgAgvgmIszzX+Rw0v1x3J8YbryY/tG ofiR7MqlrKn79Lm2gnvBXRiE8Y2KWkLFn0sGMDbAFLMV6pOYv0KGqFjgpkv0C/p1eE/mog5D3hR DJ8TPYlkuuzPnmkHh8uP4dCrqfCjTGnkMuyH9Zg1XiLyvOtquM0iHnGzbp3TP3loiMd45Z+MfyJ LkJQlAacXHcEfGk+DqaodtMDkNVnyrvl8BS+0nQp0nc6elAdUK/2uKLKgB4Dlyo5Bk4JKJij2Wz L2QaaeM4OUL2TUayJqz8Xu9GVt4rLFchZsXqXshgzzdLZzLn/p6pzp6zYW/ajsd2icMh8k0Avgv s4rbBb9TPsIUCnHIiUpAxIteroQ3R/9nVr4c02kHA1ZfkbFxHjPM489nhxyR3z83GrmCPoICXzM c51XOkExiDHUrdRyifnW9Soj/O5eDvDCQpLMZaxIBmohgQdRPZDcBDH+T6ufmRQLpD0ZFhU8E2U qmOTT/kO8hxSKNurkKciEw2Ah0PsR5oOHkDgiybFlUyLBCKA8mNqOQAEpz+Tct9CihReDIo5WW8 I7/42KPkWtSdAFA== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Add the necessary bits to nfs4_1.x and remove the duplicate definitions from nfs4.h and the uapi nfs4 header. Regenerate the xdr files. Signed-off-by: Jeff Layton --- Documentation/sunrpc/xdr/nfs4_1.x | 250 ++++++++++++++- fs/nfsd/nfs4xdr_gen.c | 590 +++++++++++++++++++++++++++++++= +++- fs/nfsd/nfs4xdr_gen.h | 20 +- fs/nfsd/trace.h | 1 + include/linux/nfs4.h | 127 -------- include/linux/sunrpc/xdrgen/nfs4_1.h | 280 ++++++++++++++++- include/uapi/linux/nfs4.h | 2 - 7 files changed, 1129 insertions(+), 141 deletions(-) diff --git a/Documentation/sunrpc/xdr/nfs4_1.x b/Documentation/sunrpc/xdr/n= fs4_1.x index 5b45547b2ebc..632f5b579c39 100644 --- a/Documentation/sunrpc/xdr/nfs4_1.x +++ b/Documentation/sunrpc/xdr/nfs4_1.x @@ -45,19 +45,165 @@ pragma header nfs4; /* * Basic typedefs for RFC 1832 data type definitions */ -typedef hyper int64_t; -typedef unsigned int uint32_t; +typedef int int32_t; +typedef unsigned int uint32_t; +typedef hyper int64_t; +typedef unsigned hyper uint64_t; + +const NFS4_VERIFIER_SIZE =3D 8; +const NFS4_FHSIZE =3D 128; + +enum nfsstat4 { + NFS4_OK =3D 0, /* everything is okay */ + NFS4ERR_PERM =3D 1, /* caller not privileged */ + NFS4ERR_NOENT =3D 2, /* no such file/directory */ + NFS4ERR_IO =3D 5, /* hard I/O error */ + NFS4ERR_NXIO =3D 6, /* no such device */ + NFS4ERR_ACCESS =3D 13, /* access denied */ + NFS4ERR_EXIST =3D 17, /* file already exists */ + NFS4ERR_XDEV =3D 18, /* different filesystems */ + + /* + * Please do not allocate value 19; it was used in NFSv3 + * and we do not want a value in NFSv3 to have a different + * meaning in NFSv4.x. + */ + + NFS4ERR_NOTDIR =3D 20, /* should be a directory */ + NFS4ERR_ISDIR =3D 21, /* should not be directory */ + NFS4ERR_INVAL =3D 22, /* invalid argument */ + NFS4ERR_FBIG =3D 27, /* file exceeds server max */ + NFS4ERR_NOSPC =3D 28, /* no space on filesystem */ + NFS4ERR_ROFS =3D 30, /* read-only filesystem */ + NFS4ERR_MLINK =3D 31, /* too many hard links */ + NFS4ERR_NAMETOOLONG =3D 63, /* name exceeds server max */ + NFS4ERR_NOTEMPTY =3D 66, /* directory not empty */ + NFS4ERR_DQUOT =3D 69, /* hard quota limit reached*/ + NFS4ERR_STALE =3D 70, /* file no longer exists */ + NFS4ERR_BADHANDLE =3D 10001,/* Illegal filehandle */ + NFS4ERR_BAD_COOKIE =3D 10003,/* READDIR cookie is stale */ + NFS4ERR_NOTSUPP =3D 10004,/* operation not supported */ + NFS4ERR_TOOSMALL =3D 10005,/* response limit exceeded */ + NFS4ERR_SERVERFAULT =3D 10006,/* undefined server error */ + NFS4ERR_BADTYPE =3D 10007,/* type invalid for CREATE */ + NFS4ERR_DELAY =3D 10008,/* file "busy" - retry */ + NFS4ERR_SAME =3D 10009,/* nverify says attrs same */ + NFS4ERR_DENIED =3D 10010,/* lock unavailable */ + NFS4ERR_EXPIRED =3D 10011,/* lock lease expired */ + NFS4ERR_LOCKED =3D 10012,/* I/O failed due to lock */ + NFS4ERR_GRACE =3D 10013,/* in grace period */ + NFS4ERR_FHEXPIRED =3D 10014,/* filehandle expired */ + NFS4ERR_SHARE_DENIED =3D 10015,/* share reserve denied */ + NFS4ERR_WRONGSEC =3D 10016,/* wrong security flavor */ + NFS4ERR_CLID_INUSE =3D 10017,/* clientid in use */ + + /* NFS4ERR_RESOURCE is not a valid error in NFSv4.1 */ + NFS4ERR_RESOURCE =3D 10018,/* resource exhaustion */ + + NFS4ERR_MOVED =3D 10019,/* filesystem relocated */ + NFS4ERR_NOFILEHANDLE =3D 10020,/* current FH is not set */ + NFS4ERR_MINOR_VERS_MISMATCH=3D 10021,/* minor vers not supp */ + NFS4ERR_STALE_CLIENTID =3D 10022,/* server has rebooted */ + NFS4ERR_STALE_STATEID =3D 10023,/* server has rebooted */ + NFS4ERR_OLD_STATEID =3D 10024,/* state is out of sync */ + NFS4ERR_BAD_STATEID =3D 10025,/* incorrect stateid */ + NFS4ERR_BAD_SEQID =3D 10026,/* request is out of seq. */ + NFS4ERR_NOT_SAME =3D 10027,/* verify - attrs not same */ + NFS4ERR_LOCK_RANGE =3D 10028,/* overlapping lock range */ + NFS4ERR_SYMLINK =3D 10029,/* should be file/directory*/ + NFS4ERR_RESTOREFH =3D 10030,/* no saved filehandle */ + NFS4ERR_LEASE_MOVED =3D 10031,/* some filesystem moved */ + NFS4ERR_ATTRNOTSUPP =3D 10032,/* recommended attr not sup*/ + NFS4ERR_NO_GRACE =3D 10033,/* reclaim outside of grace*/ + NFS4ERR_RECLAIM_BAD =3D 10034,/* reclaim error at server */ + NFS4ERR_RECLAIM_CONFLICT=3D 10035,/* conflict on reclaim */ + NFS4ERR_BADXDR =3D 10036,/* XDR decode failed */ + NFS4ERR_LOCKS_HELD =3D 10037,/* file locks held at CLOSE*/ + NFS4ERR_OPENMODE =3D 10038,/* conflict in OPEN and I/O*/ + NFS4ERR_BADOWNER =3D 10039,/* owner translation bad */ + NFS4ERR_BADCHAR =3D 10040,/* utf-8 char not supported*/ + NFS4ERR_BADNAME =3D 10041,/* name not supported */ + NFS4ERR_BAD_RANGE =3D 10042,/* lock range not supported*/ + NFS4ERR_LOCK_NOTSUPP =3D 10043,/* no atomic up/downgrade */ + NFS4ERR_OP_ILLEGAL =3D 10044,/* undefined operation */ + NFS4ERR_DEADLOCK =3D 10045,/* file locking deadlock */ + NFS4ERR_FILE_OPEN =3D 10046,/* open file blocks op. */ + NFS4ERR_ADMIN_REVOKED =3D 10047,/* lockowner state revoked */ + NFS4ERR_CB_PATH_DOWN =3D 10048,/* callback path down */ + + /* NFSv4.1 errors start here. */ + + NFS4ERR_BADIOMODE =3D 10049, + NFS4ERR_BADLAYOUT =3D 10050, + NFS4ERR_BAD_SESSION_DIGEST =3D 10051, + NFS4ERR_BADSESSION =3D 10052, + NFS4ERR_BADSLOT =3D 10053, + NFS4ERR_COMPLETE_ALREADY =3D 10054, + NFS4ERR_CONN_NOT_BOUND_TO_SESSION =3D 10055, + NFS4ERR_DELEG_ALREADY_WANTED =3D 10056, + NFS4ERR_BACK_CHAN_BUSY =3D 10057,/*backchan reqs outstanding*/ + NFS4ERR_LAYOUTTRYLATER =3D 10058, + NFS4ERR_LAYOUTUNAVAILABLE =3D 10059, + NFS4ERR_NOMATCHING_LAYOUT =3D 10060, + NFS4ERR_RECALLCONFLICT =3D 10061, + NFS4ERR_UNKNOWN_LAYOUTTYPE =3D 10062, + NFS4ERR_SEQ_MISORDERED =3D 10063,/* unexpected seq.ID in req*/ + NFS4ERR_SEQUENCE_POS =3D 10064,/* [CB_]SEQ. op not 1st op */ + NFS4ERR_REQ_TOO_BIG =3D 10065,/* request too big */ + NFS4ERR_REP_TOO_BIG =3D 10066,/* reply too big */ + NFS4ERR_REP_TOO_BIG_TO_CACHE =3D10067,/* rep. not all cached*/ + NFS4ERR_RETRY_UNCACHED_REP =3D10068,/* retry & rep. uncached*/ + NFS4ERR_UNSAFE_COMPOUND =3D10069,/* retry/recovery too hard */ + NFS4ERR_TOO_MANY_OPS =3D 10070,/*too many ops in [CB_]COMP*/ + NFS4ERR_OP_NOT_IN_SESSION =3D10071,/* op needs [CB_]SEQ. op */ + NFS4ERR_HASH_ALG_UNSUPP =3D 10072, /* hash alg. not supp. */ + /* Error 10073 is unused. */ + NFS4ERR_CLIENTID_BUSY =3D 10074,/* clientid has state */ + NFS4ERR_PNFS_IO_HOLE =3D 10075,/* IO to _SPARSE file hole */ + NFS4ERR_SEQ_FALSE_RETRY=3D 10076,/* Retry !=3D original req. */ + NFS4ERR_BAD_HIGH_SLOT =3D 10077,/* req has bad highest_slot*/ + NFS4ERR_DEADSESSION =3D 10078,/*new req sent to dead sess*/ + NFS4ERR_ENCR_ALG_UNSUPP=3D 10079,/* encr alg. not supp. */ + NFS4ERR_PNFS_NO_LAYOUT =3D 10080,/* I/O without a layout */ + NFS4ERR_NOT_ONLY_OP =3D 10081,/* addl ops not allowed */ + NFS4ERR_WRONG_CRED =3D 10082,/* op done by wrong cred */ + NFS4ERR_WRONG_TYPE =3D 10083,/* op on wrong type object */ + NFS4ERR_DIRDELEG_UNAVAIL=3D10084,/* delegation not avail. */ + NFS4ERR_REJECT_DELEG =3D 10085,/* cb rejected delegation */ + NFS4ERR_RETURNCONFLICT =3D 10086,/* layout get before return*/ + NFS4ERR_DELEG_REVOKED =3D 10087, /* deleg./layout revoked */ + NFS4ERR_PARTNER_NOTSUPP =3D 10088, + NFS4ERR_PARTNER_NO_AUTH =3D 10089, + NFS4ERR_UNION_NOTSUPP =3D 10090, + NFS4ERR_OFFLOAD_DENIED =3D 10091, + NFS4ERR_WRONG_LFS =3D 10092, + NFS4ERR_BADLABEL =3D 10093, + NFS4ERR_OFFLOAD_NO_REQS =3D 10094, + NFS4ERR_NOXATTR =3D 10095, + NFS4ERR_XATTR2BIG =3D 10096, + + /* always set this to one more than the last one in the enum */ + NFS4ERR_FIRST_FREE =3D 10097 +}; =20 /* * Basic data types */ +typedef opaque attrlist4<>; typedef uint32_t bitmap4<>; +typedef opaque verifier4[NFS4_VERIFIER_SIZE]; +typedef uint64_t nfs_cookie4; +typedef opaque nfs_fh4; =20 typedef opaque utf8string<>; typedef utf8string utf8str_cis; typedef utf8string utf8str_cs; typedef utf8string utf8str_mixed; =20 +typedef utf8str_cs component4; +typedef utf8str_cs linktext4; +typedef component4 pathname4<>; + /* * Timeval */ @@ -66,6 +212,21 @@ struct nfstime4 { uint32_t nseconds; }; =20 +/* + * File attribute container + */ +struct fattr4 { + bitmap4 attrmask; + attrlist4 attr_vals; +}; + +/* + * Stateid + */ +struct stateid4 { + uint32_t seqid; + opaque other[12]; +}; =20 /* * The following content was extracted from draft-ietf-nfsv4-delstid @@ -245,3 +406,88 @@ const FATTR4_ACL_TRUEFORM =3D 89; const FATTR4_ACL_TRUEFORM_SCOPE =3D 90; const FATTR4_POSIX_DEFAULT_ACL =3D 91; const FATTR4_POSIX_ACCESS_ACL =3D 92; + +/* + * Directory notification types. + */ +enum notify_type4 { + NOTIFY4_CHANGE_CHILD_ATTRS =3D 0, + NOTIFY4_CHANGE_DIR_ATTRS =3D 1, + NOTIFY4_REMOVE_ENTRY =3D 2, + NOTIFY4_ADD_ENTRY =3D 3, + NOTIFY4_RENAME_ENTRY =3D 4, + NOTIFY4_CHANGE_COOKIE_VERIFIER =3D 5 +}; + +/* Changed entry information. */ +struct notify_entry4 { + component4 ne_file; + fattr4 ne_attrs; +}; + +/* Previous entry information */ +struct prev_entry4 { + notify_entry4 pe_prev_entry; + /* what READDIR returned for this entry */ + nfs_cookie4 pe_prev_entry_cookie; +}; + +struct notify_remove4 { + notify_entry4 nrm_old_entry; + nfs_cookie4 nrm_old_entry_cookie; +}; +pragma public notify_remove4; + +struct notify_add4 { + /* + * Information on object + * possibly renamed over. + */ + notify_remove4 nad_old_entry<1>; + notify_entry4 nad_new_entry; + /* what READDIR would have returned for this entry */ + nfs_cookie4 nad_new_entry_cookie<1>; + prev_entry4 nad_prev_entry<1>; + bool nad_last_entry; +}; +pragma public notify_add4; + +struct notify_attr4 { + notify_entry4 na_changed_entry; +}; +pragma public notify_attr4; + +struct notify_rename4 { + notify_remove4 nrn_old_entry; + notify_add4 nrn_new_entry; +}; +pragma public notify_rename4; + +struct notify_verifier4 { + verifier4 nv_old_cookieverf; + verifier4 nv_new_cookieverf; +}; + +/* + * Objects of type notify_<>4 and + * notify_device_<>4 are encoded in this. + */ +typedef opaque notifylist4<>; + +struct notify4 { + /* composed from notify_type4 or notify_deviceid_type4 */ + bitmap4 notify_mask; + notifylist4 notify_vals; +}; + +struct CB_NOTIFY4args { + stateid4 cna_stateid; + nfs_fh4 cna_fh; + notify4 cna_changes<>; +}; +pragma public CB_NOTIFY4args; + +struct CB_NOTIFY4res { + nfsstat4 cnr_status; +}; +pragma public CB_NOTIFY4res; diff --git a/fs/nfsd/nfs4xdr_gen.c b/fs/nfsd/nfs4xdr_gen.c index 824497051b87..5e656d6bbb8e 100644 --- a/fs/nfsd/nfs4xdr_gen.c +++ b/fs/nfsd/nfs4xdr_gen.c @@ -1,16 +1,16 @@ // SPDX-License-Identifier: GPL-2.0 // Generated by xdrgen. Manual edits will be lost. // XDR specification file: ../../Documentation/sunrpc/xdr/nfs4_1.x -// XDR specification modification time: Thu Jan 8 23:12:07 2026 +// XDR specification modification time: Wed Mar 25 11:39:22 2026 =20 #include =20 #include "nfs4xdr_gen.h" =20 static bool __maybe_unused -xdrgen_decode_int64_t(struct xdr_stream *xdr, int64_t *ptr) +xdrgen_decode_int32_t(struct xdr_stream *xdr, int32_t *ptr) { - return xdrgen_decode_hyper(xdr, ptr); + return xdrgen_decode_int(xdr, ptr); } =20 static bool __maybe_unused @@ -19,6 +19,155 @@ xdrgen_decode_uint32_t(struct xdr_stream *xdr, uint32_t= *ptr) return xdrgen_decode_unsigned_int(xdr, ptr); } =20 +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_uint64_t(struct xdr_stream *xdr, uint64_t *ptr) +{ + return xdrgen_decode_unsigned_hyper(xdr, ptr); +} + +static bool __maybe_unused +xdrgen_decode_nfsstat4(struct xdr_stream *xdr, nfsstat4 *ptr) +{ + u32 val; + + if (xdr_stream_decode_u32(xdr, &val) < 0) + return false; + /* Compiler may optimize to a range check for dense enums */ + switch (val) { + case NFS4_OK: + case NFS4ERR_PERM: + case NFS4ERR_NOENT: + case NFS4ERR_IO: + case NFS4ERR_NXIO: + case NFS4ERR_ACCESS: + case NFS4ERR_EXIST: + case NFS4ERR_XDEV: + case NFS4ERR_NOTDIR: + case NFS4ERR_ISDIR: + case NFS4ERR_INVAL: + case NFS4ERR_FBIG: + case NFS4ERR_NOSPC: + case NFS4ERR_ROFS: + case NFS4ERR_MLINK: + case NFS4ERR_NAMETOOLONG: + case NFS4ERR_NOTEMPTY: + case NFS4ERR_DQUOT: + case NFS4ERR_STALE: + case NFS4ERR_BADHANDLE: + case NFS4ERR_BAD_COOKIE: + case NFS4ERR_NOTSUPP: + case NFS4ERR_TOOSMALL: + case NFS4ERR_SERVERFAULT: + case NFS4ERR_BADTYPE: + case NFS4ERR_DELAY: + case NFS4ERR_SAME: + case NFS4ERR_DENIED: + case NFS4ERR_EXPIRED: + case NFS4ERR_LOCKED: + case NFS4ERR_GRACE: + case NFS4ERR_FHEXPIRED: + case NFS4ERR_SHARE_DENIED: + case NFS4ERR_WRONGSEC: + case NFS4ERR_CLID_INUSE: + case NFS4ERR_RESOURCE: + case NFS4ERR_MOVED: + case NFS4ERR_NOFILEHANDLE: + case NFS4ERR_MINOR_VERS_MISMATCH: + case NFS4ERR_STALE_CLIENTID: + case NFS4ERR_STALE_STATEID: + case NFS4ERR_OLD_STATEID: + case NFS4ERR_BAD_STATEID: + case NFS4ERR_BAD_SEQID: + case NFS4ERR_NOT_SAME: + case NFS4ERR_LOCK_RANGE: + case NFS4ERR_SYMLINK: + case NFS4ERR_RESTOREFH: + case NFS4ERR_LEASE_MOVED: + case NFS4ERR_ATTRNOTSUPP: + case NFS4ERR_NO_GRACE: + case NFS4ERR_RECLAIM_BAD: + case NFS4ERR_RECLAIM_CONFLICT: + case NFS4ERR_BADXDR: + case NFS4ERR_LOCKS_HELD: + case NFS4ERR_OPENMODE: + case NFS4ERR_BADOWNER: + case NFS4ERR_BADCHAR: + case NFS4ERR_BADNAME: + case NFS4ERR_BAD_RANGE: + case NFS4ERR_LOCK_NOTSUPP: + case NFS4ERR_OP_ILLEGAL: + case NFS4ERR_DEADLOCK: + case NFS4ERR_FILE_OPEN: + case NFS4ERR_ADMIN_REVOKED: + case NFS4ERR_CB_PATH_DOWN: + case NFS4ERR_BADIOMODE: + case NFS4ERR_BADLAYOUT: + case NFS4ERR_BAD_SESSION_DIGEST: + case NFS4ERR_BADSESSION: + case NFS4ERR_BADSLOT: + case NFS4ERR_COMPLETE_ALREADY: + case NFS4ERR_CONN_NOT_BOUND_TO_SESSION: + case NFS4ERR_DELEG_ALREADY_WANTED: + case NFS4ERR_BACK_CHAN_BUSY: + case NFS4ERR_LAYOUTTRYLATER: + case NFS4ERR_LAYOUTUNAVAILABLE: + case NFS4ERR_NOMATCHING_LAYOUT: + case NFS4ERR_RECALLCONFLICT: + case NFS4ERR_UNKNOWN_LAYOUTTYPE: + case NFS4ERR_SEQ_MISORDERED: + case NFS4ERR_SEQUENCE_POS: + case NFS4ERR_REQ_TOO_BIG: + case NFS4ERR_REP_TOO_BIG: + case NFS4ERR_REP_TOO_BIG_TO_CACHE: + case NFS4ERR_RETRY_UNCACHED_REP: + case NFS4ERR_UNSAFE_COMPOUND: + case NFS4ERR_TOO_MANY_OPS: + case NFS4ERR_OP_NOT_IN_SESSION: + case NFS4ERR_HASH_ALG_UNSUPP: + case NFS4ERR_CLIENTID_BUSY: + case NFS4ERR_PNFS_IO_HOLE: + case NFS4ERR_SEQ_FALSE_RETRY: + case NFS4ERR_BAD_HIGH_SLOT: + case NFS4ERR_DEADSESSION: + case NFS4ERR_ENCR_ALG_UNSUPP: + case NFS4ERR_PNFS_NO_LAYOUT: + case NFS4ERR_NOT_ONLY_OP: + case NFS4ERR_WRONG_CRED: + case NFS4ERR_WRONG_TYPE: + case NFS4ERR_DIRDELEG_UNAVAIL: + case NFS4ERR_REJECT_DELEG: + case NFS4ERR_RETURNCONFLICT: + case NFS4ERR_DELEG_REVOKED: + case NFS4ERR_PARTNER_NOTSUPP: + case NFS4ERR_PARTNER_NO_AUTH: + case NFS4ERR_UNION_NOTSUPP: + case NFS4ERR_OFFLOAD_DENIED: + case NFS4ERR_WRONG_LFS: + case NFS4ERR_BADLABEL: + case NFS4ERR_OFFLOAD_NO_REQS: + case NFS4ERR_NOXATTR: + case NFS4ERR_XATTR2BIG: + case NFS4ERR_FIRST_FREE: + break; + default: + return false; + } + *ptr =3D val; + return true; +} + +static bool __maybe_unused +xdrgen_decode_attrlist4(struct xdr_stream *xdr, attrlist4 *ptr) +{ + return xdrgen_decode_opaque(xdr, ptr, 0); +} + static bool __maybe_unused xdrgen_decode_bitmap4(struct xdr_stream *xdr, bitmap4 *ptr) { @@ -30,6 +179,24 @@ xdrgen_decode_bitmap4(struct xdr_stream *xdr, bitmap4 *= ptr) return true; } =20 +static bool __maybe_unused +xdrgen_decode_verifier4(struct xdr_stream *xdr, verifier4 *ptr) +{ + return xdr_stream_decode_opaque_fixed(xdr, ptr, NFS4_VERIFIER_SIZE) =3D= =3D 0; +} + +static bool __maybe_unused +xdrgen_decode_nfs_cookie4(struct xdr_stream *xdr, nfs_cookie4 *ptr) +{ + return xdrgen_decode_uint64_t(xdr, ptr); +} + +static bool __maybe_unused +xdrgen_decode_nfs_fh4(struct xdr_stream *xdr, nfs_fh4 *ptr) +{ + return xdrgen_decode_opaque(xdr, ptr, NFS4_FHSIZE); +} + static bool __maybe_unused xdrgen_decode_utf8string(struct xdr_stream *xdr, utf8string *ptr) { @@ -54,6 +221,29 @@ xdrgen_decode_utf8str_mixed(struct xdr_stream *xdr, utf= 8str_mixed *ptr) return xdrgen_decode_utf8string(xdr, ptr); } =20 +static bool __maybe_unused +xdrgen_decode_component4(struct xdr_stream *xdr, component4 *ptr) +{ + return xdrgen_decode_utf8str_cs(xdr, ptr); +} + +static bool __maybe_unused +xdrgen_decode_linktext4(struct xdr_stream *xdr, linktext4 *ptr) +{ + return xdrgen_decode_utf8str_cs(xdr, ptr); +} + +static bool __maybe_unused +xdrgen_decode_pathname4(struct xdr_stream *xdr, pathname4 *ptr) +{ + if (xdr_stream_decode_u32(xdr, &ptr->count) < 0) + return false; + for (u32 i =3D 0; i < ptr->count; i++) + if (!xdrgen_decode_component4(xdr, &ptr->element[i])) + return false; + return true; +} + static bool __maybe_unused xdrgen_decode_nfstime4(struct xdr_stream *xdr, struct nfstime4 *ptr) { @@ -64,6 +254,26 @@ xdrgen_decode_nfstime4(struct xdr_stream *xdr, struct n= fstime4 *ptr) return true; } =20 +static bool __maybe_unused +xdrgen_decode_fattr4(struct xdr_stream *xdr, struct fattr4 *ptr) +{ + if (!xdrgen_decode_bitmap4(xdr, &ptr->attrmask)) + return false; + if (!xdrgen_decode_attrlist4(xdr, &ptr->attr_vals)) + return false; + return true; +} + +static bool __maybe_unused +xdrgen_decode_stateid4(struct xdr_stream *xdr, struct stateid4 *ptr) +{ + if (!xdrgen_decode_uint32_t(xdr, &ptr->seqid)) + return false; + if (xdr_stream_decode_opaque_fixed(xdr, ptr->other, 12) < 0) + return false; + return true; +} + static bool __maybe_unused xdrgen_decode_fattr4_offline(struct xdr_stream *xdr, fattr4_offline *ptr) { @@ -366,9 +576,160 @@ xdrgen_decode_fattr4_posix_access_acl(struct xdr_stre= am *xdr, fattr4_posix_acces */ =20 static bool __maybe_unused -xdrgen_encode_int64_t(struct xdr_stream *xdr, const int64_t value) +xdrgen_decode_notify_type4(struct xdr_stream *xdr, notify_type4 *ptr) { - return xdrgen_encode_hyper(xdr, value); + u32 val; + + if (xdr_stream_decode_u32(xdr, &val) < 0) + return false; + /* Compiler may optimize to a range check for dense enums */ + switch (val) { + case NOTIFY4_CHANGE_CHILD_ATTRS: + case NOTIFY4_CHANGE_DIR_ATTRS: + case NOTIFY4_REMOVE_ENTRY: + case NOTIFY4_ADD_ENTRY: + case NOTIFY4_RENAME_ENTRY: + case NOTIFY4_CHANGE_COOKIE_VERIFIER: + break; + default: + return false; + } + *ptr =3D val; + return true; +} + +static bool __maybe_unused +xdrgen_decode_notify_entry4(struct xdr_stream *xdr, struct notify_entry4 *= ptr) +{ + if (!xdrgen_decode_component4(xdr, &ptr->ne_file)) + return false; + if (!xdrgen_decode_fattr4(xdr, &ptr->ne_attrs)) + return false; + return true; +} + +static bool __maybe_unused +xdrgen_decode_prev_entry4(struct xdr_stream *xdr, struct prev_entry4 *ptr) +{ + if (!xdrgen_decode_notify_entry4(xdr, &ptr->pe_prev_entry)) + return false; + if (!xdrgen_decode_nfs_cookie4(xdr, &ptr->pe_prev_entry_cookie)) + return false; + return true; +} + +bool +xdrgen_decode_notify_remove4(struct xdr_stream *xdr, struct notify_remove4= *ptr) +{ + if (!xdrgen_decode_notify_entry4(xdr, &ptr->nrm_old_entry)) + return false; + if (!xdrgen_decode_nfs_cookie4(xdr, &ptr->nrm_old_entry_cookie)) + return false; + return true; +} + +bool +xdrgen_decode_notify_add4(struct xdr_stream *xdr, struct notify_add4 *ptr) +{ + if (xdr_stream_decode_u32(xdr, &ptr->nad_old_entry.count) < 0) + return false; + if (ptr->nad_old_entry.count > 1) + return false; + for (u32 i =3D 0; i < ptr->nad_old_entry.count; i++) + if (!xdrgen_decode_notify_remove4(xdr, &ptr->nad_old_entry.element[i])) + return false; + if (!xdrgen_decode_notify_entry4(xdr, &ptr->nad_new_entry)) + return false; + if (xdr_stream_decode_u32(xdr, &ptr->nad_new_entry_cookie.count) < 0) + return false; + if (ptr->nad_new_entry_cookie.count > 1) + return false; + for (u32 i =3D 0; i < ptr->nad_new_entry_cookie.count; i++) + if (!xdrgen_decode_nfs_cookie4(xdr, &ptr->nad_new_entry_cookie.element[i= ])) + return false; + if (xdr_stream_decode_u32(xdr, &ptr->nad_prev_entry.count) < 0) + return false; + if (ptr->nad_prev_entry.count > 1) + return false; + for (u32 i =3D 0; i < ptr->nad_prev_entry.count; i++) + if (!xdrgen_decode_prev_entry4(xdr, &ptr->nad_prev_entry.element[i])) + return false; + if (!xdrgen_decode_bool(xdr, &ptr->nad_last_entry)) + return false; + return true; +} + +bool +xdrgen_decode_notify_attr4(struct xdr_stream *xdr, struct notify_attr4 *pt= r) +{ + if (!xdrgen_decode_notify_entry4(xdr, &ptr->na_changed_entry)) + return false; + return true; +} + +bool +xdrgen_decode_notify_rename4(struct xdr_stream *xdr, struct notify_rename4= *ptr) +{ + if (!xdrgen_decode_notify_remove4(xdr, &ptr->nrn_old_entry)) + return false; + if (!xdrgen_decode_notify_add4(xdr, &ptr->nrn_new_entry)) + return false; + return true; +} + +static bool __maybe_unused +xdrgen_decode_notify_verifier4(struct xdr_stream *xdr, struct notify_verif= ier4 *ptr) +{ + if (!xdrgen_decode_verifier4(xdr, &ptr->nv_old_cookieverf)) + return false; + if (!xdrgen_decode_verifier4(xdr, &ptr->nv_new_cookieverf)) + return false; + return true; +} + +static bool __maybe_unused +xdrgen_decode_notifylist4(struct xdr_stream *xdr, notifylist4 *ptr) +{ + return xdrgen_decode_opaque(xdr, ptr, 0); +} + +static bool __maybe_unused +xdrgen_decode_notify4(struct xdr_stream *xdr, struct notify4 *ptr) +{ + if (!xdrgen_decode_bitmap4(xdr, &ptr->notify_mask)) + return false; + if (!xdrgen_decode_notifylist4(xdr, &ptr->notify_vals)) + return false; + return true; +} + +bool +xdrgen_decode_CB_NOTIFY4args(struct xdr_stream *xdr, struct CB_NOTIFY4args= *ptr) +{ + if (!xdrgen_decode_stateid4(xdr, &ptr->cna_stateid)) + return false; + if (!xdrgen_decode_nfs_fh4(xdr, &ptr->cna_fh)) + return false; + if (xdr_stream_decode_u32(xdr, &ptr->cna_changes.count) < 0) + return false; + for (u32 i =3D 0; i < ptr->cna_changes.count; i++) + if (!xdrgen_decode_notify4(xdr, &ptr->cna_changes.element[i])) + return false; + return true; +} + +bool +xdrgen_decode_CB_NOTIFY4res(struct xdr_stream *xdr, struct CB_NOTIFY4res *= ptr) +{ + if (!xdrgen_decode_nfsstat4(xdr, &ptr->cnr_status)) + return false; + return true; +} + +static bool __maybe_unused +xdrgen_encode_int32_t(struct xdr_stream *xdr, const int32_t value) +{ + return xdrgen_encode_int(xdr, value); } =20 static bool __maybe_unused @@ -377,6 +738,30 @@ xdrgen_encode_uint32_t(struct xdr_stream *xdr, const u= int32_t value) return xdrgen_encode_unsigned_int(xdr, value); } =20 +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_uint64_t(struct xdr_stream *xdr, const uint64_t value) +{ + return xdrgen_encode_unsigned_hyper(xdr, value); +} + +static bool __maybe_unused +xdrgen_encode_nfsstat4(struct xdr_stream *xdr, nfsstat4 value) +{ + return xdr_stream_encode_u32(xdr, value) =3D=3D XDR_UNIT; +} + +static bool __maybe_unused +xdrgen_encode_attrlist4(struct xdr_stream *xdr, const attrlist4 value) +{ + return xdr_stream_encode_opaque(xdr, value.data, value.len) >=3D 0; +} + static bool __maybe_unused xdrgen_encode_bitmap4(struct xdr_stream *xdr, const bitmap4 value) { @@ -388,6 +773,24 @@ xdrgen_encode_bitmap4(struct xdr_stream *xdr, const bi= tmap4 value) return true; } =20 +static bool __maybe_unused +xdrgen_encode_verifier4(struct xdr_stream *xdr, const verifier4 value) +{ + return xdr_stream_encode_opaque_fixed(xdr, value, NFS4_VERIFIER_SIZE) >= =3D 0; +} + +static bool __maybe_unused +xdrgen_encode_nfs_cookie4(struct xdr_stream *xdr, const nfs_cookie4 value) +{ + return xdrgen_encode_uint64_t(xdr, value); +} + +static bool __maybe_unused +xdrgen_encode_nfs_fh4(struct xdr_stream *xdr, const nfs_fh4 value) +{ + return xdr_stream_encode_opaque(xdr, value.data, value.len) >=3D 0; +} + static bool __maybe_unused xdrgen_encode_utf8string(struct xdr_stream *xdr, const utf8string value) { @@ -412,6 +815,29 @@ xdrgen_encode_utf8str_mixed(struct xdr_stream *xdr, co= nst utf8str_mixed value) return xdrgen_encode_utf8string(xdr, value); } =20 +static bool __maybe_unused +xdrgen_encode_component4(struct xdr_stream *xdr, const component4 value) +{ + return xdrgen_encode_utf8str_cs(xdr, value); +} + +static bool __maybe_unused +xdrgen_encode_linktext4(struct xdr_stream *xdr, const linktext4 value) +{ + return xdrgen_encode_utf8str_cs(xdr, value); +} + +static bool __maybe_unused +xdrgen_encode_pathname4(struct xdr_stream *xdr, const pathname4 value) +{ + if (xdr_stream_encode_u32(xdr, value.count) !=3D XDR_UNIT) + return false; + for (u32 i =3D 0; i < value.count; i++) + if (!xdrgen_encode_component4(xdr, value.element[i])) + return false; + return true; +} + static bool __maybe_unused xdrgen_encode_nfstime4(struct xdr_stream *xdr, const struct nfstime4 *valu= e) { @@ -422,6 +848,26 @@ xdrgen_encode_nfstime4(struct xdr_stream *xdr, const s= truct nfstime4 *value) return true; } =20 +static bool __maybe_unused +xdrgen_encode_fattr4(struct xdr_stream *xdr, const struct fattr4 *value) +{ + if (!xdrgen_encode_bitmap4(xdr, value->attrmask)) + return false; + if (!xdrgen_encode_attrlist4(xdr, value->attr_vals)) + return false; + return true; +} + +static bool __maybe_unused +xdrgen_encode_stateid4(struct xdr_stream *xdr, const struct stateid4 *valu= e) +{ + if (!xdrgen_encode_uint32_t(xdr, value->seqid)) + return false; + if (xdr_stream_encode_opaque_fixed(xdr, value->other, 12) < 0) + return false; + return true; +} + static bool __maybe_unused xdrgen_encode_fattr4_offline(struct xdr_stream *xdr, const fattr4_offline = value) { @@ -567,3 +1013,137 @@ xdrgen_encode_fattr4_posix_access_acl(struct xdr_str= eam *xdr, const fattr4_posix return false; return true; } + +static bool __maybe_unused +xdrgen_encode_notify_type4(struct xdr_stream *xdr, notify_type4 value) +{ + return xdr_stream_encode_u32(xdr, value) =3D=3D XDR_UNIT; +} + +static bool __maybe_unused +xdrgen_encode_notify_entry4(struct xdr_stream *xdr, const struct notify_en= try4 *value) +{ + if (!xdrgen_encode_component4(xdr, value->ne_file)) + return false; + if (!xdrgen_encode_fattr4(xdr, &value->ne_attrs)) + return false; + return true; +} + +static bool __maybe_unused +xdrgen_encode_prev_entry4(struct xdr_stream *xdr, const struct prev_entry4= *value) +{ + if (!xdrgen_encode_notify_entry4(xdr, &value->pe_prev_entry)) + return false; + if (!xdrgen_encode_nfs_cookie4(xdr, value->pe_prev_entry_cookie)) + return false; + return true; +} + +bool +xdrgen_encode_notify_remove4(struct xdr_stream *xdr, const struct notify_r= emove4 *value) +{ + if (!xdrgen_encode_notify_entry4(xdr, &value->nrm_old_entry)) + return false; + if (!xdrgen_encode_nfs_cookie4(xdr, value->nrm_old_entry_cookie)) + return false; + return true; +} + +bool +xdrgen_encode_notify_add4(struct xdr_stream *xdr, const struct notify_add4= *value) +{ + if (value->nad_old_entry.count > 1) + return false; + if (xdr_stream_encode_u32(xdr, value->nad_old_entry.count) !=3D XDR_UNIT) + return false; + for (u32 i =3D 0; i < value->nad_old_entry.count; i++) + if (!xdrgen_encode_notify_remove4(xdr, &value->nad_old_entry.element[i])) + return false; + if (!xdrgen_encode_notify_entry4(xdr, &value->nad_new_entry)) + return false; + if (value->nad_new_entry_cookie.count > 1) + return false; + if (xdr_stream_encode_u32(xdr, value->nad_new_entry_cookie.count) !=3D XD= R_UNIT) + return false; + for (u32 i =3D 0; i < value->nad_new_entry_cookie.count; i++) + if (!xdrgen_encode_nfs_cookie4(xdr, value->nad_new_entry_cookie.element[= i])) + return false; + if (value->nad_prev_entry.count > 1) + return false; + if (xdr_stream_encode_u32(xdr, value->nad_prev_entry.count) !=3D XDR_UNIT) + return false; + for (u32 i =3D 0; i < value->nad_prev_entry.count; i++) + if (!xdrgen_encode_prev_entry4(xdr, &value->nad_prev_entry.element[i])) + return false; + if (!xdrgen_encode_bool(xdr, value->nad_last_entry)) + return false; + return true; +} + +bool +xdrgen_encode_notify_attr4(struct xdr_stream *xdr, const struct notify_att= r4 *value) +{ + if (!xdrgen_encode_notify_entry4(xdr, &value->na_changed_entry)) + return false; + return true; +} + +bool +xdrgen_encode_notify_rename4(struct xdr_stream *xdr, const struct notify_r= ename4 *value) +{ + if (!xdrgen_encode_notify_remove4(xdr, &value->nrn_old_entry)) + return false; + if (!xdrgen_encode_notify_add4(xdr, &value->nrn_new_entry)) + return false; + return true; +} + +static bool __maybe_unused +xdrgen_encode_notify_verifier4(struct xdr_stream *xdr, const struct notify= _verifier4 *value) +{ + if (!xdrgen_encode_verifier4(xdr, value->nv_old_cookieverf)) + return false; + if (!xdrgen_encode_verifier4(xdr, value->nv_new_cookieverf)) + return false; + return true; +} + +static bool __maybe_unused +xdrgen_encode_notifylist4(struct xdr_stream *xdr, const notifylist4 value) +{ + return xdr_stream_encode_opaque(xdr, value.data, value.len) >=3D 0; +} + +static bool __maybe_unused +xdrgen_encode_notify4(struct xdr_stream *xdr, const struct notify4 *value) +{ + if (!xdrgen_encode_bitmap4(xdr, value->notify_mask)) + return false; + if (!xdrgen_encode_notifylist4(xdr, value->notify_vals)) + return false; + return true; +} + +bool +xdrgen_encode_CB_NOTIFY4args(struct xdr_stream *xdr, const struct CB_NOTIF= Y4args *value) +{ + if (!xdrgen_encode_stateid4(xdr, &value->cna_stateid)) + return false; + if (!xdrgen_encode_nfs_fh4(xdr, value->cna_fh)) + return false; + if (xdr_stream_encode_u32(xdr, value->cna_changes.count) !=3D XDR_UNIT) + return false; + for (u32 i =3D 0; i < value->cna_changes.count; i++) + if (!xdrgen_encode_notify4(xdr, &value->cna_changes.element[i])) + return false; + return true; +} + +bool +xdrgen_encode_CB_NOTIFY4res(struct xdr_stream *xdr, const struct CB_NOTIFY= 4res *value) +{ + if (!xdrgen_encode_nfsstat4(xdr, value->cnr_status)) + return false; + return true; +} diff --git a/fs/nfsd/nfs4xdr_gen.h b/fs/nfsd/nfs4xdr_gen.h index 1c487f1a11ab..503fe2ccba51 100644 --- a/fs/nfsd/nfs4xdr_gen.h +++ b/fs/nfsd/nfs4xdr_gen.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* Generated by xdrgen. Manual edits will be lost. */ /* XDR specification file: ../../Documentation/sunrpc/xdr/nfs4_1.x */ -/* XDR specification modification time: Thu Jan 8 23:12:07 2026 */ +/* XDR specification modification time: Wed Mar 25 11:39:22 2026 */ =20 #ifndef _LINUX_XDRGEN_NFS4_1_DECL_H #define _LINUX_XDRGEN_NFS4_1_DECL_H @@ -32,4 +32,22 @@ bool xdrgen_decode_posixaceperm4(struct xdr_stream *xdr,= posixaceperm4 *ptr); bool xdrgen_encode_posixaceperm4(struct xdr_stream *xdr, const posixaceper= m4 value); =20 =20 +bool xdrgen_decode_notify_remove4(struct xdr_stream *xdr, struct notify_re= move4 *ptr); +bool xdrgen_encode_notify_remove4(struct xdr_stream *xdr, const struct not= ify_remove4 *value); + +bool xdrgen_decode_notify_add4(struct xdr_stream *xdr, struct notify_add4 = *ptr); +bool xdrgen_encode_notify_add4(struct xdr_stream *xdr, const struct notify= _add4 *value); + +bool xdrgen_decode_notify_attr4(struct xdr_stream *xdr, struct notify_attr= 4 *ptr); +bool xdrgen_encode_notify_attr4(struct xdr_stream *xdr, const struct notif= y_attr4 *value); + +bool xdrgen_decode_notify_rename4(struct xdr_stream *xdr, struct notify_re= name4 *ptr); +bool xdrgen_encode_notify_rename4(struct xdr_stream *xdr, const struct not= ify_rename4 *value); + +bool xdrgen_decode_CB_NOTIFY4args(struct xdr_stream *xdr, struct CB_NOTIFY= 4args *ptr); +bool xdrgen_encode_CB_NOTIFY4args(struct xdr_stream *xdr, const struct CB_= NOTIFY4args *value); + +bool xdrgen_decode_CB_NOTIFY4res(struct xdr_stream *xdr, struct CB_NOTIFY4= res *ptr); +bool xdrgen_encode_CB_NOTIFY4res(struct xdr_stream *xdr, const struct CB_N= OTIFY4res *value); + #endif /* _LINUX_XDRGEN_NFS4_1_DECL_H */ diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h index a13d18447324..60cacf64181c 100644 --- a/fs/nfsd/trace.h +++ b/fs/nfsd/trace.h @@ -1677,6 +1677,7 @@ TRACE_EVENT(nfsd_cb_setup_err, { OP_CB_RECALL, "CB_RECALL" }, \ { OP_CB_LAYOUTRECALL, "CB_LAYOUTRECALL" }, \ { OP_CB_RECALL_ANY, "CB_RECALL_ANY" }, \ + { OP_CB_NOTIFY, "CB_NOTIFY" }, \ { OP_CB_NOTIFY_LOCK, "CB_NOTIFY_LOCK" }, \ { OP_CB_OFFLOAD, "CB_OFFLOAD" }) =20 diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index d87be1f25273..44e5e9fa12e1 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h @@ -171,133 +171,6 @@ Needs to be updated if more operations are defined in= future.*/ #define LAST_NFS42_OP OP_REMOVEXATTR #define LAST_NFS4_OP LAST_NFS42_OP =20 -enum nfsstat4 { - NFS4_OK =3D 0, - NFS4ERR_PERM =3D 1, - NFS4ERR_NOENT =3D 2, - NFS4ERR_IO =3D 5, - NFS4ERR_NXIO =3D 6, - NFS4ERR_ACCESS =3D 13, - NFS4ERR_EXIST =3D 17, - NFS4ERR_XDEV =3D 18, - /* Unused/reserved 19 */ - NFS4ERR_NOTDIR =3D 20, - NFS4ERR_ISDIR =3D 21, - NFS4ERR_INVAL =3D 22, - NFS4ERR_FBIG =3D 27, - NFS4ERR_NOSPC =3D 28, - NFS4ERR_ROFS =3D 30, - NFS4ERR_MLINK =3D 31, - NFS4ERR_NAMETOOLONG =3D 63, - NFS4ERR_NOTEMPTY =3D 66, - NFS4ERR_DQUOT =3D 69, - NFS4ERR_STALE =3D 70, - NFS4ERR_BADHANDLE =3D 10001, - NFS4ERR_BAD_COOKIE =3D 10003, - NFS4ERR_NOTSUPP =3D 10004, - NFS4ERR_TOOSMALL =3D 10005, - NFS4ERR_SERVERFAULT =3D 10006, - NFS4ERR_BADTYPE =3D 10007, - NFS4ERR_DELAY =3D 10008, - NFS4ERR_SAME =3D 10009, - NFS4ERR_DENIED =3D 10010, - NFS4ERR_EXPIRED =3D 10011, - NFS4ERR_LOCKED =3D 10012, - NFS4ERR_GRACE =3D 10013, - NFS4ERR_FHEXPIRED =3D 10014, - NFS4ERR_SHARE_DENIED =3D 10015, - NFS4ERR_WRONGSEC =3D 10016, - NFS4ERR_CLID_INUSE =3D 10017, - NFS4ERR_RESOURCE =3D 10018, - NFS4ERR_MOVED =3D 10019, - NFS4ERR_NOFILEHANDLE =3D 10020, - NFS4ERR_MINOR_VERS_MISMATCH =3D 10021, - NFS4ERR_STALE_CLIENTID =3D 10022, - NFS4ERR_STALE_STATEID =3D 10023, - NFS4ERR_OLD_STATEID =3D 10024, - NFS4ERR_BAD_STATEID =3D 10025, - NFS4ERR_BAD_SEQID =3D 10026, - NFS4ERR_NOT_SAME =3D 10027, - NFS4ERR_LOCK_RANGE =3D 10028, - NFS4ERR_SYMLINK =3D 10029, - NFS4ERR_RESTOREFH =3D 10030, - NFS4ERR_LEASE_MOVED =3D 10031, - NFS4ERR_ATTRNOTSUPP =3D 10032, - NFS4ERR_NO_GRACE =3D 10033, - NFS4ERR_RECLAIM_BAD =3D 10034, - NFS4ERR_RECLAIM_CONFLICT =3D 10035, - NFS4ERR_BADXDR =3D 10036, - NFS4ERR_LOCKS_HELD =3D 10037, - NFS4ERR_OPENMODE =3D 10038, - NFS4ERR_BADOWNER =3D 10039, - NFS4ERR_BADCHAR =3D 10040, - NFS4ERR_BADNAME =3D 10041, - NFS4ERR_BAD_RANGE =3D 10042, - NFS4ERR_LOCK_NOTSUPP =3D 10043, - NFS4ERR_OP_ILLEGAL =3D 10044, - NFS4ERR_DEADLOCK =3D 10045, - NFS4ERR_FILE_OPEN =3D 10046, - NFS4ERR_ADMIN_REVOKED =3D 10047, - NFS4ERR_CB_PATH_DOWN =3D 10048, - - /* nfs41 */ - NFS4ERR_BADIOMODE =3D 10049, - NFS4ERR_BADLAYOUT =3D 10050, - NFS4ERR_BAD_SESSION_DIGEST =3D 10051, - NFS4ERR_BADSESSION =3D 10052, - NFS4ERR_BADSLOT =3D 10053, - NFS4ERR_COMPLETE_ALREADY =3D 10054, - NFS4ERR_CONN_NOT_BOUND_TO_SESSION =3D 10055, - NFS4ERR_DELEG_ALREADY_WANTED =3D 10056, - NFS4ERR_BACK_CHAN_BUSY =3D 10057, /* backchan reqs outstanding */ - NFS4ERR_LAYOUTTRYLATER =3D 10058, - NFS4ERR_LAYOUTUNAVAILABLE =3D 10059, - NFS4ERR_NOMATCHING_LAYOUT =3D 10060, - NFS4ERR_RECALLCONFLICT =3D 10061, - NFS4ERR_UNKNOWN_LAYOUTTYPE =3D 10062, - NFS4ERR_SEQ_MISORDERED =3D 10063, /* unexpected seq.id in req */ - NFS4ERR_SEQUENCE_POS =3D 10064, /* [CB_]SEQ. op not 1st op */ - NFS4ERR_REQ_TOO_BIG =3D 10065, /* request too big */ - NFS4ERR_REP_TOO_BIG =3D 10066, /* reply too big */ - NFS4ERR_REP_TOO_BIG_TO_CACHE =3D 10067, /* rep. not all cached */ - NFS4ERR_RETRY_UNCACHED_REP =3D 10068, /* retry & rep. uncached */ - NFS4ERR_UNSAFE_COMPOUND =3D 10069, /* retry/recovery too hard */ - NFS4ERR_TOO_MANY_OPS =3D 10070, /* too many ops in [CB_]COMP */ - NFS4ERR_OP_NOT_IN_SESSION =3D 10071, /* op needs [CB_]SEQ. op */ - NFS4ERR_HASH_ALG_UNSUPP =3D 10072, /* hash alg. not supp. */ - /* Error 10073 is unused. */ - NFS4ERR_CLIENTID_BUSY =3D 10074, /* clientid has state */ - NFS4ERR_PNFS_IO_HOLE =3D 10075, /* IO to _SPARSE file hole */ - NFS4ERR_SEQ_FALSE_RETRY =3D 10076, /* retry not original */ - NFS4ERR_BAD_HIGH_SLOT =3D 10077, /* sequence arg bad */ - NFS4ERR_DEADSESSION =3D 10078, /* persistent session dead */ - NFS4ERR_ENCR_ALG_UNSUPP =3D 10079, /* SSV alg mismatch */ - NFS4ERR_PNFS_NO_LAYOUT =3D 10080, /* direct I/O with no layout */ - NFS4ERR_NOT_ONLY_OP =3D 10081, /* bad compound */ - NFS4ERR_WRONG_CRED =3D 10082, /* permissions:state change */ - NFS4ERR_WRONG_TYPE =3D 10083, /* current operation mismatch */ - NFS4ERR_DIRDELEG_UNAVAIL =3D 10084, /* no directory delegation */ - NFS4ERR_REJECT_DELEG =3D 10085, /* on callback */ - NFS4ERR_RETURNCONFLICT =3D 10086, /* outstanding layoutreturn */ - NFS4ERR_DELEG_REVOKED =3D 10087, /* deleg./layout revoked */ - - /* nfs42 */ - NFS4ERR_PARTNER_NOTSUPP =3D 10088, - NFS4ERR_PARTNER_NO_AUTH =3D 10089, - NFS4ERR_UNION_NOTSUPP =3D 10090, - NFS4ERR_OFFLOAD_DENIED =3D 10091, - NFS4ERR_WRONG_LFS =3D 10092, - NFS4ERR_BADLABEL =3D 10093, - NFS4ERR_OFFLOAD_NO_REQS =3D 10094, - - /* xattr (RFC8276) */ - NFS4ERR_NOXATTR =3D 10095, - NFS4ERR_XATTR2BIG =3D 10096, - - /* can be used for internal errors */ - NFS4ERR_FIRST_FREE -}; - /* error codes for internal client use */ #define NFS4ERR_RESET_TO_MDS 12001 #define NFS4ERR_RESET_TO_PNFS 12002 diff --git a/include/linux/sunrpc/xdrgen/nfs4_1.h b/include/linux/sunrpc/xd= rgen/nfs4_1.h index 4ac54bdbd335..f761c3ddb4c7 100644 --- a/include/linux/sunrpc/xdrgen/nfs4_1.h +++ b/include/linux/sunrpc/xdrgen/nfs4_1.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* Generated by xdrgen. Manual edits will be lost. */ /* XDR specification file: ../../Documentation/sunrpc/xdr/nfs4_1.x */ -/* XDR specification modification time: Thu Jan 8 23:12:07 2026 */ +/* XDR specification modification time: Wed Mar 25 11:39:22 2026 */ =20 #ifndef _LINUX_XDRGEN_NFS4_1_DEF_H #define _LINUX_XDRGEN_NFS4_1_DEF_H @@ -9,15 +9,150 @@ #include #include =20 -typedef s64 int64_t; +typedef s32 int32_t; =20 typedef u32 uint32_t; =20 +typedef s64 int64_t; + +typedef u64 uint64_t; + +enum { NFS4_VERIFIER_SIZE =3D 8 }; + +enum { NFS4_FHSIZE =3D 128 }; + +enum nfsstat4 { + NFS4_OK =3D 0, + NFS4ERR_PERM =3D 1, + NFS4ERR_NOENT =3D 2, + NFS4ERR_IO =3D 5, + NFS4ERR_NXIO =3D 6, + NFS4ERR_ACCESS =3D 13, + NFS4ERR_EXIST =3D 17, + NFS4ERR_XDEV =3D 18, + NFS4ERR_NOTDIR =3D 20, + NFS4ERR_ISDIR =3D 21, + NFS4ERR_INVAL =3D 22, + NFS4ERR_FBIG =3D 27, + NFS4ERR_NOSPC =3D 28, + NFS4ERR_ROFS =3D 30, + NFS4ERR_MLINK =3D 31, + NFS4ERR_NAMETOOLONG =3D 63, + NFS4ERR_NOTEMPTY =3D 66, + NFS4ERR_DQUOT =3D 69, + NFS4ERR_STALE =3D 70, + NFS4ERR_BADHANDLE =3D 10001, + NFS4ERR_BAD_COOKIE =3D 10003, + NFS4ERR_NOTSUPP =3D 10004, + NFS4ERR_TOOSMALL =3D 10005, + NFS4ERR_SERVERFAULT =3D 10006, + NFS4ERR_BADTYPE =3D 10007, + NFS4ERR_DELAY =3D 10008, + NFS4ERR_SAME =3D 10009, + NFS4ERR_DENIED =3D 10010, + NFS4ERR_EXPIRED =3D 10011, + NFS4ERR_LOCKED =3D 10012, + NFS4ERR_GRACE =3D 10013, + NFS4ERR_FHEXPIRED =3D 10014, + NFS4ERR_SHARE_DENIED =3D 10015, + NFS4ERR_WRONGSEC =3D 10016, + NFS4ERR_CLID_INUSE =3D 10017, + NFS4ERR_RESOURCE =3D 10018, + NFS4ERR_MOVED =3D 10019, + NFS4ERR_NOFILEHANDLE =3D 10020, + NFS4ERR_MINOR_VERS_MISMATCH =3D 10021, + NFS4ERR_STALE_CLIENTID =3D 10022, + NFS4ERR_STALE_STATEID =3D 10023, + NFS4ERR_OLD_STATEID =3D 10024, + NFS4ERR_BAD_STATEID =3D 10025, + NFS4ERR_BAD_SEQID =3D 10026, + NFS4ERR_NOT_SAME =3D 10027, + NFS4ERR_LOCK_RANGE =3D 10028, + NFS4ERR_SYMLINK =3D 10029, + NFS4ERR_RESTOREFH =3D 10030, + NFS4ERR_LEASE_MOVED =3D 10031, + NFS4ERR_ATTRNOTSUPP =3D 10032, + NFS4ERR_NO_GRACE =3D 10033, + NFS4ERR_RECLAIM_BAD =3D 10034, + NFS4ERR_RECLAIM_CONFLICT =3D 10035, + NFS4ERR_BADXDR =3D 10036, + NFS4ERR_LOCKS_HELD =3D 10037, + NFS4ERR_OPENMODE =3D 10038, + NFS4ERR_BADOWNER =3D 10039, + NFS4ERR_BADCHAR =3D 10040, + NFS4ERR_BADNAME =3D 10041, + NFS4ERR_BAD_RANGE =3D 10042, + NFS4ERR_LOCK_NOTSUPP =3D 10043, + NFS4ERR_OP_ILLEGAL =3D 10044, + NFS4ERR_DEADLOCK =3D 10045, + NFS4ERR_FILE_OPEN =3D 10046, + NFS4ERR_ADMIN_REVOKED =3D 10047, + NFS4ERR_CB_PATH_DOWN =3D 10048, + NFS4ERR_BADIOMODE =3D 10049, + NFS4ERR_BADLAYOUT =3D 10050, + NFS4ERR_BAD_SESSION_DIGEST =3D 10051, + NFS4ERR_BADSESSION =3D 10052, + NFS4ERR_BADSLOT =3D 10053, + NFS4ERR_COMPLETE_ALREADY =3D 10054, + NFS4ERR_CONN_NOT_BOUND_TO_SESSION =3D 10055, + NFS4ERR_DELEG_ALREADY_WANTED =3D 10056, + NFS4ERR_BACK_CHAN_BUSY =3D 10057, + NFS4ERR_LAYOUTTRYLATER =3D 10058, + NFS4ERR_LAYOUTUNAVAILABLE =3D 10059, + NFS4ERR_NOMATCHING_LAYOUT =3D 10060, + NFS4ERR_RECALLCONFLICT =3D 10061, + NFS4ERR_UNKNOWN_LAYOUTTYPE =3D 10062, + NFS4ERR_SEQ_MISORDERED =3D 10063, + NFS4ERR_SEQUENCE_POS =3D 10064, + NFS4ERR_REQ_TOO_BIG =3D 10065, + NFS4ERR_REP_TOO_BIG =3D 10066, + NFS4ERR_REP_TOO_BIG_TO_CACHE =3D 10067, + NFS4ERR_RETRY_UNCACHED_REP =3D 10068, + NFS4ERR_UNSAFE_COMPOUND =3D 10069, + NFS4ERR_TOO_MANY_OPS =3D 10070, + NFS4ERR_OP_NOT_IN_SESSION =3D 10071, + NFS4ERR_HASH_ALG_UNSUPP =3D 10072, + NFS4ERR_CLIENTID_BUSY =3D 10074, + NFS4ERR_PNFS_IO_HOLE =3D 10075, + NFS4ERR_SEQ_FALSE_RETRY =3D 10076, + NFS4ERR_BAD_HIGH_SLOT =3D 10077, + NFS4ERR_DEADSESSION =3D 10078, + NFS4ERR_ENCR_ALG_UNSUPP =3D 10079, + NFS4ERR_PNFS_NO_LAYOUT =3D 10080, + NFS4ERR_NOT_ONLY_OP =3D 10081, + NFS4ERR_WRONG_CRED =3D 10082, + NFS4ERR_WRONG_TYPE =3D 10083, + NFS4ERR_DIRDELEG_UNAVAIL =3D 10084, + NFS4ERR_REJECT_DELEG =3D 10085, + NFS4ERR_RETURNCONFLICT =3D 10086, + NFS4ERR_DELEG_REVOKED =3D 10087, + NFS4ERR_PARTNER_NOTSUPP =3D 10088, + NFS4ERR_PARTNER_NO_AUTH =3D 10089, + NFS4ERR_UNION_NOTSUPP =3D 10090, + NFS4ERR_OFFLOAD_DENIED =3D 10091, + NFS4ERR_WRONG_LFS =3D 10092, + NFS4ERR_BADLABEL =3D 10093, + NFS4ERR_OFFLOAD_NO_REQS =3D 10094, + NFS4ERR_NOXATTR =3D 10095, + NFS4ERR_XATTR2BIG =3D 10096, + NFS4ERR_FIRST_FREE =3D 10097, +}; + +typedef enum nfsstat4 nfsstat4; + +typedef opaque attrlist4; + typedef struct { u32 count; uint32_t *element; } bitmap4; =20 +typedef u8 verifier4[NFS4_VERIFIER_SIZE]; + +typedef uint64_t nfs_cookie4; + +typedef opaque nfs_fh4; + typedef opaque utf8string; =20 typedef utf8string utf8str_cis; @@ -26,11 +161,30 @@ typedef utf8string utf8str_cs; =20 typedef utf8string utf8str_mixed; =20 +typedef utf8str_cs component4; + +typedef utf8str_cs linktext4; + +typedef struct { + u32 count; + component4 *element; +} pathname4; + struct nfstime4 { int64_t seconds; uint32_t nseconds; }; =20 +struct fattr4 { + bitmap4 attrmask; + attrlist4 attr_vals; +}; + +struct stateid4 { + uint32_t seqid; + u8 other[12]; +}; + typedef bool fattr4_offline; =20 enum { FATTR4_OFFLINE =3D 83 }; @@ -216,11 +370,98 @@ enum { FATTR4_POSIX_DEFAULT_ACL =3D 91 }; =20 enum { FATTR4_POSIX_ACCESS_ACL =3D 92 }; =20 -#define NFS4_int64_t_sz \ - (XDR_hyper) +enum notify_type4 { + NOTIFY4_CHANGE_CHILD_ATTRS =3D 0, + NOTIFY4_CHANGE_DIR_ATTRS =3D 1, + NOTIFY4_REMOVE_ENTRY =3D 2, + NOTIFY4_ADD_ENTRY =3D 3, + NOTIFY4_RENAME_ENTRY =3D 4, + NOTIFY4_CHANGE_COOKIE_VERIFIER =3D 5, +}; + +typedef enum notify_type4 notify_type4; + +struct notify_entry4 { + component4 ne_file; + struct fattr4 ne_attrs; +}; + +struct prev_entry4 { + struct notify_entry4 pe_prev_entry; + nfs_cookie4 pe_prev_entry_cookie; +}; + +struct notify_remove4 { + struct notify_entry4 nrm_old_entry; + nfs_cookie4 nrm_old_entry_cookie; +}; + +struct notify_add4 { + struct { + u32 count; + struct notify_remove4 *element; + } nad_old_entry; + struct notify_entry4 nad_new_entry; + struct { + u32 count; + nfs_cookie4 *element; + } nad_new_entry_cookie; + struct { + u32 count; + struct prev_entry4 *element; + } nad_prev_entry; + bool nad_last_entry; +}; + +struct notify_attr4 { + struct notify_entry4 na_changed_entry; +}; + +struct notify_rename4 { + struct notify_remove4 nrn_old_entry; + struct notify_add4 nrn_new_entry; +}; + +struct notify_verifier4 { + verifier4 nv_old_cookieverf; + verifier4 nv_new_cookieverf; +}; + +typedef opaque notifylist4; + +struct notify4 { + bitmap4 notify_mask; + notifylist4 notify_vals; +}; + +struct CB_NOTIFY4args { + struct stateid4 cna_stateid; + nfs_fh4 cna_fh; + struct { + u32 count; + struct notify4 *element; + } cna_changes; +}; + +struct CB_NOTIFY4res { + nfsstat4 cnr_status; +}; + +#define NFS4_int32_t_sz \ + (XDR_int) #define NFS4_uint32_t_sz \ (XDR_unsigned_int) +#define NFS4_int64_t_sz \ + (XDR_hyper) +#define NFS4_uint64_t_sz \ + (XDR_unsigned_hyper) +#define NFS4_nfsstat4_sz (XDR_int) +#define NFS4_attrlist4_sz (XDR_unsigned_int) #define NFS4_bitmap4_sz (XDR_unsigned_int) +#define NFS4_verifier4_sz (XDR_QUADLEN(NFS4_VERIFIER_SIZE)) +#define NFS4_nfs_cookie4_sz \ + (NFS4_uint64_t_sz) +#define NFS4_nfs_fh4_sz (XDR_unsigned_int + XDR_QUADLEN(NF= S4_FHSIZE)) #define NFS4_utf8string_sz (XDR_unsigned_int) #define NFS4_utf8str_cis_sz \ (NFS4_utf8string_sz) @@ -228,8 +469,17 @@ enum { FATTR4_POSIX_ACCESS_ACL =3D 92 }; (NFS4_utf8string_sz) #define NFS4_utf8str_mixed_sz \ (NFS4_utf8string_sz) +#define NFS4_component4_sz \ + (NFS4_utf8str_cs_sz) +#define NFS4_linktext4_sz \ + (NFS4_utf8str_cs_sz) +#define NFS4_pathname4_sz (XDR_unsigned_int) #define NFS4_nfstime4_sz \ (NFS4_int64_t_sz + NFS4_uint32_t_sz) +#define NFS4_fattr4_sz \ + (NFS4_bitmap4_sz + NFS4_attrlist4_sz) +#define NFS4_stateid4_sz \ + (NFS4_uint32_t_sz + XDR_QUADLEN(12)) #define NFS4_fattr4_offline_sz \ (XDR_bool) #define NFS4_open_arguments4_sz \ @@ -259,5 +509,27 @@ enum { FATTR4_POSIX_ACCESS_ACL =3D 92 }; (NFS4_aclscope4_sz) #define NFS4_fattr4_posix_default_acl_sz (XDR_unsigned_int) #define NFS4_fattr4_posix_access_acl_sz (XDR_unsigned_int) +#define NFS4_notify_type4_sz (XDR_int) +#define NFS4_notify_entry4_sz \ + (NFS4_component4_sz + NFS4_fattr4_sz) +#define NFS4_prev_entry4_sz \ + (NFS4_notify_entry4_sz + NFS4_nfs_cookie4_sz) +#define NFS4_notify_remove4_sz \ + (NFS4_notify_entry4_sz + NFS4_nfs_cookie4_sz) +#define NFS4_notify_add4_sz \ + (XDR_unsigned_int + (1 * (NFS4_notify_remove4_sz)) + NFS4_notify_entry4_s= z + XDR_unsigned_int + (1 * (NFS4_nfs_cookie4_sz)) + XDR_unsigned_int + (1 = * (NFS4_prev_entry4_sz)) + XDR_bool) +#define NFS4_notify_attr4_sz \ + (NFS4_notify_entry4_sz) +#define NFS4_notify_rename4_sz \ + (NFS4_notify_remove4_sz + NFS4_notify_add4_sz) +#define NFS4_notify_verifier4_sz \ + (NFS4_verifier4_sz + NFS4_verifier4_sz) +#define NFS4_notifylist4_sz (XDR_unsigned_int) +#define NFS4_notify4_sz \ + (NFS4_bitmap4_sz + NFS4_notifylist4_sz) +#define NFS4_CB_NOTIFY4args_sz \ + (NFS4_stateid4_sz + NFS4_nfs_fh4_sz + XDR_unsigned_int) +#define NFS4_CB_NOTIFY4res_sz \ + (NFS4_nfsstat4_sz) =20 #endif /* _LINUX_XDRGEN_NFS4_1_DEF_H */ diff --git a/include/uapi/linux/nfs4.h b/include/uapi/linux/nfs4.h index 4273e0249fcb..289205b53a08 100644 --- a/include/uapi/linux/nfs4.h +++ b/include/uapi/linux/nfs4.h @@ -17,11 +17,9 @@ #include =20 #define NFS4_BITMAP_SIZE 3 -#define NFS4_VERIFIER_SIZE 8 #define NFS4_STATEID_SEQID_SIZE 4 #define NFS4_STATEID_OTHER_SIZE 12 #define NFS4_STATEID_SIZE (NFS4_STATEID_SEQID_SIZE + NFS4_STATEID_OTHER_SI= ZE) -#define NFS4_FHSIZE 128 #define NFS4_MAXPATHLEN PATH_MAX #define NFS4_MAXNAMLEN NAME_MAX #define NFS4_OPAQUE_LIMIT 1024 --=20 2.53.0 From nobody Sun Jun 21 04:17:36 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 380273B776D; Tue, 7 Apr 2026 13:22:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568154; cv=none; b=F+D5HuqHpGI4CldvrsgbQObW7IBSwyhDX7NAnq3g/R9UkqOthqQsbmbB1yOsoSC1RXm66J9NWZ9fdpEcm79lY+YuTOmpCJ6DMqk/cBRJ29mOLYkarQUsP6LWgRChUa1Xko7NXBYW1q+EmL5WCiBOSYg7sZ17371TmbHIF2Lv6IY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568154; c=relaxed/simple; bh=s72czDExX6Nxo4FsO43XYOw6JoIhVcsInWaSiqS9x8k=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=eE+IjWe9ulwMJqFmpQWZx1O0UcrRcIYqY9AbEeHXYgEZNG+4njtEe7dkZ/FQ35LVOgHR+YDIEfOkqNiRY/5DFoSvAAkTTYcE1vfhYnCrF/F1s9/c/lQumnOjeouF0LU1IuPwWlIKfbQgkYhsHD2c1nRtok6gH5JDxQVT9iXosNY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=BmX2GhNg; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="BmX2GhNg" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C478EC19424; Tue, 7 Apr 2026 13:22:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775568153; bh=s72czDExX6Nxo4FsO43XYOw6JoIhVcsInWaSiqS9x8k=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=BmX2GhNg+YeOU0bdReSPfQ0/Rff1lo4evHPQfA+copgE0hqqJeQpTdjVyCs4eZ/1U Nbp6UbpwUGhpEMzN3m6Bz+3l2JVRtDoD/hE1PQaP8WU7edDgRi5D1JfIfHOjwfEsbo MZC/Pk+tAPyZBNWHDovjJClcyg7aFTDI9LxotD7e5YV+2N+pNih8Y3YFtuZErYlsFc K3pfH53gEfGnASsbrdzwrKJIJgN020cuHPJQGsJHjAFz7IbjFj9GpHrFApS/on7lcT XwFAIFykfgYMmNsPXfYRvwUmaRuZtxwFsLVjaIhxbmZbasGaeXsBepiP0kh5vtOQm0 JCSIM2nyZcxlg== From: Jeff Layton Date: Tue, 07 Apr 2026 09:21:18 -0400 Subject: [PATCH 05/24] nfs_common: add new NOTIFY4_* flags proposed in RFC8881bis Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260407-dir-deleg-v1-5-aaf68c478abd@kernel.org> References: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> In-Reply-To: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Amir Goldstein Cc: Calum Mackay , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=4154; i=jlayton@kernel.org; h=from:subject:message-id; bh=s72czDExX6Nxo4FsO43XYOw6JoIhVcsInWaSiqS9x8k=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp1QUECx/KiVHXKW5X8pF4bvevF+j3VX8+5bHtA ceX+YT/M4mJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCadUFBAAKCRAADmhBGVaC FeEwD/97dZJG2ZbHEKg253lB9zwuX7cR/nlizRlZSC31hvvy9AfS6wCxAxBlvHq8d+f9EUcFCWx v1e+55mLcD+7pvNfylf2LhoTvQjUJ8jcCRxfasVDkUKFdx1q7zs9Y7+PIRIcN5a2VdaFvjKWKgb 6vYRquWptJs2GtQ7xcxQLxCIO/kqkuBpi/k0tw29vJLsLE72PL2in/Z3Q7QLSR6ho4Ded0oa737 7Ev8Yy98EtXwS3r2WSvgjLcMdLJy/gXNM6JAV1ISYTu33Aw2295c8YEkUmxhioCJ8ByeQFmGXVp 2AgtANbjZCbUzznpOdlQMF/jPSh9VbLczSDCY2nNqjRljYNXA6pttfMxVT/qJkzjjUtSfDspIVs aG8LajilTr1SmDRx0j8PYBD0Khe0sJotjZXa3oi8i55uVrQLvXcvn6rb2MjOKUy86RwSn7+fHny B7t7GfFVjAWM/af31TOlT5n1M1RoPmS4Utz4TnoQCL5m0UoBLZTD/DhfpgXdhz+jtWddjY+uGBq jZm8tysTh5GasvZfuYkjFJMWNkCKyGvp1yakQ/WtRn6NPvUny1wyXpDb6zl7G1vJrKj+fyhExr9 iIRPV3TS0X9wHkZh+ClOVcKet/b0WGPshoXZkI7Nx/1ueAn58iHFjLao7ul6qafvsPdBlxA4jua RWObhkGi3M2q0Rw== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 RFC8881bis adds some new flags to GET_DIR_DELEGATION that we very much need to support. Signed-off-by: Jeff Layton --- Documentation/sunrpc/xdr/nfs4_1.x | 16 +++++++++++++++- fs/nfsd/nfs4xdr_gen.c | 13 ++++++++++++- fs/nfsd/nfs4xdr_gen.h | 2 +- include/linux/sunrpc/xdrgen/nfs4_1.h | 13 ++++++++++++- 4 files changed, 40 insertions(+), 4 deletions(-) diff --git a/Documentation/sunrpc/xdr/nfs4_1.x b/Documentation/sunrpc/xdr/n= fs4_1.x index 632f5b579c39..aa14b590b524 100644 --- a/Documentation/sunrpc/xdr/nfs4_1.x +++ b/Documentation/sunrpc/xdr/nfs4_1.x @@ -416,7 +416,21 @@ enum notify_type4 { NOTIFY4_REMOVE_ENTRY =3D 2, NOTIFY4_ADD_ENTRY =3D 3, NOTIFY4_RENAME_ENTRY =3D 4, - NOTIFY4_CHANGE_COOKIE_VERIFIER =3D 5 + NOTIFY4_CHANGE_COOKIE_VERIFIER =3D 5, + /* + * Added in NFSv4.1 bis document + */ + NOTIFY4_GFLAG_EXTEND =3D 6, + NOTIFY4_AUFLAG_VALID =3D 7, + NOTIFY4_AUFLAG_USER =3D 8, + NOTIFY4_AUFLAG_GROUP =3D 9, + NOTIFY4_AUFLAG_OTHER =3D 10, + NOTIFY4_CHANGE_AUTH =3D 11, + NOTIFY4_CFLAG_ORDER =3D 12, + NOTIFY4_AUFLAG_GANOW =3D 13, + NOTIFY4_AUFLAG_GALATER =3D 14, + NOTIFY4_CHANGE_GA =3D 15, + NOTIFY4_CHANGE_AMASK =3D 16 }; =20 /* Changed entry information. */ diff --git a/fs/nfsd/nfs4xdr_gen.c b/fs/nfsd/nfs4xdr_gen.c index 5e656d6bbb8e..80369139ef7e 100644 --- a/fs/nfsd/nfs4xdr_gen.c +++ b/fs/nfsd/nfs4xdr_gen.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 // Generated by xdrgen. Manual edits will be lost. // XDR specification file: ../../Documentation/sunrpc/xdr/nfs4_1.x -// XDR specification modification time: Wed Mar 25 11:39:22 2026 +// XDR specification modification time: Wed Mar 25 11:40:02 2026 =20 #include =20 @@ -590,6 +590,17 @@ xdrgen_decode_notify_type4(struct xdr_stream *xdr, not= ify_type4 *ptr) case NOTIFY4_ADD_ENTRY: case NOTIFY4_RENAME_ENTRY: case NOTIFY4_CHANGE_COOKIE_VERIFIER: + case NOTIFY4_GFLAG_EXTEND: + case NOTIFY4_AUFLAG_VALID: + case NOTIFY4_AUFLAG_USER: + case NOTIFY4_AUFLAG_GROUP: + case NOTIFY4_AUFLAG_OTHER: + case NOTIFY4_CHANGE_AUTH: + case NOTIFY4_CFLAG_ORDER: + case NOTIFY4_AUFLAG_GANOW: + case NOTIFY4_AUFLAG_GALATER: + case NOTIFY4_CHANGE_GA: + case NOTIFY4_CHANGE_AMASK: break; default: return false; diff --git a/fs/nfsd/nfs4xdr_gen.h b/fs/nfsd/nfs4xdr_gen.h index 503fe2ccba51..092a1ed399c7 100644 --- a/fs/nfsd/nfs4xdr_gen.h +++ b/fs/nfsd/nfs4xdr_gen.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* Generated by xdrgen. Manual edits will be lost. */ /* XDR specification file: ../../Documentation/sunrpc/xdr/nfs4_1.x */ -/* XDR specification modification time: Wed Mar 25 11:39:22 2026 */ +/* XDR specification modification time: Wed Mar 25 11:40:02 2026 */ =20 #ifndef _LINUX_XDRGEN_NFS4_1_DECL_H #define _LINUX_XDRGEN_NFS4_1_DECL_H diff --git a/include/linux/sunrpc/xdrgen/nfs4_1.h b/include/linux/sunrpc/xd= rgen/nfs4_1.h index f761c3ddb4c7..537504069f24 100644 --- a/include/linux/sunrpc/xdrgen/nfs4_1.h +++ b/include/linux/sunrpc/xdrgen/nfs4_1.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* Generated by xdrgen. Manual edits will be lost. */ /* XDR specification file: ../../Documentation/sunrpc/xdr/nfs4_1.x */ -/* XDR specification modification time: Wed Mar 25 11:39:22 2026 */ +/* XDR specification modification time: Wed Mar 25 11:40:02 2026 */ =20 #ifndef _LINUX_XDRGEN_NFS4_1_DEF_H #define _LINUX_XDRGEN_NFS4_1_DEF_H @@ -377,6 +377,17 @@ enum notify_type4 { NOTIFY4_ADD_ENTRY =3D 3, NOTIFY4_RENAME_ENTRY =3D 4, NOTIFY4_CHANGE_COOKIE_VERIFIER =3D 5, + NOTIFY4_GFLAG_EXTEND =3D 6, + NOTIFY4_AUFLAG_VALID =3D 7, + NOTIFY4_AUFLAG_USER =3D 8, + NOTIFY4_AUFLAG_GROUP =3D 9, + NOTIFY4_AUFLAG_OTHER =3D 10, + NOTIFY4_CHANGE_AUTH =3D 11, + NOTIFY4_CFLAG_ORDER =3D 12, + NOTIFY4_AUFLAG_GANOW =3D 13, + NOTIFY4_AUFLAG_GALATER =3D 14, + NOTIFY4_CHANGE_GA =3D 15, + NOTIFY4_CHANGE_AMASK =3D 16, }; =20 typedef enum notify_type4 notify_type4; --=20 2.53.0 From nobody Sun Jun 21 04:17:36 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4EC6325D527; Tue, 7 Apr 2026 13:22:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568156; cv=none; b=F2aEbk5cXN3UrDRIz2CQofjSBRp02M4aomWG0d8nWH+EpDgZd6xGq1/13zDU3F+2UcFz1lZ2reiUPv7mxcmw0TPtZLrRYhkaCFCKAqimIePmMVHTRYnTZU8PkgBTvJAmZ+qKUymR1wGf/2c04lQO+qMHecJutTweTNM/atHMh7E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568156; c=relaxed/simple; bh=o+x2LCRljjVywCu2fUOpIb31IQvgXIq8do452s8pusw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=FfnHUHEPx8p2LrZYjCa7uIoQ1W1Y+YWsZfGJQ7BkQ3lY68lQvYIvgr5rFGXx3uQSHQyyB+gpQ+2e8SfH2b8vy5kpLaqF1z+byipO7MIrG+PLcG2I81uuFhwdXHR+gW2TdHyOr5jJ0hXVQ04GFMEpmbvmS8cZmf+wQwJX3prPPv0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=prUxAruW; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="prUxAruW" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1D580C116C6; Tue, 7 Apr 2026 13:22:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775568156; bh=o+x2LCRljjVywCu2fUOpIb31IQvgXIq8do452s8pusw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=prUxAruWTe/rhAxxTh+tk0VxwbzHQJ6PlHAfM1Yc01i+AgkhLWovhyYiPmdhCcRuy zO+bw5wndQgCg81t1GcDbdX6t1IfSk0y+cEKXmG0oEXeIP9r6LJYTsOPUovx5iNU9B TXxjC0f74kd+VaikEK+urJOwzr/gLAhtFUUV9LdMHErEz5q8u629mh98qINd0TIdlC IguPlkJ/FwnJrch1O18bxFCqGwUWTEpM+SETXiFE2G0YUp7vyuIEJJDE+z0VxKPPsz t+Q9iFwhj/ZYHYilgV7tLSrzWnK6x8dRGzBzLWgQlwsoMplHBmA2SLhkRAffmcZ5YS nLex3/B16Lr1Q== From: Jeff Layton Date: Tue, 07 Apr 2026 09:21:19 -0400 Subject: [PATCH 06/24] nfsd: allow nfsd to get a dir lease with an ignore mask Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260407-dir-deleg-v1-6-aaf68c478abd@kernel.org> References: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> In-Reply-To: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Amir Goldstein Cc: Calum Mackay , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=2342; i=jlayton@kernel.org; h=from:subject:message-id; bh=o+x2LCRljjVywCu2fUOpIb31IQvgXIq8do452s8pusw=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp1QUFStqft3I9/+53osV6YZkoIhpSZ9wLWB1Qj 1gi2wwZC4GJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCadUFBQAKCRAADmhBGVaC FVNdD/0QElF/ydNopPAGqjNQOt1Bdr5PxncTQVPsyyr53m3P+gzsFJJfeFhLMpH0/HIukPpTB/Q db8Qz3aplWW8Gt+6aB133jsudBKjCtyCiZGRx7YqZvnxiYKSUDY6awEEnfUt64Lnrb2Uc+zeb23 DglvZyHHmtXDZQGEOKnxijjyLOsfjFydBR/CEVwB0kVBQZbIGQBZ8O3x7MszgLFzmoOw2zWZbSs byQoZbkYOhRmCUMLguP+whyWPQrdbDAYnPe2sl/85pyLqsylSjaaVoxnhsQhdmwUJtWCBTgPh9G Wz1SCUF1+90eJMHSUlq0ylm2zitPJ6cqDkdiGMCDwssMvXZ4dzm6nN3taLUrOaXbZWRfQRwef0K aFnC/A0BLKMUsZAw4XwExBGlAXbQ1hLXhaX/ZLWSTnP9qOmhjPyCZuD3aQ6GgDPsySvKgIz59mt fgRTyBI9DXdqLVCoOFxO01YpzzwuPcR0GNySZ5KsJS+B4rx0s8MzWgC9L1sY4zap0kDUvqxsfmz 3YuNEaMkb79inTMR4scskfyzpEeGCsUt0FqjQGpPLT2MBX6NAg6U2nzx8mcUN7YYX/j6lnC9sMU eMKHGDsT5IyN7ihEHaLwd6zyL8ZsxN0212/Fn8NA17Y3lS3F00gBpEVRZ3UsR3rBfaYJBquHaLG qfZGTwZCWNZYdrA== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 When requesting a directory lease, enable the FL_IGN_DIR_* bits that correspond to the requested notification types. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4state.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index fa657badf5f8..c8fb84c38637 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -6021,7 +6021,22 @@ static bool nfsd4_cb_channel_good(struct nfs4_client= *clp) return clp->cl_minorversion && clp->cl_cb_state =3D=3D NFSD4_CB_UNKNOWN; } =20 -static struct file_lease *nfs4_alloc_init_lease(struct nfs4_delegation *dp) +static unsigned int +nfsd_notify_to_ignore(u32 notify) +{ + unsigned int mask =3D 0; + + if (notify & BIT(NOTIFY4_REMOVE_ENTRY)) + mask |=3D FL_IGN_DIR_DELETE; + if (notify & BIT(NOTIFY4_ADD_ENTRY)) + mask |=3D FL_IGN_DIR_CREATE; + if (notify & BIT(NOTIFY4_RENAME_ENTRY)) + mask |=3D FL_IGN_DIR_RENAME; + + return mask; +} + +static struct file_lease *nfs4_alloc_init_lease(struct nfs4_delegation *dp= , u32 notify) { struct file_lease *fl; =20 @@ -6029,7 +6044,7 @@ static struct file_lease *nfs4_alloc_init_lease(struc= t nfs4_delegation *dp) if (!fl) return NULL; fl->fl_lmops =3D &nfsd_lease_mng_ops; - fl->c.flc_flags =3D FL_DELEG; + fl->c.flc_flags =3D FL_DELEG | nfsd_notify_to_ignore(notify); fl->c.flc_type =3D deleg_is_read(dp->dl_type) ? F_RDLCK : F_WRLCK; fl->c.flc_owner =3D (fl_owner_t)dp; fl->c.flc_pid =3D current->tgid; @@ -6246,7 +6261,7 @@ nfs4_set_delegation(struct nfsd4_open *open, struct n= fs4_ol_stateid *stp, if (stp->st_stid.sc_export) dp->dl_stid.sc_export =3D exp_get(stp->st_stid.sc_export); =20 - fl =3D nfs4_alloc_init_lease(dp); + fl =3D nfs4_alloc_init_lease(dp, 0); if (!fl) goto out_clnt_odstate; =20 @@ -9612,12 +9627,11 @@ nfsd_get_dir_deleg(struct nfsd4_compound_state *cst= ate, dp->dl_stid.sc_export =3D exp_get(cstate->current_fh.fh_export); =20 - fl =3D nfs4_alloc_init_lease(dp); + fl =3D nfs4_alloc_init_lease(dp, gdd->gddr_notification[0]); if (!fl) goto out_put_stid; =20 - status =3D kernel_setlease(nf->nf_file, - fl->c.flc_type, &fl, NULL); + status =3D kernel_setlease(nf->nf_file, fl->c.flc_type, &fl, NULL); if (fl) locks_free_lease(fl); if (status) --=20 2.53.0 From nobody Sun Jun 21 04:17:36 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9550D3B8934; Tue, 7 Apr 2026 13:22:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568158; cv=none; b=i5gjeZkqo7zDfbP6f7LtoJe9qPvYzufWIYUCKxiY52+HHUrvdn0ybDrkddmiBE2XhDBpNH7D4Uy+2rbRxYcZCNaAx1DSdNj6Jor7L68r1zS1XzGlwWKdSce8E+3OsAgssJsgTveoI3RINYhb4KL6O2kyeDJ8LOOPh68BnH5PHu8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568158; c=relaxed/simple; bh=G2sTjncD1ODMIjiC0sw7aDKsTC8PNpiHd3OAW/OSY74=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=pVvbMUmjfPyPT1cnyMrvOSx/rZXeum1hHF2FwgZDMheSOG+lWwza1GkQiBHze9hTllIEMyACdC/P1tUk89JRWDRtvz6E45PE8+TgTH1xagU5Ya5F7mtEO85qT+uMfO8T/ZXADkgKnQiXOsta/it8zS2lpo6j2lVAPrPgAubX4dI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=d/fmlD77; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="d/fmlD77" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6B10DC19424; Tue, 7 Apr 2026 13:22:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775568158; bh=G2sTjncD1ODMIjiC0sw7aDKsTC8PNpiHd3OAW/OSY74=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=d/fmlD77hj6y3CQdcRftrUOI6UQG+8/aYiJTB50kcSEAx3lKMiEhBHMnC3tzYrdxQ 5//zqJGsKu+pGO4kPcVmm1XI0GAdNvl5QdUvmtpRBa2npsTcWKzZaXQ7rbQMuweRgh stBbcRCch0emVsSqOlQ2z8dcsToN69M2BJGpDlW0XhQsegfzYxiFqDcMzo1mfOiXSV Ra2CeLi46C7+KW1N/YciPVi9DlrDFJ+0nOFEc3mQtTSpSBAhV0jMIiNcF78O0InRZd E4NK2uvY2W1so/Gj9BLg+lcKatIqmKoNfemElI1aRwN2MXI2xr0R28w8lEi2iqRFrS 4HTypqhHsfp3g== From: Jeff Layton Date: Tue, 07 Apr 2026 09:21:20 -0400 Subject: [PATCH 07/24] vfs: add fsnotify_modify_mark_mask() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260407-dir-deleg-v1-7-aaf68c478abd@kernel.org> References: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> In-Reply-To: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Amir Goldstein Cc: Calum Mackay , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=2392; i=jlayton@kernel.org; h=from:subject:message-id; bh=G2sTjncD1ODMIjiC0sw7aDKsTC8PNpiHd3OAW/OSY74=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp1QUFkHA83FdGD+wNMWjDEyVzpvMG34AkOQlK4 SqWFNP00gSJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCadUFBQAKCRAADmhBGVaC FcZgEACjYLp79flnHlsvY6rgaXwBjFHjIZSar9TTiUE6odY31z3RM7LSYdNzelfPvyvbB0fcVMx f7rJ5VRsYT0UXiSzdSIN5y5qqnNHyq6rLyJ8E2YoPEjDRVftfReQ55ZlfaFZAmOkF+/iggphe8B xyLuqfNlG7O/vXU7MI/CyNmpqNaCPWQP4I4JUyi1nMJ5pZ3RBYzTpghxsHRJ+RbqhGfDZhsEQ/W N+Ad4U28AfDWQoU25q5aWH/ZmXZA2GDxYabrW9eIwZeLce6GDyKIRH7s28DSVzSxZJgqMNGcKVb e/QqKYwxadhn9FOM1lp2eyRIQnEL+n2I2X4j3MleJqG/fW9jKqHEDBX1Syk3Zttyo5iw+av0KML mdbEin5C4BpaGnM6vG2tb6nZw5VgRHMm1/fYlycUA0NbY6pAmipGAC2vLA/kT+H2x/FdK2hbZ4+ QNcwb1KNdfn4QOH7gm/Y1U6qGGZqvd4fS/6rh3/LmwhUz1bQ6HLa772v6ogJO0vuYdaYjvwmpN1 D5J4RPnvHxWRkM4vPEjfTzjYyxkmTRDV4V0qqo3f+U72qlyuma0ou2RsQ0/gJPIAsj2iv0rnlMX 6T3XyGUqHe0qn34TKY1xaCgcCKOWEYFxzBe2FRo3S8GZqOIvSnwm1+GpL8qfBg/hRWxaTsi4ak1 rz444NJ9RaurFUA== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 nfsd needs to be able to modify the mask on an existing mark when new directory delegations are set or unset. Add an exported function that allows the caller to set and clear bits in the mark->mask, and does the recalculation if something changed. Suggested-by: Jan Kara Signed-off-by: Jeff Layton Reviewed-by: Jan Kara --- fs/notify/mark.c | 29 +++++++++++++++++++++++++++++ include/linux/fsnotify_backend.h | 1 + 2 files changed, 30 insertions(+) diff --git a/fs/notify/mark.c b/fs/notify/mark.c index c2ed5b11b0fe..b1e73c6fd382 100644 --- a/fs/notify/mark.c +++ b/fs/notify/mark.c @@ -310,6 +310,35 @@ void fsnotify_recalc_mask(struct fsnotify_mark_connect= or *conn) fsnotify_conn_set_children_dentry_flags(conn); } =20 +/** + * fsnotify_modify_mark_mask - set and/or clear flags in a mark's mask + * @mark: mark to be modified + * @set: bits to be set in mask + * @clear: bits to be cleared in mask + * + * Modify a fsnotify_mark mask as directed, and update its associated conn. + * The caller is expected to hold a reference to the mark. + */ +void fsnotify_modify_mark_mask(struct fsnotify_mark *mark, u32 set, u32 cl= ear) +{ + bool recalc =3D false; + u32 mask; + + WARN_ON_ONCE(clear & set); + + spin_lock(&mark->lock); + mask =3D mark->mask; + mark->mask |=3D set; + mark->mask &=3D ~clear; + if (mark->mask !=3D mask) + recalc =3D true; + spin_unlock(&mark->lock); + + if (recalc) + fsnotify_recalc_mask(mark->connector); +} +EXPORT_SYMBOL_GPL(fsnotify_modify_mark_mask); + /* Free all connectors queued for freeing once SRCU period ends */ static void fsnotify_connector_destroy_workfn(struct work_struct *work) { diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_back= end.h index 95985400d3d8..66e185bd1b1b 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -917,6 +917,7 @@ extern void fsnotify_get_mark(struct fsnotify_mark *mar= k); extern void fsnotify_put_mark(struct fsnotify_mark *mark); extern void fsnotify_finish_user_wait(struct fsnotify_iter_info *iter_info= ); extern bool fsnotify_prepare_user_wait(struct fsnotify_iter_info *iter_inf= o); +extern void fsnotify_modify_mark_mask(struct fsnotify_mark *mark, u32 set,= u32 clear); =20 static inline void fsnotify_init_event(struct fsnotify_event *event) { --=20 2.53.0 From nobody Sun Jun 21 04:17:36 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DE2E53B7759; Tue, 7 Apr 2026 13:22:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568160; cv=none; b=i5J5HlLYJP5xWFm9ULsR7KIgqn5IgyUoi6QMTwP0b3RDxsV1wSysZxZzRGbZZr/fvr2FFke56GO0yNj7Jn8xSYmK9LpZBrN3OX/rvY3QcmXVZY4YclHpZAv01+pVGNfTDiiX+5E1BKNHW5g3Zd77xpugm4Kdn3Q4Qo7MmTSqnFg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568160; c=relaxed/simple; bh=OIY77SIo0TepOZn2Lbp/Z+oBVvNUrVSYNZ0dZ7ULTgs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=h6jlpkk1u2doNJOZKYizLLY1YC95yZbHIGDmMWwtQMF8tATwuUUe+YMmE9z2S8Idw6gmZ0do0xBWgYnRbXyavvYEuQPEiRzhRkV3PzSRLvMXj8iv2j+n3WgSSx1IenvQm/sI6aLHzhSAHlUhbz1XRs4GkPTj5FCet1rinC7yBDY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=GHY7U2w+; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="GHY7U2w+" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B5C62C19424; Tue, 7 Apr 2026 13:22:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775568160; bh=OIY77SIo0TepOZn2Lbp/Z+oBVvNUrVSYNZ0dZ7ULTgs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=GHY7U2w+/ngRFQ49BDULSjbJu6vVaQJonachwzkaCciCfHQzOSeC44vjGcxPyC5tM eQQy6bX9xX4r4h6sdA3rzTPd9K7JcIxjx3Nj6cOJ44vdpR0wBV6n5n7+2Bmc8FAwCs hTvhkfBSupQoaq2W3Gi2ezvLgIliKdBSDlzLD8gmTg8eTizF7LQ5ITr+E0RpTjWJrt Vtsx59U9DLPaWNVqAceFE342MfWtEDiXatXZgLyHvqN7oaCbPXO43K0g7B7JXsvHfV shzKqVeyQECC11lKX8JIw462G5N+GTP+ec2/Q09WKV8q0ge1UM5fhwGWyuVQYv21SV gjxaE8IrHBK+g== From: Jeff Layton Date: Tue, 07 Apr 2026 09:21:21 -0400 Subject: [PATCH 08/24] nfsd: update the fsnotify mark when setting or removing a dir delegation Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260407-dir-deleg-v1-8-aaf68c478abd@kernel.org> References: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> In-Reply-To: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Amir Goldstein Cc: Calum Mackay , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=2030; i=jlayton@kernel.org; h=from:subject:message-id; bh=OIY77SIo0TepOZn2Lbp/Z+oBVvNUrVSYNZ0dZ7ULTgs=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp1QUFdtgoPAdYLHuBKgS0Uu2s8rL4VBmNelNiN 2pRjxKa4zKJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCadUFBQAKCRAADmhBGVaC FRPdEACTtnF28Ax1HBFWpM+qQgY4KM6ZZ9Gq7Xm0SnWn3o0L6kGZ0c+KWnKw4hb47dFRP0JxKJ0 +OyFwwKYeSzB1Ckngu9zRmQvY90Y4IIsK3kgOWu+WZX6gclAZptAe8Eh+vJ2Kc54uWpHASuAR8J bgVwytzoOfPthh/CzuFsXT99jDOdg2jxxWHKOdw/WjQLdNkc/kh9S0r/r5wiPOccd2ZihmhI92Y mE/E9CYmOftRIhf6JMOBdsXvRfqGmiz3UHnEznCfdvRW2QEappvEXCwIcjpNX88ADmRbFbCDuND AaXHa00sp6t6l5xOoqp3Z7GICl+/u1q5mGF/UiPKLmnMEGE5BUC5mZFZfpUhLdY/8yckbHSLA0f bMdLWX1/ZztfS+SORSqXmLhy9AAE4wPlTnyTc3m4wx5aQTsudrNSA/yOMlL66ORzvFmUg2ieuDz cYZFuJDsHtwewoxQob9KlvkT+3u85AaigyPPGq5TBit5CYdTkMrkUgSMOT2pbmJjffGOZuMef/9 7Xa8wNPBPO0z5jnNQCINMGwAMRucPBLGr1rVuu9lL4q6Ra+nnsl/yHiL2XCO14lYmWkXK8IItaI r8G0rfgpYoJCO21dOyQh831cKMINEhKEtoD4MJcN2UYJVev/XexzmcmJpT0jtvnS1haa76ljSqX I0I7tYU4paIw4lw== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Add a new helper function that will update the mask on the nfsd_file's fsnotify_mark to be a union of all current directory delegations on an inode. Call that when directory delegations are added or removed. Signed-off-by: Jeff Layton Reviewed-by: Jan Kara --- fs/nfsd/nfs4state.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index c8fb84c38637..9a4cff08c67d 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -1258,6 +1258,37 @@ static void nfsd4_finalize_deleg_timestamps(struct n= fs4_delegation *dp, struct f } } =20 +static void nfsd_fsnotify_recalc_mask(struct nfsd_file *nf) +{ + struct fsnotify_mark *mark =3D &nf->nf_mark->nfm_mark; + struct inode *inode =3D file_inode(nf->nf_file); + u32 lease_mask, set =3D 0, clear =3D 0; + + /* This is only needed when adding or removing dir delegs */ + if (!S_ISDIR(inode->i_mode)) + return; + + /* Set up notifications for any ignored delegation events */ + lease_mask =3D inode_lease_ignore_mask(inode); + + if (lease_mask & FL_IGN_DIR_CREATE) + set |=3D FS_CREATE; + else + clear |=3D FS_CREATE; + + if (lease_mask & FL_IGN_DIR_DELETE) + set |=3D FS_DELETE; + else + clear |=3D FS_DELETE; + + if (lease_mask & FL_IGN_DIR_RENAME) + set |=3D FS_RENAME; + else + clear |=3D FS_RENAME; + + fsnotify_modify_mark_mask(mark, set, clear); +} + static void nfs4_unlock_deleg_lease(struct nfs4_delegation *dp) { struct nfs4_file *fp =3D dp->dl_stid.sc_file; @@ -1266,6 +1297,7 @@ static void nfs4_unlock_deleg_lease(struct nfs4_deleg= ation *dp) WARN_ON_ONCE(!fp->fi_delegees); =20 nfsd4_finalize_deleg_timestamps(dp, nf->nf_file); + nfsd_fsnotify_recalc_mask(nf); kernel_setlease(nf->nf_file, F_UNLCK, NULL, (void **)&dp); put_deleg_file(fp); } @@ -9652,6 +9684,7 @@ nfsd_get_dir_deleg(struct nfsd4_compound_state *cstat= e, =20 if (!status) { put_nfs4_file(fp); + nfsd_fsnotify_recalc_mask(nf); return dp; } =20 --=20 2.53.0 From nobody Sun Jun 21 04:17:36 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 61CC73B8955; Tue, 7 Apr 2026 13:22:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568163; cv=none; b=rr0hCj81Q7SHdnMKtE1w+njAndNB4EmwD5qbFlGhfMh5rYXr8Bb0CFO9e2dX/szZBXxNNcbSKiEVWd/hUcx2DkYPzm57pDkCm9wv8wLE7GL+w2J/QIja7bCUxlzH1mBfS63ghQMo3l1/Exocq82tTP0wONCeRBWpx0pr1nhDFw8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568163; c=relaxed/simple; bh=nd+D7JHwqvtqus2IrGozp20RqKgFY4Lczm6Ea+egZkM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=a83F8ry6zk3SYwothJqzuuOWZZXBYllHr0S8Wix4tAxUE/QQJ1rcpcPs7zjw7QzL998IFIadGr6FkDYlfFNmGKaq6qHrkNHey0vkpVXTukbqbdi8H1hb3rUcgG1937aNPKrZp2QfQL1QiZ5PSZG+8ubkSh3o0u8ritQYXZ8tfOg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=I9P3o+JX; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="I9P3o+JX" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0CA9CC2BCB3; Tue, 7 Apr 2026 13:22:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775568163; bh=nd+D7JHwqvtqus2IrGozp20RqKgFY4Lczm6Ea+egZkM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=I9P3o+JXZWPZ/DTmHCW2Vf6hiYoG3tPiHVrIsFR+SdEsCKHlLjzq26w5oRTqm9hGN 1xJcF+byZPIq/EO5ibrH+jnqlzP1EF5EIUHKWtGG3k+Dr0P50NjajzTzEKC/X0qJx8 ankkW+p3KnyKjaBWV2Cr5LktmUF9R9hinarEETBMWZVfZrpypiLFUlljkEuAaZ3yAh I0Ai4GL0bGnuXYig8UmV4kFgxyV9XQMjG+41GIioRSTp9B5MpPEpA1pEvNWmtH/P1O jLddwaac/NE6uwwIFufFLf9G6+htwUthvUSahzfOBgJk6b3i5QLCkSlL6wsx6lyv1u HcINqKeNOmTNA== From: Jeff Layton Date: Tue, 07 Apr 2026 09:21:22 -0400 Subject: [PATCH 09/24] nfsd: make nfsd4_callback_ops->prepare operation bool return Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260407-dir-deleg-v1-9-aaf68c478abd@kernel.org> References: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> In-Reply-To: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Amir Goldstein Cc: Calum Mackay , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=3301; i=jlayton@kernel.org; h=from:subject:message-id; bh=nd+D7JHwqvtqus2IrGozp20RqKgFY4Lczm6Ea+egZkM=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp1QUGYR4StIUmqXHYQ8LsRuehLLuNekfLhQJlv jtxN0K4/qGJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCadUFBgAKCRAADmhBGVaC FZKRD/9uXvtVIhYr54EY5zXd6T+Gdlz3VOubDXk35HryRF03Bbj9nB3/AgiDlw3j4ImF/r7bwzd N+vOEml1BWWZMFTe6MWpzqTm9hJtVp38VNLWG8g49NKACSbUxsJwdFatjowvWwhC61H+PlrYB7M ErbBVJQLOr7Nz5BOJD5/saTzbo3AUHQ9K1ANwhB1GCjxr7z6i/EkGLNaB9MUJPburkhK+X2Ao3l csa3/wwcKcEb8V2xWXnUqdZ+/K4ROZmWmA/7TeDT/I1MxosU8cbUQu9u9XkPkaT5Lbc/wzyl9iy 7NwRbNSHwbg8YKYkXcr907Ju2CsU4Kzs5nSc9E6merCUeNJOyxcU05svudBE2GlUWLFbmdwqeUw 2PfxMBEHnH6FL4am3zEbcNlX28GEgVXKi1Sdatkxrb/IzFE3fAZEvsZSLMH6hcrl5aOw6nrA804 wjecIOckBxyCxvQHMeNII0SLKrvIvMxEtfuaHaMyZCdcIhXZU+xe71J8NM24ODS2XcDl9Wp7Eo2 +xLm7JHezp8kO8Snoq5lXINWfz9qEs1xUqH3CXgznZ3Zst13TSyClH+fBPL4mpaHAhCYQ76+w6K mRGYJLDbRUIQG02c5UiGxnGgNgpwFIBX8goOeBkFE6TzfVo4AekTVjrOntxp5YCKklzrmKmKDDZ KysNvESejl9oiBg== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 For a CB_NOTIFY operation, we need to stop processing the callback if an allocation fails. Change the ->prepare callback operation to return true if processing should continue, and false otherwise. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4callback.c | 5 ++++- fs/nfsd/nfs4layouts.c | 3 ++- fs/nfsd/nfs4state.c | 6 ++++-- fs/nfsd/state.h | 6 +++--- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index 50827405468d..25bbf5b8814d 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c @@ -1715,7 +1715,10 @@ nfsd4_run_cb_work(struct work_struct *work) =20 if (!test_and_clear_bit(NFSD4_CALLBACK_REQUEUE, &cb->cb_flags)) { if (cb->cb_ops && cb->cb_ops->prepare) - cb->cb_ops->prepare(cb); + if (!cb->cb_ops->prepare(cb)) { + nfsd41_destroy_cb(cb); + return; + } } =20 cb->cb_msg.rpc_cred =3D clp->cl_cb_cred; diff --git a/fs/nfsd/nfs4layouts.c b/fs/nfsd/nfs4layouts.c index c550b83f4432..8974e3d85d75 100644 --- a/fs/nfsd/nfs4layouts.c +++ b/fs/nfsd/nfs4layouts.c @@ -654,7 +654,7 @@ nfsd4_cb_layout_fail(struct nfs4_layout_stateid *ls, st= ruct nfsd_file *file) } } =20 -static void +static bool nfsd4_cb_layout_prepare(struct nfsd4_callback *cb) { struct nfs4_layout_stateid *ls =3D @@ -663,6 +663,7 @@ nfsd4_cb_layout_prepare(struct nfsd4_callback *cb) mutex_lock(&ls->ls_mutex); nfs4_inc_and_copy_stateid(&ls->ls_recall_sid, &ls->ls_stid); mutex_unlock(&ls->ls_mutex); + return true; } =20 static int diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 9a4cff08c67d..fd3d7cd427e1 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -355,12 +355,13 @@ remove_blocked_locks(struct nfs4_lockowner *lo) } } =20 -static void +static bool nfsd4_cb_notify_lock_prepare(struct nfsd4_callback *cb) { struct nfsd4_blocked_lock *nbl =3D container_of(cb, struct nfsd4_blocked_lock, nbl_cb); locks_delete_block(&nbl->nbl_lock); + return true; } =20 static int @@ -5538,7 +5539,7 @@ bool nfsd_wait_for_delegreturn(struct svc_rqst *rqstp= , struct inode *inode) return timeo > 0; } =20 -static void nfsd4_cb_recall_prepare(struct nfsd4_callback *cb) +static bool nfsd4_cb_recall_prepare(struct nfsd4_callback *cb) { struct nfs4_delegation *dp =3D cb_to_delegation(cb); struct nfsd_net *nn =3D net_generic(dp->dl_stid.sc_client->net, @@ -5559,6 +5560,7 @@ static void nfsd4_cb_recall_prepare(struct nfsd4_call= back *cb) list_add_tail(&dp->dl_recall_lru, &nn->del_recall_lru); } spin_unlock(&nn->deleg_lock); + return true; } =20 static int nfsd4_cb_recall_done(struct nfsd4_callback *cb, diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 811c148f36fc..7d2afe7dcc3e 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -98,9 +98,9 @@ struct nfsd4_callback { }; =20 struct nfsd4_callback_ops { - void (*prepare)(struct nfsd4_callback *); - int (*done)(struct nfsd4_callback *, struct rpc_task *); - void (*release)(struct nfsd4_callback *); + bool (*prepare)(struct nfsd4_callback *cb); + int (*done)(struct nfsd4_callback *cb, struct rpc_task *task); + void (*release)(struct nfsd4_callback *cb); uint32_t opcode; }; =20 --=20 2.53.0 From nobody Sun Jun 21 04:17:36 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BB4B63B9D8C; Tue, 7 Apr 2026 13:22:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568165; cv=none; b=ghk9IurjDnFehRi0wHpxGWB0ak/PHeH9doNWwGvVb2TcJ/nB2fNy9TL07pbGDjkvt14+947CqQ3Pyhcr1NVPPKhpFYqFOQqjZH4L0BtlAG5X9kgRHK+VxqmITnh4MqGNW9Be0Dqa/dNAV2IXO6WiLayRJEjBll6A3bAPq9u5s90= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568165; c=relaxed/simple; bh=QsfWLs2tuIZnRN7M+rne4mPXGqyvfLmtMwoip+RYIUc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=reEBi98IIOllzV84g19oGfI9J7du9rtyzlDC+7t8VcseOZ4b5RfFFYb3+qHK+APJZ77B2qkeF2YdORL+sykuqoO0AYJzesXFbA1hU1ihSpQ0yZd7dAvaLDR8gApfNZVReiAboukRkDpCY0XHNgOJ2nfjajgHOZtz42Gj9aA6v6c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=RxW1oL4I; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="RxW1oL4I" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 57780C19424; Tue, 7 Apr 2026 13:22:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775568165; bh=QsfWLs2tuIZnRN7M+rne4mPXGqyvfLmtMwoip+RYIUc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=RxW1oL4IZBowPtl0gZvIpDpo3h/HT7kNNvUc0kstM9e1pi+wdlYeavmx8twbMr7R1 aYu6NNwpoxXOMgUQrcvaNZ0o8DhAkBHUIMF4hRisjgeJV/9fNDPKXKjTmJzV2/JhGt aQCQF6V7hzDignfgMPTmFJ+Wn+Rsk1GUl9BiewxR/OM9j4yo9EEcosFvvr8a9ciJ0C Xp/PZyapPfB/FsNI+mU1hQDOkfZcXm87sJX8/HNgiPwXPGMtIMUzQDpPHuX5/sqjod E9WLzeoKe740fBfmQmIO0AsBXiR3jJ9iAi6N3aVkKmbtWkBDMr2+0h7I7Jbl+zgHrj 1rZaBrNIJ378A== From: Jeff Layton Date: Tue, 07 Apr 2026 09:21:23 -0400 Subject: [PATCH 10/24] nfsd: add callback encoding and decoding linkages for CB_NOTIFY Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260407-dir-deleg-v1-10-aaf68c478abd@kernel.org> References: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> In-Reply-To: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Amir Goldstein Cc: Calum Mackay , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=3990; i=jlayton@kernel.org; h=from:subject:message-id; bh=QsfWLs2tuIZnRN7M+rne4mPXGqyvfLmtMwoip+RYIUc=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp1QUGGQBA59bo7BEIDhxHETnkunHictFtwHMbl xfsKUrQixOJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCadUFBgAKCRAADmhBGVaC FTXcEACW/CYK7/vpVn7qgSBZE+ENIo4OvJlBFQ7Lii/m9yQJGwPIPFZ6SP7R0tMY7lGVfv2K82K 1+ZM/O8BJ7xx8CGU3Ww2d4yv+LsWfWoFgkU1w4EncV1zHVRrHvan69yqrJ2AHof5JCz8fbK41uZ +v87NAzr/qXyRP2HaoxISq5PU5AfmrnsKCSd2DmU5gK0wTmcgEVtJwkHRpt+pA+t8te6ZIOYFfT Tmx1N+IZY8SmorIIDhC4evRL9Mhm/pb+zm4sETqPTOfu2ukpYopo+rFJ+vVClrAw2a3pBk2k/Z4 x1HvdRCy2Y/wFPTgvwUIdQNYJpmRepqboRZ9O3QToMz/Wvpuc4H7tiuPQIgLYtRDQQ6JsaFXfw0 HfZq/+N1Z71ij2Cg4tusYG9S0Q6PtsbNtWrGOjP1iR+LLi6uLNomLb1kzO/Hvj7HFHyPpre7f2R 4g3wliMECBABoYzMohgsATzJOJxSGNmgNXuHIpijFlAj2NPeCINlEgyJVMsdZedL3izLKj+/xwU GEqwnqxaVG2Y+VbG/GAnwlP4tZPHqVy6/5pYgL+pLrHX5d3I19du+eMe5nR7VYLQv2W54vbuscP dlBrqySUJwBPCxDUIca7TFSg10U0PmobL3GIVRV7RB5FwQ3pY3PuRn0TPotiM0cUrGoSZRpZBpe iyKxVEBvw0pIRiA== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Add routines for encoding and decoding CB_NOTIFY messages. These call into the code generated by xdrgen to do the actual encoding and decoding. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4callback.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ fs/nfsd/state.h | 8 ++++++++ fs/nfsd/xdr4cb.h | 12 ++++++++++++ 3 files changed, 66 insertions(+) diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index 25bbf5b8814d..ea3e7deb06fa 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c @@ -865,6 +865,51 @@ static void encode_stateowner(struct xdr_stream *xdr, = struct nfs4_stateowner *so xdr_encode_opaque(p, so->so_owner.data, so->so_owner.len); } =20 +static void nfs4_xdr_enc_cb_notify(struct rpc_rqst *req, + struct xdr_stream *xdr, + const void *data) +{ + const struct nfsd4_callback *cb =3D data; + struct nfs4_cb_compound_hdr hdr =3D { + .ident =3D 0, + .minorversion =3D cb->cb_clp->cl_minorversion, + }; + struct CB_NOTIFY4args args =3D { }; + + WARN_ON_ONCE(hdr.minorversion =3D=3D 0); + + encode_cb_compound4args(xdr, &hdr); + encode_cb_sequence4args(xdr, cb, &hdr); + + /* + * FIXME: get stateid and fh from delegation. Inline the cna_changes + * buffer, and zero it. + */ + WARN_ON_ONCE(!xdrgen_encode_CB_NOTIFY4args(xdr, &args)); + + hdr.nops++; + encode_cb_nops(&hdr); +} + +static int nfs4_xdr_dec_cb_notify(struct rpc_rqst *rqstp, + struct xdr_stream *xdr, + void *data) +{ + struct nfsd4_callback *cb =3D data; + struct nfs4_cb_compound_hdr hdr; + int status; + + status =3D decode_cb_compound4res(xdr, &hdr); + if (unlikely(status)) + return status; + + status =3D decode_cb_sequence4res(xdr, cb); + if (unlikely(status || cb->cb_seq_status)) + return status; + + return decode_cb_op_status(xdr, OP_CB_NOTIFY, &cb->cb_status); +} + static void nfs4_xdr_enc_cb_notify_lock(struct rpc_rqst *req, struct xdr_stream *xdr, const void *data) @@ -1026,6 +1071,7 @@ static const struct rpc_procinfo nfs4_cb_procedures[]= =3D { #ifdef CONFIG_NFSD_PNFS PROC(CB_LAYOUT, COMPOUND, cb_layout, cb_layout), #endif + PROC(CB_NOTIFY, COMPOUND, cb_notify, cb_notify), PROC(CB_NOTIFY_LOCK, COMPOUND, cb_notify_lock, cb_notify_lock), PROC(CB_OFFLOAD, COMPOUND, cb_offload, cb_offload), PROC(CB_RECALL_ANY, COMPOUND, cb_recall_any, cb_recall_any), diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 7d2afe7dcc3e..22c9a1e7d8fd 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -190,6 +190,13 @@ struct nfs4_cb_fattr { u64 ncf_cur_fsize; }; =20 +/* + * FIXME: the current backchannel encoder can't handle a send buffer longer + * than a single page (see bc_alloc/bc_free). + */ +#define NOTIFY4_EVENT_QUEUE_SIZE 3 +#define NOTIFY4_PAGE_ARRAY_SIZE 1 + /* * Represents a delegation stateid. The nfs4_client holds references to th= ese * and they are put when it is being destroyed or when the delegation is @@ -774,6 +781,7 @@ enum nfsd4_cb_op { NFSPROC4_CLNT_CB_NOTIFY_LOCK, NFSPROC4_CLNT_CB_RECALL_ANY, NFSPROC4_CLNT_CB_GETATTR, + NFSPROC4_CLNT_CB_NOTIFY, }; =20 /* Returns true iff a is later than b: */ diff --git a/fs/nfsd/xdr4cb.h b/fs/nfsd/xdr4cb.h index f4e29c0c701c..b06d0170d7c4 100644 --- a/fs/nfsd/xdr4cb.h +++ b/fs/nfsd/xdr4cb.h @@ -33,6 +33,18 @@ cb_sequence_dec_sz + \ op_dec_sz) =20 +#define NFS4_enc_cb_notify_sz (cb_compound_enc_hdr_sz + \ + cb_sequence_enc_sz + \ + 1 + enc_stateid_sz + \ + enc_nfs4_fh_sz + \ + 1 + \ + NOTIFY4_EVENT_QUEUE_SIZE * \ + (2 + (NFS4_OPAQUE_LIMIT >> 2))) + +#define NFS4_dec_cb_notify_sz (cb_compound_dec_hdr_sz + \ + cb_sequence_dec_sz + \ + op_dec_sz) + #define NFS4_enc_cb_notify_lock_sz (cb_compound_enc_hdr_sz + \ cb_sequence_enc_sz + \ 2 + 1 + \ --=20 2.53.0 From nobody Sun Jun 21 04:17:36 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 23B1C3B7B70; Tue, 7 Apr 2026 13:22:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568168; cv=none; b=pClbEnyVyh47wuYsR8ZXvG/kHFwnhCTbiNlSzF8XWnndfoSTM8OTK2N7wuQjQ4QRzBaTAvX7GWwW2K4O+tEIzAYEzVWpQRlSXLtmi6Bagh8iL858LVnQmbtxd/xi4fdvOXo3l1Ov1sJLM99dc3DmgFyBigxI68Yw9S8BmgeiE58= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568168; c=relaxed/simple; bh=6qtaDL3rkdEPWOgz3AFRqb0KZOdqrrkg/QLukDLfkwY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ozd0KsdiP8+PWA84Kwb1Ry3jC1IKW/Yvsyz8YhOmLrMmEypZRYrSnleT+cfua5oDrsvI3fj21Tqk0g9qKIWDeoqBP9aXWSN+jQnX5jtBoHMOAhmDlc3XVN6jJrj5Ay52uCEb1Bf2QYQyUYm5akPmEb6NzYgnn84nt6YbqLWozAg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=s7Iy/0my; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="s7Iy/0my" Received: by smtp.kernel.org (Postfix) with ESMTPSA id AA948C2BCAF; Tue, 7 Apr 2026 13:22:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775568167; bh=6qtaDL3rkdEPWOgz3AFRqb0KZOdqrrkg/QLukDLfkwY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=s7Iy/0myh2XoTiCGzTr7pAQfaJK8PQYpFUeuGIvtYrG15N4Z7/mInStwzfAmSZ3rY IlHhkckufO0oeL7Y8RS3u20t1VQ9DGYIb7wWjd9ow+jvw+pOrP1k5aLHNofIikfJYr 2DrBIydygTQgMN6vbKXdWHTIKW5gAySdWV6mUghwId1nzMlaGwQkKovcCKK5f5v4l/ M7lAuHj1ifCpTWv55/pv+HsOwfwtUf9rE69G2Epr35n0/Q9MR5Bbl/mMI7b3ORBn95 QMG7RDUa2UHFUQCSQh3IK0EHksrxjYCyaV/LCWcrbdHdbGhMsT4d9/FV1Ib5DjsCTB /Ca5hRUzjCo0A== From: Jeff Layton Date: Tue, 07 Apr 2026 09:21:24 -0400 Subject: [PATCH 11/24] nfsd: use RCU to protect fi_deleg_file Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260407-dir-deleg-v1-11-aaf68c478abd@kernel.org> References: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> In-Reply-To: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Amir Goldstein Cc: Calum Mackay , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=7799; i=jlayton@kernel.org; h=from:subject:message-id; bh=6qtaDL3rkdEPWOgz3AFRqb0KZOdqrrkg/QLukDLfkwY=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp1QUGYsLcv0no2bvqBI0TQBweBQCeRNhjdIKsM F//SSRluBCJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCadUFBgAKCRAADmhBGVaC FZQQD/9C49RtvoS6zymbdCAB/rka0SQl/K0pcEq8pWo7l7vI4yB7n9Sd5hVvcbswURAnO2l7ZzR sQ09E8GutBut2RO+JYywjLPRnON0lJcWSnles715SSzc07/f+oSThCZU2tux1qNahfxuZ4lI1mv Qgj4Z0byOz3dRB+SGmxAAn0WFWiPyj8BKxUG7i7DAPGMibim0Ujur1Ro/MdPUmHN9qDMSSu1Nhq tk9vH8D9h2zipEg8+oTzJtlvHX1MVBLSQSeX38F1MVxkovQ7dtzdrA8TF0BO61JfSvrrZeIgW+U sGpjTThravizuS6l55nk1zm7JYYx3NuHvacpJ/Ox+Jaq9PKa2vIqNvMAkcLMOGK2HZtZltJvkB2 /ZBmN0c+wPrx9d+rIHb1M1L3+fuXkymR9ztCyvxKaw/1EQt2OhUahkjOnldwBq4Dht52K6tCdmq 65NEyNFu/JHNleEVVCvgj03YJFSRxU/NeyH5aCobi4A1b+MU8vqoNu6Y+Gfn8lZjE9a52asfYwJ o8ghx4MKIzjQF/aj9f9ouF/RD+YPMd3OD95q9Mb4pJcCQTo2b2BZIUBV/blJdObQNNevXDSlGsJ Herp9GGimDW/I5FoXNo8WA+YPPxJRBaXPv5MPen5CxcM4BIam92FehAxdyWoCl6e4uozK8qzBIi hBSMHMrqsMFRbGg== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 fi_deleg_file can be NULLed by put_deleg_file() when fi_delegees drops to zero during delegation teardown (e.g. DELEGRETURN). Concurrent accesses from workqueue callbacks -- such as CB_NOTIFY -- can dereference a NULL pointer if they race with this teardown. Annotate fi_deleg_file with __rcu and convert all accessors to use proper RCU primitives: - rcu_assign_pointer() / RCU_INIT_POINTER() for stores - rcu_dereference_protected() for reads under fi_lock or where fi_delegees > 0 guarantees stability This prepares for a subsequent patch that will use rcu_read_lock + rcu_dereference + nfsd_file_get to safely acquire a reference from the CB_NOTIFY callback path without holding fi_lock. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4layouts.c | 2 +- fs/nfsd/nfs4state.c | 40 ++++++++++++++++++++++++---------------- fs/nfsd/state.h | 2 +- 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/fs/nfsd/nfs4layouts.c b/fs/nfsd/nfs4layouts.c index 8974e3d85d75..d32cc6b38c23 100644 --- a/fs/nfsd/nfs4layouts.c +++ b/fs/nfsd/nfs4layouts.c @@ -248,7 +248,7 @@ nfsd4_alloc_layout_stateid(struct nfsd4_compound_state = *cstate, NFSPROC4_CLNT_CB_LAYOUT); =20 if (parent->sc_type =3D=3D SC_TYPE_DELEG) - ls->ls_file =3D nfsd_file_get(fp->fi_deleg_file); + ls->ls_file =3D nfsd_file_get(rcu_dereference_protected(fp->fi_deleg_fil= e, 1)); else ls->ls_file =3D find_any_file(fp); BUG_ON(!ls->ls_file); diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index fd3d7cd427e1..4afe7e68fb51 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -1210,7 +1210,9 @@ static void put_deleg_file(struct nfs4_file *fp) =20 spin_lock(&fp->fi_lock); if (--fp->fi_delegees =3D=3D 0) { - swap(nf, fp->fi_deleg_file); + nf =3D rcu_dereference_protected(fp->fi_deleg_file, + lockdep_is_held(&fp->fi_lock)); + rcu_assign_pointer(fp->fi_deleg_file, NULL); swap(rnf, fp->fi_rdeleg_file); } spin_unlock(&fp->fi_lock); @@ -1293,7 +1295,7 @@ static void nfsd_fsnotify_recalc_mask(struct nfsd_fil= e *nf) static void nfs4_unlock_deleg_lease(struct nfs4_delegation *dp) { struct nfs4_file *fp =3D dp->dl_stid.sc_file; - struct nfsd_file *nf =3D fp->fi_deleg_file; + struct nfsd_file *nf =3D rcu_dereference_protected(fp->fi_deleg_file, 1); =20 WARN_ON_ONCE(!fp->fi_delegees); =20 @@ -3159,7 +3161,8 @@ static int nfs4_show_deleg(struct seq_file *s, struct= nfs4_stid *st) /* XXX: lease time, whether it's being recalled. */ =20 spin_lock(&nf->fi_lock); - file =3D nf->fi_deleg_file; + file =3D rcu_dereference_protected(nf->fi_deleg_file, + lockdep_is_held(&nf->fi_lock)); if (file) { seq_puts(s, ", "); nfs4_show_superblock(s, file); @@ -4941,7 +4944,7 @@ static void nfsd4_file_init(const struct svc_fh *fh, = struct nfs4_file *fp) INIT_LIST_HEAD(&fp->fi_delegations); INIT_LIST_HEAD(&fp->fi_clnt_odstate); fh_copy_shallow(&fp->fi_fhandle, &fh->fh_handle); - fp->fi_deleg_file =3D NULL; + RCU_INIT_POINTER(fp->fi_deleg_file, NULL); fp->fi_rdeleg_file =3D NULL; fp->fi_had_conflict =3D false; fp->fi_share_deny =3D 0; @@ -6082,7 +6085,7 @@ static struct file_lease *nfs4_alloc_init_lease(struc= t nfs4_delegation *dp, u32 fl->c.flc_type =3D deleg_is_read(dp->dl_type) ? F_RDLCK : F_WRLCK; fl->c.flc_owner =3D (fl_owner_t)dp; fl->c.flc_pid =3D current->tgid; - fl->c.flc_file =3D dp->dl_stid.sc_file->fi_deleg_file->nf_file; + fl->c.flc_file =3D rcu_dereference_protected(dp->dl_stid.sc_file->fi_dele= g_file, 1)->nf_file; return fl; } =20 @@ -6090,7 +6093,7 @@ static int nfsd4_check_conflicting_opens(struct nfs4_= client *clp, struct nfs4_file *fp) { struct nfs4_ol_stateid *st; - struct file *f =3D fp->fi_deleg_file->nf_file; + struct file *f =3D rcu_dereference_protected(fp->fi_deleg_file, 1)->nf_fi= le; struct inode *ino =3D file_inode(f); int writes; =20 @@ -6167,7 +6170,7 @@ nfsd4_verify_deleg_dentry(struct nfsd4_open *open, st= ruct nfs4_file *fp, =20 exp_put(exp); dput(child); - if (child !=3D file_dentry(fp->fi_deleg_file->nf_file)) + if (child !=3D file_dentry(rcu_dereference_protected(fp->fi_deleg_file, 1= )->nf_file)) return -EAGAIN; =20 return 0; @@ -6273,8 +6276,9 @@ nfs4_set_delegation(struct nfsd4_open *open, struct n= fs4_ol_stateid *stp, status =3D -EAGAIN; else if (nfsd4_verify_setuid_write(open, nf)) status =3D -EAGAIN; - else if (!fp->fi_deleg_file) { - fp->fi_deleg_file =3D nf; + else if (!rcu_dereference_protected(fp->fi_deleg_file, + lockdep_is_held(&fp->fi_lock))) { + rcu_assign_pointer(fp->fi_deleg_file, nf); /* increment early to prevent fi_deleg_file from being * cleared */ fp->fi_delegees =3D 1; @@ -6299,7 +6303,7 @@ nfs4_set_delegation(struct nfsd4_open *open, struct n= fs4_ol_stateid *stp, if (!fl) goto out_clnt_odstate; =20 - status =3D kernel_setlease(fp->fi_deleg_file->nf_file, + status =3D kernel_setlease(rcu_dereference_protected(fp->fi_deleg_file, 1= )->nf_file, fl->c.flc_type, &fl, NULL); if (fl) locks_free_lease(fl); @@ -6320,7 +6324,7 @@ nfs4_set_delegation(struct nfsd4_open *open, struct n= fs4_ol_stateid *stp, * Now that the deleg is set, check again to ensure that nothing * raced in and changed the mode while we weren't looking. */ - status =3D nfsd4_verify_setuid_write(open, fp->fi_deleg_file); + status =3D nfsd4_verify_setuid_write(open, rcu_dereference_protected(fp->= fi_deleg_file, 1)); if (status) goto out_unlock; =20 @@ -6341,7 +6345,8 @@ nfs4_set_delegation(struct nfsd4_open *open, struct n= fs4_ol_stateid *stp, =20 return dp; out_unlock: - kernel_setlease(fp->fi_deleg_file->nf_file, F_UNLCK, NULL, (void **)&dp); + kernel_setlease(rcu_dereference_protected(fp->fi_deleg_file, 1)->nf_file, + F_UNLCK, NULL, (void **)&dp); out_clnt_odstate: put_clnt_odstate(dp->dl_clnt_odstate); nfs4_put_stid(&dp->dl_stid); @@ -6498,8 +6503,9 @@ nfs4_open_delegation(struct svc_rqst *rqstp, struct n= fsd4_open *open, memcpy(&open->op_delegate_stateid, &dp->dl_stid.sc_stateid, sizeof(dp->dl= _stid.sc_stateid)); =20 if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE) { - struct file *f =3D dp->dl_stid.sc_file->fi_deleg_file->nf_file; + struct file *f; =20 + f =3D rcu_dereference_protected(dp->dl_stid.sc_file->fi_deleg_file, 1)->= nf_file; if (!nfsd4_add_rdaccess_to_wrdeleg(rqstp, open, fh, stp) || !nfs4_delegation_stat(dp, currentfh, &stat)) { nfs4_put_stid(&dp->dl_stid); @@ -9638,8 +9644,9 @@ nfsd_get_dir_deleg(struct nfsd4_compound_state *cstat= e, /* existing delegation? */ if (nfs4_delegation_exists(clp, fp)) { status =3D -EAGAIN; - } else if (!fp->fi_deleg_file) { - fp->fi_deleg_file =3D nfsd_file_get(nf); + } else if (!rcu_dereference_protected(fp->fi_deleg_file, + lockdep_is_held(&fp->fi_lock))) { + rcu_assign_pointer(fp->fi_deleg_file, nfsd_file_get(nf)); fp->fi_delegees =3D 1; } else { ++fp->fi_delegees; @@ -9691,7 +9698,8 @@ nfsd_get_dir_deleg(struct nfsd4_compound_state *cstat= e, } =20 /* Something failed. Drop the lease and clean up the stid */ - kernel_setlease(fp->fi_deleg_file->nf_file, F_UNLCK, NULL, (void **)&dp); + kernel_setlease(rcu_dereference_protected(fp->fi_deleg_file, 1)->nf_file, + F_UNLCK, NULL, (void **)&dp); out_put_stid: nfs4_put_stid(&dp->dl_stid); out_delegees: diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 22c9a1e7d8fd..eb5946b0999e 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -698,7 +698,7 @@ struct nfs4_file { */ atomic_t fi_access[2]; u32 fi_share_deny; - struct nfsd_file *fi_deleg_file; + struct nfsd_file __rcu *fi_deleg_file; struct nfsd_file *fi_rdeleg_file; int fi_delegees; struct knfsd_fh fi_fhandle; --=20 2.53.0 From nobody Sun Jun 21 04:17:36 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 55CDA3B7B71; Tue, 7 Apr 2026 13:22:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568170; cv=none; b=n+Wg6CGa++LYHum5qJlKJtndVGkHjXqYJvRGnLQwvtR4/+ABDR17Qr+2ZjvFhHCNjxl3wAnOL2argczJI3bgzR9B7ScTSMXXC4N8/R6Uv/lOAtxkgtvNwhDzbOWfwnFiUyrOtuQ3m+W2x4eWUr1nSk3H7eqMuNReLRtSXKeVsUo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568170; c=relaxed/simple; bh=KI9Y73gpFpkREBJqDZaHuXcw1A6OI3TbZ6+Ci8pMqFc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=CpS1A3c5M7dI9M6lSW9p9Hu8y7wDKCULkOqNi8YdG0IlwEOXI4vzJvo76XM/OiloXiGKSslpOfHHNfwi1tfCaw3CCxwaGQ348kb1+zqkV46CmOnxaItGMpjy6LxKafuDXR2jMRkQwfe4KQuo0N7s/NnisGTTN06NdJh1hwXHZ0I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=sh17iT23; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="sh17iT23" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 03880C116C6; Tue, 7 Apr 2026 13:22:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775568170; bh=KI9Y73gpFpkREBJqDZaHuXcw1A6OI3TbZ6+Ci8pMqFc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=sh17iT23RohKQT5nPmE9xYPv7QFIYIaSi+QmBmk5Iaid24c/kI6h+70ZsV2M9idpQ NbmnMJj/T0rYc8eXgznDnU09zwQto/hlRLrqYP2Es7g/ZRGib0cANAoN0dcU0XPw4Y 8DIMAt85SMdxwJB+kIh9J3ghuw3jks7UrU/joXYyr4vgbXeXsiPKRdsi502b4+V3SD IlCRtQPcdNLGciRjddH+0rqhByUnwxOW56rhhI13061WV58QIVikD8z5uP2wJ1bugY +rVKRwteOpFkHEs2Y8phx3VYab2ScPI7dwpD+oBzA9RHWS2PuufWYkDR9ZrwSb7BKM IOqz4JQtoGZxQ== From: Jeff Layton Date: Tue, 07 Apr 2026 09:21:25 -0400 Subject: [PATCH 12/24] nfsd: add data structures for handling CB_NOTIFY Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260407-dir-deleg-v1-12-aaf68c478abd@kernel.org> References: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> In-Reply-To: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Amir Goldstein Cc: Calum Mackay , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=9027; i=jlayton@kernel.org; h=from:subject:message-id; bh=KI9Y73gpFpkREBJqDZaHuXcw1A6OI3TbZ6+Ci8pMqFc=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp1QUHPbJV2fy3FfTxF6+BUanjoTP5HQztisfaf sHKsVqncOuJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCadUFBwAKCRAADmhBGVaC FcScEACy+rF43hJ9TFJjTFnzIujKjQuzaohU8LprcdE2I72v6boOF/yOJB55+IgOR2l+W0vVOog G9mGmUDS1R+HWIBIs067V0Hq+8u1vknvnHJKp0xxCao2bkMKrK9D9wKkMVuhdSlhDV3pmXZTzZE ODtptmTKcoxNuxKQUpPjlFR6TUTtRsisZrFOVRumYQXymWXWbsUeIlz2ot2oebx4mi+vzEbTAl3 Gu6Sybfk5Wz37T5mYoq/OYmFK8/gHx0LgzsoSnaKoEfXrsgJIQn5XOHoZ+TJRQS9eJD4ODG9P+N Xc3AFVgWjrCJIuf8SvfRFXgmyYFGjAfAR0vNuqHRvdnE6DARqxLU2SCc2vFgkZ6ZtDqyMbjstVi 9AiNaN+f0akVpHILssHXT9zeX4yvurV/O5K/R8sWO9DRnDqnf1nor4WvraBLzAWXolVFmnN8Ljb bjD4P8ANTAsqIW2B4y3nj6FwAWZDRo3/88xN3Ol2qFtPflpGLTqB5zv5X2BwzpJscfnDRimunBZ 15PaQf1wE5BuDwAsStuDJtceVyN+HJjU0NJmBb1ySpwkl8n1EzHVegsdiJsm2ulqePZPgTFUMsy STVut9YcYH2Qe5peA/mIh+3NX4S9jfQLAwCXvXlZwYMXiutx2NEYS120Ak8xsFW6m1vK7FyaHha bTVcGPeQlaOWleQ== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Add the data structures, allocation helpers, and callback operations needed for directory delegation CB_NOTIFY support: - struct nfsd_notify_event: carries fsnotify events for CB_NOTIFY - struct nfsd4_cb_notify: per-delegation state for notification handling - Union dl_cb_fattr with dl_cb_notify in nfs4_delegation since a delegation is either a regular file delegation or a directory delegation, never both Refactor alloc_init_deleg() into a common __alloc_init_deleg() base with a pluggable sc_free callback, and add alloc_init_dir_deleg() which allocates the page array and notify4 buffer needed for CB_NOTIFY encoding. Add skeleton nfsd4_cb_notify_ops with done/release handlers that will be filled in when the notification path is wired up. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4state.c | 117 +++++++++++++++++++++++++++++++++++++++++++++---= ---- fs/nfsd/state.h | 46 ++++++++++++++++++++- 2 files changed, 147 insertions(+), 16 deletions(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 4afe7e68fb51..b2b8c454fc0f 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -124,6 +124,7 @@ static void free_session(struct nfsd4_session *); static const struct nfsd4_callback_ops nfsd4_cb_recall_ops; static const struct nfsd4_callback_ops nfsd4_cb_notify_lock_ops; static const struct nfsd4_callback_ops nfsd4_cb_getattr_ops; +static const struct nfsd4_callback_ops nfsd4_cb_notify_ops; =20 static struct workqueue_struct *laundry_wq; =20 @@ -1121,29 +1122,31 @@ static void block_delegations(struct knfsd_fh *fh) } =20 static struct nfs4_delegation * -alloc_init_deleg(struct nfs4_client *clp, struct nfs4_file *fp, - struct nfs4_clnt_odstate *odstate, u32 dl_type) +__alloc_init_deleg(struct nfs4_client *clp, struct nfs4_file *fp, + struct nfs4_clnt_odstate *odstate, u32 dl_type, + void (*sc_free)(struct nfs4_stid *)) { struct nfs4_delegation *dp; struct nfs4_stid *stid; long n; =20 - dprintk("NFSD alloc_init_deleg\n"); + if (delegation_blocked(&fp->fi_fhandle)) + return NULL; + n =3D atomic_long_inc_return(&num_delegations); if (n < 0 || n > max_delegations) goto out_dec; - if (delegation_blocked(&fp->fi_fhandle)) - goto out_dec; - stid =3D nfs4_alloc_stid(clp, deleg_slab, nfs4_free_deleg); + + stid =3D nfs4_alloc_stid(clp, deleg_slab, sc_free); if (stid =3D=3D NULL) goto out_dec; - dp =3D delegstateid(stid); =20 /* * delegation seqid's are never incremented. The 4.1 special * meaning of seqid 0 isn't meaningful, really, but let's avoid - * 0 anyway just for consistency and use 1: + * 0 anyway just for consistency and use 1. */ + dp =3D delegstateid(stid); dp->dl_stid.sc_stateid.si_generation =3D 1; INIT_LIST_HEAD(&dp->dl_perfile); INIT_LIST_HEAD(&dp->dl_perclnt); @@ -1153,19 +1156,75 @@ alloc_init_deleg(struct nfs4_client *clp, struct nf= s4_file *fp, dp->dl_type =3D dl_type; dp->dl_retries =3D 1; dp->dl_recalled =3D false; - nfsd4_init_cb(&dp->dl_recall, dp->dl_stid.sc_client, - &nfsd4_cb_recall_ops, NFSPROC4_CLNT_CB_RECALL); - nfsd4_init_cb(&dp->dl_cb_fattr.ncf_getattr, dp->dl_stid.sc_client, - &nfsd4_cb_getattr_ops, NFSPROC4_CLNT_CB_GETATTR); - dp->dl_cb_fattr.ncf_file_modified =3D false; get_nfs4_file(fp); dp->dl_stid.sc_file =3D fp; + nfsd4_init_cb(&dp->dl_recall, dp->dl_stid.sc_client, + &nfsd4_cb_recall_ops, NFSPROC4_CLNT_CB_RECALL); return dp; out_dec: atomic_long_dec(&num_delegations); return NULL; } =20 +static struct nfs4_delegation * +alloc_init_deleg(struct nfs4_client *clp, struct nfs4_file *fp, + struct nfs4_clnt_odstate *odstate, u32 dl_type) +{ + struct nfs4_delegation *dp; + + dp =3D __alloc_init_deleg(clp, fp, odstate, dl_type, nfs4_free_deleg); + if (!dp) + return NULL; + + nfsd4_init_cb(&dp->dl_cb_fattr.ncf_getattr, dp->dl_stid.sc_client, + &nfsd4_cb_getattr_ops, NFSPROC4_CLNT_CB_GETATTR); + dp->dl_cb_fattr.ncf_file_modified =3D false; + return dp; +} + +static void nfs4_free_dir_deleg(struct nfs4_stid *stid) +{ + struct nfs4_delegation *dp =3D delegstateid(stid); + struct nfsd4_cb_notify *ncn =3D &dp->dl_cb_notify; + int i; + + for (i =3D 0; i < ncn->ncn_evt_cnt; ++i) + nfsd_notify_event_put(ncn->ncn_evt[i]); + release_pages(ncn->ncn_pages, NOTIFY4_PAGE_ARRAY_SIZE); + kfree(ncn->ncn_nf); + nfs4_free_deleg(stid); +} + +static struct nfs4_delegation * +alloc_init_dir_deleg(struct nfs4_client *clp, struct nfs4_file *fp) +{ + struct nfs4_delegation *dp; + struct nfsd4_cb_notify *ncn; + int npages; + + dp =3D __alloc_init_deleg(clp, fp, NULL, NFS4_OPEN_DELEGATE_READ, nfs4_fr= ee_dir_deleg); + if (!dp) + return NULL; + + ncn =3D &dp->dl_cb_notify; + + npages =3D alloc_pages_bulk(GFP_KERNEL, NOTIFY4_PAGE_ARRAY_SIZE, ncn->ncn= _pages); + if (npages !=3D NOTIFY4_PAGE_ARRAY_SIZE) { + nfs4_free_dir_deleg(&dp->dl_stid); + return NULL; + } + + ncn->ncn_nf =3D kcalloc(NOTIFY4_EVENT_QUEUE_SIZE, sizeof(*ncn->ncn_nf), G= FP_KERNEL); + if (!ncn->ncn_nf) { + nfs4_free_dir_deleg(&dp->dl_stid); + return NULL; + } + spin_lock_init(&ncn->ncn_lock); + nfsd4_init_cb(&ncn->ncn_cb, dp->dl_stid.sc_client, + &nfsd4_cb_notify_ops, NFSPROC4_CLNT_CB_NOTIFY); + return dp; +} + void nfs4_put_stid(struct nfs4_stid *s) { @@ -3381,6 +3440,30 @@ nfsd4_cb_getattr_release(struct nfsd4_callback *cb) nfs4_put_stid(&dp->dl_stid); } =20 +static int +nfsd4_cb_notify_done(struct nfsd4_callback *cb, + struct rpc_task *task) +{ + switch (task->tk_status) { + case -NFS4ERR_DELAY: + rpc_delay(task, 2 * HZ); + return 0; + default: + return 1; + } +} + +static void +nfsd4_cb_notify_release(struct nfsd4_callback *cb) +{ + struct nfsd4_cb_notify *ncn =3D + container_of(cb, struct nfsd4_cb_notify, ncn_cb); + struct nfs4_delegation *dp =3D + container_of(ncn, struct nfs4_delegation, dl_cb_notify); + + nfs4_put_stid(&dp->dl_stid); +} + static const struct nfsd4_callback_ops nfsd4_cb_recall_any_ops =3D { .done =3D nfsd4_cb_recall_any_done, .release =3D nfsd4_cb_recall_any_release, @@ -3393,6 +3476,12 @@ static const struct nfsd4_callback_ops nfsd4_cb_geta= ttr_ops =3D { .opcode =3D OP_CB_GETATTR, }; =20 +static const struct nfsd4_callback_ops nfsd4_cb_notify_ops =3D { + .done =3D nfsd4_cb_notify_done, + .release =3D nfsd4_cb_notify_release, + .opcode =3D OP_CB_NOTIFY, +}; + static void nfs4_cb_getattr(struct nfs4_cb_fattr *ncf) { struct nfs4_delegation *dp =3D @@ -9661,7 +9750,7 @@ nfsd_get_dir_deleg(struct nfsd4_compound_state *cstat= e, =20 /* Try to set up the lease */ status =3D -ENOMEM; - dp =3D alloc_init_deleg(clp, fp, NULL, NFS4_OPEN_DELEGATE_READ); + dp =3D alloc_init_dir_deleg(clp, fp); if (!dp) goto out_delegees; if (cstate->current_fh.fh_export) diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index eb5946b0999e..500e07e47909 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -197,6 +197,44 @@ struct nfs4_cb_fattr { #define NOTIFY4_EVENT_QUEUE_SIZE 3 #define NOTIFY4_PAGE_ARRAY_SIZE 1 =20 +struct nfsd_notify_event { + refcount_t ne_ref; // refcount + u32 ne_mask; // FS_* mask from fsnotify callback + struct dentry *ne_dentry; // dentry reference to target + u32 ne_namelen; // length of ne_name + char ne_name[]; // name of dentry being changed +}; + +static inline struct nfsd_notify_event *nfsd_notify_event_get(struct nfsd_= notify_event *ne) +{ + refcount_inc(&ne->ne_ref); + return ne; +} + +static inline void nfsd_notify_event_put(struct nfsd_notify_event *ne) +{ + if (refcount_dec_and_test(&ne->ne_ref)) { + dput(ne->ne_dentry); + kfree(ne); + } +} + +/* + * Represents a directory delegation. The callback is for handling CB_NOTI= FYs. + * As notifications from fsnotify come in, allocate a new event, take the = ncn_lock, + * and add it to the ncn_evt queue. The CB_NOTIFY prepare handler will tak= e the + * lock, clean out the list and process it. + */ +struct nfsd4_cb_notify { + spinlock_t ncn_lock; // protects the evt queue and count + int ncn_evt_cnt; // count of events in ncn_evt + int ncn_nf_cnt; // count of valid entries in ncn_nf + struct nfsd_notify_event *ncn_evt[NOTIFY4_EVENT_QUEUE_SIZE]; // list of e= vents + struct page *ncn_pages[NOTIFY4_PAGE_ARRAY_SIZE]; // for encoding + struct notify4 *ncn_nf; // array of notify4's to be sent + struct nfsd4_callback ncn_cb; // notify4 callback +}; + /* * Represents a delegation stateid. The nfs4_client holds references to th= ese * and they are put when it is being destroyed or when the delegation is @@ -233,8 +271,12 @@ struct nfs4_delegation { bool dl_written; bool dl_setattr; =20 - /* for CB_GETATTR */ - struct nfs4_cb_fattr dl_cb_fattr; + union { + /* for CB_GETATTR */ + struct nfs4_cb_fattr dl_cb_fattr; + /* for CB_NOTIFY */ + struct nfsd4_cb_notify dl_cb_notify; + }; =20 /* For delegated timestamps */ struct timespec64 dl_atime; --=20 2.53.0 From nobody Sun Jun 21 04:17:36 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C17B03B8BC5; Tue, 7 Apr 2026 13:22:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568172; cv=none; b=ePF1ukP6Sqh8Ci0qDtCNqE/do+m9sTZvJtM02ojPdI+tnG5Gwy9SUGZeX2GD3yBHtAdYnruvodD/ecIi+kbKIFVHCNqid0UlmWHf5D7FXJNaKnQuM3kjRUZPGzF4Dw9MFrIwgxlx/J+0MnIFKFOd+WMbJoYTDCnlXHA8TVvMR/A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568172; c=relaxed/simple; bh=57qUbN0dfePHcj6mYPgbd1R10X/wovB9awMm4+f+0GE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=hbSSPfxyoUeOmyHyrkhmBjBkk3D+PqV1IGiUGRLTlodxfKjrUsGbn+3LCx57TRsY6AT9v+UBqbrCVgGGGEztLKCSj8CTonn5idQTOeEtYj8Ph5cdk8hPC5LYn1edeO5m4ihz6XyJ75WujgKV6P16lUXcnJhWdVnzAw9VNbO+M3U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=R5Je9+n9; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="R5Je9+n9" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4F154C4AF09; Tue, 7 Apr 2026 13:22:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775568172; bh=57qUbN0dfePHcj6mYPgbd1R10X/wovB9awMm4+f+0GE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=R5Je9+n95Ym4gvd5jxmNGtFqHpUKNd5K5500xpClMIqtxW3MuBIrCaAHPEv7lUgST VvIrRdC4l35V9eYk9NyiV9nKVVIlzw2pVEO9jK2r7M7u68dJTPoQRCjmlA50ae9QYs +9vxBcT16urwotuVhiuJ/clO6bB9MCEw3xGljziI2MsJTGBq/wksPQKSR3JabfmsQ8 BEWxhQ7XieiKhIxGWltN8VBEuPnpIdWr7sAUYtMAs94t21vDCIBE4DX8DzNeV5aUN2 UfsXB2FkgckVmXQBPAflEcGPA021DRHzoSMc2mkBU6HSpOUU5q9UhGICj0r946DDlr UI5ghOFGh7kXQ== From: Jeff Layton Date: Tue, 07 Apr 2026 09:21:26 -0400 Subject: [PATCH 13/24] nfsd: add notification handlers for dir events Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260407-dir-deleg-v1-13-aaf68c478abd@kernel.org> References: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> In-Reply-To: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Amir Goldstein Cc: Calum Mackay , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=20134; i=jlayton@kernel.org; h=from:subject:message-id; bh=57qUbN0dfePHcj6mYPgbd1R10X/wovB9awMm4+f+0GE=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp1QUHNWdvYIJ10kvQLbRVCRwqP29IccHMJkBRi XPngTp6CGyJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCadUFBwAKCRAADmhBGVaC FeeID/wLeCsjxZvIcYZR7sLEJD+DR+vJlmJr5LcXeSfGzyPDFaxnYJE7K+iat6Fz0eoglz5YKfV UYRv7MKop5BmudRpCZLb60V9uZ8m8O8HhXf11ad1uNquEfSjg7PGazAYtZVBWoXPETUXjWGhHQj QolvhRJ31ZX8ApS4QOehst+QRjk5kKRgmsMbzCkBkLBYnOa9ckNGUsa3Ua9iD678cYYWcqYzWzF 84Cgw4CYPlQXxTjYoRBKBbDWflZbsw7kUtM2O/zz2QQg0GkdPaVy6ij5d6PMpeI6vnwDnGwQunc FlEnPEK2nlPmIlo3YVHj+Ye3ZQjBlKJR8Qqryw+t7vqaXNLvvuwIKB7uDYMJWO8gFolsdzlzMSJ wNzlmkm0kOnnMn8O33DD1vPPGwo5uSc+tTrccmGALuwUlWcDl01FqLX1qqs2FeBRAVlbaAPnV3i 2zqRzuJ3OMZtocvn0od/fJn2eZR7eGD4/Ga8qtMVhjiYjljmZrqu7Ac4iGGscuPbzTmIAvzgPl/ V1MQXG5aIZlEXsYVU75JZKtDZ7CD7ABY0Z0dCFWvmlj8TJj9EpKbB8mQ2lHNabLtKoRb+vG5y69 vR9C93sS37p4PhKlm9UOJnwQVwZLVQ5kp38DcNKfVTur2ZcuzyS4+f3NKqd6Y9RbVeDtuYmS2Pb r7yxdUs/T3j2VQA== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Add the necessary parts to accept a fsnotify callback for directory change event and create a CB_NOTIFY request for it. When a dir nfsd_file is created set a handle_event callback to handle the notification. Use that to allocate a nfsd_notify_event object and then hand off a reference to each delegation's CB_NOTIFY. If anything fails along the way, recall any affected delegations. Signed-off-by: Jeff Layton --- fs/nfsd/filecache.c | 57 ++++++++---- fs/nfsd/nfs4callback.c | 19 +++- fs/nfsd/nfs4state.c | 248 ++++++++++++++++++++++++++++++++++++++++++++-= ---- fs/nfsd/nfs4xdr.c | 96 +++++++++++++++++++ fs/nfsd/state.h | 2 + fs/nfsd/xdr4.h | 3 + 6 files changed, 383 insertions(+), 42 deletions(-) diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c index 24511c3208db..56889fca6dca 100644 --- a/fs/nfsd/filecache.c +++ b/fs/nfsd/filecache.c @@ -72,6 +72,7 @@ static struct kmem_cache *nfsd_file_mark_slab; static struct list_lru nfsd_file_lru; static unsigned long nfsd_file_flags; static struct fsnotify_group *nfsd_file_fsnotify_group; +static struct fsnotify_group *nfsd_dir_fsnotify_group; static struct delayed_work nfsd_filecache_laundrette; static struct rhltable nfsd_file_rhltable ____cacheline_aligned_in_smp; @@ -147,7 +148,7 @@ static void nfsd_file_mark_put(struct nfsd_file_mark *nfm) { if (refcount_dec_and_test(&nfm->nfm_ref)) { - fsnotify_destroy_mark(&nfm->nfm_mark, nfsd_file_fsnotify_group); + fsnotify_destroy_mark(&nfm->nfm_mark, nfm->nfm_mark.group); fsnotify_put_mark(&nfm->nfm_mark); } } @@ -155,35 +156,37 @@ nfsd_file_mark_put(struct nfsd_file_mark *nfm) static struct nfsd_file_mark * nfsd_file_mark_find_or_create(struct inode *inode) { - int err; - struct fsnotify_mark *mark; struct nfsd_file_mark *nfm =3D NULL, *new; + struct fsnotify_group *group; + struct fsnotify_mark *mark; + int err; + + group =3D S_ISDIR(inode->i_mode) ? nfsd_dir_fsnotify_group : nfsd_file_fs= notify_group; =20 do { - fsnotify_group_lock(nfsd_file_fsnotify_group); - mark =3D fsnotify_find_inode_mark(inode, - nfsd_file_fsnotify_group); + fsnotify_group_lock(group); + mark =3D fsnotify_find_inode_mark(inode, group); if (mark) { nfm =3D nfsd_file_mark_get(container_of(mark, struct nfsd_file_mark, nfm_mark)); - fsnotify_group_unlock(nfsd_file_fsnotify_group); + fsnotify_group_unlock(group); if (nfm) { fsnotify_put_mark(mark); break; } /* Avoid soft lockup race with nfsd_file_mark_put() */ - fsnotify_destroy_mark(mark, nfsd_file_fsnotify_group); + fsnotify_destroy_mark(mark, group); fsnotify_put_mark(mark); } else { - fsnotify_group_unlock(nfsd_file_fsnotify_group); + fsnotify_group_unlock(group); } =20 /* allocate a new nfm */ new =3D kmem_cache_alloc(nfsd_file_mark_slab, GFP_KERNEL); if (!new) return NULL; - fsnotify_init_mark(&new->nfm_mark, nfsd_file_fsnotify_group); + fsnotify_init_mark(&new->nfm_mark, group); new->nfm_mark.mask =3D FS_ATTRIB|FS_DELETE_SELF; refcount_set(&new->nfm_ref, 1); =20 @@ -812,12 +815,25 @@ nfsd_file_fsnotify_handle_event(struct fsnotify_mark = *mark, u32 mask, return 0; } =20 +static int +nfsd_dir_fsnotify_handle_event(struct fsnotify_group *group, u32 mask, + const void *data, int data_type, struct inode *dir, + const struct qstr *name, u32 cookie, + struct fsnotify_iter_info *iter_info) +{ + return nfsd_handle_dir_event(mask, dir, data, data_type, name); +} =20 static const struct fsnotify_ops nfsd_file_fsnotify_ops =3D { .handle_inode_event =3D nfsd_file_fsnotify_handle_event, .free_mark =3D nfsd_file_mark_free, }; =20 +static const struct fsnotify_ops nfsd_dir_fsnotify_ops =3D { + .handle_event =3D nfsd_dir_fsnotify_handle_event, + .free_mark =3D nfsd_file_mark_free, +}; + int nfsd_file_cache_init(void) { @@ -869,8 +885,7 @@ nfsd_file_cache_init(void) goto out_shrinker; } =20 - nfsd_file_fsnotify_group =3D fsnotify_alloc_group(&nfsd_file_fsnotify_ops, - 0); + nfsd_file_fsnotify_group =3D fsnotify_alloc_group(&nfsd_file_fsnotify_ops= , 0); if (IS_ERR(nfsd_file_fsnotify_group)) { pr_err("nfsd: unable to create fsnotify group: %ld\n", PTR_ERR(nfsd_file_fsnotify_group)); @@ -879,11 +894,23 @@ nfsd_file_cache_init(void) goto out_notifier; } =20 + nfsd_dir_fsnotify_group =3D fsnotify_alloc_group(&nfsd_dir_fsnotify_ops, = 0); + if (IS_ERR(nfsd_dir_fsnotify_group)) { + pr_err("nfsd: unable to create fsnotify group: %ld\n", + PTR_ERR(nfsd_dir_fsnotify_group)); + ret =3D PTR_ERR(nfsd_dir_fsnotify_group); + nfsd_dir_fsnotify_group =3D NULL; + goto out_notify_group; + } + INIT_DELAYED_WORK(&nfsd_filecache_laundrette, nfsd_file_gc_worker); out: if (ret) clear_bit(NFSD_FILE_CACHE_UP, &nfsd_file_flags); return ret; +out_notify_group: + fsnotify_put_group(nfsd_file_fsnotify_group); + nfsd_file_fsnotify_group =3D NULL; out_notifier: lease_unregister_notifier(&nfsd_file_lease_notifier); out_shrinker: @@ -1223,10 +1250,8 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct = net *net, open_file: trace_nfsd_file_alloc(nf); =20 - if (type =3D=3D S_IFREG) - nf->nf_mark =3D nfsd_file_mark_find_or_create(inode); - - if (type !=3D S_IFREG || nf->nf_mark) { + nf->nf_mark =3D nfsd_file_mark_find_or_create(inode); + if (nf->nf_mark) { if (file) { get_file(file); nf->nf_file =3D file; diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index ea3e7deb06fa..1964a213f80e 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c @@ -870,21 +870,30 @@ static void nfs4_xdr_enc_cb_notify(struct rpc_rqst *r= eq, const void *data) { const struct nfsd4_callback *cb =3D data; + struct nfsd4_cb_notify *ncn =3D container_of(cb, struct nfsd4_cb_notify, = ncn_cb); + struct nfs4_delegation *dp =3D container_of(ncn, struct nfs4_delegation, = dl_cb_notify); struct nfs4_cb_compound_hdr hdr =3D { .ident =3D 0, .minorversion =3D cb->cb_clp->cl_minorversion, }; - struct CB_NOTIFY4args args =3D { }; + struct CB_NOTIFY4args args; + __be32 *p; =20 WARN_ON_ONCE(hdr.minorversion =3D=3D 0); =20 encode_cb_compound4args(xdr, &hdr); encode_cb_sequence4args(xdr, cb, &hdr); =20 - /* - * FIXME: get stateid and fh from delegation. Inline the cna_changes - * buffer, and zero it. - */ + p =3D xdr_reserve_space(xdr, 4); + *p =3D cpu_to_be32(OP_CB_NOTIFY); + + args.cna_stateid.seqid =3D dp->dl_stid.sc_stateid.si_generation; + memcpy(&args.cna_stateid.other, &dp->dl_stid.sc_stateid.si_opaque, + ARRAY_SIZE(args.cna_stateid.other)); + args.cna_fh.len =3D dp->dl_stid.sc_file->fi_fhandle.fh_size; + args.cna_fh.data =3D dp->dl_stid.sc_file->fi_fhandle.fh_raw; + args.cna_changes.count =3D ncn->ncn_nf_cnt; + args.cna_changes.element =3D ncn->ncn_nf; WARN_ON_ONCE(!xdrgen_encode_CB_NOTIFY4args(xdr, &args)); =20 hdr.nops++; diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index b2b8c454fc0f..339c3d0bb575 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -55,6 +55,7 @@ #include "netns.h" #include "pnfs.h" #include "filecache.h" +#include "nfs4xdr_gen.h" #include "trace.h" =20 #define NFSDDBG_FACILITY NFSDDBG_PROC @@ -3440,15 +3441,125 @@ nfsd4_cb_getattr_release(struct nfsd4_callback *cb) nfs4_put_stid(&dp->dl_stid); } =20 +static void nfsd_break_one_deleg(struct nfs4_delegation *dp) +{ + bool queued; + + if (test_and_set_bit(NFSD4_CALLBACK_RUNNING, &dp->dl_recall.cb_flags)) + return; + + /* + * We're assuming the state code never drops its reference + * without first removing the lease. Since we're in this lease + * callback (and since the lease code is serialized by the + * flc_lock) we know the server hasn't removed the lease yet, and + * we know it's safe to take a reference. + */ + refcount_inc(&dp->dl_stid.sc_count); + queued =3D nfsd4_run_cb(&dp->dl_recall); + WARN_ON_ONCE(!queued); + if (!queued) + refcount_dec(&dp->dl_stid.sc_count); +} + +static bool +nfsd4_cb_notify_prepare(struct nfsd4_callback *cb) +{ + struct nfsd4_cb_notify *ncn =3D container_of(cb, struct nfsd4_cb_notify, = ncn_cb); + struct nfs4_delegation *dp =3D container_of(ncn, struct nfs4_delegation, = dl_cb_notify); + struct nfsd_notify_event *events[NOTIFY4_EVENT_QUEUE_SIZE]; + struct xdr_buf xdr =3D { .buflen =3D PAGE_SIZE * NOTIFY4_PAGE_ARRAY_SIZE, + .pages =3D ncn->ncn_pages }; + struct xdr_stream stream; + struct nfsd_file *nf; + int count, i; + bool error =3D false; + + xdr_init_encode_pages(&stream, &xdr); + + spin_lock(&ncn->ncn_lock); + count =3D ncn->ncn_evt_cnt; + + /* spurious queueing? */ + if (count =3D=3D 0) { + spin_unlock(&ncn->ncn_lock); + return false; + } + + /* we can't keep up! */ + if (count > NOTIFY4_EVENT_QUEUE_SIZE) { + spin_unlock(&ncn->ncn_lock); + goto out_recall; + } + + memcpy(events, ncn->ncn_evt, sizeof(*events) * count); + ncn->ncn_evt_cnt =3D 0; + spin_unlock(&ncn->ncn_lock); + + rcu_read_lock(); + nf =3D nfsd_file_get(rcu_dereference(dp->dl_stid.sc_file->fi_deleg_file)); + rcu_read_unlock(); + if (!nf) { + for (i =3D 0; i < count; ++i) + nfsd_notify_event_put(events[i]); + goto out_recall; + } + + for (i =3D 0; i < count; ++i) { + struct nfsd_notify_event *nne =3D events[i]; + + if (!error) { + u32 *maskp =3D (u32 *)xdr_reserve_space(&stream, sizeof(*maskp)); + u8 *p; + + if (!maskp) { + error =3D true; + goto put_event; + } + + p =3D nfsd4_encode_notify_event(&stream, nne, dp, nf, maskp); + if (!p) { + pr_notice("Count not generate CB_NOTIFY from fsnotify mask 0x%x\n", + nne->ne_mask); + error =3D true; + goto put_event; + } + + ncn->ncn_nf[i].notify_mask.count =3D 1; + ncn->ncn_nf[i].notify_mask.element =3D maskp; + ncn->ncn_nf[i].notify_vals.data =3D p; + ncn->ncn_nf[i].notify_vals.len =3D (u8 *)stream.p - p; + } +put_event: + nfsd_notify_event_put(nne); + } + if (!error) { + ncn->ncn_nf_cnt =3D count; + nfsd_file_put(nf); + return true; + } + nfsd_file_put(nf); +out_recall: + nfsd_break_one_deleg(dp); + return false; +} + static int nfsd4_cb_notify_done(struct nfsd4_callback *cb, struct rpc_task *task) { + struct nfsd4_cb_notify *ncn =3D container_of(cb, struct nfsd4_cb_notify, = ncn_cb); + struct nfs4_delegation *dp =3D container_of(ncn, struct nfs4_delegation, = dl_cb_notify); + switch (task->tk_status) { case -NFS4ERR_DELAY: rpc_delay(task, 2 * HZ); return 0; default: + /* For any other hard error, recall the deleg */ + nfsd_break_one_deleg(dp); + fallthrough; + case 0: return 1; } } @@ -3477,6 +3588,7 @@ static const struct nfsd4_callback_ops nfsd4_cb_getat= tr_ops =3D { }; =20 static const struct nfsd4_callback_ops nfsd4_cb_notify_ops =3D { + .prepare =3D nfsd4_cb_notify_prepare, .done =3D nfsd4_cb_notify_done, .release =3D nfsd4_cb_notify_release, .opcode =3D OP_CB_NOTIFY, @@ -5702,27 +5814,6 @@ static const struct nfsd4_callback_ops nfsd4_cb_reca= ll_ops =3D { .opcode =3D OP_CB_RECALL, }; =20 -static void nfsd_break_one_deleg(struct nfs4_delegation *dp) -{ - bool queued; - - if (test_and_set_bit(NFSD4_CALLBACK_RUNNING, &dp->dl_recall.cb_flags)) - return; - - /* - * We're assuming the state code never drops its reference - * without first removing the lease. Since we're in this lease - * callback (and since the lease code is serialized by the - * flc_lock) we know the server hasn't removed the lease yet, and - * we know it's safe to take a reference. - */ - refcount_inc(&dp->dl_stid.sc_count); - queued =3D nfsd4_run_cb(&dp->dl_recall); - WARN_ON_ONCE(!queued); - if (!queued) - refcount_dec(&dp->dl_stid.sc_count); -} - /* Called from break_lease() with flc_lock held. */ static bool nfsd_break_deleg_cb(struct file_lease *fl) @@ -9796,3 +9887,118 @@ nfsd_get_dir_deleg(struct nfsd4_compound_state *cst= ate, put_nfs4_file(fp); return ERR_PTR(status); } + +static void +nfsd4_run_cb_notify(struct nfsd4_cb_notify *ncn) +{ + struct nfs4_delegation *dp =3D container_of(ncn, struct nfs4_delegation, = dl_cb_notify); + + if (test_and_set_bit(NFSD4_CALLBACK_RUNNING, &ncn->ncn_cb.cb_flags)) + return; + + if (!refcount_inc_not_zero(&dp->dl_stid.sc_count)) + clear_bit(NFSD4_CALLBACK_RUNNING, &ncn->ncn_cb.cb_flags); + else + nfsd4_run_cb(&ncn->ncn_cb); +} + +static struct nfsd_notify_event * +alloc_nfsd_notify_event(u32 mask, const struct qstr *q, struct dentry *den= try) +{ + struct nfsd_notify_event *ne; + + ne =3D kmalloc(sizeof(*ne) + q->len + 1, GFP_KERNEL); + if (!ne) + return NULL; + + memcpy(&ne->ne_name, q->name, q->len); + refcount_set(&ne->ne_ref, 1); + ne->ne_mask =3D mask; + ne->ne_name[q->len] =3D '\0'; + ne->ne_namelen =3D q->len; + ne->ne_dentry =3D dget(dentry); + return ne; +} + +static bool +should_notify_deleg(u32 mask, struct file_lease *fl) +{ + /* Only nfsd leases */ + if (fl->fl_lmops !=3D &nfsd_lease_mng_ops) + return false; + + /* Skip if this event wasn't ignored by the lease */ + if ((mask & FS_DELETE) && !(fl->c.flc_flags & FL_IGN_DIR_DELETE)) + return false; + if ((mask & FS_CREATE) && !(fl->c.flc_flags & FL_IGN_DIR_CREATE)) + return false; + if ((mask & FS_RENAME) && !(fl->c.flc_flags & FL_IGN_DIR_RENAME)) + return false; + + return true; +} + +static void +nfsd_recall_all_dir_delegs(const struct inode *dir) +{ + struct file_lock_context *ctx =3D locks_inode_context(dir); + struct file_lock_core *flc; + + spin_lock(&ctx->flc_lock); + list_for_each_entry(flc, &ctx->flc_lease, flc_list) { + struct file_lease *fl =3D container_of(flc, struct file_lease, c); + + if (fl->fl_lmops =3D=3D &nfsd_lease_mng_ops) + nfsd_break_deleg_cb(fl); + } + spin_unlock(&ctx->flc_lock); +} + +int +nfsd_handle_dir_event(u32 mask, const struct inode *dir, const void *data, + int data_type, const struct qstr *name) +{ + struct dentry *dentry =3D fsnotify_data_dentry(data, data_type); + struct file_lock_context *ctx; + struct file_lock_core *flc; + struct nfsd_notify_event *evt; + + /* Don't do anything if this is not an expected event */ + if (!(mask & (FS_CREATE|FS_DELETE|FS_RENAME))) + return 0; + + ctx =3D locks_inode_context(dir); + if (!ctx || list_empty(&ctx->flc_lease)) + return 0; + + evt =3D alloc_nfsd_notify_event(mask, name, dentry); + if (!evt) { + nfsd_recall_all_dir_delegs(dir); + return 0; + } + + spin_lock(&ctx->flc_lock); + list_for_each_entry(flc, &ctx->flc_lease, flc_list) { + struct file_lease *fl =3D container_of(flc, struct file_lease, c); + struct nfs4_delegation *dp =3D flc->flc_owner; + struct nfsd4_cb_notify *ncn =3D &dp->dl_cb_notify; + + if (!should_notify_deleg(mask, fl)) + continue; + + spin_lock(&ncn->ncn_lock); + if (ncn->ncn_evt_cnt >=3D NOTIFY4_EVENT_QUEUE_SIZE) { + /* We're generating notifications too fast. Recall. */ + spin_unlock(&ncn->ncn_lock); + nfsd_break_deleg_cb(fl); + continue; + } + ncn->ncn_evt[ncn->ncn_evt_cnt++] =3D nfsd_notify_event_get(evt); + spin_unlock(&ncn->ncn_lock); + + nfsd4_run_cb_notify(ncn); + } + spin_unlock(&ctx->flc_lock); + nfsd_notify_event_put(evt); + return 0; +} diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 2a0946c630e1..9ad13f96c219 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -4098,6 +4098,102 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct = xdr_stream *xdr, goto out; } =20 +static bool +nfsd4_setup_notify_entry4(struct notify_entry4 *ne, struct xdr_stream *xdr, + struct dentry *dentry, struct nfs4_delegation *dp, + struct nfsd_file *nf, char *name, u32 namelen) +{ + uint32_t *attrmask; + + /* Reserve space for attrmask */ + attrmask =3D xdr_reserve_space(xdr, 3 * sizeof(uint32_t)); + if (!attrmask) + return false; + + ne->ne_file.data =3D name; + ne->ne_file.len =3D namelen; + ne->ne_attrs.attrmask.element =3D attrmask; + + attrmask[0] =3D 0; + attrmask[1] =3D 0; + attrmask[2] =3D 0; + ne->ne_attrs.attr_vals.data =3D NULL; + ne->ne_attrs.attr_vals.len =3D 0; + ne->ne_attrs.attrmask.count =3D 1; + return true; +} + +/** + * nfsd4_encode_notify_event - encode a notify + * @xdr: stream to which to encode the fattr4 + * @nne: nfsd_notify_event to encode + * @dp: delegation where the event occurred + * @notify_mask: pointer to word where notification mask should be set + * + * Encode @nne into @xdr. Returns a pointer to the start of the event, or = NULL if + * the event couldn't be encoded. The appropriate bit in the notify_mask w= ill also + * be set on success. + */ +u8 *nfsd4_encode_notify_event(struct xdr_stream *xdr, struct nfsd_notify_e= vent *nne, + struct nfs4_delegation *dp, struct nfsd_file *nf, + u32 *notify_mask) +{ + u8 *p =3D NULL; + + *notify_mask =3D 0; + + if (nne->ne_mask & FS_DELETE) { + struct notify_remove4 nr =3D { }; + + if (!nfsd4_setup_notify_entry4(&nr.nrm_old_entry, xdr, nne->ne_dentry, d= p, + nf, nne->ne_name, nne->ne_namelen)) + goto out_err; + p =3D (u8 *)xdr->p; + if (!xdrgen_encode_notify_remove4(xdr, &nr)) + goto out_err; + *notify_mask |=3D BIT(NOTIFY4_REMOVE_ENTRY); + } else if (nne->ne_mask & FS_CREATE) { + struct notify_add4 na =3D { }; + + if (!nfsd4_setup_notify_entry4(&na.nad_new_entry, xdr, nne->ne_dentry, d= p, + nf, nne->ne_name, nne->ne_namelen)) + goto out_err; + + p =3D (u8 *)xdr->p; + if (!xdrgen_encode_notify_add4(xdr, &na)) + goto out_err; + + *notify_mask |=3D BIT(NOTIFY4_ADD_ENTRY); + } else if (nne->ne_mask & FS_RENAME) { + struct notify_rename4 nr =3D { }; + struct name_snapshot n; + bool ret; + + /* Don't send any attributes in the old_entry since they're the same in = new */ + if (!nfsd4_setup_notify_entry4(&nr.nrn_old_entry.nrm_old_entry, xdr, + NULL, dp, nf, nne->ne_name, + nne->ne_namelen)) + goto out_err; + + take_dentry_name_snapshot(&n, nne->ne_dentry); + ret =3D nfsd4_setup_notify_entry4(&nr.nrn_new_entry.nad_new_entry, xdr, + nne->ne_dentry, dp, nf, (char *)n.name.name, + n.name.len); + if (ret) { + p =3D (u8 *)xdr->p; + ret =3D xdrgen_encode_notify_rename4(xdr, &nr); + } + release_dentry_name_snapshot(&n); + if (!ret) + goto out_err; + *notify_mask |=3D BIT(NOTIFY4_RENAME_ENTRY); + } + return p; +out_err: + pr_warn("nfsd: unable to marshal notify_rename4 to xdr stream\n"); + return NULL; +} + static void svcxdr_init_encode_from_buffer(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p, int bytes) { diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 500e07e47909..dbeacbb7a5c8 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -897,6 +897,8 @@ bool nfsd4_has_active_async_copies(struct nfs4_client *= clp); extern struct nfs4_client_reclaim *nfs4_client_to_reclaim(struct xdr_netob= j name, struct xdr_netobj princhash, struct nfsd_net *nn); extern bool nfs4_has_reclaimed_state(struct xdr_netobj name, struct nfsd_n= et *nn); +int nfsd_handle_dir_event(u32 mask, const struct inode *dir, const void *d= ata, + int data_type, const struct qstr *name); =20 void put_nfs4_file(struct nfs4_file *fi); extern void nfs4_put_cpntf_state(struct nfsd_net *nn, diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index 417e9ad9fbb3..d276840aca50 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -955,6 +955,9 @@ __be32 nfsd4_encode_fattr_to_buf(__be32 **p, int words, struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, u32 *bmval, struct svc_rqst *, int ignore_crossmnt); +u8 *nfsd4_encode_notify_event(struct xdr_stream *xdr, struct nfsd_notify_e= vent *nne, + struct nfs4_delegation *dd, struct nfsd_file *nf, + u32 *notify_mask); extern __be32 nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *, union nfsd4_op_u *u); extern __be32 nfsd4_setclientid_confirm(struct svc_rqst *rqstp, --=20 2.53.0 From nobody Sun Jun 21 04:17:36 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1CA953B7B7B; Tue, 7 Apr 2026 13:22:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568175; cv=none; b=GUj2BNS5D3Q0bEFkwmFTo+1oFSO/WeyFG2UJGqoA7WxxX4xkr9SiMVUL7IN2TTizbKAoqZAixreHWDRpUJn+k3PFpKnaQBeqrG8f2jZ1x5syCsDr3eGvHU4Pc1ZyE66hWPlHXO+jpMmmNHs8rDK/m9h5vs8ad93kU0Hzrw2VfOE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568175; c=relaxed/simple; bh=g1I47p9tYcaU/TzDYfO6i1CSHlKcg5dHhdBE+M75uqM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=VnGL961P/GS/vRieZsYLbfv4dWPsUNiGNkWcjlK7Kn8EElS4zZsd2iG6EjA4r31Ho0xBA33G95iNFA4WryxmD8upCWAYZNoNyuOulNDUI8LVwxlvUSW/wrwZeHtSxAh9VbkDHtNUnN2gFwzxhUknpysy+NjC8c5v/sWvv9CKOAY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Z/lmwWIz; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Z/lmwWIz" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9A3B9C116C6; Tue, 7 Apr 2026 13:22:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775568174; bh=g1I47p9tYcaU/TzDYfO6i1CSHlKcg5dHhdBE+M75uqM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Z/lmwWIzkqrMJOz9N7Ckzmze88VfU9EqebQ7b0wavxOZE3WIY3lVafy27a4HbyiL1 HVZl43I7yDxgKqzJ5foPmKQz1AVK7LT9itVaDWUL4CSBQTVSnwe8bIx7MG3DKcSWlE 9M+5sf0pDujkeq32I6lIYU2YjLDc0aQWhJ0FsPRqQfadxI3o/cT5w6tyr97LqLZQVc o5t+pyAxDchv2FQ3Q+b2FhEYbNJKuXx9HoeUJnUBl5HsJcu4Gz+/flHbuAKmuzTdoE gcbOYqry/GQzPO1u+rvDOwKs34uMl1fGCg0bvDUHD85/0q/fcwYbw6vZ6DWpNBsYCA ZOWoQZp2v9YwA== From: Jeff Layton Date: Tue, 07 Apr 2026 09:21:27 -0400 Subject: [PATCH 14/24] nfsd: add tracepoint to dir_event handler Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260407-dir-deleg-v1-14-aaf68c478abd@kernel.org> References: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> In-Reply-To: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Amir Goldstein Cc: Calum Mackay , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=1716; i=jlayton@kernel.org; h=from:subject:message-id; bh=g1I47p9tYcaU/TzDYfO6i1CSHlKcg5dHhdBE+M75uqM=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp1QUHhVJtZw/rVGCFdLIokYltsEfMeXjinHD3c U/vqhnACuqJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCadUFBwAKCRAADmhBGVaC FcCfD/95Un4hir96q/sORwpTWijQdhjwl/7B9+xLgnGjF3V9L2UT902waAysGgx7EJKP+WfAmok 8kYyd+DhxZrN+R6yuqCpauSVRfxlAcsFnUVCJ64HuYFiu7QCo6VTvFRzDk1TswPz6wDf8wEKJZc 9oolXdWHoE7V67fgx0qY5/RN0RR2k4hOofTYlFm660TxB6/jCOCZA1YS+qXfbjIvfeBKtiEcqed rKmZCyoN5iMy0XJ0WdE6inJnVq4uLwCVrpfeRFdLxYZoN9JNuHq0YoJDd07Djlj5rA3lxZMBJUX H4SbhJY6JQs7bElnUouTAnIl7w9H6YMnHLQIJfIbdJsJhiHogh2qwcCzB0OyOp4+3vrd287j5rW QXGX2s3BItcIYcgBDgWuXlU9yJ0Snia/X85C4vfDG79K19+jk+ClSm1hdIF3bULHR+9kInfhECl v2nYmflsXTKRYzDPRFd6rxRehTOU1eEWfkD2kxvs/Ivv+usnu8SdJQCjxqHFUM+KtPAEZTRTKjR FAqDQmAUoEWomGCuxVnSvw0bkcn8/nTCS4k3ZBxiXbUXoFt6d66zaXFfXO6APmlhuqarghSGQJr WT+KVLM4O1xarL2FEO6ESctHP0J/Mm/As/2cU/eAzAcm7OIBFoXzXw5IiUCHPeEzQ7YcJQW0iET g9wh2fPAKvdPS8g== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Add some extra visibility around the fsnotify handlers. Signed-off-by: Jeff Layton Reviewed-by: Steven Rostedt (Google) --- fs/nfsd/nfs4state.c | 2 ++ fs/nfsd/trace.h | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 339c3d0bb575..f3bf572b0ada 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -9963,6 +9963,8 @@ nfsd_handle_dir_event(u32 mask, const struct inode *d= ir, const void *data, struct file_lock_core *flc; struct nfsd_notify_event *evt; =20 + trace_nfsd_file_fsnotify_handle_dir_event(mask, dir, name); + /* Don't do anything if this is not an expected event */ if (!(mask & (FS_CREATE|FS_DELETE|FS_RENAME))) return 0; diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h index 60cacf64181c..3302cb926254 100644 --- a/fs/nfsd/trace.h +++ b/fs/nfsd/trace.h @@ -1377,6 +1377,26 @@ TRACE_EVENT(nfsd_file_fsnotify_handle_event, __entry->nlink, __entry->mode, __entry->mask) ); =20 +TRACE_EVENT(nfsd_file_fsnotify_handle_dir_event, + TP_PROTO(u32 mask, const struct inode *dir, const struct qstr *name), + TP_ARGS(mask, dir, name), + TP_STRUCT__entry( + __field(u32, mask) + __field(dev_t, s_dev) + __field(ino_t, i_ino) + __string_len(name, name->name, name->len) + ), + TP_fast_assign( + __entry->mask =3D mask; + __entry->s_dev =3D dir->i_sb->s_dev; + __entry->i_ino =3D dir->i_ino; + __assign_str(name); + ), + TP_printk("inode=3D0x%x:0x%x:0x%lx mask=3D0x%x name=3D%s", + MAJOR(__entry->s_dev), MINOR(__entry->s_dev), + __entry->i_ino, __entry->mask, __get_str(name)) +); + DECLARE_EVENT_CLASS(nfsd_file_gc_class, TP_PROTO( const struct nfsd_file *nf --=20 2.53.0 From nobody Sun Jun 21 04:17:36 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1DDBC3BD62F; Tue, 7 Apr 2026 13:22:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568177; cv=none; b=UI7WVm1YVnoFRzMG2zdDicYLhcdMYRCWIzVxgldNUBqh/2JiIq8ksox+57/hBV7HKByvBIGoNYFqmElf9IvcHdzgkIJWcd6Rti5P5zUssmxDJolmX+uh9o1AdNRhrzAiDoBUCC9oNKOhvb0EZpwExr6OKHbyKZo6LHRuL2wkJnc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568177; c=relaxed/simple; bh=Z4zXI+/IobxHZzp9dQaWHHuZTrII6y4E+PNc85tZohQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZkRXrUJhy0gDxUnFYB0NQQImRj8pJvaInts8zj1n4C/GMOJb5azmoy2XPxqZBYHEupuL2KsW9M6fVi3vV1czZb1JaF+R0US8+n0qRqjEfUtlcss227/5CsZm6iT6dCqyCtzKKdHajROrehnWnW15UtAq2+Ru7/g2e/3fgfofxIs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=NVEeqR9/; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="NVEeqR9/" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E7F5AC2BCB2; Tue, 7 Apr 2026 13:22:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775568177; bh=Z4zXI+/IobxHZzp9dQaWHHuZTrII6y4E+PNc85tZohQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=NVEeqR9/4xCM6Wei7iezf2QGvWNJIsosQFD5zQ76NybPB9z0H7QBDUnTxhoO0diCl 6xqq/Zk16C6ypyjFBjRIlMAS6nlLdzH4ogGCgy3Lbu1/RdgkvVRYytagldxQBr4YEs 4ZsFzuVa/3Jbiyw7Pk8zQWgQd0+dg+YSWryJUPlbuR+PdaTJ1lPXy2xcFvJ+djqhjp pA9ExRJp09VkfsZjfMj8ekLt+tD3s1NCnNs8ny0z3APIb1bZEZhvkK4gtFEAHM0j9T JfJ4/xQ//BZ0CpLHJhq0elx2lmjREqjIXzA6070A/mh/ZWg8j2e0H0ZpYJIUks9EiF M/50CozkDJDnA== From: Jeff Layton Date: Tue, 07 Apr 2026 09:21:28 -0400 Subject: [PATCH 15/24] nfsd: apply the notify mask to the delegation when requested Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260407-dir-deleg-v1-15-aaf68c478abd@kernel.org> References: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> In-Reply-To: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Amir Goldstein Cc: Calum Mackay , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=1720; i=jlayton@kernel.org; h=from:subject:message-id; bh=Z4zXI+/IobxHZzp9dQaWHHuZTrII6y4E+PNc85tZohQ=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp1QUINxLwL7o0cUZ45n+7bAG37tQfqs6aYWIAX xsDYCUUMk+JAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCadUFCAAKCRAADmhBGVaC FYS/D/4o7wY7j8NcguHPQOTzZ4OtGT7veKWW0iQc7FK8+ycMEt5RqatvjXZUozUXaMbt/0T3gOY UTCn9vr7SEkbJ2YYxnQ6Y/sGgUBo1F71LArFM7OZ/wAO+SmYoxcaimM9Ore7AgLcluPaDlyWYct HiVPxIPlPgx4oznB9CgJCFDvfu7AvMHRdLSlshLwzHgSw77145+KtbQHbfLZiZD8FVRFjQcSina ZFEsZpygh7E7n0OvH5CgBPzXdph2WZ0yWdym7wPjrWFl8TntMwPFqft2J2onb9IYCGGY7a/Fgjx /OWsH5Sch7OTlsoqiD0zJoGczwbMNbgodXrgo57XOAC3bhlX5xBpS8v39Q6G6k/7Nn2nkjBsYUc jKLlSL7mCfixudULsPgmG9R8+mwLX3g8fWtFhKYyys/fcp1Ey6toDOnBxbe/d4BpJEa8vYRB/dy zjtFVxEnKCRM3Y86RH9Qp8LmSuqmyuiZGLwkoR4trCIQJbP5gW+WPqxWGXE69VWf7zI/4rSlzLS 1lTG+fq/p7PH6XyrXhVGkhPwNOxo7xgvLynz+4JcM5mhDf7Py20a7XU1Z9Y/4NGfUoWiuvQLlB1 Wibk21R5SUCgCE55l3wIEo+qo7hk63+MnWoU6+KpETHMGzba17HQ7SxyeOXFxCqU5vLwypWFe/G QTmqImZ7PpN0umQ== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 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. 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. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4proc.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 2797da8cc950..01e3bf9e1839 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -2506,12 +2506,18 @@ nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_c= ompound_state *cstate, return status =3D=3D nfserr_same ? nfs_ok : status; } =20 +#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 =3D &u->get_dir_delegation; + u32 requested =3D gdd->gdda_notification_types[0]; struct nfs4_delegation *dd; struct nfsd_file *nf; __be32 status; @@ -2520,6 +2526,12 @@ nfsd4_get_dir_delegation(struct svc_rqst *rqstp, if (status !=3D nfs_ok) return status; =20 + /* No notifications if you don't set NOTIFY4_GFLAG_EXTEND! */ + if (!(requested & BIT(NOTIFY4_GFLAG_EXTEND))) + requested =3D 0; + + gdd->gddr_notification[0] =3D requested & SUPPORTED_NOTIFY_MASK; + /* * RFC 8881, section 18.39.3 says: * --=20 2.53.0 From nobody Sun Jun 21 04:17:36 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 67D0D3B8949; Tue, 7 Apr 2026 13:22:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568179; cv=none; b=UN097utwKLYmYUMw5BQyxQfaJVcOHIwgAZFP5nRvdPnIWqWrnTm5TSksikNoQ6sXynbNuGryuJ3nqA9lGqqL5eU5T3aFpb1n+9LNkFPinc2PTBIX+NQ+WpGMyl/+Gqcy4bRcEh1R54ijbzanyHPD3+on5xNoENnlXcVVx+kfHZE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568179; c=relaxed/simple; bh=rXPUzV+gnDxb/8xomIAbdxx5WejVQ90e/6v5r6rmuwg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=BP4/751FLRFYe90xj9LKrPk9ZeOu4phtm3MjhsdYxn3pVCi4cibY9y0tNzAYkjgII8aGNdTp4LFBEZf56U2LBDgEizw/84c89coTqKmeHwcWWNDWGE8WxMJBQnjlLRGQNnQ0CWG8tmBQp1YzobXk9pWgNT4mP/1kWO8YpyYDddk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=o5SQdmtR; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="o5SQdmtR" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3F192C2BCAF; Tue, 7 Apr 2026 13:22:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775568179; bh=rXPUzV+gnDxb/8xomIAbdxx5WejVQ90e/6v5r6rmuwg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=o5SQdmtRqevhJEIGSh3SVtBwijR/+PiDuCX981c9ylPwWuv1VyYTq7n08unVyfHYX YpNq5gQz4JiB126YOtdqICA8CsoieOzrB8S+80lMy2GkPbQQMPcGi+vX8LqgdTAEjl sEBbUEGND8RP+BYrdG26ocObgmeo4ufkZJCpkvUUvD+djAGTixeXJ+94e6eL+BFYFs WrKidJqQf0W21+EL5lb/Vct1ZruVy5rvyZVRc/Ek3prfrzqDyjAtEG130RavAJRGYJ lwWVDB3O9QjFBY56316aoMt0pHBpkIkglCc5YmUyYo5z8Qt6G0pGigOwPOoaQsRUwd IiCkAe8gURiNg== From: Jeff Layton Date: Tue, 07 Apr 2026 09:21:29 -0400 Subject: [PATCH 16/24] nfsd: add helper to marshal a fattr4 from completed args Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260407-dir-deleg-v1-16-aaf68c478abd@kernel.org> References: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> In-Reply-To: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Amir Goldstein Cc: Calum Mackay , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=3372; i=jlayton@kernel.org; h=from:subject:message-id; bh=rXPUzV+gnDxb/8xomIAbdxx5WejVQ90e/6v5r6rmuwg=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp1QUIe8RcNM+t4MP0C74pNO5Q1QHFsL1JDB4q+ NKS7Z3+/SCJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCadUFCAAKCRAADmhBGVaC FT6dEACk483WLPz/InDepEOHF0t/b1NYTy6BiXmtgqT+0uL/nak6AX4c6u0+edsRF5qcHm/SPQ8 ltSZCzA4l/5KnP6dIJ0173Xz8Fb7ZQMugjBFPsLsQ6Up8avRWYbw0lNnABLO+/AC7C0qJRqMKV6 hT+ZBYWwY+Y+CJiOcVtvi2zYPaGNgPa0ZedY42xAnZS259XmjfZjg+kFXMUpBaBZfJ0/smaAxzT sBX7yN7NykydSZtcHnbWNLDdKL4DD7LoyiHXHbB1iBsPwTxkKhUg4+//NbsJvmTC4nQcypufPmJ vLTuDUFcXZlDRKB/+sV+l4FxwFcfi7/H8IZNiKeys5raclfo1dUT6z45HZqEcx/KpjV+W+UAcN8 9i5ezWDAJlO8lLtJLuUpdGT56hryJI7K2gVwAgehu0ancj40JMwip+gG00BxbQmlWmwZhg0MY5+ MofrYCxc+21TNGEJ+EKDHwmvKRA3NqHd+NwYhZPVo8qjo2vP+rfyOWWpYHesBIkkAQwz7V+5O1q lfNhFETJOBsgFKcQyQDUj7UwchBXGOhtC7IUj4YoyjlFndA6oEEekgBil1iZ/LWWBcY4HCM+ORj AhfAwSFKEKJ6ZPoDjVXv3N8QAXgeKNudwaKt/LIQAQo3PmAgNUtyVnEaUUcJ3ShBjcxiDPq4R15 al2GmsNBpQe22YQ== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Break the loop that encodes the actual attr_vals field into a separate function. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4xdr.c | 46 ++++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 9ad13f96c219..2ba3fcadb742 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -3852,6 +3852,22 @@ static const nfsd4_enc_attr nfsd4_enc_fattr4_encode_= ops[] =3D { #endif }; =20 +static __be32 +nfsd4_encode_attr_vals(struct xdr_stream *xdr, u32 *attrmask, struct nfsd4= _fattr_args *args) +{ + DECLARE_BITMAP(attr_bitmap, ARRAY_SIZE(nfsd4_enc_fattr4_encode_ops)); + unsigned long bit; + __be32 status; + + bitmap_from_arr32(attr_bitmap, attrmask, ARRAY_SIZE(nfsd4_enc_fattr4_enco= de_ops)); + for_each_set_bit(bit, attr_bitmap, ARRAY_SIZE(nfsd4_enc_fattr4_encode_ops= )) { + status =3D nfsd4_enc_fattr4_encode_ops[bit](xdr, args); + if (status !=3D nfs_ok) + return status; + } + return nfs_ok; +} + /* * Note: @fhp can be NULL; in this case, we might have to compose the file= handle * ourselves. @@ -3862,7 +3878,6 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xd= r_stream *xdr, struct dentry *dentry, const u32 *bmval, int ignore_crossmnt) { - DECLARE_BITMAP(attr_bitmap, ARRAY_SIZE(nfsd4_enc_fattr4_encode_ops)); struct nfs4_delegation *dp =3D NULL; struct nfsd4_fattr_args args; struct svc_fh *tempfh =3D NULL; @@ -3877,7 +3892,6 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xd= r_stream *xdr, .mnt =3D exp->ex_path.mnt, .dentry =3D dentry, }; - unsigned long bit; =20 WARN_ON_ONCE(bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1); WARN_ON_ONCE(!nfsd_attrs_supported(minorversion, bmval)); @@ -4050,27 +4064,22 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct = xdr_stream *xdr, #endif /* CONFIG_NFSD_V4_POSIX_ACLS */ =20 /* attrmask */ - status =3D nfsd4_encode_bitmap4(xdr, attrmask[0], attrmask[1], - attrmask[2]); + status =3D nfsd4_encode_bitmap4(xdr, attrmask[0], attrmask[1], attrmask[2= ]); if (status) - goto out; + return status; =20 /* attr_vals */ attrlen_offset =3D xdr->buf->len; - if (unlikely(!xdr_reserve_space(xdr, XDR_UNIT))) - goto out_resource; - bitmap_from_arr32(attr_bitmap, attrmask, - ARRAY_SIZE(nfsd4_enc_fattr4_encode_ops)); - for_each_set_bit(bit, attr_bitmap, - ARRAY_SIZE(nfsd4_enc_fattr4_encode_ops)) { - status =3D nfsd4_enc_fattr4_encode_ops[bit](xdr, &args); - if (status !=3D nfs_ok) - goto out; + if (unlikely(!xdr_reserve_space(xdr, XDR_UNIT))) { + status =3D nfserr_resource; + goto out; } - attrlen =3D cpu_to_be32(xdr->buf->len - attrlen_offset - XDR_UNIT); - write_bytes_to_xdr_buf(xdr->buf, attrlen_offset, &attrlen, XDR_UNIT); - status =3D nfs_ok; =20 + status =3D nfsd4_encode_attr_vals(xdr, attrmask, &args); + if (status =3D=3D nfs_ok) { + attrlen =3D cpu_to_be32(xdr->buf->len - attrlen_offset - XDR_UNIT); + write_bytes_to_xdr_buf(xdr->buf, attrlen_offset, &attrlen, XDR_UNIT); + } out: #ifdef CONFIG_NFSD_V4_POSIX_ACLS if (args.dpacl) @@ -4093,9 +4102,6 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xd= r_stream *xdr, out_nfserr: status =3D nfserrno(err); goto out; -out_resource: - status =3D nfserr_resource; - goto out; } =20 static bool --=20 2.53.0 From nobody Sun Jun 21 04:17:36 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BACEF3B9604; Tue, 7 Apr 2026 13:23:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568181; cv=none; b=p+MUTYKWgHzJspgy7JWTv/hPgeD8wiNg3mithaWdFMrfW7D5PjR5QIUP/Ry0DFi2y0cR4zebMFMZjIL7yHBN8HfHoalNG76A7tJRW0IA02fqZsIYZSR97iNltdWU4x1uhfqcO3eCqlqXWsfEk0GxETUFm4DOl2GqNpa7268PS9g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568181; c=relaxed/simple; bh=dvFkfIFmNTD6FOkMvIBtui2fVHcj2XA+6eKjVJjIZY4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=M3/7yFf2bhAOKeljzhlmORUnd9imLZorHTvdf9z8XdazPlwScqYdXWOMCB4q8XsGTar9R+/mS1HHb3eXrVN8jv+FDtY8M1PLoEsJvXjdzAwyO6n9MvsW6DZ+gFwpkAk9U7EmLBsQypZyQOWj5pl7Ep3ujiBd9saU+YgpJWnzYWg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=pL6TIqPQ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="pL6TIqPQ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 89EE4C2BCAF; Tue, 7 Apr 2026 13:22:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775568181; bh=dvFkfIFmNTD6FOkMvIBtui2fVHcj2XA+6eKjVJjIZY4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=pL6TIqPQV3+IOw9Sr8XOaOHwZtBhOpBNnXb/WM0pgfDbu+Gebs5UwlW1E1rUlAopQ giPTT6UPIzG9eJaT9nEDRei3f4Ls0GVq6scEc3wrjA6JzrSOQyilyQcNI9TO5GnXnG f/a7nRGYDh0KXXbQIl6urYt9nloUibokPwHqmZiZSClyTO0LFLF2EXw1Duq2eBEeB6 omIToIxNYOAS+PshsXNy6fQU4phmHBiXg6txREMXrW4N9OzHo/jGDOTOjZRj9dAt3j MY890Op0o4iwWiGOFBg+AJNqpWUCL1SXq5ujckz3dswsU6slH5S7KqqbNmJ2KTJLkM rTzz8RG/0nVAA== From: Jeff Layton Date: Tue, 07 Apr 2026 09:21:30 -0400 Subject: [PATCH 17/24] nfsd: allow nfsd4_encode_fattr4_change() to work with no export Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260407-dir-deleg-v1-17-aaf68c478abd@kernel.org> References: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> In-Reply-To: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Amir Goldstein Cc: Calum Mackay , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=846; i=jlayton@kernel.org; h=from:subject:message-id; bh=dvFkfIFmNTD6FOkMvIBtui2fVHcj2XA+6eKjVJjIZY4=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp1QUIF7cZXNXHX75V5YV9w/FPIeBvaOl1/Uz5F 14bcqZWly+JAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCadUFCAAKCRAADmhBGVaC Ffr2EADFFuWcZQwYe//XnyyuQw55HjrbtGQJxDVx2EbQkCqzyBWSMStF74Tv2BnNb6eGZji/ehq SKUYqZoHxuuIAAgI1kLm+La9CXU56Kztjpw+chDeeRf6FNyAWz5EMWO4dX3P4IalT/WnxNESvw8 ojsOXWgtMNapqfQ0U2Rdle3plGIQA3lMeTJTTPluOuidLR8DOGBMujZAGKON5AeqI/0qzbQYJCW 45S26VnHKgmE2SbEONh6uB6UcewNjtXY47obAa9vGxrY6FmF4ZgRWiz+wxw3XLIzoN4deIwvf1k cwHZhTs2vL8LnesfT1Q3eAKWwJabfWF3Rp4dgi3g8JJ9PsOmeihbSGOi34q/QxC6FPTW0VtexyY ul7FZbAGwyHEPj3Bmb8V9NN0MPe9sEMJXinRJ+X4UgK9OkfwBobxuj+fymMB1+Dmw+/BlUhiPcv QVkGYsmXkgXyPFcF+0RF8F6JT921nEyA5KzLuLO0UHTYV3ve0e9XAWAu1x4Bwe7l9OgeiLgniN2 L9E/G2Mn5V6TpWgS13TJ4kDtNEY/2k/3Rhxp30GPQIUErT9GnJI8vDSv4gaxwkJSQiBlmBBJueR G/LWxumo9PTHnqISF5OvTnjDMNBnj0yoEfD4S3bw7ZtyvCQyE4n0POwLRfg+uzBN+O1hx5S2S49 f455uDXXMnDztMA== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 In the context of a CB_NOTIFY callback, we may not have easy access to a svc_export. nfsd will not currently grant a delegation on a the V4 root however, so this should be safe. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4xdr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 2ba3fcadb742..49ca24851707 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -3257,7 +3257,7 @@ static __be32 nfsd4_encode_fattr4_change(struct xdr_s= tream *xdr, { const struct svc_export *exp =3D args->exp; =20 - if (unlikely(exp->ex_flags & NFSEXP_V4ROOT)) { + if (exp && unlikely(exp->ex_flags & NFSEXP_V4ROOT)) { u32 flush_time =3D convert_to_wallclock(exp->cd->flush_time); =20 if (xdr_stream_encode_u32(xdr, flush_time) !=3D XDR_UNIT) --=20 2.53.0 From nobody Sun Jun 21 04:17:36 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4D04D3BF664; Tue, 7 Apr 2026 13:23:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568184; cv=none; b=RnaUyWBry+DZyC2Ie5R22r8uUWu6Z7LKXdQst4GpqFr6i93uu0yvN9eRIGOPSTXlEgb9Tdh0LsKYAEzz/ys5k99pK9W12TOBIDTucfe+J3MwrEOCptMF3X5GDAf/ns1hnHYF2xmXFBxxM2JncyuCfHJbTmdeKXEwgvyAA5XSS5Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568184; c=relaxed/simple; bh=j3wX8gQVlfaixCiAFgl9DGooV7QaUz5OrbnHAIp6G6U=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ija2t4HpnlPlmSMgA3n1J3OUje6kbC7Q7FwduGxU1l7zad7j8CVojB2mAjUkhSsWIuJ4sKoRTutzKzLdsfdHiLI+kz/ExKLUHCpoCFu4MuNKkaq8px5j3HeGJgFkp54umvHbp2hWphUseziUgHY3DRb6RSEbWS+r2Gbb7MksHIk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=D1OIgklK; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="D1OIgklK" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D908BC19424; Tue, 7 Apr 2026 13:23:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775568183; bh=j3wX8gQVlfaixCiAFgl9DGooV7QaUz5OrbnHAIp6G6U=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=D1OIgklKAvq2Y+hO8PViXMnm2w2ec1IAQKrWfx5C6dfYruxh4f4UMTAh2I6pJD3Sx PL37h9U8pIOSs4d/8/tJRAOFZGm8kLvzqkakps5b4hjuL0ZE61XxsQKN2UfjkEotVo 7q8jrPi4XscX4T/M4NZPKFMDKMkrbcYFElz6rvKvAyaSVcCd69eTTNdbVwCEsH2odZ jmxZTRvCjeWiq8gR0KTYBEBbWXuP5AGeXtbv+rxEsdXuYeRnxsRbvQbX+ys8t+u7JP fIqn5RZXgrBrRN01eFPjoeE1PVzMOlPJgGa95rwEu+Mc2IYRg9BqLpxCSZrr0U/7Vc b3+gcesjUTMKA== From: Jeff Layton Date: Tue, 07 Apr 2026 09:21:31 -0400 Subject: [PATCH 18/24] nfsd: send basic file attributes in CB_NOTIFY Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260407-dir-deleg-v1-18-aaf68c478abd@kernel.org> References: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> In-Reply-To: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Amir Goldstein Cc: Calum Mackay , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=2682; i=jlayton@kernel.org; h=from:subject:message-id; bh=j3wX8gQVlfaixCiAFgl9DGooV7QaUz5OrbnHAIp6G6U=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp1QUJ1mbRF1hs5NtRa30vG3RBHyATuGdwZzbpq qTrcoRZm6qJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCadUFCQAKCRAADmhBGVaC FSRFEADRIftXFX3DjXgwVMEBaLL3Mc6P+9JYI2Muqc6JYl4vvuHK3pHD2OsGWyvZS+KIi4Bb5Po M4TQsvLcbvudQTcNksptJlr+fF4QFu/+AGaJqSPJHGFvTybMBUQtv0jF3S+Bc4uETcRUMMiZtV6 IblaLw0zuJnOfmA3SLTlEAhxSmVSsMbBxjeyUm57BTx1pDV/U6xH1/XP4jraCPF19sIhT2jALTo Fc2GCZlvLfyJn06+qLcy2IjkWp8prFx+8Q9jE1z1DYhxZ3rhCCLt3RIKIqCv+7XGoaCCyCqppr4 DDbogQOj32+FQMkFRs1UMoq2U5vzqa2B+o+A1yywslZB6iAWeJbpVUyOpb8DmtHBnlwuKI2+2zq bRxlabF4o2L37K8iN9QHHQapNNojrVZ+YI7kg9rXpZEMdeORmU3pLthF2f+5lzG6T2KXL/ooej6 ggAiC8zHiin1yy3gMCCjTo1fDuZTNljqTxjqH0uXOc8UDvVS6rScv7yAr4MB7Xms3qn64n7RMIA GEsA/H4/PWFT3aMI2Jo8uFy/zpcjszrenv0HfZABDevbw/X2aqDQhTn1kqHzi3uS0S0mL/5zQ9T SNxygjFd5xXlEDtDtlQgsXOgmgCfdrBgNGWKDXcfa2F0RcVshpwpJHiACFyx1NujwEXWdboZa24 tsief2qJ1iwQGGg== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 In addition to the filename, send attributes about the inode in a CB_NOTIFY event. This patch just adds a the basic inode information that can be acquired via GETATTR. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4xdr.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 49ca24851707..0cdce460f9c8 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -4104,12 +4104,21 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct = xdr_stream *xdr, goto out; } =20 +#define CB_NOTIFY_STATX_REQUEST_MASK (STATX_BASIC_STATS | \ + STATX_BTIME | \ + STATX_CHANGE_COOKIE) + static bool nfsd4_setup_notify_entry4(struct notify_entry4 *ne, struct xdr_stream *xdr, struct dentry *dentry, struct nfs4_delegation *dp, struct nfsd_file *nf, char *name, u32 namelen) { + struct path path =3D { .mnt =3D nf->nf_file->f_path.mnt, + .dentry =3D dentry }; + struct nfsd4_fattr_args args =3D { }; uint32_t *attrmask; + __be32 status; + int ret; =20 /* Reserve space for attrmask */ attrmask =3D xdr_reserve_space(xdr, 3 * sizeof(uint32_t)); @@ -4120,6 +4129,41 @@ nfsd4_setup_notify_entry4(struct notify_entry4 *ne, = struct xdr_stream *xdr, ne->ne_file.len =3D namelen; ne->ne_attrs.attrmask.element =3D attrmask; =20 + /* FIXME: d_find_alias for inode ? */ + if (!path.dentry || !d_inode(path.dentry)) + goto noattrs; + + /* + * It is possible that the client was granted a delegation when a file + * was created. Note that we don't issue a CB_GETATTR here since stale + * attributes are presumably ok. + */ + ret =3D vfs_getattr(&path, &args.stat, CB_NOTIFY_STATX_REQUEST_MASK, AT_S= TATX_SYNC_AS_STAT); + if (ret) + goto noattrs; + + args.change_attr =3D nfsd4_change_attribute(&args.stat); + + attrmask[0] =3D FATTR4_WORD0_TYPE | FATTR4_WORD0_CHANGE | + FATTR4_WORD0_SIZE | FATTR4_WORD0_FILEID; + attrmask[1] =3D FATTR4_WORD1_MODE | FATTR4_WORD1_NUMLINKS | FATTR4_WORD1_= RAWDEV | + FATTR4_WORD1_SPACE_USED | FATTR4_WORD1_TIME_ACCESS | + FATTR4_WORD1_TIME_METADATA | FATTR4_WORD1_TIME_MODIFY; + attrmask[2] =3D 0; + + if (args.stat.result_mask & STATX_BTIME) + attrmask[1] |=3D FATTR4_WORD1_TIME_CREATE; + + ne->ne_attrs.attrmask.count =3D 2; + ne->ne_attrs.attr_vals.data =3D (u8 *)xdr->p; + + status =3D nfsd4_encode_attr_vals(xdr, attrmask, &args); + if (status !=3D nfs_ok) + goto noattrs; + + ne->ne_attrs.attr_vals.len =3D (u8 *)xdr->p - ne->ne_attrs.attr_vals.data; + return true; +noattrs: attrmask[0] =3D 0; attrmask[1] =3D 0; attrmask[2] =3D 0; --=20 2.53.0 From nobody Sun Jun 21 04:17:36 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 999EF3BFE3F; Tue, 7 Apr 2026 13:23:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568186; cv=none; b=H6BmyPHA8c/+e5nb4pMIFYqm8SqRuxeiClEFjUnA8W5uYyT0YgeO9xty2KXdDfffPgTmIOof16Ati6H53QRCY/XwTy3dVjtL5VM8GWJhR/9kIpmYBj1sg1KkAS9SpAOIn5ZTZ9VBM711TN2uqtp3KTWHpYIoH/Qo8nPs/f/Zqw8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568186; c=relaxed/simple; bh=J40w/4AecsAWUgq0DpKUB39lTx0eXB+tjH+n1jPhzPY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=I+bhIP28GiryW0pPDdxjrfJF5biXhxo+SwsC5YYMlyboc7QGMdWKd0C/g20jUcBQ5ASKS4qxO/SlJzddoNUbm6YyTnfAjKXJepBxD9GUhyY1KSZQ85CAADBy7MgD10zCRAnBEWk0d4UpB13qJMQ3275JwxDk9EzH6+qimf+fHp4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=cj6ObmdX; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="cj6ObmdX" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2F3E8C2BCB0; Tue, 7 Apr 2026 13:23:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775568186; bh=J40w/4AecsAWUgq0DpKUB39lTx0eXB+tjH+n1jPhzPY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=cj6ObmdXJNFIb6tBlsL6/nehVhTHY+yPRa3yRLgVUZIVe0QsEUMnhAbjZ2b2IBo77 TDEz/5tsbodyVAh3JvM2rzgus4Vl2XodZGUAPEyws5V4krM5dqetKkUw9/Jp8NeB3Z 8hanI+iC5fLTUtn9hhrbn3WSYmI5KegFUfc8xj/RzAe4pcRlxLCWu/km4xUomDIA1Q 4ldH0GpNdLc4KkRvK53Hsym6DrzQ2DRS0kAZu6wrNXQtfC1viDex9ayOG6l0woacZi lgy90SFaHwO/6nDYJPsEBUPzMBeWI7KyfbLDGDl+jKfC/doVDe4N/NJXlVgejtaA45 GV9t3a1iGyLaA== From: Jeff Layton Date: Tue, 07 Apr 2026 09:21:32 -0400 Subject: [PATCH 19/24] nfsd: allow encoding a filehandle into fattr4 without a svc_fh Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260407-dir-deleg-v1-19-aaf68c478abd@kernel.org> References: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> In-Reply-To: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Amir Goldstein Cc: Calum Mackay , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=2594; i=jlayton@kernel.org; h=from:subject:message-id; bh=J40w/4AecsAWUgq0DpKUB39lTx0eXB+tjH+n1jPhzPY=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp1QUJ2y7V+VYcPHNsJgfbshtmoBxEeYXA2psMz JKGYkrMmXaJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCadUFCQAKCRAADmhBGVaC FTYDD/4tQBIa34V42fqpRCfUHuzNhog5zWCJrU7w0q7/sw3Pqy6F7Z4fTRWc15IejtHbGgf9M57 IghwtKVgSuASVy+zReF06cIhLRnmEcHz36vOp+fCLqoMX/pjEGUPjJ3Jj9NoAj/yyS4IhUx8rsf QQHkD3fpgUH5sxGcqtZWUE4qkSX83CWOsdqTJzv+/3djxI4gfeiwmwZHrQ6ebNRDLGjNWN4UO8M FitchHKwwKsuTjsABiXbGHalOyGHqPuXPzS1/ALfoVMJzEw9AoD/44KzinukyjkD3jHFP3qvmZy JRin6LxFZ4/rTa5xZZjQTKhMT2F+cFYQMzu+L+Yi/3A95lrtdjhNm1AM9XBWfz1owbtqw0oV7XT wgLoei5abf8EBHfhqm9tXD7UyPTUXX/lKa8vpNFRTglUqnsS1gUw/xxeWCBwnW00pvKLrkwQTCe 2idcBcy1YSMJQDEMpfn74JSL+ZW0TN7KWz4o4ixNqsbeGaEYmDMvp+mpkgMozBPJjOjk+eskBt7 iBQzajwkk+yyS4I5AWeB/n0JE80s9gkzJpQa1Bg70vEnIDA8JF1h+hvnXIY/GVQj0e3KTlVh74T bejVh+rGAkRZeOtY3p28BgBhG3+INUxevb5l5MJt5WLPPY4CNyL4R36+AaxrC2rboRRNdOi6/Kw eP36WOGswgWCt7g== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 The current fattr4 encoder requires a svc_fh in order to encode the filehandle. This is not available in a CB_NOTIFY callback. Add a a new "fhandle" field to struct nfsd4_fattr_args and copy the filehandle into there from the svc_fh. CB_NOTIFY will populate it via other means. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4xdr.c | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 0cdce460f9c8..faf0c3d35dee 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -2701,7 +2701,7 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp) } =20 static __be32 nfsd4_encode_nfs_fh4(struct xdr_stream *xdr, - struct knfsd_fh *fh_handle) + const struct knfsd_fh *fh_handle) { return nfsd4_encode_opaque(xdr, fh_handle->fh_raw, fh_handle->fh_size); } @@ -3144,6 +3144,7 @@ struct nfsd4_fattr_args { struct svc_fh *fhp; struct svc_export *exp; struct dentry *dentry; + struct knfsd_fh fhandle; struct kstat stat; struct kstatfs statfs; struct nfs4_acl *acl; @@ -3359,7 +3360,7 @@ static __be32 nfsd4_encode_fattr4_acl(struct xdr_stre= am *xdr, static __be32 nfsd4_encode_fattr4_filehandle(struct xdr_stream *xdr, const struct nfsd4_fattr_args *args) { - return nfsd4_encode_nfs_fh4(xdr, &args->fhp->fh_handle); + return nfsd4_encode_nfs_fh4(xdr, &args->fhandle); } =20 static __be32 nfsd4_encode_fattr4_fileid(struct xdr_stream *xdr, @@ -3969,19 +3970,23 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct = xdr_stream *xdr, if (err) goto out_nfserr; } - if ((attrmask[0] & (FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FSID)) && - !fhp) { - tempfh =3D kmalloc_obj(struct svc_fh); - status =3D nfserr_jukebox; - if (!tempfh) - goto out; - fh_init(tempfh, NFS4_FHSIZE); - status =3D fh_compose(tempfh, exp, dentry, NULL); - if (status) - goto out; - args.fhp =3D tempfh; - } else - args.fhp =3D fhp; + + args.fhp =3D fhp; + if ((attrmask[0] & (FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FSID))) { + if (!args.fhp) { + tempfh =3D kmalloc_obj(struct svc_fh); + status =3D nfserr_jukebox; + if (!tempfh) + goto out; + fh_init(tempfh, NFS4_FHSIZE); + status =3D fh_compose(tempfh, exp, dentry, NULL); + if (status) + goto out; + args.fhp =3D tempfh; + } + if (args.fhp) + fh_copy_shallow(&args.fhandle, &args.fhp->fh_handle); + } =20 if (attrmask[0] & FATTR4_WORD0_ACL) { err =3D nfsd4_get_nfs4_acl(rqstp, dentry, &args.acl); --=20 2.53.0 From nobody Sun Jun 21 04:17:36 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E57D43B9DA0; Tue, 7 Apr 2026 13:23:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568189; cv=none; b=mgilj/edZdQjiJJbz8231yaGsFGrtksfdpnWw0F39YR5AX/+72zkm9LS/zZnehX0qdQSS8gqJZ7Sg09G2uKnMdCxNi4gGIag95S5fmI9YBUrpK2hS58c0qA04sEnodOOXspL8u/DgTH7tC8UXUmRW9FeEeF/ig7s+PXXG2mJCQo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568189; c=relaxed/simple; bh=Y0Ef697EebMArSFW6C9jXtnQz6TfSRIm7o8BBtDPbqs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Ph2eBkBAysZwCWEL8LcZYbgV5x5uRF9E6u5nEwFR7os7Csoyy2Su60UQMXpD8//zySWlmo75FNUA9ZtdJnIMzK0acSuyqRYv9UZN1QQ4L2hnHXjFiCGmdRWIzO1BqigHwavN/3AOZSDmjbl9xKKahFjqCCv/TF33a0VVFV+/RNE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=JZKMb0ZT; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="JZKMb0ZT" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 79DEFC116C6; Tue, 7 Apr 2026 13:23:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775568188; bh=Y0Ef697EebMArSFW6C9jXtnQz6TfSRIm7o8BBtDPbqs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=JZKMb0ZT1lxUK9RReDgR+zSHSo8T6JrDaWovM767kRny4IR5nedb8RyG4qWqX6cZJ lsfHA9rcjLIorMhOIUaASgcncpJZcMojYdLfYsrzn8VFlAnaMqbTwRTbQ55totJ1s1 HnKK4eyvxpmb56L5QqVsXA59uW4MH5o6FildwOBGw8NFBKp2wxQFAlyU888HJYXEws qHs5v5PSH0TePmsbayEAOvvFWF+nX19pmFEM2qn9v9sre1TwlBoyma+jdPyP447NrK KuyYAi2ymz87VTFh5E2h4vTsOHjrl07D6aVNQBfn9mC2ddZIAwD0CUfnoMvDg65qjT hP0aHTeM+zg2Q== From: Jeff Layton Date: Tue, 07 Apr 2026 09:21:33 -0400 Subject: [PATCH 20/24] nfsd: add a fi_connectable flag to struct nfs4_file Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260407-dir-deleg-v1-20-aaf68c478abd@kernel.org> References: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> In-Reply-To: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Amir Goldstein Cc: Calum Mackay , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=1379; i=jlayton@kernel.org; h=from:subject:message-id; bh=Y0Ef697EebMArSFW6C9jXtnQz6TfSRIm7o8BBtDPbqs=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp1QUJlVa6uz/6jZzGHdhCAxoqZn7jrQXeOIZwo EbF4XMk1GOJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCadUFCQAKCRAADmhBGVaC FfSpEACZO8IC6XlzaFXCwcCrToIw+1ZatZ2KksLX+NJ5g3kDJEWjOBDnkMwvMDdb1z4pwllRmBj 6rHn322rvA53o9ggGbRS956G04JE5J8UJvdxXBkXQS6lINlkq7c6Nc4CEzIjpKG77j5Nhrfp95q PhH4vSsVBhGZvAhm3lk5668GZSvawfzLxvx9SucPZNEaOcYCHmTOz3InY8rwDAlTvAQd0a6ZVWZ YlsBMvhNE8VJzRQi2LAvGlqb8Xk+k8A6iiyTlv0fTHsEDxFZ0erJAbioVx67d+6Vlf3DgtVTs44 8EgyX8oYcJR2Oz+QqW0U7RuMBcUfQMandQYWLz3LzrBQMFex4TNvfSYBNnxWibtZhpZKbx5GhTM UngvYMxv03kG8cGU9IFqTgBtPEJdHi4QvldnbgOs4MbhjDZ1qpwHXeJhLaqdZK7DNX9oET+ATSM 0IyD3Mgq5hOTUr3AtxtRCrqvUZZvSqoRp4vmLJlLu0rixTrAMvFHqNzzMAa3Ids5T8lis4OxzwY GHN8saTOdDkNFzC28Ke0HO/6yiSzio01weIJUFw/sxnJa1t9aWnkgoIgTkVb0W/6SusM21sl1w3 6I4sM0Bucv1fpcziNZFSepT61FsllqpERbsm7wFT9GTL056Jobgg3UPwxS5VTamE1el+8ecGOdw kG9UFATVP856O0w== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 When encoding a filehandle for a CB_NOTIFY, there is no svc_export available, but the server needs to know whether to encode a connectable filehandle. Add a flag to the nfs4_file that tells whether the svc_export under which a directory delegation was acquired requires connectable filehandles. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4state.c | 1 + fs/nfsd/state.h | 1 + 2 files changed, 2 insertions(+) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index f3bf572b0ada..0580c935d804 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -5153,6 +5153,7 @@ static void nfsd4_file_init(const struct svc_fh *fh, = struct nfs4_file *fp) memset(fp->fi_access, 0, sizeof(fp->fi_access)); fp->fi_aliased =3D false; fp->fi_inode =3D d_inode(fh->fh_dentry); + fp->fi_connectable =3D fh->fh_export->ex_flags & EXPORT_FH_CONNECTABLE; #ifdef CONFIG_NFSD_PNFS INIT_LIST_HEAD(&fp->fi_lo_states); atomic_set(&fp->fi_lo_recalls, 0); diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index dbeacbb7a5c8..d060d70c5820 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -745,6 +745,7 @@ struct nfs4_file { int fi_delegees; struct knfsd_fh fi_fhandle; bool fi_had_conflict; + bool fi_connectable; #ifdef CONFIG_NFSD_PNFS struct list_head fi_lo_states; atomic_t fi_lo_recalls; --=20 2.53.0 From nobody Sun Jun 21 04:17:36 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 33E1C3B9DBC; Tue, 7 Apr 2026 13:23:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568191; cv=none; b=XOtexA45rOXsuQ3S5SkcNdV/+TaWI8VB8vj0gTnjg6Jb3dguP0NQLtlkSW5evY5cWCKETwec0XfhV5R0d3AWn7fhnCVHsaXr9KXiY5Vbt2D3GSlNwlhvA7CT17tkXe27/Ms0TVB6oxP9V5TLMYjiW5f1mn8eOf/hXx/K6SUXE1g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568191; c=relaxed/simple; bh=69Who8r5Sb8ThckXkfsHphQ4S1KXUACGaFrCg+dMFxY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=nhFtJyqLei1whGLAE1ulc2amc9sKQZBrBjipXTANQ+KmT2wsDSfw3kARM9HKVK8nspQMkhQEnSizD4FW+F/FCcIJt39QPyabsJg1Tgfjzd/NiNKJPk4gn158kQwI2AJWLJ6NpmMugm5KCPopMgWcrXsNWvOirWsdMKOGK8oEEGU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=pQCn8Sri; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="pQCn8Sri" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C458BC2BCB0; Tue, 7 Apr 2026 13:23:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775568190; bh=69Who8r5Sb8ThckXkfsHphQ4S1KXUACGaFrCg+dMFxY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=pQCn8SriFyUaCC55mz/T9SHS8N8HSBwTYXdETLJTHvXmWFZSEBiUBNaS8cQay6YAi nBCy1S0vBW4IIdX8VqLRJQca2lXU9VKyOLaCEe9giulQ4+Pxw7amHUVV3nNYbI8Vy7 2J7tJS9dWxb2TsK4IbR/NyXKFDuOqNTxibHJqorkC6Z4d4jDOgD/JkK+/Qg+TWELiv J9V+1jjYhZebp/rIUTsxSbeSLjhXV/0+SQHPmDhxIvjyrC+BCKF9ustFirZlD97Nxe GIIutwB+GNzT8AhPupmLGDQzkQZLbUmJJRdX0Bh2pRvO3hFq82BH6smYppkTWV3Sq+ buzclgy3cSFzg== From: Jeff Layton Date: Tue, 07 Apr 2026 09:21:34 -0400 Subject: [PATCH 21/24] nfsd: add the filehandle to returned attributes in CB_NOTIFY Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260407-dir-deleg-v1-21-aaf68c478abd@kernel.org> References: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> In-Reply-To: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Amir Goldstein Cc: Calum Mackay , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=2618; i=jlayton@kernel.org; h=from:subject:message-id; bh=69Who8r5Sb8ThckXkfsHphQ4S1KXUACGaFrCg+dMFxY=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp1QUKO/c2Fj+9LQlaR9SOd8t4Jad4jMfKnIzeZ yvlBkjx2QKJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCadUFCgAKCRAADmhBGVaC FVJREACrBV8KbB6vVL2Pfa3c+TGp+SLR+yfe6S+72xf0mRBc5DwE3SYRDVs1yB8OC5YlIWUiAOV kGeHjkMhOPEzFtgt13ZqZDsTn75zlr41bXyVWuH4ZwrTkT/GFqh33IVIDv8gjOmB7aKEe2SPpRz AnAGAMR0IAF9PAxT2fFhQ3rpmXUD7QgPUN5dmNdHSMBKKW5UHAtfTTOEPmKTnkJgvpvqu1TUmuw APkbtns7NurbZ6xhxwgLTZXsqvmLbSc5cuGRrCn2gal1fDLt6fz95celDWKhTIRqceaU/+TMSDH TEHtS0tivkfNit33c6HrLv/zZNmzRyRaVVf5i2UQ6TF3E9pD9CyyykpC/Ox/446kdgPAkvmEY9g zfD3MzmSFIv6ff6kbGvnla8qJTfUs5aKOBBd3TyZkTp2EK2BtpLa37uXblFJ6kHi4YevXmduLep L9vjarB7rU1ynoIRUOiUm9TGTV1QSjaGghB7n2eS9iRJ0pUptHIw7iGT4T0yUJ4euGv4BLTkSGm NHRH7UsZ+k7V/3lj9vJgstUvci2C/p7wHU5h29MpH2RRi6/YSqetcJDSlg2tFfqBif/frMTCAny Xn6TAetDMqell2Xp944sCabRvEtWMCRRwQsYZco2PnYFjZJvwNCSY53f2rvYThE99/flkQF4Fnq qECfEqGy1yA7KIQ== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 nfsd's usual fh_compose routine requires a svc_export and fills out a svc_fh. In the context of a CB_NOTIFY there is no such export to consult. Add a new routine that composes a filehandle with only a parent filehandle and nfs4_file. Use that to fill out the fhandle field in the nfsd4_fattr_args. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4xdr.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index faf0c3d35dee..e468cbc087ad 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -4109,6 +4109,39 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct x= dr_stream *xdr, goto out; } =20 +static bool +setup_notify_fhandle(struct dentry *dentry, struct nfs4_file *fi, + struct nfsd_file *nf, struct nfsd4_fattr_args *args) +{ + int fileid_type, fsid_len, maxsize, flags =3D 0; + struct knfsd_fh *fhp =3D &args->fhandle; + struct inode *inode =3D d_inode(dentry); + struct inode *parent =3D NULL; + struct fid *fid; + + fsid_len =3D key_len(fi->fi_fhandle.fh_fsid_type); + fhp->fh_size =3D 4 + fsid_len; + + /* Copy first 4 bytes + fsid */ + memcpy(&fhp->fh_raw, &fi->fi_fhandle.fh_raw, fhp->fh_size); + + fid =3D (struct fid *)(fh_fsid(fhp) + fsid_len/4); + maxsize =3D (NFS4_FHSIZE - fhp->fh_size)/4; + + if (fi->fi_connectable && !S_ISDIR(inode->i_mode)) { + parent =3D d_inode(nf->nf_file->f_path.dentry); + flags =3D EXPORT_FH_CONNECTABLE; + } + + fileid_type =3D exportfs_encode_inode_fh(inode, fid, &maxsize, parent, fl= ags); + if (fileid_type < 0) + return false; + + fhp->fh_fileid_type =3D fileid_type; + fhp->fh_size +=3D maxsize * 4; + return true; +} + #define CB_NOTIFY_STATX_REQUEST_MASK (STATX_BASIC_STATS | \ STATX_BTIME | \ STATX_CHANGE_COOKIE) @@ -4118,6 +4151,7 @@ nfsd4_setup_notify_entry4(struct notify_entry4 *ne, s= truct xdr_stream *xdr, struct dentry *dentry, struct nfs4_delegation *dp, struct nfsd_file *nf, char *name, u32 namelen) { + struct nfs4_file *fi =3D dp->dl_stid.sc_file; struct path path =3D { .mnt =3D nf->nf_file->f_path.mnt, .dentry =3D dentry }; struct nfsd4_fattr_args args =3D { }; @@ -4156,6 +4190,9 @@ nfsd4_setup_notify_entry4(struct notify_entry4 *ne, s= truct xdr_stream *xdr, FATTR4_WORD1_TIME_METADATA | FATTR4_WORD1_TIME_MODIFY; attrmask[2] =3D 0; =20 + if (setup_notify_fhandle(dentry, fi, nf, &args)) + attrmask[0] |=3D FATTR4_WORD0_FILEHANDLE; + if (args.stat.result_mask & STATX_BTIME) attrmask[1] |=3D FATTR4_WORD1_TIME_CREATE; =20 --=20 2.53.0 From nobody Sun Jun 21 04:17:36 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 42E083C1973; Tue, 7 Apr 2026 13:23:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568193; cv=none; b=nh+KvaVW0YRs8Kp7TYA9RlQHXBpM/2KgBzYzrKkjVxUEJPBvsCjQBGHMwF4Blu6e2HzyW/zotOU6HDNMtwhbAmLbGfjSfrQyxhbFvTt6YKsPeVqDeq+CEbr4ZxG9UJtC6vy5TKcgnyJOWkp9wHmbEBFnoBw7t/iu30/faa18CDE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568193; c=relaxed/simple; bh=6lW+mmfHSBDA9D8DC1Iq7Pv3CaqCnyz3U/MpxK0qRxU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=KnSYdKr9EIWw7jNyspO7sTDfjTy/aegvpzhmV5DzsSPctaEZkhwrR66UbdFlFEBdmR/7NKqt/r73Opsz0fJifJb68tJ3lex6AEBhi1dgHScFSbLjaQsZEfO0dVFs4sJz9iuS5vCLLN9yheo/b8Evllk+oFtoPXdI+sXXZA6KbpY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=n1UhGFiI; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="n1UhGFiI" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1B116C19424; Tue, 7 Apr 2026 13:23:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775568193; bh=6lW+mmfHSBDA9D8DC1Iq7Pv3CaqCnyz3U/MpxK0qRxU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=n1UhGFiIs6RGIOAT6gPDlrzBvZZIUJD3OeWKCcJGCdmVaAHsBQS3wudTjIVR9wH8w Eiyf5A3YQlY221n0VBuMHwssDDIKEjjer4SA4/61toMn4WjT3g57YJixrXSlQpZpV5 0Jz1nP423+hSyiwX+NZ0qVEWPBfkMc/ztcdth2WY1932QZwLyvNf+M9XzXKRQAA4i/ hnhOu6szCJSoXGQZtSrTcIm+Ws0Cqnbjc49cM7k8SOiuA/tYiQisOnxNJINOO11FPh WBbBSucCigjwJEEsy7FxLrQyufX9tgpviHXuVSkY5qzQ0G49a5Wgj8jS7TBti43ym2 yIpSVW7z2VkAQ== From: Jeff Layton Date: Tue, 07 Apr 2026 09:21:35 -0400 Subject: [PATCH 22/24] nfsd: properly track requested child attributes Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260407-dir-deleg-v1-22-aaf68c478abd@kernel.org> References: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> In-Reply-To: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Amir Goldstein Cc: Calum Mackay , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=3821; i=jlayton@kernel.org; h=from:subject:message-id; bh=6lW+mmfHSBDA9D8DC1Iq7Pv3CaqCnyz3U/MpxK0qRxU=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp1QUKeBwnCG+4vk3hoAGyaYN+Q7iDhFKhKs1cL LFLfqRoYxiJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCadUFCgAKCRAADmhBGVaC FStsEACQ+cUDVZW+lIi5EFecrkI6Puv2AKSwwp2PQfvR6ZwGpBYhql0gzYHNWIULoeWYXJPsuyc 5jm921xFddO+Wo34QTSRHg7mRGHU9zCf+sdkAGtpe66x3QZyIA19MtLgNNmBuYBvH2yFW6+FQbr ZZeYMoWAaXChsO6GnW0Keuy55OP9cWNCl7JupYnwqLfJwN07gyIkyjo7SIUNk5UCnh7AlpDc3sv TySg9gYK+DnUr+3B05hg2UTChbV3aEylpA1DJI2WlAJuQsgyCJWGqzCX2BPlQPpoTpd9tOh7X/w bXafkbBL4SgxVsOqVNdDJU/XaloYhupce80GjEZ+/TsI8eTTYyTi2fAwUzIHHs/7Foq5zYIaNLl 3VtsD0ET5VWcETBYmjYZBKfepZohhZJbHiDk0M/hLarTHQmu/bHP9wamsFxj949ylrpJMJnWA9M df1WFq7fcjTL2yMEJhKmBPwTAjky0hbAXloeHrUYa8rYUlynG8KPqIBmPsxHBQOlbtOpMHhfK7S PAIDXkYe+gZZ9JzPDFEc9yU7kPA7tW2ApTI2peEOLXkyo2oJISGd2RPQTMYNsYO6dnPpawhyV6v cFn9ehNQvK9R0SW7i+4rzhgXEHvpWiwCvxgdyYJR2nx8CgbAhzSZQ/WAcNA3jXvbolld66wC+ox HD+ujPLCxMyE67A== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Track the union of requested and supported child attributes in the delegation, and only encode the attributes in that union when sending add/remove/rename updates. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4proc.c | 2 ++ fs/nfsd/nfs4state.c | 18 ++++++++++++++++++ fs/nfsd/nfs4xdr.c | 15 ++++++--------- fs/nfsd/state.h | 3 +++ 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 01e3bf9e1839..a807a55dddf9 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -2553,6 +2553,8 @@ nfsd4_get_dir_delegation(struct svc_rqst *rqstp, =20 gdd->gddrnf_status =3D GDD4_OK; memcpy(&gdd->gddr_stateid, &dd->dl_stid.sc_stateid, sizeof(gdd->gddr_stat= eid)); + gdd->gddr_child_attributes[0] =3D dd->dl_child_attrs[0]; + gdd->gddr_child_attributes[1] =3D dd->dl_child_attrs[1]; nfs4_put_stid(&dd->dl_stid); return nfs_ok; } diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 0580c935d804..59a9b1ca836b 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -9780,6 +9780,21 @@ nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp,= struct dentry *dentry, return status; } =20 +#define GDD_WORD0_CHILD_ATTRS (FATTR4_WORD0_TYPE | \ + FATTR4_WORD0_CHANGE | \ + FATTR4_WORD0_SIZE | \ + FATTR4_WORD0_FILEID | \ + FATTR4_WORD0_FILEHANDLE) + +#define GDD_WORD1_CHILD_ATTRS (FATTR4_WORD1_MODE | \ + FATTR4_WORD1_NUMLINKS | \ + FATTR4_WORD1_RAWDEV | \ + FATTR4_WORD1_SPACE_USED | \ + FATTR4_WORD1_TIME_ACCESS | \ + FATTR4_WORD1_TIME_METADATA | \ + FATTR4_WORD1_TIME_MODIFY | \ + FATTR4_WORD1_TIME_CREATE) + /** * nfsd_get_dir_deleg - attempt to get a directory delegation * @cstate: compound state @@ -9849,6 +9864,9 @@ nfsd_get_dir_deleg(struct nfsd4_compound_state *cstat= e, dp->dl_stid.sc_export =3D exp_get(cstate->current_fh.fh_export); =20 + dp->dl_child_attrs[0] =3D gdd->gdda_child_attributes[0] & GDD_WORD0_CHILD= _ATTRS; + dp->dl_child_attrs[1] =3D gdd->gdda_child_attributes[1] & GDD_WORD1_CHILD= _ATTRS; + fl =3D nfs4_alloc_init_lease(dp, gdd->gddr_notification[0]); if (!fl) goto out_put_stid; diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index e468cbc087ad..35646809becb 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -4183,18 +4183,15 @@ nfsd4_setup_notify_entry4(struct notify_entry4 *ne,= struct xdr_stream *xdr, =20 args.change_attr =3D nfsd4_change_attribute(&args.stat); =20 - attrmask[0] =3D FATTR4_WORD0_TYPE | FATTR4_WORD0_CHANGE | - FATTR4_WORD0_SIZE | FATTR4_WORD0_FILEID; - attrmask[1] =3D FATTR4_WORD1_MODE | FATTR4_WORD1_NUMLINKS | FATTR4_WORD1_= RAWDEV | - FATTR4_WORD1_SPACE_USED | FATTR4_WORD1_TIME_ACCESS | - FATTR4_WORD1_TIME_METADATA | FATTR4_WORD1_TIME_MODIFY; + attrmask[0] =3D dp->dl_child_attrs[0]; + attrmask[1] =3D dp->dl_child_attrs[1]; attrmask[2] =3D 0; =20 - if (setup_notify_fhandle(dentry, fi, nf, &args)) - attrmask[0] |=3D FATTR4_WORD0_FILEHANDLE; + if (!setup_notify_fhandle(dentry, fi, nf, &args)) + attrmask[0] &=3D ~FATTR4_WORD0_FILEHANDLE; =20 - if (args.stat.result_mask & STATX_BTIME) - attrmask[1] |=3D FATTR4_WORD1_TIME_CREATE; + if (!(args.stat.result_mask & STATX_BTIME)) + attrmask[1] &=3D ~FATTR4_WORD1_TIME_CREATE; =20 ne->ne_attrs.attrmask.count =3D 2; ne->ne_attrs.attr_vals.data =3D (u8 *)xdr->p; diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index d060d70c5820..7ca5ef9caafe 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -282,6 +282,9 @@ struct nfs4_delegation { struct timespec64 dl_atime; struct timespec64 dl_mtime; struct timespec64 dl_ctime; + + /* For dir delegations */ + uint32_t dl_child_attrs[2]; }; =20 static inline bool deleg_is_read(u32 dl_type) --=20 2.53.0 From nobody Sun Jun 21 04:17:36 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C07413BA23B; Tue, 7 Apr 2026 13:23:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568195; cv=none; b=Rq7PHv8KFKXIMVV9QzGCcQW4kQx9Gq5QksCboH2mYxDxtNfNVy6ML2i/KUF+dBbVLRqI5m4jkdu7h3FzpAlhxS20tdosHf69SLN2nO4//Jolnmjls5DQi7zsUmNl8cUBNy7n1H3A36U9DG5UwuP89wyBN4hXV+KG02DczDDGgg0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568195; c=relaxed/simple; bh=cV8pXiuyww/5TGNvhSUjcD3GMkRQw1n4h5NogV50cnI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=YM4d3mRxaflKGvN5RmRxneuTbIYJto0RCWB8EgAtPL3acPkE9gd64hpSWIGHTfaHLbrt9hGOUQozCCAeHt1EZUUP+z5Pd120OyPylI8vzE1snnAxt1r0UFISojSUlZztpDBFemKpIRUY0Vd+mIZAvmRwbTus8u+smohmcgpkXtU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=JmXX/5XO; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="JmXX/5XO" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 66360C2BCAF; Tue, 7 Apr 2026 13:23:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775568195; bh=cV8pXiuyww/5TGNvhSUjcD3GMkRQw1n4h5NogV50cnI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=JmXX/5XONUkCrb+nx9dY1n9XoWY6F3FipeusMaKqc048XeJa9G69AudB5j0QIuKoc gxXPw28zqFQDStctePz5VIqKYUVb+7ZOsaPVoJy/pBdDl2F+MejTa7vj9F4RFS+UUQ qpv2vzq+8FKaiVjjbZLQjETc9t3KPz9ufkbLX3Klq4UY/0sY3/NrJYbv4wjbjGILRs F5jnoYGCM0phchAjNUDki+i8gpsGakzRfzl4RSKJjiZAhLNMQhlWp37u7z5XPT3qYz fzx9uf6szUXOV26ymcoPLOrvHje34MQ4jZvNMePbWnZ/BwpzHEQFO2vcXmzQTRQFU/ 8PqDYvoqV4tuA== From: Jeff Layton Date: Tue, 07 Apr 2026 09:21:36 -0400 Subject: [PATCH 23/24] nfsd: track requested dir attributes Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260407-dir-deleg-v1-23-aaf68c478abd@kernel.org> References: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> In-Reply-To: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Amir Goldstein Cc: Calum Mackay , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=2846; i=jlayton@kernel.org; h=from:subject:message-id; bh=cV8pXiuyww/5TGNvhSUjcD3GMkRQw1n4h5NogV50cnI=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp1QUL8zuuKLv6Yact/lLT4jRwrbRopcqjbV94M PYWLd84jIOJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCadUFCwAKCRAADmhBGVaC FQ92EADCa7pHQEKRBDt2eQob0s1rgETuh1Wpk18yZ3Txw8qa5tUHPcy+o0k9PpnfyEys6/BaDEr bxcaooM6z4ycTqVnxYFc4I5m5/cl00kx50z2Z9ZlGbSEY7vl5FX3Qgr/kXlnn+BP5ejueeTkkIC Brz5rTtEYXSn697xleZqEzWHgVCFgz7YLdlXghmKpaLNmNDEMCuPYGtctTGzOHuo0MnVabhbEJO UL0vP32xafljSpjlMeXYUGHZX7sq/KTuD+pGelFeJDDozdgOuIKF6TkQpGB6nqckir8aQZbtsbz i09DqGsKM7ujFGJsp5xf8rxPfW/R2Mx+dODC2xFc9mTH4pppXSOsjTs3nFhN5Ie5zsWLm04nC2u v2twYTUbFx8k3de5FtPx7UJJZn6Fd9yb/5DZTZf3t0yPOC8dbKpFlk2WgRuAARpWD+TyiOHJXaJ uOqJQhq8e3rL+sl7Lklc5xyTBvwiBp3kLVa+CTAmkfDBhkETRV5CaNzV5Z5piCc3AIbetpYefoQ LYu1sxKcmi8iDsycHf36hrjaKEi8BP5a7tWN7zzNvrRFRs6/7AkkvmqoZjdYy79J3obuHj3MINg 8uncqrAS/1EhZ3KoIgb75T9Kb82z8beqZWfiZYUkZx0njRJB6EBg+D1HTND8OwFnAV5WTnhvEfH OieY/B55nsDLEIw== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Track the union of requested and supported dir attributes in the delegation, and only encode the attributes in that union when sending add/remove/rename updates. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4proc.c | 7 ++++--- fs/nfsd/nfs4state.c | 14 +++++++++++++- fs/nfsd/state.h | 2 ++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index a807a55dddf9..82d7c473e4d3 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -2506,9 +2506,10 @@ nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_co= mpound_state *cstate, return status =3D=3D nfserr_same ? nfs_ok : status; } =20 -#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)) =20 static __be32 diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 59a9b1ca836b..c4b6f4d65a47 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -9795,6 +9795,15 @@ nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp,= struct dentry *dentry, FATTR4_WORD1_TIME_MODIFY | \ FATTR4_WORD1_TIME_CREATE) =20 +#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 @@ -9864,10 +9873,13 @@ nfsd_get_dir_deleg(struct nfsd4_compound_state *cst= ate, dp->dl_stid.sc_export =3D exp_get(cstate->current_fh.fh_export); =20 + dp->dl_notify_mask =3D gdd->gddr_notification[0]; dp->dl_child_attrs[0] =3D gdd->gdda_child_attributes[0] & GDD_WORD0_CHILD= _ATTRS; dp->dl_child_attrs[1] =3D gdd->gdda_child_attributes[1] & GDD_WORD1_CHILD= _ATTRS; + dp->dl_dir_attrs[0] =3D gdd->gdda_dir_attributes[0] & GDD_WORD0_DIR_ATTRS; + dp->dl_dir_attrs[1] =3D gdd->gdda_dir_attributes[1] & GDD_WORD1_DIR_ATTRS; =20 - fl =3D nfs4_alloc_init_lease(dp, gdd->gddr_notification[0]); + fl =3D nfs4_alloc_init_lease(dp, dp->dl_notify_mask); if (!fl) goto out_put_stid; =20 diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 7ca5ef9caafe..56a3cfb12e65 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -284,7 +284,9 @@ struct nfs4_delegation { struct timespec64 dl_ctime; =20 /* For dir delegations */ + uint32_t dl_notify_mask; uint32_t dl_child_attrs[2]; + uint32_t dl_dir_attrs[2]; }; =20 static inline bool deleg_is_read(u32 dl_type) --=20 2.53.0 From nobody Sun Jun 21 04:17:36 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D7AE53BAD81; Tue, 7 Apr 2026 13:23:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568197; cv=none; b=ExeW+G5aZmgogKPWDo4SvvrRoLCfTefkFA88BhQalQbyA85G6SiCABOKcuHRL30T3Ink6xQ7mHNajwr/HWplukaBxuBLeMLoWd4hHxJkT2CEzok6mC7WHCRFb6i4Du1V8CqsGPpR7dzBchQMxsHVYPzo7RjE8Dj2TZeXjmUmYO4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775568197; c=relaxed/simple; bh=N+ewIUhqIHe2sDtA5GLxcBpX3A61fz037ixhW7ZLoZc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=JhGsoTKN0Ow/LMmcuB1pvkjH8+qlg4Uicp1srwsEaCZTRp0UngVm4l5zYzxvA95NR83cUF2cwp9AUYNEDJiANRrJ8y5mRVS0rZDPEMRk3Qt7rkunMb+yzZehuzlvJHGMjZ4x7maV4D0jcwRzrB/vyrhSuQPszl5Ty9uEKSAwzIA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=gFNvnC1m; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="gFNvnC1m" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B05E5C2BCB0; Tue, 7 Apr 2026 13:23:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775568197; bh=N+ewIUhqIHe2sDtA5GLxcBpX3A61fz037ixhW7ZLoZc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=gFNvnC1mh9D5Q4e5Ek+oTW8wD3m7CTunKFG3jPBMs6aGuF1d92bur6Yc7Hjbkp6dX Z2hsqmh9Ogv0WcG56IJioer3zXABXpacPa1lqjtqlR0dSZArNLbtsIHg1o+m5yl+Qp GxnHsrFrc2Vz5VqfMCLejBcHHI7uXOstookDIRyKgJJudBogDDDL40kmqyuaHscX51 fpmMYxe+5dwh+7y8GoUm7o5ldswW3asthI6+bXqC2Z3B6uP/GYw/gBPE9HpNOMBhiI hXaU1VY1Ub+5dsu5kFqWD0crrPefmZOspqq/rx7Lapg3+evO6Qoco/t8xa11JAcF4r o14FDuCCIa02Q== From: Jeff Layton Date: Tue, 07 Apr 2026 09:21:37 -0400 Subject: [PATCH 24/24] nfsd: add support to CB_NOTIFY for dir attribute changes Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260407-dir-deleg-v1-24-aaf68c478abd@kernel.org> References: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> In-Reply-To: <20260407-dir-deleg-v1-0-aaf68c478abd@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Alexander Aring , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Jonathan Corbet , Shuah Khan , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , Amir Goldstein Cc: Calum Mackay , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=6108; i=jlayton@kernel.org; h=from:subject:message-id; bh=N+ewIUhqIHe2sDtA5GLxcBpX3A61fz037ixhW7ZLoZc=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp1QULdWggYOsqOFrE5WckiwisWouEGdFj9at6Y K+0O926hcCJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCadUFCwAKCRAADmhBGVaC FQrQD/wOQFTlBqMq/w6845qcUCWDAmcaqx/7T6LwaqaXVLify8aVCP1tQ2dtVivZ6WjqZLJEB8x utek04ufjR366rxLUTx4cBjRK+gq+uHFzxWJ8XnO1evG3Xq6JrcHj71CSgDt10fBoXTpsiiaxcf RAv1ht2izBWmnK198hJqDNBA7ApaEhhI90pmxAlWJ1EP2PVKt0+49Ry6CfEvxYEoCNU9hHLEI9A RFYTltJqmQdQsEc7Ks9KbIpOaKsCwXRJlHYVsaGAO8zjqJIQFb/euUOm4CEZ3SwmZmfrxECkOL3 5rhCPwi/2IfK9SpbgW0OjCVeathPDG1WrKYYQGX2pI+IpCb4PbxnDbkqXQ119VAECVEhH3deFTm V8hoSXfmmYY74RF3DkcvnpgoXx10lioaoGgiGdTrVy1GO31/e1FipS7rfp3BhFS7UEPhoOKqUAG QtC+VXY3JUS/NVQr4414nU5GQuZ+IghEVukonE5fSzias/Ebsm75IQ5qxjy0h2OKBACsoKxrOz7 8SCMmxGOS38y1xSsty5ah74uTAbKPKwggmrKrpbCM0DHKyHUbcJhtclWo0cZfxwNSVWZJVy/Ooy f+G1c8aAYRXvvBvW/hCgWnqdRWEqYMw2trVFnsLy0dutOMsJO3rcX1sUcQJEfkzyMQZNsidZwPl 59j2LDserQjS3pQ== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 If the client requested dir attribute change notifications, send those alongside any set of add/remove/rename events. Note that the server will still recall the delegation on a SETATTR, so these are only sent for changes to child dirents. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4state.c | 25 ++++++++++++++++++++-- fs/nfsd/nfs4xdr.c | 61 +++++++++++++++++++++++++++++++++++++++++++++----= ---- fs/nfsd/xdr4.h | 2 ++ 3 files changed, 77 insertions(+), 11 deletions(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index c4b6f4d65a47..01a2fb11dc0e 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -3470,10 +3470,15 @@ nfsd4_cb_notify_prepare(struct nfsd4_callback *cb) struct nfsd_notify_event *events[NOTIFY4_EVENT_QUEUE_SIZE]; struct xdr_buf xdr =3D { .buflen =3D PAGE_SIZE * NOTIFY4_PAGE_ARRAY_SIZE, .pages =3D ncn->ncn_pages }; + int limit =3D NOTIFY4_EVENT_QUEUE_SIZE; struct xdr_stream stream; struct nfsd_file *nf; - int count, i; bool error =3D false; + int count, i; + + /* Save a slot for dir attr update if requested */ + if (dp->dl_notify_mask & BIT(NOTIFY4_CHANGE_DIR_ATTRS)) + --limit; =20 xdr_init_encode_pages(&stream, &xdr); =20 @@ -3487,7 +3492,7 @@ nfsd4_cb_notify_prepare(struct nfsd4_callback *cb) } =20 /* we can't keep up! */ - if (count > NOTIFY4_EVENT_QUEUE_SIZE) { + if (count > limit) { spin_unlock(&ncn->ncn_lock); goto out_recall; } @@ -3534,6 +3539,22 @@ nfsd4_cb_notify_prepare(struct nfsd4_callback *cb) nfsd_notify_event_put(nne); } if (!error) { + if (dp->dl_notify_mask & BIT(NOTIFY4_CHANGE_DIR_ATTRS)) { + u32 *maskp =3D (u32 *)xdr_reserve_space(&stream, sizeof(*maskp)); + + if (maskp) { + u8 *p =3D nfsd4_encode_dir_attr_change(&stream, dp, nf); + + if (p) { + *maskp =3D BIT(NOTIFY4_CHANGE_DIR_ATTRS); + ncn->ncn_nf[count].notify_mask.count =3D 1; + ncn->ncn_nf[count].notify_mask.element =3D maskp; + ncn->ncn_nf[count].notify_vals.data =3D p; + ncn->ncn_nf[count].notify_vals.len =3D (u8 *)stream.p - p; + ++count; + } + } + } ncn->ncn_nf_cnt =3D count; nfsd_file_put(nf); return true; diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 35646809becb..6e76502ca149 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -4152,11 +4152,11 @@ nfsd4_setup_notify_entry4(struct notify_entry4 *ne,= struct xdr_stream *xdr, struct nfsd_file *nf, char *name, u32 namelen) { struct nfs4_file *fi =3D dp->dl_stid.sc_file; - struct path path =3D { .mnt =3D nf->nf_file->f_path.mnt, - .dentry =3D dentry }; + struct path path =3D nf->nf_file->f_path; struct nfsd4_fattr_args args =3D { }; uint32_t *attrmask; __be32 status; + bool parent; int ret; =20 /* Reserve space for attrmask */ @@ -4168,6 +4168,9 @@ nfsd4_setup_notify_entry4(struct notify_entry4 *ne, s= truct xdr_stream *xdr, ne->ne_file.len =3D namelen; ne->ne_attrs.attrmask.element =3D attrmask; =20 + parent =3D (dentry =3D=3D path.dentry); + path.dentry =3D dentry; + /* FIXME: d_find_alias for inode ? */ if (!path.dentry || !d_inode(path.dentry)) goto noattrs; @@ -4183,15 +4186,20 @@ nfsd4_setup_notify_entry4(struct notify_entry4 *ne,= struct xdr_stream *xdr, =20 args.change_attr =3D nfsd4_change_attribute(&args.stat); =20 - attrmask[0] =3D dp->dl_child_attrs[0]; - attrmask[1] =3D dp->dl_child_attrs[1]; - attrmask[2] =3D 0; + if (parent) { + attrmask[0] =3D dp->dl_dir_attrs[0]; + attrmask[1] =3D dp->dl_dir_attrs[1]; + } else { + attrmask[0] =3D dp->dl_child_attrs[0]; + attrmask[1] =3D dp->dl_child_attrs[1]; =20 - if (!setup_notify_fhandle(dentry, fi, nf, &args)) - attrmask[0] &=3D ~FATTR4_WORD0_FILEHANDLE; + if (!setup_notify_fhandle(dentry, fi, nf, &args)) + attrmask[0] &=3D ~FATTR4_WORD0_FILEHANDLE; =20 - if (!(args.stat.result_mask & STATX_BTIME)) - attrmask[1] &=3D ~FATTR4_WORD1_TIME_CREATE; + if (!(args.stat.result_mask & STATX_BTIME)) + attrmask[1] &=3D ~FATTR4_WORD1_TIME_CREATE; + } + attrmask[2] =3D 0; =20 ne->ne_attrs.attrmask.count =3D 2; ne->ne_attrs.attr_vals.data =3D (u8 *)xdr->p; @@ -4283,6 +4291,41 @@ u8 *nfsd4_encode_notify_event(struct xdr_stream *xdr= , struct nfsd_notify_event * return NULL; } =20 +/** + * nfsd4_encode_dir_attr_change + * @xdr: stream to which to encode the fattr4 + * @dp: delegation where the event occurred + * @nf: nfsd_file opened on the directory + * + * Encode a dir attr change event. + */ +u8 *nfsd4_encode_dir_attr_change(struct xdr_stream *xdr, struct nfs4_deleg= ation *dp, + struct nfsd_file *nf) +{ + struct dentry *dentry =3D nf->nf_file->f_path.dentry; + struct notify_attr4 na =3D { }; + struct name_snapshot n; + bool ret; + u8 *p =3D NULL; + + if (!(dp->dl_notify_mask & BIT(NOTIFY4_CHANGE_DIR_ATTRS))) + return NULL; + + take_dentry_name_snapshot(&n, dentry); + ret =3D nfsd4_setup_notify_entry4(&na.na_changed_entry, xdr, + dentry, dp, nf, (char *)n.name.name, + n.name.len); + + /* Don't bother with the event if we're not encoding attrs */ + if (ret && na.na_changed_entry.ne_attrs.attr_vals.len) { + p =3D (u8 *)xdr->p; + if (!xdrgen_encode_notify_attr4(xdr, &na)) + p =3D NULL; + } + release_dentry_name_snapshot(&n); + return p; +} + static void svcxdr_init_encode_from_buffer(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p, int bytes) { diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index d276840aca50..cf7f0df68d63 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -958,6 +958,8 @@ __be32 nfsd4_encode_fattr_to_buf(__be32 **p, int words, u8 *nfsd4_encode_notify_event(struct xdr_stream *xdr, struct nfsd_notify_e= vent *nne, struct nfs4_delegation *dd, struct nfsd_file *nf, u32 *notify_mask); +u8 *nfsd4_encode_dir_attr_change(struct xdr_stream *xdr, struct nfs4_deleg= ation *dp, + struct nfsd_file *nf); extern __be32 nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *, union nfsd4_op_u *u); extern __be32 nfsd4_setclientid_confirm(struct svc_rqst *rqstp, --=20 2.53.0