diff options
Diffstat (limited to 'drivers/md/raid5.c')
-rw-r--r-- | drivers/md/raid5.c | 79 |
1 files changed, 43 insertions, 36 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index c5439dce0295..a4502686e7a8 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -2774,10 +2774,12 @@ static void handle_stripe_clean_event(struct r5conf *conf, | |||
2774 | dev = &sh->dev[i]; | 2774 | dev = &sh->dev[i]; |
2775 | if (!test_bit(R5_LOCKED, &dev->flags) && | 2775 | if (!test_bit(R5_LOCKED, &dev->flags) && |
2776 | (test_bit(R5_UPTODATE, &dev->flags) || | 2776 | (test_bit(R5_UPTODATE, &dev->flags) || |
2777 | test_and_clear_bit(R5_Discard, &dev->flags))) { | 2777 | test_bit(R5_Discard, &dev->flags))) { |
2778 | /* We can return any write requests */ | 2778 | /* We can return any write requests */ |
2779 | struct bio *wbi, *wbi2; | 2779 | struct bio *wbi, *wbi2; |
2780 | pr_debug("Return write for disc %d\n", i); | 2780 | pr_debug("Return write for disc %d\n", i); |
2781 | if (test_and_clear_bit(R5_Discard, &dev->flags)) | ||
2782 | clear_bit(R5_UPTODATE, &dev->flags); | ||
2781 | wbi = dev->written; | 2783 | wbi = dev->written; |
2782 | dev->written = NULL; | 2784 | dev->written = NULL; |
2783 | while (wbi && wbi->bi_sector < | 2785 | while (wbi && wbi->bi_sector < |
@@ -2795,7 +2797,8 @@ static void handle_stripe_clean_event(struct r5conf *conf, | |||
2795 | !test_bit(STRIPE_DEGRADED, &sh->state), | 2797 | !test_bit(STRIPE_DEGRADED, &sh->state), |
2796 | 0); | 2798 | 0); |
2797 | } | 2799 | } |
2798 | } | 2800 | } else if (test_bit(R5_Discard, &sh->dev[i].flags)) |
2801 | clear_bit(R5_Discard, &sh->dev[i].flags); | ||
2799 | 2802 | ||
2800 | if (test_and_clear_bit(STRIPE_FULL_WRITE, &sh->state)) | 2803 | if (test_and_clear_bit(STRIPE_FULL_WRITE, &sh->state)) |
2801 | if (atomic_dec_and_test(&conf->pending_full_writes)) | 2804 | if (atomic_dec_and_test(&conf->pending_full_writes)) |
@@ -3490,40 +3493,6 @@ static void handle_stripe(struct stripe_head *sh) | |||
3490 | handle_failed_sync(conf, sh, &s); | 3493 | handle_failed_sync(conf, sh, &s); |
3491 | } | 3494 | } |
3492 | 3495 | ||
3493 | /* | ||
3494 | * might be able to return some write requests if the parity blocks | ||
3495 | * are safe, or on a failed drive | ||
3496 | */ | ||
3497 | pdev = &sh->dev[sh->pd_idx]; | ||
3498 | s.p_failed = (s.failed >= 1 && s.failed_num[0] == sh->pd_idx) | ||
3499 | || (s.failed >= 2 && s.failed_num[1] == sh->pd_idx); | ||
3500 | qdev = &sh->dev[sh->qd_idx]; | ||
3501 | s.q_failed = (s.failed >= 1 && s.failed_num[0] == sh->qd_idx) | ||
3502 | || (s.failed >= 2 && s.failed_num[1] == sh->qd_idx) | ||
3503 | || conf->level < 6; | ||
3504 | |||
3505 | if (s.written && | ||
3506 | (s.p_failed || ((test_bit(R5_Insync, &pdev->flags) | ||
3507 | && !test_bit(R5_LOCKED, &pdev->flags) | ||
3508 | && (test_bit(R5_UPTODATE, &pdev->flags) || | ||
3509 | test_bit(R5_Discard, &pdev->flags))))) && | ||
3510 | (s.q_failed || ((test_bit(R5_Insync, &qdev->flags) | ||
3511 | && !test_bit(R5_LOCKED, &qdev->flags) | ||
3512 | && (test_bit(R5_UPTODATE, &qdev->flags) || | ||
3513 | test_bit(R5_Discard, &qdev->flags)))))) | ||
3514 | handle_stripe_clean_event(conf, sh, disks, &s.return_bi); | ||
3515 | |||
3516 | /* Now we might consider reading some blocks, either to check/generate | ||
3517 | * parity, or to satisfy requests | ||
3518 | * or to load a block that is being partially written. | ||
3519 | */ | ||
3520 | if (s.to_read || s.non_overwrite | ||
3521 | || (conf->level == 6 && s.to_write && s.failed) | ||
3522 | || (s.syncing && (s.uptodate + s.compute < disks)) | ||
3523 | || s.replacing | ||
3524 | || s.expanding) | ||
3525 | handle_stripe_fill(sh, &s, disks); | ||
3526 | |||
3527 | /* Now we check to see if any write operations have recently | 3496 | /* Now we check to see if any write operations have recently |
3528 | * completed | 3497 | * completed |
3529 | */ | 3498 | */ |
@@ -3561,6 +3530,40 @@ static void handle_stripe(struct stripe_head *sh) | |||
3561 | s.dec_preread_active = 1; | 3530 | s.dec_preread_active = 1; |
3562 | } | 3531 | } |
3563 | 3532 | ||
3533 | /* | ||
3534 | * might be able to return some write requests if the parity blocks | ||
3535 | * are safe, or on a failed drive | ||
3536 | */ | ||
3537 | pdev = &sh->dev[sh->pd_idx]; | ||
3538 | s.p_failed = (s.failed >= 1 && s.failed_num[0] == sh->pd_idx) | ||
3539 | || (s.failed >= 2 && s.failed_num[1] == sh->pd_idx); | ||
3540 | qdev = &sh->dev[sh->qd_idx]; | ||
3541 | s.q_failed = (s.failed >= 1 && s.failed_num[0] == sh->qd_idx) | ||
3542 | || (s.failed >= 2 && s.failed_num[1] == sh->qd_idx) | ||
3543 | || conf->level < 6; | ||
3544 | |||
3545 | if (s.written && | ||
3546 | (s.p_failed || ((test_bit(R5_Insync, &pdev->flags) | ||
3547 | && !test_bit(R5_LOCKED, &pdev->flags) | ||
3548 | && (test_bit(R5_UPTODATE, &pdev->flags) || | ||
3549 | test_bit(R5_Discard, &pdev->flags))))) && | ||
3550 | (s.q_failed || ((test_bit(R5_Insync, &qdev->flags) | ||
3551 | && !test_bit(R5_LOCKED, &qdev->flags) | ||
3552 | && (test_bit(R5_UPTODATE, &qdev->flags) || | ||
3553 | test_bit(R5_Discard, &qdev->flags)))))) | ||
3554 | handle_stripe_clean_event(conf, sh, disks, &s.return_bi); | ||
3555 | |||
3556 | /* Now we might consider reading some blocks, either to check/generate | ||
3557 | * parity, or to satisfy requests | ||
3558 | * or to load a block that is being partially written. | ||
3559 | */ | ||
3560 | if (s.to_read || s.non_overwrite | ||
3561 | || (conf->level == 6 && s.to_write && s.failed) | ||
3562 | || (s.syncing && (s.uptodate + s.compute < disks)) | ||
3563 | || s.replacing | ||
3564 | || s.expanding) | ||
3565 | handle_stripe_fill(sh, &s, disks); | ||
3566 | |||
3564 | /* Now to consider new write requests and what else, if anything | 3567 | /* Now to consider new write requests and what else, if anything |
3565 | * should be read. We do not handle new writes when: | 3568 | * should be read. We do not handle new writes when: |
3566 | * 1/ A 'write' operation (copy+xor) is already in flight. | 3569 | * 1/ A 'write' operation (copy+xor) is already in flight. |
@@ -5529,6 +5532,10 @@ static int run(struct mddev *mddev) | |||
5529 | * discard data disk but write parity disk | 5532 | * discard data disk but write parity disk |
5530 | */ | 5533 | */ |
5531 | stripe = stripe * PAGE_SIZE; | 5534 | stripe = stripe * PAGE_SIZE; |
5535 | /* Round up to power of 2, as discard handling | ||
5536 | * currently assumes that */ | ||
5537 | while ((stripe-1) & stripe) | ||
5538 | stripe = (stripe | (stripe-1)) + 1; | ||
5532 | mddev->queue->limits.discard_alignment = stripe; | 5539 | mddev->queue->limits.discard_alignment = stripe; |
5533 | mddev->queue->limits.discard_granularity = stripe; | 5540 | mddev->queue->limits.discard_granularity = stripe; |
5534 | /* | 5541 | /* |