Skip to content

Commit 448ec63

Browse files
Amy Chiangshligit
authored andcommitted
md/raid5: Assigning NULL to sh->batch_head before testing bit R5_Overlap of a stripe
In add_stripe_bio(), if the stripe_head is in batch list, the incoming bio is regarded as overlapping, and the bit R5_Overlap on this stripe_head is set. break_stripe_batch_list() checks bit R5_Overlap on each stripe_head first then assigns NULL to sh->batch_head. If break_stripe_batch_list() checks bit R5_Overlap on stripe_head A after add_stripe_bio() finds stripe_head A is in batch list and before add_stripe_bio() sets bit R5_Overlapt of stripe_head A, break_stripe_batch_list() would not know there's a process in wait_for_overlap and needs to call wake_up(). There's a huge chance a process never returns from schedule() if add_stripe_bio() is called from raid5_make_request(). In break_stripe_batch_list(), assigning NULL to sh->batch_head should be done before it checks bit R5_Overlap of a stripe_head. Signed-off-by: Amy Chiang <amychiang@qnap.com> Signed-off-by: Shaohua Li <shli@fb.com>
1 parent b33d106 commit 448ec63

File tree

1 file changed

+3
-3
lines changed

1 file changed

+3
-3
lines changed

drivers/md/raid5.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4620,15 +4620,15 @@ static void break_stripe_batch_list(struct stripe_head *head_sh,
46204620

46214621
sh->check_state = head_sh->check_state;
46224622
sh->reconstruct_state = head_sh->reconstruct_state;
4623+
spin_lock_irq(&sh->stripe_lock);
4624+
sh->batch_head = NULL;
4625+
spin_unlock_irq(&sh->stripe_lock);
46234626
for (i = 0; i < sh->disks; i++) {
46244627
if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
46254628
do_wakeup = 1;
46264629
sh->dev[i].flags = head_sh->dev[i].flags &
46274630
(~((1 << R5_WriteError) | (1 << R5_Overlap)));
46284631
}
4629-
spin_lock_irq(&sh->stripe_lock);
4630-
sh->batch_head = NULL;
4631-
spin_unlock_irq(&sh->stripe_lock);
46324632
if (handle_flags == 0 ||
46334633
sh->state & handle_flags)
46344634
set_bit(STRIPE_HANDLE, &sh->state);

0 commit comments

Comments
 (0)