diff options
author | NeilBrown <neilb@suse.de> | 2014-01-22 11:45:03 +1100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-01-29 05:06:19 -0800 |
commit | e4e80e0bec9e03b6e323857e9bb2820f5bbe6287 (patch) | |
tree | dc936b4e115a3a863db9d8f3415230ea77e3cbbd /block | |
parent | 34fa7e82ec661cf54f21b1677d2e05173e5a812c (diff) |
md/raid5: close recently introduced race in stripe_head management.
commit 7da9d450ab2843bf1db378c156acc6304dbc1c2b upstream.
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: 566c09c53455d7c4f1130928ef8071da1a24ea65
Reported-and-tested-by: Ian Kumlien <ian.kumlien@gmail.com>
Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'block')
0 files changed, 0 insertions, 0 deletions