summaryrefslogtreecommitdiff
path: root/drivers/md
diff options
context:
space:
mode:
authorXiao Ni <xni@redhat.com>2019-07-08 05:14:32 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-10-05 14:10:10 +0300
commite8323e0ddce1db207f457c0db3e939f54c5569f2 (patch)
treef70a44eea454a34decb5757f015465f243a0c971 /drivers/md
parentbacff03bb28632d7d29259580b69c6c8e5ac4dbd (diff)
downloadlinux-e8323e0ddce1db207f457c0db3e939f54c5569f2.tar.xz
md/raid6: Set R5_ReadError when there is read failure on parity disk
commit 143f6e733b73051cd22dcb80951c6c929da413ce upstream. 7471fb77ce4d ("md/raid6: Fix anomily when recovering a single device in RAID6.") avoids rereading P when it can be computed from other members. However, this misses the chance to re-write the right data to P. This patch sets R5_ReadError if the re-read fails. Also, when re-read is skipped, we also missed the chance to reset rdev->read_errors to 0. It can fail the disk when there are many read errors on P member disk (other disks don't have read error) V2: upper layer read request don't read parity/Q data. So there is no need to consider such situation. This is Reported-by: kbuild test robot <lkp@intel.com> Fixes: 7471fb77ce4d ("md/raid6: Fix anomily when recovering a single device in RAID6.") Cc: <stable@vger.kernel.org> #4.4+ Signed-off-by: Xiao Ni <xni@redhat.com> Signed-off-by: Song Liu <songliubraving@fb.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/raid5.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index dbc4655a9576..4a5aad26ded7 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -2573,7 +2573,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