Merge tag 'for-6.14-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux

Pull btrfs fixes from David Sterba:

 - add lockdep annotation for relocation root to fix a splat warning
   while merging roots

 - fix assertion failure when splitting ordered extent after transaction
   abort

 - don't print 'qgroup inconsistent' message when rescan process updates
   qgroup data sooner than the subvolume deletion process

 - fix use-after-free (accessing the error number) when attempting to
   join an aborted transaction

 - avoid starting new transaction if not necessary when cleaning qgroup
   during subvolume drop

* tag 'for-6.14-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
  btrfs: avoid starting new transaction when cleaning qgroup during subvolume drop
  btrfs: fix use-after-free when attempting to join an aborted transaction
  btrfs: do not output error message if a qgroup has been already cleaned up
  btrfs: fix assertion failure when splitting ordered extent after transaction abort
  btrfs: fix lockdep splat while merging a relocation root
This commit is contained in:
Linus Torvalds
2025-02-05 08:13:07 -08:00
4 changed files with 22 additions and 7 deletions

View File

@@ -1496,6 +1496,7 @@ read_block_for_search(struct btrfs_root *root, struct btrfs_path *p,
if (!p->skip_locking) {
btrfs_unlock_up_safe(p, parent_level + 1);
btrfs_maybe_reset_lockdep_class(root, tmp);
tmp_locked = true;
btrfs_tree_read_lock(tmp);
btrfs_release_path(p);
@@ -1539,6 +1540,7 @@ read_block_for_search(struct btrfs_root *root, struct btrfs_path *p,
if (!p->skip_locking) {
ASSERT(ret == -EAGAIN);
btrfs_maybe_reset_lockdep_class(root, tmp);
tmp_locked = true;
btrfs_tree_read_lock(tmp);
btrfs_release_path(p);

View File

@@ -1229,6 +1229,18 @@ struct btrfs_ordered_extent *btrfs_split_ordered_extent(
*/
if (WARN_ON_ONCE(len >= ordered->num_bytes))
return ERR_PTR(-EINVAL);
/*
* If our ordered extent had an error there's no point in continuing.
* The error may have come from a transaction abort done either by this
* task or some other concurrent task, and the transaction abort path
* iterates over all existing ordered extents and sets the flag
* BTRFS_ORDERED_IOERR on them.
*/
if (unlikely(flags & (1U << BTRFS_ORDERED_IOERR))) {
const int fs_error = BTRFS_FS_ERROR(fs_info);
return fs_error ? ERR_PTR(fs_error) : ERR_PTR(-EIO);
}
/* We cannot split partially completed ordered extents. */
if (ordered->bytes_left) {
ASSERT(!(flags & ~BTRFS_ORDERED_TYPE_FLAGS));

View File

@@ -1880,11 +1880,7 @@ int btrfs_qgroup_cleanup_dropped_subvolume(struct btrfs_fs_info *fs_info, u64 su
* Commit current transaction to make sure all the rfer/excl numbers
* get updated.
*/
trans = btrfs_start_transaction(fs_info->quota_root, 0);
if (IS_ERR(trans))
return PTR_ERR(trans);
ret = btrfs_commit_transaction(trans);
ret = btrfs_commit_current_transaction(fs_info->quota_root);
if (ret < 0)
return ret;
@@ -1897,8 +1893,11 @@ int btrfs_qgroup_cleanup_dropped_subvolume(struct btrfs_fs_info *fs_info, u64 su
/*
* It's squota and the subvolume still has numbers needed for future
* accounting, in this case we can not delete it. Just skip it.
*
* Or the qgroup is already removed by a qgroup rescan. For both cases we're
* safe to ignore them.
*/
if (ret == -EBUSY)
if (ret == -EBUSY || ret == -ENOENT)
ret = 0;
return ret;
}

View File

@@ -274,8 +274,10 @@ loop:
cur_trans = fs_info->running_transaction;
if (cur_trans) {
if (TRANS_ABORTED(cur_trans)) {
const int abort_error = cur_trans->aborted;
spin_unlock(&fs_info->trans_lock);
return cur_trans->aborted;
return abort_error;
}
if (btrfs_blocked_trans_types[cur_trans->state] & type) {
spin_unlock(&fs_info->trans_lock);