From: Christoph Hellwig hch@lst.de
mainline inclusion from mainline-v5.13-rc1 commit d144fe6ff176d79efd411e520103a99e11874c36 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...
-------------------------------------------------
Allocate the new mddev first speculatively, which greatly simplifies the code flow.
Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Song Liu song@kernel.org Signed-off-by: Li Lingfeng lilingfeng3@huawei.com Signed-off-by: Li Nan linan122@huawei.com --- drivers/md/md.c | 60 ++++++++++++++++++++----------------------------- 1 file changed, 24 insertions(+), 36 deletions(-)
diff --git a/drivers/md/md.c b/drivers/md/md.c index ba4c7d6505da..acf3341a1c40 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -761,57 +761,45 @@ static struct mddev *mddev_find(dev_t unit)
static struct mddev *mddev_find_or_alloc(dev_t unit) { - struct mddev *mddev, *new = NULL; + struct mddev *mddev = NULL, *new;
if (unit && MAJOR(unit) != MD_MAJOR) - unit &= ~((1<<MdpMinorShift)-1); + unit &= ~((1 << MdpMinorShift) - 1);
- retry: - spin_lock(&all_mddevs_lock); + new = kzalloc(sizeof(*new), GFP_KERNEL); + if (!new) + return NULL; + mddev_init(new);
+ spin_lock(&all_mddevs_lock); if (unit) { mddev = mddev_find_locked(unit); if (mddev) { mddev_get(mddev); - spin_unlock(&all_mddevs_lock); - kfree(new); - return mddev; + goto out_free_new; }
- if (new) { - list_add(&new->all_mddevs, &all_mddevs); - spin_unlock(&all_mddevs_lock); - new->hold_active = UNTIL_IOCTL; - return new; - } - } else if (new) { + new->unit = unit; + if (MAJOR(unit) == MD_MAJOR) + new->md_minor = MINOR(unit); + else + new->md_minor = MINOR(unit) >> MdpMinorShift; + new->hold_active = UNTIL_IOCTL; + } else { new->unit = mddev_alloc_unit(); - if (!new->unit) { - spin_unlock(&all_mddevs_lock); - kfree(new); - return NULL; - } + if (!new->unit) + goto out_free_new; new->md_minor = MINOR(new->unit); new->hold_active = UNTIL_STOP; - list_add(&new->all_mddevs, &all_mddevs); - spin_unlock(&all_mddevs_lock); - return new; } - spin_unlock(&all_mddevs_lock); - - new = kzalloc(sizeof(*new), GFP_KERNEL); - if (!new) - return NULL;
- new->unit = unit; - if (MAJOR(unit) == MD_MAJOR) - new->md_minor = MINOR(unit); - else - new->md_minor = MINOR(unit) >> MdpMinorShift; - - mddev_init(new); - - goto retry; + list_add(&new->all_mddevs, &all_mddevs); + spin_unlock(&all_mddevs_lock); + return new; +out_free_new: + spin_unlock(&all_mddevs_lock); + kfree(new); + return mddev; }
static struct attribute_group md_redundancy_group;