From aacae8c469f9ce4b303a2eb61593ff522c1420bc Mon Sep 17 00:00:00 2001 From: Damien Le Moal Date: Thu, 2 Jun 2022 21:03:44 +0900 Subject: block: null_blk: Fix null_zone_write() The bio and rq fields of struct nullb_cmd are now overlapping in a union. So we cannot use a test on ->bio being non-NULL to detect the NULL_Q_BIO queue mode. null_zone_write() use such broken test to set the sector position of a zone append write in the command bio or request. When the null_blk device uses the NULL_Q_MQ queue mode, null_zone_write() wrongly end up setting the bio sector position, resulting in the command request to be broken and random crashes following. Fix this by testing the device queue mode directly. Fixes: 8ba816b23abd ("null-blk: save memory footprint for struct nullb_cmd") Signed-off-by: Damien Le Moal Reviewed-by: Johannes Thumshirn Link: https://lore.kernel.org/r/20220602120344.1365329-1-damien.lemoal@opensource.wdc.com Signed-off-by: Jens Axboe --- drivers/block/null_blk/main.c | 6 ------ drivers/block/null_blk/null_blk.h | 7 +++++++ drivers/block/null_blk/zoned.c | 6 +++--- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c index 539cfeac263d..6b67088f4ea7 100644 --- a/drivers/block/null_blk/main.c +++ b/drivers/block/null_blk/main.c @@ -77,12 +77,6 @@ enum { NULL_IRQ_TIMER = 2, }; -enum { - NULL_Q_BIO = 0, - NULL_Q_RQ = 1, - NULL_Q_MQ = 2, -}; - static bool g_virt_boundary = false; module_param_named(virt_boundary, g_virt_boundary, bool, 0444); MODULE_PARM_DESC(virt_boundary, "Require a virtual boundary for the device. Default: False"); diff --git a/drivers/block/null_blk/null_blk.h b/drivers/block/null_blk/null_blk.h index 4525a65e1b23..8359b43842f2 100644 --- a/drivers/block/null_blk/null_blk.h +++ b/drivers/block/null_blk/null_blk.h @@ -60,6 +60,13 @@ struct nullb_zone { unsigned int capacity; }; +/* Queue modes */ +enum { + NULL_Q_BIO = 0, + NULL_Q_RQ = 1, + NULL_Q_MQ = 2, +}; + struct nullb_device { struct nullb *nullb; struct config_item item; diff --git a/drivers/block/null_blk/zoned.c b/drivers/block/null_blk/zoned.c index ed158ea4fdd1..2fdd7b20c224 100644 --- a/drivers/block/null_blk/zoned.c +++ b/drivers/block/null_blk/zoned.c @@ -398,10 +398,10 @@ static blk_status_t null_zone_write(struct nullb_cmd *cmd, sector_t sector, */ if (append) { sector = zone->wp; - if (cmd->bio) - cmd->bio->bi_iter.bi_sector = sector; - else + if (dev->queue_mode == NULL_Q_MQ) cmd->rq->__sector = sector; + else + cmd->bio->bi_iter.bi_sector = sector; } else if (sector != zone->wp) { ret = BLK_STS_IOERR; goto unlock; -- cgit v1.2.3