aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2014-01-05 21:19:42 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-01-25 11:27:12 -0500
commitc44bc4496d29b70f95f2197eb950581a455c92a8 (patch)
treee681d062ef4dcab42f4dc585999934ad4d4dbf6f /drivers/md
parentddd618aa9eee9f143d750d15497bf6f117874928 (diff)
md/raid5: Fix possible confusion when multiple write errors occur.
commit 1cc03eb93245e63b0b7a7832165efdc52e25b4e6 upstream. 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> Fixes: 5d8c71f9e5fbdd95650be00294d238e27a363b5c Signed-off-by: NeilBrown <neilb@suse.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/md')
-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 4bed5454b8dc..51422999fd08 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -3391,7 +3391,7 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s)
3391 */ 3391 */
3392 set_bit(R5_Insync, &dev->flags); 3392 set_bit(R5_Insync, &dev->flags);
3393 3393
3394 if (rdev && test_bit(R5_WriteError, &dev->flags)) { 3394 if (test_bit(R5_WriteError, &dev->flags)) {
3395 /* This flag does not apply to '.replacement' 3395 /* This flag does not apply to '.replacement'
3396 * only to .rdev, so make sure to check that*/ 3396 * only to .rdev, so make sure to check that*/
3397 struct md_rdev *rdev2 = rcu_dereference( 3397 struct md_rdev *rdev2 = rcu_dereference(
@@ -3404,7 +3404,7 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s)
3404 } else 3404 } else
3405 clear_bit(R5_WriteError, &dev->flags); 3405 clear_bit(R5_WriteError, &dev->flags);
3406 } 3406 }
3407 if (rdev && test_bit(R5_MadeGood, &dev->flags)) { 3407 if (test_bit(R5_MadeGood, &dev->flags)) {
3408 /* This flag does not apply to '.replacement' 3408 /* This flag does not apply to '.replacement'
3409 * only to .rdev, so make sure to check that*/ 3409 * only to .rdev, so make sure to check that*/
3410 struct md_rdev *rdev2 = rcu_dereference( 3410 struct md_rdev *rdev2 = rcu_dereference(