Btrfs: bail out gracefully rather than BUG_ON
If a file's DIR_ITEM key is invalid (due to memory errors) and gets written to disk, a future lookup_path can end up with kernel panic due to BUG_ON(). This gets rid of the BUG_ON(), meanwhile output the corrupted key and return ENOENT if it's invalid. Signed-off-by: Liu Bo <bo.li.liu@oracle.com> Reported-by: Guillaume Bouchard <bouchard@mercs-eng.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
619c47f3d4
commit
56a0e706fc
|
@ -5445,6 +5445,14 @@ static int btrfs_inode_by_name(struct inode *dir, struct dentry *dentry,
|
||||||
goto out_err;
|
goto out_err;
|
||||||
|
|
||||||
btrfs_dir_item_key_to_cpu(path->nodes[0], di, location);
|
btrfs_dir_item_key_to_cpu(path->nodes[0], di, location);
|
||||||
|
if (location->type != BTRFS_INODE_ITEM_KEY &&
|
||||||
|
location->type != BTRFS_ROOT_ITEM_KEY) {
|
||||||
|
btrfs_warn(root->fs_info,
|
||||||
|
"%s gets something invalid in DIR_ITEM (name %s, directory ino %llu, location(%llu %u %llu))",
|
||||||
|
__func__, name, btrfs_ino(BTRFS_I(dir)),
|
||||||
|
location->objectid, location->type, location->offset);
|
||||||
|
goto out_err;
|
||||||
|
}
|
||||||
out:
|
out:
|
||||||
btrfs_free_path(path);
|
btrfs_free_path(path);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -5761,8 +5769,6 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry)
|
||||||
return inode;
|
return inode;
|
||||||
}
|
}
|
||||||
|
|
||||||
BUG_ON(location.type != BTRFS_ROOT_ITEM_KEY);
|
|
||||||
|
|
||||||
index = srcu_read_lock(&fs_info->subvol_srcu);
|
index = srcu_read_lock(&fs_info->subvol_srcu);
|
||||||
ret = fixup_tree_root_location(fs_info, dir, dentry,
|
ret = fixup_tree_root_location(fs_info, dir, dentry,
|
||||||
&location, &sub_root);
|
&location, &sub_root);
|
||||||
|
|
Loading…
Reference in New Issue