Skip to content

Commit e8f6130

Browse files
naotakdave
authored andcommitted
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>
1 parent e564cd2 commit e8f6130

2 files changed

Lines changed: 66 additions & 48 deletions

File tree

fs/btrfs/zoned.c

Lines changed: 57 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1823,6 +1823,62 @@ static int btrfs_load_block_group_raid10(struct btrfs_block_group *bg,
18231823
return 0;
18241824
}
18251825

1826+
EXPORT_FOR_TESTS
1827+
int btrfs_load_block_group_by_raid_type(struct btrfs_block_group *bg,
1828+
struct btrfs_chunk_map *map,
1829+
struct zone_info *zone_info,
1830+
unsigned long *active, u64 last_alloc)
1831+
{
1832+
struct btrfs_fs_info *fs_info = bg->fs_info;
1833+
u64 profile;
1834+
int ret;
1835+
1836+
profile = map->type & BTRFS_BLOCK_GROUP_PROFILE_MASK;
1837+
switch (profile) {
1838+
case 0: /* single */
1839+
ret = btrfs_load_block_group_single(bg, &zone_info[0], active);
1840+
break;
1841+
case BTRFS_BLOCK_GROUP_DUP:
1842+
ret = btrfs_load_block_group_dup(bg, map, zone_info, active, last_alloc);
1843+
break;
1844+
case BTRFS_BLOCK_GROUP_RAID1:
1845+
case BTRFS_BLOCK_GROUP_RAID1C3:
1846+
case BTRFS_BLOCK_GROUP_RAID1C4:
1847+
ret = btrfs_load_block_group_raid1(bg, map, zone_info, active, last_alloc);
1848+
break;
1849+
case BTRFS_BLOCK_GROUP_RAID0:
1850+
ret = btrfs_load_block_group_raid0(bg, map, zone_info, active, last_alloc);
1851+
break;
1852+
case BTRFS_BLOCK_GROUP_RAID10:
1853+
ret = btrfs_load_block_group_raid10(bg, map, zone_info, active, last_alloc);
1854+
break;
1855+
case BTRFS_BLOCK_GROUP_RAID5:
1856+
case BTRFS_BLOCK_GROUP_RAID6:
1857+
default:
1858+
btrfs_err(fs_info, "zoned: profile %s not yet supported",
1859+
btrfs_bg_type_to_raid_name(map->type));
1860+
return -EINVAL;
1861+
}
1862+
1863+
if (ret == -EIO && profile != 0 && profile != BTRFS_BLOCK_GROUP_RAID0 &&
1864+
profile != BTRFS_BLOCK_GROUP_RAID10) {
1865+
/*
1866+
* Detected broken write pointer. Make this block group
1867+
* unallocatable by setting the allocation pointer at the end of
1868+
* allocatable region. Relocating this block group will fix the
1869+
* mismatch.
1870+
*
1871+
* Currently, we cannot handle RAID0 or RAID10 case like this
1872+
* because we don't have a proper zone_capacity value. But,
1873+
* reading from this block group won't work anyway by a missing
1874+
* stripe.
1875+
*/
1876+
bg->alloc_offset = bg->zone_capacity;
1877+
}
1878+
1879+
return ret;
1880+
}
1881+
18261882
int btrfs_load_block_group_zone_info(struct btrfs_block_group *cache, bool new)
18271883
{
18281884
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)
18351891
unsigned long *active = NULL;
18361892
u64 last_alloc = 0;
18371893
u32 num_sequential = 0, num_conventional = 0;
1838-
u64 profile;
18391894

18401895
if (!btrfs_is_zoned(fs_info))
18411896
return 0;
@@ -1895,53 +1950,7 @@ int btrfs_load_block_group_zone_info(struct btrfs_block_group *cache, bool new)
18951950
}
18961951
}
18971952

1898-
profile = map->type & BTRFS_BLOCK_GROUP_PROFILE_MASK;
1899-
switch (profile) {
1900-
case 0: /* single */
1901-
ret = btrfs_load_block_group_single(cache, &zone_info[0], active);
1902-
break;
1903-
case BTRFS_BLOCK_GROUP_DUP:
1904-
ret = btrfs_load_block_group_dup(cache, map, zone_info, active,
1905-
last_alloc);
1906-
break;
1907-
case BTRFS_BLOCK_GROUP_RAID1:
1908-
case BTRFS_BLOCK_GROUP_RAID1C3:
1909-
case BTRFS_BLOCK_GROUP_RAID1C4:
1910-
ret = btrfs_load_block_group_raid1(cache, map, zone_info,
1911-
active, last_alloc);
1912-
break;
1913-
case BTRFS_BLOCK_GROUP_RAID0:
1914-
ret = btrfs_load_block_group_raid0(cache, map, zone_info,
1915-
active, last_alloc);
1916-
break;
1917-
case BTRFS_BLOCK_GROUP_RAID10:
1918-
ret = btrfs_load_block_group_raid10(cache, map, zone_info,
1919-
active, last_alloc);
1920-
break;
1921-
case BTRFS_BLOCK_GROUP_RAID5:
1922-
case BTRFS_BLOCK_GROUP_RAID6:
1923-
default:
1924-
btrfs_err(fs_info, "zoned: profile %s not yet supported",
1925-
btrfs_bg_type_to_raid_name(map->type));
1926-
ret = -EINVAL;
1927-
goto out;
1928-
}
1929-
1930-
if (ret == -EIO && profile != 0 && profile != BTRFS_BLOCK_GROUP_RAID0 &&
1931-
profile != BTRFS_BLOCK_GROUP_RAID10) {
1932-
/*
1933-
* Detected broken write pointer. Make this block group
1934-
* unallocatable by setting the allocation pointer at the end of
1935-
* allocatable region. Relocating this block group will fix the
1936-
* mismatch.
1937-
*
1938-
* Currently, we cannot handle RAID0 or RAID10 case like this
1939-
* because we don't have a proper zone_capacity value. But,
1940-
* reading from this block group won't work anyway by a missing
1941-
* stripe.
1942-
*/
1943-
cache->alloc_offset = cache->zone_capacity;
1944-
}
1953+
ret = btrfs_load_block_group_by_raid_type(cache, map, zone_info, active, last_alloc);
19451954

19461955
out:
19471956
/* Reject non SINGLE data profiles without RST */

fs/btrfs/zoned.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,15 @@ void btrfs_check_active_zone_reservation(struct btrfs_fs_info *fs_info);
9999
int btrfs_reset_unused_block_groups(struct btrfs_space_info *space_info, u64 num_bytes);
100100
void btrfs_show_zoned_stats(struct btrfs_fs_info *fs_info, struct seq_file *seq);
101101

102+
#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
103+
struct zone_info;
104+
105+
int btrfs_load_block_group_by_raid_type(struct btrfs_block_group *bg,
106+
struct btrfs_chunk_map *map,
107+
struct zone_info *zone_info,
108+
unsigned long *active, u64 last_alloc);
109+
#endif
110+
102111
#else /* CONFIG_BLK_DEV_ZONED */
103112

104113
static inline int btrfs_get_dev_zone_info_all_devices(struct btrfs_fs_info *fs_info)

0 commit comments

Comments
 (0)