mirror of
https://github.com/kdave/btrfs-progs
synced 2024-12-17 20:05:24 +00:00
btrfs-progs: image: keep track of seen blocks when walking trees
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. Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Josef Bacik <josef@toxicpanda.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
639b1fc2e7
commit
29e56c7e05
12
image/main.c
12
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) {
|
||||
|
Loading…
Reference in New Issue
Block a user