aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2015-05-22 01:20:04 -0400
committerNeilBrown <neilb@suse.de>2015-05-27 21:35:47 -0400
commitb15a9dbdbfe72848b7ed4cd3f97fe80daaf99c89 (patch)
tree6ded7e7742996dea5e05f46802b2cb800fbfa49d
parentd0852df543e5aa7db34c1ad26d053782bcbf48f1 (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.c6
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
4201static int clear_batch_ready(struct stripe_head *sh) 4201static 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);