Skip to content

Commit 343dc54

Browse files
Zheng Qixingaxboe
authored andcommitted
block: fix kobject double initialization in add_disk
Device-mapper can call add_disk() multiple times for the same gendisk due to its two-phase creation process (dm create + dm load). This leads to kobject double initialization errors when the underlying iSCSI devices become temporarily unavailable and then reappear. However, if the first add_disk() call fails and is retried, the queue_kobj gets initialized twice, causing: kobject: kobject (ffff88810c27bb90): tried to init an initialized object, something is seriously wrong. Call Trace: <TASK> dump_stack_lvl+0x5b/0x80 kobject_init.cold+0x43/0x51 blk_register_queue+0x46/0x280 add_disk_fwnode+0xb5/0x280 dm_setup_md_queue+0x194/0x1c0 table_load+0x297/0x2d0 ctl_ioctl+0x2a2/0x480 dm_ctl_ioctl+0xe/0x20 __x64_sys_ioctl+0xc7/0x110 do_syscall_64+0x72/0x390 entry_SYSCALL_64_after_hwframe+0x76/0x7e Fix this by separating kobject initialization from sysfs registration: - Initialize queue_kobj early during gendisk allocation - add_disk() only adds the already-initialized kobject to sysfs - del_gendisk() removes from sysfs but doesn't destroy the kobject - Final cleanup happens when the disk is released Fixes: 2bd8522 ("block: untangle request_queue refcounting from sysfs") Reported-by: Li Lingfeng <lilingfeng3@huawei.com> Closes: https://lore.kernel.org/all/83591d0b-2467-433c-bce0-5581298eb161@huawei.com/ Signed-off-by: Zheng Qixing <zhengqixing@huawei.com> Reviewed-by: Ming Lei <ming.lei@redhat.com> Reviewed-by: Yu Kuai <yukuai3@huawei.com> Reviewed-by: Nilay Shroff <nilay@linux.ibm.com> Link: https://lore.kernel.org/r/20250808053609.3237836-1-zhengqixing@huaweicloud.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent 196447c commit 343dc54

File tree

3 files changed

+8
-7
lines changed

3 files changed

+8
-7
lines changed

block/blk-sysfs.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -847,7 +847,7 @@ static void blk_queue_release(struct kobject *kobj)
847847
/* nothing to do here, all data is associated with the parent gendisk */
848848
}
849849

850-
static const struct kobj_type blk_queue_ktype = {
850+
const struct kobj_type blk_queue_ktype = {
851851
.default_groups = blk_queue_attr_groups,
852852
.sysfs_ops = &queue_sysfs_ops,
853853
.release = blk_queue_release,
@@ -875,15 +875,14 @@ int blk_register_queue(struct gendisk *disk)
875875
struct request_queue *q = disk->queue;
876876
int ret;
877877

878-
kobject_init(&disk->queue_kobj, &blk_queue_ktype);
879878
ret = kobject_add(&disk->queue_kobj, &disk_to_dev(disk)->kobj, "queue");
880879
if (ret < 0)
881-
goto out_put_queue_kobj;
880+
return ret;
882881

883882
if (queue_is_mq(q)) {
884883
ret = blk_mq_sysfs_register(disk);
885884
if (ret)
886-
goto out_put_queue_kobj;
885+
goto out_del_queue_kobj;
887886
}
888887
mutex_lock(&q->sysfs_lock);
889888

@@ -934,8 +933,8 @@ int blk_register_queue(struct gendisk *disk)
934933
mutex_unlock(&q->sysfs_lock);
935934
if (queue_is_mq(q))
936935
blk_mq_sysfs_unregister(disk);
937-
out_put_queue_kobj:
938-
kobject_put(&disk->queue_kobj);
936+
out_del_queue_kobj:
937+
kobject_del(&disk->queue_kobj);
939938
return ret;
940939
}
941940

@@ -986,5 +985,4 @@ void blk_unregister_queue(struct gendisk *disk)
986985
elevator_set_none(q);
987986

988987
blk_debugfs_remove(disk);
989-
kobject_put(&disk->queue_kobj);
990988
}

block/blk.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ struct elevator_tags;
2929
/* Max future timer expiry for timeouts */
3030
#define BLK_MAX_TIMEOUT (5 * HZ)
3131

32+
extern const struct kobj_type blk_queue_ktype;
3233
extern struct dentry *blk_debugfs_root;
3334

3435
struct blk_flush_queue {

block/genhd.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1303,6 +1303,7 @@ static void disk_release(struct device *dev)
13031303
disk_free_zone_resources(disk);
13041304
xa_destroy(&disk->part_tbl);
13051305

1306+
kobject_put(&disk->queue_kobj);
13061307
disk->queue->disk = NULL;
13071308
blk_put_queue(disk->queue);
13081309

@@ -1486,6 +1487,7 @@ struct gendisk *__alloc_disk_node(struct request_queue *q, int node_id,
14861487
INIT_LIST_HEAD(&disk->slave_bdevs);
14871488
#endif
14881489
mutex_init(&disk->rqos_state_mutex);
1490+
kobject_init(&disk->queue_kobj, &blk_queue_ktype);
14891491
return disk;
14901492

14911493
out_erase_part0:

0 commit comments

Comments
 (0)