From: Jeff Layton <jlayton@kernel.org>
To: Alexander Viro <viro@zeniv.linux.org.uk>,
Christian Brauner <brauner@kernel.org>, Jan Kara <jack@suse.cz>,
Chuck Lever <chuck.lever@oracle.com>,
Alexander Aring <alex.aring@gmail.com>,
Trond Myklebust <trondmy@kernel.org>,
Anna Schumaker <anna@kernel.org>,
Steve French <sfrench@samba.org>,
Paulo Alcantara <pc@manguebit.com>,
Ronnie Sahlberg <ronniesahlberg@gmail.com>,
Shyam Prasad N <sprasad@microsoft.com>,
Tom Talpey <tom@talpey.com>,
Bharath SM <bharathsm@microsoft.com>,
NeilBrown <neil@brown.name>,
Olga Kornievskaia <okorniev@redhat.com>,
Dai Ngo <Dai.Ngo@oracle.com>, Jonathan Corbet <corbet@lwn.net>,
Amir Goldstein <amir73il@gmail.com>,
Miklos Szeredi <miklos@szeredi.hu>
Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org,
samba-technical@lists.samba.org, linux-doc@vger.kernel.org,
Jeff Layton <jlayton@kernel.org>
Subject: [PATCH RFC v2 16/28] filelock: add support for ignoring deleg breaks for dir change events
Date: Mon, 02 Jun 2025 10:01:59 -0400 [thread overview]
Message-ID: <20250602-dir-deleg-v2-16-a7919700de86@kernel.org> (raw)
In-Reply-To: <20250602-dir-deleg-v2-0-a7919700de86@kernel.org>
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 a support for ignoring lease breaks on directory changes.
Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
fs/locks.c | 56 ++++++++++++++++++++++++++++++++++++++++--------
include/linux/filelock.h | 29 ++++++++++++++-----------
2 files changed, 63 insertions(+), 22 deletions(-)
diff --git a/fs/locks.c b/fs/locks.c
index 6e46176d1e00962904f03c151500e593f410e4c6..95270a1fab4a1792a6fcad738cc9d937d99ad2af 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1526,15 +1526,52 @@ any_leases_conflict(struct inode *inode, struct file_lease *breaker)
return false;
}
+static bool
+ignore_dir_deleg_break(struct file_lease *fl, unsigned int flags)
+{
+ if ((flags & LEASE_BREAK_DIR_CREATE) && (fl->c.flc_flags & FL_IGN_DIR_CREATE))
+ return true;
+ if ((flags & LEASE_BREAK_DIR_DELETE) && (fl->c.flc_flags & FL_IGN_DIR_DELETE))
+ return true;
+ if ((flags & LEASE_BREAK_DIR_RENAME) && (fl->c.flc_flags & FL_IGN_DIR_RENAME))
+ return true;
+
+ return false;
+}
+
+static bool
+visible_leases_remaining(struct inode *inode, unsigned int flags)
+{
+ struct file_lock_context *ctx = locks_inode_context(inode);
+ struct file_lease *fl;
+
+ lockdep_assert_held(&ctx->flc_lock);
+
+ if (list_empty(&ctx->flc_lease))
+ return false;
+
+ if (!S_ISDIR(inode->i_mode))
+ return true;
+
+ list_for_each_entry(fl, &ctx->flc_lease, c.flc_list) {
+ if (!ignore_dir_deleg_break(fl, flags))
+ return true;
+ }
+ return false;
+}
+
/**
- * __break_lease - revoke all outstanding leases on file
- * @inode: the inode of the file to return
- * @flags: LEASE_BREAK_* flags
+ * __break_lease - revoke all outstanding leases on file
+ * @inode: the inode of the file to return
+ * @flags: LEASE_BREAK_* flags
*
- * break_lease (inlined for speed) has checked there already is at least
- * some kind of lock (maybe a lease) on this file. Leases are broken on
- * a call to open() or truncate(). This function can block waiting for the
- * lease break unless you specify LEASE_BREAK_NONBLOCK.
+ * break_lease (inlined for speed) has checked there already is at least
+ * some kind of lock (maybe a lease) on this file. Leases and Delegations
+ * are broken on a call to open() or truncate(). Delegations are also
+ * broken on any event that would change the ctime. Directory delegations
+ * are broken whenever the directory changes (unless the delegation is set
+ * up to ignore the event). This function can block waiting for the lease
+ * break unless you specify LEASE_BREAK_NONBLOCK.
*/
int __break_lease(struct inode *inode, unsigned int flags)
{
@@ -1545,7 +1582,6 @@ int __break_lease(struct inode *inode, unsigned int flags)
bool want_write = !(flags & LEASE_BREAK_OPEN_RDONLY);
int error = 0;
-
new_fl = lease_alloc(NULL, want_write ? F_WRLCK : F_RDLCK);
if (IS_ERR(new_fl))
return PTR_ERR(new_fl);
@@ -1584,6 +1620,8 @@ int __break_lease(struct inode *inode, unsigned int flags)
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;
@@ -1599,7 +1637,7 @@ int __break_lease(struct inode *inode, unsigned int flags)
locks_delete_lock_ctx(&fl->c, &dispose);
}
- if (list_empty(&ctx->flc_lease))
+ if (!visible_leases_remaining(inode, flags))
goto out;
if (flags & LEASE_BREAK_NONBLOCK) {
diff --git a/include/linux/filelock.h b/include/linux/filelock.h
index f2b2d1e1d1ab08671895c3bfe398e5bba02353d8..32b30c14f5fd52727b1a18957e9dbc930c922941 100644
--- a/include/linux/filelock.h
+++ b/include/linux/filelock.h
@@ -4,19 +4,22 @@
#include <linux/fs.h>
-#define FL_POSIX 1
-#define FL_FLOCK 2
-#define FL_DELEG 4 /* NFSv4 delegation */
-#define FL_ACCESS 8 /* not trying to lock, just looking */
-#define FL_EXISTS 16 /* when unlocking, test for existence */
-#define FL_LEASE 32 /* lease held on this file */
-#define FL_CLOSE 64 /* unlock on close */
-#define FL_SLEEP 128 /* A blocking lock */
-#define FL_DOWNGRADE_PENDING 256 /* Lease is being downgraded */
-#define FL_UNLOCK_PENDING 512 /* Lease is being broken */
-#define FL_OFDLCK 1024 /* lock is "owned" by struct file */
-#define FL_LAYOUT 2048 /* outstanding pNFS layout */
-#define FL_RECLAIM 4096 /* reclaiming from a reboot server */
+#define FL_POSIX BIT(0) /* POSIX lock */
+#define FL_FLOCK BIT(1) /* BSD lock */
+#define FL_LEASE BIT(2) /* file lease */
+#define FL_DELEG BIT(3) /* NFSv4 delegation */
+#define FL_LAYOUT BIT(4) /* outstanding pNFS layout */
+#define FL_ACCESS BIT(5) /* not trying to lock, just looking */
+#define FL_EXISTS BIT(6) /* when unlocking, test for existence */
+#define FL_CLOSE BIT(7) /* unlock on close */
+#define FL_SLEEP BIT(8) /* A blocking lock */
+#define FL_DOWNGRADE_PENDING BIT(9) /* Lease is being downgraded */
+#define FL_UNLOCK_PENDING BIT(10) /* Lease is being broken */
+#define FL_OFDLCK BIT(11) /* POSIX lock "owned" by struct file */
+#define FL_RECLAIM BIT(12) /* reclaiming from a reboot server */
+#define FL_IGN_DIR_CREATE BIT(13) /* ignore DIR_CREATE events */
+#define FL_IGN_DIR_DELETE BIT(14) /* ignore DIR_DELETE events */
+#define FL_IGN_DIR_RENAME BIT(15) /* ignore DIR_RENAME events */
#define FL_CLOSE_POSIX (FL_POSIX | FL_CLOSE)
--
2.49.0
next prev parent reply other threads:[~2025-06-02 14:02 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-06-02 14:01 [PATCH RFC v2 00/28] vfs, nfsd, nfs: implement directory delegations Jeff Layton
2025-06-02 14:01 ` [PATCH RFC v2 01/28] filelock: push the S_ISREG check down to ->setlease handlers Jeff Layton
2025-06-02 14:01 ` [PATCH RFC v2 02/28] filelock: add a lm_may_setlease lease_manager callback Jeff Layton
2025-06-02 14:01 ` [PATCH RFC v2 03/28] vfs: add try_break_deleg calls for parents to vfs_{link,rename,unlink} Jeff Layton
2025-06-02 14:01 ` [PATCH RFC v2 04/28] vfs: allow mkdir to wait for delegation break on parent Jeff Layton
2025-06-05 11:19 ` Jan Kara
2025-06-05 11:25 ` Jeff Layton
2025-06-06 10:10 ` Christian Brauner
2025-06-02 14:01 ` [PATCH RFC v2 05/28] vfs: allow rmdir " Jeff Layton
2025-06-02 14:01 ` [PATCH RFC v2 06/28] vfs: break parent dir delegations in open(..., O_CREAT) codepath Jeff Layton
2025-06-02 14:01 ` [PATCH RFC v2 07/28] vfs: make vfs_create break delegations on parent directory Jeff Layton
2025-06-02 14:01 ` [PATCH RFC v2 08/28] vfs: make vfs_mknod " Jeff Layton
2025-06-02 14:01 ` [PATCH RFC v2 09/28] filelock: lift the ban on directory leases in generic_setlease Jeff Layton
2025-06-02 14:01 ` [PATCH RFC v2 10/28] nfsd: allow filecache to hold S_IFDIR files Jeff Layton
2025-06-02 14:01 ` [PATCH RFC v2 11/28] nfsd: allow DELEGRETURN on directories Jeff Layton
2025-06-02 14:01 ` [PATCH RFC v2 12/28] nfsd: check for delegation conflicts vs. the same client Jeff Layton
2025-06-02 14:01 ` [PATCH RFC v2 13/28] nfsd: wire up GET_DIR_DELEGATION handling Jeff Layton
2025-06-02 14:01 ` [PATCH RFC v2 14/28] filelock: rework the __break_lease API to use flags Jeff Layton
2025-06-02 14:01 ` [PATCH RFC v2 15/28] filelock: add struct delegated_inode Jeff Layton
2025-06-02 14:01 ` Jeff Layton [this message]
2025-06-02 14:02 ` [PATCH RFC v2 17/28] filelock: add an inode_lease_ignore_mask helper Jeff Layton
2025-06-02 14:02 ` [PATCH RFC v2 18/28] nfsd: add protocol support for CB_NOTIFY Jeff Layton
2025-06-02 14:02 ` [PATCH RFC v2 19/28] nfsd: add callback encoding and decoding linkages " Jeff Layton
2025-06-02 14:02 ` [PATCH RFC v2 20/28] nfsd: add data structures for handling CB_NOTIFY to directory delegation Jeff Layton
2025-06-02 14:02 ` [PATCH RFC v2 21/28] fsnotify: export fsnotify_recalc_mask() Jeff Layton
2025-06-03 20:13 ` Jan Kara
2025-06-03 20:17 ` Jeff Layton
2025-06-02 14:02 ` [PATCH RFC v2 22/28] nfsd: update the fsnotify mark when setting or removing a dir delegation Jeff Layton
2025-06-02 14:02 ` [PATCH RFC v2 23/28] nfsd: make nfsd4_callback_ops->prepare operation bool return Jeff Layton
2025-06-02 14:02 ` [PATCH RFC v2 24/28] nfsd: add notification handlers for dir events Jeff Layton
2025-06-02 14:02 ` [PATCH RFC v2 25/28] nfsd: allow nfsd to get a dir lease with an ignore mask Jeff Layton
2025-06-02 14:02 ` [PATCH RFC v2 26/28] nfsd: add a tracepoint for nfsd_file_fsnotify_handle_dir_event() Jeff Layton
2025-06-02 14:02 ` [PATCH RFC v2 27/28] nfsd: add support for NOTIFY4_ADD_ENTRY events Jeff Layton
2025-06-02 14:02 ` [PATCH RFC v2 28/28] nfsd: add support for NOTIFY4_RENAME_ENTRY events Jeff Layton
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250602-dir-deleg-v2-16-a7919700de86@kernel.org \
--to=jlayton@kernel.org \
--cc=Dai.Ngo@oracle.com \
--cc=alex.aring@gmail.com \
--cc=amir73il@gmail.com \
--cc=anna@kernel.org \
--cc=bharathsm@microsoft.com \
--cc=brauner@kernel.org \
--cc=chuck.lever@oracle.com \
--cc=corbet@lwn.net \
--cc=jack@suse.cz \
--cc=linux-cifs@vger.kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-nfs@vger.kernel.org \
--cc=miklos@szeredi.hu \
--cc=neil@brown.name \
--cc=okorniev@redhat.com \
--cc=pc@manguebit.com \
--cc=ronniesahlberg@gmail.com \
--cc=samba-technical@lists.samba.org \
--cc=sfrench@samba.org \
--cc=sprasad@microsoft.com \
--cc=tom@talpey.com \
--cc=trondmy@kernel.org \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).