• C
    btrfs: fix repair of compressed extents · 81bd9328
    Christoph Hellwig 提交于
    Currently the checksum of compressed extents is verified based on the
    compressed data and the lower btrfs_bio, but the actual repair process
    is driven by end_bio_extent_readpage on the upper btrfs_bio for the
    decompressed data.
    
    This has a bunch of issues, including not being able to properly
    communicate the failed mirror up in case that the I/O submission got
    preempted, a general loss of if an error was an I/O error or a checksum
    verification failure, but most importantly that this design causes
    btrfs_clean_io_failure to eventually write back the uncompressed good
    data onto the disk sectors that are supposed to contain compressed data.
    
    Fix this by moving the repair to the lower btrfs_bio.  To do so, a fair
    amount of code has to be reshuffled:
    
     a) the lower btrfs_bio now needs a valid csum pointer.  The easiest way
        to achieve that is to pass NULL btrfs_lookup_bio_sums and just use
        the btrfs_bio management of csums.  For a compressed_bio that is
        split into multiple btrfs_bios this means additional memory
        allocations, but the code becomes a lot more regular.
     b) checksum verification now runs directly on the lower btrfs_bio instead
        of the compressed_bio.  This actually nicely simplifies the end I/O
        processing.
     c) btrfs_repair_one_sector can't just look up the logical address for
        the file offset any more, as there is no corresponding relative
        offsets that apply to the file offset and the logic address for
        compressed extents.  Instead require that the saved bvec_iter in the
        btrfs_bio is filled out for all read bios and use that, which again
        removes a fair amount of code.
    Reviewed-by: NNikolay Borisov <nborisov@suse.com>
    Signed-off-by: NChristoph Hellwig <hch@lst.de>
    Signed-off-by: NDavid Sterba <dsterba@suse.com>
    81bd9328
inode.c 326.2 KB