aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/md.txt8
-rw-r--r--drivers/md/md.c60
2 files changed, 68 insertions, 0 deletions
diff --git a/Documentation/md.txt b/Documentation/md.txt
index 7b3d471bb9f0..b8d172b254f7 100644
--- a/Documentation/md.txt
+++ b/Documentation/md.txt
@@ -200,6 +200,14 @@ All md devices contain:
200 This can be written only while the array is being assembled, not 200 This can be written only while the array is being assembled, not
201 after it is started. 201 after it is started.
202 202
203 new_dev
204 This file can be written but not read. The value written should
205 be a block device number as major:minor. e.g. 8:0
206 This will cause that device to be attached to the array, if it is
207 available. It will then appear at md/dev-XXX (depending on the
208 name of the device) and further configuration is then possible.
209
210
203As component devices are added to an md array, they appear in the 'md' 211As component devices are added to an md array, they appear in the 'md'
204directory as new directories named 212directory as new directories named
205 dev-XXX 213 dev-XXX
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)
1987static struct md_sysfs_entry md_chunk_size = 1987static 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
1990static ssize_t
1991null_show(mddev_t *mddev, char *page)
1992{
1993 return -EINVAL;
1994}
1995
1996static ssize_t
1997new_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
2047static struct md_sysfs_entry md_new_device =
2048__ATTR(new_dev, 0200, null_show, new_dev_store);
1990 2049
1991static ssize_t 2050static ssize_t
1992size_show(mddev_t *mddev, char *page) 2051size_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