• Filipe Manana's avatar
    Btrfs: fix race between device replace and read repair · b5de8d0d
    Filipe Manana authored
    While we are finishing a device replace operation we can have a concurrent
    task trying to do a read repair operation, in which case it will call
    btrfs_map_block() to get a struct btrfs_bio which can have a stripe that
    points to the source device of the device replace operation. This allows
    for the read repair task to dereference the stripe's device pointer after
    the device replace operation has freed the source device, resulting in
    an invalid memory access. This is similar to the problem solved by my
    previous patch in the same series and named "Btrfs: fix race between
    device replace and discard".
    
    So fix this by surrounding the call to btrfs_map_block() and the code
    that uses the returned struct btrfs_bio with calls to
    btrfs_bio_counter_inc_blocked() and btrfs_bio_counter_dec(), giving the
    proper serialization with the finishing phase of the device replace
    operation.
    Signed-off-by: default avatarFilipe Manana <fdmanana@suse.com>
    Reviewed-by: default avatarJosef Bacik <jbacik@fb.com>
    b5de8d0d
extent_io.c 147 KB