[PATCH 12/22] btrfs-progs: check: make free space tree validation extent tree v2 aware
From: Josef Bacik <josef@toxicpanda.com>
Date: 2021-11-05 20:41:12
Subsystem:
the rest · Maintainer:
Linus Torvalds
The free space tree needs to be validated against all referenced blocks in the file system, so use the btrfs_mark_used_blocks() helper to check the free space tree and free space cache against. This will do the right thing for both extent tree v1 and extent tree v2. Signed-off-by: Josef Bacik <josef@toxicpanda.com> --- check/main.c | 90 ++++++++++++++++++---------------------------------- 1 file changed, 31 insertions(+), 59 deletions(-)
diff --git a/check/main.c b/check/main.c
index 46d08040..6252a890 100644
--- a/check/main.c
+++ b/check/main.c@@ -5611,72 +5611,38 @@ static int check_cache_range(struct btrfs_root *root, } static int verify_space_cache(struct btrfs_root *root, - struct btrfs_block_group *cache) + struct btrfs_block_group *cache, + struct extent_io_tree *used) { - struct btrfs_path path; - struct extent_buffer *leaf; - struct btrfs_key key; - u64 last; + u64 start, end, last_end, bg_end; int ret = 0; - root = btrfs_extent_root(root->fs_info, cache->start); + start = cache->start; + bg_end = cache->start + cache->length; + last_end = start; - last = max_t(u64, cache->start, BTRFS_SUPER_INFO_OFFSET); - - btrfs_init_path(&path); - key.objectid = last; - key.offset = 0; - key.type = BTRFS_EXTENT_ITEM_KEY; - ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0); - if (ret < 0) - goto out; - ret = 0; - while (1) { - if (path.slots[0] >= btrfs_header_nritems(path.nodes[0])) { - ret = btrfs_next_leaf(root, &path); - if (ret < 0) - goto out; - if (ret > 0) { - ret = 0; - break; - } - } - leaf = path.nodes[0]; - btrfs_item_key_to_cpu(leaf, &key, path.slots[0]); - if (key.objectid >= cache->start + cache->length) + while (start < bg_end) { + ret = find_first_extent_bit(used, cache->start, &start, &end, + EXTENT_DIRTY); + if (ret || start >= bg_end) { + ret = 0; break; - if (key.type != BTRFS_EXTENT_ITEM_KEY && - key.type != BTRFS_METADATA_ITEM_KEY) { - path.slots[0]++; - continue; } - - if (last == key.objectid) { - if (key.type == BTRFS_EXTENT_ITEM_KEY) - last = key.objectid + key.offset; - else - last = key.objectid + gfs_info->nodesize; - path.slots[0]++; - continue; + if (last_end < start) { + ret = check_cache_range(root, cache, last_end, + start - last_end); + if (ret) + return ret; } - - ret = check_cache_range(root, cache, last, - key.objectid - last); - if (ret) - break; - if (key.type == BTRFS_EXTENT_ITEM_KEY) - last = key.objectid + key.offset; - else - last = key.objectid + gfs_info->nodesize; - path.slots[0]++; + end = min(end, bg_end - 1); + clear_extent_dirty(used, start, end); + start = end + 1; + last_end = start; } - if (last < cache->start + cache->length) - ret = check_cache_range(root, cache, last, - cache->start + cache->length - last); - -out: - btrfs_release_path(&path); + if (last_end < bg_end) + ret = check_cache_range(root, cache, last_end, + bg_end - last_end); if (!ret && !RB_EMPTY_ROOT(&cache->free_space_ctl->free_space_offset)) {
@@ -5690,11 +5656,17 @@ out: static int check_space_cache(struct btrfs_root *root) { + struct extent_io_tree used; struct btrfs_block_group *cache; u64 start = BTRFS_SUPER_INFO_OFFSET + BTRFS_SUPER_INFO_SIZE; int ret; int error = 0; + extent_io_tree_init(&used); + ret = btrfs_mark_used_blocks(gfs_info, &used); + if (ret) + return ret; + while (1) { ctx.item_count++; cache = btrfs_lookup_first_block_group(gfs_info, start);
@@ -5739,14 +5711,14 @@ static int check_space_cache(struct btrfs_root *root) continue; } - ret = verify_space_cache(root, cache); + ret = verify_space_cache(root, cache, &used); if (ret) { fprintf(stderr, "cache appears valid but isn't %llu\n", cache->start); error++; } } - + extent_io_tree_cleanup(&used); return error ? -EINVAL : 0; }
--
2.26.3