null_blk: Add conventional zone configuration for zoned support
Allow the creation of conventional zones by adding the zone_nr_conv configuration attribute. This new attribute is used only for zoned devices and indicates the number of conventional zones to create. The default value is 0. Since host-managed zoned block devices must always have at least one sequential zone, if the value of zone_nr_conv is larger than or equal to the total number of zones of the device nr_zones, zone_nr_conv is automatically changed to nr_zones - 1. Reviewed-by: Matias Bjorling <matias.bjorling@wdc.com> Reviewed-by: Damien Le Moal <damien.lemoal@wdc.com> Signed-off-by: Masato Suzuki <masato.suzuki@wdc.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
85758777c2
commit
ea2c18e104
|
@ -49,6 +49,7 @@ struct nullb_device {
|
||||||
unsigned long completion_nsec; /* time in ns to complete a request */
|
unsigned long completion_nsec; /* time in ns to complete a request */
|
||||||
unsigned long cache_size; /* disk cache size in MB */
|
unsigned long cache_size; /* disk cache size in MB */
|
||||||
unsigned long zone_size; /* zone size in MB if device is zoned */
|
unsigned long zone_size; /* zone size in MB if device is zoned */
|
||||||
|
unsigned int zone_nr_conv; /* number of conventional zones */
|
||||||
unsigned int submit_queues; /* number of submission queues */
|
unsigned int submit_queues; /* number of submission queues */
|
||||||
unsigned int home_node; /* home node for the device */
|
unsigned int home_node; /* home node for the device */
|
||||||
unsigned int queue_mode; /* block interface */
|
unsigned int queue_mode; /* block interface */
|
||||||
|
|
|
@ -188,6 +188,10 @@ static unsigned long g_zone_size = 256;
|
||||||
module_param_named(zone_size, g_zone_size, ulong, S_IRUGO);
|
module_param_named(zone_size, g_zone_size, ulong, S_IRUGO);
|
||||||
MODULE_PARM_DESC(zone_size, "Zone size in MB when block device is zoned. Must be power-of-two: Default: 256");
|
MODULE_PARM_DESC(zone_size, "Zone size in MB when block device is zoned. Must be power-of-two: Default: 256");
|
||||||
|
|
||||||
|
static unsigned int g_zone_nr_conv;
|
||||||
|
module_param_named(zone_nr_conv, g_zone_nr_conv, uint, 0444);
|
||||||
|
MODULE_PARM_DESC(zone_nr_conv, "Number of conventional zones when block device is zoned. Default: 0");
|
||||||
|
|
||||||
static struct nullb_device *null_alloc_dev(void);
|
static struct nullb_device *null_alloc_dev(void);
|
||||||
static void null_free_dev(struct nullb_device *dev);
|
static void null_free_dev(struct nullb_device *dev);
|
||||||
static void null_del_dev(struct nullb *nullb);
|
static void null_del_dev(struct nullb *nullb);
|
||||||
|
@ -293,6 +297,7 @@ NULLB_DEVICE_ATTR(mbps, uint);
|
||||||
NULLB_DEVICE_ATTR(cache_size, ulong);
|
NULLB_DEVICE_ATTR(cache_size, ulong);
|
||||||
NULLB_DEVICE_ATTR(zoned, bool);
|
NULLB_DEVICE_ATTR(zoned, bool);
|
||||||
NULLB_DEVICE_ATTR(zone_size, ulong);
|
NULLB_DEVICE_ATTR(zone_size, ulong);
|
||||||
|
NULLB_DEVICE_ATTR(zone_nr_conv, uint);
|
||||||
|
|
||||||
static ssize_t nullb_device_power_show(struct config_item *item, char *page)
|
static ssize_t nullb_device_power_show(struct config_item *item, char *page)
|
||||||
{
|
{
|
||||||
|
@ -407,6 +412,7 @@ static struct configfs_attribute *nullb_device_attrs[] = {
|
||||||
&nullb_device_attr_badblocks,
|
&nullb_device_attr_badblocks,
|
||||||
&nullb_device_attr_zoned,
|
&nullb_device_attr_zoned,
|
||||||
&nullb_device_attr_zone_size,
|
&nullb_device_attr_zone_size,
|
||||||
|
&nullb_device_attr_zone_nr_conv,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -520,6 +526,7 @@ static struct nullb_device *null_alloc_dev(void)
|
||||||
dev->use_per_node_hctx = g_use_per_node_hctx;
|
dev->use_per_node_hctx = g_use_per_node_hctx;
|
||||||
dev->zoned = g_zoned;
|
dev->zoned = g_zoned;
|
||||||
dev->zone_size = g_zone_size;
|
dev->zone_size = g_zone_size;
|
||||||
|
dev->zone_nr_conv = g_zone_nr_conv;
|
||||||
return dev;
|
return dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,25 @@ int null_zone_init(struct nullb_device *dev)
|
||||||
if (!dev->zones)
|
if (!dev->zones)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
for (i = 0; i < dev->nr_zones; i++) {
|
if (dev->zone_nr_conv >= dev->nr_zones) {
|
||||||
|
dev->zone_nr_conv = dev->nr_zones - 1;
|
||||||
|
pr_info("null_blk: changed the number of conventional zones to %u",
|
||||||
|
dev->zone_nr_conv);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < dev->zone_nr_conv; i++) {
|
||||||
|
struct blk_zone *zone = &dev->zones[i];
|
||||||
|
|
||||||
|
zone->start = sector;
|
||||||
|
zone->len = dev->zone_size_sects;
|
||||||
|
zone->wp = zone->start + zone->len;
|
||||||
|
zone->type = BLK_ZONE_TYPE_CONVENTIONAL;
|
||||||
|
zone->cond = BLK_ZONE_COND_NOT_WP;
|
||||||
|
|
||||||
|
sector += dev->zone_size_sects;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = dev->zone_nr_conv; i < dev->nr_zones; i++) {
|
||||||
struct blk_zone *zone = &dev->zones[i];
|
struct blk_zone *zone = &dev->zones[i];
|
||||||
|
|
||||||
zone->start = zone->wp = sector;
|
zone->start = zone->wp = sector;
|
||||||
|
@ -98,6 +116,8 @@ void null_zone_write(struct nullb_cmd *cmd, sector_t sector,
|
||||||
if (zone->wp == zone->start + zone->len)
|
if (zone->wp == zone->start + zone->len)
|
||||||
zone->cond = BLK_ZONE_COND_FULL;
|
zone->cond = BLK_ZONE_COND_FULL;
|
||||||
break;
|
break;
|
||||||
|
case BLK_ZONE_COND_NOT_WP:
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
/* Invalid zone condition */
|
/* Invalid zone condition */
|
||||||
cmd->error = BLK_STS_IOERR;
|
cmd->error = BLK_STS_IOERR;
|
||||||
|
@ -111,6 +131,11 @@ void null_zone_reset(struct nullb_cmd *cmd, sector_t sector)
|
||||||
unsigned int zno = null_zone_no(dev, sector);
|
unsigned int zno = null_zone_no(dev, sector);
|
||||||
struct blk_zone *zone = &dev->zones[zno];
|
struct blk_zone *zone = &dev->zones[zno];
|
||||||
|
|
||||||
|
if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL) {
|
||||||
|
cmd->error = BLK_STS_IOERR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
zone->cond = BLK_ZONE_COND_EMPTY;
|
zone->cond = BLK_ZONE_COND_EMPTY;
|
||||||
zone->wp = zone->start;
|
zone->wp = zone->start;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue