Skip to content

Commit 834328a

Browse files
author
Jan Schmidt
committed
Btrfs: tree mod log's old roots could still be part of the tree
Tree mod log treated old root buffers as always empty buffers when starting the rewind operations. However, the old root may still be part of the current tree at a lower level, with still some valid entries. Signed-off-by: Jan Schmidt <[email protected]>
1 parent ba1bfbd commit 834328a

File tree

1 file changed

+21
-4
lines changed

1 file changed

+21
-4
lines changed

fs/btrfs/ctree.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1239,6 +1239,7 @@ get_old_root(struct btrfs_root *root, u64 time_seq)
12391239
struct tree_mod_root *old_root = NULL;
12401240
u64 old_generation = 0;
12411241
u64 logical;
1242+
u32 blocksize;
12421243

12431244
eb = btrfs_read_lock_root_node(root);
12441245
tm = __tree_mod_log_oldest_root(root->fs_info, root, time_seq);
@@ -1254,12 +1255,28 @@ get_old_root(struct btrfs_root *root, u64 time_seq)
12541255
}
12551256

12561257
tm = tree_mod_log_search(root->fs_info, logical, time_seq);
1257-
if (old_root)
1258+
if (old_root && tm && tm->op != MOD_LOG_KEY_REMOVE_WHILE_FREEING) {
1259+
btrfs_tree_read_unlock(root->node);
1260+
free_extent_buffer(root->node);
1261+
blocksize = btrfs_level_size(root, old_root->level);
1262+
eb = read_tree_block(root, logical, blocksize, 0);
1263+
if (!eb) {
1264+
pr_warn("btrfs: failed to read tree block %llu from get_old_root\n",
1265+
logical);
1266+
WARN_ON(1);
1267+
} else {
1268+
eb = btrfs_clone_extent_buffer(eb);
1269+
}
1270+
} else if (old_root) {
1271+
btrfs_tree_read_unlock(root->node);
1272+
free_extent_buffer(root->node);
12581273
eb = alloc_dummy_extent_buffer(logical, root->nodesize);
1259-
else
1274+
} else {
12601275
eb = btrfs_clone_extent_buffer(root->node);
1261-
btrfs_tree_read_unlock(root->node);
1262-
free_extent_buffer(root->node);
1276+
btrfs_tree_read_unlock(root->node);
1277+
free_extent_buffer(root->node);
1278+
}
1279+
12631280
if (!eb)
12641281
return NULL;
12651282
btrfs_tree_read_lock(eb);

0 commit comments

Comments
 (0)