Skip to content

Commit 4060299

Browse files
Christoph Hellwigaxboe
authored andcommitted
block: fix error unwinding in blk_register_queue
blk_register_queue fails to handle errors from blk_mq_sysfs_register, leaks various resources on errors and accidentally sets queue refs percpu refcount to percpu mode on kobject_add failure. Fix all that by properly unwinding on errors. Signed-off-by: Christoph Hellwig <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jens Axboe <[email protected]>
1 parent 6fc75f3 commit 4060299

File tree

1 file changed

+16
-12
lines changed

1 file changed

+16
-12
lines changed

block/blk-sysfs.c

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -823,13 +823,15 @@ int blk_register_queue(struct gendisk *disk)
823823
int ret;
824824

825825
mutex_lock(&q->sysfs_dir_lock);
826-
827826
ret = kobject_add(&q->kobj, &disk_to_dev(disk)->kobj, "queue");
828827
if (ret < 0)
829-
goto unlock;
828+
goto out_unlock_dir;
830829

831-
if (queue_is_mq(q))
832-
blk_mq_sysfs_register(disk);
830+
if (queue_is_mq(q)) {
831+
ret = blk_mq_sysfs_register(disk);
832+
if (ret)
833+
goto out_del_queue_kobj;
834+
}
833835
mutex_lock(&q->sysfs_lock);
834836

835837
mutex_lock(&q->debugfs_mutex);
@@ -841,17 +843,17 @@ int blk_register_queue(struct gendisk *disk)
841843

842844
ret = disk_register_independent_access_ranges(disk);
843845
if (ret)
844-
goto put_dev;
846+
goto out_debugfs_remove;
845847

846848
if (q->elevator) {
847849
ret = elv_register_queue(q, false);
848850
if (ret)
849-
goto put_dev;
851+
goto out_unregister_ia_ranges;
850852
}
851853

852854
ret = blk_crypto_sysfs_register(disk);
853855
if (ret)
854-
goto put_dev;
856+
goto out_elv_unregister;
855857

856858
blk_queue_flag_set(QUEUE_FLAG_REGISTERED, q);
857859
wbt_enable_default(q);
@@ -862,8 +864,6 @@ int blk_register_queue(struct gendisk *disk)
862864
if (q->elevator)
863865
kobject_uevent(&q->elevator->kobj, KOBJ_ADD);
864866
mutex_unlock(&q->sysfs_lock);
865-
866-
unlock:
867867
mutex_unlock(&q->sysfs_dir_lock);
868868

869869
/*
@@ -882,13 +882,17 @@ int blk_register_queue(struct gendisk *disk)
882882

883883
return ret;
884884

885-
put_dev:
885+
out_elv_unregister:
886886
elv_unregister_queue(q);
887+
out_unregister_ia_ranges:
887888
disk_unregister_independent_access_ranges(disk);
889+
out_debugfs_remove:
890+
blk_debugfs_remove(disk);
888891
mutex_unlock(&q->sysfs_lock);
889-
mutex_unlock(&q->sysfs_dir_lock);
892+
out_del_queue_kobj:
890893
kobject_del(&q->kobj);
891-
894+
out_unlock_dir:
895+
mutex_unlock(&q->sysfs_dir_lock);
892896
return ret;
893897
}
894898

0 commit comments

Comments
 (0)