• NeilBrown's avatar
    md/raid5: close recently introduced race in stripe_head management. · 7da9d450
    NeilBrown authored
    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: 566c09c5
    Cc: stable@vger.kernel.org (3.13)
    Reported-and-tested-by: default avatarIan Kumlien <ian.kumlien@gmail.com>
    Signed-off-by: default avatarNeilBrown <neilb@suse.de>
    7da9d450
raid5.c 197 KB