On 10/8/18 3:00 PM, Qu Wenruo wrote:
Add such check at check_dev_item(), since at that timing we're also iterating dev extents for dev item accounting. Signed-off-by: Qu Wenruo <[email protected]> --- check/mode-lowmem.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/check/mode-lowmem.c b/check/mode-lowmem.c index 1bce44f5658a..d387423639e6 100644 --- a/check/mode-lowmem.c +++ b/check/mode-lowmem.c @@ -4065,6 +4065,8 @@ static int check_dev_item(struct btrfs_fs_info *fs_info, u64 dev_id; u64 used; u64 total = 0; + u64 prev_devid = 0; + u64 prev_dev_ext_end = 0;
Those two new variables aren't assigned anymore in the patch... Thanks, Su
int ret;dev_item = btrfs_item_ptr(eb, slot, struct btrfs_dev_item);@@ -4086,8 +4088,16 @@ static int check_dev_item(struct btrfs_fs_info *fs_info, 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) { + u64 devid; + u64 physical_offset; + u64 physical_len; + if (path.slots[0] >= btrfs_header_nritems(path.nodes[0])) goto next;@@ -4099,7 +4109,25 @@ static int check_dev_item(struct btrfs_fs_info *fs_info, ptr = btrfs_item_ptr(path.nodes[0], path.slots[0],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; + } + total += physical_len; next: ret = btrfs_next_item(dev_root, &path); if (ret)
