btrfs-progs: check: detect and fix problems with super_bytes_used

We do not detect problems with our bytes_used counter in the super
block.  Thankfully the same method to fix block groups is used to re-set
the value in the super block, so simply add some extra code to validate
the bytes_used field and then piggy back on the repair code for block
groups.

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:
Josef Bacik 2021-08-23 15:23:10 -04:00 committed by David Sterba
parent 04520da77b
commit e64af00bd1

View File

@ -8659,12 +8659,14 @@ static int check_block_groups(struct block_group_tree *bg_cache)
struct btrfs_trans_handle *trans;
struct cache_extent *item;
struct block_group_record *bg_rec;
u64 used = 0;
int ret = 0;
for (item = first_cache_extent(&bg_cache->tree);
item;
item = next_cache_extent(item)) {
bg_rec = container_of(item, struct block_group_record, cache);
used += bg_rec->actual_used;
if (bg_rec->disk_used == bg_rec->actual_used)
continue;
fprintf(stderr,
@ -8674,6 +8676,19 @@ static int check_block_groups(struct block_group_tree *bg_cache)
ret = -1;
}
/*
* We check the super bytes_used here because it's the sum of all block
* groups used, and the repair actually happens in
* btrfs_fix_block_accounting, so we can kill both birds with the same
* stone here.
*/
if (used != btrfs_super_bytes_used(gfs_info->super_copy)) {
fprintf(stderr,
"super bytes used %llu mismatches actual used %llu\n",
btrfs_super_bytes_used(gfs_info->super_copy), used);
ret = -1;
}
if (!repair || !ret)
return ret;