Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+22 -8
+1 -1
fs/ceph/caps.c
··· 2913 2913 2914 2914 while (true) { 2915 2915 flags &= CEPH_FILE_MODE_MASK; 2916 - if (atomic_read(&fi->num_locks)) 2916 + if (vfs_inode_has_locks(inode)) 2917 2917 flags |= CHECK_FILELOCK; 2918 2918 _got = 0; 2919 2919 ret = try_get_cap_refs(inode, need, want, endoff,
+18 -6
fs/ceph/locks.c
··· 32 32 33 33 static void ceph_fl_copy_lock(struct file_lock *dst, struct file_lock *src) 34 34 { 35 - struct ceph_file_info *fi = dst->fl_file->private_data; 36 35 struct inode *inode = file_inode(dst->fl_file); 37 36 atomic_inc(&ceph_inode(inode)->i_filelock_ref); 38 - atomic_inc(&fi->num_locks); 37 + dst->fl_u.ceph.inode = igrab(inode); 39 38 } 40 39 40 + /* 41 + * Do not use the 'fl->fl_file' in release function, which 42 + * is possibly already released by another thread. 43 + */ 41 44 static void ceph_fl_release_lock(struct file_lock *fl) 42 45 { 43 - struct ceph_file_info *fi = fl->fl_file->private_data; 44 - struct inode *inode = file_inode(fl->fl_file); 45 - struct ceph_inode_info *ci = ceph_inode(inode); 46 - atomic_dec(&fi->num_locks); 46 + struct inode *inode = fl->fl_u.ceph.inode; 47 + struct ceph_inode_info *ci; 48 + 49 + /* 50 + * If inode is NULL it should be a request file_lock, 51 + * nothing we can do. 52 + */ 53 + if (!inode) 54 + return; 55 + 56 + ci = ceph_inode(inode); 47 57 if (atomic_dec_and_test(&ci->i_filelock_ref)) { 48 58 /* clear error when all locks are released */ 49 59 spin_lock(&ci->i_ceph_lock); 50 60 ci->i_ceph_flags &= ~CEPH_I_ERROR_FILELOCK; 51 61 spin_unlock(&ci->i_ceph_lock); 52 62 } 63 + fl->fl_u.ceph.inode = NULL; 64 + iput(inode); 53 65 } 54 66 55 67 static const struct file_lock_operations ceph_fl_lock_ops = {
-1
fs/ceph/super.h
··· 790 790 struct list_head rw_contexts; 791 791 792 792 u32 filp_gen; 793 - atomic_t num_locks; 794 793 }; 795 794 796 795 struct ceph_dir_file_info {
+3
include/linux/fs.h
··· 1119 1119 int state; /* state of grant or error if -ve */ 1120 1120 unsigned int debug_id; 1121 1121 } afs; 1122 + struct { 1123 + struct inode *inode; 1124 + } ceph; 1122 1125 } fl_u; 1123 1126 } __randomize_layout; 1124 1127