@@ -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+
18261882int 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
19461955out :
19471956 /* Reject non SINGLE data profiles without RST */
0 commit comments