Commit d152c682 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Jens Axboe
Browse files

block: add an explicit ->disk backpointer to the request_queue



Replace the magic lookup through the kobject tree with an explicit
backpointer, given that the device model links are set up and torn
down at times when I/O is still possible, leading to potential
NULL or invalid pointer dereferences.

Fixes: edb0872f ("block: move the bdi from the request_queue to the gendisk")
Reported-by: default avatarsyzbot <syzbot+aa0801b6b32dca9dda82@syzkaller.appspotmail.com>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Tested-by: default avatarSven Schnelle <svens@linux.ibm.com>
Link: https://lore.kernel.org/r/20210816134624.GA24234@lst.de


Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 61a35cfc
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -5269,7 +5269,7 @@ bfq_set_next_ioprio_data(struct bfq_queue *bfqq, struct bfq_io_cq *bic)
	switch (ioprio_class) {
	default:
		pr_err("bdi %s: bfq: bad prio class %d\n",
			bdi_dev_name(queue_to_disk(bfqq->bfqd->queue)->bdi),
			bdi_dev_name(bfqq->bfqd->queue->disk->bdi),
			ioprio_class);
		fallthrough;
	case IOPRIO_CLASS_NONE:
+2 −2
Original line number Diff line number Diff line
@@ -489,9 +489,9 @@ static int blkcg_reset_stats(struct cgroup_subsys_state *css,

const char *blkg_dev_name(struct blkcg_gq *blkg)
{
	if (!queue_has_disk(blkg->q) || !queue_to_disk(blkg->q)->bdi->dev)
	if (!blkg->q->disk || !blkg->q->disk->bdi->dev)
		return NULL;
	return bdi_dev_name(queue_to_disk(blkg->q)->bdi);
	return bdi_dev_name(blkg->q->disk->bdi);
}

/**
+1 −1
Original line number Diff line number Diff line
@@ -525,7 +525,7 @@ void blk_mq_free_request(struct request *rq)
		__blk_mq_dec_active_requests(hctx);

	if (unlikely(laptop_mode && !blk_rq_is_passthrough(rq)))
		laptop_io_completion(queue_to_disk(q)->bdi);
		laptop_io_completion(q->disk->bdi);

	rq_qos_done(q, rq);

+4 −4
Original line number Diff line number Diff line
@@ -141,9 +141,9 @@ void blk_queue_max_hw_sectors(struct request_queue *q, unsigned int max_hw_secto
				 limits->logical_block_size >> SECTOR_SHIFT);
	limits->max_sectors = max_sectors;

	if (!queue_has_disk(q))
	if (!q->disk)
		return;
	queue_to_disk(q)->bdi->io_pages = max_sectors >> (PAGE_SHIFT - 9);
	q->disk->bdi->io_pages = max_sectors >> (PAGE_SHIFT - 9);
}
EXPORT_SYMBOL(blk_queue_max_hw_sectors);

@@ -475,9 +475,9 @@ EXPORT_SYMBOL(blk_limits_io_opt);
void blk_queue_io_opt(struct request_queue *q, unsigned int opt)
{
	blk_limits_io_opt(&q->limits, opt);
	if (!queue_has_disk(q))
	if (!q->disk)
		return;
	queue_to_disk(q)->bdi->ra_pages =
	q->disk->bdi->ra_pages =
		max(queue_io_opt(q) * 2 / PAGE_SIZE, VM_READAHEAD_PAGES);
}
EXPORT_SYMBOL(blk_queue_io_opt);
+6 −7
Original line number Diff line number Diff line
@@ -90,9 +90,9 @@ static ssize_t queue_ra_show(struct request_queue *q, char *page)
{
	unsigned long ra_kb;

	if (!queue_has_disk(q))
	if (!q->disk)
		return -EINVAL;
	ra_kb = queue_to_disk(q)->bdi->ra_pages << (PAGE_SHIFT - 10);
	ra_kb = q->disk->bdi->ra_pages << (PAGE_SHIFT - 10);
	return queue_var_show(ra_kb, page);
}

@@ -102,12 +102,12 @@ queue_ra_store(struct request_queue *q, const char *page, size_t count)
	unsigned long ra_kb;
	ssize_t ret;

	if (!queue_has_disk(q))
	if (!q->disk)
		return -EINVAL;
	ret = queue_var_store(&ra_kb, page, count);
	if (ret < 0)
		return ret;
	queue_to_disk(q)->bdi->ra_pages = ra_kb >> (PAGE_SHIFT - 10);
	q->disk->bdi->ra_pages = ra_kb >> (PAGE_SHIFT - 10);
	return ret;
}

@@ -254,9 +254,8 @@ queue_max_sectors_store(struct request_queue *q, const char *page, size_t count)

	spin_lock_irq(&q->queue_lock);
	q->limits.max_sectors = max_sectors_kb << 1;
	if (queue_has_disk(q))
		queue_to_disk(q)->bdi->io_pages =
			max_sectors_kb >> (PAGE_SHIFT - 10);
	if (q->disk)
		q->disk->bdi->io_pages = max_sectors_kb >> (PAGE_SHIFT - 10);
	spin_unlock_irq(&q->queue_lock);

	return ret;
Loading