null_blk: Support REQ_OP_ZONE_APPEND
Support REQ_OP_ZONE_APPEND requests for null_blk devices with zoned mode enabled. Use the internally tracked zone write pointer position as the actual write position and return it using the command request __sector field in the case of an mq device and using the command BIO sector in the case of a BIO device. Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com> Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com> Reviewed-by: Hannes Reinecke <hare@suse.de> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
5795eb4430
commit
e0489ed5da
@ -70,13 +70,20 @@ int null_init_zoned_dev(struct nullb_device *dev, struct request_queue *q)
|
|||||||
|
|
||||||
int null_register_zoned_dev(struct nullb *nullb)
|
int null_register_zoned_dev(struct nullb *nullb)
|
||||||
{
|
{
|
||||||
|
struct nullb_device *dev = nullb->dev;
|
||||||
struct request_queue *q = nullb->q;
|
struct request_queue *q = nullb->q;
|
||||||
|
|
||||||
if (queue_is_mq(q))
|
if (queue_is_mq(q)) {
|
||||||
return blk_revalidate_disk_zones(nullb->disk, NULL);
|
int ret = blk_revalidate_disk_zones(nullb->disk, NULL);
|
||||||
|
|
||||||
blk_queue_chunk_sectors(q, nullb->dev->zone_size_sects);
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
} else {
|
||||||
|
blk_queue_chunk_sectors(q, dev->zone_size_sects);
|
||||||
q->nr_zones = blkdev_nr_zones(nullb->disk);
|
q->nr_zones = blkdev_nr_zones(nullb->disk);
|
||||||
|
}
|
||||||
|
|
||||||
|
blk_queue_max_zone_append_sectors(q, dev->zone_size_sects);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -138,7 +145,7 @@ size_t null_zone_valid_read_len(struct nullb *nullb,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static blk_status_t null_zone_write(struct nullb_cmd *cmd, sector_t sector,
|
static blk_status_t null_zone_write(struct nullb_cmd *cmd, sector_t sector,
|
||||||
unsigned int nr_sectors)
|
unsigned int nr_sectors, bool append)
|
||||||
{
|
{
|
||||||
struct nullb_device *dev = cmd->nq->dev;
|
struct nullb_device *dev = cmd->nq->dev;
|
||||||
unsigned int zno = null_zone_no(dev, sector);
|
unsigned int zno = null_zone_no(dev, sector);
|
||||||
@ -158,9 +165,21 @@ static blk_status_t null_zone_write(struct nullb_cmd *cmd, sector_t sector,
|
|||||||
case BLK_ZONE_COND_IMP_OPEN:
|
case BLK_ZONE_COND_IMP_OPEN:
|
||||||
case BLK_ZONE_COND_EXP_OPEN:
|
case BLK_ZONE_COND_EXP_OPEN:
|
||||||
case BLK_ZONE_COND_CLOSED:
|
case BLK_ZONE_COND_CLOSED:
|
||||||
/* Writes must be at the write pointer position */
|
/*
|
||||||
if (sector != zone->wp)
|
* Regular writes must be at the write pointer position.
|
||||||
|
* Zone append writes are automatically issued at the write
|
||||||
|
* pointer and the position returned using the request or BIO
|
||||||
|
* sector.
|
||||||
|
*/
|
||||||
|
if (append) {
|
||||||
|
sector = zone->wp;
|
||||||
|
if (cmd->bio)
|
||||||
|
cmd->bio->bi_iter.bi_sector = sector;
|
||||||
|
else
|
||||||
|
cmd->rq->__sector = sector;
|
||||||
|
} else if (sector != zone->wp) {
|
||||||
return BLK_STS_IOERR;
|
return BLK_STS_IOERR;
|
||||||
|
}
|
||||||
|
|
||||||
if (zone->cond != BLK_ZONE_COND_EXP_OPEN)
|
if (zone->cond != BLK_ZONE_COND_EXP_OPEN)
|
||||||
zone->cond = BLK_ZONE_COND_IMP_OPEN;
|
zone->cond = BLK_ZONE_COND_IMP_OPEN;
|
||||||
@ -242,7 +261,9 @@ blk_status_t null_process_zoned_cmd(struct nullb_cmd *cmd, enum req_opf op,
|
|||||||
{
|
{
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case REQ_OP_WRITE:
|
case REQ_OP_WRITE:
|
||||||
return null_zone_write(cmd, sector, nr_sectors);
|
return null_zone_write(cmd, sector, nr_sectors, false);
|
||||||
|
case REQ_OP_ZONE_APPEND:
|
||||||
|
return null_zone_write(cmd, sector, nr_sectors, true);
|
||||||
case REQ_OP_ZONE_RESET:
|
case REQ_OP_ZONE_RESET:
|
||||||
case REQ_OP_ZONE_RESET_ALL:
|
case REQ_OP_ZONE_RESET_ALL:
|
||||||
case REQ_OP_ZONE_OPEN:
|
case REQ_OP_ZONE_OPEN:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user