Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: 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>

authored by

Christoph Hellwig and committed by
Jens Axboe
34cb92c0 a1108768

+30 -49
+6 -16
drivers/md/md-autodetect.c
··· 125 125 char *devname = args->device_names; 126 126 dev_t devices[MD_SB_DISKS + 1], mdev; 127 127 struct mdu_array_info_s ainfo = { }; 128 - struct block_device *bdev; 129 128 struct mddev *mddev; 130 129 int err = 0, i; 131 130 char name[16]; ··· 168 169 169 170 pr_info("md: Loading %s: %s\n", name, args->device_names); 170 171 171 - md_alloc(mdev, name); 172 - bdev = blkdev_get_by_dev(mdev, FMODE_READ, NULL); 173 - if (IS_ERR(bdev)) { 174 - pr_err("md: open failed - cannot start array %s\n", name); 172 + mddev = md_alloc(mdev, name); 173 + if (IS_ERR(mddev)) { 174 + pr_err("md: md_alloc failed - cannot start array %s\n", name); 175 175 return; 176 176 } 177 - 178 - err = -EIO; 179 - if (WARN(bdev->bd_disk->fops != &md_fops, 180 - "Opening block device %x resulted in non-md device\n", 181 - mdev)) 182 - goto out_blkdev_put; 183 - 184 - mddev = bdev->bd_disk->private_data; 185 177 186 178 err = mddev_lock(mddev); 187 179 if (err) { 188 180 pr_err("md: failed to lock array %s\n", name); 189 - goto out_blkdev_put; 181 + goto out_mddev_put; 190 182 } 191 183 192 184 if (!list_empty(&mddev->disks) || mddev->raid_disks) { ··· 221 231 pr_warn("md: starting %s failed\n", name); 222 232 out_unlock: 223 233 mddev_unlock(mddev); 224 - out_blkdev_put: 225 - blkdev_put(bdev, FMODE_READ); 234 + out_mddev_put: 235 + mddev_put(mddev); 226 236 } 227 237 228 238 static int __init raid_setup(char *str)
+22 -32
drivers/md/md.c
··· 635 635 636 636 static void mddev_delayed_delete(struct work_struct *ws); 637 637 638 - static void mddev_put(struct mddev *mddev) 638 + void mddev_put(struct mddev *mddev) 639 639 { 640 640 if (!atomic_dec_and_lock(&mddev->active, &all_mddevs_lock)) 641 641 return; ··· 713 713 714 714 return dev; 715 715 } 716 - 717 - #ifndef MODULE 718 - static struct mddev *mddev_find(dev_t unit) 719 - { 720 - struct mddev *mddev; 721 - 722 - if (MAJOR(unit) != MD_MAJOR) 723 - unit &= ~((1 << MdpMinorShift) - 1); 724 - 725 - spin_lock(&all_mddevs_lock); 726 - mddev = mddev_find_locked(unit); 727 - if (mddev && !mddev_get(mddev)) 728 - mddev = NULL; 729 - spin_unlock(&all_mddevs_lock); 730 - 731 - return mddev; 732 - } 733 - #endif 734 716 735 717 static struct mddev *mddev_alloc(dev_t unit) 736 718 { ··· 5596 5614 } 5597 5615 EXPORT_SYMBOL_GPL(mddev_init_writes_pending); 5598 5616 5599 - int md_alloc(dev_t dev, char *name) 5617 + struct mddev *md_alloc(dev_t dev, char *name) 5600 5618 { 5601 5619 /* 5602 5620 * If dev is zero, name is the name of a device to allocate with ··· 5688 5706 * different from a normal close on last release now. 5689 5707 */ 5690 5708 mddev->hold_active = 0; 5691 - goto done; 5709 + mutex_unlock(&disks_mutex); 5710 + mddev_put(mddev); 5711 + return ERR_PTR(error); 5692 5712 } 5693 5713 5694 5714 kobject_uevent(&mddev->kobj, KOBJ_ADD); 5695 5715 mddev->sysfs_state = sysfs_get_dirent_safe(mddev->kobj.sd, "array_state"); 5696 5716 mddev->sysfs_level = sysfs_get_dirent_safe(mddev->kobj.sd, "level"); 5697 - 5698 - done: 5699 5717 mutex_unlock(&disks_mutex); 5700 - mddev_put(mddev); 5701 - return error; 5718 + return mddev; 5702 5719 5703 5720 out_put_disk: 5704 5721 put_disk(disk); ··· 5705 5724 mddev_free(mddev); 5706 5725 out_unlock: 5707 5726 mutex_unlock(&disks_mutex); 5708 - return error; 5727 + return ERR_PTR(error); 5728 + } 5729 + 5730 + static int md_alloc_and_put(dev_t dev, char *name) 5731 + { 5732 + struct mddev *mddev = md_alloc(dev, name); 5733 + 5734 + if (IS_ERR(mddev)) 5735 + return PTR_ERR(mddev); 5736 + mddev_put(mddev); 5737 + return 0; 5709 5738 } 5710 5739 5711 5740 static void md_probe(dev_t dev) ··· 5723 5732 if (MAJOR(dev) == MD_MAJOR && MINOR(dev) >= 512) 5724 5733 return; 5725 5734 if (create_on_open) 5726 - md_alloc(dev, NULL); 5735 + md_alloc_and_put(dev, NULL); 5727 5736 } 5728 5737 5729 5738 static int add_named_array(const char *val, const struct kernel_param *kp) ··· 5745 5754 return -E2BIG; 5746 5755 strscpy(buf, val, len+1); 5747 5756 if (strncmp(buf, "md_", 3) == 0) 5748 - return md_alloc(0, buf); 5757 + return md_alloc_and_put(0, buf); 5749 5758 if (strncmp(buf, "md", 2) == 0 && 5750 5759 isdigit(buf[2]) && 5751 5760 kstrtoul(buf+2, 10, &devnum) == 0 && 5752 5761 devnum <= MINORMASK) 5753 - return md_alloc(MKDEV(MD_MAJOR, devnum), NULL); 5762 + return md_alloc_and_put(MKDEV(MD_MAJOR, devnum), NULL); 5754 5763 5755 5764 return -EINVAL; 5756 5765 } ··· 6491 6500 break; 6492 6501 } 6493 6502 6494 - md_alloc(dev, NULL); 6495 - mddev = mddev_find(dev); 6496 - if (!mddev) 6503 + mddev = md_alloc(dev, NULL); 6504 + if (IS_ERR(mddev)) 6497 6505 break; 6498 6506 6499 6507 if (mddev_lock(mddev))
+2 -1
drivers/md/md.h
··· 767 767 extern int strict_strtoul_scaled(const char *cp, unsigned long *res, int scale); 768 768 769 769 extern void mddev_init(struct mddev *mddev); 770 - int md_alloc(dev_t dev, char *name); 770 + struct mddev *md_alloc(dev_t dev, char *name); 771 + void mddev_put(struct mddev *mddev); 771 772 extern int md_run(struct mddev *mddev); 772 773 extern int md_start(struct mddev *mddev); 773 774 extern void md_stop(struct mddev *mddev);