diff options
author | NeilBrown <neilb@suse.de> | 2015-05-20 22:00:47 -0400 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2015-05-27 21:36:25 -0400 |
commit | fb642b92c267beeefd352af9bc461eac93a7552c (patch) | |
tree | b65a1548db0ed487de3fe42ac8a072c3a8a59c05 /drivers/md/raid5.c | |
parent | 4e3d62ff4976f26d22b8b91572a49136bb3a23f1 (diff) |
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: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md/raid5.c')
-rw-r--r-- | drivers/md/raid5.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index fc5c4039c394..6de2e1edd492 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -3557,7 +3557,8 @@ unhash: | |||
3557 | spin_lock_irq(&head_sh->stripe_lock); | 3557 | spin_lock_irq(&head_sh->stripe_lock); |
3558 | head_sh->batch_head = NULL; | 3558 | head_sh->batch_head = NULL; |
3559 | spin_unlock_irq(&head_sh->stripe_lock); | 3559 | spin_unlock_irq(&head_sh->stripe_lock); |
3560 | wake_up_nr(&conf->wait_for_overlap, wakeup_nr); | 3560 | if (wakeup_nr) |
3561 | wake_up(&conf->wait_for_overlap); | ||
3561 | if (head_sh->state & STRIPE_EXPAND_SYNC_FLAG) | 3562 | if (head_sh->state & STRIPE_EXPAND_SYNC_FLAG) |
3562 | set_bit(STRIPE_HANDLE, &head_sh->state); | 3563 | set_bit(STRIPE_HANDLE, &head_sh->state); |
3563 | } | 3564 | } |
@@ -4238,6 +4239,7 @@ static void break_stripe_batch_list(struct stripe_head *head_sh) | |||
4238 | { | 4239 | { |
4239 | struct stripe_head *sh, *next; | 4240 | struct stripe_head *sh, *next; |
4240 | int i; | 4241 | int i; |
4242 | int do_wakeup = 0; | ||
4241 | 4243 | ||
4242 | list_for_each_entry_safe(sh, next, &head_sh->batch_list, batch_list) { | 4244 | list_for_each_entry_safe(sh, next, &head_sh->batch_list, batch_list) { |
4243 | 4245 | ||
@@ -4250,10 +4252,12 @@ static void break_stripe_batch_list(struct stripe_head *head_sh) | |||
4250 | STRIPE_EXPAND_SYNC_FLAG)); | 4252 | STRIPE_EXPAND_SYNC_FLAG)); |
4251 | sh->check_state = head_sh->check_state; | 4253 | sh->check_state = head_sh->check_state; |
4252 | sh->reconstruct_state = head_sh->reconstruct_state; | 4254 | sh->reconstruct_state = head_sh->reconstruct_state; |
4253 | for (i = 0; i < sh->disks; i++) | 4255 | for (i = 0; i < sh->disks; i++) { |
4256 | if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags)) | ||
4257 | do_wakeup = 1; | ||
4254 | sh->dev[i].flags = head_sh->dev[i].flags & | 4258 | sh->dev[i].flags = head_sh->dev[i].flags & |
4255 | (~((1 << R5_WriteError) | (1 << R5_Overlap))); | 4259 | (~((1 << R5_WriteError) | (1 << R5_Overlap))); |
4256 | 4260 | } | |
4257 | spin_lock_irq(&sh->stripe_lock); | 4261 | spin_lock_irq(&sh->stripe_lock); |
4258 | sh->batch_head = NULL; | 4262 | sh->batch_head = NULL; |
4259 | spin_unlock_irq(&sh->stripe_lock); | 4263 | spin_unlock_irq(&sh->stripe_lock); |
@@ -4261,6 +4265,15 @@ static void break_stripe_batch_list(struct stripe_head *head_sh) | |||
4261 | set_bit(STRIPE_HANDLE, &sh->state); | 4265 | set_bit(STRIPE_HANDLE, &sh->state); |
4262 | release_stripe(sh); | 4266 | release_stripe(sh); |
4263 | } | 4267 | } |
4268 | spin_lock_irq(&head_sh->stripe_lock); | ||
4269 | head_sh->batch_head = NULL; | ||
4270 | spin_unlock_irq(&head_sh->stripe_lock); | ||
4271 | for (i = 0; i < head_sh->disks; i++) | ||
4272 | if (test_and_clear_bit(R5_Overlap, &head_sh->dev[i].flags)) | ||
4273 | do_wakeup = 1; | ||
4274 | |||
4275 | if (do_wakeup) | ||
4276 | wake_up(&head_sh->raid_conf->wait_for_overlap); | ||
4264 | } | 4277 | } |
4265 | 4278 | ||
4266 | static void handle_stripe(struct stripe_head *sh) | 4279 | static void handle_stripe(struct stripe_head *sh) |