md: refactor mddev_find_or_alloc
authorChristoph Hellwig <hch@lst.de>
Mon, 12 Apr 2021 08:05:29 +0000 (10:05 +0200)
committerSong Liu <song@kernel.org>
Thu, 15 Apr 2021 18:06:32 +0000 (11:06 -0700)
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>
drivers/md/md.c

index 8ef06330fc66e4097ed0c0c676fe1ae3e842310a..de6f8e511c14e7ec2172315bee810653837d9642 100644 (file)
@@ -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;