• Filipe Manana's avatar
    Btrfs: incremental send, fix emission of invalid clone operations · 72610b1b
    Filipe Manana authored
    When doing an incremental send it's possible that the computed send stream
    contains clone operations that will fail on the receiver if the receiver
    has compression enabled and the clone operations target a sector sized
    extent that starts at a zero file offset, is not compressed on the source
    filesystem but ends up being compressed and inlined at the destination
    filesystem.
    
    Example scenario:
    
      $ mkfs.btrfs -f /dev/sdb
      $ mount -o compress /dev/sdb /mnt
    
      # By doing a direct IO write, the data is not compressed.
      $ xfs_io -f -d -c "pwrite -S 0xab 0 4K" /mnt/foobar
      $ btrfs subvolume snapshot -r /mnt /mnt/mysnap1
    
      $ xfs_io -c "reflink /mnt/foobar 0 8K 4K" /mnt/foobar
      $ btrfs subvolume snapshot -r /mnt /mnt/mysnap2
    
      $ btrfs send -f /tmp/1.snap /mnt/mysnap1
      $ btrfs send -f /tmp/2.snap -p /mnt/mysnap1 /mnt/mysnap2
      $ umount /mnt
    
      $ mkfs.btrfs -f /dev/sdc
      $ mount -o compress /dev/sdc /mnt
      $ btrfs receive -f /tmp/1.snap /mnt
      $ btrfs receive -f /tmp/2.snap /mnt
      ERROR: failed to clone extents to foobar
      Operation not supported
    
    The same could be achieved by mounting the source filesystem without
    compression and doing a buffered IO write instead of a direct IO one,
    and mounting the destination filesystem with compression enabled.
    
    So fix this by issuing regular write operations in the send stream
    instead of clone operations when the source offset is zero and the
    range has a length matching the sector size.
    Signed-off-by: default avatarFilipe Manana <fdmanana@suse.com>
    Reviewed-by: default avatarLiu Bo <bo.li.liu@oracle.com>
    Signed-off-by: default avatarChris Mason <clm@fb.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    72610b1b
send.c 158 KB