• NeilBrown's avatar
    md/raid5: preserve STRIPE_PREREAD_ACTIVE in break_stripe_batch_list · 550da24f
    NeilBrown authored
    break_stripe_batch_list breaks up a batch and copies some flags from
    the batch head to the members, preserving others.
    
    It doesn't preserve or copy STRIPE_PREREAD_ACTIVE.  This is not
    normally a problem as STRIPE_PREREAD_ACTIVE is cleared when a
    stripe_head is added to a batch, and is not set on stripe_heads
    already in a batch.
    
    However there is no locking to ensure one thread doesn't set the flag
    after it has just been cleared in another.  This does occasionally happen.
    
    md/raid5 maintains a count of the number of stripe_heads with
    STRIPE_PREREAD_ACTIVE set: conf->preread_active_stripes.  When
    break_stripe_batch_list clears STRIPE_PREREAD_ACTIVE inadvertently
    this could becomes incorrect and will never again return to zero.
    
    md/raid5 delays the handling of some stripe_heads until
    preread_active_stripes becomes zero.  So when the above mention race
    happens, those stripe_heads become blocked and never progress,
    resulting is write to the array handing.
    
    So: change break_stripe_batch_list to preserve STRIPE_PREREAD_ACTIVE
    in the members of a batch.
    
    URL: https://bugzilla.kernel.org/show_bug.cgi?id=108741
    URL: https://bugzilla.redhat.com/show_bug.cgi?id=1258153
    URL: http://thread.gmane.org/5649C0E9.2030204@zoner.cz
    Reported-by: Martin Svec <martin.svec@zoner.cz> (and others)
    Tested-by: default avatarTom Weber <linux@junkyard.4t2.com>
    Fixes: 1b956f7a ("md/raid5: be more selective about distributing flags across batch.")
    Cc: stable@vger.kernel.org (v4.1 and later)
    Signed-off-by: default avatarNeilBrown <neilb@suse.com>
    Signed-off-by: default avatarShaohua Li <shli@fb.com>
    550da24f
raid5.c 223 KB