Commit 861e3781 authored by NeilBrown's avatar NeilBrown Committed by Ben Hutchings

md/raid5: Fix possible confusion when multiple write errors occur.

commit 1cc03eb9 upstream.

commit 5d8c71f9
    md: raid5 crash during degradation

Fixed a crash in an overly simplistic way which could leave
R5_WriteError or R5_MadeGood set in the stripe cache for devices
for which it is no longer relevant.
When those devices are removed and spares added the flags are still
set and can cause incorrect behaviour.

commit 14a75d3e
    md/raid5: preferentially read from replacement device if possible.

Fixed the same bug if a more effective way, so we can now revert
the original commit.
Reported-and-tested-by: default avatarAlexander Lyakas <alex.bolshoy@gmail.com>
Fixes: 5d8c71f9Signed-off-by: default avatarNeilBrown <neilb@suse.de>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: default avatarBen Hutchings <ben@decadent.org.uk>
parent 2ab27c17
...@@ -3084,7 +3084,7 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s) ...@@ -3084,7 +3084,7 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s)
*/ */
set_bit(R5_Insync, &dev->flags); set_bit(R5_Insync, &dev->flags);
if (rdev && test_bit(R5_WriteError, &dev->flags)) { if (test_bit(R5_WriteError, &dev->flags)) {
clear_bit(R5_Insync, &dev->flags); clear_bit(R5_Insync, &dev->flags);
if (!test_bit(Faulty, &rdev->flags)) { if (!test_bit(Faulty, &rdev->flags)) {
s->handle_bad_blocks = 1; s->handle_bad_blocks = 1;
...@@ -3092,7 +3092,7 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s) ...@@ -3092,7 +3092,7 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s)
} else } else
clear_bit(R5_WriteError, &dev->flags); clear_bit(R5_WriteError, &dev->flags);
} }
if (rdev && test_bit(R5_MadeGood, &dev->flags)) { if (test_bit(R5_MadeGood, &dev->flags)) {
if (!test_bit(Faulty, &rdev->flags)) { if (!test_bit(Faulty, &rdev->flags)) {
s->handle_bad_blocks = 1; s->handle_bad_blocks = 1;
atomic_inc(&rdev->nr_pending); atomic_inc(&rdev->nr_pending);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment