@@ -981,7 +981,7 @@ static int btrfs_load_block_group_dup(struct btrfs_fs_info *fs_info,
981
981
struct btrfs_block_group * bg ,
982
982
struct map_lookup * map ,
983
983
struct zone_info * zone_info ,
984
- unsigned long * active )
984
+ unsigned long * active , u64 last_alloc )
985
985
{
986
986
if ((map -> type & BTRFS_BLOCK_GROUP_DATA ) && !fs_info -> stripe_root ) {
987
987
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,
1002
1002
zone_info [1 ].physical );
1003
1003
return - EIO ;
1004
1004
}
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
+
1005
1011
if (zone_info [0 ].alloc_offset != zone_info [1 ].alloc_offset ) {
1006
1012
btrfs_err (fs_info ,
1007
1013
"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,
1022
1028
struct btrfs_block_group * bg ,
1023
1029
struct map_lookup * map ,
1024
1030
struct zone_info * zone_info ,
1025
- unsigned long * active )
1031
+ unsigned long * active , u64 last_alloc )
1026
1032
{
1027
1033
int i ;
1028
1034
@@ -1036,9 +1042,10 @@ static int btrfs_load_block_group_raid1(struct btrfs_fs_info *fs_info,
1036
1042
bg -> zone_capacity = min_not_zero (zone_info [0 ].capacity , zone_info [1 ].capacity );
1037
1043
1038
1044
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 )
1041
1046
continue ;
1047
+ if (zone_info [i ].alloc_offset == WP_CONVENTIONAL )
1048
+ zone_info [i ].alloc_offset = last_alloc ;
1042
1049
1043
1050
if (zone_info [0 ].alloc_offset != zone_info [i ].alloc_offset ) {
1044
1051
btrfs_err (fs_info ,
@@ -1066,7 +1073,7 @@ static int btrfs_load_block_group_raid0(struct btrfs_fs_info *fs_info,
1066
1073
struct btrfs_block_group * bg ,
1067
1074
struct map_lookup * map ,
1068
1075
struct zone_info * zone_info ,
1069
- unsigned long * active )
1076
+ unsigned long * active , u64 last_alloc )
1070
1077
{
1071
1078
if ((map -> type & BTRFS_BLOCK_GROUP_DATA ) && !fs_info -> stripe_root ) {
1072
1079
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,
1075
1082
}
1076
1083
1077
1084
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 )
1080
1086
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
+ }
1081
1103
1082
1104
if (test_bit (0 , active ) != test_bit (i , active )) {
1083
1105
return - EIO ;
@@ -1096,7 +1118,7 @@ static int btrfs_load_block_group_raid10(struct btrfs_fs_info *fs_info,
1096
1118
struct btrfs_block_group * bg ,
1097
1119
struct map_lookup * map ,
1098
1120
struct zone_info * zone_info ,
1099
- unsigned long * active )
1121
+ unsigned long * active , u64 last_alloc )
1100
1122
{
1101
1123
if ((map -> type & BTRFS_BLOCK_GROUP_DATA ) && !fs_info -> stripe_root ) {
1102
1124
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,
1105
1127
}
1106
1128
1107
1129
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 )
1110
1131
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
+ }
1111
1148
1112
1149
if (test_bit (0 , active ) != test_bit (i , active )) {
1113
1150
return - EIO ;
@@ -1214,18 +1251,18 @@ int btrfs_load_block_group_zone_info(struct btrfs_fs_info *fs_info,
1214
1251
ret = btrfs_load_block_group_single (fs_info , cache , & zone_info [0 ], active );
1215
1252
break ;
1216
1253
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 );
1218
1255
break ;
1219
1256
case BTRFS_BLOCK_GROUP_RAID1 :
1220
1257
case BTRFS_BLOCK_GROUP_RAID1C3 :
1221
1258
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 );
1223
1260
break ;
1224
1261
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 );
1226
1263
break ;
1227
1264
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 );
1229
1266
break ;
1230
1267
case BTRFS_BLOCK_GROUP_RAID5 :
1231
1268
case BTRFS_BLOCK_GROUP_RAID6 :
0 commit comments