Skip to content

Commit b321a52

Browse files
boryaskdave
authored andcommitted
btrfs: free qgroup pertrans reserve on transaction abort
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: [email protected] # 5.15+ Reviewed-by: Qu Wenruo <[email protected]> Signed-off-by: Boris Burkov <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 9e65bfc commit b321a52

File tree

4 files changed

+34
-4
lines changed

4 files changed

+34
-4
lines changed

fs/btrfs/disk-io.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4799,6 +4799,32 @@ void btrfs_cleanup_dirty_bgs(struct btrfs_transaction *cur_trans,
47994799
}
48004800
}
48014801

4802+
static void btrfs_free_all_qgroup_pertrans(struct btrfs_fs_info *fs_info)
4803+
{
4804+
struct btrfs_root *gang[8];
4805+
int i;
4806+
int ret;
4807+
4808+
spin_lock(&fs_info->fs_roots_radix_lock);
4809+
while (1) {
4810+
ret = radix_tree_gang_lookup_tag(&fs_info->fs_roots_radix,
4811+
(void **)gang, 0,
4812+
ARRAY_SIZE(gang),
4813+
BTRFS_ROOT_TRANS_TAG);
4814+
if (ret == 0)
4815+
break;
4816+
for (i = 0; i < ret; i++) {
4817+
struct btrfs_root *root = gang[i];
4818+
4819+
btrfs_qgroup_free_meta_all_pertrans(root);
4820+
radix_tree_tag_clear(&fs_info->fs_roots_radix,
4821+
(unsigned long)root->root_key.objectid,
4822+
BTRFS_ROOT_TRANS_TAG);
4823+
}
4824+
}
4825+
spin_unlock(&fs_info->fs_roots_radix_lock);
4826+
}
4827+
48024828
void btrfs_cleanup_one_transaction(struct btrfs_transaction *cur_trans,
48034829
struct btrfs_fs_info *fs_info)
48044830
{
@@ -4827,6 +4853,8 @@ void btrfs_cleanup_one_transaction(struct btrfs_transaction *cur_trans,
48274853
EXTENT_DIRTY);
48284854
btrfs_destroy_pinned_extent(fs_info, &cur_trans->pinned_extents);
48294855

4856+
btrfs_free_all_qgroup_pertrans(fs_info);
4857+
48304858
cur_trans->state =TRANS_STATE_COMPLETED;
48314859
wake_up(&cur_trans->commit_wait);
48324860
}

fs/btrfs/qgroup.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4337,8 +4337,9 @@ static void qgroup_convert_meta(struct btrfs_fs_info *fs_info, u64 ref_root,
43374337

43384338
qgroup_rsv_release(fs_info, qgroup, num_bytes,
43394339
BTRFS_QGROUP_RSV_META_PREALLOC);
4340-
qgroup_rsv_add(fs_info, qgroup, num_bytes,
4341-
BTRFS_QGROUP_RSV_META_PERTRANS);
4340+
if (!sb_rdonly(fs_info->sb))
4341+
qgroup_rsv_add(fs_info, qgroup, num_bytes,
4342+
BTRFS_QGROUP_RSV_META_PERTRANS);
43424343

43434344
list_for_each_entry(glist, &qgroup->groups, next_group)
43444345
qgroup_iterator_add(&qgroup_list, glist->group);

fs/btrfs/transaction.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@
3737

3838
static struct kmem_cache *btrfs_trans_handle_cachep;
3939

40-
#define BTRFS_ROOT_TRANS_TAG 0
41-
4240
/*
4341
* Transaction states and transitions
4442
*

fs/btrfs/transaction.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
#include "ctree.h"
1313
#include "misc.h"
1414

15+
/* Radix-tree tag for roots that are part of the trasaction. */
16+
#define BTRFS_ROOT_TRANS_TAG 0
17+
1518
enum btrfs_trans_state {
1619
TRANS_STATE_RUNNING,
1720
TRANS_STATE_COMMIT_PREP,

0 commit comments

Comments
 (0)