diff options
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/raid5.c | 32 | ||||
-rw-r--r-- | drivers/md/raid5.h | 2 |
2 files changed, 20 insertions, 14 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 7638cc31e7e8..80ec9a6d8a18 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -1273,6 +1273,8 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, | |||
1273 | int pd_idx, qd_idx; | 1273 | int pd_idx, qd_idx; |
1274 | int ddf_layout = 0; | 1274 | int ddf_layout = 0; |
1275 | sector_t new_sector; | 1275 | sector_t new_sector; |
1276 | int algorithm = previous ? conf->prev_algo | ||
1277 | : conf->algorithm; | ||
1276 | int sectors_per_chunk = previous ? (conf->prev_chunk >> 9) | 1278 | int sectors_per_chunk = previous ? (conf->prev_chunk >> 9) |
1277 | : (conf->chunk_size >> 9); | 1279 | : (conf->chunk_size >> 9); |
1278 | int raid_disks = previous ? conf->previous_raid_disks | 1280 | int raid_disks = previous ? conf->previous_raid_disks |
@@ -1307,7 +1309,7 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, | |||
1307 | pd_idx = data_disks; | 1309 | pd_idx = data_disks; |
1308 | break; | 1310 | break; |
1309 | case 5: | 1311 | case 5: |
1310 | switch (conf->algorithm) { | 1312 | switch (algorithm) { |
1311 | case ALGORITHM_LEFT_ASYMMETRIC: | 1313 | case ALGORITHM_LEFT_ASYMMETRIC: |
1312 | pd_idx = data_disks - stripe % raid_disks; | 1314 | pd_idx = data_disks - stripe % raid_disks; |
1313 | if (*dd_idx >= pd_idx) | 1315 | if (*dd_idx >= pd_idx) |
@@ -1335,13 +1337,13 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, | |||
1335 | break; | 1337 | break; |
1336 | default: | 1338 | default: |
1337 | printk(KERN_ERR "raid5: unsupported algorithm %d\n", | 1339 | printk(KERN_ERR "raid5: unsupported algorithm %d\n", |
1338 | conf->algorithm); | 1340 | algorithm); |
1339 | BUG(); | 1341 | BUG(); |
1340 | } | 1342 | } |
1341 | break; | 1343 | break; |
1342 | case 6: | 1344 | case 6: |
1343 | 1345 | ||
1344 | switch (conf->algorithm) { | 1346 | switch (algorithm) { |
1345 | case ALGORITHM_LEFT_ASYMMETRIC: | 1347 | case ALGORITHM_LEFT_ASYMMETRIC: |
1346 | pd_idx = raid_disks - 1 - (stripe % raid_disks); | 1348 | pd_idx = raid_disks - 1 - (stripe % raid_disks); |
1347 | qd_idx = pd_idx + 1; | 1349 | qd_idx = pd_idx + 1; |
@@ -1454,7 +1456,7 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, | |||
1454 | 1456 | ||
1455 | default: | 1457 | default: |
1456 | printk(KERN_CRIT "raid6: unsupported algorithm %d\n", | 1458 | printk(KERN_CRIT "raid6: unsupported algorithm %d\n", |
1457 | conf->algorithm); | 1459 | algorithm); |
1458 | BUG(); | 1460 | BUG(); |
1459 | } | 1461 | } |
1460 | break; | 1462 | break; |
@@ -1481,6 +1483,8 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous) | |||
1481 | sector_t new_sector = sh->sector, check; | 1483 | sector_t new_sector = sh->sector, check; |
1482 | int sectors_per_chunk = previous ? (conf->prev_chunk >> 9) | 1484 | int sectors_per_chunk = previous ? (conf->prev_chunk >> 9) |
1483 | : (conf->chunk_size >> 9); | 1485 | : (conf->chunk_size >> 9); |
1486 | int algorithm = previous ? conf->prev_algo | ||
1487 | : conf->algorithm; | ||
1484 | sector_t stripe; | 1488 | sector_t stripe; |
1485 | int chunk_offset; | 1489 | int chunk_offset; |
1486 | int chunk_number, dummy1, dd_idx = i; | 1490 | int chunk_number, dummy1, dd_idx = i; |
@@ -1497,7 +1501,7 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous) | |||
1497 | switch(conf->level) { | 1501 | switch(conf->level) { |
1498 | case 4: break; | 1502 | case 4: break; |
1499 | case 5: | 1503 | case 5: |
1500 | switch (conf->algorithm) { | 1504 | switch (algorithm) { |
1501 | case ALGORITHM_LEFT_ASYMMETRIC: | 1505 | case ALGORITHM_LEFT_ASYMMETRIC: |
1502 | case ALGORITHM_RIGHT_ASYMMETRIC: | 1506 | case ALGORITHM_RIGHT_ASYMMETRIC: |
1503 | if (i > sh->pd_idx) | 1507 | if (i > sh->pd_idx) |
@@ -1516,14 +1520,14 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous) | |||
1516 | break; | 1520 | break; |
1517 | default: | 1521 | default: |
1518 | printk(KERN_ERR "raid5: unsupported algorithm %d\n", | 1522 | printk(KERN_ERR "raid5: unsupported algorithm %d\n", |
1519 | conf->algorithm); | 1523 | algorithm); |
1520 | BUG(); | 1524 | BUG(); |
1521 | } | 1525 | } |
1522 | break; | 1526 | break; |
1523 | case 6: | 1527 | case 6: |
1524 | if (i == sh->qd_idx) | 1528 | if (i == sh->qd_idx) |
1525 | return 0; /* It is the Q disk */ | 1529 | return 0; /* It is the Q disk */ |
1526 | switch (conf->algorithm) { | 1530 | switch (algorithm) { |
1527 | case ALGORITHM_LEFT_ASYMMETRIC: | 1531 | case ALGORITHM_LEFT_ASYMMETRIC: |
1528 | case ALGORITHM_RIGHT_ASYMMETRIC: | 1532 | case ALGORITHM_RIGHT_ASYMMETRIC: |
1529 | case ALGORITHM_ROTATING_ZERO_RESTART: | 1533 | case ALGORITHM_ROTATING_ZERO_RESTART: |
@@ -1571,7 +1575,7 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous) | |||
1571 | break; | 1575 | break; |
1572 | default: | 1576 | default: |
1573 | printk(KERN_CRIT "raid6: unsupported algorithm %d\n", | 1577 | printk(KERN_CRIT "raid6: unsupported algorithm %d\n", |
1574 | conf->algorithm); | 1578 | algorithm); |
1575 | BUG(); | 1579 | BUG(); |
1576 | } | 1580 | } |
1577 | break; | 1581 | break; |
@@ -4330,8 +4334,10 @@ static raid5_conf_t *setup_conf(mddev_t *mddev) | |||
4330 | conf->algorithm = mddev->new_layout; | 4334 | conf->algorithm = mddev->new_layout; |
4331 | conf->max_nr_stripes = NR_STRIPES; | 4335 | conf->max_nr_stripes = NR_STRIPES; |
4332 | conf->reshape_progress = mddev->reshape_position; | 4336 | conf->reshape_progress = mddev->reshape_position; |
4333 | if (conf->reshape_progress != MaxSector) | 4337 | if (conf->reshape_progress != MaxSector) { |
4334 | conf->prev_chunk = mddev->chunk_size; | 4338 | conf->prev_chunk = mddev->chunk_size; |
4339 | conf->prev_algo = mddev->layout; | ||
4340 | } | ||
4335 | 4341 | ||
4336 | memory = conf->max_nr_stripes * (sizeof(struct stripe_head) + | 4342 | memory = conf->max_nr_stripes * (sizeof(struct stripe_head) + |
4337 | conf->raid_disks * ((sizeof(struct bio) + PAGE_SIZE))) / 1024; | 4343 | conf->raid_disks * ((sizeof(struct bio) + PAGE_SIZE))) / 1024; |
@@ -4472,14 +4478,14 @@ static int run(mddev_t *mddev) | |||
4472 | 4478 | ||
4473 | if (mddev->degraded == 0) | 4479 | if (mddev->degraded == 0) |
4474 | printk("raid5: raid level %d set %s active with %d out of %d" | 4480 | printk("raid5: raid level %d set %s active with %d out of %d" |
4475 | " devices, algorithm %d\n", conf->level, mdname(mddev), | 4481 | " devices, algorithm %d\n", conf->level, mdname(mddev), |
4476 | mddev->raid_disks-mddev->degraded, mddev->raid_disks, | 4482 | mddev->raid_disks-mddev->degraded, mddev->raid_disks, |
4477 | conf->algorithm); | 4483 | mddev->new_layout); |
4478 | else | 4484 | else |
4479 | printk(KERN_ALERT "raid5: raid level %d set %s active with %d" | 4485 | printk(KERN_ALERT "raid5: raid level %d set %s active with %d" |
4480 | " out of %d devices, algorithm %d\n", conf->level, | 4486 | " out of %d devices, algorithm %d\n", conf->level, |
4481 | mdname(mddev), mddev->raid_disks - mddev->degraded, | 4487 | mdname(mddev), mddev->raid_disks - mddev->degraded, |
4482 | mddev->raid_disks, conf->algorithm); | 4488 | mddev->raid_disks, mddev->new_layout); |
4483 | 4489 | ||
4484 | print_raid5_conf(conf); | 4490 | print_raid5_conf(conf); |
4485 | 4491 | ||
diff --git a/drivers/md/raid5.h b/drivers/md/raid5.h index b9c93280fc1d..cdd045681720 100644 --- a/drivers/md/raid5.h +++ b/drivers/md/raid5.h | |||
@@ -350,7 +350,7 @@ struct raid5_private_data { | |||
350 | */ | 350 | */ |
351 | sector_t reshape_safe; | 351 | sector_t reshape_safe; |
352 | int previous_raid_disks; | 352 | int previous_raid_disks; |
353 | int prev_chunk; | 353 | int prev_chunk, prev_algo; |
354 | short generation; /* increments with every reshape */ | 354 | short generation; /* increments with every reshape */ |
355 | 355 | ||
356 | struct list_head handle_list; /* stripes needing handling */ | 356 | struct list_head handle_list; /* stripes needing handling */ |