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 'for-6.13-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux

Pull btrfs fixes from David Sterba:

- add lockdep annotations for io_uring/encoded read integration, inode
lock is held when returning to userspace

- properly reflect experimental config option to sysfs

- handle NULL root in case the rescue mode accepts invalid/damaged tree
roots (rescue=ibadroot)

- regression fix of a deadlock between transaction and extent locks

- fix pending bio accounting bug in encoded read ioctl

- fix NOWAIT mode when checking references for NOCOW files

- fix use-after-free in a rb-tree cleanup in ref-verify debugging tool

* tag 'for-6.13-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
btrfs: fix lockdep warnings on io_uring encoded reads
btrfs: ref-verify: fix use-after-free after invalid ref action
btrfs: add a sanity check for btrfs root in btrfs_search_slot()
btrfs: don't loop for nowait writes when checking for cross references
btrfs: sysfs: advertise experimental features only if CONFIG_BTRFS_EXPERIMENTAL=y
btrfs: fix deadlock between transaction commits and extent locks
btrfs: fix use-after-free in btrfs_encoded_read_endio()

+43 -8
+5 -1
fs/btrfs/ctree.c
··· 2046 2046 const struct btrfs_key *key, struct btrfs_path *p, 2047 2047 int ins_len, int cow) 2048 2048 { 2049 - struct btrfs_fs_info *fs_info = root->fs_info; 2049 + struct btrfs_fs_info *fs_info; 2050 2050 struct extent_buffer *b; 2051 2051 int slot; 2052 2052 int ret; ··· 2059 2059 int min_write_lock_level; 2060 2060 int prev_cmp; 2061 2061 2062 + if (!root) 2063 + return -EINVAL; 2064 + 2065 + fs_info = root->fs_info; 2062 2066 might_sleep(); 2063 2067 2064 2068 lowest_level = p->lowest_level;
+1 -1
fs/btrfs/extent-tree.c
··· 2422 2422 goto out; 2423 2423 2424 2424 ret = check_delayed_ref(root, path, objectid, offset, bytenr); 2425 - } while (ret == -EAGAIN); 2425 + } while (ret == -EAGAIN && !path->nowait); 2426 2426 2427 2427 out: 2428 2428 btrfs_release_path(path);
+14 -4
fs/btrfs/inode.c
··· 3063 3063 goto out; 3064 3064 } 3065 3065 3066 + /* 3067 + * If it's a COW write we need to lock the extent range as we will be 3068 + * inserting/replacing file extent items and unpinning an extent map. 3069 + * This must be taken before joining a transaction, as it's a higher 3070 + * level lock (like the inode's VFS lock), otherwise we can run into an 3071 + * ABBA deadlock with other tasks (transactions work like a lock, 3072 + * depending on their current state). 3073 + */ 3074 + if (!test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags)) { 3075 + clear_bits |= EXTENT_LOCKED; 3076 + lock_extent(io_tree, start, end, &cached_state); 3077 + } 3078 + 3066 3079 if (freespace_inode) 3067 3080 trans = btrfs_join_transaction_spacecache(root); 3068 3081 else ··· 3111 3098 } 3112 3099 goto out; 3113 3100 } 3114 - 3115 - clear_bits |= EXTENT_LOCKED; 3116 - lock_extent(io_tree, start, end, &cached_state); 3117 3101 3118 3102 if (test_bit(BTRFS_ORDERED_COMPRESSED, &ordered_extent->flags)) 3119 3103 compress_type = ordered_extent->compress_type; ··· 9099 9089 */ 9100 9090 WRITE_ONCE(priv->status, bbio->bio.bi_status); 9101 9091 } 9102 - if (atomic_dec_return(&priv->pending) == 0) { 9092 + if (atomic_dec_and_test(&priv->pending)) { 9103 9093 int err = blk_status_to_errno(READ_ONCE(priv->status)); 9104 9094 9105 9095 if (priv->uring_ctx) {
+10
fs/btrfs/ioctl.c
··· 4751 4751 size_t page_offset; 4752 4752 ssize_t ret; 4753 4753 4754 + /* The inode lock has already been acquired in btrfs_uring_read_extent. */ 4755 + btrfs_lockdep_inode_acquire(inode, i_rwsem); 4756 + 4754 4757 if (priv->err) { 4755 4758 ret = priv->err; 4756 4759 goto out; ··· 4861 4858 * btrfs_uring_read_finished(), which will handle unlocking the extent 4862 4859 * and inode and freeing the allocations. 4863 4860 */ 4861 + 4862 + /* 4863 + * We're returning to userspace with the inode lock held, and that's 4864 + * okay - it'll get unlocked in a worker thread. Call 4865 + * btrfs_lockdep_inode_release() to avoid confusing lockdep. 4866 + */ 4867 + btrfs_lockdep_inode_release(inode, i_rwsem); 4864 4868 4865 4869 return -EIOCBQUEUED; 4866 4870
+10
fs/btrfs/locking.h
··· 129 129 rwsem_release(&owner->lock##_map, _THIS_IP_) 130 130 131 131 /* 132 + * Used to account for the fact that when doing io_uring encoded I/O, we can 133 + * return to userspace with the inode lock still held. 134 + */ 135 + #define btrfs_lockdep_inode_acquire(owner, lock) \ 136 + rwsem_acquire_read(&owner->vfs_inode.lock.dep_map, 0, 0, _THIS_IP_) 137 + 138 + #define btrfs_lockdep_inode_release(owner, lock) \ 139 + rwsem_release(&owner->vfs_inode.lock.dep_map, _THIS_IP_) 140 + 141 + /* 132 142 * Macros for the transaction states wait events, similar to the generic wait 133 143 * event macros. 134 144 */
+1
fs/btrfs/ref-verify.c
··· 857 857 "dropping a ref for a root that doesn't have a ref on the block"); 858 858 dump_block_entry(fs_info, be); 859 859 dump_ref_action(fs_info, ra); 860 + rb_erase(&ref->node, &be->refs); 860 861 kfree(ref); 861 862 kfree(ra); 862 863 goto out_unlock;
+2 -2
fs/btrfs/sysfs.c
··· 295 295 #ifdef CONFIG_BLK_DEV_ZONED 296 296 BTRFS_FEAT_ATTR_INCOMPAT(zoned, ZONED); 297 297 #endif 298 - #ifdef CONFIG_BTRFS_DEBUG 298 + #ifdef CONFIG_BTRFS_EXPERIMENTAL 299 299 /* Remove once support for extent tree v2 is feature complete */ 300 300 BTRFS_FEAT_ATTR_INCOMPAT(extent_tree_v2, EXTENT_TREE_V2); 301 301 /* Remove once support for raid stripe tree is feature complete. */ ··· 329 329 #ifdef CONFIG_BLK_DEV_ZONED 330 330 BTRFS_FEAT_ATTR_PTR(zoned), 331 331 #endif 332 - #ifdef CONFIG_BTRFS_DEBUG 332 + #ifdef CONFIG_BTRFS_EXPERIMENTAL 333 333 BTRFS_FEAT_ATTR_PTR(extent_tree_v2), 334 334 BTRFS_FEAT_ATTR_PTR(raid_stripe_tree), 335 335 #endif