mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2024-12-28 16:53:49 +00:00
for-6.13-rc1-tag
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE8rQSAMVO+zA4DBdWxWXV+ddtWDsFAmdPMbMACgkQxWXV+ddt WDtFSA/+Kd61BPKaiZFF0yjOsjBOlu8WMHFLO5xa2ZRqV3HUzm6rdO4wUSq3Eyqg lrFszPfLA0REZIEdY2rqDKJduk1MZZg6NY7Pvn+/ByGOorM0Ym1BJoydtlUN5o2Y AWeaDxs6LBMwRqpai0+AkikufK/jK7QfhHci+Oo2XmOv1C39DQbkXO76SYh/yERt CcZNaSjm9DUlLxOOpkefxYvpPW4Uv4NSBfh9aymX/u1VxXqeuMuzPZqwZO+nwl/p M1yr9fcbrqh3yKC+JjhD7xmOJM3x4c2PmzSkQTdepOuAlQvuQ/iFD+Zc1YjY0XlT Fl938rdTKULgCarR5rdsXqdlFRnOprlgt0J1Pdf+GipTVU0EY3WU343HCz6h8pmG F/NPvlCahkEtk1UCguL92NOBeAf0adWhuYfKjkuxYuL5ZTvzsOl2ymF6Vlja0Y39 VK4exjG4ilDESxweinJe53k3QLDwvUc2h0D291QVoo2X06dhXda8oOVK+6lR5mij zDtXqurjlCybT1W7op6RcWMY0TaA8IR3Bo9oU1YbVcctuc86/X8SERv1G8MQtXhh tevOVb/cKy7gEw9q73OtrH/J2EAklnsesnpH2sdt7WUEzOQPw9BIwEa/NRbjvoqn n2ts5KktBhNjM1s0elHBf7o4+OaTrTlTrp0HelXyONZucPrzDQ4= =4mFO -----END PGP SIGNATURE----- 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()
This commit is contained in:
commit
feffde684a
@ -2046,7 +2046,7 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
||||
const struct btrfs_key *key, struct btrfs_path *p,
|
||||
int ins_len, int cow)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = root->fs_info;
|
||||
struct btrfs_fs_info *fs_info;
|
||||
struct extent_buffer *b;
|
||||
int slot;
|
||||
int ret;
|
||||
@ -2059,6 +2059,10 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
||||
int min_write_lock_level;
|
||||
int prev_cmp;
|
||||
|
||||
if (!root)
|
||||
return -EINVAL;
|
||||
|
||||
fs_info = root->fs_info;
|
||||
might_sleep();
|
||||
|
||||
lowest_level = p->lowest_level;
|
||||
|
@ -2422,7 +2422,7 @@ int btrfs_cross_ref_exist(struct btrfs_root *root, u64 objectid, u64 offset,
|
||||
goto out;
|
||||
|
||||
ret = check_delayed_ref(root, path, objectid, offset, bytenr);
|
||||
} while (ret == -EAGAIN);
|
||||
} while (ret == -EAGAIN && !path->nowait);
|
||||
|
||||
out:
|
||||
btrfs_release_path(path);
|
||||
|
@ -3063,6 +3063,19 @@ int btrfs_finish_one_ordered(struct btrfs_ordered_extent *ordered_extent)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* If it's a COW write we need to lock the extent range as we will be
|
||||
* inserting/replacing file extent items and unpinning an extent map.
|
||||
* This must be taken before joining a transaction, as it's a higher
|
||||
* level lock (like the inode's VFS lock), otherwise we can run into an
|
||||
* ABBA deadlock with other tasks (transactions work like a lock,
|
||||
* depending on their current state).
|
||||
*/
|
||||
if (!test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags)) {
|
||||
clear_bits |= EXTENT_LOCKED;
|
||||
lock_extent(io_tree, start, end, &cached_state);
|
||||
}
|
||||
|
||||
if (freespace_inode)
|
||||
trans = btrfs_join_transaction_spacecache(root);
|
||||
else
|
||||
@ -3099,9 +3112,6 @@ int btrfs_finish_one_ordered(struct btrfs_ordered_extent *ordered_extent)
|
||||
goto out;
|
||||
}
|
||||
|
||||
clear_bits |= EXTENT_LOCKED;
|
||||
lock_extent(io_tree, start, end, &cached_state);
|
||||
|
||||
if (test_bit(BTRFS_ORDERED_COMPRESSED, &ordered_extent->flags))
|
||||
compress_type = ordered_extent->compress_type;
|
||||
if (test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags)) {
|
||||
@ -9089,7 +9099,7 @@ static void btrfs_encoded_read_endio(struct btrfs_bio *bbio)
|
||||
*/
|
||||
WRITE_ONCE(priv->status, bbio->bio.bi_status);
|
||||
}
|
||||
if (atomic_dec_return(&priv->pending) == 0) {
|
||||
if (atomic_dec_and_test(&priv->pending)) {
|
||||
int err = blk_status_to_errno(READ_ONCE(priv->status));
|
||||
|
||||
if (priv->uring_ctx) {
|
||||
|
@ -4751,6 +4751,9 @@ static void btrfs_uring_read_finished(struct io_uring_cmd *cmd, unsigned int iss
|
||||
size_t page_offset;
|
||||
ssize_t ret;
|
||||
|
||||
/* The inode lock has already been acquired in btrfs_uring_read_extent. */
|
||||
btrfs_lockdep_inode_acquire(inode, i_rwsem);
|
||||
|
||||
if (priv->err) {
|
||||
ret = priv->err;
|
||||
goto out;
|
||||
@ -4859,6 +4862,13 @@ static int btrfs_uring_read_extent(struct kiocb *iocb, struct iov_iter *iter,
|
||||
* and inode and freeing the allocations.
|
||||
*/
|
||||
|
||||
/*
|
||||
* We're returning to userspace with the inode lock held, and that's
|
||||
* okay - it'll get unlocked in a worker thread. Call
|
||||
* btrfs_lockdep_inode_release() to avoid confusing lockdep.
|
||||
*/
|
||||
btrfs_lockdep_inode_release(inode, i_rwsem);
|
||||
|
||||
return -EIOCBQUEUED;
|
||||
|
||||
out_fail:
|
||||
|
@ -128,6 +128,16 @@ enum btrfs_lockdep_trans_states {
|
||||
#define btrfs_lockdep_release(owner, lock) \
|
||||
rwsem_release(&owner->lock##_map, _THIS_IP_)
|
||||
|
||||
/*
|
||||
* Used to account for the fact that when doing io_uring encoded I/O, we can
|
||||
* return to userspace with the inode lock still held.
|
||||
*/
|
||||
#define btrfs_lockdep_inode_acquire(owner, lock) \
|
||||
rwsem_acquire_read(&owner->vfs_inode.lock.dep_map, 0, 0, _THIS_IP_)
|
||||
|
||||
#define btrfs_lockdep_inode_release(owner, lock) \
|
||||
rwsem_release(&owner->vfs_inode.lock.dep_map, _THIS_IP_)
|
||||
|
||||
/*
|
||||
* Macros for the transaction states wait events, similar to the generic wait
|
||||
* event macros.
|
||||
|
@ -857,6 +857,7 @@ int btrfs_ref_tree_mod(struct btrfs_fs_info *fs_info,
|
||||
"dropping a ref for a root that doesn't have a ref on the block");
|
||||
dump_block_entry(fs_info, be);
|
||||
dump_ref_action(fs_info, ra);
|
||||
rb_erase(&ref->node, &be->refs);
|
||||
kfree(ref);
|
||||
kfree(ra);
|
||||
goto out_unlock;
|
||||
|
@ -295,7 +295,7 @@ BTRFS_FEAT_ATTR_INCOMPAT(simple_quota, SIMPLE_QUOTA);
|
||||
#ifdef CONFIG_BLK_DEV_ZONED
|
||||
BTRFS_FEAT_ATTR_INCOMPAT(zoned, ZONED);
|
||||
#endif
|
||||
#ifdef CONFIG_BTRFS_DEBUG
|
||||
#ifdef CONFIG_BTRFS_EXPERIMENTAL
|
||||
/* Remove once support for extent tree v2 is feature complete */
|
||||
BTRFS_FEAT_ATTR_INCOMPAT(extent_tree_v2, EXTENT_TREE_V2);
|
||||
/* Remove once support for raid stripe tree is feature complete. */
|
||||
@ -329,7 +329,7 @@ static struct attribute *btrfs_supported_feature_attrs[] = {
|
||||
#ifdef CONFIG_BLK_DEV_ZONED
|
||||
BTRFS_FEAT_ATTR_PTR(zoned),
|
||||
#endif
|
||||
#ifdef CONFIG_BTRFS_DEBUG
|
||||
#ifdef CONFIG_BTRFS_EXPERIMENTAL
|
||||
BTRFS_FEAT_ATTR_PTR(extent_tree_v2),
|
||||
BTRFS_FEAT_ATTR_PTR(raid_stripe_tree),
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user