Commit 5c1a712f authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'ceph-for-6.2-rc3' of https://github.com/ceph/ceph-client

Pull ceph fixes from Ilya Dryomov:
 "Two file locking fixes from Xiubo"

* tag 'ceph-for-6.2-rc3' of https://github.com/ceph/ceph-client:
  ceph: avoid use-after-free in ceph_fl_release_lock()
  ceph: switch to vfs_inode_has_locks() to fix file lock bug
parents 7b8c854c 8e185871
......@@ -2913,7 +2913,7 @@ int ceph_get_caps(struct file *filp, int need, int want, loff_t endoff, int *got
while (true) {
flags &= CEPH_FILE_MODE_MASK;
if (atomic_read(&fi->num_locks))
if (vfs_inode_has_locks(inode))
flags |= CHECK_FILELOCK;
_got = 0;
ret = try_get_cap_refs(inode, need, want, endoff,
......
......@@ -32,24 +32,36 @@ void __init ceph_flock_init(void)
static void ceph_fl_copy_lock(struct file_lock *dst, struct file_lock *src)
{
struct ceph_file_info *fi = dst->fl_file->private_data;
struct inode *inode = file_inode(dst->fl_file);
atomic_inc(&ceph_inode(inode)->i_filelock_ref);
atomic_inc(&fi->num_locks);
dst->fl_u.ceph.inode = igrab(inode);
}
/*
* Do not use the 'fl->fl_file' in release function, which
* is possibly already released by another thread.
*/
static void ceph_fl_release_lock(struct file_lock *fl)
{
struct ceph_file_info *fi = fl->fl_file->private_data;
struct inode *inode = file_inode(fl->fl_file);
struct ceph_inode_info *ci = ceph_inode(inode);
atomic_dec(&fi->num_locks);
struct inode *inode = fl->fl_u.ceph.inode;
struct ceph_inode_info *ci;
/*
* If inode is NULL it should be a request file_lock,
* nothing we can do.
*/
if (!inode)
return;
ci = ceph_inode(inode);
if (atomic_dec_and_test(&ci->i_filelock_ref)) {
/* clear error when all locks are released */
spin_lock(&ci->i_ceph_lock);
ci->i_ceph_flags &= ~CEPH_I_ERROR_FILELOCK;
spin_unlock(&ci->i_ceph_lock);
}
fl->fl_u.ceph.inode = NULL;
iput(inode);
}
static const struct file_lock_operations ceph_fl_lock_ops = {
......
......@@ -790,7 +790,6 @@ struct ceph_file_info {
struct list_head rw_contexts;
u32 filp_gen;
atomic_t num_locks;
};
struct ceph_dir_file_info {
......
......@@ -1119,6 +1119,9 @@ struct file_lock {
int state; /* state of grant or error if -ve */
unsigned int debug_id;
} afs;
struct {
struct inode *inode;
} ceph;
} fl_u;
} __randomize_layout;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment