Commit 7faadb25 authored by Jeff Layton's avatar Jeff Layton Committed by zhaoxiaoqiang11
Browse files

filelock: new helper: vfs_inode_has_locks

stable inclusion
from stable-v5.10.163
commit 407710427dd53290b6406ca7583ba82ae7f7ba59
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I7PJ9N

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=407710427dd53290b6406ca7583ba82ae7f7ba59



----------------------------------------------------

[ Upstream commit ab1ddef9 ]

Ceph has a need to know whether a particular inode 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_inode_has_locks helper that just returns whether any locks
are currently held on the inode.

Reviewed-by: default avatarXiubo Li <xiubli@redhat.com>
Reviewed-by: default avatarChristoph Hellwig <hch@infradead.org>
Signed-off-by: default avatarJeff Layton <jlayton@kernel.org>
Stable-dep-of: 461ab10e ("ceph: switch to vfs_inode_has_locks() to fix file lock bug")
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarzhaoxiaoqiang11 <zhaoxiaoqiang11@jd.com>
parent 981dae72
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -2813,6 +2813,29 @@ int vfs_cancel_lock(struct file *filp, struct file_lock *fl)
}
EXPORT_SYMBOL_GPL(vfs_cancel_lock);

/**
 * vfs_inode_has_locks - are any file locks held on @inode?
 * @inode: inode to check for locks
 *
 * Return true if there are any FL_POSIX or FL_FLOCK locks currently
 * set on @inode.
 */
bool vfs_inode_has_locks(struct inode *inode)
{
	struct file_lock_context *ctx;
	bool ret;

	ctx = smp_load_acquire(&inode->i_flctx);
	if (!ctx)
		return false;

	spin_lock(&ctx->flc_lock);
	ret = !list_empty(&ctx->flc_posix) || !list_empty(&ctx->flc_flock);
	spin_unlock(&ctx->flc_lock);
	return ret;
}
EXPORT_SYMBOL_GPL(vfs_inode_has_locks);

#ifdef CONFIG_PROC_FS
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
+6 −0
Original line number Diff line number Diff line
@@ -1187,6 +1187,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_inode_has_locks(struct inode *inode);
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);
@@ -1299,6 +1300,11 @@ static inline int vfs_cancel_lock(struct file *filp, struct file_lock *fl)
	return 0;
}

static inline bool vfs_inode_has_locks(struct inode *inode)
{
	return false;
}

static inline int locks_lock_inode_wait(struct inode *inode, struct file_lock *fl)
{
	return -ENOLCK;