From 6bc715d662f064cdee9a6423d8617bde9aaf37ed Mon Sep 17 00:00:00 2001 From: zhangyue Date: Thu, 4 Jan 2024 10:50:02 +0800 Subject: [PATCH 01/11] md: fix double free of mddev->private in autorun_array() mainline inclusion from mainline-v5.16-rc5 commit 07641b5f32f6991758b08da9b1f4173feeb64f2a category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I63WZE Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=07641b5f32f6991758b08da9b1f4173feeb64f2a -------------------------------- In driver/md/md.c, if the function autorun_array() is called, the problem of double free may occur. In function autorun_array(), when the function do_md_run() returns an error, the function do_md_stop() will be called. The function do_md_run() called function md_run(), but in function md_run(), the pointer mddev->private may be freed. The function do_md_stop() called the function __md_stop(), but in function __md_stop(), the pointer mddev->private also will be freed without judging null. At this time, the pointer mddev->private will be double free, so it needs to be judged null or not. Signed-off-by: zhangyue Signed-off-by: Song Liu Signed-off-by: Li Nan --- drivers/md/md.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index f52ce85c6561..db2a535f5c71 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -6363,7 +6363,8 @@ static void __md_stop(struct mddev *mddev) spin_lock(&mddev->lock); mddev->pers = NULL; spin_unlock(&mddev->lock); - pers->free(mddev, mddev->private); + if (mddev->private) + pers->free(mddev, mddev->private); mddev->private = NULL; if (pers->sync_request && mddev->to_remove == NULL) mddev->to_remove = &md_redundancy_group; -- Gitee From 9d321cf18049cf4cf90c6a1aa823a625094dff3a Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 4 Jan 2024 10:50:03 +0800 Subject: [PATCH 02/11] md: use msleep() in md_notify_reboot() mainline inclusion from mainline-v5.18-rc1 commit 7d959f6e978cbbca90e26a192cc39480e977182f category: bugfix bugzilla: 188015, https://gitee.com/openeuler/kernel/issues/I63WZE Reference: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git/commit/?id=7d959f6e978cbbca90e26a192cc39480e977182f -------------------------------- Calling mdelay(1000) from process context, even while a reboot is in progress, does not make sense. Using msleep() allows other threads to make progress. Signed-off-by: Eric Dumazet Cc: linux-raid@vger.kernel.org Signed-off-by: Song Liu Signed-off-by: Li Nan --- drivers/md/md.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index db2a535f5c71..97580c86ab35 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -9656,7 +9656,7 @@ static int md_notify_reboot(struct notifier_block *this, * driver, we do want to have a safe RAID driver ... */ if (need_delay) - mdelay(1000*1); + msleep(1000); return NOTIFY_DONE; } -- Gitee From acd79c2c9fd669b37f13e026cc0e8185f898e886 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Thu, 4 Jan 2024 10:50:04 +0800 Subject: [PATCH 03/11] md/raid10: fix improper BUG_ON() in raise_barrier() mainline inclusion from mainline-v6.1-rc1 commit 4f350284a7306b3dff676caeafd3faf1b5c068d5 category: bugfix bugzilla: 188015, https://gitee.com/openeuler/kernel/issues/I63WZE Reference: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git/commit/?id=4f350284a7306b3dff676caeafd3faf1b5c068d5 -------------------------------- 'conf->barrier' is protected by 'conf->resync_lock', reading 'conf->barrier' without holding the lock is wrong. Signed-off-by: Yu Kuai Reviewed-by: Logan Gunthorpe Acked-by: Guoqing Jiang Signed-off-by: Song Liu Signed-off-by: Li Nan --- drivers/md/raid10.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 222d9ed76b4b..f1ff63c0444c 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -941,8 +941,8 @@ static void flush_pending_writes(struct r10conf *conf) static void raise_barrier(struct r10conf *conf, int force) { - BUG_ON(force && !conf->barrier); spin_lock_irq(&conf->resync_lock); + BUG_ON(force && !conf->barrier); /* Wait until no block IO is waiting (unless 'force') */ wait_event_lock_irq(conf->wait_barrier, force || !conf->nr_waiting, -- Gitee From 2d046fe63657f94338d966f38b7db502b18dec89 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 4 Jan 2024 10:50:05 +0800 Subject: [PATCH 04/11] md: convert to blk_alloc_disk/blk_cleanup_disk mainline inclusion from mainline-v5.14-rc1 commit 0f1d2e0643c544df50dbc436da930201218fa1e2 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=0f1d2e0643c544df50dbc436da930201218fa1e2 -------------------------------- Convert the md driver to use the blk_alloc_disk and blk_cleanup_disk helpers to simplify gendisk and request_queue allocation. Signed-off-by: Christoph Hellwig Reviewed-by: Hannes Reinecke Reviewed-by: Ulf Hansson Link: https://lore.kernel.org/r/20210521055116.1053587-15-hch@lst.de Signed-off-by: Jens Axboe Conflict: drivers/md/md.c the merging order of commit ad3fc798800f ("md: revert io stats accounting") is inconsistent. Signed-off-by: Li Nan --- drivers/md/md.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 97580c86ab35..bba90a46cdf4 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -5665,12 +5665,10 @@ static void md_free(struct kobject *ko) if (mddev->sysfs_level) sysfs_put(mddev->sysfs_level); - if (mddev->gendisk) + if (mddev->gendisk) { del_gendisk(mddev->gendisk); - if (mddev->queue) - blk_cleanup_queue(mddev->queue); - if (mddev->gendisk) - put_disk(mddev->gendisk); + blk_cleanup_disk(mddev->gendisk); + } percpu_ref_exit(&mddev->writes_pending); bioset_exit(&mddev->bio_set); @@ -5774,20 +5772,13 @@ static int md_alloc(dev_t dev, char *name) mddev->hold_active = UNTIL_STOP; error = -ENOMEM; - mddev->queue = blk_alloc_queue(NUMA_NO_NODE); - if (!mddev->queue) + disk = blk_alloc_disk(NUMA_NO_NODE); + if (!disk) goto abort; - blk_set_stacking_limits(&mddev->queue->limits); - - disk = alloc_disk(1 << shift); - if (!disk) { - blk_cleanup_queue(mddev->queue); - mddev->queue = NULL; - goto abort; - } disk->major = MAJOR(mddev->unit); disk->first_minor = unit << shift; + disk->minors = 1 << shift; if (name) strcpy(disk->disk_name, name); else if (partitioned) @@ -5796,7 +5787,9 @@ static int md_alloc(dev_t dev, char *name) sprintf(disk->disk_name, "md%d", unit); disk->fops = &md_fops; disk->private_data = mddev; - disk->queue = mddev->queue; + + mddev->queue = disk->queue; + blk_set_stacking_limits(&mddev->queue->limits); blk_queue_write_cache(mddev->queue, true, true); /* Allow extended partitions. This makes the * 'mdp' device redundant, but we can't really -- Gitee From acd17df750d76b6ab1c2d664d9f1ae19262d50f1 Mon Sep 17 00:00:00 2001 From: Luis Chamberlain Date: Thu, 4 Jan 2024 10:50:06 +0800 Subject: [PATCH 05/11] md: add error handling support for add_disk() mainline inclusion from mainline-v5.16-rc1 commit 9be68dd7ac0e13be2ac57770c1f921d6b3294c6e 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=9be68dd7ac0e13be2ac57770c1f921d6b3294c6e -------------------------------- We never checked for errors on add_disk() as this function returned void. Now that this is fixed, use the shiny new error handling. We just do the unwinding of what was not done before, and are sure to unlock prior to bailing. Signed-off-by: Luis Chamberlain Signed-off-by: Christoph Hellwig Signed-off-by: Song Liu Signed-off-by: Jens Axboe Conflict: drivers/md/md.c use add_disk_safe(). Signed-off-by: Li Nan --- drivers/md/md.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index bba90a46cdf4..78d603fb8036 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -5798,7 +5798,11 @@ static int md_alloc(dev_t dev, char *name) disk->flags |= GENHD_FL_EXT_DEVT; disk->events |= DISK_EVENT_MEDIA_CHANGE; mddev->gendisk = disk; - add_disk(disk); + error = add_disk_safe(disk); + if (error) { + blk_cleanup_disk(disk); + goto abort; + } error = kobject_add(&mddev->kobj, &disk_to_dev(disk)->kobj, "%s", "md"); if (error) { -- Gitee From 11d8b0e6db0ffa76c01ec2dc9b751baeea92d2d7 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 4 Jan 2024 10:50:07 +0800 Subject: [PATCH 06/11] md: add the bitmap group to the default groups for the md kobject mainline inclusion from mainline-v5.16-rc1 commit 51238e7fbd6182e36dbc093c92ae93142c57c0f5 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=51238e7fbd6182e36dbc093c92ae93142c57c0f5 -------------------------------- Replace the deprecated default_attrs with the default_groups mechanism, and add the always visible bitmap group to the groups created add kobject_add time. Signed-off-by: Christoph Hellwig Signed-off-by: Song Liu Signed-off-by: Jens Axboe Signed-off-by: Li Nan --- drivers/md/md.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 78d603fb8036..dd34e44d9962 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -5588,6 +5588,10 @@ static struct attribute *md_default_attrs[] = { NULL, }; +static const struct attribute_group md_default_group = { + .attrs = md_default_attrs, +}; + static struct attribute *md_redundancy_attrs[] = { &md_scan_mode.attr, &md_last_scan_mode.attr, @@ -5610,6 +5614,12 @@ static struct attribute_group md_redundancy_group = { .attrs = md_redundancy_attrs, }; +static const struct attribute_group *md_attr_groups[] = { + &md_default_group, + &md_bitmap_group, + NULL, +}; + static ssize_t md_attr_show(struct kobject *kobj, struct attribute *attr, char *page) { @@ -5684,7 +5694,7 @@ static const struct sysfs_ops md_sysfs_ops = { static struct kobj_type md_ktype = { .release = md_free, .sysfs_ops = &md_sysfs_ops, - .default_attrs = md_default_attrs, + .default_groups = md_attr_groups, }; int mdp_major = 0; @@ -5693,7 +5703,6 @@ static void mddev_delayed_delete(struct work_struct *ws) { struct mddev *mddev = container_of(ws, struct mddev, del_work); - sysfs_remove_group(&mddev->kobj, &md_bitmap_group); kobject_del(&mddev->kobj); kobject_put(&mddev->kobj); } @@ -5813,9 +5822,6 @@ static int md_alloc(dev_t dev, char *name) disk->disk_name); error = 0; } - if (mddev->kobj.sd && - sysfs_create_group(&mddev->kobj, &md_bitmap_group)) - pr_debug("pointless warning\n"); abort: mutex_unlock(&disks_mutex); if (!error && mddev->kobj.sd) { -- Gitee From 8999f7dfb81e51df1364827e73411b95e5d5afe8 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 4 Jan 2024 10:50:08 +0800 Subject: [PATCH 07/11] md: extend disks_mutex coverage mainline inclusion from mainline-v5.16-rc1 commit 94f3cd7d832c28681f1dea54b4dd8606e5e2bc75 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=94f3cd7d832c28681f1dea54b4dd8606e5e2bc75 -------------------------------- disks_mutex is intended to serialize md_alloc. Extended it to also cover the kobject_uevent call and getting the sysfs dirent to help reducing error handling complexity. Signed-off-by: Christoph Hellwig Signed-off-by: Song Liu Signed-off-by: Jens Axboe Signed-off-by: Li Nan --- drivers/md/md.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index dd34e44d9962..480144fbeb1e 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -5823,12 +5823,12 @@ static int md_alloc(dev_t dev, char *name) error = 0; } abort: - mutex_unlock(&disks_mutex); 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"); } + mutex_unlock(&disks_mutex); mddev_put(mddev); return error; } -- Gitee From 14f37d255f002f7bc20770cd7e8e55f150b897a4 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 4 Jan 2024 10:50:09 +0800 Subject: [PATCH 08/11] md: properly unwind when failing to add the kobject in md_alloc mainline inclusion from mainline-v5.16-rc1 commit 7ad1069166c0ccdd572d27e01cc7f7f84477df1e 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: Christoph Hellwig Signed-off-by: Song Liu Signed-off-by: Jens Axboe Conflict: drivers/md/md.c Because add_disk_safe(). Signed-off-by: Li Nan --- drivers/md/md.c | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 480144fbeb1e..b1a671eb2d6d 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -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) { - 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; -- Gitee From ece14f9774b51a2235cadaf667cc751fd6336637 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 4 Jan 2024 10:50:10 +0800 Subject: [PATCH 09/11] md: fix mddev->kobj lifetime mainline inclusion from mainline-v6.0-rc1 commit ca39f7502425d437cbf83d29d99b43bd61342858 category: bugfix bugzilla: 188733, https://gitee.com/openeuler/kernel/issues/I81XCK, https://gitee.com/openeuler/kernel/issues/I81XCK Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ca39f7502425d437cbf83d29d99b43bd61342858 ------------------------------------------------- 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 Reviewed-by: Logan Gunthorpe Reviewed-by: Hannes Reinecke Signed-off-by: Song Liu Signed-off-by: Jens Axboe Conflict: drivers/md/md.c 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 --- 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 b1a671eb2d6d..0cf90ed4cfe3 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -686,7 +686,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); @@ -5675,10 +5674,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); @@ -5703,7 +5701,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); } @@ -5811,6 +5808,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; -- Gitee From da72f3d2b9fcbaa42d6df7a10b96c9c04838a5e3 Mon Sep 17 00:00:00 2001 From: Rikard Falkeborn Date: Thu, 4 Jan 2024 10:50:11 +0800 Subject: [PATCH 10/11] md: Constify attribute_group structs mainline inclusion from mainline-v5.14-rc1 commit c32dc04059c79ddb4f7cff94ad5de6e92ea2218d 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=c32dc04059c79ddb4f7cff94ad5de6e92ea2218d -------------------------------- The attribute_group structs are never modified, they're only passed to sysfs_create_group() and sysfs_remove_group(). Make them const to allow the compiler to put them in read-only memory. Signed-off-by: Rikard Falkeborn Signed-off-by: Song Liu Signed-off-by: Li Nan --- drivers/md/md-bitmap.c | 2 +- drivers/md/md.c | 6 +++--- drivers/md/md.h | 4 ++-- drivers/md/raid5.c | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index e842beb89858..895bbb512135 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -2637,7 +2637,7 @@ static struct attribute *md_bitmap_attrs[] = { &max_backlog_used.attr, NULL }; -struct attribute_group md_bitmap_group = { +const struct attribute_group md_bitmap_group = { .name = "bitmap", .attrs = md_bitmap_attrs, }; diff --git a/drivers/md/md.c b/drivers/md/md.c index 0cf90ed4cfe3..b841b6ed379b 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -800,7 +800,7 @@ static struct mddev *mddev_alloc(dev_t unit) return ERR_PTR(error); } -static struct attribute_group md_redundancy_group; +static const struct attribute_group md_redundancy_group; void mddev_unlock(struct mddev *mddev) { @@ -817,7 +817,7 @@ void mddev_unlock(struct mddev *mddev) * test it under the same mutex to ensure its correct value * is seen. */ - struct attribute_group *to_remove = mddev->to_remove; + const struct attribute_group *to_remove = mddev->to_remove; mddev->to_remove = NULL; mddev->sysfs_active = 1; mutex_unlock(&mddev->reconfig_mutex); @@ -5608,7 +5608,7 @@ static struct attribute *md_redundancy_attrs[] = { &md_degraded.attr, NULL, }; -static struct attribute_group md_redundancy_group = { +static const struct attribute_group md_redundancy_group = { .name = NULL, .attrs = md_redundancy_attrs, }; diff --git a/drivers/md/md.h b/drivers/md/md.h index 845ccd842975..72e9f31c3ef9 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -500,7 +500,7 @@ struct mddev { atomic_t max_corr_read_errors; /* max read retries */ struct list_head all_mddevs; - struct attribute_group *to_remove; + const struct attribute_group *to_remove; struct bio_set bio_set; struct bio_set sync_set; /* for sync operations like @@ -637,7 +637,7 @@ struct md_sysfs_entry { ssize_t (*show)(struct mddev *, char *); ssize_t (*store)(struct mddev *, const char *, size_t); }; -extern struct attribute_group md_bitmap_group; +extern const struct attribute_group md_bitmap_group; static inline struct kernfs_node *sysfs_get_dirent_safe(struct kernfs_node *sd, char *name) { diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index bef14340f9c1..7e78499aa9d3 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -6950,7 +6950,7 @@ static struct attribute *raid5_attrs[] = { &ppl_write_hint.attr, NULL, }; -static struct attribute_group raid5_attrs_group = { +static const struct attribute_group raid5_attrs_group = { .name = NULL, .attrs = raid5_attrs, }; -- Gitee From 6d01bb59a71cfc5d3b84745f38701f05d25dd5ca Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 4 Jan 2024 10:50:12 +0800 Subject: [PATCH 11/11] md: fix error handling in md_alloc mainline inclusion from mainline-v6.0-rc1 commit c57094a6e1ed5dd2d6401f79b8e6da34dd28f959 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=c57094a6e1ed5dd2d6401f79b8e6da34dd28f959 -------------------------------- Error handling in md_alloc is a mess. Untangle it to just free the mddev directly before add_disk is called and thus the gendisk is globally visible. After that clear the hold flag and let the mddev_put take care of cleaning up the mddev through the usual mechanisms. Fixes: 5e55e2f5fc95 ("[PATCH] md: convert compile time warnings into runtime warnings") Fixes: 9be68dd7ac0e ("md: add error handling support for add_disk()") Fixes: 7ad1069166c0 ("md: properly unwind when failing to add the kobject in md_alloc") Signed-off-by: Christoph Hellwig Reviewed-by: Logan Gunthorpe Reviewed-by: Hannes Reinecke Signed-off-by: Song Liu Signed-off-by: Jens Axboe Conflict: drivers/md/md.c Commit 8b9ab6266204 ("block: remove blk_cleanup_disk") change blk_cleanup_disk() to put_disk(). Keep using blk_cleanup_disk() here. And add_disk_safe(). Signed-off-by: Li Nan --- drivers/md/md.c | 45 ++++++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index b841b6ed379b..02dcf64103ca 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -800,6 +800,15 @@ static struct mddev *mddev_alloc(dev_t unit) return ERR_PTR(error); } +static void mddev_free(struct mddev *mddev) +{ + spin_lock(&all_mddevs_lock); + list_del(&mddev->all_mddevs); + spin_unlock(&all_mddevs_lock); + + kfree(mddev); +} + static const struct attribute_group md_redundancy_group; void mddev_unlock(struct mddev *mddev) @@ -5748,8 +5757,8 @@ static int md_alloc(dev_t dev, char *name) mutex_lock(&disks_mutex); mddev = mddev_alloc(dev); if (IS_ERR(mddev)) { - mutex_unlock(&disks_mutex); - return PTR_ERR(mddev); + error = PTR_ERR(mddev); + goto out_unlock; } partitioned = (MAJOR(mddev->unit) != MD_MAJOR); @@ -5767,7 +5776,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 out_unlock_disks_mutex; + goto out_free_mddev; } spin_unlock(&all_mddevs_lock); } @@ -5780,7 +5789,7 @@ static int md_alloc(dev_t dev, char *name) error = -ENOMEM; disk = blk_alloc_disk(NUMA_NO_NODE); if (!disk) - goto out_unlock_disks_mutex; + goto out_free_mddev; disk->major = MAJOR(mddev->unit); disk->first_minor = unit << shift; @@ -5806,26 +5815,36 @@ static int md_alloc(dev_t dev, char *name) mddev->gendisk = disk; error = add_disk_safe(disk); if (error) - goto out_cleanup_disk; + goto out_put_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; + if (error) { + /* + * The disk is already live at this point. Clear the hold flag + * and let mddev_put take care of the deletion, as it isn't any + * different from a normal close on last release now. + */ + mddev->hold_active = 0; + goto done; + } 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: +done: mutex_unlock(&disks_mutex); mddev_put(mddev); return error; + +out_put_disk: + blk_cleanup_disk(disk); +out_free_mddev: + mddev_free(mddev); +out_unlock: + mutex_unlock(&disks_mutex); + return error; } static struct kobject *md_probe(dev_t dev, int *part, void *data) -- Gitee