Commit fb642b92 authored by NeilBrown's avatar NeilBrown

md/raid5: duplicate some more handle_stripe_clean_event code in break_stripe_batch_list

break_stripe_batch list didn't clear head_sh->batch_head.
This was probably a bug.

Also clear all R5_Overlap flags and if any were cleared, wake up
'wait_for_overlap'.
This isn't always necessary but the worst effect is a little
extra checking for code that is waiting on wait_for_overlap.

Also, don't use wake_up_nr() because that does the wrong thing
if 'nr' is zero, and it number of flags cleared doesn't
strongly correlate with the number of threads to wake.
Signed-off-by: default avatarNeilBrown <neilb@suse.de>
parent 4e3d62ff
...@@ -3557,7 +3557,8 @@ static void handle_stripe_clean_event(struct r5conf *conf, ...@@ -3557,7 +3557,8 @@ static void handle_stripe_clean_event(struct r5conf *conf,
spin_lock_irq(&head_sh->stripe_lock); spin_lock_irq(&head_sh->stripe_lock);
head_sh->batch_head = NULL; head_sh->batch_head = NULL;
spin_unlock_irq(&head_sh->stripe_lock); spin_unlock_irq(&head_sh->stripe_lock);
wake_up_nr(&conf->wait_for_overlap, wakeup_nr); if (wakeup_nr)
wake_up(&conf->wait_for_overlap);
if (head_sh->state & STRIPE_EXPAND_SYNC_FLAG) if (head_sh->state & STRIPE_EXPAND_SYNC_FLAG)
set_bit(STRIPE_HANDLE, &head_sh->state); set_bit(STRIPE_HANDLE, &head_sh->state);
} }
...@@ -4238,6 +4239,7 @@ static void break_stripe_batch_list(struct stripe_head *head_sh) ...@@ -4238,6 +4239,7 @@ static void break_stripe_batch_list(struct stripe_head *head_sh)
{ {
struct stripe_head *sh, *next; struct stripe_head *sh, *next;
int i; int i;
int do_wakeup = 0;
list_for_each_entry_safe(sh, next, &head_sh->batch_list, batch_list) { list_for_each_entry_safe(sh, next, &head_sh->batch_list, batch_list) {
...@@ -4250,10 +4252,12 @@ static void break_stripe_batch_list(struct stripe_head *head_sh) ...@@ -4250,10 +4252,12 @@ static void break_stripe_batch_list(struct stripe_head *head_sh)
STRIPE_EXPAND_SYNC_FLAG)); STRIPE_EXPAND_SYNC_FLAG));
sh->check_state = head_sh->check_state; sh->check_state = head_sh->check_state;
sh->reconstruct_state = head_sh->reconstruct_state; sh->reconstruct_state = head_sh->reconstruct_state;
for (i = 0; i < sh->disks; i++) for (i = 0; i < sh->disks; i++) {
if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
do_wakeup = 1;
sh->dev[i].flags = head_sh->dev[i].flags & sh->dev[i].flags = head_sh->dev[i].flags &
(~((1 << R5_WriteError) | (1 << R5_Overlap))); (~((1 << R5_WriteError) | (1 << R5_Overlap)));
}
spin_lock_irq(&sh->stripe_lock); spin_lock_irq(&sh->stripe_lock);
sh->batch_head = NULL; sh->batch_head = NULL;
spin_unlock_irq(&sh->stripe_lock); spin_unlock_irq(&sh->stripe_lock);
...@@ -4261,6 +4265,15 @@ static void break_stripe_batch_list(struct stripe_head *head_sh) ...@@ -4261,6 +4265,15 @@ static void break_stripe_batch_list(struct stripe_head *head_sh)
set_bit(STRIPE_HANDLE, &sh->state); set_bit(STRIPE_HANDLE, &sh->state);
release_stripe(sh); release_stripe(sh);
} }
spin_lock_irq(&head_sh->stripe_lock);
head_sh->batch_head = NULL;
spin_unlock_irq(&head_sh->stripe_lock);
for (i = 0; i < head_sh->disks; i++)
if (test_and_clear_bit(R5_Overlap, &head_sh->dev[i].flags))
do_wakeup = 1;
if (do_wakeup)
wake_up(&head_sh->raid_conf->wait_for_overlap);
} }
static void handle_stripe(struct stripe_head *sh) static void handle_stripe(struct stripe_head *sh)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment