History

block: introduce zone_write_granularity limit

Per ZBC and ZAC specifications, host-managed SMR hard-disks mandate that all writes into sequential write required zones be aligned to the device physical block size. However, NVMe ZNS does not have this constraint and allows write operations into sequential zones to be aligned to the device logical block size. This inconsistency does not help with software portability across device types. To solve this, introduce the zone_write_granularity queue limit to indicate the alignment constraint, in bytes, of write operations into zones of a zoned block device. This new limit is exported as a read-only sysfs queue attribute and the helper blk_queue_zone_write_granularity() introduced for drivers to set this limit. The function blk_queue_set_zoned() is modified to set this new limit to the device logical block size by default. NVMe ZNS devices as well as zoned nullb devices use this default value as is. The scsi disk driver is modified to execute the blk_queue_zone_write_granularity() helper to set the zone write granularity of host-managed SMR disks to the disk physical block size. The accessor functions queue_zone_write_granularity() and bdev_zone_write_granularity() are also introduced.

Damien Le Moal committed 5 years ago

Commit a805a4f1 parent eafc63a5 files · +74 −1Browse files

Showing the changes to include/linux/blkdev.h (1 of 5 files). Show all

Unified · Split

include/linux/blkdev.h+15−0
@@ -337,6 +337,7 @@ struct queue_limits { · 336 unmodified lines
337337 unsigned int max_zone_append_sectors;
338338 unsigned int discard_granularity;
339339 unsigned int discard_alignment;
340+ unsigned int zone_write_granularity;
340341
341342 unsigned short max_segments;
342343 unsigned short max_integrity_segments;
@@ -1160,6 +1161,8 @@ extern void blk_queue_logical_block_size(struct request_queue *, unsigned int); · 817 unmodified lines
11601161 extern void blk_queue_max_zone_append_sectors(struct request_queue *q,
11611162 unsigned int max_zone_append_sectors);
11621163 extern void blk_queue_physical_block_size(struct request_queue *, unsigned int);
1164+void blk_queue_zone_write_granularity(struct request_queue *q,
1165+ unsigned int size);
11631166 extern void blk_queue_alignment_offset(struct request_queue *q,
11641167 unsigned int alignment);
11651168 void blk_queue_update_readahead(struct request_queue *q);
@@ -1473,6 +1476,18 @@ static inline int bdev_io_opt(struct block_device *bdev) · 307 unmodified lines
14731476 return queue_io_opt(bdev_get_queue(bdev));
14741477 }
14751478
1479+static inline unsigned int
1480+queue_zone_write_granularity(const struct request_queue *q)
1481+{
1482+ return q->limits.zone_write_granularity;
1483+}
1484+
1485+static inline unsigned int
1486+bdev_zone_write_granularity(struct block_device *bdev)
1487+{
1488+ return queue_zone_write_granularity(bdev_get_queue(bdev));
1489+}
1490+
14761491 static inline int queue_alignment_offset(const struct request_queue *q)
14771492 {
14781493 if (q->limits.misaligned)