From: Damien Le Moal <damien.lemoal@xxxxxxx> Support REQ_OP_ZONE_APPEND requests for zone mode null_blk devices. Use the internally tracked zone write pointer position as the write position. Signed-off-by: Damien Le Moal <damien.lemoal@xxxxxxx> --- drivers/block/null_blk_main.c | 9 ++++++--- drivers/block/null_blk_zoned.c | 21 ++++++++++++++++++--- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/drivers/block/null_blk_main.c b/drivers/block/null_blk_main.c index 133060431dbd..62869431f2cf 100644 --- a/drivers/block/null_blk_main.c +++ b/drivers/block/null_blk_main.c @@ -1575,15 +1575,18 @@ static int null_gendisk_register(struct nullb *nullb) #ifdef CONFIG_BLK_DEV_ZONED if (nullb->dev->zoned) { - if (queue_is_mq(nullb->q)) { + struct request_queue *q = nullb->q; + + if (queue_is_mq(q)) { int ret = blk_revalidate_disk_zones(disk); if (ret) return ret; } else { - blk_queue_chunk_sectors(nullb->q, + blk_queue_chunk_sectors(q, nullb->dev->zone_size_sects); - nullb->q->nr_zones = blkdev_nr_zones(disk); + q->nr_zones = blkdev_nr_zones(disk); } + blk_queue_max_zone_append_sectors(q, q->limits.max_hw_sectors); } #endif diff --git a/drivers/block/null_blk_zoned.c b/drivers/block/null_blk_zoned.c index ed34785dd64b..ed9c4cde68f3 100644 --- a/drivers/block/null_blk_zoned.c +++ b/drivers/block/null_blk_zoned.c @@ -116,7 +116,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); @@ -131,7 +131,20 @@ 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 */ + /* + * 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; + } + if (sector != zone->wp) return BLK_STS_IOERR; @@ -211,7 +224,9 @@ blk_status_t null_handle_zoned(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: -- 2.24.1