In 7471fb77(md/raid6: Fix anomily when recovering a single device in RAID6.) It avoids to re-read P when it can be computed from other members. But it misses the chance to re-write the right data to P. Now it sets R5_ReadError if the re-read fails. Because it avoids the re-read, so it misses the chance to set R5_ReadError. The re-write is submitted in state machine when r5dev has flag R5_ReadError. So it doesn't re-write the right data to disk. We need to do this to keep the raid having right data. Because it don't send re-read, so it also misses the chance to reset rdev->read_erros to 0. It can fail the disk when there are many read errors on P member disk(other disks don't have read error) Fixes: 7471fb77(md/raid6: Fix anomily when recovering a single device in RAID6.) Signed-off-by: Xiao Ni <xni@xxxxxxxxxx> --- drivers/md/raid5.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 9c4f765..6cdd37f 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -2561,7 +2561,9 @@ static void raid5_end_read_request(struct bio * bi) && !test_bit(R5_ReadNoMerge, &sh->dev[i].flags)) retry = 1; if (retry) - if (test_bit(R5_ReadNoMerge, &sh->dev[i].flags)) { + if (sh->qd_idx >= 0 && sh->pd_idx == i) + set_bit(R5_ReadError, &sh->dev[i].flags); + else if (test_bit(R5_ReadNoMerge, &sh->dev[i].flags)) { set_bit(R5_ReadError, &sh->dev[i].flags); clear_bit(R5_ReadNoMerge, &sh->dev[i].flags); } else @@ -6128,7 +6130,10 @@ static int retry_aligned_read(struct r5conf *conf, struct bio *raid_bio, return handled; } - set_bit(R5_ReadNoMerge, &sh->dev[dd_idx].flags); + if (sh->qd_idx >= 0 && sh->pd_idx == i) + set_bit(R5_ReadError, &sh->dev[i].flags); + else + set_bit(R5_ReadNoMerge, &sh->dev[dd_idx].flags); handle_stripe(sh); raid5_release_stripe(sh); handled++; -- 2.7.5