Commit 99283414 authored by Yu Kuai's avatar Yu Kuai Committed by Li Nan
Browse files

block: fix memory leak for elevator on add_disk failure

mainline inclusion
from mainline-v6.1-rc3
commit 02341a08
category: bugfix
bugzilla: 188733

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=02341a08c9dec5a88527981b0bdf0fb6f7499cbf



----------------------------------------

The default elevator is allocated in the beginning of device_add_disk(),
however, it's not freed in the following error path.

Fixes: 50e34d78 ("block: disable the elevator int del_gendisk")
Signed-off-by: default avatarYu Kuai <yukuai3@huawei.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarJason Yan <yanaijie@huawei.com>
Link: https://lore.kernel.org/r/20221022021615.2756171-1-yukuai1@huaweicloud.com


Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
confilic:
  block/genhd.c
Signed-off-by: default avatarZhong Jinghua <zhongjinghua@huawei.com>
Signed-off-by: default avatarLi Nan <linan122@huawei.com>
parent e50ddbff
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -786,6 +786,7 @@ static int __device_add_disk(struct device *parent, struct gendisk *disk,
	if (register_queue)
		elevator_init_mq(disk->queue);

	retval = -EINVAL;
	/* minors == 0 indicates to use ext devt from part0 and should
	 * be accompanied with EXT_DEVT flag.  Make sure all
	 * parameters make sense.
@@ -796,7 +797,7 @@ static int __device_add_disk(struct device *parent, struct gendisk *disk,

	retval = blk_alloc_devt(&disk->part0, &devt);
	if (retval)
		return retval;
		goto out_exit_elevator;
	disk->major = MAJOR(devt);
	disk->first_minor = MINOR(devt);

@@ -922,7 +923,14 @@ static int __device_add_disk(struct device *parent, struct gendisk *disk,
		bdi_unregister(disk->queue->backing_dev_info);
out_free_ext_minor:
	blk_free_devt(devt);
	return WARN_ON_ONCE(retval); /* keep until all callers handle errors */
out_exit_elevator:
	if (register_queue && disk->queue->elevator) {
		mutex_lock(&disk->queue->sysfs_lock);
		elevator_exit(disk->queue, disk->queue->elevator);
		mutex_unlock(&disk->queue->sysfs_lock);
	}
	WARN_ON_ONCE(retval); /* keep until all callers handle errors */
	return retval;
}

void device_add_disk(struct device *parent, struct gendisk *disk,