]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
block: null_blk: Fix null_zone_write()
authorDamien Le Moal <damien.lemoal@opensource.wdc.com>
Thu, 2 Jun 2022 12:03:44 +0000 (21:03 +0900)
committerJens Axboe <axboe@kernel.dk>
Thu, 2 Jun 2022 13:11:28 +0000 (07:11 -0600)
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 <damien.lemoal@opensource.wdc.com>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Link: https://lore.kernel.org/r/20220602120344.1365329-1-damien.lemoal@opensource.wdc.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
drivers/block/null_blk/main.c
drivers/block/null_blk/null_blk.h
drivers/block/null_blk/zoned.c

index 539cfeac263dbe1f49e0a7c1f9f77037554b65cc..6b67088f4ea71c759f0e2ff0ece7dc8ab408368a 100644 (file)
@@ -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");
index 4525a65e1b23d91bd6a756901c0d6d5064b99558..8359b43842f2f6518bd072f6cbdf1e44c5104aa9 100644 (file)
@@ -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;
index ed158ea4fdd1adf5f5abde17d5e7f216e9e0ca20..2fdd7b20c224e82b8f7f20620ebdf39d86d380da 100644 (file)
@@ -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;