Skip to content

Commit

Permalink
btrfs: free qgroup pertrans reserve on transaction abort
Browse files Browse the repository at this point in the history
If we abort a transaction, we never run the code that frees the pertrans
qgroup reservation. This results in warnings on unmount as that
reservation has been leaked. The leak isn't a huge issue since the fs is
read-only, but it's better to clean it up when we know we can/should. Do
it during the cleanup_transaction step of aborting.

CC: stable@vger.kernel.org # 5.15+
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Boris Burkov <boris@bur.io>
Signed-off-by: David Sterba <dsterba@suse.com>
  • Loading branch information
Boris Burkov authored and David Sterba committed Dec 6, 2023
1 parent 9e65bfc commit b321a52
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 4 deletions.
28 changes: 28 additions & 0 deletions fs/btrfs/disk-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -4799,6 +4799,32 @@ void btrfs_cleanup_dirty_bgs(struct btrfs_transaction *cur_trans,
}
}

static void btrfs_free_all_qgroup_pertrans(struct btrfs_fs_info *fs_info)
{
struct btrfs_root *gang[8];
int i;
int ret;

spin_lock(&fs_info->fs_roots_radix_lock);
while (1) {
ret = radix_tree_gang_lookup_tag(&fs_info->fs_roots_radix,
(void **)gang, 0,
ARRAY_SIZE(gang),
BTRFS_ROOT_TRANS_TAG);
if (ret == 0)
break;
for (i = 0; i < ret; i++) {
struct btrfs_root *root = gang[i];

btrfs_qgroup_free_meta_all_pertrans(root);
radix_tree_tag_clear(&fs_info->fs_roots_radix,
(unsigned long)root->root_key.objectid,
BTRFS_ROOT_TRANS_TAG);
}
}
spin_unlock(&fs_info->fs_roots_radix_lock);
}

void btrfs_cleanup_one_transaction(struct btrfs_transaction *cur_trans,
struct btrfs_fs_info *fs_info)
{
Expand Down Expand Up @@ -4827,6 +4853,8 @@ void btrfs_cleanup_one_transaction(struct btrfs_transaction *cur_trans,
EXTENT_DIRTY);
btrfs_destroy_pinned_extent(fs_info, &cur_trans->pinned_extents);

btrfs_free_all_qgroup_pertrans(fs_info);

cur_trans->state =TRANS_STATE_COMPLETED;
wake_up(&cur_trans->commit_wait);
}
Expand Down
5 changes: 3 additions & 2 deletions fs/btrfs/qgroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -4337,8 +4337,9 @@ static void qgroup_convert_meta(struct btrfs_fs_info *fs_info, u64 ref_root,

qgroup_rsv_release(fs_info, qgroup, num_bytes,
BTRFS_QGROUP_RSV_META_PREALLOC);
qgroup_rsv_add(fs_info, qgroup, num_bytes,
BTRFS_QGROUP_RSV_META_PERTRANS);
if (!sb_rdonly(fs_info->sb))
qgroup_rsv_add(fs_info, qgroup, num_bytes,
BTRFS_QGROUP_RSV_META_PERTRANS);

list_for_each_entry(glist, &qgroup->groups, next_group)
qgroup_iterator_add(&qgroup_list, glist->group);
Expand Down
2 changes: 0 additions & 2 deletions fs/btrfs/transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@

static struct kmem_cache *btrfs_trans_handle_cachep;

#define BTRFS_ROOT_TRANS_TAG 0

/*
* Transaction states and transitions
*
Expand Down
3 changes: 3 additions & 0 deletions fs/btrfs/transaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
#include "ctree.h"
#include "misc.h"

/* Radix-tree tag for roots that are part of the trasaction. */
#define BTRFS_ROOT_TRANS_TAG 0

enum btrfs_trans_state {
TRANS_STATE_RUNNING,
TRANS_STATE_COMMIT_PREP,
Expand Down

0 comments on commit b321a52

Please sign in to comment.