• Filipe Manana's avatar
    Btrfs: fix xattr loss after power failure · 9a8fca62
    Filipe Manana authored
    If a file has xattrs, we fsync it, to ensure we clear the flags
    BTRFS_INODE_NEEDS_FULL_SYNC and BTRFS_INODE_COPY_EVERYTHING from its
    inode, the current transaction commits and then we fsync it (without
    either of those bits being set in its inode), we end up not logging
    all its xattrs. This results in deleting all xattrs when replying the
    log after a power failure.
    
    Trivial reproducer
    
      $ mkfs.btrfs -f /dev/sdb
      $ mount /dev/sdb /mnt
    
      $ touch /mnt/foobar
      $ setfattr -n user.xa -v qwerty /mnt/foobar
      $ xfs_io -c "fsync" /mnt/foobar
    
      $ sync
    
      $ xfs_io -c "pwrite -S 0xab 0 64K" /mnt/foobar
      $ xfs_io -c "fsync" /mnt/foobar
      <power failure>
    
      $ mount /dev/sdb /mnt
      $ getfattr --absolute-names --dump /mnt/foobar
      <empty output>
      $
    
    So fix this by making sure all xattrs are logged if we log a file's inode
    item and neither the flags BTRFS_INODE_NEEDS_FULL_SYNC nor
    BTRFS_INODE_COPY_EVERYTHING were set in the inode.
    
    Fixes: 36283bf7 ("Btrfs: fix fsync xattr loss in the fast fsync path")
    Cc: <stable@vger.kernel.org> # 4.2+
    Signed-off-by: default avatarFilipe Manana <fdmanana@suse.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    9a8fca62
tree-log.c 161 KB