Btrfs: detect corruption when non-root leaf has zero item
Right now we treat leaf which has zero item as a valid one because we could have an empty tree, that is, a root that is also a leaf without any item, however, in the same case but when the leaf is not a root, we can end up with hitting the BUG_ON(1) in btrfs_extend_item() called by setup_inline_extent_backref(). This makes us check the situation as a corruption if leaf is not its own root. Signed-off-by: Liu Bo <bo.li.liu@oracle.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com> Signed-off-by: Chris Mason <clm@fb.com>
This commit is contained in:
parent
053ab70f06
commit
1ba98d086f
|
@ -560,8 +560,29 @@ static noinline int check_leaf(struct btrfs_root *root,
|
||||||
u32 nritems = btrfs_header_nritems(leaf);
|
u32 nritems = btrfs_header_nritems(leaf);
|
||||||
int slot;
|
int slot;
|
||||||
|
|
||||||
if (nritems == 0)
|
if (nritems == 0) {
|
||||||
|
struct btrfs_root *check_root;
|
||||||
|
|
||||||
|
key.objectid = btrfs_header_owner(leaf);
|
||||||
|
key.type = BTRFS_ROOT_ITEM_KEY;
|
||||||
|
key.offset = (u64)-1;
|
||||||
|
|
||||||
|
check_root = btrfs_get_fs_root(root->fs_info, &key, false);
|
||||||
|
/*
|
||||||
|
* The only reason we also check NULL here is that during
|
||||||
|
* open_ctree() some roots has not yet been set up.
|
||||||
|
*/
|
||||||
|
if (!IS_ERR_OR_NULL(check_root)) {
|
||||||
|
/* if leaf is the root, then it's fine */
|
||||||
|
if (leaf->start !=
|
||||||
|
btrfs_root_bytenr(&check_root->root_item)) {
|
||||||
|
CORRUPT("non-root leaf's nritems is 0",
|
||||||
|
leaf, root, 0);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check the 0 item */
|
/* Check the 0 item */
|
||||||
if (btrfs_item_offset_nr(leaf, 0) + btrfs_item_size_nr(leaf, 0) !=
|
if (btrfs_item_offset_nr(leaf, 0) + btrfs_item_size_nr(leaf, 0) !=
|
||||||
|
|
Loading…
Reference in New Issue