• Qu Wenruo's avatar
    btrfs: check superblock to ensure the fs was not modified at thaw time · a05d3c91
    Qu Wenruo authored
    [BACKGROUND]
    There is an incident report that, one user hibernated the system, with
    one btrfs on removable device still mounted.
    
    Then by some incident, the btrfs got mounted and modified by another
    system/OS, then back to the hibernated system.
    
    After resuming from the hibernation, new write happened into the victim btrfs.
    
    Now the fs is completely broken, since the underlying btrfs is no longer
    the same one before the hibernation, and the user lost their data due to
    various transid mismatch.
    
    [REPRODUCER]
    We can emulate the situation using the following small script:
    
      truncate -s 1G $dev
      mkfs.btrfs -f $dev
      mount $dev $mnt
      fsstress -w -d $mnt -n 500
      sync
      xfs_freeze -f $mnt
      cp $dev $dev.backup
    
      # There is no way to mount the same cloned fs on the same system,
      # as the conflicting fsid will be rejected by btrfs.
      # Thus here we have to wipe the fs using a different btrfs.
      mkfs.btrfs -f $dev.backup
    
      dd if=$dev.backup of=$dev bs=1M
      xfs_freeze -u $mnt
      fsstress -w -d $mnt -n 20
      umount $mnt
      btrfs check $dev
    
    The final fsck will fail due to some tree blocks has incorrect fsid.
    
    This is enough to emulate the problem hit by the unfortunate user.
    
    [ENHANCEMENT]
    Although such case should not be that common, it can still happen from
    time to time.
    
    From the view of btrfs, we can detect any unexpected super block change,
    and if there is any unexpected change, we just mark the fs read-only,
    and thaw the fs.
    
    By this we can limit the damage to minimal, and I hope no one would lose
    their data by this anymore.
    Suggested-by: default avatarGoffredo Baroncelli <kreijack@libero.it>
    Link: https://lore.kernel.org/linux-btrfs/83bf3b4b-7f4c-387a-b286-9251e3991e34@bluemole.com/Reviewed-by: default avatarAnand Jain <anand.jain@oracle.com>
    Signed-off-by: default avatarQu Wenruo <wqu@suse.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    a05d3c91
disk-io.c 145 KB