Commit 14f37d25 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Li Nan
Browse files

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

mainline inclusion
from mainline-v5.16-rc1
commit 7ad10691
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I81XCK

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=7ad1069166c0ccdd572d27e01cc7f7f84477df1e



--------------------------------

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>

Conflict:
	drivers/md/md.c
	Because add_disk_safe().

Signed-off-by: default avatarLi Nan <linan122@huawei.com>
parent 8999f7df
Loading
Loading
Loading
Loading
+17 −20
Original line number Diff line number Diff line
@@ -5770,7 +5770,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);
	}
@@ -5783,7 +5783,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;
@@ -5808,26 +5808,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) {
	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;