forked from Mirrors/btrfs-progs
btrfs-progs: check: lowmem: Add check for overlapping dev extents
Add such check to check_dev_item(), since at that time we're also iterating dev extents for dev item accounting. Signed-off-by: Qu Wenruo <wqu@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>master
parent
37cf7de3a1
commit
920d475a98
|
@ -4095,6 +4095,8 @@ static int check_dev_item(struct btrfs_fs_info *fs_info,
|
||||||
u64 dev_id;
|
u64 dev_id;
|
||||||
u64 used;
|
u64 used;
|
||||||
u64 total = 0;
|
u64 total = 0;
|
||||||
|
u64 prev_devid = 0;
|
||||||
|
u64 prev_dev_ext_end = 0;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
dev_item = btrfs_item_ptr(eb, slot, struct btrfs_dev_item);
|
dev_item = btrfs_item_ptr(eb, slot, struct btrfs_dev_item);
|
||||||
|
@ -4116,8 +4118,16 @@ static int check_dev_item(struct btrfs_fs_info *fs_info,
|
||||||
return REFERENCER_MISSING;
|
return REFERENCER_MISSING;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Iterate dev_extents to calculate the used space of a device */
|
/*
|
||||||
|
* Iterate dev_extents to calculate the used space of a device
|
||||||
|
*
|
||||||
|
* Also make sure no dev extents overlap and end beyond device boundary
|
||||||
|
*/
|
||||||
while (1) {
|
while (1) {
|
||||||
|
u64 devid;
|
||||||
|
u64 physical_offset;
|
||||||
|
u64 physical_len;
|
||||||
|
|
||||||
if (path.slots[0] >= btrfs_header_nritems(path.nodes[0]))
|
if (path.slots[0] >= btrfs_header_nritems(path.nodes[0]))
|
||||||
goto next;
|
goto next;
|
||||||
|
|
||||||
|
@ -4129,7 +4139,27 @@ static int check_dev_item(struct btrfs_fs_info *fs_info,
|
||||||
|
|
||||||
ptr = btrfs_item_ptr(path.nodes[0], path.slots[0],
|
ptr = btrfs_item_ptr(path.nodes[0], path.slots[0],
|
||||||
struct btrfs_dev_extent);
|
struct btrfs_dev_extent);
|
||||||
total += btrfs_dev_extent_length(path.nodes[0], ptr);
|
devid = key.objectid;
|
||||||
|
physical_offset = key.offset;
|
||||||
|
physical_len = btrfs_dev_extent_length(path.nodes[0], ptr);
|
||||||
|
|
||||||
|
if (prev_devid == devid && physical_offset < prev_dev_ext_end) {
|
||||||
|
error(
|
||||||
|
"dev extent devid %llu offset %llu len %llu overlap with previous dev extent end %llu",
|
||||||
|
devid, physical_offset, physical_len,
|
||||||
|
prev_dev_ext_end);
|
||||||
|
return ACCOUNTING_MISMATCH;
|
||||||
|
}
|
||||||
|
if (physical_offset + physical_len > total_bytes) {
|
||||||
|
error(
|
||||||
|
"dev extent devid %llu offset %llu len %llu is beyond device boundary %llu",
|
||||||
|
devid, physical_offset, physical_len,
|
||||||
|
total_bytes);
|
||||||
|
return ACCOUNTING_MISMATCH;
|
||||||
|
}
|
||||||
|
prev_devid = devid;
|
||||||
|
prev_dev_ext_end = physical_offset + physical_len;
|
||||||
|
total += physical_len;
|
||||||
next:
|
next:
|
||||||
ret = btrfs_next_item(dev_root, &path);
|
ret = btrfs_next_item(dev_root, &path);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
Loading…
Reference in New Issue