Skip to content

Commit

Permalink
md: return the allocated devices from md_alloc
Browse files Browse the repository at this point in the history
Two callers of md_alloc want to use the newly allocated devices, so
return it instead of letting them find it cumbersomely after the
allocation.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Reviewed-and-tested-by: Logan Gunthorpe <logang@deltatee.com>
Signed-off-by: Song Liu <song@kernel.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
  • Loading branch information
Christoph Hellwig authored and axboe committed Aug 2, 2022
1 parent a110876 commit 34cb92c
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 49 deletions.
22 changes: 6 additions & 16 deletions drivers/md/md-autodetect.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ static void __init md_setup_drive(struct md_setup_args *args)
char *devname = args->device_names;
dev_t devices[MD_SB_DISKS + 1], mdev;
struct mdu_array_info_s ainfo = { };
struct block_device *bdev;
struct mddev *mddev;
int err = 0, i;
char name[16];
Expand Down Expand Up @@ -169,25 +168,16 @@ static void __init md_setup_drive(struct md_setup_args *args)

pr_info("md: Loading %s: %s\n", name, args->device_names);

md_alloc(mdev, name);
bdev = blkdev_get_by_dev(mdev, FMODE_READ, NULL);
if (IS_ERR(bdev)) {
pr_err("md: open failed - cannot start array %s\n", name);
mddev = md_alloc(mdev, name);
if (IS_ERR(mddev)) {
pr_err("md: md_alloc failed - cannot start array %s\n", name);
return;
}

err = -EIO;
if (WARN(bdev->bd_disk->fops != &md_fops,
"Opening block device %x resulted in non-md device\n",
mdev))
goto out_blkdev_put;

mddev = bdev->bd_disk->private_data;

err = mddev_lock(mddev);
if (err) {
pr_err("md: failed to lock array %s\n", name);
goto out_blkdev_put;
goto out_mddev_put;
}

if (!list_empty(&mddev->disks) || mddev->raid_disks) {
Expand Down Expand Up @@ -231,8 +221,8 @@ static void __init md_setup_drive(struct md_setup_args *args)
pr_warn("md: starting %s failed\n", name);
out_unlock:
mddev_unlock(mddev);
out_blkdev_put:
blkdev_put(bdev, FMODE_READ);
out_mddev_put:
mddev_put(mddev);
}

static int __init raid_setup(char *str)
Expand Down
54 changes: 22 additions & 32 deletions drivers/md/md.c
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,7 @@ static inline struct mddev *mddev_get(struct mddev *mddev)

static void mddev_delayed_delete(struct work_struct *ws);

static void mddev_put(struct mddev *mddev)
void mddev_put(struct mddev *mddev)
{
if (!atomic_dec_and_lock(&mddev->active, &all_mddevs_lock))
return;
Expand Down Expand Up @@ -714,24 +714,6 @@ static dev_t mddev_alloc_unit(void)
return dev;
}

#ifndef MODULE
static struct mddev *mddev_find(dev_t unit)
{
struct mddev *mddev;

if (MAJOR(unit) != MD_MAJOR)
unit &= ~((1 << MdpMinorShift) - 1);

spin_lock(&all_mddevs_lock);
mddev = mddev_find_locked(unit);
if (mddev && !mddev_get(mddev))
mddev = NULL;
spin_unlock(&all_mddevs_lock);

return mddev;
}
#endif

static struct mddev *mddev_alloc(dev_t unit)
{
struct mddev *new;
Expand Down Expand Up @@ -5614,7 +5596,7 @@ int mddev_init_writes_pending(struct mddev *mddev)
}
EXPORT_SYMBOL_GPL(mddev_init_writes_pending);

int md_alloc(dev_t dev, char *name)
struct mddev *md_alloc(dev_t dev, char *name)
{
/*
* If dev is zero, name is the name of a device to allocate with
Expand Down Expand Up @@ -5706,33 +5688,42 @@ int md_alloc(dev_t dev, char *name)
* different from a normal close on last release now.
*/
mddev->hold_active = 0;
goto done;
mutex_unlock(&disks_mutex);
mddev_put(mddev);
return ERR_PTR(error);
}

kobject_uevent(&mddev->kobj, KOBJ_ADD);
mddev->sysfs_state = sysfs_get_dirent_safe(mddev->kobj.sd, "array_state");
mddev->sysfs_level = sysfs_get_dirent_safe(mddev->kobj.sd, "level");

done:
mutex_unlock(&disks_mutex);
mddev_put(mddev);
return error;
return mddev;

out_put_disk:
put_disk(disk);
out_free_mddev:
mddev_free(mddev);
out_unlock:
mutex_unlock(&disks_mutex);
return error;
return ERR_PTR(error);
}

static int md_alloc_and_put(dev_t dev, char *name)
{
struct mddev *mddev = md_alloc(dev, name);

if (IS_ERR(mddev))
return PTR_ERR(mddev);
mddev_put(mddev);
return 0;
}

static void md_probe(dev_t dev)
{
if (MAJOR(dev) == MD_MAJOR && MINOR(dev) >= 512)
return;
if (create_on_open)
md_alloc(dev, NULL);
md_alloc_and_put(dev, NULL);
}

static int add_named_array(const char *val, const struct kernel_param *kp)
Expand All @@ -5754,12 +5745,12 @@ static int add_named_array(const char *val, const struct kernel_param *kp)
return -E2BIG;
strscpy(buf, val, len+1);
if (strncmp(buf, "md_", 3) == 0)
return md_alloc(0, buf);
return md_alloc_and_put(0, buf);
if (strncmp(buf, "md", 2) == 0 &&
isdigit(buf[2]) &&
kstrtoul(buf+2, 10, &devnum) == 0 &&
devnum <= MINORMASK)
return md_alloc(MKDEV(MD_MAJOR, devnum), NULL);
return md_alloc_and_put(MKDEV(MD_MAJOR, devnum), NULL);

return -EINVAL;
}
Expand Down Expand Up @@ -6500,9 +6491,8 @@ static void autorun_devices(int part)
break;
}

md_alloc(dev, NULL);
mddev = mddev_find(dev);
if (!mddev)
mddev = md_alloc(dev, NULL);
if (IS_ERR(mddev))
break;

if (mddev_lock(mddev))
Expand Down
3 changes: 2 additions & 1 deletion drivers/md/md.h
Original file line number Diff line number Diff line change
Expand Up @@ -767,7 +767,8 @@ extern int md_integrity_add_rdev(struct md_rdev *rdev, struct mddev *mddev);
extern int strict_strtoul_scaled(const char *cp, unsigned long *res, int scale);

extern void mddev_init(struct mddev *mddev);
int md_alloc(dev_t dev, char *name);
struct mddev *md_alloc(dev_t dev, char *name);
void mddev_put(struct mddev *mddev);
extern int md_run(struct mddev *mddev);
extern int md_start(struct mddev *mddev);
extern void md_stop(struct mddev *mddev);
Expand Down

0 comments on commit 34cb92c

Please sign in to comment.