diff options
| -rw-r--r-- | drivers/md/dm.c | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 20f7e4ef5342..45abb54037fc 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
| @@ -1155,12 +1155,14 @@ void dm_accept_partial_bio(struct bio *bio, unsigned n_sectors) | |||
| 1155 | EXPORT_SYMBOL_GPL(dm_accept_partial_bio); | 1155 | EXPORT_SYMBOL_GPL(dm_accept_partial_bio); |
| 1156 | 1156 | ||
| 1157 | /* | 1157 | /* |
| 1158 | * The zone descriptors obtained with a zone report indicate | 1158 | * The zone descriptors obtained with a zone report indicate zone positions |
| 1159 | * zone positions within the target device. The zone descriptors | 1159 | * within the target backing device, regardless of that device is a partition |
| 1160 | * must be remapped to match their position within the dm device. | 1160 | * and regardless of the target mapping start sector on the device or partition. |
| 1161 | * A target may call dm_remap_zone_report after completion of a | 1161 | * The zone descriptors start sector and write pointer position must be adjusted |
| 1162 | * REQ_OP_ZONE_REPORT bio to remap the zone descriptors obtained | 1162 | * to match their relative position within the dm device. |
| 1163 | * from the target device mapping to the dm device. | 1163 | * A target may call dm_remap_zone_report() after completion of a |
| 1164 | * REQ_OP_ZONE_REPORT bio to remap the zone descriptors obtained from the | ||
| 1165 | * backing device. | ||
| 1164 | */ | 1166 | */ |
| 1165 | void dm_remap_zone_report(struct dm_target *ti, struct bio *bio, sector_t start) | 1167 | void dm_remap_zone_report(struct dm_target *ti, struct bio *bio, sector_t start) |
| 1166 | { | 1168 | { |
| @@ -1171,6 +1173,7 @@ void dm_remap_zone_report(struct dm_target *ti, struct bio *bio, sector_t start) | |||
| 1171 | struct blk_zone *zone; | 1173 | struct blk_zone *zone; |
| 1172 | unsigned int nr_rep = 0; | 1174 | unsigned int nr_rep = 0; |
| 1173 | unsigned int ofst; | 1175 | unsigned int ofst; |
| 1176 | sector_t part_offset; | ||
| 1174 | struct bio_vec bvec; | 1177 | struct bio_vec bvec; |
| 1175 | struct bvec_iter iter; | 1178 | struct bvec_iter iter; |
| 1176 | void *addr; | 1179 | void *addr; |
| @@ -1179,6 +1182,15 @@ void dm_remap_zone_report(struct dm_target *ti, struct bio *bio, sector_t start) | |||
| 1179 | return; | 1182 | return; |
| 1180 | 1183 | ||
| 1181 | /* | 1184 | /* |
| 1185 | * bio sector was incremented by the request size on completion. Taking | ||
| 1186 | * into account the original request sector, the target start offset on | ||
| 1187 | * the backing device and the target mapping offset (ti->begin), the | ||
| 1188 | * start sector of the backing device. The partition offset is always 0 | ||
| 1189 | * if the target uses a whole device. | ||
| 1190 | */ | ||
| 1191 | part_offset = bio->bi_iter.bi_sector + ti->begin - (start + bio_end_sector(report_bio)); | ||
| 1192 | |||
| 1193 | /* | ||
| 1182 | * Remap the start sector of the reported zones. For sequential zones, | 1194 | * Remap the start sector of the reported zones. For sequential zones, |
| 1183 | * also remap the write pointer position. | 1195 | * also remap the write pointer position. |
| 1184 | */ | 1196 | */ |
| @@ -1195,6 +1207,7 @@ void dm_remap_zone_report(struct dm_target *ti, struct bio *bio, sector_t start) | |||
| 1195 | /* Set zones start sector */ | 1207 | /* Set zones start sector */ |
| 1196 | while (hdr->nr_zones && ofst < bvec.bv_len) { | 1208 | while (hdr->nr_zones && ofst < bvec.bv_len) { |
| 1197 | zone = addr + ofst; | 1209 | zone = addr + ofst; |
| 1210 | zone->start -= part_offset; | ||
| 1198 | if (zone->start >= start + ti->len) { | 1211 | if (zone->start >= start + ti->len) { |
| 1199 | hdr->nr_zones = 0; | 1212 | hdr->nr_zones = 0; |
| 1200 | break; | 1213 | break; |
| @@ -1206,7 +1219,7 @@ void dm_remap_zone_report(struct dm_target *ti, struct bio *bio, sector_t start) | |||
| 1206 | else if (zone->cond == BLK_ZONE_COND_EMPTY) | 1219 | else if (zone->cond == BLK_ZONE_COND_EMPTY) |
| 1207 | zone->wp = zone->start; | 1220 | zone->wp = zone->start; |
| 1208 | else | 1221 | else |
| 1209 | zone->wp = zone->wp + ti->begin - start; | 1222 | zone->wp = zone->wp + ti->begin - start - part_offset; |
| 1210 | } | 1223 | } |
| 1211 | ofst += sizeof(struct blk_zone); | 1224 | ofst += sizeof(struct blk_zone); |
| 1212 | hdr->nr_zones--; | 1225 | hdr->nr_zones--; |
