summaryrefslogtreecommitdiffstats
path: root/drivers/block/null_blk_zoned.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-11-25 20:22:37 +0100
committerLinus Torvalds <torvalds@linux-foundation.org>2019-11-25 20:22:37 +0100
commit464a47f45d2ae2db859f0e7c128b5f01aff19a53 (patch)
tree81862e9d67614d5283dfb3d45d86b74c548f0386 /drivers/block/null_blk_zoned.c
parentMerge tag 'for-5.5/drivers-post-20191122' of git://git.kernel.dk/linux-block (diff)
parentscsi: sd_zbc: Remove set but not used variable 'buflen' (diff)
downloadlinux-464a47f45d2ae2db859f0e7c128b5f01aff19a53.tar.xz
linux-464a47f45d2ae2db859f0e7c128b5f01aff19a53.zip
Merge tag 'for-5.5/zoned-20191122' of git://git.kernel.dk/linux-block
Pull zoned block device update from Jens Axboe: "Enhancements and improvements to the zoned device support" * tag 'for-5.5/zoned-20191122' of git://git.kernel.dk/linux-block: scsi: sd_zbc: Remove set but not used variable 'buflen' block: rework zone reporting scsi: sd_zbc: Cleanup sd_zbc_alloc_report_buffer() null_blk: Add zone_nr_conv to features null_blk: clean up report zones null_blk: clean up the block device operations block: Remove partition support for zoned block devices block: Simplify report zones execution block: cleanup the !zoned case in blk_revalidate_disk_zones block: Enhance blk_revalidate_disk_zones()
Diffstat (limited to 'drivers/block/null_blk_zoned.c')
-rw-r--r--drivers/block/null_blk_zoned.c33
1 files changed, 23 insertions, 10 deletions
diff --git a/drivers/block/null_blk_zoned.c b/drivers/block/null_blk_zoned.c
index 02f41a3bc4cb..d4d88b581822 100644
--- a/drivers/block/null_blk_zoned.c
+++ b/drivers/block/null_blk_zoned.c
@@ -66,22 +66,35 @@ void null_zone_exit(struct nullb_device *dev)
kvfree(dev->zones);
}
-int null_zone_report(struct gendisk *disk, sector_t sector,
- struct blk_zone *zones, unsigned int *nr_zones)
+int null_report_zones(struct gendisk *disk, sector_t sector,
+ unsigned int nr_zones, report_zones_cb cb, void *data)
{
struct nullb *nullb = disk->private_data;
struct nullb_device *dev = nullb->dev;
- unsigned int zno, nrz = 0;
+ unsigned int first_zone, i;
+ struct blk_zone zone;
+ int error;
- zno = null_zone_no(dev, sector);
- if (zno < dev->nr_zones) {
- nrz = min_t(unsigned int, *nr_zones, dev->nr_zones - zno);
- memcpy(zones, &dev->zones[zno], nrz * sizeof(struct blk_zone));
- }
+ first_zone = null_zone_no(dev, sector);
+ if (first_zone >= dev->nr_zones)
+ return 0;
- *nr_zones = nrz;
+ nr_zones = min(nr_zones, dev->nr_zones - first_zone);
+ for (i = 0; i < nr_zones; i++) {
+ /*
+ * Stacked DM target drivers will remap the zone information by
+ * modifying the zone information passed to the report callback.
+ * So use a local copy to avoid corruption of the device zone
+ * array.
+ */
+ memcpy(&zone, &dev->zones[first_zone + i],
+ sizeof(struct blk_zone));
+ error = cb(&zone, i, data);
+ if (error)
+ return error;
+ }
- return 0;
+ return nr_zones;
}
size_t null_zone_valid_read_len(struct nullb *nullb,