btrfs-progs: check: orig: reject bad metadata backref with invalid level
[BUG] There is a bug report that kernel tree-checker rejected an invalid metadata item: corrupt leaf: block=934474399744 slot=68 extent bytenr=425173254144 len=16384 invalid tree level, have 33554432 expect [0, 7] But original mode btrfs-check reports nothing wrong. (lowmem mode will just crash, and fixed in previous patch). [CAUSE] For original mode it doesn't really check tree level, thus didn't find the problem. [FIX] I don't have a good idea to completely make original mode to verify the level in backref and in the tree block (while lowmem does that). But at least we can detect obviously corrupted level just like kernel. Now original mode will detect such problem: ... [2/7] checking extents ERROR: tree block 30457856 has bad backref level, has 256 expect [0, 7] ref mismatch on [30457856 16384] extent item 0, found 1 tree backref 30457856 root 5 not found in extent tree backpointer mismatch on [30457856 16384] ERROR: errors found in extent allocation tree or chunk allocation [3/7] checking free space tree ... Reported-by: Stickstoff <stickstoff@posteo.de> Link: https://lore.kernel.org/linux-btrfs/6ed4cd5a-7430-f326-4056-25ae7eb44416@posteo.de/ Signed-off-by: Qu Wenruo <wqu@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
bf21c82675
commit
1a8f283c97
19
check/main.c
19
check/main.c
|
@ -5447,6 +5447,25 @@ static int process_extent_item(struct btrfs_root *root,
|
|||
if (metadata)
|
||||
btrfs_check_subpage_eb_alignment(gfs_info, key.objectid, num_bytes);
|
||||
|
||||
ptr = (unsigned long)(ei + 1);
|
||||
if (metadata) {
|
||||
u64 level;
|
||||
|
||||
if (key.type == BTRFS_EXTENT_ITEM_KEY) {
|
||||
struct btrfs_tree_block_info *info;
|
||||
|
||||
info = (struct btrfs_tree_block_info *)ptr;
|
||||
level = btrfs_tree_block_level(eb, info);
|
||||
} else {
|
||||
level = key.offset;
|
||||
}
|
||||
if (level >= BTRFS_MAX_LEVEL) {
|
||||
error(
|
||||
"tree block %llu has bad backref level, has %llu expect [0, %u]",
|
||||
key.objectid, level, BTRFS_MAX_LEVEL - 1);
|
||||
return -EUCLEAN;
|
||||
}
|
||||
}
|
||||
memset(&tmpl, 0, sizeof(tmpl));
|
||||
tmpl.start = key.objectid;
|
||||
tmpl.nr = num_bytes;
|
||||
|
|
Loading…
Reference in New Issue