filelock: new helper: vfs_inode_has_locks
[ Upstream commitab1ddef98a
] 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: Xiubo Li <xiubli@redhat.com> Reviewed-by: Christoph Hellwig <hch@infradead.org> Signed-off-by: Jeff Layton <jlayton@kernel.org> Stable-dep-of:461ab10ef7
("ceph: switch to vfs_inode_has_locks() to fix file lock bug") Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Родитель
f34b03ce3a
Коммит
54e72ce5f1
23
fs/locks.c
23
fs/locks.c
|
@ -2703,6 +2703,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>
|
||||
|
|
|
@ -1195,6 +1195,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);
|
||||
|
@ -1307,6 +1308,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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче