• Filipe Manana's avatar
    Btrfs: fix fsync after succession of renames and unlink/rmdir · a3baaf0d
    Filipe Manana authored
    After a succession of renames operations of different files and unlinking
    one of them, if we fsync one of the renamed files we can end up with a
    log that will either fail to replay at mount time or result in a filesystem
    that is in an inconsistent state. One example scenario:
    
      $ mkfs.btrfs -f /dev/sdb
      $ mount /dev/sdb /mnt
    
      $ mkdir /mnt/testdir
      $ touch /mnt/testdir/fname1
      $ touch /mnt/testdir/fname2
    
      $ sync
    
      $ mv /mnt/testdir/fname1 /mnt/testdir/fname3
      $ rm -f /mnt/testdir/fname2
      $ ln /mnt/testdir/fname3 /mnt/testdir/fname2
    
      $ touch /mnt/testdir/fname1
      $ xfs_io -c "fsync" /mnt/testdir/fname1
    
      <power failure>
    
      $ mount /dev/sdb /mnt
      $ umount /mnt
      $ btrfs check /dev/sdb
      [1/7] checking root items
      [2/7] checking extents
      [3/7] checking free space cache
      [4/7] checking fs roots
      root 5 inode 259 errors 2, no orphan item
      ERROR: errors found in fs roots
      Opening filesystem to check...
      Checking filesystem on /dev/sdc
      UUID: 20e4abb8-5a19-4492-8bb4-6084125c2d0d
      found 393216 bytes used, error(s) found
      total csum bytes: 0
      total tree bytes: 131072
      total fs tree bytes: 32768
      total extent tree bytes: 16384
      btree space waste bytes: 122986
      file data blocks allocated: 262144
       referenced 262144
    
    On a kernel without the first patch in this series, titled
    "[PATCH] Btrfs: fix fsync after succession of renames of different files",
    we get instead an error when mounting the filesystem due to failure of
    replaying the log:
    
      $ mount /dev/sdb /mnt
      mount: mount /dev/sdb on /mnt failed: File exists
    
    Fix this by logging the parent directory of an inode whenever we find an
    inode that no longer exists (was unlinked in the current transaction),
    during the procedure which finds inodes that have old names that collide
    with new names of other inodes.
    
    A test case for fstests follows soon.
    Reviewed-by: default avatarNikolay Borisov <nborisov@suse.com>
    Signed-off-by: default avatarFilipe Manana <fdmanana@suse.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    a3baaf0d
tree-log.c 168 KB