@@ -981,7 +981,7 @@ static int btrfs_load_block_group_dup(struct btrfs_fs_info *fs_info,
981981 struct btrfs_block_group * bg ,
982982 struct map_lookup * map ,
983983 struct zone_info * zone_info ,
984- unsigned long * active )
984+ unsigned long * active , u64 last_alloc )
985985{
986986 if ((map -> type & BTRFS_BLOCK_GROUP_DATA ) && !fs_info -> stripe_root ) {
987987 btrfs_err (fs_info , "zoned: data DUP profile needs raid-stripe-tree" );
@@ -1002,6 +1002,12 @@ static int btrfs_load_block_group_dup(struct btrfs_fs_info *fs_info,
10021002 zone_info [1 ].physical );
10031003 return - EIO ;
10041004 }
1005+
1006+ if (zone_info [0 ].alloc_offset == WP_CONVENTIONAL )
1007+ zone_info [0 ].alloc_offset = last_alloc ;
1008+ if (zone_info [1 ].alloc_offset == WP_CONVENTIONAL )
1009+ zone_info [1 ].alloc_offset = last_alloc ;
1010+
10051011 if (zone_info [0 ].alloc_offset != zone_info [1 ].alloc_offset ) {
10061012 btrfs_err (fs_info ,
10071013 "zoned: write pointer offset mismatch of zones in DUP profile" );
@@ -1022,7 +1028,7 @@ static int btrfs_load_block_group_raid1(struct btrfs_fs_info *fs_info,
10221028 struct btrfs_block_group * bg ,
10231029 struct map_lookup * map ,
10241030 struct zone_info * zone_info ,
1025- unsigned long * active )
1031+ unsigned long * active , u64 last_alloc )
10261032{
10271033 int i ;
10281034
@@ -1036,9 +1042,10 @@ static int btrfs_load_block_group_raid1(struct btrfs_fs_info *fs_info,
10361042 bg -> zone_capacity = min_not_zero (zone_info [0 ].capacity , zone_info [1 ].capacity );
10371043
10381044 for (i = 0 ; i < map -> num_stripes ; i ++ ) {
1039- if (zone_info [i ].alloc_offset == WP_MISSING_DEV ||
1040- zone_info [i ].alloc_offset == WP_CONVENTIONAL )
1045+ if (zone_info [i ].alloc_offset == WP_MISSING_DEV )
10411046 continue ;
1047+ if (zone_info [i ].alloc_offset == WP_CONVENTIONAL )
1048+ zone_info [i ].alloc_offset = last_alloc ;
10421049
10431050 if (zone_info [0 ].alloc_offset != zone_info [i ].alloc_offset ) {
10441051 btrfs_err (fs_info ,
@@ -1066,7 +1073,7 @@ static int btrfs_load_block_group_raid0(struct btrfs_fs_info *fs_info,
10661073 struct btrfs_block_group * bg ,
10671074 struct map_lookup * map ,
10681075 struct zone_info * zone_info ,
1069- unsigned long * active )
1076+ unsigned long * active , u64 last_alloc )
10701077{
10711078 if ((map -> type & BTRFS_BLOCK_GROUP_DATA ) && !fs_info -> stripe_root ) {
10721079 btrfs_err (fs_info , "zoned: data %s needs raid-stripe-tree" ,
@@ -1075,9 +1082,24 @@ static int btrfs_load_block_group_raid0(struct btrfs_fs_info *fs_info,
10751082 }
10761083
10771084 for (int i = 0 ; i < map -> num_stripes ; i ++ ) {
1078- if (zone_info [i ].alloc_offset == WP_MISSING_DEV ||
1079- zone_info [i ].alloc_offset == WP_CONVENTIONAL )
1085+ if (zone_info [i ].alloc_offset == WP_MISSING_DEV )
10801086 continue ;
1087+ if (zone_info [i ].alloc_offset == WP_CONVENTIONAL ) {
1088+ u64 stripe_nr , full_stripe_nr ;
1089+ u64 stripe_offset ;
1090+ int stripe_index ;
1091+
1092+ stripe_nr = last_alloc / map -> stripe_len ;
1093+ stripe_offset = stripe_nr * map -> stripe_len ;
1094+ full_stripe_nr = stripe_nr / map -> num_stripes ;
1095+ stripe_index = stripe_nr % map -> num_stripes ;
1096+
1097+ zone_info [i ].alloc_offset = full_stripe_nr * map -> stripe_len ;
1098+ if (stripe_index > i )
1099+ zone_info [i ].alloc_offset += map -> stripe_len ;
1100+ else if (stripe_index == i )
1101+ zone_info [i ].alloc_offset += (last_alloc - stripe_offset );
1102+ }
10811103
10821104 if (test_bit (0 , active ) != test_bit (i , active )) {
10831105 return - EIO ;
@@ -1096,7 +1118,7 @@ static int btrfs_load_block_group_raid10(struct btrfs_fs_info *fs_info,
10961118 struct btrfs_block_group * bg ,
10971119 struct map_lookup * map ,
10981120 struct zone_info * zone_info ,
1099- unsigned long * active )
1121+ unsigned long * active , u64 last_alloc )
11001122{
11011123 if ((map -> type & BTRFS_BLOCK_GROUP_DATA ) && !fs_info -> stripe_root ) {
11021124 btrfs_err (fs_info , "zoned: data %s needs raid-stripe-tree" ,
@@ -1105,9 +1127,24 @@ static int btrfs_load_block_group_raid10(struct btrfs_fs_info *fs_info,
11051127 }
11061128
11071129 for (int i = 0 ; i < map -> num_stripes ; i ++ ) {
1108- if (zone_info [i ].alloc_offset == WP_MISSING_DEV ||
1109- zone_info [i ].alloc_offset == WP_CONVENTIONAL )
1130+ if (zone_info [i ].alloc_offset == WP_MISSING_DEV )
11101131 continue ;
1132+ if (zone_info [i ].alloc_offset == WP_CONVENTIONAL ) {
1133+ u64 stripe_nr , full_stripe_nr ;
1134+ u64 stripe_offset ;
1135+ int stripe_index ;
1136+
1137+ stripe_nr = last_alloc / map -> stripe_len ;
1138+ stripe_offset = stripe_nr * map -> stripe_len ;
1139+ full_stripe_nr = stripe_nr / (map -> num_stripes / map -> sub_stripes );
1140+ stripe_index = stripe_nr % (map -> num_stripes / map -> sub_stripes );
1141+
1142+ zone_info [i ].alloc_offset = full_stripe_nr * map -> stripe_len ;
1143+ if (stripe_index > (i / map -> sub_stripes ))
1144+ zone_info [i ].alloc_offset += map -> stripe_len ;
1145+ else if (stripe_index == (i / map -> sub_stripes ))
1146+ zone_info [i ].alloc_offset += (last_alloc - stripe_offset );
1147+ }
11111148
11121149 if (test_bit (0 , active ) != test_bit (i , active )) {
11131150 return - EIO ;
@@ -1214,18 +1251,18 @@ int btrfs_load_block_group_zone_info(struct btrfs_fs_info *fs_info,
12141251 ret = btrfs_load_block_group_single (fs_info , cache , & zone_info [0 ], active );
12151252 break ;
12161253 case BTRFS_BLOCK_GROUP_DUP :
1217- ret = btrfs_load_block_group_dup (fs_info , cache , map , zone_info , active );
1254+ ret = btrfs_load_block_group_dup (fs_info , cache , map , zone_info , active , last_alloc );
12181255 break ;
12191256 case BTRFS_BLOCK_GROUP_RAID1 :
12201257 case BTRFS_BLOCK_GROUP_RAID1C3 :
12211258 case BTRFS_BLOCK_GROUP_RAID1C4 :
1222- ret = btrfs_load_block_group_raid1 (fs_info , cache , map , zone_info , active );
1259+ ret = btrfs_load_block_group_raid1 (fs_info , cache , map , zone_info , active , last_alloc );
12231260 break ;
12241261 case BTRFS_BLOCK_GROUP_RAID0 :
1225- ret = btrfs_load_block_group_raid0 (fs_info , cache , map , zone_info , active );
1262+ ret = btrfs_load_block_group_raid0 (fs_info , cache , map , zone_info , active , last_alloc );
12261263 break ;
12271264 case BTRFS_BLOCK_GROUP_RAID10 :
1228- ret = btrfs_load_block_group_raid10 (fs_info , cache , map , zone_info , active );
1265+ ret = btrfs_load_block_group_raid10 (fs_info , cache , map , zone_info , active , last_alloc );
12291266 break ;
12301267 case BTRFS_BLOCK_GROUP_RAID5 :
12311268 case BTRFS_BLOCK_GROUP_RAID6 :
0 commit comments