aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/md/dm-raid.c75
1 files changed, 50 insertions, 25 deletions
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
index 982e3e390c4..10635e965fe 100644
--- a/drivers/md/dm-raid.c
+++ b/drivers/md/dm-raid.c
@@ -338,6 +338,52 @@ static int validate_region_size(struct raid_set *rs, unsigned long region_size)
338} 338}
339 339
340/* 340/*
341 * validate_rebuild_devices
342 * @rs
343 *
344 * Determine if the devices specified for rebuild can result in a valid
345 * usable array that is capable of rebuilding the given devices.
346 *
347 * Returns: 0 on success, -EINVAL on failure.
348 */
349static int validate_rebuild_devices(struct raid_set *rs)
350{
351 unsigned i, rebuild_cnt = 0;
352
353 if (!(rs->print_flags & DMPF_REBUILD))
354 return 0;
355
356 for (i = 0; i < rs->md.raid_disks; i++)
357 if (!test_bit(In_sync, &rs->dev[i].rdev.flags))
358 rebuild_cnt++;
359
360 switch (rs->raid_type->level) {
361 case 1:
362 if (rebuild_cnt >= rs->md.raid_disks)
363 goto too_many;
364 break;
365 case 4:
366 case 5:
367 case 6:
368 if (rebuild_cnt > rs->raid_type->parity_devs)
369 goto too_many;
370 break;
371 case 10:
372 default:
373 DMERR("The rebuild parameter is not supported for %s",
374 rs->raid_type->name);
375 rs->ti->error = "Rebuild not supported for this RAID type";
376 return -EINVAL;
377 }
378
379 return 0;
380
381too_many:
382 rs->ti->error = "Too many rebuild devices specified";
383 return -EINVAL;
384}
385
386/*
341 * Possible arguments are... 387 * Possible arguments are...
342 * <chunk_size> [optional_args] 388 * <chunk_size> [optional_args]
343 * 389 *
@@ -365,7 +411,7 @@ static int parse_raid_params(struct raid_set *rs, char **argv,
365{ 411{
366 char *raid10_format = "near"; 412 char *raid10_format = "near";
367 unsigned raid10_copies = 2; 413 unsigned raid10_copies = 2;
368 unsigned i, rebuild_cnt = 0; 414 unsigned i;
369 unsigned long value, region_size = 0; 415 unsigned long value, region_size = 0;
370 sector_t sectors_per_dev = rs->ti->len; 416 sector_t sectors_per_dev = rs->ti->len;
371 sector_t max_io_len; 417 sector_t max_io_len;
@@ -461,30 +507,6 @@ static int parse_raid_params(struct raid_set *rs, char **argv,
461 507
462 /* Parameters that take a numeric value are checked here */ 508 /* Parameters that take a numeric value are checked here */
463 if (!strcasecmp(key, "rebuild")) { 509 if (!strcasecmp(key, "rebuild")) {
464 rebuild_cnt++;
465
466 switch (rs->raid_type->level) {
467 case 1:
468 if (rebuild_cnt >= rs->md.raid_disks) {
469 rs->ti->error = "Too many rebuild devices specified";
470 return -EINVAL;
471 }
472 break;
473 case 4:
474 case 5:
475 case 6:
476 if (rebuild_cnt > rs->raid_type->parity_devs) {
477 rs->ti->error = "Too many rebuild devices specified for given RAID type";
478 return -EINVAL;
479 }
480 break;
481 case 10:
482 default:
483 DMERR("The rebuild parameter is not supported for %s", rs->raid_type->name);
484 rs->ti->error = "Rebuild not supported for this RAID type";
485 return -EINVAL;
486 }
487
488 if (value > rs->md.raid_disks) { 510 if (value > rs->md.raid_disks) {
489 rs->ti->error = "Invalid rebuild index given"; 511 rs->ti->error = "Invalid rebuild index given";
490 return -EINVAL; 512 return -EINVAL;
@@ -608,6 +630,9 @@ static int parse_raid_params(struct raid_set *rs, char **argv,
608 } 630 }
609 rs->md.dev_sectors = sectors_per_dev; 631 rs->md.dev_sectors = sectors_per_dev;
610 632
633 if (validate_rebuild_devices(rs))
634 return -EINVAL;
635
611 /* Assume there are no metadata devices until the drives are parsed */ 636 /* Assume there are no metadata devices until the drives are parsed */
612 rs->md.persistent = 0; 637 rs->md.persistent = 0;
613 rs->md.external = 1; 638 rs->md.external = 1;