aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/raid5.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2011-07-26 21:00:36 -0400
committerNeilBrown <neilb@suse.de>2011-07-26 21:00:36 -0400
commitc8ac1803ff0af5aa614587ac0c66d46b7a3bdfcc (patch)
treee1ac80fb2151802d8a2654b5c91e06c77c0f3686 /drivers/md/raid5.c
parent93b3dbce6456a79c545b45e86ccc2244e923cc99 (diff)
md/raid5: unite handle_stripe_dirtying5 and handle_stripe_dirtying6
RAID6 is only allowed to choose 'reconstruct-write' while RAID5 is also allow 'read-modify-write' Apart from this difference, handle_stripe_dirtying[56] are nearly identical. So resolve these differences and create just one function. Signed-off-by: NeilBrown <neilb@suse.de> Reviewed-by: Namhyung Kim <namhyung@gmail.com>
Diffstat (limited to 'drivers/md/raid5.c')
-rw-r--r--drivers/md/raid5.c77
1 files changed, 21 insertions, 56 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index a63a679105ca..a3018970d6a3 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -2468,11 +2468,19 @@ static void handle_stripe_clean_event(raid5_conf_t *conf,
2468 md_wakeup_thread(conf->mddev->thread); 2468 md_wakeup_thread(conf->mddev->thread);
2469} 2469}
2470 2470
2471static void handle_stripe_dirtying5(raid5_conf_t *conf, 2471static void handle_stripe_dirtying(raid5_conf_t *conf,
2472 struct stripe_head *sh, struct stripe_head_state *s, int disks) 2472 struct stripe_head *sh,
2473 struct stripe_head_state *s,
2474 int disks)
2473{ 2475{
2474 int rmw = 0, rcw = 0, i; 2476 int rmw = 0, rcw = 0, i;
2475 for (i = disks; i--; ) { 2477 if (conf->max_degraded == 2) {
2478 /* RAID6 requires 'rcw' in current implementation
2479 * Calculate the real rcw later - for now fake it
2480 * look like rcw is cheaper
2481 */
2482 rcw = 1; rmw = 2;
2483 } else for (i = disks; i--; ) {
2476 /* would I have to read this buffer for read_modify_write */ 2484 /* would I have to read this buffer for read_modify_write */
2477 struct r5dev *dev = &sh->dev[i]; 2485 struct r5dev *dev = &sh->dev[i];
2478 if ((dev->towrite || i == sh->pd_idx) && 2486 if ((dev->towrite || i == sh->pd_idx) &&
@@ -2519,16 +2527,19 @@ static void handle_stripe_dirtying5(raid5_conf_t *conf,
2519 } 2527 }
2520 } 2528 }
2521 } 2529 }
2522 if (rcw <= rmw && rcw > 0) 2530 if (rcw <= rmw && rcw > 0) {
2523 /* want reconstruct write, but need to get some data */ 2531 /* want reconstruct write, but need to get some data */
2532 rcw = 0;
2524 for (i = disks; i--; ) { 2533 for (i = disks; i--; ) {
2525 struct r5dev *dev = &sh->dev[i]; 2534 struct r5dev *dev = &sh->dev[i];
2526 if (!test_bit(R5_OVERWRITE, &dev->flags) && 2535 if (!test_bit(R5_OVERWRITE, &dev->flags) &&
2527 i != sh->pd_idx && 2536 i != sh->pd_idx && i != sh->qd_idx &&
2528 !test_bit(R5_LOCKED, &dev->flags) && 2537 !test_bit(R5_LOCKED, &dev->flags) &&
2529 !(test_bit(R5_UPTODATE, &dev->flags) || 2538 !(test_bit(R5_UPTODATE, &dev->flags) ||
2530 test_bit(R5_Wantcompute, &dev->flags)) && 2539 test_bit(R5_Wantcompute, &dev->flags))) {
2531 test_bit(R5_Insync, &dev->flags)) { 2540 rcw++;
2541 if (!test_bit(R5_Insync, &dev->flags))
2542 continue; /* it's a failed drive */
2532 if ( 2543 if (
2533 test_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) { 2544 test_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) {
2534 pr_debug("Read_old block " 2545 pr_debug("Read_old block "
@@ -2542,6 +2553,7 @@ static void handle_stripe_dirtying5(raid5_conf_t *conf,
2542 } 2553 }
2543 } 2554 }
2544 } 2555 }
2556 }
2545 /* now if nothing is locked, and if we have enough data, 2557 /* now if nothing is locked, and if we have enough data,
2546 * we can start a write request 2558 * we can start a write request
2547 */ 2559 */
@@ -2558,53 +2570,6 @@ static void handle_stripe_dirtying5(raid5_conf_t *conf,
2558 schedule_reconstruction(sh, s, rcw == 0, 0); 2570 schedule_reconstruction(sh, s, rcw == 0, 0);
2559} 2571}
2560 2572
2561static void handle_stripe_dirtying6(raid5_conf_t *conf,
2562 struct stripe_head *sh, struct stripe_head_state *s,
2563 int disks)
2564{
2565 int rcw = 0, pd_idx = sh->pd_idx, i;
2566 int qd_idx = sh->qd_idx;
2567
2568 set_bit(STRIPE_HANDLE, &sh->state);
2569 for (i = disks; i--; ) {
2570 struct r5dev *dev = &sh->dev[i];
2571 /* check if we haven't enough data */
2572 if (!test_bit(R5_OVERWRITE, &dev->flags) &&
2573 i != pd_idx && i != qd_idx &&
2574 !test_bit(R5_LOCKED, &dev->flags) &&
2575 !(test_bit(R5_UPTODATE, &dev->flags) ||
2576 test_bit(R5_Wantcompute, &dev->flags))) {
2577 rcw++;
2578 if (!test_bit(R5_Insync, &dev->flags))
2579 continue; /* it's a failed drive */
2580
2581 if (
2582 test_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) {
2583 pr_debug("Read_old stripe %llu "
2584 "block %d for Reconstruct\n",
2585 (unsigned long long)sh->sector, i);
2586 set_bit(R5_LOCKED, &dev->flags);
2587 set_bit(R5_Wantread, &dev->flags);
2588 s->locked++;
2589 } else {
2590 pr_debug("Request delayed stripe %llu "
2591 "block %d for Reconstruct\n",
2592 (unsigned long long)sh->sector, i);
2593 set_bit(STRIPE_DELAYED, &sh->state);
2594 set_bit(STRIPE_HANDLE, &sh->state);
2595 }
2596 }
2597 }
2598 /* now if nothing is locked, and if we have enough data, we can start a
2599 * write request
2600 */
2601 if ((s->req_compute || !test_bit(STRIPE_COMPUTE_RUN, &sh->state)) &&
2602 s->locked == 0 && rcw == 0 &&
2603 !test_bit(STRIPE_BIT_DELAY, &sh->state)) {
2604 schedule_reconstruction(sh, s, 1, 0);
2605 }
2606}
2607
2608static void handle_parity_checks5(raid5_conf_t *conf, struct stripe_head *sh, 2573static void handle_parity_checks5(raid5_conf_t *conf, struct stripe_head *sh,
2609 struct stripe_head_state *s, int disks) 2574 struct stripe_head_state *s, int disks)
2610{ 2575{
@@ -3099,7 +3064,7 @@ static int handle_stripe5(struct stripe_head *sh, struct stripe_head_state *s)
3099 * block. 3064 * block.
3100 */ 3065 */
3101 if (s->to_write && !sh->reconstruct_state && !sh->check_state) 3066 if (s->to_write && !sh->reconstruct_state && !sh->check_state)
3102 handle_stripe_dirtying5(conf, sh, s, disks); 3067 handle_stripe_dirtying(conf, sh, s, disks);
3103 3068
3104 /* maybe we need to check and possibly fix the parity for this stripe 3069 /* maybe we need to check and possibly fix the parity for this stripe
3105 * Any reads will already have been scheduled, so we just see if enough 3070 * Any reads will already have been scheduled, so we just see if enough
@@ -3288,7 +3253,7 @@ static int handle_stripe6(struct stripe_head *sh, struct stripe_head_state *s)
3288 * block. 3253 * block.
3289 */ 3254 */
3290 if (s->to_write && !sh->reconstruct_state && !sh->check_state) 3255 if (s->to_write && !sh->reconstruct_state && !sh->check_state)
3291 handle_stripe_dirtying6(conf, sh, s, disks); 3256 handle_stripe_dirtying(conf, sh, s, disks);
3292 3257
3293 /* maybe we need to check and possibly fix the parity for this stripe 3258 /* maybe we need to check and possibly fix the parity for this stripe
3294 * Any reads will already have been scheduled, so we just see if enough 3259 * Any reads will already have been scheduled, so we just see if enough