• Filipe Manana's avatar
    Btrfs: fix wrong dentries after fsync of file that got its parent replaced · 0f375eed
    Filipe Manana authored
    In a scenario like the following:
      mkdir /mnt/A               # inode 258
      mkdir /mnt/B               # inode 259
      touch /mnt/B/bar           # inode 260
      mv /mnt/B/bar /mnt/A/bar
      mv -T /mnt/A /mnt/B
      fsync /mnt/B/bar
      <power fail>
    After replaying the log we end up with file bar having 2 hard links, both
    with the name 'bar' and one in the directory with inode number 258 and the
    other in the directory with inode number 259. Also, we end up with the
    directory inode 259 still existing and with the directory inode 258 still
    named as 'A', instead of 'B'. In this scenario, file 'bar' should only
    have one hard link, located at directory inode 258, the directory inode
    259 should not exist anymore and the name for directory inode 258 should
    be 'B'.
    This incorrect behaviour happens because when attempting to log the old
    parents of an inode, we skip any parents that no longer exist. Fix this
    by forcing a full commit if an old parent no longer exists.
    A test case for fstests follows soon.
    CC: stable@vger.kernel.org # 4.4+
    Signed-off-by: default avatarFilipe Manana <fdmanana@suse.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>