md: properly unwind when failing to add the kobject in md_alloc

Add proper error handling to delete the gendisk when failing to add
the md kobject and clean up the error unwinding in general.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Song Liu <songliubraving@fb.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
Christoph Hellwig 2021-09-01 13:38:33 +02:00 committed by Jens Axboe
parent 94f3cd7d83
commit 7ad1069166

View file

@ -5672,7 +5672,7 @@ static int md_alloc(dev_t dev, char *name)
strcmp(mddev2->gendisk->disk_name, name) == 0) {
spin_unlock(&all_mddevs_lock);
error = -EEXIST;
goto abort;
goto out_unlock_disks_mutex;
}
spin_unlock(&all_mddevs_lock);
}
@ -5685,7 +5685,7 @@ static int md_alloc(dev_t dev, char *name)
error = -ENOMEM;
disk = blk_alloc_disk(NUMA_NO_NODE);
if (!disk)
goto abort;
goto out_unlock_disks_mutex;
disk->major = MAJOR(mddev->unit);
disk->first_minor = unit << shift;
@ -5710,26 +5710,23 @@ static int md_alloc(dev_t dev, char *name)
disk->events |= DISK_EVENT_MEDIA_CHANGE;
mddev->gendisk = disk;
error = add_disk(disk);
if (error) {
blk_cleanup_disk(disk);
goto abort;
}
if (error)
goto out_cleanup_disk;
error = kobject_add(&mddev->kobj, &disk_to_dev(disk)->kobj, "%s", "md");
if (error) {
/* This isn't possible, but as kobject_init_and_add is marked
* __must_check, we must do something with the result
*/
pr_debug("md: cannot register %s/md - name in use\n",
disk->disk_name);
error = 0;
}
abort:
if (!error && mddev->kobj.sd) {
kobject_uevent(&mddev->kobj, KOBJ_ADD);
mddev->sysfs_state = sysfs_get_dirent_safe(mddev->kobj.sd, "array_state");
mddev->sysfs_level = sysfs_get_dirent_safe(mddev->kobj.sd, "level");
}
if (error)
goto out_del_gendisk;
kobject_uevent(&mddev->kobj, KOBJ_ADD);
mddev->sysfs_state = sysfs_get_dirent_safe(mddev->kobj.sd, "array_state");
mddev->sysfs_level = sysfs_get_dirent_safe(mddev->kobj.sd, "level");
goto out_unlock_disks_mutex;
out_del_gendisk:
del_gendisk(disk);
out_cleanup_disk:
blk_cleanup_disk(disk);
out_unlock_disks_mutex:
mutex_unlock(&disks_mutex);
mddev_put(mddev);
return error;