aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/raid5.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2011-07-25 21:35:19 -0400
committerNeilBrown <neilb@suse.de>2011-07-25 21:35:19 -0400
commitf2b3b44deee1524ca4f006048e0569f47eefdb74 (patch)
tree49f758f1f46ceb9bbab9bdaa40117030f031a0b8 /drivers/md/raid5.c
parent82e5a1718b9d0401b826341b9023766d04cb82f2 (diff)
md/raid5: unify stripe_head_state and r6_state
'struct stripe_head_state' stores state about the 'current' stripe that is passed around while handling the stripe. For RAID6 there is an extension structure: r6_state, which is also passed around. There is no value in keeping these separate, so move the fields from the latter into the former. This means that all code now needs to treat s->failed_num as an small array, but this is a small cost. 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, 38 insertions, 39 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index dfb3d9f80a3c..bbc7792f013c 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -2318,7 +2318,7 @@ static int fetch_block5(struct stripe_head *sh, struct stripe_head_state *s,
2318 int disk_idx, int disks) 2318 int disk_idx, int disks)
2319{ 2319{
2320 struct r5dev *dev = &sh->dev[disk_idx]; 2320 struct r5dev *dev = &sh->dev[disk_idx];
2321 struct r5dev *failed_dev = &sh->dev[s->failed_num]; 2321 struct r5dev *failed_dev = &sh->dev[s->failed_num[0]];
2322 2322
2323 /* is the data in this block needed, and can we get it? */ 2323 /* is the data in this block needed, and can we get it? */
2324 if (!test_bit(R5_LOCKED, &dev->flags) && 2324 if (!test_bit(R5_LOCKED, &dev->flags) &&
@@ -2334,7 +2334,7 @@ static int fetch_block5(struct stripe_head *sh, struct stripe_head_state *s,
2334 * otherwise read it if the backing disk is insync 2334 * otherwise read it if the backing disk is insync
2335 */ 2335 */
2336 if ((s->uptodate == disks - 1) && 2336 if ((s->uptodate == disks - 1) &&
2337 (s->failed && disk_idx == s->failed_num)) { 2337 (s->failed && disk_idx == s->failed_num[0])) {
2338 set_bit(STRIPE_COMPUTE_RUN, &sh->state); 2338 set_bit(STRIPE_COMPUTE_RUN, &sh->state);
2339 set_bit(STRIPE_OP_COMPUTE_BLK, &s->ops_request); 2339 set_bit(STRIPE_OP_COMPUTE_BLK, &s->ops_request);
2340 set_bit(R5_Wantcompute, &dev->flags); 2340 set_bit(R5_Wantcompute, &dev->flags);
@@ -2388,11 +2388,11 @@ static void handle_stripe_fill5(struct stripe_head *sh,
2388 * 0 to tell the loop in handle_stripe_fill6 to continue 2388 * 0 to tell the loop in handle_stripe_fill6 to continue
2389 */ 2389 */
2390static int fetch_block6(struct stripe_head *sh, struct stripe_head_state *s, 2390static int fetch_block6(struct stripe_head *sh, struct stripe_head_state *s,
2391 struct r6_state *r6s, int disk_idx, int disks) 2391 int disk_idx, int disks)
2392{ 2392{
2393 struct r5dev *dev = &sh->dev[disk_idx]; 2393 struct r5dev *dev = &sh->dev[disk_idx];
2394 struct r5dev *fdev[2] = { &sh->dev[r6s->failed_num[0]], 2394 struct r5dev *fdev[2] = { &sh->dev[s->failed_num[0]],
2395 &sh->dev[r6s->failed_num[1]] }; 2395 &sh->dev[s->failed_num[1]] };
2396 2396
2397 if (!test_bit(R5_LOCKED, &dev->flags) && 2397 if (!test_bit(R5_LOCKED, &dev->flags) &&
2398 !test_bit(R5_UPTODATE, &dev->flags) && 2398 !test_bit(R5_UPTODATE, &dev->flags) &&
@@ -2409,8 +2409,8 @@ static int fetch_block6(struct stripe_head *sh, struct stripe_head_state *s,
2409 BUG_ON(test_bit(R5_Wantcompute, &dev->flags)); 2409 BUG_ON(test_bit(R5_Wantcompute, &dev->flags));
2410 BUG_ON(test_bit(R5_Wantread, &dev->flags)); 2410 BUG_ON(test_bit(R5_Wantread, &dev->flags));
2411 if ((s->uptodate == disks - 1) && 2411 if ((s->uptodate == disks - 1) &&
2412 (s->failed && (disk_idx == r6s->failed_num[0] || 2412 (s->failed && (disk_idx == s->failed_num[0] ||
2413 disk_idx == r6s->failed_num[1]))) { 2413 disk_idx == s->failed_num[1]))) {
2414 /* have disk failed, and we're requested to fetch it; 2414 /* have disk failed, and we're requested to fetch it;
2415 * do compute it 2415 * do compute it
2416 */ 2416 */
@@ -2465,7 +2465,7 @@ static int fetch_block6(struct stripe_head *sh, struct stripe_head_state *s,
2465 * handle_stripe_fill6 - read or compute data to satisfy pending requests. 2465 * handle_stripe_fill6 - read or compute data to satisfy pending requests.
2466 */ 2466 */
2467static void handle_stripe_fill6(struct stripe_head *sh, 2467static void handle_stripe_fill6(struct stripe_head *sh,
2468 struct stripe_head_state *s, struct r6_state *r6s, 2468 struct stripe_head_state *s,
2469 int disks) 2469 int disks)
2470{ 2470{
2471 int i; 2471 int i;
@@ -2477,7 +2477,7 @@ static void handle_stripe_fill6(struct stripe_head *sh,
2477 if (!test_bit(STRIPE_COMPUTE_RUN, &sh->state) && !sh->check_state && 2477 if (!test_bit(STRIPE_COMPUTE_RUN, &sh->state) && !sh->check_state &&
2478 !sh->reconstruct_state) 2478 !sh->reconstruct_state)
2479 for (i = disks; i--; ) 2479 for (i = disks; i--; )
2480 if (fetch_block6(sh, s, r6s, i, disks)) 2480 if (fetch_block6(sh, s, i, disks))
2481 break; 2481 break;
2482 set_bit(STRIPE_HANDLE, &sh->state); 2482 set_bit(STRIPE_HANDLE, &sh->state);
2483} 2483}
@@ -2625,7 +2625,7 @@ static void handle_stripe_dirtying5(raid5_conf_t *conf,
2625 2625
2626static void handle_stripe_dirtying6(raid5_conf_t *conf, 2626static void handle_stripe_dirtying6(raid5_conf_t *conf,
2627 struct stripe_head *sh, struct stripe_head_state *s, 2627 struct stripe_head *sh, struct stripe_head_state *s,
2628 struct r6_state *r6s, int disks) 2628 int disks)
2629{ 2629{
2630 int rcw = 0, pd_idx = sh->pd_idx, i; 2630 int rcw = 0, pd_idx = sh->pd_idx, i;
2631 int qd_idx = sh->qd_idx; 2631 int qd_idx = sh->qd_idx;
@@ -2688,7 +2688,7 @@ static void handle_parity_checks5(raid5_conf_t *conf, struct stripe_head *sh,
2688 s->uptodate--; 2688 s->uptodate--;
2689 break; 2689 break;
2690 } 2690 }
2691 dev = &sh->dev[s->failed_num]; 2691 dev = &sh->dev[s->failed_num[0]];
2692 /* fall through */ 2692 /* fall through */
2693 case check_state_compute_result: 2693 case check_state_compute_result:
2694 sh->check_state = check_state_idle; 2694 sh->check_state = check_state_idle;
@@ -2760,7 +2760,7 @@ static void handle_parity_checks5(raid5_conf_t *conf, struct stripe_head *sh,
2760 2760
2761static void handle_parity_checks6(raid5_conf_t *conf, struct stripe_head *sh, 2761static void handle_parity_checks6(raid5_conf_t *conf, struct stripe_head *sh,
2762 struct stripe_head_state *s, 2762 struct stripe_head_state *s,
2763 struct r6_state *r6s, int disks) 2763 int disks)
2764{ 2764{
2765 int pd_idx = sh->pd_idx; 2765 int pd_idx = sh->pd_idx;
2766 int qd_idx = sh->qd_idx; 2766 int qd_idx = sh->qd_idx;
@@ -2779,14 +2779,14 @@ static void handle_parity_checks6(raid5_conf_t *conf, struct stripe_head *sh,
2779 switch (sh->check_state) { 2779 switch (sh->check_state) {
2780 case check_state_idle: 2780 case check_state_idle:
2781 /* start a new check operation if there are < 2 failures */ 2781 /* start a new check operation if there are < 2 failures */
2782 if (s->failed == r6s->q_failed) { 2782 if (s->failed == s->q_failed) {
2783 /* The only possible failed device holds Q, so it 2783 /* The only possible failed device holds Q, so it
2784 * makes sense to check P (If anything else were failed, 2784 * makes sense to check P (If anything else were failed,
2785 * we would have used P to recreate it). 2785 * we would have used P to recreate it).
2786 */ 2786 */
2787 sh->check_state = check_state_run; 2787 sh->check_state = check_state_run;
2788 } 2788 }
2789 if (!r6s->q_failed && s->failed < 2) { 2789 if (!s->q_failed && s->failed < 2) {
2790 /* Q is not failed, and we didn't use it to generate 2790 /* Q is not failed, and we didn't use it to generate
2791 * anything, so it makes sense to check it 2791 * anything, so it makes sense to check it
2792 */ 2792 */
@@ -2828,13 +2828,13 @@ static void handle_parity_checks6(raid5_conf_t *conf, struct stripe_head *sh,
2828 */ 2828 */
2829 BUG_ON(s->uptodate < disks - 1); /* We don't need Q to recover */ 2829 BUG_ON(s->uptodate < disks - 1); /* We don't need Q to recover */
2830 if (s->failed == 2) { 2830 if (s->failed == 2) {
2831 dev = &sh->dev[r6s->failed_num[1]]; 2831 dev = &sh->dev[s->failed_num[1]];
2832 s->locked++; 2832 s->locked++;
2833 set_bit(R5_LOCKED, &dev->flags); 2833 set_bit(R5_LOCKED, &dev->flags);
2834 set_bit(R5_Wantwrite, &dev->flags); 2834 set_bit(R5_Wantwrite, &dev->flags);
2835 } 2835 }
2836 if (s->failed >= 1) { 2836 if (s->failed >= 1) {
2837 dev = &sh->dev[r6s->failed_num[0]]; 2837 dev = &sh->dev[s->failed_num[0]];
2838 s->locked++; 2838 s->locked++;
2839 set_bit(R5_LOCKED, &dev->flags); 2839 set_bit(R5_LOCKED, &dev->flags);
2840 set_bit(R5_Wantwrite, &dev->flags); 2840 set_bit(R5_Wantwrite, &dev->flags);
@@ -2922,7 +2922,7 @@ static void handle_parity_checks6(raid5_conf_t *conf, struct stripe_head *sh,
2922} 2922}
2923 2923
2924static void handle_stripe_expansion(raid5_conf_t *conf, struct stripe_head *sh, 2924static void handle_stripe_expansion(raid5_conf_t *conf, struct stripe_head *sh,
2925 struct r6_state *r6s) 2925 struct stripe_head_state *r6s)
2926{ 2926{
2927 int i; 2927 int i;
2928 2928
@@ -3082,7 +3082,7 @@ static void handle_stripe5(struct stripe_head *sh)
3082 clear_bit(R5_Insync, &dev->flags); 3082 clear_bit(R5_Insync, &dev->flags);
3083 if (!test_bit(R5_Insync, &dev->flags)) { 3083 if (!test_bit(R5_Insync, &dev->flags)) {
3084 s.failed++; 3084 s.failed++;
3085 s.failed_num = i; 3085 s.failed_num[0] = i;
3086 } 3086 }
3087 } 3087 }
3088 spin_unlock_irq(&conf->device_lock); 3088 spin_unlock_irq(&conf->device_lock);
@@ -3107,7 +3107,7 @@ static void handle_stripe5(struct stripe_head *sh)
3107 pr_debug("locked=%d uptodate=%d to_read=%d" 3107 pr_debug("locked=%d uptodate=%d to_read=%d"
3108 " to_write=%d failed=%d failed_num=%d\n", 3108 " to_write=%d failed=%d failed_num=%d\n",
3109 s.locked, s.uptodate, s.to_read, s.to_write, 3109 s.locked, s.uptodate, s.to_read, s.to_write,
3110 s.failed, s.failed_num); 3110 s.failed, s.failed_num[0]);
3111 /* check if the array has lost two devices and, if so, some requests might 3111 /* check if the array has lost two devices and, if so, some requests might
3112 * need to be failed 3112 * need to be failed
3113 */ 3113 */
@@ -3127,7 +3127,7 @@ static void handle_stripe5(struct stripe_head *sh)
3127 ((test_bit(R5_Insync, &dev->flags) && 3127 ((test_bit(R5_Insync, &dev->flags) &&
3128 !test_bit(R5_LOCKED, &dev->flags) && 3128 !test_bit(R5_LOCKED, &dev->flags) &&
3129 test_bit(R5_UPTODATE, &dev->flags)) || 3129 test_bit(R5_UPTODATE, &dev->flags)) ||
3130 (s.failed == 1 && s.failed_num == sh->pd_idx))) 3130 (s.failed == 1 && s.failed_num[0] == sh->pd_idx)))
3131 handle_stripe_clean_event(conf, sh, disks, &return_bi); 3131 handle_stripe_clean_event(conf, sh, disks, &return_bi);
3132 3132
3133 /* Now we might consider reading some blocks, either to check/generate 3133 /* Now we might consider reading some blocks, either to check/generate
@@ -3198,11 +3198,11 @@ static void handle_stripe5(struct stripe_head *sh)
3198 * the repair/check process 3198 * the repair/check process
3199 */ 3199 */
3200 if (s.failed == 1 && !conf->mddev->ro && 3200 if (s.failed == 1 && !conf->mddev->ro &&
3201 test_bit(R5_ReadError, &sh->dev[s.failed_num].flags) 3201 test_bit(R5_ReadError, &sh->dev[s.failed_num[0]].flags)
3202 && !test_bit(R5_LOCKED, &sh->dev[s.failed_num].flags) 3202 && !test_bit(R5_LOCKED, &sh->dev[s.failed_num[0]].flags)
3203 && test_bit(R5_UPTODATE, &sh->dev[s.failed_num].flags) 3203 && test_bit(R5_UPTODATE, &sh->dev[s.failed_num[0]].flags)
3204 ) { 3204 ) {
3205 dev = &sh->dev[s.failed_num]; 3205 dev = &sh->dev[s.failed_num[0]];
3206 if (!test_bit(R5_ReWrite, &dev->flags)) { 3206 if (!test_bit(R5_ReWrite, &dev->flags)) {
3207 set_bit(R5_Wantwrite, &dev->flags); 3207 set_bit(R5_Wantwrite, &dev->flags);
3208 set_bit(R5_ReWrite, &dev->flags); 3208 set_bit(R5_ReWrite, &dev->flags);
@@ -3292,7 +3292,6 @@ static void handle_stripe6(struct stripe_head *sh)
3292 struct bio *return_bi = NULL; 3292 struct bio *return_bi = NULL;
3293 int i, pd_idx = sh->pd_idx, qd_idx = sh->qd_idx; 3293 int i, pd_idx = sh->pd_idx, qd_idx = sh->qd_idx;
3294 struct stripe_head_state s; 3294 struct stripe_head_state s;
3295 struct r6_state r6s;
3296 struct r5dev *dev, *pdev, *qdev; 3295 struct r5dev *dev, *pdev, *qdev;
3297 mdk_rdev_t *blocked_rdev = NULL; 3296 mdk_rdev_t *blocked_rdev = NULL;
3298 int dec_preread_active = 0; 3297 int dec_preread_active = 0;
@@ -3370,7 +3369,7 @@ static void handle_stripe6(struct stripe_head *sh)
3370 clear_bit(R5_Insync, &dev->flags); 3369 clear_bit(R5_Insync, &dev->flags);
3371 if (!test_bit(R5_Insync, &dev->flags)) { 3370 if (!test_bit(R5_Insync, &dev->flags)) {
3372 if (s.failed < 2) 3371 if (s.failed < 2)
3373 r6s.failed_num[s.failed] = i; 3372 s.failed_num[s.failed] = i;
3374 s.failed++; 3373 s.failed++;
3375 } 3374 }
3376 } 3375 }
@@ -3396,7 +3395,7 @@ static void handle_stripe6(struct stripe_head *sh)
3396 pr_debug("locked=%d uptodate=%d to_read=%d" 3395 pr_debug("locked=%d uptodate=%d to_read=%d"
3397 " to_write=%d failed=%d failed_num=%d,%d\n", 3396 " to_write=%d failed=%d failed_num=%d,%d\n",
3398 s.locked, s.uptodate, s.to_read, s.to_write, s.failed, 3397 s.locked, s.uptodate, s.to_read, s.to_write, s.failed,
3399 r6s.failed_num[0], r6s.failed_num[1]); 3398 s.failed_num[0], s.failed_num[1]);
3400 /* check if the array has lost >2 devices and, if so, some requests 3399 /* check if the array has lost >2 devices and, if so, some requests
3401 * might need to be failed 3400 * might need to be failed
3402 */ 3401 */
@@ -3413,17 +3412,17 @@ static void handle_stripe6(struct stripe_head *sh)
3413 * are safe, or on a failed drive 3412 * are safe, or on a failed drive
3414 */ 3413 */
3415 pdev = &sh->dev[pd_idx]; 3414 pdev = &sh->dev[pd_idx];
3416 r6s.p_failed = (s.failed >= 1 && r6s.failed_num[0] == pd_idx) 3415 s.p_failed = (s.failed >= 1 && s.failed_num[0] == pd_idx)
3417 || (s.failed >= 2 && r6s.failed_num[1] == pd_idx); 3416 || (s.failed >= 2 && s.failed_num[1] == pd_idx);
3418 qdev = &sh->dev[qd_idx]; 3417 qdev = &sh->dev[qd_idx];
3419 r6s.q_failed = (s.failed >= 1 && r6s.failed_num[0] == qd_idx) 3418 s.q_failed = (s.failed >= 1 && s.failed_num[0] == qd_idx)
3420 || (s.failed >= 2 && r6s.failed_num[1] == qd_idx); 3419 || (s.failed >= 2 && s.failed_num[1] == qd_idx);
3421 3420
3422 if ( s.written && 3421 if (s.written &&
3423 ( r6s.p_failed || ((test_bit(R5_Insync, &pdev->flags) 3422 (s.p_failed || ((test_bit(R5_Insync, &pdev->flags)
3424 && !test_bit(R5_LOCKED, &pdev->flags) 3423 && !test_bit(R5_LOCKED, &pdev->flags)
3425 && test_bit(R5_UPTODATE, &pdev->flags)))) && 3424 && test_bit(R5_UPTODATE, &pdev->flags)))) &&
3426 ( r6s.q_failed || ((test_bit(R5_Insync, &qdev->flags) 3425 (s.q_failed || ((test_bit(R5_Insync, &qdev->flags)
3427 && !test_bit(R5_LOCKED, &qdev->flags) 3426 && !test_bit(R5_LOCKED, &qdev->flags)
3428 && test_bit(R5_UPTODATE, &qdev->flags))))) 3427 && test_bit(R5_UPTODATE, &qdev->flags)))))
3429 handle_stripe_clean_event(conf, sh, disks, &return_bi); 3428 handle_stripe_clean_event(conf, sh, disks, &return_bi);
@@ -3434,7 +3433,7 @@ static void handle_stripe6(struct stripe_head *sh)
3434 */ 3433 */
3435 if (s.to_read || s.non_overwrite || (s.to_write && s.failed) || 3434 if (s.to_read || s.non_overwrite || (s.to_write && s.failed) ||
3436 (s.syncing && (s.uptodate + s.compute < disks)) || s.expanding) 3435 (s.syncing && (s.uptodate + s.compute < disks)) || s.expanding)
3437 handle_stripe_fill6(sh, &s, &r6s, disks); 3436 handle_stripe_fill6(sh, &s, disks);
3438 3437
3439 /* Now we check to see if any write operations have recently 3438 /* Now we check to see if any write operations have recently
3440 * completed 3439 * completed
@@ -3472,7 +3471,7 @@ static void handle_stripe6(struct stripe_head *sh)
3472 * block. 3471 * block.
3473 */ 3472 */
3474 if (s.to_write && !sh->reconstruct_state && !sh->check_state) 3473 if (s.to_write && !sh->reconstruct_state && !sh->check_state)
3475 handle_stripe_dirtying6(conf, sh, &s, &r6s, disks); 3474 handle_stripe_dirtying6(conf, sh, &s, disks);
3476 3475
3477 /* maybe we need to check and possibly fix the parity for this stripe 3476 /* maybe we need to check and possibly fix the parity for this stripe
3478 * Any reads will already have been scheduled, so we just see if enough 3477 * Any reads will already have been scheduled, so we just see if enough
@@ -3483,7 +3482,7 @@ static void handle_stripe6(struct stripe_head *sh)
3483 (s.syncing && s.locked == 0 && 3482 (s.syncing && s.locked == 0 &&
3484 !test_bit(STRIPE_COMPUTE_RUN, &sh->state) && 3483 !test_bit(STRIPE_COMPUTE_RUN, &sh->state) &&
3485 !test_bit(STRIPE_INSYNC, &sh->state))) 3484 !test_bit(STRIPE_INSYNC, &sh->state)))
3486 handle_parity_checks6(conf, sh, &s, &r6s, disks); 3485 handle_parity_checks6(conf, sh, &s, disks);
3487 3486
3488 if (s.syncing && s.locked == 0 && test_bit(STRIPE_INSYNC, &sh->state)) { 3487 if (s.syncing && s.locked == 0 && test_bit(STRIPE_INSYNC, &sh->state)) {
3489 md_done_sync(conf->mddev, STRIPE_SECTORS,1); 3488 md_done_sync(conf->mddev, STRIPE_SECTORS,1);
@@ -3495,7 +3494,7 @@ static void handle_stripe6(struct stripe_head *sh)
3495 */ 3494 */
3496 if (s.failed <= 2 && !conf->mddev->ro) 3495 if (s.failed <= 2 && !conf->mddev->ro)
3497 for (i = 0; i < s.failed; i++) { 3496 for (i = 0; i < s.failed; i++) {
3498 dev = &sh->dev[r6s.failed_num[i]]; 3497 dev = &sh->dev[s.failed_num[i]];
3499 if (test_bit(R5_ReadError, &dev->flags) 3498 if (test_bit(R5_ReadError, &dev->flags)
3500 && !test_bit(R5_LOCKED, &dev->flags) 3499 && !test_bit(R5_LOCKED, &dev->flags)
3501 && test_bit(R5_UPTODATE, &dev->flags) 3500 && test_bit(R5_UPTODATE, &dev->flags)
@@ -3557,7 +3556,7 @@ static void handle_stripe6(struct stripe_head *sh)
3557 3556
3558 if (s.expanding && s.locked == 0 && 3557 if (s.expanding && s.locked == 0 &&
3559 !test_bit(STRIPE_COMPUTE_RUN, &sh->state)) 3558 !test_bit(STRIPE_COMPUTE_RUN, &sh->state))
3560 handle_stripe_expansion(conf, sh, &r6s); 3559 handle_stripe_expansion(conf, sh, &s);
3561 3560
3562 unlock: 3561 unlock:
3563 3562