Skip to content
  • Qu Wenruo's avatar
    btrfs: scrub: Don't use inode pages for device replace · 2102637c
    Qu Wenruo authored
    commit ac0b4145d662a3b9e34085dea460fb06ede9b69b upstream.
    
    [BUG]
    Btrfs can create compressed extent without checksum (even though it
    shouldn't), and if we then try to replace device containing such extent,
    the result device will contain all the uncompressed data instead of the
    compressed one.
    
    Test case already submitted to fstests:
    https://patchwork.kernel.org/patch/10442353/
    
    [CAUSE]
    When handling compressed extent without checksum, device replace will
    goe into copy_nocow_pages() function.
    
    In that function, btrfs will get all inodes referring to this data
    extents and then use find_or_create_page() to get pages direct from that
    inode.
    
    The problem here is, pages directly from inode are always uncompressed.
    And for compressed data extent, they mismatch with on-disk data.
    Thus this leads to corrupted compressed data extent written to replace
    device.
    
    [FIX]
    In this attempt, we could just remove the "optimization" branch, and let
    unified scrub_pages() to handle it.
    
    Although scrub_pages() won't bother reusing page cache, it will be a
    little slower, but it does the correct csum checking and won't cause
    such data corruption caused by "optimization".
    
    Note about the fix: this is the minimal fix that can be backported to
    older stable trees without conflicts. The whole callchain from
    copy_nocow_pages() can be deleted, and will be in followup patches.
    
    Fixes: ff023aac
    
     ("Btrfs: add code to scrub to copy read data to another disk")
    CC: stable@vger.kernel.org # 4.4+
    Reported-by: default avatarJames Harvey <jamespharvey20@gmail.com>
    Reviewed-by: default avatarJames Harvey <jamespharvey20@gmail.com>
    Signed-off-by: default avatarQu Wenruo <wqu@suse.com>
    [ remove code removal, add note why ]
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    2102637c