summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2021-04-12 10:05:29 +0200
committerSong Liu <song@kernel.org>2021-04-15 11:06:32 -0700
commitd144fe6ff176d79efd411e520103a99e11874c36 (patch)
tree9e3b39fbce20c5f69c28cd6fd230847e659ab094
parent85c8c3c1f8d9e31f626c93435dd91c2f85603e07 (diff)
downloadlinux-d144fe6ff176d79efd411e520103a99e11874c36.tar.bz2
md: refactor mddev_find_or_alloc
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>
-rw-r--r--drivers/md/md.c60
1 files changed, 24 insertions, 36 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 8ef06330fc66..de6f8e511c14 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -784,57 +784,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;