Skip to content

Commit ce06684

Browse files
josefbacikgregkh
authored andcommitted
btrfs: drop log root for dropped roots
commit 889bfa3 upstream. If we fsync on a subvolume and create a log root for that volume, and then later delete that subvolume we'll never clean up its log root. Fix this by making switch_commit_roots free the log for any dropped roots we encounter. The extra churn is because we need a btrfs_trans_handle, not the btrfs_transaction. CC: [email protected] # 5.4+ Reviewed-by: Filipe Manana <[email protected]> Signed-off-by: Josef Bacik <[email protected]> Signed-off-by: David Sterba <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 7baf8f6 commit ce06684

File tree

1 file changed

+12
-10
lines changed

1 file changed

+12
-10
lines changed

fs/btrfs/transaction.c

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,14 @@ void btrfs_put_transaction(struct btrfs_transaction *transaction)
7777
}
7878
}
7979

80-
static noinline void switch_commit_roots(struct btrfs_transaction *trans)
80+
static noinline void switch_commit_roots(struct btrfs_trans_handle *trans)
8181
{
82+
struct btrfs_transaction *cur_trans = trans->transaction;
8283
struct btrfs_fs_info *fs_info = trans->fs_info;
8384
struct btrfs_root *root, *tmp;
8485

8586
down_write(&fs_info->commit_root_sem);
86-
list_for_each_entry_safe(root, tmp, &trans->switch_commits,
87+
list_for_each_entry_safe(root, tmp, &cur_trans->switch_commits,
8788
dirty_list) {
8889
list_del_init(&root->dirty_list);
8990
free_extent_buffer(root->commit_root);
@@ -95,16 +96,17 @@ static noinline void switch_commit_roots(struct btrfs_transaction *trans)
9596
}
9697

9798
/* We can free old roots now. */
98-
spin_lock(&trans->dropped_roots_lock);
99-
while (!list_empty(&trans->dropped_roots)) {
100-
root = list_first_entry(&trans->dropped_roots,
99+
spin_lock(&cur_trans->dropped_roots_lock);
100+
while (!list_empty(&cur_trans->dropped_roots)) {
101+
root = list_first_entry(&cur_trans->dropped_roots,
101102
struct btrfs_root, root_list);
102103
list_del_init(&root->root_list);
103-
spin_unlock(&trans->dropped_roots_lock);
104+
spin_unlock(&cur_trans->dropped_roots_lock);
105+
btrfs_free_log(trans, root);
104106
btrfs_drop_and_free_fs_root(fs_info, root);
105-
spin_lock(&trans->dropped_roots_lock);
107+
spin_lock(&cur_trans->dropped_roots_lock);
106108
}
107-
spin_unlock(&trans->dropped_roots_lock);
109+
spin_unlock(&cur_trans->dropped_roots_lock);
108110
up_write(&fs_info->commit_root_sem);
109111
}
110112

@@ -1359,7 +1361,7 @@ static int qgroup_account_snapshot(struct btrfs_trans_handle *trans,
13591361
ret = commit_cowonly_roots(trans);
13601362
if (ret)
13611363
goto out;
1362-
switch_commit_roots(trans->transaction);
1364+
switch_commit_roots(trans);
13631365
ret = btrfs_write_and_wait_transaction(trans);
13641366
if (ret)
13651367
btrfs_handle_fs_error(fs_info, ret,
@@ -2245,7 +2247,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
22452247
list_add_tail(&fs_info->chunk_root->dirty_list,
22462248
&cur_trans->switch_commits);
22472249

2248-
switch_commit_roots(cur_trans);
2250+
switch_commit_roots(trans);
22492251

22502252
ASSERT(list_empty(&cur_trans->dirty_bgs));
22512253
ASSERT(list_empty(&cur_trans->io_bgs));

0 commit comments

Comments
 (0)