Skip to content

Commit 69eb071

Browse files
maharmstoneadam900710
authored andcommitted
btrfs-progs: check that device byte values in superblock match those in chunk root
The superblock of each device contains a copy of the corresponding struct btrfs_dev_item that lives in the chunk root. Add a check that the total_bytes and bytes_used values of these two copies match. Signed-off-by: Mark Harmstone <[email protected]> [ Change the error to warning ] Reviewed-by: Boris Burkov <[email protected]> Signed-off-by: Qu Wenruo <[email protected]>
1 parent 2e01e0c commit 69eb071

File tree

1 file changed

+35
-0
lines changed

1 file changed

+35
-0
lines changed

check/main.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8645,6 +8645,7 @@ static int check_device_used(struct device_record *dev_rec,
86458645
if (opt_check_repair) {
86468646
ret = repair_dev_item_bytes_used(gfs_info,
86478647
dev_rec->devid, total_byte);
8648+
dev_rec->byte_used = total_byte;
86488649
}
86498650
return ret;
86508651
} else {
@@ -8702,6 +8703,28 @@ static bool is_super_size_valid(void)
87028703
return true;
87038704
}
87048705

8706+
static int check_super_dev_item(struct device_record *dev_rec)
8707+
{
8708+
struct btrfs_dev_item *super_di = &gfs_info->super_copy->dev_item;
8709+
int ret = 0;
8710+
8711+
if (btrfs_stack_device_total_bytes(super_di) != dev_rec->total_byte) {
8712+
warning("device %llu's total_bytes was %llu in tree but %llu in superblock",
8713+
dev_rec->devid, dev_rec->total_byte,
8714+
btrfs_stack_device_total_bytes(super_di));
8715+
ret = 1;
8716+
}
8717+
8718+
if (btrfs_stack_device_bytes_used(super_di) != dev_rec->byte_used) {
8719+
warning("device %llu's bytes_used was %llu in tree but %llu in superblock",
8720+
dev_rec->devid, dev_rec->byte_used,
8721+
btrfs_stack_device_bytes_used(super_di));
8722+
ret = 1;
8723+
}
8724+
8725+
return ret;
8726+
}
8727+
87058728
/* check btrfs_dev_item -> btrfs_dev_extent */
87068729
static int check_devices(struct rb_root *dev_cache,
87078730
struct device_extent_tree *dev_extent_cache)
@@ -8723,6 +8746,18 @@ static int check_devices(struct rb_root *dev_cache,
87238746
gfs_info->sectorsize);
87248747
if (dev_rec->bad_block_dev_size && !ret)
87258748
ret = 1;
8749+
8750+
if (dev_rec->devid == gfs_info->super_copy->dev_item.devid) {
8751+
/*
8752+
* This dev item mismatch between super and chunk tree
8753+
* is not a criticl problem, and CI kernels do not receive
8754+
* needed backport so they will cause mismatch during RW mounts.
8755+
*
8756+
* SO here we didn't record the mismatch as an error.
8757+
*/
8758+
check_super_dev_item(dev_rec);
8759+
}
8760+
87268761
dev_node = rb_next(dev_node);
87278762
}
87288763
list_for_each_entry(dext_rec, &dev_extent_cache->no_device_orphans,

0 commit comments

Comments
 (0)