summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2021-04-12 10:05:30 +0200
committerSong Liu <song@kernel.org>2021-04-15 11:06:32 -0700
commit0d809b3837a0bede8f58a67e303e339585777bf4 (patch)
treed5b2a07dfb1302dde7fe28666d02f87295986eb2
parentd144fe6ff176d79efd411e520103a99e11874c36 (diff)
downloadlinux-0d809b3837a0bede8f58a67e303e339585777bf4.tar.bz2
md: do not return existing mddevs from mddev_find_or_alloc
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>
-rw-r--r--drivers/md/md.c46
1 files changed, 23 insertions, 23 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index de6f8e511c14..af9bdb907b2b 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -782,26 +782,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);
@@ -809,6 +807,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;
@@ -822,7 +821,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;
@@ -5661,29 +5660,29 @@ 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);
mutex_lock(&disks_mutex);
- error = -EEXIST;
- if (mddev->gendisk)
- goto abort;
+ 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.
@@ -5695,6 +5694,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 abort;
}
spin_unlock(&all_mddevs_lock);