Commit aacae8c4 authored by Damien Le Moal's avatar Damien Le Moal Committed by Jens Axboe
Browse files

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: 8ba816b2 ("null-blk: save memory footprint for struct nullb_cmd")
Signed-off-by: default avatarDamien Le Moal <damien.lemoal@opensource.wdc.com>
Reviewed-by: default avatarJohannes Thumshirn <johannes.thumshirn@wdc.com>
Link: https://lore.kernel.org/r/20220602120344.1365329-1-damien.lemoal@opensource.wdc.com


Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent c9fdf7b4
Loading
Loading
Loading
Loading
+0 −6
Original line number Diff line number Diff line
@@ -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");
+7 −0
Original line number Diff line number Diff line
@@ -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;
+3 −3
Original line number Diff line number Diff line
@@ -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;