summaryrefslogtreecommitdiff
path: root/drivers/md/md.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2021-09-01 14:38:33 +0300
committerJens Axboe <axboe@kernel.dk>2021-10-18 23:50:23 +0300
commit7ad1069166c0ccdd572d27e01cc7f7f84477df1e (patch)
tree0d1aca1a632d10208555d4212f5af9d30fef4ef7 /drivers/md/md.c
parent94f3cd7d832c28681f1dea54b4dd8606e5e2bc75 (diff)
downloadlinux-7ad1069166c0ccdd572d27e01cc7f7f84477df1e.tar.xz
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>
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r--drivers/md/md.c37
1 files changed, 17 insertions, 20 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 946bbedf5dcf..c6b15ff0074f 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -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;