From: Christoph Hellwig hch@lst.de
mainline inclusion from mainline-v5.13-rc1 commit 0d809b3837a0bede8f58a67e303e339585777bf4 category: bugfix bugzilla: 189427, https://gitee.com/openeuler/kernel/issues/I8O6NL
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
-------------------------------------------------
Instead of returning an existing mddev, just for it to be discarded later directly return -EEXIST. Rename the function to mddev_alloc now that it doesn't find an existing mddev.
Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Song Liu song@kernel.org
Conflicts: Commit 5e8daf906f89 ("md: Flush workqueue md_rdev_misc_wq in md_alloc()") add flushing md_rdev_misc_wq in md_alloc(); Commit a4c94d46c7dc ("[Backport] md: properly unwind when failing to add the kobject in md_alloc") changed "goto abort" to "goto out_unlock_disks_mutex" and commit fe8412162d24 ("[Backport] md: fix error handling in md_alloc") changed "goto out_unlock_disks_mutex" to "goto done"; Commit a4c94d46c7dc ("[Backport] md: properly unwind when failing to add the kobject in md_alloc") changed "goto abort" to "goto out_unlock_disks_mutex" and commit fe8412162d24 ("[Backport] md: fix error handling in md_alloc") changed "goto out_unlock_disks_mutex" to "goto out_free_mddev". Signed-off-by: Li Lingfeng lilingfeng3@huawei.com Signed-off-by: Li Nan linan122@huawei.com --- drivers/md/md.c | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-)
diff --git a/drivers/md/md.c b/drivers/md/md.c index acf3341a1c40..804ad7b74ecf 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -759,26 +759,24 @@ static struct mddev *mddev_find(dev_t unit) return mddev; }
-static struct mddev *mddev_find_or_alloc(dev_t unit) +static struct mddev *mddev_alloc(dev_t unit) { - struct mddev *mddev = NULL, *new; + struct mddev *new; + int error;
if (unit && MAJOR(unit) != MD_MAJOR) unit &= ~((1 << MdpMinorShift) - 1);
new = kzalloc(sizeof(*new), GFP_KERNEL); if (!new) - return NULL; + return ERR_PTR(-ENOMEM); mddev_init(new);
spin_lock(&all_mddevs_lock); if (unit) { - mddev = mddev_find_locked(unit); - if (mddev) { - mddev_get(mddev); + error = -EEXIST; + if (mddev_find_locked(unit)) goto out_free_new; - } - new->unit = unit; if (MAJOR(unit) == MD_MAJOR) new->md_minor = MINOR(unit); @@ -786,6 +784,7 @@ static struct mddev *mddev_find_or_alloc(dev_t unit) new->md_minor = MINOR(unit) >> MdpMinorShift; new->hold_active = UNTIL_IOCTL; } else { + error = -ENODEV; new->unit = mddev_alloc_unit(); if (!new->unit) goto out_free_new; @@ -799,7 +798,7 @@ static struct mddev *mddev_find_or_alloc(dev_t unit) out_free_new: spin_unlock(&all_mddevs_lock); kfree(new); - return mddev; + return ERR_PTR(error); }
static struct attribute_group md_redundancy_group; @@ -5747,30 +5746,30 @@ static int md_alloc(dev_t dev, char *name) * writing to /sys/module/md_mod/parameters/new_array. */ static DEFINE_MUTEX(disks_mutex); - struct mddev *mddev = mddev_find_or_alloc(dev); + struct mddev *mddev; struct gendisk *disk; int partitioned; int shift; int unit; - int error; - - if (!mddev) - return -ENODEV; + int error ;
- partitioned = (MAJOR(mddev->unit) != MD_MAJOR); - shift = partitioned ? MdpMinorShift : 0; - unit = MINOR(mddev->unit) >> shift; - - /* wait for any previous instance of this device to be - * completely removed (mddev_delayed_delete). + /* + * Wait for any previous instance of this device to be completely + * removed (mddev_delayed_delete). */ flush_workqueue(md_misc_wq); flush_workqueue(md_rdev_misc_wq);
mutex_lock(&disks_mutex); - error = -EEXIST; - if (mddev->gendisk) - goto done; + mddev = mddev_alloc(dev); + if (IS_ERR(mddev)) { + mutex_unlock(&disks_mutex); + return PTR_ERR(mddev); + } + + partitioned = (MAJOR(mddev->unit) != MD_MAJOR); + shift = partitioned ? MdpMinorShift : 0; + unit = MINOR(mddev->unit) >> shift;
if (name && !dev) { /* Need to ensure that 'name' is not a duplicate. @@ -5782,6 +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); + error = -EEXIST; goto out_free_mddev; } spin_unlock(&all_mddevs_lock);