Skip to content

Commit 889bfa3

Browse files
josefbacikkdave
authored andcommitted
btrfs: drop log root for dropped roots
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]>
1 parent 668e48a commit 889bfa3

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
@@ -147,13 +147,14 @@ void btrfs_put_transaction(struct btrfs_transaction *transaction)
147147
}
148148
}
149149

150-
static noinline void switch_commit_roots(struct btrfs_transaction *trans)
150+
static noinline void switch_commit_roots(struct btrfs_trans_handle *trans)
151151
{
152+
struct btrfs_transaction *cur_trans = trans->transaction;
152153
struct btrfs_fs_info *fs_info = trans->fs_info;
153154
struct btrfs_root *root, *tmp;
154155

155156
down_write(&fs_info->commit_root_sem);
156-
list_for_each_entry_safe(root, tmp, &trans->switch_commits,
157+
list_for_each_entry_safe(root, tmp, &cur_trans->switch_commits,
157158
dirty_list) {
158159
list_del_init(&root->dirty_list);
159160
free_extent_buffer(root->commit_root);
@@ -165,16 +166,17 @@ static noinline void switch_commit_roots(struct btrfs_transaction *trans)
165166
}
166167

167168
/* We can free old roots now. */
168-
spin_lock(&trans->dropped_roots_lock);
169-
while (!list_empty(&trans->dropped_roots)) {
170-
root = list_first_entry(&trans->dropped_roots,
169+
spin_lock(&cur_trans->dropped_roots_lock);
170+
while (!list_empty(&cur_trans->dropped_roots)) {
171+
root = list_first_entry(&cur_trans->dropped_roots,
171172
struct btrfs_root, root_list);
172173
list_del_init(&root->root_list);
173-
spin_unlock(&trans->dropped_roots_lock);
174+
spin_unlock(&cur_trans->dropped_roots_lock);
175+
btrfs_free_log(trans, root);
174176
btrfs_drop_and_free_fs_root(fs_info, root);
175-
spin_lock(&trans->dropped_roots_lock);
177+
spin_lock(&cur_trans->dropped_roots_lock);
176178
}
177-
spin_unlock(&trans->dropped_roots_lock);
179+
spin_unlock(&cur_trans->dropped_roots_lock);
178180
up_write(&fs_info->commit_root_sem);
179181
}
180182

@@ -1421,7 +1423,7 @@ static int qgroup_account_snapshot(struct btrfs_trans_handle *trans,
14211423
ret = commit_cowonly_roots(trans);
14221424
if (ret)
14231425
goto out;
1424-
switch_commit_roots(trans->transaction);
1426+
switch_commit_roots(trans);
14251427
ret = btrfs_write_and_wait_transaction(trans);
14261428
if (ret)
14271429
btrfs_handle_fs_error(fs_info, ret,
@@ -2301,7 +2303,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
23012303
list_add_tail(&fs_info->chunk_root->dirty_list,
23022304
&cur_trans->switch_commits);
23032305

2304-
switch_commit_roots(cur_trans);
2306+
switch_commit_roots(trans);
23052307

23062308
ASSERT(list_empty(&cur_trans->dirty_bgs));
23072309
ASSERT(list_empty(&cur_trans->io_bgs));

0 commit comments

Comments
 (0)