btrfs-progs: repair: bail if we find an unaligned extent

The fuzz-test/003 was infinite looping when I reworked the code to
re-calculate the used bytes for the superblock.  This is because fsck
wasn't properly fixing the bad extent before my change, it just happened
to error out nicely, whereas my change made it so we go the wrong bytes
used count and just infinite looped trying to fix the problem.

Fix this by sanity checking the extent when we try to re-calculate the
bytes_used.  This makes us no longer infinite loop so we can get through
the fuzz tests.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Josef Bacik 2022-02-22 17:22:38 -05:00 committed by David Sterba
parent c91d5bf144
commit 3aacdc4404
1 changed files with 14 additions and 4 deletions

View File

@ -178,9 +178,11 @@ static int populate_used_from_extent_root(struct btrfs_root *root,
if (slot >= btrfs_header_nritems(leaf)) { if (slot >= btrfs_header_nritems(leaf)) {
ret = btrfs_next_leaf(root, &path); ret = btrfs_next_leaf(root, &path);
if (ret < 0) if (ret < 0)
return ret;
if (ret > 0)
break; break;
if (ret > 0) {
ret = 0;
break;
}
leaf = path.nodes[0]; leaf = path.nodes[0];
slot = path.slots[0]; slot = path.slots[0];
} }
@ -191,13 +193,21 @@ static int populate_used_from_extent_root(struct btrfs_root *root,
else if (key.type == BTRFS_METADATA_ITEM_KEY) else if (key.type == BTRFS_METADATA_ITEM_KEY)
end = start + fs_info->nodesize - 1; end = start + fs_info->nodesize - 1;
if (start != end) if (start != end) {
if (!IS_ALIGNED(start, fs_info->sectorsize) ||
!IS_ALIGNED(end + 1, fs_info->sectorsize)) {
fprintf(stderr, "unaligned value in the extent tree start %llu end %llu\n",
start, end + 1);
ret = -EINVAL;
break;
}
set_extent_dirty(io_tree, start, end); set_extent_dirty(io_tree, start, end);
}
path.slots[0]++; path.slots[0]++;
} }
btrfs_release_path(&path); btrfs_release_path(&path);
return 0; return ret;
} }
int btrfs_mark_used_blocks(struct btrfs_fs_info *fs_info, int btrfs_mark_used_blocks(struct btrfs_fs_info *fs_info,