From nobody Tue Jun 16 06:04:57 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 C88AE22A4E9; Tue, 28 Apr 2026 07:10:23 +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=1777360223; cv=none; b=OJvLAvD95NmuadSal2SwLPgLuT9/ewRWaj39AVIPdo9zH5W4nvo743G0JVAJcNf4nOEc5CDh3ksOvKEa1PfLkXnf8UfUfhveqWxcthpwrOTAKv6Xc3meORq6o+1nfUsVsFwPteJKlU5av5mrn3iyUjrKtM3DgLxNTK0c1JUfGT8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777360223; c=relaxed/simple; bh=SSAdEWM+ofXOJU1zf9WFQv+WMKZekPpJCkvMvEn6hf0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=DSSQQC+6Ezp8vhKAtiIW6dOaBO92FLzgjWRbxSTZ2fhdLpWVnxoapFLAaO9osM1KR0IIfpj+WGxICs/fyxJ1HvtEtMG6Gu0VW7b2ypOUSGmJ8e618/rPouVEXvl8JfTT5YwZA43j3JXAo/hY18OKIJm3lOMI8DIDZ4sXxFE4QTs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=H+K1tX1K; 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="H+K1tX1K" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0BFB7C2BCAF; Tue, 28 Apr 2026 07:10:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777360223; bh=SSAdEWM+ofXOJU1zf9WFQv+WMKZekPpJCkvMvEn6hf0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=H+K1tX1KrM6PpZWjqHAGoSBuJpMajHH7U65z1gi+pkK5a2aGJIyWTuRfWDC5bBB0i LkYvjTRG0pWNPW43ZiGJs0iZtyKGlN9dHplPBL2WZYNhhsojgG/iVJO6+A/JHy5Vyz O5Wib/TB0emC1NvDqsh5rplppOyvcWx/hi5Uk4HdOIC+50fk7DH9EfWC1G8ywLVngt gtYuv+x/6A3ze1YAKZH+SnH4ZutqKKGzQruUdW9XoVrxm8bFGJgCLoAB76rgAfH/95 xcXWVnQ++UA1RYkWYkL7MQZrMwNu6QaFAuiaP1XhoPPo7OyaBieh8yxBeCPekO34/O e+IqjP0epH4Lw== From: Jeff Layton Date: Tue, 28 Apr 2026 08:09:45 +0100 Subject: [PATCH v3 01/28] filelock: pass current blocking lease to trace_break_lease_block() rather than "new_fl" 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: <20260428-dir-deleg-v3-1-5a0780ba9def@kernel.org> References: <20260428-dir-deleg-v3-0-5a0780ba9def@kernel.org> In-Reply-To: <20260428-dir-deleg-v3-0-5a0780ba9def@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=1258; i=jlayton@kernel.org; h=from:subject:message-id; bh=SSAdEWM+ofXOJU1zf9WFQv+WMKZekPpJCkvMvEn6hf0=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp8F1MMl3pxBzY0cOV4TMIfAHAgj72nno40qM2+ xd/NyEzwuWJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCafBdTAAKCRAADmhBGVaC Fdr+EACXrGFa/aD+nrNW0vYZ04n+m5eXgR+iObb1IXpwnjxtC3iejDkdQwgYVEKJ7YoRMWe2x1V 5yLx86tiD8Jww15Zfj2ZeKKevZPkQ2ts4NNaUxE61B6UbfQCSE8W0YwOSVVjRxcp9wtnPQSyk1W 1ZPYGhmOx8zIV9mbs/LnuPZmcdSL5Hvnrr1wh6zUJhmdTCebHpnRWVQwRrKpj1GsQk4h+xMnBvP 8/OQsbBl32CZ+N3nEyy8Xq5D51bYktMEa0QByzFZJBmFdmIAQsAxYGANYu2kD5ysS3yVsQqaM1E 39YhnZVgGkIGDSQmT8OA0HBIr4Lp9/Rq3RNBuAdHM0ug4xTy7M5gpAInBYTaVrypkuZDSB3NiV8 sZy02fvD0XT6MQQhHIeK65PFWxvIGUnjsQgF+qrcfUxhFSzmW1h4KhdYMwVVzIZ0Uy5J8/mR5V7 2b6Hpg4OvCyCGLCvp7mgZy8PIIOdT0Z107Ao3YDg14Wm7A69dgtRk2GuHAgKp9tQJy2XKHkBIUr 6sJkIfgqBdi5ak+9gcM4vCiemKn4v0jwwT113kY/NhTRAYpwHspsdlgHCadMnBrMQMezgUe7y95 kudXxeEqiCYASQ4EA05aUu88QFt9WFnoaNV8xs1MwdHtF/ovDvo7O222i4Z3lDtEV1Y5YzMJ7bq yuERRHBaWrYwPVQ== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 The break_lease_block tracepoint currently just shows the type of "new_fl", which we can predict from the "flags" value. Switch it to display info about "fl" instead, as that's the file_lease on which the code is blocking. For trace_break_lease_unblock(), pass it a NULL pointer. "fl" may have been freed by that point, and passing it the info in new_fl is deceptive. Signed-off-by: Jeff Layton Acked-by: Chuck Lever --- fs/locks.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/locks.c b/fs/locks.c index 8e44b1f6c15a..d82c5be7aa5b 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1691,7 +1691,7 @@ int __break_lease(struct inode *inode, unsigned int f= lags) } else break_time++; locks_insert_block(&fl->c, &new_fl->c, leases_conflict); - trace_break_lease_block(inode, new_fl); + trace_break_lease_block(inode, fl); spin_unlock(&ctx->flc_lock); percpu_up_read(&file_rwsem); =20 @@ -1702,7 +1702,7 @@ int __break_lease(struct inode *inode, unsigned int f= lags) =20 percpu_down_read(&file_rwsem); spin_lock(&ctx->flc_lock); - trace_break_lease_unblock(inode, new_fl); + trace_break_lease_unblock(inode, NULL); __locks_delete_block(&new_fl->c); if (error >=3D 0) { /* --=20 2.54.0 From nobody Tue Jun 16 06:04:57 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 57AD83A7F5D; Tue, 28 Apr 2026 07:10: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=1777360229; cv=none; b=WPBLlJDtn8tlb/iBtsDo/y6+i0Br44v4yyhx6u3/gzUQ/D2AJqbfH/32bqZXxtPPJmXB9BR16v2WYUJaAzlFizrvqA8sy3xspk3CBmQgXJetoT7e7V+8K7aJecNb8oiw/50PbjMC4eShbaMUdYRnS6w6hr8sUyYNnZ49in0hjdA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777360229; c=relaxed/simple; bh=8Z7N2bQ8blLyLleUqDAJ5BSeFey9tIkMgl+lwwL6tDE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=PdV53NSaeXB74AdzWiHBPrVoUfyxCE3HsQ/OqxFust3pZRjkJKvpZMPSENCFNzZTI7/c65uI6t6wxV85gzzAdfSUoH0g0go7jrDjEBkAE88Nh6vAcXYUkF4YYclMB58hNRn++RHrSTbgG//DUfmPDH++EmEwT+s8yr/xJRbnVOI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=WpZtaXkk; 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="WpZtaXkk" Received: by smtp.kernel.org (Postfix) with ESMTPSA id DE4C4C2BCB5; Tue, 28 Apr 2026 07:10:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777360228; bh=8Z7N2bQ8blLyLleUqDAJ5BSeFey9tIkMgl+lwwL6tDE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=WpZtaXkklluRDa1rIqja8qQscb/l4lGzYkaskiD/CcxnOWGsxkj3rpvu8XELfpr8v fPZv4SOT/PEnyREEMgKY1x4Y0EAlJbBMDnZ2gCWm7J6YEB550ZiN4z7+lI8XRH9ErW Ym05lg9UIwgCDAHDHK2swqwcvZDfTNPlOy0seYo9fYMbpXnR6WrE7RWeYvVg9ucUl2 /hiDeEIv/vIewBC4WyuI6XJ8lLoMt1+ElRhPTeeK+2iys62/zHFtnNqO+aoW5Ifnzx Ml1QSLUOaYCl3HxGWuSfGZfPozxV6cbyCw7UwekRrvHFxzRFPoHfuE+gNU6lOt6kj1 AAQ8e5ZGaOocA== From: Jeff Layton Date: Tue, 28 Apr 2026 08:09:46 +0100 Subject: [PATCH v3 02/28] 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: <20260428-dir-deleg-v3-2-5a0780ba9def@kernel.org> References: <20260428-dir-deleg-v3-0-5a0780ba9def@kernel.org> In-Reply-To: <20260428-dir-deleg-v3-0-5a0780ba9def@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=16061; i=jlayton@kernel.org; h=from:subject:message-id; bh=8Z7N2bQ8blLyLleUqDAJ5BSeFey9tIkMgl+lwwL6tDE=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp8F1NrG5vP5Rn3ZLLlAwiFh66t/dzdn8FQNR9N fsmzc8zATWJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCafBdTQAKCRAADmhBGVaC FSrGD/9fxZP2XK5h1u+8XoRGo1XEpfJW5gilbqtZloNpk3SnPcSVvdMbzEUNNqlRluwcfuu+EqO PWTkSXgKCG0BujEdplYLocMcSPobL7EnxTruUWgZjXjXr1fir5awO1/n0hVheukiDcy5iPbIrVZ icXUGbU8MDijSp8t4AaGf61JT3mntHUpv4dxE6mhZCiyMasWHG+ow75wlx89rOWgA13Y2ue+C9A +rhMHtYBibDWi3AxT3Iwj25mM7v38BWRNYSQxZdenB+I/dxNvUmxdXdczY0wjvDk5bVRLo/vfAi rmuBmFOy2BfVeqJS5uPoBNhTKdD5VR3KznkYVX1UWevKW4qmzqfgdscmoSFYaOZRmXLoLWCsbCJ Kwe9RDcGoYDSjBzJNvdVRAfiEdRLRNkaOmyqvmiuYBS/k4D0QViaLaBVASuEuFXrI7e7wtKNahU 13Xse4p+ZLQCIYGsYZ7lxMVNOnWoGrE3ZHvQB0i/Mf5NQBXorm+nrvz0H3LDPD8F3mbIQdeDPg2 YHBd2Iy1BcY83dU+IcYWfWBvDcT6z8eofx80OssXcvCsGCFnL2hisciMCcFArZCiljIde+9bJ0A eIaIBsQ66w2RqdmSGFCa6RtqW4gWzJx7QciCt3VwKOluEYjaFrBl74zFA70Zq0LcudLpDk7zUCY U67JwrbPy5IcNzA== 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. Reviewed-by: Jan Kara Signed-off-by: Jeff Layton Acked-by: Chuck Lever --- fs/attr.c | 2 +- fs/locks.c | 82 ++++++++++++++++++++++++++++---------= ---- 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, 120 insertions(+), 61 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 d82c5be7aa5b..8b5958f34b61 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1583,29 +1583,63 @@ static bool leases_conflict(struct file_lock_core *= lc, struct file_lock_core *bc } =20 static bool -any_leases_conflict(struct inode *inode, struct file_lease *breaker) +ignore_dir_deleg_break(struct file_lease *fl, unsigned int flags) { - struct file_lock_context *ctx =3D inode->i_flctx; - struct file_lock_core *flc; + 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 unsigned int +break_lease_flags_to_type(unsigned int flags) +{ + if (flags & LEASE_BREAK_LEASE) + return FL_LEASE; + else if (flags & LEASE_BREAK_DELEG) + return FL_DELEG; + else if (flags & LEASE_BREAK_LAYOUT) + return FL_LAYOUT; + else + return 0; + +} + +static struct file_lease * +first_visible_lease(struct inode *inode, struct file_lease *new_fl, unsign= ed int flags) +{ + struct file_lock_context *ctx =3D locks_inode_context(inode); + struct file_lease *fl; =20 lockdep_assert_held(&ctx->flc_lock); =20 - list_for_each_entry(flc, &ctx->flc_lease, flc_list) { - if (leases_conflict(flc, &breaker->c)) - return true; + list_for_each_entry(fl, &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; + return fl; } - return false; + return NULL; } =20 + /** - * __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) { @@ -1617,13 +1651,8 @@ int __break_lease(struct inode *inode, unsigned int = flags) bool want_write =3D !(flags & LEASE_BREAK_OPEN_RDONLY); int error =3D 0; =20 - if (flags & LEASE_BREAK_LEASE) - type =3D FL_LEASE; - else if (flags & LEASE_BREAK_DELEG) - type =3D FL_DELEG; - else if (flags & LEASE_BREAK_LAYOUT) - type =3D FL_LAYOUT; - else + type =3D break_lease_flags_to_type(flags); + if (!type) return -EINVAL; =20 new_fl =3D lease_alloc(NULL, type, want_write ? F_WRLCK : F_RDLCK); @@ -1642,7 +1671,7 @@ int __break_lease(struct inode *inode, unsigned int f= lags) =20 time_out_leases(inode, &dispose); =20 - if (!any_leases_conflict(inode, new_fl)) + if (!first_visible_lease(inode, new_fl, flags)) goto out; =20 break_time =3D 0; @@ -1655,6 +1684,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 +1701,8 @@ int __break_lease(struct inode *inode, unsigned int f= lags) locks_delete_lock_ctx(&fl->c, &dispose); } =20 - if (list_empty(&ctx->flc_lease)) + fl =3D first_visible_lease(inode, new_fl, flags); + if (!fl) goto out; =20 if (flags & LEASE_BREAK_NONBLOCK) { @@ -1680,7 +1712,6 @@ int __break_lease(struct inode *inode, unsigned int f= lags) } =20 restart: - fl =3D list_first_entry(&ctx->flc_lease, struct file_lease, c.flc_list); break_time =3D fl->fl_break_time; if (break_time !=3D 0) { if (time_after(jiffies, break_time)) { @@ -1711,7 +1742,8 @@ int __break_lease(struct inode *inode, unsigned int f= lags) */ if (error =3D=3D 0) time_out_leases(inode, &dispose); - if (any_leases_conflict(inode, new_fl)) + fl =3D first_visible_lease(inode, new_fl, flags); + if (fl) goto restart; error =3D 0; } 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..9dd4e67a6f30 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_DELEG BIT(2) /* NFSv4 delegation */ +#define FL_ACCESS BIT(3) /* not trying to lock, just looking */ +#define FL_EXISTS BIT(4) /* when unlocking, test for existence */ +#define FL_LEASE BIT(5) /* file lease */ +#define FL_CLOSE BIT(6) /* unlock on close */ +#define FL_SLEEP BIT(7) /* A blocking lock */ +#define FL_DOWNGRADE_PENDING BIT(8) /* Lease is being downgraded */ +#define FL_UNLOCK_PENDING BIT(9) /* Lease is being broken */ +#define FL_OFDLCK BIT(10) /* POSIX lock "owned" by struct file */ +#define FL_LAYOUT BIT(11) /* outstanding pNFS layout */ +#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(5) // dir deleg create event +#define LEASE_BREAK_DIR_DELETE BIT(6) // dir deleg delete event +#define LEASE_BREAK_DIR_RENAME BIT(7) // 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.54.0 From nobody Tue Jun 16 06:04:57 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 0F040399013; Tue, 28 Apr 2026 07:10:34 +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=1777360234; cv=none; b=CHPA4hD+3Jnz9M7cgJqP1UKUh0MgHzMlFtDb4Aj3bmWXudeAJ0T4eyt6846fVfy69dv+zv+gkoE+v3/O4wnd12raNVMsGITKoXR1mYiP95+BjS5k+cWdy/28tarfilhNBue3WKy8nxXOpFFecgpfSENT8nn8JHYdhx9xG88NPuM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777360234; c=relaxed/simple; bh=u8nVDaJ9xrV6lyojNp3gPoVC+MwSz/nPHOAsTNCV76A=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=fnqG3yt6jFW2eUCeSiFjR+qKzlIEvFcqPIHZVDEPrj7sWE7v8gFnxnDOb/3gHPredIV7gdppRbgbgb31k6ykaxnMtsFKvYLilWSX2y8f0lIfn7YGrUdvfox+3/1sXRo/20016q6GoJY7uNbVWFnu/9Y67urFUApwDJXogiVuXJo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=W6ctUkqq; 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="W6ctUkqq" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5F7AAC2BCAF; Tue, 28 Apr 2026 07:10:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777360233; bh=u8nVDaJ9xrV6lyojNp3gPoVC+MwSz/nPHOAsTNCV76A=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=W6ctUkqqLjN9n0YFTBBoc53nQXofKEtOy/AIZNdsVUwHAmrr9V5ctXoS4lrl4JO30 Jes59W0uDn3O6+7vlRDf+8IZRYVRxZd2/phYhmBaUQXdCZXHRVFlwcovMIFYbLtDYF KzlZPHtofzhZXLMEOXsNvNj8oY7Xt1qbnw9p5iK1u7RBxFv9uXFAqWomB28cAkyF7z +h8DAPVpnv3jsSs6Kho7A4DL8Lo8ZmRt4F3Ti5+DAfUolWDAA9TTz3xFcpVtOJ5Gxe x3N8DV8Pm9aibUCvTP50Ke9TyVsDasUf6yaY51UE7UDCaY7dGQa49A+CFsYwNutQYW bMxvPwZ81G0sw== From: Jeff Layton Date: Tue, 28 Apr 2026 08:09:47 +0100 Subject: [PATCH v3 03/28] 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: <20260428-dir-deleg-v3-3-5a0780ba9def@kernel.org> References: <20260428-dir-deleg-v3-0-5a0780ba9def@kernel.org> In-Reply-To: <20260428-dir-deleg-v3-0-5a0780ba9def@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=2144; i=jlayton@kernel.org; h=from:subject:message-id; bh=u8nVDaJ9xrV6lyojNp3gPoVC+MwSz/nPHOAsTNCV76A=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp8F1NEtJpHeRoTpnLNnDoZ4d7uPPGl/+Ed/sP6 kDz9HajneKJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCafBdTQAKCRAADmhBGVaC FdXMD/wOt8JZs4fjCouGgGRfpPGSujCgzPUIUEXCp7aI7wxVFtQPEFvxj6mupxPYGFx/XmeJ1qw 8bJEq+QacZ7UiKAM8wBLzUJgnRqgmbG0LmY2WhSN4bkR28VmhBrFA/iiQUz9Dn7quoSXlhi2MNx nSbM2EjQV281hWAVo017PDumUNMCdjiWFAbmz5UMwY8xfYfu3MERDyRdMcMDwhQrbJG9s0iToPL 3+vdj4QS/7Ch14FbdLV40W00T7/dToqg1HgUO0Oc9sne+n1EfGMNE59PweqXbl+/cxsgRPV289n oytzZDe3M/1ZbWplXOO3UxqCnP6wrMt3NZ4rX4G3M4twgNH/C0djiazUPfCFnHJ0sic5pGvqyP7 jFLO4e7gSeqp+QQKTU0pfxXMBYv95NIO6KIGQRK1plL2pASCdI12sCU8Zq2mX8kxXxAdUQwfaFK iY5FnUwNL8GszByE4qI6Qod8o8obj3CfL/2Xvz8Cw3Mni8iDw6Dbl4/FbyYJAMz02rCbK4tiIuQ XxBFc5OpR1PqH4i3g66neyWOOExNzicsBzp4oeQd58RTcEvl/DN8ZmGse0kNK7FIY+X4sg/T13X 8ON7gVkzlQQpkJplRfTVthVp4bcl05JdDH7xNBQP0k20GnujYa4xPkglDJoqrrn1znE7SwsiXwJ 3+gYAwunf8WwhGw== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 ...mostly to show the LEASE_BREAK_* flags. Reviewed-by: Jan Kara Signed-off-by: Jeff Layton Acked-by: Chuck Lever --- 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 8b5958f34b61..792c3920b33a 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1651,6 +1651,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); + type =3D break_lease_flags_to_type(flags); if (!type) return -EINVAL; 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.54.0 From nobody Tue Jun 16 06:04:57 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 8834B3AC0CB; Tue, 28 Apr 2026 07:10: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=1777360238; cv=none; b=jxpy32/TyhFURK43hJvy3g1eQiOtoI1SsWMv9rFfwcIMKtxAukVGg24gK4uRc+S6PVTo5qUyGAKq+yA+Ezk/Q+n5UgN95dJkS27eFVqZo0ENIc3yaM2bdLOsVNIU6VK5Dhy6CaNgvX7aOJYroCMVLxO8kaUNg+5Bqk6mgHuuLLY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777360238; c=relaxed/simple; bh=IuBgyfioZ3xNhDmwdST2xiPVoLcfcrwzjswVVDGmPJA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=I1cPVVj0mgSdYL+eqFioo2BSJrlNXc1rtjH+a3wY2MnmIttNetcITUZ/Hisl5LEl9gY7L9GYLThBWP02EJY2daqPancd7tfHf3HSptb5W0CldfaN/ndDPiOHJPTn6B3PdBEHyQn9ZKKUMcco59WJPvoS5HA3edXjgXoIWXGYodI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=RRn6bOKR; 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="RRn6bOKR" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 52FD4C2BCB6; Tue, 28 Apr 2026 07:10:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777360238; bh=IuBgyfioZ3xNhDmwdST2xiPVoLcfcrwzjswVVDGmPJA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=RRn6bOKROAyFS3XJrswkFC6WT+xnM2NR9asW23E7H3xfwOZ7oi3+5QcL6m2RehX/0 o40xvpMyeQhYo+0zF0h7cjT7DT331+sL3i+qheQZsRTLIBqphu662u3/xp+GMy7Sx6 KP3Qs3HdHkc7LEJgzCjnwyBsR8B26EHipsT9q5RHZEl8Wsnu3li1bk8tXq8oIr3ARY gUFf1DUM1IboG2dD4UJPhQt85PY8hO/3GaIy4/3/Z2dvjPC0zkeTbKU3pPDjBSS1Ne WA88jr7b8Uz4Ag/0VyohbYSAYcfEjlulEwAx7zCmENhfnf1VAGmPoN8nAYhPz/VCsi qG16eNaKfSNZg== From: Jeff Layton Date: Tue, 28 Apr 2026 08:09:48 +0100 Subject: [PATCH v3 04/28] 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: <20260428-dir-deleg-v3-4-5a0780ba9def@kernel.org> References: <20260428-dir-deleg-v3-0-5a0780ba9def@kernel.org> In-Reply-To: <20260428-dir-deleg-v3-0-5a0780ba9def@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=2251; i=jlayton@kernel.org; h=from:subject:message-id; bh=IuBgyfioZ3xNhDmwdST2xiPVoLcfcrwzjswVVDGmPJA=; b=kA0DAAoBAA5oQRlWghUByyZiAGnwXU2hh0ZZO/L8wq2UGnaq4tqa5dMqjCV3yarG8+4DGecGW 4kCMwQAAQoAHRYhBEvA17JEcbKhhOr10wAOaEEZVoIVBQJp8F1NAAoJEAAOaEEZVoIVOWMQAJoQ vKpMcnY9DVgRhALHuwyFFoJS5Iy0uPEs52rbkCnJAcwsDnQyXZdmN+8H60CCbtt6s4IT/INW+IO UR9jhD9rNqp0LbdMqINJsQLbqi3njvjNA89/nhW8MYb3/uijynDL0J/BFyJMvr/miAjdTSKhDAU xTZ4ShQDvrJkARzrjoCNE704N9H7o/bX6twyUr9lk8pERftGEO05UoNcMHHUVkMqdSvREP6ICVQ Wgqonroe7GQsc5uhv3RsJBHHjIE7Qh3rAycnHKVMMdMWnWlCXkY6bEfBWs+EQjMypKL+eZ/Wvs/ fqb3WKiRRidL6XOtn/DOzJpvls0z1twEnNFP4mwOL9e6f2elBGUR18BQM4HqV/FCw5Gb0ffZrMw 75d6dBFHNxzypluzuxl1c+Znbt1b9+ViWaJABRBdQwmTgTMjjuFV3ypF5wPJqbwvjLBWfNtGl75 h0NG3K+d6Zot6UPvENl2bDTeyhSyrcG0aW52cBXZFv2dgNYK0B1ki4jLYIXJvm+jDVI/Iz738fl L4r8xA0BCVTdC68lGyyVhNIZZsdWH6TxUyvxEM5gIb1wr7jjo667m3L64TVzTczNotWA/8mZu5H 66bhYNKs5jpf8kGsFeBDpXB3tOZO+71DuSNXyixuWug+jmVEn2BBuzQ/ixhMPoHKCBq/ew9EGDB X7lQH 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. Reviewed-by: Jan Kara Signed-off-by: Jeff Layton Acked-by: Chuck Lever --- 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 792c3920b33a..61f64b261282 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1582,6 +1582,38 @@ static bool leases_conflict(struct file_lock_core *l= c, struct file_lock_core *bc return rc; } =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 9dd4e67a6f30..6e125902c58a 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.54.0 From nobody Tue Jun 16 06:04:57 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 C23F73A759D; Tue, 28 Apr 2026 07:10:42 +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=1777360242; cv=none; b=L7cSWbdWank0cWKKrNnSU/Vx1govEyzsGLegJzptE4meAH1ZAVg6jX9KDudGzfiSWeUGAY0HZS7w6DpPkOQYKBzI0aKCC7d9qNmucqK/awPcnJE4nqNLL1AyW0BDiP98GSAtoqA5W6bo+9LUlT4K2SXolZAjv3cterg9KJBqCmM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777360242; c=relaxed/simple; bh=De00MlFrQJ0V85UIwGjDHrcc8+0WC3lBEWRCtuTezRI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=M64KxFKyJFoB7e3MZ9mhOgMPWG5+mPatFWzDMiKYNfiA5ervwgTtQRD4y4lT7rWmR6k16HOUKT3Q/yzcff7w8ZsDVKK6/Jb75SL230ZZw+Tnxffz/pay04cBB3mhxvbMu0E62lrp+9pdxkwzpDH27lhcL1B44GLChbas1xUAk24= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=WoZRz2pj; 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="WoZRz2pj" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 98F63C2BCAF; Tue, 28 Apr 2026 07:10:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777360242; bh=De00MlFrQJ0V85UIwGjDHrcc8+0WC3lBEWRCtuTezRI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=WoZRz2pj5RUkymf4s3+GI7GYYNQCnHcZLU5rpsiwJZMV8bknzSf3s/vPQ2EE2Y4a+ ryQwZOW0B8mxfX3wn2y0yZ3wDbTNJCb/iPrji53YN2WjNg1rhL34sfhMWLpOlcAEZi Ydl+b64phXHPg7tgUGSBhC2hdCGTf22iwV9dnDJ/utSRYq5MHrNV3BkNNsBj5clG9L Tgg4ZOrQXQjekpPyh8Z0zDKJGr/61JrYvTxdgqbDmg5zdCAFmK8hzIWXAI80PmnKM+ UTp3JJPloRNe1pN8WVChUkW6Q6fqOetpemsrNxVUslq5qk0uHOMgG6FKrgY7yg/+x0 /0WF3sOYt5PZg== From: Jeff Layton Date: Tue, 28 Apr 2026 08:09:49 +0100 Subject: [PATCH v3 05/28] fsnotify: new tracepoint in fsnotify() 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: <20260428-dir-deleg-v3-5-5a0780ba9def@kernel.org> References: <20260428-dir-deleg-v3-0-5a0780ba9def@kernel.org> In-Reply-To: <20260428-dir-deleg-v3-0-5a0780ba9def@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=4199; i=jlayton@kernel.org; h=from:subject:message-id; bh=De00MlFrQJ0V85UIwGjDHrcc8+0WC3lBEWRCtuTezRI=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp8F1O0YduBPP7mTpP6tn5nuPakUzLToKY/viDw Jt1WX3IyJeJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCafBdTgAKCRAADmhBGVaC FauiD/9is1l/3fTtoK7FeP3BP2+/zW7ngsi6zeqMB9851qnAn4L5e9zh6MwtMYBtB9zk8Zdm0zV ofxCILANC7aQmy7ONdyETZMLJ0YPYSv+t3d9LS5LJb82HTPfkkKk4FLLIdQSY5zaRYmdYLAVzLb 8GliVw6tfYt8qy/5N6nEoAddKAitebm7P74JnEL7kLE8vJHLAS8iN0j0+wZXWMpDjvdng2SYqT5 vn8XNO//7ug+1lp704tU8tfF13US8EJaEbhEThhT3WZ07B4hRt3fgB3mqZr30AAEhgQP6x+6uFp kcKZvjLZ/OMdadaq+jqvghT1bTj75AUYzvqx7N7YhVJ33IUTlqYZRUzVNjnbvNOoTjZresy9ZjB Wg4Bwu0OkvXcwCPDy8/Cn4Ryj8EvZJ250Mz0KGr9vErwNlRDo9fVKjBUQ0vxK7wkp6m9u4IQC2A vR+R/qfGUgnaLurkOwFVo/R0VzXiPqOlpPenePf3aVOx6DdkAkqQLFbo5PEoEIpLmvxhupNr0D4 DNEOl7t1Tn6QFqxN19CZZBzJMK198WOXx1j/OgPUUrUt7WDBtoq6M9Gf/he8SaV/2lSmeM4hh2i QMpnQZToDeP1y8zdk517q2n9qgfFaex83pNmpPdAotuJCJIaXDamzSaPehHzG6hVJYYn+/jDKib 52zKWsz381WdDqQ== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Add a tracepoint so we can see exactly how this is being called. Reviewed-by: Jan Kara Signed-off-by: Jeff Layton Acked-by: Chuck Lever --- fs/notify/fsnotify.c | 5 ++++ include/trace/events/fsnotify.h | 51 +++++++++++++++++++++++++++++++++++++= ++++ include/trace/misc/fsnotify.h | 35 ++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+) diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index 9995de1710e5..5448738635f6 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c @@ -14,6 +14,9 @@ #include #include "fsnotify.h" =20 +#define CREATE_TRACE_POINTS +#include + /* * Clear all of the marks on an inode when it is being evicted from core */ @@ -504,6 +507,8 @@ int fsnotify(__u32 mask, const void *data, int data_typ= e, struct inode *dir, int ret =3D 0; __u32 test_mask, marks_mask =3D 0; =20 + trace_fsnotify(mask, data, data_type, dir, file_name, inode, cookie); + if (path) mnt =3D real_mount(path->mnt); =20 diff --git a/include/trace/events/fsnotify.h b/include/trace/events/fsnotif= y.h new file mode 100644 index 000000000000..341bbd57a39b --- /dev/null +++ b/include/trace/events/fsnotify.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM fsnotify + +#if !defined(_TRACE_FSNOTIFY_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_FSNOTIFY_H + +#include + +#include + +TRACE_EVENT(fsnotify, + TP_PROTO(__u32 mask, const void *data, int data_type, + struct inode *dir, const struct qstr *file_name, + struct inode *inode, u32 cookie), + + TP_ARGS(mask, data, data_type, dir, file_name, inode, cookie), + + TP_STRUCT__entry( + __field(__u32, mask) + __field(unsigned long, dir_ino) + __field(unsigned long, ino) + __field(dev_t, s_dev) + __field(int, data_type) + __field(u32, cookie) + __string(file_name, file_name ? (const char *)file_name->name : "") + ), + + TP_fast_assign( + __entry->mask =3D mask; + __entry->dir_ino =3D dir ? dir->i_ino : 0; + __entry->ino =3D inode ? inode->i_ino : 0; + __entry->s_dev =3D dir ? dir->i_sb->s_dev : + inode ? inode->i_sb->s_dev : 0; + __entry->data_type =3D data_type; + __entry->cookie =3D cookie; + __assign_str(file_name); + ), + + TP_printk("dev=3D%d:%d dir=3D%lu ino=3D%lu data_type=3D%d cookie=3D0x%x m= ask=3D0x%x %s name=3D%s", + MAJOR(__entry->s_dev), MINOR(__entry->s_dev), + __entry->dir_ino, __entry->ino, + __entry->data_type, __entry->cookie, + __entry->mask, show_fsnotify_mask(__entry->mask), + __get_str(file_name)) +); + +#endif /* _TRACE_FSNOTIFY_H */ + +/* This part must be outside protection */ +#include diff --git a/include/trace/misc/fsnotify.h b/include/trace/misc/fsnotify.h new file mode 100644 index 000000000000..a201e1bd6d8c --- /dev/null +++ b/include/trace/misc/fsnotify.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Display helpers for fsnotify events + */ + +#include + +#define show_fsnotify_mask(mask) \ + __print_flags(mask, "|", \ + { FS_ACCESS, "ACCESS" }, \ + { FS_MODIFY, "MODIFY" }, \ + { FS_ATTRIB, "ATTRIB" }, \ + { FS_CLOSE_WRITE, "CLOSE_WRITE" }, \ + { FS_CLOSE_NOWRITE, "CLOSE_NOWRITE" }, \ + { FS_OPEN, "OPEN" }, \ + { FS_MOVED_FROM, "MOVED_FROM" }, \ + { FS_MOVED_TO, "MOVED_TO" }, \ + { FS_CREATE, "CREATE" }, \ + { FS_DELETE, "DELETE" }, \ + { FS_DELETE_SELF, "DELETE_SELF" }, \ + { FS_MOVE_SELF, "MOVE_SELF" }, \ + { FS_OPEN_EXEC, "OPEN_EXEC" }, \ + { FS_UNMOUNT, "UNMOUNT" }, \ + { FS_Q_OVERFLOW, "Q_OVERFLOW" }, \ + { FS_ERROR, "ERROR" }, \ + { FS_OPEN_PERM, "OPEN_PERM" }, \ + { FS_ACCESS_PERM, "ACCESS_PERM" }, \ + { FS_OPEN_EXEC_PERM, "OPEN_EXEC_PERM" }, \ + { FS_PRE_ACCESS, "PRE_ACCESS" }, \ + { FS_MNT_ATTACH, "MNT_ATTACH" }, \ + { FS_MNT_DETACH, "MNT_DETACH" }, \ + { FS_EVENT_ON_CHILD, "EVENT_ON_CHILD" }, \ + { FS_RENAME, "RENAME" }, \ + { FS_DN_MULTISHOT, "DN_MULTISHOT" }, \ + { FS_ISDIR, "ISDIR" }) --=20 2.54.0 From nobody Tue Jun 16 06:04:57 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 56F204964F; Tue, 28 Apr 2026 07:10: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=1777360247; cv=none; b=twZufm9gFR41LAph24qziayVs+53ceR7REIZbhHApO0v1yCju38u7VpDmCEqRgTzHJaeOddZn1N0CNGh/y/zckI9upnLDBY1w27WSW/HGxGjV7tEkYAjfKdonP/Th+kELArktcZlLg69DKlg79iCzsIUxNdAUVL72HtQiGi4IJ4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777360247; c=relaxed/simple; bh=qXmxSNyMZVfebhWWPohdwpJs8hscP/x2dW7xOYsk7FI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=XRUwHNyNU+I6ZbpAJDpzHwYnO3J3O3Qq6MgKgMpC3hWThkj6wye3A2DPINcMnwYc/Qjb+0Qopya37U9tF1Ncxsi1gUTzf83635KbJnYKBkhcOIEcwMQ8QlL/p/TpFq73ap8N2W/jIELBSl5i8WcF1sS46MUt3R61niKr6aHpIhA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=FlRGaUb9; 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="FlRGaUb9" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 13F78C2BCB8; Tue, 28 Apr 2026 07:10:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777360246; bh=qXmxSNyMZVfebhWWPohdwpJs8hscP/x2dW7xOYsk7FI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=FlRGaUb92lb2xmiWM3umFl0dFOqupPz8lkhAm5O7eiW/WXl0FuPLkk+2uAdM5GkX+ rKtc/gXTNZmORhhKxnxv1Y1dBDZCULFhMOhDXwxpMdFkQuu1PotaBj9CSqB6msoo+Z crYtp7qvvFHuG/hFfhpr7zsufRRk6uNTpcs6GtuFsFPMSlsNBSqOXrhweXL8oyQM7J UBU0Zwk2KoT5kB5Y+JkhdzXIgSVJ0QtcMI5WXJm2lnXBnk8ejWH1aKMlEqcj2mSuH/ nqzo8XnhROhbikckRsFy7bImhuiukoV393s2rrY4KRKCuJ+0BQPxrPd9LS/inhsWDW sxpQeuDXBoM4g== From: Jeff Layton Date: Tue, 28 Apr 2026 08:09:50 +0100 Subject: [PATCH v3 06/28] fsnotify: 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: <20260428-dir-deleg-v3-6-5a0780ba9def@kernel.org> References: <20260428-dir-deleg-v3-0-5a0780ba9def@kernel.org> In-Reply-To: <20260428-dir-deleg-v3-0-5a0780ba9def@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=2430; i=jlayton@kernel.org; h=from:subject:message-id; bh=qXmxSNyMZVfebhWWPohdwpJs8hscP/x2dW7xOYsk7FI=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp8F1O2z/3ZM3yxpTY2Zx/Ed5wY2NxZElbjAyvK lHoenFQfFGJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCafBdTgAKCRAADmhBGVaC FXOWD/9/CS7Fqv+If3CgI4XRCQ1EEw7YtkSM8QXLufT/JKhDu+whFFgdSOcJK8E9WfcPfaDjODi AcvaDIGdoUuhSY/coSuZQ+eV/GRmq/hnOdS0Q3J35wGLcG60KpYuHttfRarHZXuMixorhK0LkAz 3+MRiZwTyEaQy6s1Q6LC5ibIJ2hR2SAwYSTdrAh/Pe0u4uvA8GdBEWdlePjNH3Bz1PH4478KNea kcFuNmUQ9Ycd/bjZPRj1b3IlZTiy4Jr3PTPNFd5vgFZCqN5EBkVsEuU8rK6DICPOBDdlYFfgel1 XbQAWcSYDqOWPGKrCsmQTKCGJprlsaQInFCglI60dYc6HtGhmAStMvtFHmTQoND3bF1mCCq6Eep pLKvlj7qs3uFBnVXDh1ciac4OKH+d3dSOUn4O80ucwlMOok7Dg56FDJvhv8bXrcXx3c85tXQ/jU JpJvxjmZ+ZCLf/uIdHvUZ1KVzHePrX1BGz1pPHX95TPdC//UI0HDM0Z/8HRXEiv7xuqytxYhtLj Jc3WiK0K6HNk6JIVxmDhnyLHjZsKhoAcFeQ3kBCibY5J/GNcntWsNQI5hyVjfHuwFUJowt1tLIL HwZJRtwgsMb+pmsQO/IwiQ8BfExIGRd7S7cpuP8ZDZtsp1nSSPKrRSl2KhSGmtSMnOPCUuZIdRB Y8WppMwwTCeWEQg== 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 Reviewed-by: Jan Kara Signed-off-by: Jeff Layton Acked-by: Chuck Lever --- 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.54.0 From nobody Tue Jun 16 06:04:57 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 B0D7E3ACA71; Tue, 28 Apr 2026 07:10:51 +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=1777360251; cv=none; b=luR/N0nm6LxW54wfMHKoWlLjBNtLlxJ5pqCqx+hpJLU1+jMBGfzyzWarKbzv3XarylGTXkbTT97aHcFhnkxcMbyvcqzPULPqRzSv7l2kzI/nYxo1VUVRyieKWW5CzXuSLfd+nOpcl5pvUkZym1Vzvf+OkrtZuouu2O8/NcoWhO8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777360251; c=relaxed/simple; bh=3PzI7mTd8rj75uxGR+x9voTdog5T+1azejMVS7FwP6A=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Gfca65q8YzyyW13o7jq3quBEOjZoDJh4RD28yQ+hlGmzsoHg3e8ypdWh770ly/9BFMZYn7TwNGn3tU0FixI6iJQwYC/WXnNy0XjGGEgSEhJ6LSSIKQPwrbyoiZVij/3VbaT6xdL7a1GupwAAxbq+t8Oop03i0+RKKeLmvylQrrA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=oGjq+Veg; 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="oGjq+Veg" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 56E0BC2BCAF; Tue, 28 Apr 2026 07:10:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777360251; bh=3PzI7mTd8rj75uxGR+x9voTdog5T+1azejMVS7FwP6A=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=oGjq+VegBGknQHPDGMTvGijlWI66uV81is7LKaiCs8GB1HrxcYmOdImlhcG18Zjci vJBkKoRZ3uSyMz+MQx4jxoyTm05rUPFJtEply3hYxketj3iTSYs7mOsGk9VmME8+BD eSjZQIMW9x6UlT8wRgV1S0gl0ibZ5yXpOy/tL8vJbKSnUhdAgNbH5GJcd6UFk0ET/i pmAi78gyZaeVNpoPXfTGLXpm2R3tUWFCKF7fnoG3Tc040JFhfzufTNHYTaewMs3aCv ABDwAsIJG2W0f6MR2c0JCC5ftRbDklO4p/7nha3qnGxg9E/Rn4NxXNf407Q9T3cDQi ehuQmyBZ/TJmQ== From: Jeff Layton Date: Tue, 28 Apr 2026 08:09:51 +0100 Subject: [PATCH v3 07/28] fsnotify: add FSNOTIFY_EVENT_RENAME data type 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: <20260428-dir-deleg-v3-7-5a0780ba9def@kernel.org> References: <20260428-dir-deleg-v3-0-5a0780ba9def@kernel.org> In-Reply-To: <20260428-dir-deleg-v3-0-5a0780ba9def@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=4564; i=jlayton@kernel.org; h=from:subject:message-id; bh=3PzI7mTd8rj75uxGR+x9voTdog5T+1azejMVS7FwP6A=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp8F1OBjICLvj4mnsu3wxqDkEDO+OK7jsyf7Xo4 Nzz3OTH/T+JAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCafBdTgAKCRAADmhBGVaC FQBCD/4nYfZdHSyP1sFd2tHosxjWHaeD53sxPCCqXStaOKXctNj5XuzjUI2ZKfzRjIcgOyyHrfz UgJNICuTiXYMWHvrMZsbgIK46ZJFyBk61psdpuwdRoxm1TDBfxAtUmdM6K7MqFtb2Zx2Z3WSthI uEhweGjN3ZHQ4BQVRpph4uGEi/7KJgKtVn7k8EN51VtUUY3nfv35s+kkGHuP07PZXxmIN8P0x1H OsTQ+kUnu9EmaSUI+w1IeJ9ZiWysofuFWTkJQyEOwU14MqbYFY/A+2IN8vXrH63dxUmlNqTAVD/ gQ7+2Zmitb4/CefxEl5Oo+sD77ytSF041NaWHN24QPjuUZdeXdK8KOMoydt3+/8i3QcdVw/3nsC BzmOHYRL/fgdLmj6uYHs05ARUEejhmSHRl59G3kk0ZorMUEEFqaVvGZ9Jk8ONXpfQaedpn7I7nf 5yxleNZ7dQYB7t1dPXPXUA6LlKPoDU+qHyX/DIdFfDRq+07k39E5UdSIDrPNejcQQ/JX+qkVTOj HPYe7ZfNHI+W/0D70q44FGf8D3/gnuD6PKecKrjAYSjDR0j95Nx5QcmtX0t6T6t7QRqF9k2Lhjq eTFn/8m3UP250DdVruS0VZpqFMopqtB/vSMVFGus8KQxLbvb4f8WeOmVdhVn095tzLNnwfUaQN5 xOjBQ/AESnSTTeg== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Add a new fsnotify_rename_data struct and FSNOTIFY_EVENT_RENAME data type that carries both the moved dentry and the inode that was overwritten by the rename (if any). Update fsnotify_data_inode(), fsnotify_data_dentry(), and fsnotify_data_sb() to handle the new type, and add a new fsnotify_data_rename_target() helper for extracting the overwritten target inode. Update fsnotify_move() to use the new data type for FS_RENAME and FS_MOVED_TO events, passing the overwritten target inode through the event data. FS_MOVED_FROM is unchanged since the source directory doesn't need overwrite information. This is done so that fsnotify consumers like nfsd can atomically observe the overwritten file when a rename replaces an existing entry, without needing a separate FS_DELETE event. Assisted-by: Claude (Anthropic Claude Code) Reviewed-by: Jan Kara Reviewed-by: Amir Goldstein Signed-off-by: Jeff Layton Acked-by: Chuck Lever --- include/linux/fsnotify.h | 8 ++++++-- include/linux/fsnotify_backend.h | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index 079c18bcdbde..bda798bc67bc 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h @@ -257,6 +257,10 @@ static inline void fsnotify_move(struct inode *old_dir= , struct inode *new_dir, __u32 new_dir_mask =3D FS_MOVED_TO; __u32 rename_mask =3D FS_RENAME; const struct qstr *new_name =3D &moved->d_name; + struct fsnotify_rename_data rd =3D { + .moved =3D moved, + .target =3D target, + }; =20 if (isdir) { old_dir_mask |=3D FS_ISDIR; @@ -265,12 +269,12 @@ static inline void fsnotify_move(struct inode *old_di= r, struct inode *new_dir, } =20 /* Event with information about both old and new parent+name */ - fsnotify_name(rename_mask, moved, FSNOTIFY_EVENT_DENTRY, + fsnotify_name(rename_mask, &rd, FSNOTIFY_EVENT_RENAME, old_dir, old_name, 0); =20 fsnotify_name(old_dir_mask, source, FSNOTIFY_EVENT_INODE, old_dir, old_name, fs_cookie); - fsnotify_name(new_dir_mask, source, FSNOTIFY_EVENT_INODE, + fsnotify_name(new_dir_mask, &rd, FSNOTIFY_EVENT_RENAME, new_dir, new_name, fs_cookie); =20 if (target) diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_back= end.h index 66e185bd1b1b..f8c8fb7f34ae 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -311,6 +311,7 @@ enum fsnotify_data_type { FSNOTIFY_EVENT_DENTRY, FSNOTIFY_EVENT_MNT, FSNOTIFY_EVENT_ERROR, + FSNOTIFY_EVENT_RENAME, }; =20 struct fs_error_report { @@ -335,6 +336,11 @@ struct fsnotify_mnt { u64 mnt_id; }; =20 +struct fsnotify_rename_data { + struct dentry *moved; /* the dentry that was renamed */ + struct inode *target; /* inode overwritten by rename, or NULL */ +}; + static inline struct inode *fsnotify_data_inode(const void *data, int data= _type) { switch (data_type) { @@ -348,6 +354,8 @@ static inline struct inode *fsnotify_data_inode(const v= oid *data, int data_type) return d_inode(file_range_path(data)->dentry); case FSNOTIFY_EVENT_ERROR: return ((struct fs_error_report *)data)->inode; + case FSNOTIFY_EVENT_RENAME: + return d_inode(((const struct fsnotify_rename_data *)data)->moved); default: return NULL; } @@ -363,6 +371,8 @@ static inline struct dentry *fsnotify_data_dentry(const= void *data, int data_typ return ((const struct path *)data)->dentry; case FSNOTIFY_EVENT_FILE_RANGE: return file_range_path(data)->dentry; + case FSNOTIFY_EVENT_RENAME: + return ((struct fsnotify_rename_data *)data)->moved; default: return NULL; } @@ -395,6 +405,8 @@ static inline struct super_block *fsnotify_data_sb(cons= t void *data, return file_range_path(data)->dentry->d_sb; case FSNOTIFY_EVENT_ERROR: return ((struct fs_error_report *) data)->sb; + case FSNOTIFY_EVENT_RENAME: + return ((const struct fsnotify_rename_data *)data)->moved->d_sb; default: return NULL; } @@ -430,6 +442,14 @@ static inline struct fs_error_report *fsnotify_data_er= ror_report( } } =20 +static inline struct inode *fsnotify_data_rename_target(const void *data, + int data_type) +{ + if (data_type =3D=3D FSNOTIFY_EVENT_RENAME) + return ((const struct fsnotify_rename_data *)data)->target; + return NULL; +} + static inline const struct file_range *fsnotify_data_file_range( const void *data, int data_type) --=20 2.54.0 From nobody Tue Jun 16 06:04:57 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 01D913B3BE0; Tue, 28 Apr 2026 07:10:56 +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=1777360256; cv=none; b=fo8jZIFU1253yoJ8yjdAK6NJB38Jmz9XaPtGewtBKcV1Lxi+UUYfGonpf2YfgPJfYCpSzwQ6iYArYx4bGoMk9sxsHQynDt62n+fZYWycAR7cqeBXrjFIR8HIKOEmuAQhL/BKcGCM8SY5ea00Wi2TKBzXfkxipKgJhWOKm3bPbZQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777360256; c=relaxed/simple; bh=OETy0KCLvLAu30Na6yWhAPISmDNi71qDpn2jPtWZjZk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=i4cXi98bADdsI9ID8fzVhtk89RuRSVyOrDZT/ZgiIpLjoCrr6oCYrVDvqWrOrTP/ynxzezom64Zt1QYK+dGOzQB/g8Nu/xmK9oEn+j8LcDfchuvWT6DW/+ghGQ1PJGbR2r6146/idwfYtj5rFbrcUx0RxyCNSFm98idTqI6/Ea8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=pzj0d7nu; 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="pzj0d7nu" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 03C75C2BCAF; Tue, 28 Apr 2026 07:10:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777360255; bh=OETy0KCLvLAu30Na6yWhAPISmDNi71qDpn2jPtWZjZk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=pzj0d7nufi0BP19V9kspVoFmAiGvCJ5Nw/jec3D60EJD1tuvpe+iCIRwINUemGRVW 4ggxJt66qKVhKWJvE7UYnf3Ad+MxusAdzzTWt19Rj4Tn63b7RPxKG3suollW61+TjA PTbSHsa18JlI3hRKypYRnPze5t0/TwGh6EaFxWB2RiOUJy1otXUkar9QL/L7+7EFrH xJQ/X20EOX2fPak/QMsum2XIMXF2rOBTsHCZs5KU4sLoyfFbojXibPSf9FOpSvXgbu rGcGqBxHUWT+5naZTzHY49PxiQ4VcOs05y0MjTZRxamQsllVHwzo/X+5bU+YSJRSzg IW+7itUrs+E5g== From: Jeff Layton Date: Tue, 28 Apr 2026 08:09:52 +0100 Subject: [PATCH v3 08/28] nfsd: check fl_lmops in nfsd_breaker_owns_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: <20260428-dir-deleg-v3-8-5a0780ba9def@kernel.org> References: <20260428-dir-deleg-v3-0-5a0780ba9def@kernel.org> In-Reply-To: <20260428-dir-deleg-v3-0-5a0780ba9def@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=1106; i=jlayton@kernel.org; h=from:subject:message-id; bh=OETy0KCLvLAu30Na6yWhAPISmDNi71qDpn2jPtWZjZk=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp8F1PjOnJmRTAu2KWJy7BzeiClqETNyhPye9PR qsCgOW9ou2JAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCafBdTwAKCRAADmhBGVaC FWI/EADQ42mwD42X4VmnV7An6Q3o7svM7liTb9iKHTXw8+xwfIvWSATZgg0aPKGKafc36d6IPKI OPuNr1TQ8Uu7PAP2+UuAf1TvpApq5StomjoGmfsjQ5u83AAnlVoEO2GqVeIvf8HouWYi5PkwbPL REdNY46vUaXbEirDqdDi+AeUVDwZiLnKGhjffGiJsjZemmQSd6hP29dhVx6mmtmXqMHyjPbTNQM vzNP0so1DCZ3zmg1UY3SDTjWA9KdMV1Gx+TNfuabM+U4fAnnn+HfdSCmQGeHvrH9zTzvKzjsbI5 rrIWrQxmuxP//L8ngO1/1N16fk7DFar3CM8oce/fuZ+v8UnODHResECgZVYjE1VAJB1KmraLADw od3sKfa2LsWz6NgjKhfT+i0DMZW2dyv6OBs2lMVThyYCzf7/EUdH9/a20v0TO4B3aP2XnQjEczc bHVXJAzNS9PXB3CZfji56R9pGM1QtZGmoQyUNu4gv3I2unESP1wBuE7bftTX5k+A42eYDDknA7U d/ngq8P6Vsht60DBfcmVrqGBBfQvK4LWgPfaZXxM3CHvioYtocS38j2Yq4ghD4YmhSMCBWpv8H+ nA2Luhyil89nJ/2CwmJ0tlZ8CaS/tP5aK4R+x7TJUAUW7UB9IeGXkjM+0L2TgcMA6AUMqADUZPu 7g79C3P5py9txww== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Any lease created by nfsd will have its fl_lmops set to nfsd_lease_mng_ops. Do a quick check for that first when testing whether the lease breaker owns the lease. Signed-off-by: Jeff Layton Acked-by: Chuck Lever --- fs/nfsd/nfs4state.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index c75d3940188c..35f5c098717e 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -91,6 +91,8 @@ static void _free_cpntf_state_locked(struct nfsd_net *nn,= struct nfs4_cpntf_stat static void nfsd4_file_hash_remove(struct nfs4_file *fi); static void deleg_reaper(struct nfsd_net *nn); =20 +static const struct lease_manager_operations nfsd_lease_mng_ops; + /* Locking: */ =20 enum nfsd4_st_mutex_lock_subclass { @@ -5655,6 +5657,10 @@ static bool nfsd_breaker_owns_lease(struct file_leas= e *fl) struct svc_rqst *rqst; struct nfs4_client *clp; =20 + /* Only nfsd leases */ + if (fl->fl_lmops !=3D &nfsd_lease_mng_ops) + return false; + rqst =3D nfsd_current_rqst(); if (!nfsd_v4client(rqst)) return false; --=20 2.54.0 From nobody Tue Jun 16 06:04:57 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 BE0E73A6F04; Tue, 28 Apr 2026 07:11:00 +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=1777360260; cv=none; b=rRjybZjdu15tqz1s0vnWHyYvi4u56vl3vyGVHmB8fz+3ugT5sFXc6COLHja10NAG47BFiwYryrgOWCTm/0vPpdk/r9FMX3WDMSZ9p53grrfrnzEZdhRluIIPP82NI8rS8wPgSPPx7USS8ipqzdW7gfH+DWDwBH/flCRaodNEr80= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777360260; c=relaxed/simple; bh=qrKyfK+uKwtrR2XB9q5BrGJKaQdTjIYKlgYMNo1jO80=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=moX6xE6J6OovojrZv0ZOqbgLmHCAJD9jPw2uXEgIn99c2NXShJIyFKE3CWC+y3dTaNL5MIdPbzGD1GkkfQKNEOjT5Ipyz1CNeai6f6Mf/OY5AJSzKq8tgVlwiQn1ZI+PxQqBHYVblSPgL5HKX5nxAgYWLZdnNlCahD2G4sLXrGU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=eHFw5rVv; 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="eHFw5rVv" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 47C8AC2BCAF; Tue, 28 Apr 2026 07:10:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777360260; bh=qrKyfK+uKwtrR2XB9q5BrGJKaQdTjIYKlgYMNo1jO80=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=eHFw5rVvLaKUuMRbiQZSPC4cNnL30mW+o+V9dWD9yidBNyMH0KjAm2xJm8pMdUSIy v9HW/nlY1fRPV+M9Cxg1zk2TnnoHZYbNsoGKjghrkOXiJpK8N76xUR9omsCnLVhEcH HQivBHJFzjvDsZ6PPpNQHUYo62dLEXpd0MqjV4tj1wtjX9XIEFq3WjVtsNeB/3/sIv OyA79fk4j3IW8duuhHtWypERwpaJ1OYD/X7r+AY7MbMlcTg7HQ+q/lKxcx4fmsGEal 1XEJB9TqI9qGtQQQJoOXbGBfuJaVg+HEzE/erWm0Q0vG+B20imJ+Gq52zAWIGtLE0e h1Vi0v2O/PNtA== From: Jeff Layton Date: Tue, 28 Apr 2026 08:09:53 +0100 Subject: [PATCH v3 09/28] 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: <20260428-dir-deleg-v3-9-5a0780ba9def@kernel.org> References: <20260428-dir-deleg-v3-0-5a0780ba9def@kernel.org> In-Reply-To: <20260428-dir-deleg-v3-0-5a0780ba9def@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=49615; i=jlayton@kernel.org; h=from:subject:message-id; bh=qrKyfK+uKwtrR2XB9q5BrGJKaQdTjIYKlgYMNo1jO80=; b=kA0DAAoBAA5oQRlWghUByyZiAGnwXU+gFMdeLZUDVHUq2X5G09e1WC247LCsWY7tQPl1IIpf6 okCMwQAAQoAHRYhBEvA17JEcbKhhOr10wAOaEEZVoIVBQJp8F1PAAoJEAAOaEEZVoIVJ0AP/Ryi Rji5UpqrRnDcghSowh5q5MmSEMFHMmTZQCHQ4XIm/UakeiskcNp0gNyTF2hrnJlRkEo+3KaNOsX 1KQxeJBhqM7d6cRAelEGr+ULMyEXkWzGpZJ6IJ5My5Q6b7wEPS6PTMCBFDu9zMeCQvFsJ5Gfwll L6eeyIzvE+iSu8qLuGz/hdtH/1ql8LLDGVC/eHAmuGJOlUbZWqkBcOkH341hy+UsUxxRhSdukoM nhiy5m/0wrcBS482aLkh9hnPVxh7sKLj+GsUbhvQDV4TeMI1wvhEIUlHFLJ0o+e4siKHOoIfw6a nNz16zpHcMBrfK6GJMuCHc3Gexzz7nvM78N+vf+x+Ea/jITws+EtCGKGNqur3BcAHMPu5ONKvVB h8h8uy4wYtnL2J2kgcoz0Eu8+28sq3J8vLWAYc01BxE1Y0dG+FQ3pcdGFGNs39K0Blnt3Eozw79 Gosz9mDbg5Vys1k75CmP92BXWxrNKmLcggP+TbYXbu1Mbvr5IMYzNNVJNXgWXDF0S5rChh+bK8b 1Q9aUy3fXkbOlntTQZDdmMWzNiXYn24irF017jVT09SLzPvY7q097nfiJ1DAwVC1VwUE5ylmCAO U9uEjedD5DNPXn57E31j+KUYZGIFADWm7XIt7T6CWJiTlyRtL3XhMGt/MIu0UA7dJvu4RMxsGcP /fedd 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. Note that regenerating these files caused conflicts with the definitions of NFS4_VERIFIER_SIZE and NFS4_FHSIZE in include/uapi/linux/nfs4.h. These constants are defined by the RFC, and are not part of the kernel API. They have been removed. Userspace consumers who require those constants should plan to get them from more authoritative sources. Signed-off-by: Jeff Layton Acked-by: Chuck Lever --- 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.54.0 From nobody Tue Jun 16 06:04:57 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 0BE7C3ACA7E; Tue, 28 Apr 2026 07:11:05 +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=1777360265; cv=none; b=S8QGMWGNpnye0yz8fxo6p39hXjRJNq8zCO3GZJzD23RFShW4ParRwedquvfV4mQKWyqPRITzSt/1pE0jRE33BqzFOJwQQIB+/TWJHjTSD6kRTpSptjcAWo9shJXetW6BvHOYq44d6LERjKvRCbS2qOWS2jYD6XS6ZuGV5KMN4oU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777360265; c=relaxed/simple; bh=YLh4/lMM1FLFsNW282HugdeM6AzL2tOPs8cUBDQeTEU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=VLeZd7+MaT76+rhnKNgorCsm+Bw9QkUOx7ZgDUGX4Fa+RlUuws5CQtFkb3mXqhQR9KgPdgzALzC9i3XGhOnPMxru9XngMvhSrgEwH+Qdpv13wYbxC789ddRSawIE8h5P8bdkTDLDpMTLMMr3CMbtHfUCs/8zIZOIUA9Fb53h5kU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Tcoti56b; 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="Tcoti56b" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0FBFCC2BCAF; Tue, 28 Apr 2026 07:11:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777360264; bh=YLh4/lMM1FLFsNW282HugdeM6AzL2tOPs8cUBDQeTEU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Tcoti56bBWZmvicGkzZrEGbBbIynPeV6FfpDvScI3XsKlROvyhSJBStYfkgdvPmRF w1FgzYjyVThtsa/yfZ/55gdY75OQT0MPgA1VpebdoGtyfICk5vuiNu0kuDczgjna3z 2dMYS92DkC0AN0mb2lRcXlDVnQNjoL4sQcUv0g6VIQdZlx+wXh/V15u/nMnn7smA69 6KY3GK21z2MM8xp5n/CkmKxOu/CpTHx/VupR0qVlqaD70uyrpsW7LS6erqtyY91XOH uu1yJEk0DWOC1LDDAV5uQBbYXgHSQUQwssjeiSZrFzt/cxLLoRWU4Kvm+SHX5qdRHV YnpaMH0xaSgVQ== From: Jeff Layton Date: Tue, 28 Apr 2026 08:09:54 +0100 Subject: [PATCH v3 10/28] 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: <20260428-dir-deleg-v3-10-5a0780ba9def@kernel.org> References: <20260428-dir-deleg-v3-0-5a0780ba9def@kernel.org> In-Reply-To: <20260428-dir-deleg-v3-0-5a0780ba9def@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=YLh4/lMM1FLFsNW282HugdeM6AzL2tOPs8cUBDQeTEU=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp8F1PRd4MDEoR7OOpY9j30Z/lhTCRqA2Yj7Cvn 9C3UIomc0uJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCafBdTwAKCRAADmhBGVaC FeSdD/4tHOEGCjPZ4xMEmdBQrp0V61egjEk5TaI6DFieRv5/lEmGa38pbtsArkRop0E5dezUrpk PPE5iYHo9Qt9OCr7azpKWkj0WkV2nZJ/HrdZypHEWYHukoteWIoKgVyjO+ZRQMyedISHunAR4/a sPQmY24cYAFUMqILImLyUvOIAOfPww+UaeoSaII9cmWHmh+nHRUPE7euXvaiUuXqOdBzAa0Kda+ 6kS9/QvXqF2xV475aMfu9O4D0zL8zvhQt6ysZcz9gMgXhqI/ali4clZ2I3lRhBPvUEAvLFhuNal AmJT9fQ9nWCZ12zfz9t8+ZR1UKpsndQy7Yn87c+7vqa74NgPeNkHh/G4e4Yq29naKjwU94t6PwS 5TYmzgkdhaOdJt/hBWkvxZQP/gRAiSNp/4vH332VscG3xVYyo5pXqgTJnnf+RWEpKMCibdGXfId U88rsoE0eM+EzcWOt8Vw9OTwTeZ5gPbSAseXex5qxhVxRnxMQYjSzNHTZAHsIqgTfK13Oix3BFc JQ7hee/+Umfxs4+VHnw0nY1wQ1LUreyBZYTGsM0AkU1mQSeowQuJviRSjlZbK+NCl9EMkT4dc9m ITMgNGIDKkx/n8Mw8ZZ2cNx//ehTcLyR5/lHkoNHT2zPaPw1DwqnrG/VELx/5/kIzrfYMCeSV1+ wACEBGCLOgdAuxA== 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 Acked-by: Chuck Lever --- 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.54.0 From nobody Tue Jun 16 06:04:57 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 272E93A7850; Tue, 28 Apr 2026 07:11:09 +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=1777360270; cv=none; b=TsuirW8OdgmlEIazWU/cPBTdcaHRRZYZeiQSUEO7+5tJVmy7Nm0axDvLjnYlm8L8fEQ2/2MH8y2TFYdUU1hq8hZwC3yGhY/S4+haVvAZ7P/sRlzkDEFBS8p+kSIV1vXYwaD+gO8sUCL9cpAC10eCutswxAb7wMZLNyvj+nTEIx4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777360270; c=relaxed/simple; bh=hhXLhx74Eemi9+cBWHx+kd/7BxQpq2o8mwtjMeiErng=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=pEZsLQVepBrvg773HEzX5loO/W9HnupLPWI2+U1ife1ZKAOHnOm9yufVxocrAe7+JVCwI3FExHlwu0J5Tvpqv0W7PTAQXSo7iPWEi3VZeG5yODKEWJtYTxQ8Usa3n/CIVT8A9s1blxLDX0Wn/uBFYlm+i8pc4tjuTvE7COSA7n0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=U5AQohbc; 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="U5AQohbc" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 52305C2BCAF; Tue, 28 Apr 2026 07:11:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777360269; bh=hhXLhx74Eemi9+cBWHx+kd/7BxQpq2o8mwtjMeiErng=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=U5AQohbc5OVi4kFa24dGk4eamYXx0PykAOLwhPrRooTw6yUsatyoLfLbLPZ3A2fqc ohiILhEm1MoPVbKYfGyEOVbjEai2+I4uM4XESYfrD1bFn6kZQ3A9RBLF6mfnkogDd5 fERdP1JiKhOQ0LrA2+e8ieAKYi0zpzPnhLfuZRd7skpx/oRlg1jFA6xlqZeqJvtlNT dND55JF7i4wmKnglTyJWOVx6NkWUwCUlOQeTp3MxMnWCKsah7EcZ14KWaZ11Qnjsde sqecg5w+nooVGguMXTD3XcVsZuBea2wHKqdZw094fva/pnCIm81Hud5GBZPMFwfrzx OCmyIpZbCbYVw== From: Jeff Layton Date: Tue, 28 Apr 2026 08:09:55 +0100 Subject: [PATCH v3 11/28] 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: <20260428-dir-deleg-v3-11-5a0780ba9def@kernel.org> References: <20260428-dir-deleg-v3-0-5a0780ba9def@kernel.org> In-Reply-To: <20260428-dir-deleg-v3-0-5a0780ba9def@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=hhXLhx74Eemi9+cBWHx+kd/7BxQpq2o8mwtjMeiErng=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp8F1QKEaBY8vzQl/lOHR9yCybiOtoU6fRMZfkf hHrneLC0yOJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCafBdUAAKCRAADmhBGVaC Ffg8EACiFtRZ4MNzqg91nvdlpqOXh5L2kFziSZJf0xxHadqU5wRw4V7bx8zNBTEKVGHc89uA/3q XW8vkdkEekKlkgdVrjPCRDG1UQoIiRIe/KaGtr0Mj04gRW5CZZKUYHxIr/WCp2/lOqhRMdcuZfj IGBUq+zskJ8bqTuwBFxnO9k8GumHeDJv7BqJiHwynBZwnIamp5VAST4BliOUUaOgF4nqrAw5snG nTBiZDkfnd0Hymd5aAuOk5W8jhd90FW1qUzDO/BuILTbS5pkc6lXqr5nRRCLxU6cosAM4jscuLt 5fzrE+7mUo/uG9fQgD5foOpPk6Dq5KSOgRG8F5CmR5oqs+Zw10FpQNdCo3SKFCQRDBLcqDLfSt3 jAi0l/bP9UOs6tvAnXPKlxNAfmyWJUJZ9fVg2SgV1DPl1UFEc9e2OafWy2gcUzRYKpoXPj++6pc BzSnNHU30hndoUsZ8fQO8h9zBeZdvzseK6rAtfrzNxFgTHiwZkq8UWeAiU9OJ39J8S0IEIru5qw vFCYGvPGjxQhf0s4VjYgdlOnBmSb+9XK8SpfpPWMKKCWJBYq0KIWkjvN32ODQp0XxsdZeHFlBBj 8kBceHf5E7r+cixtDVBZ2y/1CVA97e/sHGwA0NUUd6ZgLoJESU4S0bFQ4AM8iV8jgoyYijc82HQ UsYNqlp6BwiWv+Q== 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 Acked-by: Chuck Lever --- 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 35f5c098717e..bd7e4f9cdaa5 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -6040,7 +6040,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 @@ -6048,7 +6063,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; @@ -6265,7 +6280,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 @@ -9634,12 +9649,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.54.0 From nobody Tue Jun 16 06:04:57 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 1363240DFB9; Tue, 28 Apr 2026 07:11: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=1777360275; cv=none; b=hgWy8/mvlsCumzpA+ERS3Nsq/U7vDZa35HSF1Bt2nRrYZjcBy+V3SNKPknqvZD0DwmNzu018X93csONG95Wp+N8eiFPSAPb9sfvLxgnE5E5nVv3czuwDPqsj/DaElGx54LiZyi0dmFWcl+w94zUkGgGtglITg+zMZyb2ig00/vs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777360275; c=relaxed/simple; bh=xIXwEMi++lz7TkwN1XPOxxuo4FKTtSHQdly2xOtVsVI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=aqHyQCOBxdEmSnb8UpHcDhCk1wYByU4lxHtaBEbDHMD1Hx/tACKeOnPZAemZWKmT/afF81SDJLX35ML2vfjT91i10DwGb8HI/J5Q4RzLrOr9tskiZELYX2xs5PjCdcX3Vnp4f8/kZBcNJNsyUWzNyWW2M1/dyl1xmDYNKXf7U4c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=VZugNVWe; 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="VZugNVWe" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3CB85C2BCB5; Tue, 28 Apr 2026 07:11:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777360274; bh=xIXwEMi++lz7TkwN1XPOxxuo4FKTtSHQdly2xOtVsVI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=VZugNVWesUquaZbfC6vm4Si3UGLNC/v8MpK0qws/6JN+FAmjy4v2+TosvtzzXFk/+ 2O7nDI4AohxZZMubE3jyYwfvLtMG08SUyfhuL3IS239fXKPGol8FfJrjKYQhFuWi2L NGtEiBR/U9E1+Up+ufmsW83kY+YWvcS7lFIC6cSzEWZJlWBbJduPY5mGsO4ITiDwWu XYcqC/nipTDUD1ePLpGYnSGxpbCUHU0C+D3eeppSxhNf/zBVNhzWPSe4MzGsuq61N1 u8N7J6zVZ2jtdcurmiZRgOrWUJc8x1aVtkwBg7a3qBFMncqH48w8/uJ35YCCfwXrl3 wcKMDeJdzcrtA== From: Jeff Layton Date: Tue, 28 Apr 2026 08:09:56 +0100 Subject: [PATCH v3 12/28] 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: <20260428-dir-deleg-v3-12-5a0780ba9def@kernel.org> References: <20260428-dir-deleg-v3-0-5a0780ba9def@kernel.org> In-Reply-To: <20260428-dir-deleg-v3-0-5a0780ba9def@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=2096; i=jlayton@kernel.org; h=from:subject:message-id; bh=xIXwEMi++lz7TkwN1XPOxxuo4FKTtSHQdly2xOtVsVI=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp8F1Q87hysKm+0KpbORTQfRKw9X777HkSZyhtb /6bt9ED2sCJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCafBdUAAKCRAADmhBGVaC FaLVD/9L4NyC+g0ctsdDO9vZ2JEcHbWol1EYUo8qlqP61kcRufIkGsurOBSg6xvo8gKCc3HgISP F6YiltD28Z1+Ofw+Rx6QVe9BjBwT/02WLkDmsPGVLW7RT4/3IhBsO5KaPM5uw2MezVvcKdECSLg mZ5qtVHGenJ/5KUFcgWSynlofj21Maj+zSPndhPHqKmBK744j/VTkM0StgULJf3bE1Ef2w5/uKp O1w/jBInRYMoAnT6NUu/K688omVPXJypwmkpJdHNVCPdwOszi4vM56vpfp+BCl4hAXfo7BcBaLA 5iMvkYrERjOcUU85a1/wgC0LvTEPOowfEFdlzGiCtycEW7Rk0LKeS74o0VMaiA83LcgVT/0zoT8 GIRwAsRfI6iu1dJru4QW/vB5R7PFC7CVLYwrZ4fQbuCcDnPXGNH0feIfFhzXnPmWCsNQiS4ejgG y0c0f/gj08qJ7Nc1hvbodWc2kCCYv+j1GWzqv9XTv3Yc31IT1NKiR4v4yuN4/9BBDWDIGuxcv5w /TG0Au/VQf2bShSZf/ieFG12WykbJwqcSy/oDtw05fGlo4aqnZpYNor3z1e7MPN5O62muh+sXJg AaPfrigQn9U9WMnos1+k7WCvGo+MC92wIC+ThJW3r3eKgAsxl+AqtydY2cyGhpdoK1VElzkQLDg EbfiSH6L/3Mw2YQ== 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. Reviewed-by: Jan Kara Signed-off-by: Jeff Layton Acked-by: Chuck Lever --- fs/nfsd/nfs4state.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index bd7e4f9cdaa5..6adce94e9fdb 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -1260,6 +1260,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 | FS_MOVED_TO; + else + clear |=3D FS_CREATE | FS_MOVED_TO; + + if (lease_mask & FL_IGN_DIR_DELETE) + set |=3D FS_DELETE | FS_MOVED_FROM; + else + clear |=3D FS_DELETE | FS_MOVED_FROM; + + 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; @@ -1269,6 +1300,7 @@ static void nfs4_unlock_deleg_lease(struct nfs4_deleg= ation *dp) =20 nfsd4_finalize_deleg_timestamps(dp, nf->nf_file); kernel_setlease(nf->nf_file, F_UNLCK, NULL, (void **)&dp); + nfsd_fsnotify_recalc_mask(nf); put_deleg_file(fp); } =20 @@ -9674,6 +9706,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.54.0 From nobody Tue Jun 16 06:04:57 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 8DE2640DFB9; Tue, 28 Apr 2026 07:11:20 +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=1777360280; cv=none; b=Sz+NeQ8uRSsEHTl6LMTG9A9XFjOf3MPixF8iHGEs9nBLIvaJ7ABFuZmWzxWQ9ljxJqA6cWYR84z4gqIguW8tT5CSKeswydXdnKpJ7et8yazHYA+M9VHUjm5ECOUYWQb+/kNtcMS4qdFMgLOJB7h25Q67Q6djHTarwX+npMQm41A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777360280; c=relaxed/simple; bh=0uUgOvb+bJdqhTljagvaPA1ej0spqCQxXkWTbTCynIs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=m5cUqjutXZhC2fb0gVvZNtZBHyWY91HOfIcX/na1I+ZGbttIF2Bf0510xKy8/OgpGF8Wpu77b2dWO2+1b8cJeBs/6so0NwlNy+JHJOnbhOIGm61UojoK2IEN2iG9k0xkePVbEc0Ap7lTkSJLw7oIHZfpjgGNjOBImpvPougONkk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=aSd7pD8F; 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="aSd7pD8F" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5A9FBC2BCAF; Tue, 28 Apr 2026 07:11:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777360280; bh=0uUgOvb+bJdqhTljagvaPA1ej0spqCQxXkWTbTCynIs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=aSd7pD8FpHbD1tjdHK8UEgIYcZXCesp8o33dgFx5MTwv9ljWSSQv9Dzs9nB1mervB aUQFj7jcekKH5ms4SRkkNXsoviBTPZrAz4bA+WoT8zEUjliCwnIMVOOYXrSbqfu1u7 N8/bvGdoGe1f7Xvz+P2II7KCFttf+FYijaufcZhcM/OXUY9/JmWnjwZJokfqnj1809 +YTOYPeJODYJUny+KM6lbx60R+xP/qmEaRHubn5HtbSa8ob3Xx1deedXbaUmmlDkyN o72r8At4nDNzAnk04h3RoQiSEm2VY7V861zvzOksujthFohPSU3IfoeJgeUbrfsAtH +P6hq7Nb+WeYg== From: Jeff Layton Date: Tue, 28 Apr 2026 08:09:57 +0100 Subject: [PATCH v3 13/28] 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: <20260428-dir-deleg-v3-13-5a0780ba9def@kernel.org> References: <20260428-dir-deleg-v3-0-5a0780ba9def@kernel.org> In-Reply-To: <20260428-dir-deleg-v3-0-5a0780ba9def@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=0uUgOvb+bJdqhTljagvaPA1ej0spqCQxXkWTbTCynIs=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp8F1QURinUO0OXQPDGJz6sv0kbqMjkacIXRj6X 6IG+jAH3L6JAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCafBdUAAKCRAADmhBGVaC Fci2EADCiUufbmqcxg6WQ+qAbSIn8769kVV1iugk5mJUlNOMWlDHGkqBPbp1yQBZdGdJCC39LKz sw44ghuPn+ZsFU/QEUHs5oG+2KH5YAkFtlnS0qoeaDDk1U7gMyB7enkP5pMObrUOVoE9luqVD3b DY1neM1+QNWWAGcpXjr0qR/28wReYfu9SxUUJWiWSyvJPDVeZnamPRWwK7zw+UjG1MelM/7waSK P7pDHFY6if0mL3tHkXmXCzUKYhFoEMMGzxmbDcclgh/FOAd9/9UuzNQZqTu4WSRV7LUx+aofxbk /qpkMAvZYV89/V4WgQITda1hXtFNLNb33LXk+05gHO8nCaxncqWiTOvHm7b7WdeJi4hoPPJrn5R rW6BmN42k7E1fV+6MyoXYPVqsL/b0yxk3R0Wqi9am1DAl/gxWAOdJwewXF2oVIATjs3RjpZUNxL tC1lJQtpZ+CTdaUlebDSs8153mRtv9l4jL05wccQFVCNXCVbBCX9K9FCIMbP4gz99wDuS3/5045 PAz3+YRssYluxUJvQRfkBpFph4jNx15NrscoujWUMT2jIEnxMo9u5V3+kAbEeQkOupulVaxg6sv tWGRahSzCxS4jj6nmtXU/nLeSzDm2KNc4emkJxEDi7AsUVsaNhSltECbcTfFuRugMO0+QSj+/W/ q26wtZA4fTXu2ng== 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 Acked-by: Chuck Lever --- 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 6adce94e9fdb..c0046fc3c1b1 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -357,12 +357,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 @@ -5553,7 +5554,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, @@ -5574,6 +5575,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.54.0 From nobody Tue Jun 16 06:04:57 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 2AF7937C0F9; Tue, 28 Apr 2026 07:11:25 +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=1777360285; cv=none; b=JIWAdghBXozbRt49dsu8nQnXVZgtnOA6/HM9NPAZUvnuJ7UPS/DcJ/zag0nCWGDLIEX84FMl1IFrFwH0kO8W9wyPKiDc8lHjLrMFIv/HcGkRPp2wENtH9bMhBid5lfyJF6WzmfJqJ/0HtaBxx5MM2tmD3YK9LzXKco5Q2FfydCI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777360285; c=relaxed/simple; bh=JuG7V9GbPIeU/cBXF9lHXlK4ypwH1KxMIHluIcLHRy0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=hDUwo69pmppV7PKJbtdr8se+z/E6FZC3NtzyIXs0VXzhSwMizgC6GweIIqtDTnU5lfFP0R6ptKUz4Ju4leeYhbkIqeG1WfkW2LDxOHRNPCnrZzCzz6Fp3OC43oYpxtybvGsDf3Vuj4N4eae+FkdCLXydbi0NHKeelNAexsRUq5U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=VoewHr58; 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="VoewHr58" Received: by smtp.kernel.org (Postfix) with ESMTPSA id AB5B0C2BCB5; Tue, 28 Apr 2026 07:11:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777360285; bh=JuG7V9GbPIeU/cBXF9lHXlK4ypwH1KxMIHluIcLHRy0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=VoewHr58F6jBW9TvePOujkgeMHhN7BEn9EqL1F8C6vxHwRQTM7wDLBTAb1+OPjG/+ eVwAKGKQbEM/myCPcO94ZwkbYUiDI/pHlvRx8yxZBljUOP4dwGzTX+JUv/y69KRrKe Qt0bE361H4hESGPPBVvMiNLKu4EVxiZaQwnJuMBHLeZNhxrlPYmWWhdn5xajbKYuCb A2JI4cdmMBpu5GLYK5y6UtNlSvzhO2wEHPVRC9RDchNSdvo2W9khjwGmzy0y1fxYzF bWWzHOUhEBfilroCNcnMqqXYg2ljeMcn42wflN7fT8LmaGHH/jPbQKInDSjGWlyrpy 4yxOaqrS/J5bQ== From: Jeff Layton Date: Tue, 28 Apr 2026 08:09:58 +0100 Subject: [PATCH v3 14/28] 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: <20260428-dir-deleg-v3-14-5a0780ba9def@kernel.org> References: <20260428-dir-deleg-v3-0-5a0780ba9def@kernel.org> In-Reply-To: <20260428-dir-deleg-v3-0-5a0780ba9def@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=JuG7V9GbPIeU/cBXF9lHXlK4ypwH1KxMIHluIcLHRy0=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp8F1QeyO98gmMMoZSXAH8ts1PnSzWxrk61RwVN BxZPXZSwrWJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCafBdUAAKCRAADmhBGVaC Fat0EACdSZzKf+AaRG9SBOfesrWPTTAcfuS8fCdJFHXKKWZQdZhCvN8uAhDfyJty/Rz9vjJ0mf2 iRpqgB2c3G/LXLZ9UKgShqhr1cECj5PGHk7+J16tvenKtjzovmGvQGY40aGSUNfGEIIVxctLJ9c /SRKFkJ/Crv1+RIsCl5BA7vzJrxCVcUafLRogBi4dC8UMKoaWGCOxm4PxTb4aTe9rhlgJ4JWz2k z5nbnk1sXavEJG6Z7Fq/Se5s7Vw2OKctZBgqT74yooi+QBFv0TU6Prmrvrmgvp3vA+2R9A8+yy8 aRXt/otRlfEoHey5ARzs1ld919Nl5ywY2yhxJyJaonTZt9lZd6qyNtE+f5t9tgAd/zDvsNNTlWz UoC/ymrfviHVgX9riLJe9b5QUpUzPi82ywJ2e/xXT+rpNlo/VvrNcltocr4eIvKFoagkEZcjGry htUXCGTvlxhaAuyuwwIeuM/fgIcw7mcZq3Xib688gKT9tDcA9nP7VVGRIzOH79AtD3KKLNAbG3W bUO5gRfz02T0JP6D0JmTDxWPPgsqC5AUsCHZZ9W8IoEIDV5IjrE3shNWdoU5NOLYPhLSFLO1z7x jlthsEWDRPAQd3QcTlC2az+CMXE3J8xHSgdea9m/vb24/rl/dG/bLeTbaSmuWlnDP6pe+YBRw8K UFoKyh4lHsEY9Xg== 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 Acked-by: Chuck Lever --- 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.54.0 From nobody Tue Jun 16 06:04:57 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 2FE7A3A6B6D; Tue, 28 Apr 2026 07:11:30 +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=1777360290; cv=none; b=DLBmltVl+piFyyhVce8ih7qHHwNgKl9ihgBxBZ/v4QzOy1glpOAQQtliJY9/OHJzwOJk3Kr0PpP/HqpE4B1sJIBilPyh9PnyrcfkHeynA80rbUjYfcSkn7NIu5KKPth2kA2dRzpW8ctzH6HJPBKYmoXtqT1E6W1gtvnpVWcn+xM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777360290; c=relaxed/simple; bh=No/DWtPORXDhdI5WkPJdJmmnosV5Q4Pg2jWF0WLDzwk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=eQLktZV17Deo4FNQVn8hcC03+8enrdJUNTrn4vu8VwHSh6mwKn3shCrT1SvzWzjf6bXMSb7gy2LkicWaSi0fd/5nij4nkgqBvWGHSN4Hnq72Vml+377WyMnaONaLIGstxWd4kL3ThcNCqVJcygUShQFweMOXUrnrrEc+PjB+StM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=qdGo5Sw7; 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="qdGo5Sw7" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7BAD6C2BCB6; Tue, 28 Apr 2026 07:11:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777360290; bh=No/DWtPORXDhdI5WkPJdJmmnosV5Q4Pg2jWF0WLDzwk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=qdGo5Sw7tq0oP9sGFUJBBijSzY2hjEUuakFBW5VISGUA98dKLbWP1OmybdX6kT667 AmgsqMRZJwSdtJJsbLQzjLKRKok1s1R3pFVlrxl8U3DB07D0WB1o9Aqt7HNsZ8W47y OGEJk8bpg6S3elIY+/N+vpURVAPuYFeCQb+kOBCy9WvFIXyfVVlkpkZ9XloIyNGKUZ L1LQJTSX4Sw7JS4FKdgEKNkuENp+6y9iGpdYS2M/NXNmByyaRUN1Z+jfqbP3KrgE0e dfxiJ6SCoFhm5h4BSiaFMcm2m51u2kbylvp7glBgxm0c4js+1DIQvRc3/0EDanaAeS kqkjc35em7Awg== From: Jeff Layton Date: Tue, 28 Apr 2026 08:09:59 +0100 Subject: [PATCH v3 15/28] 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: <20260428-dir-deleg-v3-15-5a0780ba9def@kernel.org> References: <20260428-dir-deleg-v3-0-5a0780ba9def@kernel.org> In-Reply-To: <20260428-dir-deleg-v3-0-5a0780ba9def@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=7844; i=jlayton@kernel.org; h=from:subject:message-id; bh=No/DWtPORXDhdI5WkPJdJmmnosV5Q4Pg2jWF0WLDzwk=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp8F1RkF5WuHxwNVWZJ1MbpLK7jRjb79uOfX/1c khRktj08LeJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCafBdUQAKCRAADmhBGVaC FRn2D/9PFoBnQm1Qv/iECOPjs28AVeclsIDYZRg+40SW2liKczSE3ZhQQN1R4h4KguXp06E6rxt NCSUZbNjlvpMLbyWqez6vlfZd6HItIYxEzmB1RuxWPTiwtf8NhtkPMpKEjuCzo0lRFoy9z27F+t K5W1bGHZpsgqztw9fqmVtx+TNy+IzFLo2i/EBDiilSBueRf9ZDJtHqYhQI50qDt5pAwGE17jXJ8 I2RbZqZl0XE5Bbe9O1CAEyMJXFlVnfxLVxxt/zu3ZSSh9c/v2j+v0anHKarj7KiVHRok0A4qMBl nrnMd1jWS19BX9Wsums14fRGXUXMR8i+vf6swReXEQ0OvlmuXnhJadl303tQdufKqkfRmXV4H4S 6DNELXxXgYwOU0XJzVTHFEXxAMpooIhQvW8z15Kxo22ay0DRRvxKaAGHT+7elCzz7Ezp/4BSLY4 y9YTUOFoJ44MarZjTlhFse/mp2lFKvHr5o7Vl6Hm6/koyYHbCdXw7tTEEuHbOcbQDVOJuXfHtTL V/ndW2qruP2WvjQPkC2js59Aoea/9g/8UjzXhfx7TqW4ekU5azS7Ke7wU5BNQO7OUAbch1gU4vN 6aVcR8ctK+R9Apx2R4cwln/nhT+k9xYVDQjy2mDea0OFcIaJz5Havut4nznZZsKCZSMPrPjjM8y 6ad6ruZAytsnMqA== 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. Assisted-by: Claude (Anthropic Claude Code) Signed-off-by: Jeff Layton Acked-by: Chuck Lever --- 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 c0046fc3c1b1..ef04e26b4f30 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -1212,7 +1212,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); @@ -1295,7 +1297,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 @@ -3167,7 +3169,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); @@ -4949,7 +4952,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; @@ -6101,7 +6104,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 @@ -6109,7 +6112,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 @@ -6186,7 +6189,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; @@ -6292,8 +6295,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; @@ -6318,7 +6322,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); @@ -6339,7 +6343,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 @@ -6360,7 +6364,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); @@ -6517,8 +6522,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); @@ -9660,8 +9666,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; @@ -9713,7 +9720,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.54.0 From nobody Tue Jun 16 06:04:57 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 659A33AC0F5; Tue, 28 Apr 2026 07:11:35 +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=1777360295; cv=none; b=e9k0PrSH3kSlVQIkBGStAX/vtfr35smJt9kjyKvrueaVeDnQ31tJ9jCH1EMG4TwM5gT91GChNOnM7fl+Fz3BlmrSe2MPKxtkTCyvLIZAPPbrqFmqgHpxHYZw6AzXGnhv7FOo/yUHHHBL+0bRokiM3+2t02c87ttFm5GHvPE4+9g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777360295; c=relaxed/simple; bh=m0C86TpkBBOMpDqujAm0G8449uKEm5DvGHdnM6gWWOs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=NyclQRZ2W9dvUcftNNDxlvylrbsP5T0OXKBasZNhpG2OwxUXxGIcVvDntcXh1Llh2y1PedVubi+H6IRpskAoh1yLOvWRvN5uXOOak7/9oz5jHH4TGV2jAUAaVGBIc6migdldTw0rRvy+DheCLjr5WjrlEQBSPrMidXhTtrQib5o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=rKNnP3rB; 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="rKNnP3rB" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 77AFCC2BCB5; Tue, 28 Apr 2026 07:11:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777360295; bh=m0C86TpkBBOMpDqujAm0G8449uKEm5DvGHdnM6gWWOs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=rKNnP3rBBkZRbHKVYz1QShJS+4IfX/xbRAtJX606Y/F8Op5EgkuDl/8K6FAnNqoed HyIN0kJCvh0zyIeA066XL17gwIRErH/gvXUPUztNBrmi5FVjiRBe0JWgJK2xMdaHXK Q77Cjcl010Qfn05RsOBMK74QQ6LcLgwpccZJf8boPdzgJTay4vKMIav9GxoVHXgRaS 6XgneybIcpvtEqtVeB0wk9SlQ1cHdroVjzuLWoSD0Chfmbpznsz1mgtFyORA9hsvpV gettPxb7HX3iATfyyf9o7N5jU/gQnzaEpRSLEJfZdaacbdvKKO9jxzjgvG7jIAXZAY Tu3d+56nvBCXw== From: Jeff Layton Date: Tue, 28 Apr 2026 08:10:00 +0100 Subject: [PATCH v3 16/28] 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: <20260428-dir-deleg-v3-16-5a0780ba9def@kernel.org> References: <20260428-dir-deleg-v3-0-5a0780ba9def@kernel.org> In-Reply-To: <20260428-dir-deleg-v3-0-5a0780ba9def@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=9059; i=jlayton@kernel.org; h=from:subject:message-id; bh=m0C86TpkBBOMpDqujAm0G8449uKEm5DvGHdnM6gWWOs=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp8F1RMYAci5ZIV6oRW5Ay2xGMRCDNdvkn//yeQ M9kJbcEPSiJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCafBdUQAKCRAADmhBGVaC FeVYEACMKrHkGsynkjtiUZ+K8GNgT+r5R9YjasRWmYEXSaBr/GSOgaL00MXC8q7Wm+Nxq64IhMD yQYWagSyFuCrh7HrxSknKtWgX57SmrHRfLDuwt8owWESOC/N17jxYL9YkMCqtXgMfhsGhaQYDQF OP9Vrv09bTOydDZL2f2XdT7aZIVROkl2vkKWkQqC3BU5hnZCb4L+MFDPIqr0p2Z/a/5brUgjk5n EtOIk22stqO4l8G/s5+ryOpOdt9DCksuvA5WW/dzC87xKvxvamlLcAPQFifS9VWCCyN56lI8nAN 9sgZ2YCMwumY5frXivI9D2rMKZke84aSO4sEhUnDJ0pz5WtFDRIOIAd71yWNz7L2OIdJJGFFoR5 WVl3LNmHmQeg7uDbneYJKCj46hE15xfM22CcrQWz153RIBAXBovJ9Dua6bd3lYMLtHRvxFm5zuS AcQhiYwHSeIg+K7NF+J+W2SYvYtT8SWpwdmkeZh9w0lGorn7Mi22pBPTXVLntvv7DAu4/E90Ib+ qNne3MV87HISSsCJ14TaRPNvMPWMrsMI3DuNLW/0wQA0mB1HhqFazZfLkXsIBOn/AoINM191Npg pTbCZyOodAptZmKb1tS5H488LiU451dp9pCSjv1CcIUpjz1Ai5APcmb5zarXgShfgk7i6/ji+H+ WbwgV9oBLJPIhtg== 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 Acked-by: Chuck Lever --- fs/nfsd/nfs4state.c | 118 +++++++++++++++++++++++++++++++++++++++++++++---= ---- fs/nfsd/state.h | 46 +++++++++++++++++++- 2 files changed, 148 insertions(+), 16 deletions(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index ef04e26b4f30..1c87fd8386a6 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -126,6 +126,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 @@ -1123,29 +1124,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); @@ -1155,19 +1158,76 @@ 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]); + kfree(ncn->ncn_nf); + release_pages(ncn->ncn_pages, NOTIFY4_PAGE_ARRAY_SIZE); + 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) { + release_pages(ncn->ncn_pages, npages); + nfs4_free_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_put_stid(&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) { @@ -3389,6 +3449,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, @@ -3401,6 +3485,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 @@ -9683,7 +9773,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.54.0 From nobody Tue Jun 16 06:04:57 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 56C783CD8C9; Tue, 28 Apr 2026 07:11: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=1777360300; cv=none; b=JcctMy2CPoAs5ujhZL9zILq7ywvXnbv1eXH8QZIDSsY4SGtKutApp6YEQpim3s6l61Pla0CK3xXqz2svZLaqmpYVGVhYwbv71mmxE9DMRRI/bCHynQCV+VS699elmh4Zjqv6txnlnBtE0N/RXBb07cbOtqc3pQX2u/l8Tb2Exq0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777360300; c=relaxed/simple; bh=DN8fnAH1IdEsgPO/3bC9kTypvO8PRmcxTJpFJ7cI7N0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=WazGyPuZa2Qs51+5v0z9dkAaLh6clbHJAByiYRcUWGBixkbg1rr4bhZVf1mFn5ZhmZOmPDyXAWTik2dDWSfyBuC1kWRBzu0B+1+UVDhJ9U76SBMrdH2SGwkpECxfAvLZpd7OQKDFSgxC5SPCicDqNTrk7lAa1v0yLgPfybXArhM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=e88ybbak; 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="e88ybbak" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6B616C2BCAF; Tue, 28 Apr 2026 07:11:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777360299; bh=DN8fnAH1IdEsgPO/3bC9kTypvO8PRmcxTJpFJ7cI7N0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=e88ybbakhePkYxOpNz1yWwyqXZnaRzwM5PG+vrHoD9VtLAzoX2zfXc1qcF3UM6H3D +eGGcEa+lSBV3U//3puAYltYGjRE2ot0OHiwHWPA27qOKWJ/1aK7EDLkXmX3uB2U6s 7+K3+IJUrPMDVF7auLiF+V2wYxposkYvOKEyF0TUOAkrvo6aKuXCrvFDf3h86GI/m1 orLDE60/uQTd5MggOMuoRB5hEPkooNVYIajNfRP/zxYEaYcKIE0tKhbSyn9qfpN+VS QJwoenWBN1McTOy0LnciA8xDKSALC3PmtW8BMmjHh9QPcvfkoKdcX90AcVIyaRrM3L 188HClvE2ztHQ== From: Jeff Layton Date: Tue, 28 Apr 2026 08:10:01 +0100 Subject: [PATCH v3 17/28] 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: <20260428-dir-deleg-v3-17-5a0780ba9def@kernel.org> References: <20260428-dir-deleg-v3-0-5a0780ba9def@kernel.org> In-Reply-To: <20260428-dir-deleg-v3-0-5a0780ba9def@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=23165; i=jlayton@kernel.org; h=from:subject:message-id; bh=DN8fnAH1IdEsgPO/3bC9kTypvO8PRmcxTJpFJ7cI7N0=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp8F1R2dhVwkRPFFwzcO5UrJxmt6YtrE/BCTEgN MzfC/tnOIKJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCafBdUQAKCRAADmhBGVaC FQBYD/wMon2OrUepFNTVNJSoZc/OkBNJulfnkpTz6ePM7AAJHatd/iSogMsOUOuRaNMkzvEB4hh gDRIXeAtprY8hsfo24j8Hvh/QdZ0yhvG89GXKL0xpTpH88eE6YCse3yUf01ttH5d1bZYlFTwSig kdtS5ZR2KYVGmvbE6nJ11ogDZWZ7kX4oTvBqngExeiDUi3n8Z9PVWu4Mp11LwDhM3CCaRShD69X t0F0zUwHgUwnQ3xV3St2LF0XpYN22f0hUo2HFdU5DzNVNr9uEGXL0rqL/wvpTxqctbHBAbmw4q0 yK5QEny54Vccy5sIEqLQavq0Nww4db450i6VbXU+5N1NKWG0hLRpc1oIufSBYGONCEddRQ5Z0HQ MR9VjNvymKjK+zIe/6M9fKCUqIjOfvqvQAlZvvtSAvxe8BwmDyQ1tf6/0VUKrowZlN2GJ3Bau67 TE5y2aoHeAgo3tf0kF9qHUwZtiGqzAQ1wRbEXOXKP3iFmKFbe9wYAZPDRehvAu4CagSrXyBzjWd rYZHXpe1JSjV+eoJgIF8Z9kHCEcbwRryBUMfJoZs39wY+cja4SBnZ5plHo8OzOhugnbPR1y7PdG Y3ucnlfH7s97FRJlLAFNK4m4gDR53sLIuA66COdLzir0DaEofzEH5MquCx+W0vgMgGNsW/SYRm1 Vl3J1K05BbAPzEA== 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 Acked-by: Chuck Lever --- fs/nfsd/filecache.c | 70 ++++++++++--- fs/nfsd/nfs4callback.c | 19 +++- fs/nfsd/nfs4state.c | 268 +++++++++++++++++++++++++++++++++++++++++++++= ---- fs/nfsd/nfs4xdr.c | 121 ++++++++++++++++++++++ fs/nfsd/state.h | 4 + fs/nfsd/xdr4.h | 3 + 6 files changed, 443 insertions(+), 42 deletions(-) diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c index 24511c3208db..be8f6d8a3ba0 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,36 @@ nfsd_file_fsnotify_handle_event(struct fsnotify_mark = *mark, u32 mask, return 0; } =20 +#ifdef CONFIG_NFSD_V4 +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); +} +#else +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 0; +} +#endif =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 +896,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 +905,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: @@ -1019,6 +1057,8 @@ nfsd_file_cache_shutdown(void) rcu_barrier(); fsnotify_put_group(nfsd_file_fsnotify_group); nfsd_file_fsnotify_group =3D NULL; + fsnotify_put_group(nfsd_dir_fsnotify_group); + nfsd_dir_fsnotify_group =3D NULL; kmem_cache_destroy(nfsd_file_slab); nfsd_file_slab =3D NULL; fsnotify_wait_marks_destroyed(); @@ -1223,10 +1263,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 1c87fd8386a6..2b711443281e 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 @@ -3449,19 +3450,131 @@ 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("Could 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; } } =20 +static void nfsd4_run_cb_notify(struct nfsd4_cb_notify *ncn); + static void nfsd4_cb_notify_release(struct nfsd4_callback *cb) { @@ -3470,6 +3583,9 @@ nfsd4_cb_notify_release(struct nfsd4_callback *cb) struct nfs4_delegation *dp =3D container_of(ncn, struct nfs4_delegation, dl_cb_notify); =20 + /* Drain events that arrived while this callback was in flight */ + if (ncn->ncn_evt_cnt > 0) + nfsd4_run_cb_notify(ncn); nfs4_put_stid(&dp->dl_stid); } =20 @@ -3486,6 +3602,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, @@ -5718,27 +5835,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) @@ -9819,3 +9915,133 @@ 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 inode *target) +{ + 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); + ne->ne_target =3D target; + if (ne->ne_target) + ihold(ne->ne_target); + return ne; +} + +static bool +should_notify_deleg(u32 mask, struct file_lease *fl) +{ + /* Don't notify the client generating the event */ + if (nfsd_breaker_owns_lease(fl)) + 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 inode *target =3D fsnotify_data_rename_target(data, data_type); + struct file_lock_context *ctx; + struct file_lock_core *flc; + struct nfsd_notify_event *evt; + + /* Normalize cross-dir rename events to create/delete */ + if (mask & FS_MOVED_FROM) { + mask &=3D ~FS_MOVED_FROM; + mask |=3D FS_DELETE; + } + if (mask & FS_MOVED_TO) { + mask &=3D ~FS_MOVED_TO; + mask |=3D FS_CREATE; + } + + /* 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, target); + 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..8af1e15e1102 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -4098,6 +4098,127 @@ 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 + * @nf: nfsd_file on which 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 { }; + struct notify_remove4 old =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; + + /* If a file was overwritten, report it in nad_old_entry */ + if (nne->ne_target) { + if (!nfsd4_setup_notify_entry4(&old.nrm_old_entry, xdr, + NULL, dp, nf, + nne->ne_name, nne->ne_namelen)) + goto out_err; + na.nad_old_entry.count =3D 1; + na.nad_old_entry.element =3D &old; + } + + 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 notify_remove4 old =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 a file was overwritten, report it in nad_old_entry */ + if (ret && nne->ne_target) { + ret =3D nfsd4_setup_notify_entry4(&old.nrm_old_entry, xdr, + NULL, dp, nf, + (char *)n.name.name, n.name.len); + if (ret) { + nr.nrn_new_entry.nad_old_entry.count =3D 1; + nr.nrn_new_entry.nad_old_entry.element =3D &old; + } + } + + 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..570d66fc8297 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -201,6 +201,7 @@ 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 + struct inode *ne_target; // inode overwritten by rename, or NULL u32 ne_namelen; // length of ne_name char ne_name[]; // name of dentry being changed }; @@ -214,6 +215,7 @@ static inline struct nfsd_notify_event *nfsd_notify_eve= nt_get(struct nfsd_notify static inline void nfsd_notify_event_put(struct nfsd_notify_event *ne) { if (refcount_dec_and_test(&ne->ne_ref)) { + iput(ne->ne_target); dput(ne->ne_dentry); kfree(ne); } @@ -897,6 +899,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.54.0 From nobody Tue Jun 16 06:04:58 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 D1AC43AC0F5; Tue, 28 Apr 2026 07:11:44 +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=1777360304; cv=none; b=McPsfo6v5XCAoU+g1ulQGbb5vGKOlkQozn7xfF+/urniVM4UUZF43S09vdSwczitmgF8migYZAqhOYcUXin920AEkIm6CT9rbWjDUMu5Qclos249O6n/P0Cep3ALgB6MWs+8L3nAkUuzhxIqZTjXz7zdGuaRxRUa9l1it+OP8wk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777360304; c=relaxed/simple; bh=PbrSbsGDzBILK48DxjomAYyp/zp1sNlXie6EEkLW5gU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=hkFttJzkZjB6OJc21LujDWP3RD7U9xJEyCwypgh8OTDZiqXcj3LOSQX//PolBNrm3//ty8hzM3s6Lk4UJtcqeBw2mXm2qXeQ3TSWFMHWCHzD7YV0Eb/IYew6BEDGSjd01Pw9/rvLYhIyf0h4JUou5HAL7YpFM+/2innb0dIcyS0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=mCDdEYmo; 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="mCDdEYmo" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 98D8CC2BCB6; Tue, 28 Apr 2026 07:11:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777360304; bh=PbrSbsGDzBILK48DxjomAYyp/zp1sNlXie6EEkLW5gU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=mCDdEYmoh3j+8ogRcEtMqVt8hNrZniK/TyhuRdKAK7ravoJFjYAygJGz1n3CENdX/ nRf1uN+ZoskjAqTnJLCIusUWkgzi2ik+EJsV3CGVu3JsHaHdYFacuSONjBDxYmRCrJ X2KaqjT24CvKgrKoGtWhPcof699A6ORdm/50dJW2INyfUW80FmWZou/aPY+Fv6oU/6 bvlrlMiawCc9Pwr72fCN+92vGaYLkhZzv+EQw24fVK++p+ZNwYMdyzz8ytMDT7vrEx uWm7xYTDNAoeay5TT0dov8uAFFYoT9illb4KYwUQNmwscdjQgIAIIztb/XU6y+w041 jNdVR96Mtmt3w== From: Jeff Layton Date: Tue, 28 Apr 2026 08:10:02 +0100 Subject: [PATCH v3 18/28] 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: <20260428-dir-deleg-v3-18-5a0780ba9def@kernel.org> References: <20260428-dir-deleg-v3-0-5a0780ba9def@kernel.org> In-Reply-To: <20260428-dir-deleg-v3-0-5a0780ba9def@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=1983; i=jlayton@kernel.org; h=from:subject:message-id; bh=PbrSbsGDzBILK48DxjomAYyp/zp1sNlXie6EEkLW5gU=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp8F1S5lm/Zy5ablNM/wbgAJGSpljpuzYaUsAcq 6aob0spJIyJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCafBdUgAKCRAADmhBGVaC FXlvEADIjxo5rAg9wcEBnJtkn3ArC/GIL9FcB3U46u0IFp6PY79oIeNGUqGYDb0P26Tn/j0UQwz FCdVEdKMdC9OULR47Kw0F91nAwdG2c1QNKoFkZItnHSIk9VJUowvn+5IH1X/U5TPvfGEV2arBQF kY0gudx/2Co4y80RlkRY+TesSbUfiphdCKfTPzG+cpdG+VuYGE4m7DyKqeOy3GSGVb8b/feb6WU CjDLya8YhRKcEMuI2l9w4ADaSBZB1xsN/x86KL/dUGaYKy+E5X1HPCow0vbqFErJXGuiFNSPati 8N4n+D/Dz08YF3gcAT7sAX/Ket+P3S1iOzj6coPqljA3bO4xuKJcVJopyNsZOQBCyZnLhjeSMwk rme3Xd0DgS+7WaHARvxG7XadRqwA5aIoig39jeEqN1qXb7EgcqYOMNtHpWG3kseF1ITQcBc+HFX bZPXYgwe6LGnxdV+nW2B7DWSHzYqh2zhHTfusq6V/xOsP9+PamuV9uf3DcKkggEgQYVS62DCGvf gshEoaKbb2yqdKq+ddALaXVu/5EoXTCtTMAm4fk8wjF1cXTNw01OZOR5fOzysqZeVhsSpKqwB6/ veSigUVmoPbaP0ibxK7HGVmO1UUSJ/i7bEfJXyryV7GUAF7FUE4RdymslBPo6pPi3PuooN7lEZg H80mDR+knBlOk8A== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Add some extra visibility around the fsnotify handlers. Reviewed-by: Steven Rostedt (Google) Signed-off-by: Jeff Layton Acked-by: Chuck Lever --- fs/nfsd/nfs4state.c | 2 ++ fs/nfsd/trace.h | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 2b711443281e..f00aba95753c 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -9996,6 +9996,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_handle_dir_event(mask, dir, name); + /* Normalize cross-dir rename events to create/delete */ if (mask & FS_MOVED_FROM) { mask &=3D ~FS_MOVED_FROM; diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h index 60cacf64181c..b9119ff4253a 100644 --- a/fs/nfsd/trace.h +++ b/fs/nfsd/trace.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include =20 @@ -1377,6 +1378,27 @@ TRACE_EVENT(nfsd_file_fsnotify_handle_event, __entry->nlink, __entry->mode, __entry->mask) ); =20 +TRACE_EVENT(nfsd_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=3D%s name=3D%s", + MAJOR(__entry->s_dev), MINOR(__entry->s_dev), + __entry->i_ino, show_fsnotify_mask(__entry->mask), + __get_str(name)) +); + DECLARE_EVENT_CLASS(nfsd_file_gc_class, TP_PROTO( const struct nfsd_file *nf --=20 2.54.0 From nobody Tue Jun 16 06:04:58 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 5FA2A3B5319; Tue, 28 Apr 2026 07:11:49 +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=1777360309; cv=none; b=qlMaQz5zEwS4PKMzsu8yPTdiDR3mo/IeIxq38j6V0EAjtP5T2kGoEl+xO/tW9sQ3qr1/ZCPvBKhlTK7+lXqEnCzRZ+L9CiffHpG1m99dknCFSm3Cm5uUs6R1Mo5yfrh96fK/H99ah2gQLIsRHoftlKK31cn4ekGh8h7HaVW8P6Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777360309; c=relaxed/simple; bh=vT13omJ88avBYGucyN258JCiiQFLmujH3myXqMMliO0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=gHgwYeA79c5PvZW2EcefrbxsUXewuv9jfU+Occc2Bt6wo5n7ZPc0PmccrA9KTadWd194EEUKReAf36vrEA0+EnZiXI5h2qEDIEadt3o5xBO9NYscIUv9nY0Hv80lM27KVr1Ga9BAQ+h0Nd+QNJgxTOTXMQOCKdjkujvYDnQgmYg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=cjzij2ku; 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="cjzij2ku" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E35FBC2BCB8; Tue, 28 Apr 2026 07:11:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777360309; bh=vT13omJ88avBYGucyN258JCiiQFLmujH3myXqMMliO0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=cjzij2kuogfQieZ/URzMNhfb9lTkuFmwzsJraWgfgBHa+9sHXzIA39T0lPILwpfRi 54fQpweaLs0GaH4rzrJhl1Gr5Yc0WmGAoGBUkzAoocS6E0RpIjeMSKY0yidRtKQUa0 gSpLFslEeku2+0/7tVmEcsdHYnuhIC7AEmIBOt3muu0HGXMP07DNV0h+y6Mi+QkqY9 oW/yTX2cDxeBKu/akRMd+NG+YcfwHLGmgfo3M00idpdYJ7f9A9UTLJJb2mdeFeboFh HhclalfSdgfg4XEfv2fIz4qLY05J6+Z9zIRbTAAU/3X/0reGkmSR+DmAD5L3/evHpS B41l1UxoAmdqA== From: Jeff Layton Date: Tue, 28 Apr 2026 08:10:03 +0100 Subject: [PATCH v3 19/28] 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: <20260428-dir-deleg-v3-19-5a0780ba9def@kernel.org> References: <20260428-dir-deleg-v3-0-5a0780ba9def@kernel.org> In-Reply-To: <20260428-dir-deleg-v3-0-5a0780ba9def@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=vT13omJ88avBYGucyN258JCiiQFLmujH3myXqMMliO0=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp8F1SGqE91Drbd+PXxtfVoL+xhtx7kUAjoI4LW Uakszs2KeSJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCafBdUgAKCRAADmhBGVaC FT9cD/9vvluBBLEbvU4l9jTWxcvM1HNJqSJCL3xHE4kNhyPSJ0B5fkGi6fYUsrgA2VqfoKc9o3k V9hTW24/FcjDogCqQ7CJcOzU2fWpcfdsQe1HJJiZP4R5ZbLElUTybTHk69xyI6HUPC0N+1sIo/H zuvNvBpxGVATKnkzWi4P4fuPGyAgeN1OGXO7vKZiWflt+YW5mIr49LTur3UA4+WPwFdgTGfHGdR +0RsLP7yQDondpLwogZKv2eE2UxZ8oKONGVyit1i/EYhdFr6jUJP+QrEvFRWxAVhhfco2lnSBuU qcquT2oGc7nd4+GSXRnE7Diy5ydYuXjRSqKi+YTL0TpotWo0P9FEUzJISvzSB08yRRpqb5H8Hje YfjnGpDxj3/ZkpX/7XWN7VhDewC6iPVAFbOwLZ3E2owgcR+YlW70vOxClLPzPKmFVfZqyr4QyL7 bhtSnpgKipdPDqc+KJ0gOzDxvNejxlTTfYteefmf0VTB5KsoreDiQhVDWDTEdM5mPmcantc4T3m /I4Xs1R9yROhK0No+6h295BzrhuPX2YR//PEwrlbKU3qxmFRWVyC6rD38hDzcUGrlXN14fMkauX RLP8aX9cyAfxMOtno6kvexkb/WYoJrbM9Ji1Omw9hSmq1b88P2+mfzVzJtlgYAW50vze/XPEGVJ OSxhPKeBS1b9lSw== 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 Acked-by: Chuck Lever --- 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.54.0 From nobody Tue Jun 16 06:04:58 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 A946C3A759D; Tue, 28 Apr 2026 07:11:53 +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=1777360313; cv=none; b=QIvHuHNZQYtQpJI0tFzgANGXTsn7GwKnkXfqBKGCC8n6DcC4mg8dbTjrCiWHQ9mUJihamlXMsn3y0klXwGQ8OeqbngRqQWD3S0UN2ZvkAfwi1AwJ00JcRprGlXICbPettCmwD6r3EYblEr5enRGtczXmitNr8LgOiyyTZIPg+OA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777360313; c=relaxed/simple; bh=8oOOjvuXTFk3ATyKMsiMxYSTQ7+G0noB6pHdXQXznvk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=DcR0BH4wSqD4eDc8ysTTI1XwcRxaQiy6p9BobaKcQjDt2HlR2j8DUVqZJD4s+7tK5n60W4OH6ysEQJtv5BuMR2QSNNOfofL9ze2BitIH8ScbxwNiRX0RC2aEruttZHfXfddiNXSvYg4ligVqp+5GvHmTCSs7MkGFEbOWQ3qVxvI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ACmTlh6L; 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="ACmTlh6L" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 72010C2BCAF; Tue, 28 Apr 2026 07:11:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777360313; bh=8oOOjvuXTFk3ATyKMsiMxYSTQ7+G0noB6pHdXQXznvk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=ACmTlh6LiLGKo3z+ywpGZindiSdLrbZHQ5U+MFmyBqVS+SyMskjY1wtRB0bTNy0Z2 Nei4+G39+LV13Im+1gDGQQIIbct0U3inXdWEznL8R9mC7d55x7HD/HXOdKf0zAIWKL 36H+XzNNMymCrWgAoJYoj4sNIPNPVHBTJGiz3IkDU/ho0ApfYk0tT5+mVBHZN8KPQK hGhP/pNPeJMrh0GiTWrR67grbO/XUZDwCDx8rXSSeA2ZFTT5bo8Xjini0xV9Pe8D96 3l4GXNfHNBDXJxS8blEa1ALp6UXtKUWv9nztCrmP6qvmUVpvg5Lx1EHzdQQ7+//VxC F4+BUEtvzckhw== From: Jeff Layton Date: Tue, 28 Apr 2026 08:10:04 +0100 Subject: [PATCH v3 20/28] 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: <20260428-dir-deleg-v3-20-5a0780ba9def@kernel.org> References: <20260428-dir-deleg-v3-0-5a0780ba9def@kernel.org> In-Reply-To: <20260428-dir-deleg-v3-0-5a0780ba9def@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=3351; i=jlayton@kernel.org; h=from:subject:message-id; bh=8oOOjvuXTFk3ATyKMsiMxYSTQ7+G0noB6pHdXQXznvk=; b=kA0DAAoBAA5oQRlWghUByyZiAGnwXVKgScw5x6+7fcbzZcpsZfBYCAcEcgu/2uBP01kua2DSy IkCMwQAAQoAHRYhBEvA17JEcbKhhOr10wAOaEEZVoIVBQJp8F1SAAoJEAAOaEEZVoIVskoP/3tI A5TcqOHQdXGPBa81Saa/JhMZO4Iks7tr7jNaRAn/aQa/2z00gzdMhVQj3ZqpqQA/OtUBfCJp+F6 sYYhLDucC1S7eB6jEJeqegyaCHfJZmOIVkQxULke0J1a21keE39wqTJ2NzXFmm69Owq/PTNXMBc JQblX3GtImewTU079TARgmJZrcG1Ezz1VjVpQBgbA3N6wR7MI8kGxBWvDjj2mXcFebUq/dhoGyH MjLAxtiLQOAH0Tfl+iFE7gnUs4OeSHLhQyP2EdXZN1OZh5xW5VeOWT/auVGzT1hGqJaVUstBZ8l JS6p+V7qWEKEDaEeiXgEBVc9i0H+zulUvYTN9J3SNy/FsKyTxWkPU0r+o0lhf0zJVaQlHdxOzA4 fOR6XDzpIOZLFSFba2f6ohkycZJOcSnDuba/I+f7MrEsLAdee4m4bsczqACthHyS9opnhYGaVj+ t2EVeJR+8kD1AZryw/twsLjPZArRDZ06mSbTduhBazGygeh6hTp7K+eGCcTRMTBzAH8A51+x3xC 654gQsNXu7RbI1IHEqH9v9Ma7GoVjZLoPlYS2nMYEWGz/ofB01BxHyYKGel4WnAqHTdgnXfmHTa FF1Q1lFyMOmUB7189J6MVBp5mtTjUeh0CbcZ0fJRJKdU+MuUa4i7qkclVezWQdBfAcuYN2lY5Gs pTneN 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 Acked-by: Chuck Lever --- fs/nfsd/nfs4xdr.c | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 8af1e15e1102..b9b173ec7421 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; =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.54.0 From nobody Tue Jun 16 06:04:58 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 BBCB63AE183; Tue, 28 Apr 2026 07:11:58 +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=1777360318; cv=none; b=Fk5LrdOOzrZf4op8LixsxFo+APwaTm0w4qDBvl3ttXlq9mxJwmNzxM/WuGkBOjZ34Ty/8oZDBrw3Td7jFW//WCwhF58N+OqBYZyFoJPFESt6fwz/sfEdYYpBJfj7lj7Amng97n4UUeArBi0RA06qe+7AmYKxhoSVwvBNAgShNkI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777360318; c=relaxed/simple; bh=EZs5JSXgff2XMAUBaSSNR38ZRXCvpIIGiMGLXDvobow=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=T1pe+hkyr45cOkwiMpCVfuzoQ/7n1AMxhi5/vVPPse+okRryWoqGEiiaslbeGXBysR7u9cqr34VVyLCiZRSE0BQ0ygYXXxts+bod5aEZY+8rCDWh9a2SSn54w49xaUY3IfvZtom0demfRO1p39D+TKdBziQragA10cohNSKlaDQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=raxXBAJ/; 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="raxXBAJ/" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BC5BBC2BCB5; Tue, 28 Apr 2026 07:11:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777360318; bh=EZs5JSXgff2XMAUBaSSNR38ZRXCvpIIGiMGLXDvobow=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=raxXBAJ//miBst9b3cEXgjBEO2SsR1s/k5tJvxS91j4Co5bUTnhyvMcWDIUhtOxLI WfAmIizEeLCmR6tWx9ml0Aou1GI6RxLYjGuaDlQunG0evBwWO/9lfzh1a0jyCo3lpS 4r9Zz2hVom9Fua3fZyuI8oHBPcvJaPoC6aSIU4kC17erRM4KMkBK2mkmDZafYV7pDK qmylg131SNQQWA9voMxTrezyfcqT4DdcQI+ZyOvOZF/B5OuZNf05e3YYqIgGLZG3F+ 8bVSNrDri0+4iEEzxvQY/twUA447vhXhj45GqvG1qE/WCHmadOnIcEs2YSzf2eY5Cb 9bEEWk8ISpcBg== From: Jeff Layton Date: Tue, 28 Apr 2026 08:10:05 +0100 Subject: [PATCH v3 21/28] 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: <20260428-dir-deleg-v3-21-5a0780ba9def@kernel.org> References: <20260428-dir-deleg-v3-0-5a0780ba9def@kernel.org> In-Reply-To: <20260428-dir-deleg-v3-0-5a0780ba9def@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=EZs5JSXgff2XMAUBaSSNR38ZRXCvpIIGiMGLXDvobow=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp8F1TOUYP/lYvkXxIvVYP4JJwhZpoS1cK43W91 dYl+CbtxmCJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCafBdUwAKCRAADmhBGVaC FYOMEACUsZ1TyUGr1mFVXjxhL9qwr+E/eroeJ4vO2eTXHhgjqT38V0c01s7FK60t0Bn9LC7TBDC OiQ4ms7BelDvDsWrFi5o1z3F1FSd4kusrWqfIo61jxdxyjTDspOqoYd0iM3Z8EITb8j1P8b7Kll XZwITbWESI8CXp53CKHSplWP331NB6KnBPyrL5z2iKOPZ9mg/CJPDc8QNlieJ6Fs/zNbA2Grp0T xQnsiBtV7BEwbL5HYNV1/CCzLwnmRqL7uPGU87qR8JtIgnNWAKnmZ0bZGuKFYGV7PjplqK6SQBY 6CbxwzKXP+N8Uf9UtiPUm5xVnjJIwaB0Oq2VDq68GYA8Y+tHVJG71N8QekPMfvtIx1W375jIqWG 1fa9/aVQE3Qje7jLp32NhMedUuG2pMcALZqajIHcCIhbYsVMf0ic/9d2RQYpBHoD9NNzkptRh4Q l3cmQvKp7K96Qrj+hTLZgwDHScGk+RcV6d/Kl0calUYGBq1g2PQYvpDFVxJ/yWoD27pRNIj1pu7 bWN9IHsMjoAFMjBiJD54aLOeHSf09biE/5M7D4TATdHrkLKrmsUAQbwS1oUntFu0hXeyf8PcC4f 8DsCP8SdZn7R85tJajT1wM3YCmw7CSa+hirXVY5EtAEaKWRHAq1+/0D65hTuuaK3SFKLHd2Ob/U 3AwOvfzVqpQ1kzA== 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 Acked-by: Chuck Lever --- 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 b9b173ec7421..91681aea9d7f 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.54.0 From nobody Tue Jun 16 06:04:58 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 A0AED3A9612; Tue, 28 Apr 2026 07:12:03 +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=1777360323; cv=none; b=bAppd4G3nwVOAN7eYbvGH9GxuvtrXyQmjq7XkUo86tGbdXwkFgcMGZ8/PU6D/Tc76HFOpVgLUGBJUeL5ApPadF8UUnHHoQZM+IdEjkSLQPj0HO4LPmtpc7xYc6Nlzp1lJKZXa+so05gjs6SA3ePr2UU870XpUV12m6RV6V1xaic= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777360323; c=relaxed/simple; bh=3FB93IfyOh/XE3d3Bb9HPR6+nkrsaX/3QYQn7eFefzU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=lVJcXKlESBBiKzFtXOhvYx8fKGaD378dkHRpi0o6a9J7zkPIMryq/S40clKnIm7voUz25ji+7JthcLbSP5ptdXFhJv17O2UIEX89FHLWcj7UER+Uo55BvAFgo1xSNsAuvP2Xjo8lKhiVzbENC6r1P1Mc+8A+r13DRO+oSsy03ow= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=UXD8wTtK; 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="UXD8wTtK" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D912EC2BCAF; Tue, 28 Apr 2026 07:11:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777360323; bh=3FB93IfyOh/XE3d3Bb9HPR6+nkrsaX/3QYQn7eFefzU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=UXD8wTtKr6IlfOZ88wydQxraUHy4vxK2LsbAWZAOqYruyA0GlOgaysVRNUnNUL+IL IXOpbk2aBf4O4kCo0JW6GFmOvpbD068yz6agUpJEHhaYzBuel3PjWAGP9frhGY/cIE VLogA0AOV7MMaQ8XYZ8uJn/61iszZhP9u0n4o0PjTtncDAJXAnsPPEJElp/BiNTBcC MsXbpu72l+NVVHiYuW3rXAlxMvLbBDSUOzQGihsK/m3kmo124rDU+yeN/lN5v6ZfmJ CNFHO8NC8UA4UAz1uNAIhGzrpq5CDJ1hIl0Q+ahQxA6E188PazptjG/WiOZt3W6AU+ /4/T30TMXWzeg== From: Jeff Layton Date: Tue, 28 Apr 2026 08:10:06 +0100 Subject: [PATCH v3 22/28] 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: <20260428-dir-deleg-v3-22-5a0780ba9def@kernel.org> References: <20260428-dir-deleg-v3-0-5a0780ba9def@kernel.org> In-Reply-To: <20260428-dir-deleg-v3-0-5a0780ba9def@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=3FB93IfyOh/XE3d3Bb9HPR6+nkrsaX/3QYQn7eFefzU=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp8F1TZbwHyKhDWNk4Gph/m2VKJAVfOhUE5NMuR 6ggIlQUdsqJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCafBdUwAKCRAADmhBGVaC FTDqD/9LNQ6bKTtQtkhypVOOgNI5y1tUJvodpYtO/3grikpp/CTAOiDOk+/VxI0N5/z67+o9oFq cK54/MOlN9OIuJffvRJyIqkDAiFqGuYPm57cffzondhwUbBzMvtjhffeXULO6xE7LnZ23SzavMf 1ut7wDCl1KMQmpoRRMbK/0GCZ+fTmIwUeQGV9QY1jjTdpXO+eBmUPG+L/1yijQyUFBYqipfGNnR 4HXWkHJnPQuLkVu2gpEX50wDGMzWuEnhDU+dM4QnsO/eQ60lPa+g/Aznr8gVrsvenYL4IOiov04 WZp/ji+BSwloSvb0hsUAXL2R2w+5dW1w7O/T8i19zns3vAvJLAapiYvcNy7GDnOI8sEk+M8VM/D m6krvLZzjETb0pvCusMB2MsRWz+Dnq023lxT8LUV+BTZVccagMbBIjps5tUS7M9knXt/cbngVdB xNmBm7UVTd+38A3lF7PlpoLj3zm/6Vg8H7qWxCkky42VYdEs7Fe/BXIrGB065hOj7e3PLuRksC9 0uUjHMl3D1lYhLjPbSA+eTZDVL+wR84OjpyO+uNdox9Msvdn9O+22f3A/vzLsLP3Idcgi7U8soa r83SzCGjWhlYVqTQZ3f3YHNVf7OhZxWyI9THzRjuGJczfpXzwj8M+NjjlArdpNr8Q9iXf/Ss8L6 VkEDg6aMyy9yjEA== 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 Acked-by: Chuck Lever --- fs/nfsd/nfs4xdr.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 91681aea9d7f..f85581ebbd10 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.54.0 From nobody Tue Jun 16 06:04:58 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 B67483B19CE; Tue, 28 Apr 2026 07:12: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=1777360328; cv=none; b=aF5UD88MDIeLkYth5owO+yan5lkWo2idWvT1a6ITG+xJJzXv96woZCT28EDfrQjASFgfB8DQXye+xWqbj4H4fJQCLyqK35yXiUpyOjiPWVB3bG8PATavdiDiu6PgYJLNpazNQNZsdTgiBbepUasJRCgqwG91nKroEWYeu0M+Crg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777360328; c=relaxed/simple; bh=rXq7eUH4xSN0tI04G6bK80YWfcSKFJNz2w053/l/fqo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=q1vX6hWwtBi7zLahaC55FaanBnI05bq2dC5a1H3/DEBUTRpEwxKZPqJyrDORnDX7sqT0xNJPOuQKbNSBfyqK4b1NHOfaD114GAtHxAiC3OcP6TF4nMtbjohlpsvGwR1OsUvDuUoKellCwz3NV7oGvC+Sl5OwXrzSXHTDBAZH8jQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ASO0YgSy; 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="ASO0YgSy" Received: by smtp.kernel.org (Postfix) with ESMTPSA id DD807C2BCAF; Tue, 28 Apr 2026 07:12:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777360328; bh=rXq7eUH4xSN0tI04G6bK80YWfcSKFJNz2w053/l/fqo=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=ASO0YgSyJL40XBWMvfXv8z7uTwdHiuWfsxOZn5qEfLLpZbF+m1AFnUnNUve+cYcpV x9PxcQg6DwfdH57N7+k291pBexroHsogjcoG3TVXpI7KiuMhXTJPDgqRnue14O9DZE fvcNO3b6+ITnV34OAv0Mkz/CDpbichZZDd7ceNWABep0NBY3v4ZTzeic7I+KjlR6sx /e+k5RS/K4Oziwflnwwy2dpaPYNfpM0T363kHKS/y0v9TnEukyhPuuTrRrB7GMkU1y nx7lhf2oG/0g7eBlTx49SrJRLdiFbnyBoJfHwL+XNlX98NroWWERgImemK138PQmSw p1xv36CRmDitw== From: Jeff Layton Date: Tue, 28 Apr 2026 08:10:07 +0100 Subject: [PATCH v3 23/28] 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: <20260428-dir-deleg-v3-23-5a0780ba9def@kernel.org> References: <20260428-dir-deleg-v3-0-5a0780ba9def@kernel.org> In-Reply-To: <20260428-dir-deleg-v3-0-5a0780ba9def@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=rXq7eUH4xSN0tI04G6bK80YWfcSKFJNz2w053/l/fqo=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp8F1TKHDE4x0NA7wLvnis546b39gYAs7fMc6R4 meidxCSLcOJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCafBdUwAKCRAADmhBGVaC FfbVD/9MKOPMrwqS0Nc8GSqE5XPpHRZDPKH53MCEN0i2j3dD10Oyzy0zSr+agkWJHGjZNY6jjtt lyCNTfBIEpQHDIPD2p3J4z0YZBht/C/QFmlebR9PdLOHJ6vHcdsEOr96On9tYgkwaE2PGX6qwDj 3r6x3xcALHlsacRByvG2uqq7Y+t1Cj0272+nGLR6sgrBzPqY/rs40IbVKG3xSJVT0NI/e4lF074 9fH3pXCdIkTHPT/9kYNkaoaIpMOU2EyjfvMDvF2Ph9QO0AK2wnrTWhxyon+IlpasUa5grNVQkRC Metwb6GJlLe8mEwjkt1Dh4O6KDi6RoQAkjlJe7KBzGtiieycZqCJc7lTnNDXKsAa7NeNDpsVGKK exnR3PeAtfmlce7bO3oCBgoPtOitQQ+pC+mL2EilStor+7ml+vkjUbfg/zXvNctMY2xtr54n9Q/ AZOfFFXxFRyigE2aSoX92B6Z/CrYXTiisBB31C/u3vMXZZNv105zHJFfTggKeU9dha/tXMvFx+b z0Vl0MPL2mkMKAlM5fCQywtd5eESPWXHXWGOboS6j32/zKl2eAHd2+/vRf1XnvAQmQZU/85EMIB 2al8bYCvQdYgUQBdppV3vW1XohwEf7CV1P4695vMivJph+/rKSV2aUiX9I8CTByDeoAkffvc24a uJwc4DGkZjWoXZg== 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 Acked-by: Chuck Lever --- 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 f85581ebbd10..a9cdf7a3f8b3 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.54.0 From nobody Tue Jun 16 06:04:58 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 DC4183B7B68; Tue, 28 Apr 2026 07:12: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=1777360333; cv=none; b=q2HcZEm4F28gHOqSYqpMT8ZqqlRxY6GQi7vDBLao5maAF+8KW0URIuwADdn7se7UVsiEzd/kJRBoMDOL3iSsEBRoA8r46fQssSxh56ani3pKQYNbv1JB9hA99sOBfR5hT97mHUUhgfWSdlbmxpxQRx1qa9FeyydGFK6xbbCv3yw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777360333; c=relaxed/simple; bh=BmwaOojEgulUgvkQB2FtzNLN4OZvTiJYgZ4cG/A/lYs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=S502tcs+/YrmOqSdgOwpOAs9ffGZRV0ZCruHg/ZKqCXk9gLDEBMhEHLYUF5xrO47s+MEz4zzxk6nz7Ca9wmnTedqomcN+bvt/+LWrT7WfWgKI6uEa3ESlHABAGnVCS/oDIuUV0B1a1dzP8Jzzu4/q0nt1+MojL3CAwDhYRCHO8U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=YTkPXJls; 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="YTkPXJls" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1F73AC2BCB5; Tue, 28 Apr 2026 07:12:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777360333; bh=BmwaOojEgulUgvkQB2FtzNLN4OZvTiJYgZ4cG/A/lYs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=YTkPXJlsEYp0fZJFhZHzkne/NWc5D2JmQ9vqfGgRgYlsaAppsJEoqlzUVbJpLJY17 cxdwSxURWoRpKdXAP28jsgFq+6sjJOe2WzYD5JIgz00o440HY7stNRcyZKQoL4SgDg 7h36CVAgJK1yaBtjBlLOlkl98TnJN4v2SB14u+harGRIeP/xaIUO8hqOsaefM6mrC6 3r2pNEHWL3WUeplFcBzinwb9oL2gcHStNkpo0HgoULFmXerVnFHbZuhy/7Vla2q0Oe Nm6+9uuC+RGIIbt6F6h0MaA9oF/XPCtL3i4++KRnUKG9xzGBjljMqX6uIUF6bmq12a nkD4YiyAolQ/g== From: Jeff Layton Date: Tue, 28 Apr 2026 08:10:08 +0100 Subject: [PATCH v3 24/28] 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: <20260428-dir-deleg-v3-24-5a0780ba9def@kernel.org> References: <20260428-dir-deleg-v3-0-5a0780ba9def@kernel.org> In-Reply-To: <20260428-dir-deleg-v3-0-5a0780ba9def@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=1426; i=jlayton@kernel.org; h=from:subject:message-id; bh=BmwaOojEgulUgvkQB2FtzNLN4OZvTiJYgZ4cG/A/lYs=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp8F1UYzTvpenu/Jo12jsGOoRihwUud8xyef7OB ekwcM9smHyJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCafBdVAAKCRAADmhBGVaC Fe89EACItI37Mrdh+sGu3jHLt3VA1e9nWx/BkoxrXT7Bmcgqky/o1YejxGuMwXoo68cbLc2edtu GWUXcN6CcCitCC8+RexodQl38h1jvxnwxnsYx7Crc3EE7CPRnRMrNtLyrXtOGkmCNG2CW3ahxx9 51oKencnd4Tt+ZoVxgUzkLO0CPvPfuPWXXEgcBYw2KvdzlOJfYnJhuJXsg2G8RWGIuASKUc2dUg JsdbI2Z/biGnvs7MmYDvenGjm38GlolbUQjAzXlLC7kVNwjHZIXSB8qdmWXx15wmauz97GB2B2P xZklLGjTohegj9UOP4IsC/ev2Bh/AFy4KZTDB1xTuYStPwiFUt8fkvpcuvNX5XRSRZLjgTEoGrg gjDHwd5x5WDsPSrFlJ/zB1o7UUyk9eHzXT6Eu+3QXNXWyGLG+4Daa3fE1+KrxpU6vC8MhA664AU LMdbU3Qh3lQOnGbnmluxw5a6R1I4RGwOg4PBFyoTBzwvnNzl199HLsuCSEIXXcq+ILGIo4+tRzl qlNizR4y6Sj7Y1DMT7mxqIoMd06UskL7+Py+05bdvRq2jcY30ytVFRDTTcWQxWAAcvMtlh6U9BX TwfNSxzaL7PWSe/yfhMRDG4HsYRrp9S9YuTOsLmTq/AZ/ymEyC/Zsq8dEE45WXE1RjysVc8Xqx+ tYjjVbWUiCh6/Hg== 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 has subtree checking enabled, in which case it needs connectable filehandles. Signed-off-by: Jeff Layton Acked-by: Chuck Lever --- 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 f00aba95753c..3050980a778c 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -5167,6 +5167,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 & NFSEXP_NOSUBTREECHECK); #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 570d66fc8297..caa3f5f78dc1 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -747,6 +747,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.54.0 From nobody Tue Jun 16 06:04:58 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 5FD483AC0F8; Tue, 28 Apr 2026 07:12:19 +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=1777360339; cv=none; b=Vxc8rpFmnSPMZzJSIuW6mkU8+WDKEXbh2q7qCd+7hTrvAZjQXqegwrwKKlaqc2wK4y71Nfa3EJnYKjaTZRFNA1HetfOESo4U0zvc87DwulhoARw1ZvRG6zrbZYf/khahNDOuU9WTMdhlRwarU38NjT1y9kMzV1o+0dtpX9WaMDI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777360339; c=relaxed/simple; bh=Jm3k7OpyC+6NC37VcuzrDFowtqEqqGHoYyna1syh+u0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Mg/GidiIYtZvSAmwppfX8FvqNP8QVh5EIRz8OZW1rLIBhZ/gGGS48i5Yilcq8aYhoLjNAKFjvM0W1KAo7P2JSB4JPXFlVwy87mBGvRok6bb5ZsGj37N02acBD7ApCIe4hjgIS9voOshCSFFguHu0Qs14qsbQqVoLAPY8k0rSiPs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=EDZoE0p6; 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="EDZoE0p6" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3CCB1C4AF0E; Tue, 28 Apr 2026 07:12:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777360339; bh=Jm3k7OpyC+6NC37VcuzrDFowtqEqqGHoYyna1syh+u0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=EDZoE0p6FUkL4gJTiJYzC+Q3IvzDnguNIp6pwJN67wa5c+qJ29O6363kXcjKZ8JEu LrkStlRhJpMnYDER2KGNiZz0kkGkRFYJbSdL1pmPJN/3vWCpLB522Eoy4JzjSUqf7A kJnk0YKJaEoMSvpGqvYP4C68uvopjv35njmob9WEsmRIsSgVbCKYbV3PXpsgAVRkKR vHkHAEjS45qoRQaEKNaKRgJUUVWMSlG/dsNaIwPNJb77CB3AU2a0zuU3Bm3mdvZkxI 7tlKmfQAo/HyqOLQoroVOUd4eV9wXXmS062KEqqOrz67yWuZ2K/CiBad2ieBOw1vVS 3ZbLEdelfPBEQ== From: Jeff Layton Date: Tue, 28 Apr 2026 08:10:09 +0100 Subject: [PATCH v3 25/28] 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: <20260428-dir-deleg-v3-25-5a0780ba9def@kernel.org> References: <20260428-dir-deleg-v3-0-5a0780ba9def@kernel.org> In-Reply-To: <20260428-dir-deleg-v3-0-5a0780ba9def@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=Jm3k7OpyC+6NC37VcuzrDFowtqEqqGHoYyna1syh+u0=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp8F1UcLQOPqSSoUJIS9PK1MHYBNxfqH2xRHC0s LgJq3wzFYWJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCafBdVAAKCRAADmhBGVaC FdauD/4/BFq2cEBOn8Hnskmtz+fpIR7Vwbt1qHn+7H6nDxGV9/bQE0FD3q9VDb3wxVilFKIf4ES k7hN+V8hKoufE9R4VjIDaM3wdWkDKSdHhsBi5sSmvKlWDUSSr5WKjkPSbEKAT/QzGh0Wp/v2nd6 LqFvvSStfhh7M/WYbhNS0oOSmr0tQmV4xcjhy8uqrSrq3xasms14ewX7jGPlAkLWfCV6JtSINq8 1GzAfdQuwiGrAbLGLtYgSi0PwGv3aoyIysH2cHxny+NYwIpIyqAiGaV5+GtVuE4Y/n1uef2UGNb ARwea12vsp0hQJ3UHsAVSi6dKXHB9+vxyNQ2CLkh8wGAJQPfdaWkA54ZE6PohHjS5xyiuv8iCIA 8lGzWLp5/Ju1zbV9DBicwVZ598uu3Gx9EX+lk7ksUeRDR6dcXvMdPEE0dffo5izakM6LW+cnXQv sVDfQ6R1E0QN3+CbR0tj3q9zd0wIHwxe/YoIAriNfxcdb99irt3iF3DzAuS+KDsQ0Q2oLYSZj+d kMLwnCqbS+INTE+VSQ2c9689OUfFZtBrBmAyxtUwNvjZ317kxa8Mt5TxAn7ymwgsS8BqpXwRBOr wb6ZMIrpbuzedyDpGLRz9Q543JOGPHYw6mdyA1P2HqQv+CK+j7Ja63tTFXQLhB1DvV83wsodXHq ZUn4pslLC0oq9VQ== 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 Acked-by: Chuck Lever --- fs/nfsd/nfs4xdr.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index a9cdf7a3f8b3..5d7d8545c904 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.54.0 From nobody Tue Jun 16 06:04:58 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 A751C3C343D; Tue, 28 Apr 2026 07:12: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=1777360344; cv=none; b=oh6+fWnA4Jyhbfc/VQw1r1qDmdmp03WCjQZtbHmGrqFtRx3eHVSuNQ9Gna27CkUa8YhgFB/Oo9hPz9qZKlH8T4b9cnL5GcrFTmstNz1D73dYq+XOomDgGimJ3Sv1wzt9uaZf1j2ko1amyen5kfa4l9CB3VwYRRial1qsgG8FqME= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777360344; c=relaxed/simple; bh=IpELrrWBBc/KUMvnBP0dZemm86j1sS7cGtIsGZak/jE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=rGx2ZjT7tjtcgV/UbkTfZgk4VvcDSc+p6miRE8IiQppOXX/kSEV5vTCQl42aFmqPqTrAAvtvEH2wgVc17sfzht1/Ya5BstAclsbxWjjqAmHl7As0H3qUqX3/B+AltNKCx6n08HIke5cWSfoJl7A17dYfaEYUarYu6Jd/7abAmGE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=q70paX8X; 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="q70paX8X" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6B590C2BCAF; Tue, 28 Apr 2026 07:12:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777360344; bh=IpELrrWBBc/KUMvnBP0dZemm86j1sS7cGtIsGZak/jE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=q70paX8XjIfvliPPVYNnyB6QhXXcE0py4acazUbeTtSDuq3K0j0OaeZ5VXv+NsMDG RyGGCqFZCevcnAotBuM2Ha9Ffln14qbTgAgDL2aGqJPJKlDiSPFngoUMKuzloyY97l fA0UGPHoKE5q9OCXfxHqzVWrq5sp4iRKx1+Vg+axUVhUoV2sSqmNqpKLM8AjAygNSe lOUAB4O99g7QG+20PhE+b1EXZP+orIK0N9HUL5kqdiWqkJbHtWPiIEB5xHP1fAybBc 3BzOtCyZYhdYfWL10+pWNMP3k/lk77S5XlOu+BjdwBAzxWVTJMMsPXkOtivU8gjUTQ 1Or9tGUEJeqqw== From: Jeff Layton Date: Tue, 28 Apr 2026 08:10:10 +0100 Subject: [PATCH v3 26/28] 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: <20260428-dir-deleg-v3-26-5a0780ba9def@kernel.org> References: <20260428-dir-deleg-v3-0-5a0780ba9def@kernel.org> In-Reply-To: <20260428-dir-deleg-v3-0-5a0780ba9def@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=IpELrrWBBc/KUMvnBP0dZemm86j1sS7cGtIsGZak/jE=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp8F1UEHV4sbuJarLFKKG7OMt0C44GkiKa/FfDb NqyEuLZP9uJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCafBdVAAKCRAADmhBGVaC FQltD/9JBsYkxZRFd+E02dGIaCCTVCw4NOkNf31EJGFeuu/3bZFx4h/W/4/qKD6ChxE/xFORVUU k2j6JqWHPSK8H4ulbMXEyAzTHQ1UmHWfbtB36SAR0QRUzojTivVG0KD+0ibj3/VBSmBjBxrA5RY quVoQjcgZOszTxoWOHuG5HuD+qm81Ku7iDdpJBHYepu+v+wowJewCUEQeH6WjCsganF9HlD5OeH hWWTYpAqLarTT0XqF41XHS2X7hQkOgVOmxNF71HLY7OBqN9HGzFVszex2qGw3lCY8Swt5EBO+yg +ecIjOZWeHupcxK9UrWLYPgpw7fKM4Z8sGUcMFMqFEmJ8/mptofmO0uByM24WiJDFow6XWIKnWW fS2Bos9sANfzhmg1rCP7eTe3Yc2oNz0C/tRiwMYHSH4UDNqzChT++OsYiOd+/+W1DzxSGdZgSXn Q44HYd/28O33n2dZniezjSkugWu9WiR15z5YdJWqSF4DtyeJMwDG331BUTIZXZ9bDmVRV2eK/Ge y/b06r498LB+PQsrilbzkML8WtWIGCxh9aMBTOwIH7dZLt353bqVp+K8A1hUQjhIjzy6OCXk+O+ z7q7SoJaFqSs5FLP7HOlzaCyHYGVfGd/u/bR+8eajzuQxkXgKX4IMCYL4gfmL/it1vhL5Rv3ZEB XViwpXCulQgyxtw== 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 Acked-by: Chuck Lever --- 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 3050980a778c..d2b3283c0d31 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -9808,6 +9808,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 @@ -9877,6 +9892,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 5d7d8545c904..bd1142590d2b 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 caa3f5f78dc1..cb1ac3248fe8 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -284,6 +284,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.54.0 From nobody Tue Jun 16 06:04:58 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 CD97B3B3886; Tue, 28 Apr 2026 07:12: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=1777360349; cv=none; b=cmMrl0nvXG7UecL300pkqIMdeR47EfbX1Dt5spkqv9IFDWlJJBB3gu+QvdMRKLg1NqrB6VvC9mD4Gz4sSKdUTzDj61cFsSHCkdD7PYvQL7TZOfiMu9mojNyrPrEXckkZhCOKggEx5hKU4UV9Sq/QhGWV80MfmtVW5+P3ryh4UsQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777360349; c=relaxed/simple; bh=6iP3wYS36Ujy51+xluiGDluKmbUNqp5bbfa1ol4Sl74=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=rIWobAHfYesOxMNrwJu2pLeqn4kSMZGkhmO5bba9JfCTx3eCp4Pmw4S5R6OQahfcaIJObSoxigXfcjMPgE0uZ8btqbrzQ8UFRWHMF0pQ0GDAErVW7Cuqd5HZAMVnUVwfqGsDfWQDp2uS7j6zetYp2VrK2UaaB8+py6AOrXq8e0E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=nVZ53hhQ; 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="nVZ53hhQ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 005A6C2BCB9; Tue, 28 Apr 2026 07:12:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777360349; bh=6iP3wYS36Ujy51+xluiGDluKmbUNqp5bbfa1ol4Sl74=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=nVZ53hhQOsTlfkCFYNEOPGZRfbG/aYUnsVEnxDQ/EI27S8AYhT87Qwa+6vKeU/oFA zvCtUrPZx9NCM1w9lrTrL/vIdZtRcER5WrqyWPA6NErcgVQjiVrxAGokSQGWWU1xBl 7kJOPLsUT2pHVWJOicUUsPTUnwaWtt1ge+RWe2+fpdFGlfwtXujk2wQqGw0pvIY1pO tuKkyA1Wrlo00ncJm3Pkxoiyr2raWc1onSMNAeImjoQkHQ6hfUzBogAWHYVMRY0Xmh 4qk9eOiAdS6XOdbJs/UDXt8n1FdSCJ35cHwN01jsG4IEFvL9srLEJYSuTsEDiMj0Ac DMqocD1SDKH4w== From: Jeff Layton Date: Tue, 28 Apr 2026 08:10:11 +0100 Subject: [PATCH v3 27/28] 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: <20260428-dir-deleg-v3-27-5a0780ba9def@kernel.org> References: <20260428-dir-deleg-v3-0-5a0780ba9def@kernel.org> In-Reply-To: <20260428-dir-deleg-v3-0-5a0780ba9def@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=3281; i=jlayton@kernel.org; h=from:subject:message-id; bh=6iP3wYS36Ujy51+xluiGDluKmbUNqp5bbfa1ol4Sl74=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp8F1V9Xq0xqLREm9f1HzT9TJF7HNltp5h5bQPo /A09BEXNOCJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCafBdVQAKCRAADmhBGVaC FTVrEACNnH01nCrAifRdrmRbvkd3VmH5rWZPwoL8dlubkuYnXbyQO8TiboU1j5nUtQcwRwOHfdF EzMOGepJCVFNFh8GD2eXWt9XIDBRYzIZlFEgjC35cr0jsIqJan/mqloXYiwDEGMU7ScKG6VmX1X QTYWqELUav51AM6ea6LLDeIQ6Ol4y1VN9w4jHQR4Gn4+0ZO/RWhNrfvJqJOIhXO0adVUH6j+m5C Svblfq946FQucbH5I0jgwbV8JLZwNkmbTnykwU7RmqEHedhXzBfrr1fFs2CbBCgOnimiw/+SEQb D8L6VALGp3SBBd/pRueZu2NxGTzelwxQs687R976erF8uAmeDS5ByLkbqT/3o3Ul+jAB24dIlwF bmg1pWjUzfsLBkVDtlLBF2ldWWxq6FfMwJabrOzrnoUzMh5mxEEdCtaW0+oIO6F05vW8ZtIrftW TqpVMV+EoEiDEfm1z0R/x0GuBSYa3jKtH7Xjn5ZE2t8KH1U2jq9H3t5pjrDeW6/9kEwj0Y/p82r sXLrbABLFtBUmsbkzdlJmxDL4K4ySn1zn7WRnnP1aUTSf1wfDKw9PDrmG7d7VP3QFTDJyePGsrB 9u2p0rDLwGzak/T2Twgj2s6lD3BNbUjbEwvsQyFqZzacxZBYb/256nTtRuXmbLDZMt0mNUnfZLC XAmzAPaC12fCoOQ== 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 Acked-by: Chuck Lever --- fs/nfsd/nfs4proc.c | 9 ++++++--- fs/nfsd/nfs4state.c | 14 +++++++++++++- fs/nfsd/state.h | 2 ++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index a807a55dddf9..e4717e1e3d93 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 @@ -2555,6 +2556,8 @@ nfsd4_get_dir_delegation(struct svc_rqst *rqstp, 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]; + gdd->gddr_dir_attributes[0] =3D dd->dl_dir_attrs[0]; + gdd->gddr_dir_attributes[1] =3D dd->dl_dir_attrs[1]; nfs4_put_stid(&dd->dl_stid); return nfs_ok; } diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index d2b3283c0d31..b60aa2cf1eba 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -9823,6 +9823,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 @@ -9892,10 +9901,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 cb1ac3248fe8..4c5848285378 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -286,7 +286,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.54.0 From nobody Tue Jun 16 06:04:58 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 474403CFF44; Tue, 28 Apr 2026 07:12:34 +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=1777360354; cv=none; b=Al/YWEvK60x8syK/MmaHRlBR3RgfPKYFx0dGNXa6BJ1jyyMxqjtoTSDruLRW1gr22AyqHpb0vFqLc094BvL6eK8Z6O3tadv0tLlCtIx8IVPKZmSTXhbgn1c0ao1VZNcBjrCAY0bf996t84Fqc3+phnYfjWDC8NeoR7U5iTy/SY0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777360354; c=relaxed/simple; bh=n7GdOLLaGScAngpOva5caCcXl1A9DB2/nfeO+8CVTPU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=AnHt3BU7cFEIPiYZphVpcrUwxATKv/MmmpTODcb/S9a3gw2g+B1LeICgSgxpPVYFLDnEUkIqOmX9MF/Gz4Fk5YnBAUpRNVkCVoQBuovvvN+6z8XUhAwn3JqV/jg+VlxrGGo0Z6HQ0zyL++OTEKuJ70lT5+xaCLJrtvMWE8Gv9V4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=qTjvE2vl; 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="qTjvE2vl" Received: by smtp.kernel.org (Postfix) with ESMTPSA id F00B4C2BCB6; Tue, 28 Apr 2026 07:12:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777360354; bh=n7GdOLLaGScAngpOva5caCcXl1A9DB2/nfeO+8CVTPU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=qTjvE2vl9NTM6X/sSrSMTSYv4O9H/7JNqp9pke581D5n2G8MCv6l327mGjmx1AYNd OOIrDoiEGx1wwS9Z0TYXvmO4Fxzd7NB4JI9l11XXmYnuBy7hL/s6YxZwWDIrmQhtTZ x97RL7k+SatUC2+jrsR5ig2x8kA13pPCbdvtIryhKwLM3Mxbo/N4fIdscpI4lL+p2j Le33GM9WaR1cKbC9mesn/YHKKyPDKFElHznCftDlGmoQeX9rgWe17WxWLx1Y1PFXa4 miNcWDx5qewn9DYBNigCQIyHgeAPTdUJHdPjh3+r6ghcCicsqigOYMbxpFX+DpuIht WxqY8J8RY8Bjw== From: Jeff Layton Date: Tue, 28 Apr 2026 08:10:12 +0100 Subject: [PATCH v3 28/28] 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: <20260428-dir-deleg-v3-28-5a0780ba9def@kernel.org> References: <20260428-dir-deleg-v3-0-5a0780ba9def@kernel.org> In-Reply-To: <20260428-dir-deleg-v3-0-5a0780ba9def@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=n7GdOLLaGScAngpOva5caCcXl1A9DB2/nfeO+8CVTPU=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBp8F1VHt9GAAJhBiVzD5jvGxxI3FTEFiOwGx4nh Su7jWNAD7uJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCafBdVQAKCRAADmhBGVaC FbfjEADBe7PvfHWU5fC99nWsu80EifSmzJlkeDlt/wfTqGsYSxLv9E6/EKzQ/+0mAOGyRSVujKR xoggJ77lPm7P6H78lxNwU37jPXypeJq7BoNYwkDpL2jmcwnhOVb9hMjHxOeDiry7n3+UnHCgxD4 YQmn9AuwyPpTXA/GzRvu2yaEpIHlMpGZ/ltV3BS7BFCcjRBuwMbxcoPwesn0vf6/bxA0xs9abcW K2lPLRpp7QQFSjrDwup8ftGlDge5oTaTgdOZiVzKhw8tRT8J6oyETGyiYJw+oI3aHVQXqh2GyPf qpkeR/i9rrYmiidy2JN0fX9IYwnW34SNG+0cnHmGu+9O7/Opi6rqa3Fge4uGzred3drSXPierg4 6n8gEoX/bMc2kknxjVFYRpNZaUThAAk85CRWMIPGqKjwYKAelr8BRTpKUMLS/V1Og/ULzRjCtX9 xHeT1iE20bb9PNoRWctfkj7eTKu0OVjtcvvshmWaz3P4owZUTLo3vmVimlU6PvaPn6gfpcFYZLn SOm1RqTdUWyNR9gZODNkMqPo2TnJZjlIyhX79fA/eEvi3hxkysXLXMeegLEn2nNL0JAUEeby5pI KlXIDubBdmojT6UJqLvG8vCROIpNmdKOT8iWpHLz3rOsExuC8IUGWlE6HB45kFGaWftDxqMM7D6 s3D+OiXHbLTj/WQ== 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 Acked-by: Chuck Lever --- 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 b60aa2cf1eba..bb9093e3933f 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -3479,10 +3479,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 @@ -3496,7 +3501,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; } @@ -3543,6 +3548,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 bd1142590d2b..73f2fdf929ed 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; @@ -4308,6 +4316,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.54.0