diff options
| author | Jonathan Brassow <jbrassow@redhat.com> | 2012-10-10 22:40:24 -0400 |
|---|---|---|
| committer | NeilBrown <neilb@suse.de> | 2012-10-10 22:40:24 -0400 |
| commit | 4ec1e369af83f7ecdfbd48a905e44fc9910115ba (patch) | |
| tree | 5e7287f870140e041190604ede472ae4d7fa2baf /drivers | |
| parent | eb6491236f283eb6ebc5421fcdb14b86701a7e36 (diff) | |
DM RAID: Add rebuild capability for RAID10
DM RAID: Add code to validate replacement slots for RAID10 arrays
RAID10 can handle 'copies - 1' failures for each mirror group. This code
ensures the user has provided a valid array - one whose devices specified for
rebuild do not exceed the amount of redundancy available.
Signed-off-by: Jonathan Brassow <jbrassow@redhat.com>
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/md/dm-raid.c | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index 10635e965fec..4e79ebaab3c1 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c | |||
| @@ -349,6 +349,7 @@ static int validate_region_size(struct raid_set *rs, unsigned long region_size) | |||
| 349 | static int validate_rebuild_devices(struct raid_set *rs) | 349 | static int validate_rebuild_devices(struct raid_set *rs) |
| 350 | { | 350 | { |
| 351 | unsigned i, rebuild_cnt = 0; | 351 | unsigned i, rebuild_cnt = 0; |
| 352 | unsigned rebuilds_per_group, copies, d; | ||
| 352 | 353 | ||
| 353 | if (!(rs->print_flags & DMPF_REBUILD)) | 354 | if (!(rs->print_flags & DMPF_REBUILD)) |
| 354 | return 0; | 355 | return 0; |
| @@ -369,6 +370,37 @@ static int validate_rebuild_devices(struct raid_set *rs) | |||
| 369 | goto too_many; | 370 | goto too_many; |
| 370 | break; | 371 | break; |
| 371 | case 10: | 372 | case 10: |
| 373 | copies = raid10_md_layout_to_copies(rs->md.layout); | ||
| 374 | if (rebuild_cnt < copies) | ||
| 375 | break; | ||
| 376 | |||
| 377 | /* | ||
| 378 | * It is possible to have a higher rebuild count for RAID10, | ||
| 379 | * as long as the failed devices occur in different mirror | ||
| 380 | * groups (i.e. different stripes). | ||
| 381 | * | ||
| 382 | * Right now, we only allow for "near" copies. When other | ||
| 383 | * formats are added, we will have to check those too. | ||
| 384 | * | ||
| 385 | * When checking "near" format, make sure no adjacent devices | ||
| 386 | * have failed beyond what can be handled. In addition to the | ||
| 387 | * simple case where the number of devices is a multiple of the | ||
| 388 | * number of copies, we must also handle cases where the number | ||
| 389 | * of devices is not a multiple of the number of copies. | ||
| 390 | * E.g. dev1 dev2 dev3 dev4 dev5 | ||
| 391 | * A A B B C | ||
| 392 | * C D D E E | ||
| 393 | */ | ||
| 394 | rebuilds_per_group = 0; | ||
| 395 | for (i = 0; i < rs->md.raid_disks * copies; i++) { | ||
| 396 | d = i % rs->md.raid_disks; | ||
| 397 | if (!test_bit(In_sync, &rs->dev[d].rdev.flags) && | ||
| 398 | (++rebuilds_per_group >= copies)) | ||
| 399 | goto too_many; | ||
| 400 | if (!((i + 1) % copies)) | ||
| 401 | rebuilds_per_group = 0; | ||
| 402 | } | ||
| 403 | break; | ||
| 372 | default: | 404 | default: |
| 373 | DMERR("The rebuild parameter is not supported for %s", | 405 | DMERR("The rebuild parameter is not supported for %s", |
| 374 | rs->raid_type->name); | 406 | rs->raid_type->name); |
| @@ -1385,7 +1417,7 @@ static void raid_resume(struct dm_target *ti) | |||
| 1385 | 1417 | ||
| 1386 | static struct target_type raid_target = { | 1418 | static struct target_type raid_target = { |
| 1387 | .name = "raid", | 1419 | .name = "raid", |
| 1388 | .version = {1, 3, 0}, | 1420 | .version = {1, 3, 1}, |
| 1389 | .module = THIS_MODULE, | 1421 | .module = THIS_MODULE, |
| 1390 | .ctr = raid_ctr, | 1422 | .ctr = raid_ctr, |
| 1391 | .dtr = raid_dtr, | 1423 | .dtr = raid_dtr, |
