From: Ajay Joshi <ajay.joshi@xxxxxxx> Implement REQ_OP_ZONE_OPEN, REQ_OP_ZONE_CLOSE and REQ_OP_ZONE_FINISH support to allow explicit control of zone states. Contains contributions from Matias Bjorling, Hans Holmberg, Keith Busch and Damien Le Moal. Signed-off-by: Ajay Joshi <ajay.joshi@xxxxxxx> Signed-off-by: Matias Bjorling <matias.bjorling@xxxxxxx> Signed-off-by: Hans Holmberg <hans.holmberg@xxxxxxx> Signed-off-by: Keith Busch <kbusch@xxxxxxxxxx> Signed-off-by: Damien Le Moal <damien.lemoal@xxxxxxx> --- drivers/block/null_blk_zoned.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/drivers/block/null_blk_zoned.c b/drivers/block/null_blk_zoned.c index 4e56b17ed3ef..02f41a3bc4cb 100644 --- a/drivers/block/null_blk_zoned.c +++ b/drivers/block/null_blk_zoned.c @@ -136,13 +136,14 @@ static blk_status_t null_zone_write(struct nullb_cmd *cmd, sector_t sector, return BLK_STS_OK; } -static blk_status_t null_zone_reset(struct nullb_cmd *cmd, sector_t sector) +static blk_status_t null_zone_mgmt(struct nullb_cmd *cmd, enum req_opf op, + sector_t sector) { struct nullb_device *dev = cmd->nq->dev; struct blk_zone *zone = &dev->zones[null_zone_no(dev, sector)]; size_t i; - switch (req_op(cmd->rq)) { + switch (op) { case REQ_OP_ZONE_RESET_ALL: for (i = 0; i < dev->nr_zones; i++) { if (zone[i].type == BLK_ZONE_TYPE_CONVENTIONAL) @@ -158,6 +159,29 @@ static blk_status_t null_zone_reset(struct nullb_cmd *cmd, sector_t sector) zone->cond = BLK_ZONE_COND_EMPTY; zone->wp = zone->start; break; + case REQ_OP_ZONE_OPEN: + if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL) + return BLK_STS_IOERR; + if (zone->cond == BLK_ZONE_COND_FULL) + return BLK_STS_IOERR; + + zone->cond = BLK_ZONE_COND_EXP_OPEN; + break; + case REQ_OP_ZONE_CLOSE: + if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL) + return BLK_STS_IOERR; + if (zone->cond == BLK_ZONE_COND_FULL) + return BLK_STS_IOERR; + + zone->cond = BLK_ZONE_COND_CLOSED; + break; + case REQ_OP_ZONE_FINISH: + if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL) + return BLK_STS_IOERR; + + zone->cond = BLK_ZONE_COND_FULL; + zone->wp = zone->start + zone->len; + break; default: return BLK_STS_NOTSUPP; } @@ -172,7 +196,10 @@ blk_status_t null_handle_zoned(struct nullb_cmd *cmd, enum req_opf op, return null_zone_write(cmd, sector, nr_sectors); case REQ_OP_ZONE_RESET: case REQ_OP_ZONE_RESET_ALL: - return null_zone_reset(cmd, sector); + case REQ_OP_ZONE_OPEN: + case REQ_OP_ZONE_CLOSE: + case REQ_OP_ZONE_FINISH: + return null_zone_mgmt(cmd, op, sector); default: return BLK_STS_OK; } -- 2.21.0