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