From: Christoph Hellwig hch@lst.de
mainline inclusion from mainline-v5.16-rc1 commit 7ad1069166c0ccdd572d27e01cc7f7f84477df1e category: bugfix bugzilla: 188733, https://gitee.com/openeuler/kernel/issues/I81XCK
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
-------------------------------------------------
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
Conflict: drivers/md/md.c Commit ("0d809b3837a0 md: do not return existing mddevs from mddev_find_or_alloc") has not been merged, which remove the check of mddev->gendisk. We will not merge it since it is not abount error handle and relies on other patchs. Just goto out_unlock_disks_mutex if mddev->gendisk exists to fix conflict.
Signed-off-by: Li Nan linan122@huawei.com --- drivers/md/md.c | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-)
diff --git a/drivers/md/md.c b/drivers/md/md.c index 7e2ce1edfafb..cdc801c07bfc 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -5769,7 +5769,7 @@ static int md_alloc(dev_t dev, char *name) mutex_lock(&disks_mutex); error = -EEXIST; if (mddev->gendisk) - goto abort; + goto out_unlock_disks_mutex;
if (name && !dev) { /* Need to ensure that 'name' is not a duplicate. @@ -5781,7 +5781,7 @@ static int md_alloc(dev_t dev, char *name) if (mddev2->gendisk && strcmp(mddev2->gendisk->disk_name, name) == 0) { spin_unlock(&all_mddevs_lock); - goto abort; + goto out_unlock_disks_mutex; } spin_unlock(&all_mddevs_lock); } @@ -5794,7 +5794,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; @@ -5819,26 +5819,23 @@ static int md_alloc(dev_t dev, char *name) disk->events |= DISK_EVENT_MEDIA_CHANGE; mddev->gendisk = disk; error = add_disk_safe(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;