• Filipe Manana's avatar
    Btrfs: fix incremental send's decision to delay a dir move/rename · 7b119a8b
    Filipe Manana authored
    It's possible to change the parent/child relationship between directories
    in such a way that if a child directory has a higher inode number than
    its parent, it doesn't necessarily means the child rename/move operation
    can be performed immediately. The parent migth have its own rename/move
    operation delayed, therefore in this case the child needs to have its
    rename/move operation delayed too, and be performed after its new parent's
    rename/move.
    
    Steps to reproduce the issue:
    
          $ umount /mnt
          $ mkfs.btrfs -f /dev/sdd
          $ mount /dev/sdd /mnt
    
          $ mkdir /mnt/A
          $ mkdir /mnt/B
          $ mkdir /mnt/C
          $ mv /mnt/C /mnt/A
          $ mv /mnt/B /mnt/A/C
          $ mkdir /mnt/A/C/D
    
          $ btrfs subvolume snapshot -r /mnt /mnt/snap1
          $ btrfs send /mnt/snap1 -f /tmp/base.send
    
          $ mv /mnt/A/C/D /mnt/A/D2
          $ mv /mnt/A/C/B /mnt/A/D2/B2
          $ mv /mnt/A/C /mnt/A/D2/B2/C2
    
          $ btrfs subvolume snapshot -r /mnt /mnt/snap2
          $ btrfs send -p /mnt/snap1 /mnt/snap2 -f /tmp/incremental.send
    
    The incremental send caused the kernel code to enter an infinite loop when
    building the path string for directory C after its references are processed.
    
    The necessary conditions here are that C has an inode number higher than both
    A and B, and B as an higher inode number higher than A, and D has the highest
    inode number, that is:
        inode_number(A) < inode_number(B) < inode_number(C) < inode_number(D)
    
    The same issue could happen if after the first snapshot there's any number
    of intermediary parent directories between A2 and B2, and between B2 and C2.
    
    A test case for xfstests follows, covering this simple case and more advanced
    ones, with files and hard links created inside the directories.
    Signed-off-by: default avatarFilipe David Borba Manana <fdmanana@gmail.com>
    Signed-off-by: default avatarChris Mason <clm@fb.com>
    7b119a8b
send.c 131 KB