aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-raid.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/dm-raid.c')
-rw-r--r--drivers/md/dm-raid.c34
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)
349static int validate_rebuild_devices(struct raid_set *rs) 349static 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
1386static struct target_type raid_target = { 1418static 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,