Commit 34cb92c0 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Jens Axboe

md: return the allocated devices from md_alloc

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: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarHannes Reinecke <hare@suse.de>
Reviewed-and-tested-by: default avatarLogan Gunthorpe <logang@deltatee.com>
Signed-off-by: default avatarSong Liu <song@kernel.org>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent a1108768
...@@ -125,7 +125,6 @@ static void __init md_setup_drive(struct md_setup_args *args) ...@@ -125,7 +125,6 @@ static void __init md_setup_drive(struct md_setup_args *args)
char *devname = args->device_names; char *devname = args->device_names;
dev_t devices[MD_SB_DISKS + 1], mdev; dev_t devices[MD_SB_DISKS + 1], mdev;
struct mdu_array_info_s ainfo = { }; struct mdu_array_info_s ainfo = { };
struct block_device *bdev;
struct mddev *mddev; struct mddev *mddev;
int err = 0, i; int err = 0, i;
char name[16]; char name[16];
...@@ -169,25 +168,16 @@ static void __init md_setup_drive(struct md_setup_args *args) ...@@ -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); pr_info("md: Loading %s: %s\n", name, args->device_names);
md_alloc(mdev, name); mddev = md_alloc(mdev, name);
bdev = blkdev_get_by_dev(mdev, FMODE_READ, NULL); if (IS_ERR(mddev)) {
if (IS_ERR(bdev)) { pr_err("md: md_alloc failed - cannot start array %s\n", name);
pr_err("md: open failed - cannot start array %s\n", name);
return; 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); err = mddev_lock(mddev);
if (err) { if (err) {
pr_err("md: failed to lock array %s\n", name); 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) { if (!list_empty(&mddev->disks) || mddev->raid_disks) {
...@@ -231,8 +221,8 @@ static void __init md_setup_drive(struct md_setup_args *args) ...@@ -231,8 +221,8 @@ static void __init md_setup_drive(struct md_setup_args *args)
pr_warn("md: starting %s failed\n", name); pr_warn("md: starting %s failed\n", name);
out_unlock: out_unlock:
mddev_unlock(mddev); mddev_unlock(mddev);
out_blkdev_put: out_mddev_put:
blkdev_put(bdev, FMODE_READ); mddev_put(mddev);
} }
static int __init raid_setup(char *str) static int __init raid_setup(char *str)
......
...@@ -635,7 +635,7 @@ static inline struct mddev *mddev_get(struct mddev *mddev) ...@@ -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_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)) if (!atomic_dec_and_lock(&mddev->active, &all_mddevs_lock))
return; return;
...@@ -714,24 +714,6 @@ static dev_t mddev_alloc_unit(void) ...@@ -714,24 +714,6 @@ static dev_t mddev_alloc_unit(void)
return dev; 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) static struct mddev *mddev_alloc(dev_t unit)
{ {
struct mddev *new; struct mddev *new;
...@@ -5614,7 +5596,7 @@ int mddev_init_writes_pending(struct mddev *mddev) ...@@ -5614,7 +5596,7 @@ int mddev_init_writes_pending(struct mddev *mddev)
} }
EXPORT_SYMBOL_GPL(mddev_init_writes_pending); 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 * If dev is zero, name is the name of a device to allocate with
...@@ -5706,17 +5688,16 @@ int md_alloc(dev_t dev, char *name) ...@@ -5706,17 +5688,16 @@ int md_alloc(dev_t dev, char *name)
* different from a normal close on last release now. * different from a normal close on last release now.
*/ */
mddev->hold_active = 0; mddev->hold_active = 0;
goto done; mutex_unlock(&disks_mutex);
mddev_put(mddev);
return ERR_PTR(error);
} }
kobject_uevent(&mddev->kobj, KOBJ_ADD); kobject_uevent(&mddev->kobj, KOBJ_ADD);
mddev->sysfs_state = sysfs_get_dirent_safe(mddev->kobj.sd, "array_state"); mddev->sysfs_state = sysfs_get_dirent_safe(mddev->kobj.sd, "array_state");
mddev->sysfs_level = sysfs_get_dirent_safe(mddev->kobj.sd, "level"); mddev->sysfs_level = sysfs_get_dirent_safe(mddev->kobj.sd, "level");
done:
mutex_unlock(&disks_mutex); mutex_unlock(&disks_mutex);
mddev_put(mddev); return mddev;
return error;
out_put_disk: out_put_disk:
put_disk(disk); put_disk(disk);
...@@ -5724,7 +5705,17 @@ int md_alloc(dev_t dev, char *name) ...@@ -5724,7 +5705,17 @@ int md_alloc(dev_t dev, char *name)
mddev_free(mddev); mddev_free(mddev);
out_unlock: out_unlock:
mutex_unlock(&disks_mutex); 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) static void md_probe(dev_t dev)
...@@ -5732,7 +5723,7 @@ static void md_probe(dev_t dev) ...@@ -5732,7 +5723,7 @@ static void md_probe(dev_t dev)
if (MAJOR(dev) == MD_MAJOR && MINOR(dev) >= 512) if (MAJOR(dev) == MD_MAJOR && MINOR(dev) >= 512)
return; return;
if (create_on_open) 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) static int add_named_array(const char *val, const struct kernel_param *kp)
...@@ -5754,12 +5745,12 @@ static int add_named_array(const char *val, const struct kernel_param *kp) ...@@ -5754,12 +5745,12 @@ static int add_named_array(const char *val, const struct kernel_param *kp)
return -E2BIG; return -E2BIG;
strscpy(buf, val, len+1); strscpy(buf, val, len+1);
if (strncmp(buf, "md_", 3) == 0) if (strncmp(buf, "md_", 3) == 0)
return md_alloc(0, buf); return md_alloc_and_put(0, buf);
if (strncmp(buf, "md", 2) == 0 && if (strncmp(buf, "md", 2) == 0 &&
isdigit(buf[2]) && isdigit(buf[2]) &&
kstrtoul(buf+2, 10, &devnum) == 0 && kstrtoul(buf+2, 10, &devnum) == 0 &&
devnum <= MINORMASK) devnum <= MINORMASK)
return md_alloc(MKDEV(MD_MAJOR, devnum), NULL); return md_alloc_and_put(MKDEV(MD_MAJOR, devnum), NULL);
return -EINVAL; return -EINVAL;
} }
...@@ -6500,9 +6491,8 @@ static void autorun_devices(int part) ...@@ -6500,9 +6491,8 @@ static void autorun_devices(int part)
break; break;
} }
md_alloc(dev, NULL); mddev = md_alloc(dev, NULL);
mddev = mddev_find(dev); if (IS_ERR(mddev))
if (!mddev)
break; break;
if (mddev_lock(mddev)) if (mddev_lock(mddev))
......
...@@ -767,7 +767,8 @@ extern int md_integrity_add_rdev(struct md_rdev *rdev, struct mddev *mddev); ...@@ -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 int strict_strtoul_scaled(const char *cp, unsigned long *res, int scale);
extern void mddev_init(struct mddev *mddev); 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_run(struct mddev *mddev);
extern int md_start(struct mddev *mddev); extern int md_start(struct mddev *mddev);
extern void md_stop(struct mddev *mddev); extern void md_stop(struct mddev *mddev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment