Commit b8db9e69 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'for-4.19/dm-fixes-3' of...

Merge tag 'for-4.19/dm-fixes-3' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm

Mike writes:
  "device mapper fixes for 4.19 final

   - Fix a DM cache module init error path bug that doesn't properly
     cleanup a KMEM_CACHE if target registration fails.

   - Two stable@ fixes for DM zoned target; 4.20 will have changes that
     eliminate this code entirely but <= 4.19 needs these changes."

* tag 'for-4.19/dm-fixes-3' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm:
  dm linear: eliminate linear_end_io call if CONFIG_DM_ZONED disabled
  dm: fix report zone remapping to account for partition offset
  dm cache: destroy migration_cache if cache target registration failed
parents 588b5938 beb9caac
...@@ -3484,14 +3484,13 @@ static int __init dm_cache_init(void) ...@@ -3484,14 +3484,13 @@ static int __init dm_cache_init(void)
int r; int r;
migration_cache = KMEM_CACHE(dm_cache_migration, 0); migration_cache = KMEM_CACHE(dm_cache_migration, 0);
if (!migration_cache) { if (!migration_cache)
dm_unregister_target(&cache_target);
return -ENOMEM; return -ENOMEM;
}
r = dm_register_target(&cache_target); r = dm_register_target(&cache_target);
if (r) { if (r) {
DMERR("cache target registration failed: %d", r); DMERR("cache target registration failed: %d", r);
kmem_cache_destroy(migration_cache);
return r; return r;
} }
......
...@@ -102,6 +102,7 @@ static int linear_map(struct dm_target *ti, struct bio *bio) ...@@ -102,6 +102,7 @@ static int linear_map(struct dm_target *ti, struct bio *bio)
return DM_MAPIO_REMAPPED; return DM_MAPIO_REMAPPED;
} }
#ifdef CONFIG_DM_ZONED
static int linear_end_io(struct dm_target *ti, struct bio *bio, static int linear_end_io(struct dm_target *ti, struct bio *bio,
blk_status_t *error) blk_status_t *error)
{ {
...@@ -112,6 +113,7 @@ static int linear_end_io(struct dm_target *ti, struct bio *bio, ...@@ -112,6 +113,7 @@ static int linear_end_io(struct dm_target *ti, struct bio *bio,
return DM_ENDIO_DONE; return DM_ENDIO_DONE;
} }
#endif
static void linear_status(struct dm_target *ti, status_type_t type, static void linear_status(struct dm_target *ti, status_type_t type,
unsigned status_flags, char *result, unsigned maxlen) unsigned status_flags, char *result, unsigned maxlen)
...@@ -208,12 +210,16 @@ static size_t linear_dax_copy_to_iter(struct dm_target *ti, pgoff_t pgoff, ...@@ -208,12 +210,16 @@ static size_t linear_dax_copy_to_iter(struct dm_target *ti, pgoff_t pgoff,
static struct target_type linear_target = { static struct target_type linear_target = {
.name = "linear", .name = "linear",
.version = {1, 4, 0}, .version = {1, 4, 0},
#ifdef CONFIG_DM_ZONED
.end_io = linear_end_io,
.features = DM_TARGET_PASSES_INTEGRITY | DM_TARGET_ZONED_HM, .features = DM_TARGET_PASSES_INTEGRITY | DM_TARGET_ZONED_HM,
#else
.features = DM_TARGET_PASSES_INTEGRITY,
#endif
.module = THIS_MODULE, .module = THIS_MODULE,
.ctr = linear_ctr, .ctr = linear_ctr,
.dtr = linear_dtr, .dtr = linear_dtr,
.map = linear_map, .map = linear_map,
.end_io = linear_end_io,
.status = linear_status, .status = linear_status,
.prepare_ioctl = linear_prepare_ioctl, .prepare_ioctl = linear_prepare_ioctl,
.iterate_devices = linear_iterate_devices, .iterate_devices = linear_iterate_devices,
......
...@@ -1155,12 +1155,14 @@ void dm_accept_partial_bio(struct bio *bio, unsigned n_sectors) ...@@ -1155,12 +1155,14 @@ void dm_accept_partial_bio(struct bio *bio, unsigned n_sectors)
EXPORT_SYMBOL_GPL(dm_accept_partial_bio); EXPORT_SYMBOL_GPL(dm_accept_partial_bio);
/* /*
* The zone descriptors obtained with a zone report indicate * The zone descriptors obtained with a zone report indicate zone positions
* zone positions within the target device. The zone descriptors * within the target backing device, regardless of that device is a partition
* must be remapped to match their position within the dm device. * and regardless of the target mapping start sector on the device or partition.
* A target may call dm_remap_zone_report after completion of a * The zone descriptors start sector and write pointer position must be adjusted
* REQ_OP_ZONE_REPORT bio to remap the zone descriptors obtained * to match their relative position within the dm device.
* from the target device mapping to the dm device. * A target may call dm_remap_zone_report() after completion of a
* REQ_OP_ZONE_REPORT bio to remap the zone descriptors obtained from the
* backing device.
*/ */
void dm_remap_zone_report(struct dm_target *ti, struct bio *bio, sector_t start) void dm_remap_zone_report(struct dm_target *ti, struct bio *bio, sector_t start)
{ {
...@@ -1171,6 +1173,7 @@ void dm_remap_zone_report(struct dm_target *ti, struct bio *bio, sector_t start) ...@@ -1171,6 +1173,7 @@ void dm_remap_zone_report(struct dm_target *ti, struct bio *bio, sector_t start)
struct blk_zone *zone; struct blk_zone *zone;
unsigned int nr_rep = 0; unsigned int nr_rep = 0;
unsigned int ofst; unsigned int ofst;
sector_t part_offset;
struct bio_vec bvec; struct bio_vec bvec;
struct bvec_iter iter; struct bvec_iter iter;
void *addr; void *addr;
...@@ -1178,6 +1181,15 @@ void dm_remap_zone_report(struct dm_target *ti, struct bio *bio, sector_t start) ...@@ -1178,6 +1181,15 @@ void dm_remap_zone_report(struct dm_target *ti, struct bio *bio, sector_t start)
if (bio->bi_status) if (bio->bi_status)
return; return;
/*
* bio sector was incremented by the request size on completion. Taking
* into account the original request sector, the target start offset on
* the backing device and the target mapping offset (ti->begin), the
* start sector of the backing device. The partition offset is always 0
* if the target uses a whole device.
*/
part_offset = bio->bi_iter.bi_sector + ti->begin - (start + bio_end_sector(report_bio));
/* /*
* Remap the start sector of the reported zones. For sequential zones, * Remap the start sector of the reported zones. For sequential zones,
* also remap the write pointer position. * also remap the write pointer position.
...@@ -1195,6 +1207,7 @@ void dm_remap_zone_report(struct dm_target *ti, struct bio *bio, sector_t start) ...@@ -1195,6 +1207,7 @@ void dm_remap_zone_report(struct dm_target *ti, struct bio *bio, sector_t start)
/* Set zones start sector */ /* Set zones start sector */
while (hdr->nr_zones && ofst < bvec.bv_len) { while (hdr->nr_zones && ofst < bvec.bv_len) {
zone = addr + ofst; zone = addr + ofst;
zone->start -= part_offset;
if (zone->start >= start + ti->len) { if (zone->start >= start + ti->len) {
hdr->nr_zones = 0; hdr->nr_zones = 0;
break; break;
...@@ -1206,7 +1219,7 @@ void dm_remap_zone_report(struct dm_target *ti, struct bio *bio, sector_t start) ...@@ -1206,7 +1219,7 @@ void dm_remap_zone_report(struct dm_target *ti, struct bio *bio, sector_t start)
else if (zone->cond == BLK_ZONE_COND_EMPTY) else if (zone->cond == BLK_ZONE_COND_EMPTY)
zone->wp = zone->start; zone->wp = zone->start;
else else
zone->wp = zone->wp + ti->begin - start; zone->wp = zone->wp + ti->begin - start - part_offset;
} }
ofst += sizeof(struct blk_zone); ofst += sizeof(struct blk_zone);
hdr->nr_zones--; hdr->nr_zones--;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment