[PATCH 08/20] btrfs-progs: image: keep track of seen blocks when walking trees
From: Josef Bacik <josef@toxicpanda.com>
Date: 2021-11-05 20:29:02
Subsystem:
the rest · Maintainer:
Linus Torvalds
Extent tree v2 no longer tracks all allocated blocks on the file system, so we'll have to default to walking trees to generate metadata images. There's an annoying drawback with walking trees with btrfs-image where we'll happily copy multiple blocks over and over again if there are snapshots. Fix this by keeping track of blocks we've seen and simply skipping blocks that we've already queued up for copying. Signed-off-by: Josef Bacik <josef@toxicpanda.com> --- image/main.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/image/main.c b/image/main.c
index dbce17e7..57e0cb6c 100644
--- a/image/main.c
+++ b/image/main.c@@ -93,6 +93,8 @@ struct metadump_struct { pthread_cond_t cond; struct rb_root name_tree; + struct extent_io_tree seen; + struct list_head list; struct list_head ordered; size_t num_items;
@@ -461,6 +463,7 @@ static void metadump_destroy(struct metadump_struct *md, int num_threads) free(name->sub); free(name); } + extent_io_tree_cleanup(&md->seen); } static int metadump_init(struct metadump_struct *md, struct btrfs_root *root,
@@ -476,6 +479,7 @@ static int metadump_init(struct metadump_struct *md, struct btrfs_root *root, memset(md, 0, sizeof(*md)); INIT_LIST_HEAD(&md->list); INIT_LIST_HEAD(&md->ordered); + extent_io_tree_init(&md->seen); md->root = root; md->out = out; md->pending_start = (u64)-1;
@@ -771,6 +775,14 @@ static int copy_tree_blocks(struct btrfs_root *root, struct extent_buffer *eb, int i = 0; int ret; + bytenr = btrfs_header_bytenr(eb); + if (test_range_bit(&metadump->seen, bytenr, + bytenr + fs_info->nodesize - 1, EXTENT_DIRTY, 1)) + return 0; + + set_extent_dirty(&metadump->seen, bytenr, + bytenr + fs_info->nodesize - 1); + ret = add_extent(btrfs_header_bytenr(eb), fs_info->nodesize, metadump, 0); if (ret) {
--
2.26.3