btrfs: handle unexpected parent block offset in btrfs_alloc_tree_block()

Change a BUG_ON to a proper error handling, here it checks that a root
other than reloc tree does not see a non-zero offset. This is set by
btrfs_force_cow_block() and is a special case so the check makes sure
it's not accidentally set by other callers.

Reviewed-by: Boris Burkov <boris@bur.io>
Reviewed-by: Naohiro Aota <naohiro.aota@wdc.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
David Sterba 2024-02-07 02:34:23 +01:00
parent e3dea2dbc0
commit fc42bf9d7a
2 changed files with 19 additions and 2 deletions

View File

@ -5151,8 +5151,16 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans,
parent = ins.objectid;
flags |= BTRFS_BLOCK_FLAG_FULL_BACKREF;
owning_root = reloc_src_root;
} else
BUG_ON(parent > 0);
} else {
if (unlikely(parent > 0)) {
/*
* Other roots than reloc tree don't expect start
* offset of a parent block.
*/
ret = -EUCLEAN;
goto out_free_reserved;
}
}
if (root_objectid != BTRFS_TREE_LOG_OBJECTID) {
struct btrfs_delayed_extent_op *extent_op;

View File

@ -1671,6 +1671,15 @@ int btrfs_load_block_group_zone_info(struct btrfs_block_group *cache, bool new)
return -EINVAL;
}
/* Reject non SINGLE data profiles without RST. */
if ((map->type & BTRFS_BLOCK_GROUP_DATA) &&
(map->type & BTRFS_BLOCK_GROUP_PROFILE_MASK) &&
!fs_info->stripe_root) {
btrfs_err(fs_info, "zoned: data %s needs raid-stripe-tree",
btrfs_bg_type_to_raid_name(map->type));
return -EINVAL;
}
if (cache->alloc_offset > cache->zone_capacity) {
btrfs_err(fs_info,
"zoned: invalid write pointer %llu (larger than zone capacity %llu) in block group %llu",