]> git.baikalelectronics.ru Git - kernel.git/commit
md/raid5: close recently introduced race in stripe_head management.
authorNeilBrown <neilb@suse.de>
Wed, 22 Jan 2014 00:45:03 +0000 (11:45 +1100)
committerNeilBrown <neilb@suse.de>
Wed, 22 Jan 2014 00:45:03 +0000 (11:45 +1100)
commit02075e9436e183fb891c661b90f0f731583a1f96
tree66fd6c85cc6f11f6ce33d8360643e817e13d1b18
parent7f31e0a0e2e1ddd723f759b3ea69348318602d20
md/raid5: close recently introduced race in stripe_head management.

As release_stripe and __release_stripe decrement ->count and then
manipulate ->lru both under ->device_lock, it is important that
get_active_stripe() increments ->count and clears ->lru also under
->device_lock.

However we currently list_del_init ->lru under the lock, but increment
the ->count outside the lock.  This can lead to races and list
corruption.

So move the atomic_inc(&sh->count) up inside the ->device_lock
protected region.

Note that we still increment ->count without device lock in the case
where get_free_stripe() was called, and in fact don't take
->device_lock at all in that path.
This is safe because if the stripe_head can be found by
get_free_stripe, then the hash lock assures us the no-one else could
possibly be calling release_stripe() at the same time.

Fixes: 5e6c765ef4b02f672a3c135d50f9541ff4383788
Cc: stable@vger.kernel.org (3.13)
Reported-and-tested-by: Ian Kumlien <ian.kumlien@gmail.com>
Signed-off-by: NeilBrown <neilb@suse.de>
drivers/md/raid5.c