block: add a report_zones method
Dispatching a report zones command through the request queue is a major pain due to the command reply payload rewriting necessary. Given that blkdev_report_zones() is executing everything synchronously, implement report zones as a block device file operation instead, allowing major simplification of the code in many places. sd, null-blk, dm-linear and dm-flakey being the only block device drivers supporting exposing zoned block devices, these drivers are modified to provide the device side implementation of the report_zones() block device file operation. For device mappers, a new report_zones() target type operation is defined so that the upper block layer calls blkdev_report_zones() can be propagated down to the underlying devices of the dm targets. Implementation for this new operation is added to the dm-linear and dm-flakey targets. Reviewed-by: Hannes Reinecke <hare@suse.com> Signed-off-by: Christoph Hellwig <hch@lst.de> [Damien] * Changed method block_device argument to gendisk * Various bug fixes and improvements * Added support for null_blk, dm-linear and dm-flakey. Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com> Reviewed-by: Mike Snitzer <snitzer@redhat.com> Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:

committed by
Jens Axboe

parent
965b652e90
commit
e76239a374
@@ -283,8 +283,6 @@ enum req_opf {
|
||||
REQ_OP_FLUSH = 2,
|
||||
/* discard sectors */
|
||||
REQ_OP_DISCARD = 3,
|
||||
/* get zone information */
|
||||
REQ_OP_ZONE_REPORT = 4,
|
||||
/* securely erase sectors */
|
||||
REQ_OP_SECURE_ERASE = 5,
|
||||
/* seset a zone write pointer */
|
||||
|
@@ -396,11 +396,6 @@ struct queue_limits {
|
||||
|
||||
#ifdef CONFIG_BLK_DEV_ZONED
|
||||
|
||||
struct blk_zone_report_hdr {
|
||||
unsigned int nr_zones;
|
||||
u8 padding[60];
|
||||
};
|
||||
|
||||
extern unsigned int blkdev_nr_zones(struct block_device *bdev);
|
||||
extern int blkdev_report_zones(struct block_device *bdev,
|
||||
sector_t sector, struct blk_zone *zones,
|
||||
@@ -1867,6 +1862,9 @@ struct block_device_operations {
|
||||
int (*getgeo)(struct block_device *, struct hd_geometry *);
|
||||
/* this callback is with swap_lock and sometimes page table lock held */
|
||||
void (*swap_slot_free_notify) (struct block_device *, unsigned long);
|
||||
int (*report_zones)(struct gendisk *, sector_t sector,
|
||||
struct blk_zone *zones, unsigned int *nr_zones,
|
||||
gfp_t gfp_mask);
|
||||
struct module *owner;
|
||||
const struct pr_ops *pr_ops;
|
||||
};
|
||||
|
@@ -92,6 +92,11 @@ typedef int (*dm_message_fn) (struct dm_target *ti, unsigned argc, char **argv,
|
||||
|
||||
typedef int (*dm_prepare_ioctl_fn) (struct dm_target *ti, struct block_device **bdev);
|
||||
|
||||
typedef int (*dm_report_zones_fn) (struct dm_target *ti, sector_t sector,
|
||||
struct blk_zone *zones,
|
||||
unsigned int *nr_zones,
|
||||
gfp_t gfp_mask);
|
||||
|
||||
/*
|
||||
* These iteration functions are typically used to check (and combine)
|
||||
* properties of underlying devices.
|
||||
@@ -180,6 +185,9 @@ struct target_type {
|
||||
dm_status_fn status;
|
||||
dm_message_fn message;
|
||||
dm_prepare_ioctl_fn prepare_ioctl;
|
||||
#ifdef CONFIG_BLK_DEV_ZONED
|
||||
dm_report_zones_fn report_zones;
|
||||
#endif
|
||||
dm_busy_fn busy;
|
||||
dm_iterate_devices_fn iterate_devices;
|
||||
dm_io_hints_fn io_hints;
|
||||
@@ -420,8 +428,8 @@ struct gendisk *dm_disk(struct mapped_device *md);
|
||||
int dm_suspended(struct dm_target *ti);
|
||||
int dm_noflush_suspending(struct dm_target *ti);
|
||||
void dm_accept_partial_bio(struct bio *bio, unsigned n_sectors);
|
||||
void dm_remap_zone_report(struct dm_target *ti, struct bio *bio,
|
||||
sector_t start);
|
||||
void dm_remap_zone_report(struct dm_target *ti, sector_t start,
|
||||
struct blk_zone *zones, unsigned int *nr_zones);
|
||||
union map_info *dm_get_rq_mapinfo(struct request *rq);
|
||||
|
||||
struct queue_limits *dm_get_queue_limits(struct mapped_device *md);
|
||||
|
@@ -82,7 +82,6 @@ TRACE_DEFINE_ENUM(CP_TRIMMED);
|
||||
{ REQ_OP_WRITE, "WRITE" }, \
|
||||
{ REQ_OP_FLUSH, "FLUSH" }, \
|
||||
{ REQ_OP_DISCARD, "DISCARD" }, \
|
||||
{ REQ_OP_ZONE_REPORT, "ZONE_REPORT" }, \
|
||||
{ REQ_OP_SECURE_ERASE, "SECURE_ERASE" }, \
|
||||
{ REQ_OP_ZONE_RESET, "ZONE_RESET" }, \
|
||||
{ REQ_OP_WRITE_SAME, "WRITE_SAME" }, \
|
||||
|
Reference in New Issue
Block a user