| From 79aef9203882405f08b4f431b91a457890151888 Mon Sep 17 00:00:00 2001 |
| From: NeilBrown <neilb@suse.de> |
| Date: Tue, 8 Nov 2011 16:22:01 +1100 |
| Subject: [PATCH] md/raid5: abort any pending parity operations when array |
| fails. |
| |
| commit 9a3f530f39f4490eaa18b02719fb74ce5f4d2d86 upstream. |
| |
| When the number of failed devices exceeds the allowed number |
| we must abort any active parity operations (checks or updates) as they |
| are no longer meaningful, and can lead to a BUG_ON in |
| handle_parity_checks6. |
| |
| This bug was introduce by commit 6c0069c0ae9659e3a91b68eaed06a5c6c37f45c8 |
| in 2.6.29. |
| |
| Reported-by: Manish Katiyar <mkatiyar@gmail.com> |
| Tested-by: Manish Katiyar <mkatiyar@gmail.com> |
| Acked-by: Dan Williams <dan.j.williams@intel.com> |
| Signed-off-by: NeilBrown <neilb@suse.de> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| [PG: use 2.6.32.49 backport since raid5.c @ 9a3f530f/v3.2 differs more] |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| --- |
| drivers/md/raid5.c | 32 ++++++++++++++++++++------------ |
| 1 file changed, 20 insertions(+), 12 deletions(-) |
| |
| diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c |
| index dc3e4fc..2936c3b 100644 |
| --- a/drivers/md/raid5.c |
| +++ b/drivers/md/raid5.c |
| @@ -3040,12 +3040,16 @@ static void handle_stripe5(struct stripe_head *sh) |
| /* check if the array has lost two devices and, if so, some requests might |
| * need to be failed |
| */ |
| - if (s.failed > 1 && s.to_read+s.to_write+s.written) |
| - handle_failed_stripe(conf, sh, &s, disks, &return_bi); |
| - if (s.failed > 1 && s.syncing) { |
| - md_done_sync(conf->mddev, STRIPE_SECTORS,0); |
| - clear_bit(STRIPE_SYNCING, &sh->state); |
| - s.syncing = 0; |
| + if (s.failed > 1) { |
| + sh->check_state = 0; |
| + sh->reconstruct_state = 0; |
| + if (s.to_read+s.to_write+s.written) |
| + handle_failed_stripe(conf, sh, &s, disks, &return_bi); |
| + if (s.syncing) { |
| + md_done_sync(conf->mddev, STRIPE_SECTORS,0); |
| + clear_bit(STRIPE_SYNCING, &sh->state); |
| + s.syncing = 0; |
| + } |
| } |
| |
| /* might be able to return some write requests if the parity block |
| @@ -3323,12 +3327,16 @@ static void handle_stripe6(struct stripe_head *sh) |
| /* check if the array has lost >2 devices and, if so, some requests |
| * might need to be failed |
| */ |
| - if (s.failed > 2 && s.to_read+s.to_write+s.written) |
| - handle_failed_stripe(conf, sh, &s, disks, &return_bi); |
| - if (s.failed > 2 && s.syncing) { |
| - md_done_sync(conf->mddev, STRIPE_SECTORS,0); |
| - clear_bit(STRIPE_SYNCING, &sh->state); |
| - s.syncing = 0; |
| + if (s.failed > 2) { |
| + sh->check_state = 0; |
| + sh->reconstruct_state = 0; |
| + if (s.to_read+s.to_write+s.written) |
| + handle_failed_stripe(conf, sh, &s, disks, &return_bi); |
| + if (s.syncing) { |
| + md_done_sync(conf->mddev, STRIPE_SECTORS,0); |
| + clear_bit(STRIPE_SYNCING, &sh->state); |
| + s.syncing = 0; |
| + } |
| } |
| |
| /* |
| -- |
| 1.7.12.rc1.1.gbce1580 |
| |