|
@@ -811,6 +811,14 @@ static void stripe_add_to_batch_list(struct r5conf *conf, struct stripe_head *sh
|
|
|
spin_unlock(&head->batch_head->batch_lock);
|
|
|
goto unlock_out;
|
|
|
}
|
|
|
+ /*
|
|
|
+ * We must assign batch_head of this stripe within the
|
|
|
+ * batch_lock, otherwise clear_batch_ready of batch head
|
|
|
+ * stripe could clear BATCH_READY bit of this stripe and
|
|
|
+ * this stripe->batch_head doesn't get assigned, which
|
|
|
+ * could confuse clear_batch_ready for this stripe
|
|
|
+ */
|
|
|
+ sh->batch_head = head->batch_head;
|
|
|
|
|
|
/*
|
|
|
* at this point, head's BATCH_READY could be cleared, but we
|
|
@@ -818,8 +826,6 @@ static void stripe_add_to_batch_list(struct r5conf *conf, struct stripe_head *sh
|
|
|
*/
|
|
|
list_add(&sh->batch_list, &head->batch_list);
|
|
|
spin_unlock(&head->batch_head->batch_lock);
|
|
|
-
|
|
|
- sh->batch_head = head->batch_head;
|
|
|
} else {
|
|
|
head->batch_head = head;
|
|
|
sh->batch_head = head->batch_head;
|
|
@@ -4599,7 +4605,8 @@ static void break_stripe_batch_list(struct stripe_head *head_sh,
|
|
|
|
|
|
set_mask_bits(&sh->state, ~(STRIPE_EXPAND_SYNC_FLAGS |
|
|
|
(1 << STRIPE_PREREAD_ACTIVE) |
|
|
|
- (1 << STRIPE_DEGRADED)),
|
|
|
+ (1 << STRIPE_DEGRADED) |
|
|
|
+ (1 << STRIPE_ON_UNPLUG_LIST)),
|
|
|
head_sh->state & (1 << STRIPE_INSYNC));
|
|
|
|
|
|
sh->check_state = head_sh->check_state;
|