Message ID | 20200428104605.8143-10-johannes.thumshirn@wdc.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Introduce Zone Append for writing to zoned block devices | expand |
On 4/28/20 12:46 PM, Johannes Thumshirn wrote: > From: Damien Le Moal <damien.lemoal@wdc.com> > > 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. > > Reviewed-by: Christoph Hellwig <hch@lst.de> > Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com> > Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> > --- > drivers/block/null_blk_zoned.c | 37 ++++++++++++++++++++++++++-------- > 1 file changed, 29 insertions(+), 8 deletions(-) > > diff --git a/drivers/block/null_blk_zoned.c b/drivers/block/null_blk_zoned.c > index 46641df2e58e..9c19f747f394 100644 > --- a/drivers/block/null_blk_zoned.c > +++ b/drivers/block/null_blk_zoned.c > @@ -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); > + > + if (ret) > + return ret; > + } else { > + blk_queue_chunk_sectors(q, dev->zone_size_sects); > + q->nr_zones = blkdev_nr_zones(nullb->disk); > + } > > - blk_queue_chunk_sectors(q, nullb->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: > Reviewed-by: Hannes Reinecke <hare@suse.de> Cheers, Hannes
Johannes, > 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. Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
diff --git a/drivers/block/null_blk_zoned.c b/drivers/block/null_blk_zoned.c index 46641df2e58e..9c19f747f394 100644 --- a/drivers/block/null_blk_zoned.c +++ b/drivers/block/null_blk_zoned.c @@ -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); + + if (ret) + return ret; + } else { + blk_queue_chunk_sectors(q, dev->zone_size_sects); + q->nr_zones = blkdev_nr_zones(nullb->disk); + } - blk_queue_chunk_sectors(q, nullb->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: