diff options
author | NeilBrown <neilb@suse.de> | 2011-07-26 21:00:36 -0400 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2011-07-26 21:00:36 -0400 |
commit | c8ac1803ff0af5aa614587ac0c66d46b7a3bdfcc (patch) | |
tree | e1ac80fb2151802d8a2654b5c91e06c77c0f3686 /drivers/md/raid5.c | |
parent | 93b3dbce6456a79c545b45e86ccc2244e923cc99 (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.c | 77 |
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 | ||
2471 | static void handle_stripe_dirtying5(raid5_conf_t *conf, | 2471 | static 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 | ||
2561 | static 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 | |||
2608 | static void handle_parity_checks5(raid5_conf_t *conf, struct stripe_head *sh, | 2573 | static 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 |