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)
|
||||
{
|
||||
struct nullb_device *dev = nullb->dev;
|
||||
struct request_queue *q = nullb->q;
|
||||
|
||||
if (queue_is_mq(q))
|
||||
return blk_revalidate_disk_zones(nullb->disk, NULL);
|
||||
if (queue_is_mq(q)) {
|
||||
int ret = blk_revalidate_disk_zones(nullb->disk, NULL);
|
||||
|
||||
blk_queue_chunk_sectors(q, nullb->dev->zone_size_sects);
|
||||
q->nr_zones = blkdev_nr_zones(nullb->disk);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
blk_queue_chunk_sectors(q, dev->zone_size_sects);
|
||||
q->nr_zones = blkdev_nr_zones(nullb->disk);
|
||||
}
|
||||
|
||||
blk_queue_max_zone_append_sectors(q, dev->zone_size_sects);
|
||||
|
||||
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,
|
||||
unsigned int nr_sectors)
|
||||
unsigned int nr_sectors, bool append)
|
||||
{
|
||||
struct nullb_device *dev = cmd->nq->dev;
|
||||
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_EXP_OPEN:
|
||||
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;
|
||||
}
|
||||
|
||||
if (zone->cond != BLK_ZONE_COND_EXP_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) {
|
||||
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_ALL:
|
||||
case REQ_OP_ZONE_OPEN:
|
||||
|
|
Loading…
Reference in New Issue