Commit 7ad10691 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Jens Axboe

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: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarSong Liu <songliubraving@fb.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 94f3cd7d
...@@ -5672,7 +5672,7 @@ static int md_alloc(dev_t dev, char *name) ...@@ -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) ...@@ -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) ...@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment