aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.com>2017-04-12 02:26:13 -0400
committerShaohua Li <shli@fb.com>2017-04-12 15:30:11 -0400
commit039b7225e6e98783a7a7e79c52b29c437f29967d (patch)
tree02830472fe5f087223507e3cec16544eef02dbd4
parentfcd403aff643a120dbb3f1851337df5353ac8970 (diff)
md: allow creation of mdNNN arrays via md_mod/parameters/new_array
The intention when creating the "new_array" parameter and the possibility of having array names line "md_HOME" was to transition away from the old way of creating arrays and to eventually only use this new way. The "old" way of creating array is to create a device node in /dev and then open it. The act of opening creates the array. This is problematic because sometimes the device node can be opened when we don't want to create an array. This can easily happen when some rule triggered by udev looks at a device as it is being destroyed. The node in /dev continues to exist for a short period after an array is stopped, and opening it during this time recreates the array (as an inactive array). Unfortunately no clear plan for the transition was created. It is now time to fix that. This patch allows devices with numeric names, like "md999" to be created by writing to "new_array". This will only work if the minor number given is not already in use. This will allow mdadm to support the creation of arrays with numbers > 511 (currently not possible) by writing to new_array. mdadm can, at some point, use this approach to create *all* arrays, which will allow the transition to only using the new-way. Signed-off-by: NeilBrown <neilb@suse.com> Acted-by: Coly Li <colyli@suse.de> Signed-off-by: Shaohua Li <shli@fb.com>
-rw-r--r--drivers/md/md.c36
1 files changed, 30 insertions, 6 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 5022be183390..554bf213c043 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -5162,6 +5162,15 @@ static void no_op(struct percpu_ref *r) {}
5162 5162
5163static int md_alloc(dev_t dev, char *name) 5163static int md_alloc(dev_t dev, char *name)
5164{ 5164{
5165 /*
5166 * If dev is zero, name is the name of a device to allocate with
5167 * an arbitrary minor number. It will be "md_???"
5168 * If dev is non-zero it must be a device number with a MAJOR of
5169 * MD_MAJOR or mdp_major. In this case, if "name" is NULL, then
5170 * the device is being created by opening a node in /dev.
5171 * If "name" is not NULL, the device is being created by
5172 * writing to /sys/module/md_mod/parameters/new_array.
5173 */
5165 static DEFINE_MUTEX(disks_mutex); 5174 static DEFINE_MUTEX(disks_mutex);
5166 struct mddev *mddev = mddev_find(dev); 5175 struct mddev *mddev = mddev_find(dev);
5167 struct gendisk *disk; 5176 struct gendisk *disk;
@@ -5187,7 +5196,7 @@ static int md_alloc(dev_t dev, char *name)
5187 if (mddev->gendisk) 5196 if (mddev->gendisk)
5188 goto abort; 5197 goto abort;
5189 5198
5190 if (name) { 5199 if (name && !dev) {
5191 /* Need to ensure that 'name' is not a duplicate. 5200 /* Need to ensure that 'name' is not a duplicate.
5192 */ 5201 */
5193 struct mddev *mddev2; 5202 struct mddev *mddev2;
@@ -5201,6 +5210,11 @@ static int md_alloc(dev_t dev, char *name)
5201 } 5210 }
5202 spin_unlock(&all_mddevs_lock); 5211 spin_unlock(&all_mddevs_lock);
5203 } 5212 }
5213 if (name && dev)
5214 /*
5215 * Creating /dev/mdNNN via "newarray", so adjust hold_active.
5216 */
5217 mddev->hold_active = UNTIL_STOP;
5204 5218
5205 error = -ENOMEM; 5219 error = -ENOMEM;
5206 mddev->queue = blk_alloc_queue(GFP_KERNEL); 5220 mddev->queue = blk_alloc_queue(GFP_KERNEL);
@@ -5277,21 +5291,31 @@ static struct kobject *md_probe(dev_t dev, int *part, void *data)
5277 5291
5278static int add_named_array(const char *val, struct kernel_param *kp) 5292static int add_named_array(const char *val, struct kernel_param *kp)
5279{ 5293{
5280 /* val must be "md_*" where * is not all digits. 5294 /*
5281 * We allocate an array with a large free minor number, and 5295 * val must be "md_*" or "mdNNN".
5296 * For "md_*" we allocate an array with a large free minor number, and
5282 * set the name to val. val must not already be an active name. 5297 * set the name to val. val must not already be an active name.
5298 * For "mdNNN" we allocate an array with the minor number NNN
5299 * which must not already be in use.
5283 */ 5300 */
5284 int len = strlen(val); 5301 int len = strlen(val);
5285 char buf[DISK_NAME_LEN]; 5302 char buf[DISK_NAME_LEN];
5303 unsigned long devnum;
5286 5304
5287 while (len && val[len-1] == '\n') 5305 while (len && val[len-1] == '\n')
5288 len--; 5306 len--;
5289 if (len >= DISK_NAME_LEN) 5307 if (len >= DISK_NAME_LEN)
5290 return -E2BIG; 5308 return -E2BIG;
5291 strlcpy(buf, val, len+1); 5309 strlcpy(buf, val, len+1);
5292 if (strncmp(buf, "md_", 3) != 0) 5310 if (strncmp(buf, "md_", 3) == 0)
5293 return -EINVAL; 5311 return md_alloc(0, buf);
5294 return md_alloc(0, buf); 5312 if (strncmp(buf, "md", 2) == 0 &&
5313 isdigit(buf[2]) &&
5314 kstrtoul(buf+2, 10, &devnum) == 0 &&
5315 devnum <= MINORMASK)
5316 return md_alloc(MKDEV(MD_MAJOR, devnum), NULL);
5317
5318 return -EINVAL;
5295} 5319}
5296 5320
5297static void md_safemode_timeout(unsigned long data) 5321static void md_safemode_timeout(unsigned long data)