mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 01:04:41 +01:00
btrfs: zoned: factor out the zone loading part into a testable function
Separate btrfs_load_block_group_* calling path into a function, so that it can be an entry point of unit test. Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Signed-off-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:
parent
e564cd2511
commit
e8f6130419
2 changed files with 66 additions and 48 deletions
105
fs/btrfs/zoned.c
105
fs/btrfs/zoned.c
|
|
@ -1823,6 +1823,62 @@ static int btrfs_load_block_group_raid10(struct btrfs_block_group *bg,
|
|||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_FOR_TESTS
|
||||
int btrfs_load_block_group_by_raid_type(struct btrfs_block_group *bg,
|
||||
struct btrfs_chunk_map *map,
|
||||
struct zone_info *zone_info,
|
||||
unsigned long *active, u64 last_alloc)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = bg->fs_info;
|
||||
u64 profile;
|
||||
int ret;
|
||||
|
||||
profile = map->type & BTRFS_BLOCK_GROUP_PROFILE_MASK;
|
||||
switch (profile) {
|
||||
case 0: /* single */
|
||||
ret = btrfs_load_block_group_single(bg, &zone_info[0], active);
|
||||
break;
|
||||
case BTRFS_BLOCK_GROUP_DUP:
|
||||
ret = btrfs_load_block_group_dup(bg, map, zone_info, active, last_alloc);
|
||||
break;
|
||||
case BTRFS_BLOCK_GROUP_RAID1:
|
||||
case BTRFS_BLOCK_GROUP_RAID1C3:
|
||||
case BTRFS_BLOCK_GROUP_RAID1C4:
|
||||
ret = btrfs_load_block_group_raid1(bg, map, zone_info, active, last_alloc);
|
||||
break;
|
||||
case BTRFS_BLOCK_GROUP_RAID0:
|
||||
ret = btrfs_load_block_group_raid0(bg, map, zone_info, active, last_alloc);
|
||||
break;
|
||||
case BTRFS_BLOCK_GROUP_RAID10:
|
||||
ret = btrfs_load_block_group_raid10(bg, map, zone_info, active, last_alloc);
|
||||
break;
|
||||
case BTRFS_BLOCK_GROUP_RAID5:
|
||||
case BTRFS_BLOCK_GROUP_RAID6:
|
||||
default:
|
||||
btrfs_err(fs_info, "zoned: profile %s not yet supported",
|
||||
btrfs_bg_type_to_raid_name(map->type));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ret == -EIO && profile != 0 && profile != BTRFS_BLOCK_GROUP_RAID0 &&
|
||||
profile != BTRFS_BLOCK_GROUP_RAID10) {
|
||||
/*
|
||||
* Detected broken write pointer. Make this block group
|
||||
* unallocatable by setting the allocation pointer at the end of
|
||||
* allocatable region. Relocating this block group will fix the
|
||||
* mismatch.
|
||||
*
|
||||
* Currently, we cannot handle RAID0 or RAID10 case like this
|
||||
* because we don't have a proper zone_capacity value. But,
|
||||
* reading from this block group won't work anyway by a missing
|
||||
* stripe.
|
||||
*/
|
||||
bg->alloc_offset = bg->zone_capacity;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int btrfs_load_block_group_zone_info(struct btrfs_block_group *cache, bool new)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = cache->fs_info;
|
||||
|
|
@ -1835,7 +1891,6 @@ int btrfs_load_block_group_zone_info(struct btrfs_block_group *cache, bool new)
|
|||
unsigned long *active = NULL;
|
||||
u64 last_alloc = 0;
|
||||
u32 num_sequential = 0, num_conventional = 0;
|
||||
u64 profile;
|
||||
|
||||
if (!btrfs_is_zoned(fs_info))
|
||||
return 0;
|
||||
|
|
@ -1895,53 +1950,7 @@ int btrfs_load_block_group_zone_info(struct btrfs_block_group *cache, bool new)
|
|||
}
|
||||
}
|
||||
|
||||
profile = map->type & BTRFS_BLOCK_GROUP_PROFILE_MASK;
|
||||
switch (profile) {
|
||||
case 0: /* single */
|
||||
ret = btrfs_load_block_group_single(cache, &zone_info[0], active);
|
||||
break;
|
||||
case BTRFS_BLOCK_GROUP_DUP:
|
||||
ret = btrfs_load_block_group_dup(cache, map, zone_info, active,
|
||||
last_alloc);
|
||||
break;
|
||||
case BTRFS_BLOCK_GROUP_RAID1:
|
||||
case BTRFS_BLOCK_GROUP_RAID1C3:
|
||||
case BTRFS_BLOCK_GROUP_RAID1C4:
|
||||
ret = btrfs_load_block_group_raid1(cache, map, zone_info,
|
||||
active, last_alloc);
|
||||
break;
|
||||
case BTRFS_BLOCK_GROUP_RAID0:
|
||||
ret = btrfs_load_block_group_raid0(cache, map, zone_info,
|
||||
active, last_alloc);
|
||||
break;
|
||||
case BTRFS_BLOCK_GROUP_RAID10:
|
||||
ret = btrfs_load_block_group_raid10(cache, map, zone_info,
|
||||
active, last_alloc);
|
||||
break;
|
||||
case BTRFS_BLOCK_GROUP_RAID5:
|
||||
case BTRFS_BLOCK_GROUP_RAID6:
|
||||
default:
|
||||
btrfs_err(fs_info, "zoned: profile %s not yet supported",
|
||||
btrfs_bg_type_to_raid_name(map->type));
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ret == -EIO && profile != 0 && profile != BTRFS_BLOCK_GROUP_RAID0 &&
|
||||
profile != BTRFS_BLOCK_GROUP_RAID10) {
|
||||
/*
|
||||
* Detected broken write pointer. Make this block group
|
||||
* unallocatable by setting the allocation pointer at the end of
|
||||
* allocatable region. Relocating this block group will fix the
|
||||
* mismatch.
|
||||
*
|
||||
* Currently, we cannot handle RAID0 or RAID10 case like this
|
||||
* because we don't have a proper zone_capacity value. But,
|
||||
* reading from this block group won't work anyway by a missing
|
||||
* stripe.
|
||||
*/
|
||||
cache->alloc_offset = cache->zone_capacity;
|
||||
}
|
||||
ret = btrfs_load_block_group_by_raid_type(cache, map, zone_info, active, last_alloc);
|
||||
|
||||
out:
|
||||
/* Reject non SINGLE data profiles without RST */
|
||||
|
|
|
|||
|
|
@ -99,6 +99,15 @@ void btrfs_check_active_zone_reservation(struct btrfs_fs_info *fs_info);
|
|||
int btrfs_reset_unused_block_groups(struct btrfs_space_info *space_info, u64 num_bytes);
|
||||
void btrfs_show_zoned_stats(struct btrfs_fs_info *fs_info, struct seq_file *seq);
|
||||
|
||||
#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
|
||||
struct zone_info;
|
||||
|
||||
int btrfs_load_block_group_by_raid_type(struct btrfs_block_group *bg,
|
||||
struct btrfs_chunk_map *map,
|
||||
struct zone_info *zone_info,
|
||||
unsigned long *active, u64 last_alloc);
|
||||
#endif
|
||||
|
||||
#else /* CONFIG_BLK_DEV_ZONED */
|
||||
|
||||
static inline int btrfs_get_dev_zone_info_all_devices(struct btrfs_fs_info *fs_info)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue