aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/md/raid5.c24
-rw-r--r--drivers/md/raid5.h5
2 files changed, 21 insertions, 8 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 54f3cb312b42..3ae097d50b51 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -3440,8 +3440,10 @@ unhash:
3440 struct stripe_head, batch_list); 3440 struct stripe_head, batch_list);
3441 list_del_init(&sh->batch_list); 3441 list_del_init(&sh->batch_list);
3442 3442
3443 sh->state = head_sh->state & (~((1 << STRIPE_ACTIVE) | 3443 set_mask_bits(&sh->state, ~STRIPE_EXPAND_SYNC_FLAG,
3444 (1 << STRIPE_PREREAD_ACTIVE))); 3444 head_sh->state & ~((1 << STRIPE_ACTIVE) |
3445 (1 << STRIPE_PREREAD_ACTIVE) |
3446 STRIPE_EXPAND_SYNC_FLAG));
3445 sh->check_state = head_sh->check_state; 3447 sh->check_state = head_sh->check_state;
3446 sh->reconstruct_state = head_sh->reconstruct_state; 3448 sh->reconstruct_state = head_sh->reconstruct_state;
3447 for (i = 0; i < sh->disks; i++) { 3449 for (i = 0; i < sh->disks; i++) {
@@ -3453,6 +3455,8 @@ unhash:
3453 spin_lock_irq(&sh->stripe_lock); 3455 spin_lock_irq(&sh->stripe_lock);
3454 sh->batch_head = NULL; 3456 sh->batch_head = NULL;
3455 spin_unlock_irq(&sh->stripe_lock); 3457 spin_unlock_irq(&sh->stripe_lock);
3458 if (sh->state & STRIPE_EXPAND_SYNC_FLAG)
3459 set_bit(STRIPE_HANDLE, &sh->state);
3456 release_stripe(sh); 3460 release_stripe(sh);
3457 } 3461 }
3458 3462
@@ -3460,6 +3464,8 @@ unhash:
3460 head_sh->batch_head = NULL; 3464 head_sh->batch_head = NULL;
3461 spin_unlock_irq(&head_sh->stripe_lock); 3465 spin_unlock_irq(&head_sh->stripe_lock);
3462 wake_up_nr(&conf->wait_for_overlap, wakeup_nr); 3466 wake_up_nr(&conf->wait_for_overlap, wakeup_nr);
3467 if (head_sh->state & STRIPE_EXPAND_SYNC_FLAG)
3468 set_bit(STRIPE_HANDLE, &head_sh->state);
3463} 3469}
3464 3470
3465static void handle_stripe_dirtying(struct r5conf *conf, 3471static void handle_stripe_dirtying(struct r5conf *conf,
@@ -3927,8 +3933,8 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s)
3927 3933
3928 memset(s, 0, sizeof(*s)); 3934 memset(s, 0, sizeof(*s));
3929 3935
3930 s->expanding = test_bit(STRIPE_EXPAND_SOURCE, &sh->state); 3936 s->expanding = test_bit(STRIPE_EXPAND_SOURCE, &sh->state) && !sh->batch_head;
3931 s->expanded = test_bit(STRIPE_EXPAND_READY, &sh->state); 3937 s->expanded = test_bit(STRIPE_EXPAND_READY, &sh->state) && !sh->batch_head;
3932 s->failed_num[0] = -1; 3938 s->failed_num[0] = -1;
3933 s->failed_num[1] = -1; 3939 s->failed_num[1] = -1;
3934 3940
@@ -4150,9 +4156,11 @@ static void check_break_stripe_batch_list(struct stripe_head *sh)
4150 struct stripe_head, batch_list); 4156 struct stripe_head, batch_list);
4151 list_del_init(&sh->batch_list); 4157 list_del_init(&sh->batch_list);
4152 4158
4153 sh->state = head_sh->state & ~((1 << STRIPE_ACTIVE) | 4159 set_mask_bits(&sh->state, ~STRIPE_EXPAND_SYNC_FLAG,
4154 (1 << STRIPE_PREREAD_ACTIVE) | 4160 head_sh->state & ~((1 << STRIPE_ACTIVE) |
4155 (1 << STRIPE_DEGRADED)); 4161 (1 << STRIPE_PREREAD_ACTIVE) |
4162 (1 << STRIPE_DEGRADED) |
4163 STRIPE_EXPAND_SYNC_FLAG));
4156 sh->check_state = head_sh->check_state; 4164 sh->check_state = head_sh->check_state;
4157 sh->reconstruct_state = head_sh->reconstruct_state; 4165 sh->reconstruct_state = head_sh->reconstruct_state;
4158 for (i = 0; i < sh->disks; i++) 4166 for (i = 0; i < sh->disks; i++)
@@ -4194,7 +4202,7 @@ static void handle_stripe(struct stripe_head *sh)
4194 4202
4195 check_break_stripe_batch_list(sh); 4203 check_break_stripe_batch_list(sh);
4196 4204
4197 if (test_bit(STRIPE_SYNC_REQUESTED, &sh->state)) { 4205 if (test_bit(STRIPE_SYNC_REQUESTED, &sh->state) && !sh->batch_head) {
4198 spin_lock(&sh->stripe_lock); 4206 spin_lock(&sh->stripe_lock);
4199 /* Cannot process 'sync' concurrently with 'discard' */ 4207 /* Cannot process 'sync' concurrently with 'discard' */
4200 if (!test_bit(STRIPE_DISCARD, &sh->state) && 4208 if (!test_bit(STRIPE_DISCARD, &sh->state) &&
diff --git a/drivers/md/raid5.h b/drivers/md/raid5.h
index cf3562e99440..ee65ed844d3f 100644
--- a/drivers/md/raid5.h
+++ b/drivers/md/raid5.h
@@ -339,6 +339,11 @@ enum {
339 STRIPE_BATCH_ERR, 339 STRIPE_BATCH_ERR,
340}; 340};
341 341
342#define STRIPE_EXPAND_SYNC_FLAG \
343 ((1 << STRIPE_EXPAND_SOURCE) |\
344 (1 << STRIPE_EXPAND_READY) |\
345 (1 << STRIPE_EXPANDING) |\
346 (1 << STRIPE_SYNC_REQUESTED))
342/* 347/*
343 * Operation request flags 348 * Operation request flags
344 */ 349 */