[PATCH v3 04/28] filelock: add an inode_lease_ignore_mask helper

Jeff Layton
2026-04-28T07:10:38Z

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 <jack@suse.cz>
Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
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 *lc, struct file_lock_core *bc
return rc;
}

+#define IGNORE_MASK (FL_IGN_DIR_CREATE | FL_IGN_DIR_DELETE | FL_IGN_DIR_RENAME)
+
+/**
+ * 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 = 0;
+
+ ctx = locks_inode_context(inode);
+ if (!ctx)
+ return 0;
+
+ spin_lock(&ctx->flc_lock);
+ list_for_each_entry(flc, &ctx->flc_lease, flc_list) {
+ mask |= flc->flc_flags & IGNORE_MASK;
+ /* If we already have everything, we can stop */
+ if (mask == 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_lease **, 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);

struct notifier_block;
int lease_register_notifier(struct notifier_block *);

--
2.54.0