diff options
Diffstat (limited to 'drivers/md/raid5.c')
-rw-r--r-- | drivers/md/raid5.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 425958a76b84..c37e256b1176 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -2002,6 +2002,7 @@ static int __handle_issuing_new_read_requests5(struct stripe_head *sh, | |||
2002 | * have quiesced. | 2002 | * have quiesced. |
2003 | */ | 2003 | */ |
2004 | if ((s->uptodate == disks - 1) && | 2004 | if ((s->uptodate == disks - 1) && |
2005 | (s->failed && disk_idx == s->failed_num) && | ||
2005 | !test_bit(STRIPE_OP_CHECK, &sh->ops.pending)) { | 2006 | !test_bit(STRIPE_OP_CHECK, &sh->ops.pending)) { |
2006 | set_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending); | 2007 | set_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending); |
2007 | set_bit(R5_Wantcompute, &dev->flags); | 2008 | set_bit(R5_Wantcompute, &dev->flags); |
@@ -2087,7 +2088,9 @@ static void handle_issuing_new_read_requests6(struct stripe_head *sh, | |||
2087 | /* we would like to get this block, possibly | 2088 | /* we would like to get this block, possibly |
2088 | * by computing it, but we might not be able to | 2089 | * by computing it, but we might not be able to |
2089 | */ | 2090 | */ |
2090 | if (s->uptodate == disks-1) { | 2091 | if ((s->uptodate == disks - 1) && |
2092 | (s->failed && (i == r6s->failed_num[0] || | ||
2093 | i == r6s->failed_num[1]))) { | ||
2091 | pr_debug("Computing stripe %llu block %d\n", | 2094 | pr_debug("Computing stripe %llu block %d\n", |
2092 | (unsigned long long)sh->sector, i); | 2095 | (unsigned long long)sh->sector, i); |
2093 | compute_block_1(sh, i, 0); | 2096 | compute_block_1(sh, i, 0); |
@@ -2645,6 +2648,7 @@ static void handle_stripe5(struct stripe_head *sh) | |||
2645 | struct r5dev *dev; | 2648 | struct r5dev *dev; |
2646 | unsigned long pending = 0; | 2649 | unsigned long pending = 0; |
2647 | mdk_rdev_t *blocked_rdev = NULL; | 2650 | mdk_rdev_t *blocked_rdev = NULL; |
2651 | int prexor; | ||
2648 | 2652 | ||
2649 | memset(&s, 0, sizeof(s)); | 2653 | memset(&s, 0, sizeof(s)); |
2650 | pr_debug("handling stripe %llu, state=%#lx cnt=%d, pd_idx=%d " | 2654 | pr_debug("handling stripe %llu, state=%#lx cnt=%d, pd_idx=%d " |
@@ -2774,9 +2778,11 @@ static void handle_stripe5(struct stripe_head *sh) | |||
2774 | /* leave prexor set until postxor is done, allows us to distinguish | 2778 | /* leave prexor set until postxor is done, allows us to distinguish |
2775 | * a rmw from a rcw during biodrain | 2779 | * a rmw from a rcw during biodrain |
2776 | */ | 2780 | */ |
2781 | prexor = 0; | ||
2777 | if (test_bit(STRIPE_OP_PREXOR, &sh->ops.complete) && | 2782 | if (test_bit(STRIPE_OP_PREXOR, &sh->ops.complete) && |
2778 | test_bit(STRIPE_OP_POSTXOR, &sh->ops.complete)) { | 2783 | test_bit(STRIPE_OP_POSTXOR, &sh->ops.complete)) { |
2779 | 2784 | ||
2785 | prexor = 1; | ||
2780 | clear_bit(STRIPE_OP_PREXOR, &sh->ops.complete); | 2786 | clear_bit(STRIPE_OP_PREXOR, &sh->ops.complete); |
2781 | clear_bit(STRIPE_OP_PREXOR, &sh->ops.ack); | 2787 | clear_bit(STRIPE_OP_PREXOR, &sh->ops.ack); |
2782 | clear_bit(STRIPE_OP_PREXOR, &sh->ops.pending); | 2788 | clear_bit(STRIPE_OP_PREXOR, &sh->ops.pending); |
@@ -2810,6 +2816,8 @@ static void handle_stripe5(struct stripe_head *sh) | |||
2810 | if (!test_and_set_bit( | 2816 | if (!test_and_set_bit( |
2811 | STRIPE_OP_IO, &sh->ops.pending)) | 2817 | STRIPE_OP_IO, &sh->ops.pending)) |
2812 | sh->ops.count++; | 2818 | sh->ops.count++; |
2819 | if (prexor) | ||
2820 | continue; | ||
2813 | if (!test_bit(R5_Insync, &dev->flags) || | 2821 | if (!test_bit(R5_Insync, &dev->flags) || |
2814 | (i == sh->pd_idx && s.failed == 0)) | 2822 | (i == sh->pd_idx && s.failed == 0)) |
2815 | set_bit(STRIPE_INSYNC, &sh->state); | 2823 | set_bit(STRIPE_INSYNC, &sh->state); |