Shaohua Li 3664847d95 md/raid5: fix a race condition in stripe batch
We have a race condition in below scenario, say have 3 continuous stripes, sh1,
sh2 and sh3, sh1 is the stripe_head of sh2 and sh3:

CPU1				CPU2				CPU3
handle_stripe(sh3)
				stripe_add_to_batch_list(sh3)
				-> lock(sh2, sh3)
				-> lock batch_lock(sh1)
				-> add sh3 to batch_list of sh1
				-> unlock batch_lock(sh1)
								clear_batch_ready(sh1)
								-> lock(sh1) and batch_lock(sh1)
								-> clear STRIPE_BATCH_READY for all stripes in batch_list
								-> unlock(sh1) and batch_lock(sh1)
->clear_batch_ready(sh3)
-->test_and_clear_bit(STRIPE_BATCH_READY, sh3)
--->return 0 as sh->batch == NULL
				-> sh3->batch_head = sh1
				-> unlock (sh2, sh3)

In CPU1, handle_stripe will continue handle sh3 even it's in batch stripe list
of sh1. By moving sh3->batch_head assignment in to batch_lock, we make it
impossible to clear STRIPE_BATCH_READY before batch_head is set.

Thanks Stephane for helping debug this tricky issue.

Reported-and-tested-by: Stephane Thiell <sthiell@stanford.edu>
Cc: stable@vger.kernel.org (v4.1+)
Signed-off-by: Shaohua Li <shli@fb.com>
2017-09-05 10:57:49 -07:00
..
2017-07-07 09:44:06 -07:00
2016-11-01 09:43:26 -06:00
2017-07-25 14:54:20 -04:00
2017-06-09 09:27:32 -06:00
2017-05-08 17:15:12 -07:00
2017-07-07 09:44:06 -07:00
2017-06-09 09:27:32 -06:00
2017-06-12 08:30:13 -06:00
2017-06-09 09:27:32 -06:00
2017-08-28 07:45:48 -07:00
2017-08-28 07:45:48 -07:00
2017-08-28 07:45:48 -07:00
2015-08-13 12:31:57 -06:00
2017-08-28 07:45:48 -07:00