diff options
author | NeilBrown <neilb@suse.de> | 2015-05-22 01:20:04 -0400 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2015-05-27 21:35:47 -0400 |
commit | b15a9dbdbfe72848b7ed4cd3f97fe80daaf99c89 (patch) | |
tree | 6ded7e7742996dea5e05f46802b2cb800fbfa49d | |
parent | d0852df543e5aa7db34c1ad26d053782bcbf48f1 (diff) |
md/raid5: Ensure a batch member is not handled prematurely.
If a stripe is a member of a batch, but not the head, it must
not be handled separately from the rest of the batch.
'clear_batch_ready()' handles this requirement to some
extent but not completely. If a member is passed to handle_stripe()
a second time it returns '0' indicating the stripe can be handled,
which is wrong.
So add an extra test.
Signed-off-by: NeilBrown <neilb@suse.de>
-rw-r--r-- | drivers/md/raid5.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 42d0ea6c8597..e58736740bac 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -4200,9 +4200,13 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s) | |||
4200 | 4200 | ||
4201 | static int clear_batch_ready(struct stripe_head *sh) | 4201 | static int clear_batch_ready(struct stripe_head *sh) |
4202 | { | 4202 | { |
4203 | /* Return '1' if this is a member of batch, or | ||
4204 | * '0' if it is a lone stripe or a head which can now be | ||
4205 | * handled. | ||
4206 | */ | ||
4203 | struct stripe_head *tmp; | 4207 | struct stripe_head *tmp; |
4204 | if (!test_and_clear_bit(STRIPE_BATCH_READY, &sh->state)) | 4208 | if (!test_and_clear_bit(STRIPE_BATCH_READY, &sh->state)) |
4205 | return 0; | 4209 | return (sh->batch_head && sh->batch_head != sh); |
4206 | spin_lock(&sh->stripe_lock); | 4210 | spin_lock(&sh->stripe_lock); |
4207 | if (!sh->batch_head) { | 4211 | if (!sh->batch_head) { |
4208 | spin_unlock(&sh->stripe_lock); | 4212 | spin_unlock(&sh->stripe_lock); |