• Qu Wenruo's avatar
    btrfs: dev-replace: error out if we have unrepaired metadata error during · 8eb3dd17
    Qu Wenruo authored
    [BUG]
    Even before the scrub rework, if we have some corrupted metadata failed
    to be repaired during replace, we still continue replacing and let it
    finish just as there is nothing wrong:
    
     BTRFS info (device dm-4): dev_replace from /dev/mapper/test-scratch1 (devid 1) to /dev/mapper/test-scratch2 started
     BTRFS warning (device dm-4): tree block 5578752 mirror 1 has bad csum, has 0x00000000 want 0xade80ca1
     BTRFS warning (device dm-4): tree block 5578752 mirror 0 has bad csum, has 0x00000000 want 0xade80ca1
     BTRFS warning (device dm-4): checksum error at logical 5578752 on dev /dev/mapper/test-scratch1, physical 5578752: metadata leaf (level 0) in tree 5
     BTRFS warning (device dm-4): checksum error at logical 5578752 on dev /dev/mapper/test-scratch1, physical 5578752: metadata leaf (level 0) in tree 5
     BTRFS error (device dm-4): bdev /dev/mapper/test-scratch1 errs: wr 0, rd 0, flush 0, corrupt 1, gen 0
     BTRFS warning (device dm-4): tree block 5578752 mirror 1 has bad bytenr, has 0 want 5578752
     BTRFS error (device dm-4): unable to fixup (regular) error at logical 5578752 on dev /dev/mapper/test-scratch1
     BTRFS info (device dm-4): dev_replace from /dev/mapper/test-scratch1 (devid 1) to /dev/mapper/test-scratch2 finished
    
    This can lead to unexpected problems for the resulting filesystem.
    
    [CAUSE]
    Btrfs reuses scrub code path for dev-replace to iterate all dev extents.
    But unlike scrub, dev-replace doesn't really bother to check the scrub
    progress, which records all the errors found during replace.
    
    And even if we check the progress, we cannot really determine which
    errors are minor, which are critical just by the plain numbers.
    (remember we don't treat metadata/data checksum error differently).
    
    This behavior is there from the very beginning.
    
    [FIX]
    Instead of continuing the replace, just error out if we hit an
    unrepaired metadata sector.
    
    Now the dev-replace would be rejected with -EIO, to let the user know.
    Although it also means, the filesystem has some metadata error which
    cannot be repaired, the user would be upset anyway.
    
    The new dmesg would look like this:
    
     BTRFS info (device dm-4): dev_replace from /dev/mapper/test-scratch1 (devid 1) to /dev/mapper/test-scratch2 started
     BTRFS warning (device dm-4): tree block 5578752 mirror 1 has bad csum, has 0x00000000 want 0xade80ca1
     BTRFS warning (device dm-4): tree block 5578752 mirror 1 has bad csum, has 0x00000000 want 0xade80ca1
     BTRFS error (device dm-4): unable to fixup (regular) error at logical 5570560 on dev /dev/mapper/test-scratch1 physical 5570560
     BTRFS warning (device dm-4): header error at logical 5570560 on dev /dev/mapper/test-scratch1, physical 5570560: metadata leaf (level 0) in tree 5
     BTRFS warning (device dm-4): header error at logical 5570560 on dev /dev/mapper/test-scratch1, physical 5570560: metadata leaf (level 0) in tree 5
     BTRFS error (device dm-4): stripe 5570560 has unrepaired metadata sector at 5578752
     BTRFS error (device dm-4): btrfs_scrub_dev(/dev/mapper/test-scratch1, 1, /dev/mapper/test-scratch2) failed -5
    Signed-off-by: default avatarQu Wenruo <wqu@suse.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    8eb3dd17
scrub.c 85.2 KB