aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorJosef Bacik <josef@toxicpanda.com>2022-02-22 17:22:38 -0500
committerDavid Sterba <dsterba@suse.com>2022-03-08 18:18:01 +0100
commit3aacdc44043dc46e9aa0bc97110e8a24582ec58f (patch)
treeb45ed206348b9e374fd302bd15ca1882d012362d /common
parentc91d5bf1442dd3a5f074c8235bb706cda9fdf6d5 (diff)
downloadbtrfs-progs-3aacdc44043dc46e9aa0bc97110e8a24582ec58f.tar.gz
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>
Diffstat (limited to 'common')
-rw-r--r--common/repair.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/common/repair.c b/common/repair.c
index f8c3f89c..a1ee05c6 100644
--- a/common/repair.c
+++ b/common/repair.c
@@ -178,9 +178,11 @@ static int populate_used_from_extent_root(struct btrfs_root *root,
if (slot >= btrfs_header_nritems(leaf)) {
ret = btrfs_next_leaf(root, &path);
if (ret < 0)
- return ret;
- if (ret > 0)
break;
+ if (ret > 0) {
+ ret = 0;
+ break;
+ }
leaf = path.nodes[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)
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);
+ }
path.slots[0]++;
}
btrfs_release_path(&path);
- return 0;
+ return ret;
}
int btrfs_mark_used_blocks(struct btrfs_fs_info *fs_info,