On Wed, Jul 17, 2019 at 01:23:39PM +0100, fdman...@kernel.org wrote:
> From: Filipe Manana <fdman...@suse.com>
> 
> When doing an incremental send operation we can fail if we previously did
> deduplication operations against a file that exists in both snapshots. In
> that case we will fail the send operation with -EIO and print a message
> to dmesg/syslog like the following:
> 
>   BTRFS error (device sdc): Send: inconsistent snapshot, found updated \
>   extent for inode 257 without updated inode item, send root is 258, \
>   parent root is 257
> 
> This requires that we deduplicate to the same file in both snapshots for
> the same amount of times on each snapshot. The issue happens because a
> deduplication only updates the iversion of an inode and does not update
> any other field of the inode, therefore if we deduplicate the file on
> each snapshot for the same amount of time, the inode will have the same
> iversion value (stored as the "sequence" field on the inode item) on both
> snapshots, therefore it will be seen as unchanged between in the send
> snapshot while there are new/updated/deleted extent items when comparing
> to the parent snapshot. This makes the send operation return -EIO and
> print an error message.
> 
> Example reproducer:
> 
>   $ mkfs.btrfs -f /dev/sdb
>   $ mount /dev/sdb /mnt
> 
>   # Create our first file. The first half of the file has several 64Kb
>   # extents while the second half as a single 512Kb extent.
>   $ xfs_io -f -s -c "pwrite -S 0xb8 -b 64K 0 512K" /mnt/foo
>   $ xfs_io -c "pwrite -S 0xb8 512K 512K" /mnt/foo
> 
>   # Create the base snapshot and the parent send stream from it.
>   $ btrfs subvolume snapshot -r /mnt /mnt/mysnap1
>   $ btrfs send -f /tmp/1.snap /mnt/mysnap1
> 
>   # Create our second file, that has exactly the same data as the first
>   # file.
>   $ xfs_io -f -c "pwrite -S 0xb8 0 1M" /mnt/bar
> 
>   # Create the second snapshot, used for the incremental send, before
>   # doing the file deduplication.
>   $ btrfs subvolume snapshot -r /mnt /mnt/mysnap2
> 
>   # Now before creating the incremental send stream:
>   #
>   # 1) Deduplicate into a subrange of file foo in snapshot mysnap1. This
>   #    will drop several extent items and add a new one, also updating
>   #    the inode's iversion (sequence field in inode item) by 1, but not
>   #    any other field of the inode;
>   #
>   # 2) Deduplicate into a different subrange of file foo in snapshot
>   #    mysnap2. This will replace an extent item with a new one, also
>   #    updating the inode's iversion by 1 but not any other field of the
>   #    inode.
>   #
>   # After these two deduplication operations, the inode items, for file
>   # foo, are identical in both snapshots, but we have different extent
>   # items for this inode in both snapshots. We want to check this doesn't
>   # cause send to fail with an error or produce an incorrect stream.
> 
>   $ xfs_io -r -c "dedupe /mnt/bar 0 0 512K" /mnt/mysnap1/foo
>   $ xfs_io -r -c "dedupe /mnt/bar 512K 512K 512K" /mnt/mysnap2/foo
> 
>   # Create the incremental send stream.
>   $ btrfs send -p /mnt/mysnap1 -f /tmp/2.snap /mnt/mysnap2
>   ERROR: send ioctl failed with -5: Input/output error
> 
> This issue started happening back in 2015 when deduplication was updated
> to not update the inode's ctime and mtime and update only the iversion.
> Back then we would hit a BUG_ON() in send, but later in 2016 send was
> updated to return -EIO and print the error message instead of doing the
> BUG_ON().
> 
> A test case for fstests follows soon.
> 
> Fixes: 1c919a5e13702c ("btrfs: don't update mtime/ctime on deduped inodes")
> Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=203933
> Signed-off-by: Filipe Manana <fdman...@suse.com>

Added to misc-next, thanks.

Reply via email to