diff options
Diffstat (limited to 'drivers/md/md.c')
| -rw-r--r-- | drivers/md/md.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 40ac7fbab61f..825e235b791b 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
| @@ -1987,6 +1987,65 @@ chunk_size_store(mddev_t *mddev, const char *buf, size_t len) | |||
| 1987 | static struct md_sysfs_entry md_chunk_size = | 1987 | static struct md_sysfs_entry md_chunk_size = |
| 1988 | __ATTR(chunk_size, 0644, chunk_size_show, chunk_size_store); | 1988 | __ATTR(chunk_size, 0644, chunk_size_show, chunk_size_store); |
| 1989 | 1989 | ||
| 1990 | static ssize_t | ||
| 1991 | null_show(mddev_t *mddev, char *page) | ||
| 1992 | { | ||
| 1993 | return -EINVAL; | ||
| 1994 | } | ||
| 1995 | |||
| 1996 | static ssize_t | ||
| 1997 | new_dev_store(mddev_t *mddev, const char *buf, size_t len) | ||
| 1998 | { | ||
| 1999 | /* buf must be %d:%d\n? giving major and minor numbers */ | ||
| 2000 | /* The new device is added to the array. | ||
| 2001 | * If the array has a persistent superblock, we read the | ||
| 2002 | * superblock to initialise info and check validity. | ||
| 2003 | * Otherwise, only checking done is that in bind_rdev_to_array, | ||
| 2004 | * which mainly checks size. | ||
| 2005 | */ | ||
| 2006 | char *e; | ||
| 2007 | int major = simple_strtoul(buf, &e, 10); | ||
| 2008 | int minor; | ||
| 2009 | dev_t dev; | ||
| 2010 | mdk_rdev_t *rdev; | ||
| 2011 | int err; | ||
| 2012 | |||
| 2013 | if (!*buf || *e != ':' || !e[1] || e[1] == '\n') | ||
| 2014 | return -EINVAL; | ||
| 2015 | minor = simple_strtoul(e+1, &e, 10); | ||
| 2016 | if (*e && *e != '\n') | ||
| 2017 | return -EINVAL; | ||
| 2018 | dev = MKDEV(major, minor); | ||
| 2019 | if (major != MAJOR(dev) || | ||
| 2020 | minor != MINOR(dev)) | ||
| 2021 | return -EOVERFLOW; | ||
| 2022 | |||
| 2023 | |||
| 2024 | if (mddev->persistent) { | ||
| 2025 | rdev = md_import_device(dev, mddev->major_version, | ||
| 2026 | mddev->minor_version); | ||
| 2027 | if (!IS_ERR(rdev) && !list_empty(&mddev->disks)) { | ||
| 2028 | mdk_rdev_t *rdev0 = list_entry(mddev->disks.next, | ||
| 2029 | mdk_rdev_t, same_set); | ||
| 2030 | err = super_types[mddev->major_version] | ||
| 2031 | .load_super(rdev, rdev0, mddev->minor_version); | ||
| 2032 | if (err < 0) | ||
| 2033 | goto out; | ||
| 2034 | } | ||
| 2035 | } else | ||
| 2036 | rdev = md_import_device(dev, -1, -1); | ||
| 2037 | |||
| 2038 | if (IS_ERR(rdev)) | ||
| 2039 | return PTR_ERR(rdev); | ||
| 2040 | err = bind_rdev_to_array(rdev, mddev); | ||
| 2041 | out: | ||
| 2042 | if (err) | ||
| 2043 | export_rdev(rdev); | ||
| 2044 | return err ? err : len; | ||
| 2045 | } | ||
| 2046 | |||
| 2047 | static struct md_sysfs_entry md_new_device = | ||
| 2048 | __ATTR(new_dev, 0200, null_show, new_dev_store); | ||
| 1990 | 2049 | ||
| 1991 | static ssize_t | 2050 | static ssize_t |
| 1992 | size_show(mddev_t *mddev, char *page) | 2051 | size_show(mddev_t *mddev, char *page) |
| @@ -2144,6 +2203,7 @@ static struct attribute *md_default_attrs[] = { | |||
| 2144 | &md_chunk_size.attr, | 2203 | &md_chunk_size.attr, |
| 2145 | &md_size.attr, | 2204 | &md_size.attr, |
| 2146 | &md_metadata.attr, | 2205 | &md_metadata.attr, |
| 2206 | &md_new_device.attr, | ||
| 2147 | NULL, | 2207 | NULL, |
| 2148 | }; | 2208 | }; |
| 2149 | 2209 | ||
