Commit 797476b8 authored by Damien Le Moal's avatar Damien Le Moal Committed by Jens Axboe

block: Add 'zoned' queue limit

Add the zoned queue limit to indicate the zoning model of a block device.
Defined values are 0 (BLK_ZONED_NONE) for regular block devices,
1 (BLK_ZONED_HA) for host-aware zone block devices and 2 (BLK_ZONED_HM)
for host-managed zone block devices. The standards defined drive managed
model is not defined here since these block devices do not provide any
command for accessing zone information. Drive managed model devices will
be reported as BLK_ZONED_NONE.

The helper functions blk_queue_zoned_model and bdev_zoned_model return
the zoned limit and the functions blk_queue_is_zoned and bdev_is_zoned
return a boolean for callers to test if a block device is zoned.

The zoned attribute is also exported as a string to applications via
sysfs. BLK_ZONED_NONE shows as "none", BLK_ZONED_HA as "host-aware" and
BLK_ZONED_HM as "host-managed".
Signed-off-by: default avatarDamien Le Moal <>
Reviewed-by: default avatarChristoph Hellwig <>
Reviewed-by: default avatarMartin K. Petersen <>
Reviewed-by: default avatarShaun Tancheff <>
Tested-by: default avatarShaun Tancheff <>
Signed-off-by: default avatarJens Axboe <>
parent 14155caf
......@@ -235,3 +235,19 @@ Description:
write_same_max_bytes is 0, write same is not supported
by the device.
What: /sys/block/<disk>/queue/zoned
Date: September 2016
Contact: Damien Le Moal <>
zoned indicates if the device is a zoned block device
and the zone model of the device if it is indeed zoned.
The possible values indicated by zoned are "none" for
regular block devices and "host-aware" or "host-managed"
for zoned block devices. The characteristics of
host-aware and host-managed zoned block devices are
described in the ZBC (Zoned Block Commands) and ZAC
(Zoned Device ATA Command Set) standards. These standards
also define the "drive-managed" zone model. However,
since drive-managed zoned block devices do not support
zone commands, they will be treated as regular block
devices and zoned will report "none".
......@@ -107,6 +107,7 @@ void blk_set_default_limits(struct queue_limits *lim)
lim->io_opt = 0;
lim->misaligned = 0;
lim->cluster = 1;
lim->zoned = BLK_ZONED_NONE;
......@@ -257,6 +257,18 @@ QUEUE_SYSFS_BIT_FNS(random, ADD_RANDOM, 0);
static ssize_t queue_zoned_show(struct request_queue *q, char *page)
switch (blk_queue_zoned_model(q)) {
return sprintf(page, "host-aware\n");
return sprintf(page, "host-managed\n");
return sprintf(page, "none\n");
static ssize_t queue_nomerges_show(struct request_queue *q, char *page)
return queue_var_show((blk_queue_nomerges(q) << 1) |
......@@ -485,6 +497,11 @@ static struct queue_sysfs_entry queue_nonrot_entry = {
.store = queue_store_nonrot,
static struct queue_sysfs_entry queue_zoned_entry = {
.attr = {.name = "zoned", .mode = S_IRUGO },
.show = queue_zoned_show,
static struct queue_sysfs_entry queue_nomerges_entry = {
.attr = {.name = "nomerges", .mode = S_IRUGO | S_IWUSR },
.show = queue_nomerges_show,
......@@ -546,6 +563,7 @@ static struct attribute *default_attrs[] = {
......@@ -261,6 +261,15 @@ struct blk_queue_tag {
#define BLK_SCSI_MAX_CMDS (256)
#define BLK_SCSI_CMD_PER_LONG (BLK_SCSI_MAX_CMDS / (sizeof(long) * 8))
* Zoned block device models (zoned limit).
enum blk_zoned_model {
BLK_ZONED_NONE, /* Regular block device */
BLK_ZONED_HA, /* Host-aware zoned block device */
BLK_ZONED_HM, /* Host-managed zoned block device */
struct queue_limits {
unsigned long bounce_pfn;
unsigned long seg_boundary_mask;
......@@ -290,6 +299,7 @@ struct queue_limits {
unsigned char cluster;
unsigned char discard_zeroes_data;
unsigned char raid_partial_stripes_expensive;
enum blk_zoned_model zoned;
struct request_queue {
......@@ -627,6 +637,23 @@ static inline unsigned int blk_queue_cluster(struct request_queue *q)
return q->limits.cluster;
static inline enum blk_zoned_model
blk_queue_zoned_model(struct request_queue *q)
return q->limits.zoned;
static inline bool blk_queue_is_zoned(struct request_queue *q)
switch (blk_queue_zoned_model(q)) {
return true;
return false;
* We regard a request as sync, if either a read or a sync write
......@@ -1354,6 +1381,26 @@ static inline unsigned int bdev_write_same(struct block_device *bdev)
return 0;
static inline enum blk_zoned_model bdev_zoned_model(struct block_device *bdev)
struct request_queue *q = bdev_get_queue(bdev);
if (q)
return blk_queue_zoned_model(q);
static inline bool bdev_is_zoned(struct block_device *bdev)
struct request_queue *q = bdev_get_queue(bdev);
if (q)
return blk_queue_is_zoned(q);
return false;
static inline int queue_dma_alignment(struct request_queue *q)
return q ? q->dma_alignment : 511;
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment