diff options
| author | Jonathan Brassow <jbrassow@redhat.com> | 2012-10-10 22:40:09 -0400 |
|---|---|---|
| committer | NeilBrown <neilb@suse.de> | 2012-10-10 22:40:09 -0400 |
| commit | eb6491236f283eb6ebc5421fcdb14b86701a7e36 (patch) | |
| tree | eb79232eac585fcf2a2ad15eff108ef873f72d67 | |
| parent | 2863b9eb44787adecba4f977d71d7fd876805b1c (diff) | |
DM RAID: Move 'rebuild' checking code to its own function
DM RAID: Move chunk of code to it's own function
The code that checks whether device replacements/rebuilds are possible given
a specific RAID type is moved to it's own function. It will further expand
when the code to check RAID10 is added. A separate function makes it easier
to read.
Signed-off-by: Jonathan Brassow <jbrassow@redhat.com>
Signed-off-by: NeilBrown <neilb@suse.de>
| -rw-r--r-- | drivers/md/dm-raid.c | 75 |
1 files changed, 50 insertions, 25 deletions
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index 982e3e390c45..10635e965fec 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 | */ | ||
| 349 | static 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 | |||
| 381 | too_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; |
