summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorShaohua Li <shli@fb.com>2015-09-18 19:20:13 +0200
committerNeilBrown <neilb@suse.com>2015-10-02 09:23:43 +0200
commitebda780bce8d58ec0abab157397c9e099c41a05f (patch)
treebb3995ca492ded73273329f69791cf814b5dfdbe /drivers
parentmd: wait for pending superblock updates before switching to read-only (diff)
downloadlinux-ebda780bce8d58ec0abab157397c9e099c41a05f.tar.xz
linux-ebda780bce8d58ec0abab157397c9e099c41a05f.zip
raid5: update analysis state for failed stripe
handle_failed_stripe() makes the stripe fail, eg, all IO will return with a failure, but it doesn't update stripe_head_state. Later handle_stripe() has special handling for raid6 for handle_stripe_fill(). That check before handle_stripe_fill() doesn't skip the failed stripe and we get a kernel crash in need_this_block. This patch clear the analysis state to make sure no functions wrongly called after handle_failed_stripe() Signed-off-by: Shaohua Li <shli@fb.com> Signed-off-by: NeilBrown <neilb@suse.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/md/raid5.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 15ef2c641b2b..2105e5f1fd31 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -3150,6 +3150,8 @@ handle_failed_stripe(struct r5conf *conf, struct stripe_head *sh,
spin_unlock_irq(&sh->stripe_lock);
if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
wake_up(&conf->wait_for_overlap);
+ if (bi)
+ s->to_read--;
while (bi && bi->bi_iter.bi_sector <
sh->dev[i].sector + STRIPE_SECTORS) {
struct bio *nextbi =
@@ -3169,6 +3171,8 @@ handle_failed_stripe(struct r5conf *conf, struct stripe_head *sh,
*/
clear_bit(R5_LOCKED, &sh->dev[i].flags);
}
+ s->to_write = 0;
+ s->written = 0;
if (test_and_clear_bit(STRIPE_FULL_WRITE, &sh->state))
if (atomic_dec_and_test(&conf->pending_full_writes))