All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jeff Layton <jlayton@kernel.org>
To: chuck.lever@oracle.com, xiubli@redhat.com
Cc: linux-fsdevel@vger.kernel.org, ceph-devel@vger.kernel.org
Subject: [RFC PATCH] filelock: new helper: vfs_file_has_locks
Date: Mon, 14 Nov 2022 09:07:47 -0500	[thread overview]
Message-ID: <20221114140747.134928-1-jlayton@kernel.org> (raw)

Ceph has a need to know whether a particular file has any locks set on
it. It's currently tracking that by a num_locks field in its
filp->private_data, but that's problematic as it tries to decrement this
field when releasing locks and that can race with the file being torn
down.

Add a new vfs_file_has_locks helper that will scan the flock and posix
lists, and return true if any of the locks have a fl_file that matches
the given one. Ceph can then call this instead of doing its own
tracking.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
 fs/locks.c         | 36 ++++++++++++++++++++++++++++++++++++
 include/linux/fs.h |  1 +
 2 files changed, 37 insertions(+)

Xiubo,

Here's what I was thinking instead of trying to track this within ceph.
Most inodes never have locks set, so in most cases this will be a NULL
pointer check.

diff --git a/fs/locks.c b/fs/locks.c
index 5876c8ff0edc..c7f903b63a53 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -2672,6 +2672,42 @@ int vfs_cancel_lock(struct file *filp, struct file_lock *fl)
 }
 EXPORT_SYMBOL_GPL(vfs_cancel_lock);
 
+/**
+ * vfs_file_has_locks - are any locks held that were set on @filp?
+ * @filp: open file to check for locks
+ *
+ * Return true if are any FL_POSIX or FL_FLOCK locks currently held
+ * on @filp.
+ */
+bool vfs_file_has_locks(struct file *filp)
+{
+	struct file_lock_context *ctx;
+	struct file_lock *fl;
+	bool ret = false;
+
+	ctx = smp_load_acquire(&locks_inode(filp)->i_flctx);
+	if (!ctx)
+		return false;
+
+	spin_lock(&ctx->flc_lock);
+	list_for_each_entry(fl, &ctx->flc_posix, fl_list) {
+		if (fl->fl_file == filp) {
+			ret = true;
+			goto out;
+		}
+	}
+	list_for_each_entry(fl, &ctx->flc_flock, fl_list) {
+		if (fl->fl_file == filp) {
+			ret = true;
+			break;
+		}
+	}
+out:
+	spin_unlock(&ctx->flc_lock);
+	return ret;
+}
+EXPORT_SYMBOL(vfs_file_has_locks);
+
 #ifdef CONFIG_PROC_FS
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
diff --git a/include/linux/fs.h b/include/linux/fs.h
index e654435f1651..e4d0f1fa7f9f 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1170,6 +1170,7 @@ extern int locks_delete_block(struct file_lock *);
 extern int vfs_test_lock(struct file *, struct file_lock *);
 extern int vfs_lock_file(struct file *, unsigned int, struct file_lock *, struct file_lock *);
 extern int vfs_cancel_lock(struct file *filp, struct file_lock *fl);
+bool vfs_file_has_locks(struct file *file);
 extern int locks_lock_inode_wait(struct inode *inode, struct file_lock *fl);
 extern int __break_lease(struct inode *inode, unsigned int flags, unsigned int type);
 extern void lease_get_mtime(struct inode *, struct timespec64 *time);
-- 
2.38.1


             reply	other threads:[~2022-11-14 14:08 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-14 14:07 Jeff Layton [this message]
2022-11-14 14:19 ` [RFC PATCH] filelock: new helper: vfs_file_has_locks Chuck Lever III
2022-11-14 19:46 ` Jeff Layton
2022-11-15  5:43   ` Xiubo Li
2022-11-15 14:40     ` Jeff Layton
2022-11-16  6:16       ` Christoph Hellwig
2022-11-16  6:49       ` Xiubo Li
2022-11-16 10:55         ` Jeff Layton
2022-11-16 11:16           ` Xiubo Li
2022-11-16 11:25             ` Jeff Layton
2022-11-16 13:24               ` Xiubo Li
2022-11-15  8:54 ` Christoph Hellwig

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=20221114140747.134928-1-jlayton@kernel.org \
    --to=jlayton@kernel.org \
    --cc=ceph-devel@vger.kernel.org \
    --cc=chuck.lever@oracle.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=xiubli@redhat.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.