From: Christoph Hellwig hch@lst.de
mainline inclusion from mainline-v6.0-rc1 commit ca39f7502425d437cbf83d29d99b43bd61342858 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...
-------------------------------------------------
Once a kobject is initialized, the containing object should not be directly freed. So delay initialization until it is added. Also remove the kobject_del call as the last put will remove the kobject as well. The explicitly delete isn't needed here, and dropping it will simplify further fixes.
With this md_free now does not need to check that ->gendisk is non-NULL as it is always set by the time that kobject_init is called on mddev->kobj.
Signed-off-by: Christoph Hellwig hch@lst.de Reviewed-by: Logan Gunthorpe logang@deltatee.com Reviewed-by: Hannes Reinecke hare@suse.de Signed-off-by: Song Liu song@kernel.org Signed-off-by: Jens Axboe axboe@kernel.dk
Conflict: Commit 8b9ab6266204 ("block: remove blk_cleanup_disk") change blk_cleanup_disk() to put_disk(). Keep using blk_cleanup_disk() here.
Signed-off-by: Li Nan linan122@huawei.com --- drivers/md/md.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/drivers/md/md.c b/drivers/md/md.c index cdc801c07bfc..33905999bb05 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -687,7 +687,6 @@ static void md_safemode_timeout(struct timer_list *t);
void mddev_init(struct mddev *mddev) { - kobject_init(&mddev->kobj, &md_ktype); mutex_init(&mddev->open_mutex); mutex_init(&mddev->reconfig_mutex); mutex_init(&mddev->bitmap_info.mutex); @@ -5687,10 +5686,9 @@ static void md_free(struct kobject *ko) if (mddev->sysfs_level) sysfs_put(mddev->sysfs_level);
- if (mddev->gendisk) { - del_gendisk(mddev->gendisk); - blk_cleanup_disk(mddev->gendisk); - } + del_gendisk(mddev->gendisk); + blk_cleanup_disk(mddev->gendisk); + percpu_ref_exit(&mddev->writes_pending);
bioset_exit(&mddev->bio_set); @@ -5715,7 +5713,6 @@ static void mddev_delayed_delete(struct work_struct *ws) { struct mddev *mddev = container_of(ws, struct mddev, del_work);
- kobject_del(&mddev->kobj); kobject_put(&mddev->kobj); }
@@ -5822,6 +5819,7 @@ static int md_alloc(dev_t dev, char *name) if (error) goto out_cleanup_disk;
+ kobject_init(&mddev->kobj, &md_ktype); error = kobject_add(&mddev->kobj, &disk_to_dev(disk)->kobj, "%s", "md"); if (error) goto out_del_gendisk;