• NeilBrown's avatar
    dm: correctly handle chained bios in dec_pending() · 8dd601fa
    NeilBrown authored
    dec_pending() is given an error status (possibly 0) to be recorded
    against a bio.  It can be called several times on the one 'struct
    dm_io', and it is careful to only assign a non-zero error to
    io->status.  However when it then assigned io->status to bio->bi_status,
    it is not careful and could overwrite a genuine error status with 0.
    
    This can happen when chained bios are in use.  If a bio is chained
    beneath the bio that this dm_io is handling, the child bio might
    complete and set bio->bi_status before the dm_io completes.
    
    This has been possible since chained bios were introduced in 3.14, and
    has become a lot easier to trigger with commit 18a25da8 ("dm: ensure
    bio submission follows a depth-first tree walk") as that commit caused
    dm to start using chained bios itself.
    
    A particular failure mode is that if a bio spans an 'error' target and a
    working target, the 'error' fragment will complete instantly and set the
    ->bi_status, and the other fragment will normally complete a little
    later, and will clear ->bi_status.
    
    The fix is simply to only assign io_error to bio->bi_status when
    io_error is not zero.
    Reported-and-tested-by: default avatarMilan Broz <gmazyland@gmail.com>
    Cc: stable@vger.kernel.org (v3.14+)
    Signed-off-by: default avatarNeilBrown <neilb@suse.com>
    Signed-off-by: default avatarMike Snitzer <snitzer@redhat.com>
    8dd601fa
dm.c 71.7 KB