aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2014-01-05 21:19:42 -0500
committerNeilBrown <neilb@suse.de>2014-01-14 00:44:07 -0500
commit1cc03eb93245e63b0b7a7832165efdc52e25b4e6 (patch)
tree37d82f8afc4a45b5f3d21d3b518066823b1e9614
parent6d183de4077191d1201283a9035ce57a9b05254d (diff)
md/raid5: Fix possible confusion when multiple write errors occur.
commit 5d8c71f9e5fbdd95650be00294d238e27a363b5c 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 14a75d3e07c784c004b4b44b34af996b8e4ac453 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: Alexander Lyakas <alex.bolshoy@gmail.com> Cc: stable@vger.kernel.org (3.2+ - 3.2 will need a different fix though) Fixes: 5d8c71f9e5fbdd95650be00294d238e27a363b5c Signed-off-by: NeilBrown <neilb@suse.de>
-rw-r--r--drivers/md/raid5.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index cc055da02e2a..9168173deaf3 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -3608,7 +3608,7 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s)
3608 */ 3608 */
3609 set_bit(R5_Insync, &dev->flags); 3609 set_bit(R5_Insync, &dev->flags);
3610 3610
3611 if (rdev && test_bit(R5_WriteError, &dev->flags)) { 3611 if (test_bit(R5_WriteError, &dev->flags)) {
3612 /* This flag does not apply to '.replacement' 3612 /* This flag does not apply to '.replacement'
3613 * only to .rdev, so make sure to check that*/ 3613 * only to .rdev, so make sure to check that*/
3614 struct md_rdev *rdev2 = rcu_dereference( 3614 struct md_rdev *rdev2 = rcu_dereference(
@@ -3621,7 +3621,7 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s)
3621 } else 3621 } else
3622 clear_bit(R5_WriteError, &dev->flags); 3622 clear_bit(R5_WriteError, &dev->flags);
3623 } 3623 }
3624 if (rdev && test_bit(R5_MadeGood, &dev->flags)) { 3624 if (test_bit(R5_MadeGood, &dev->flags)) {
3625 /* This flag does not apply to '.replacement' 3625 /* This flag does not apply to '.replacement'
3626 * only to .rdev, so make sure to check that*/ 3626 * only to .rdev, so make sure to check that*/
3627 struct md_rdev *rdev2 = rcu_dereference( 3627 struct md_rdev *rdev2 = rcu_dereference(