On Mon, Jul 30, 2018 at 12:39:58PM +0100, fdman...@kernel.org wrote:
> From: Filipe Manana <fdman...@suse.com>
> 
> When doing an incremental send, if we have a file in the parent snapshot
> that has prealloc extents beyond EOF and in the send snapshot it got a
> hole punch that partially covers the prealloc extents, the send stream,
> when replayed by a receiver, can result in a file that has a size bigger
> than it should and filled with zeroes past the correct EOF.
> 
> For example:
> 
>   $ mkfs.btrfs -f /dev/sdb
>   $ mount /dev/sdb /mnt
> 
>   $ xfs_io -f -c "falloc -k 0 4M" /mnt/foobar
>   $ xfs_io -c "pwrite -S 0xea 0 1M" /mnt/foobar
> 
>   $ btrfs subvolume snapshot -r /mnt /mnt/snap1
>   $ btrfs send -f /tmp/1.send /mnt/snap1
> 
>   $ xfs_io -c "fpunch 1M 2M" /mnt/foobar
> 
>   $ btrfs subvolume snapshot -r /mnt /mnt/snap2
>   $ btrfs send -f /tmp/2.send -p /mnt/snap1 /mnt/snap2
> 
>   $ stat --format %s /mnt/snap2/foobar
>   1048576
>   $ md5sum /mnt/snap2/foobar
>   d31659e82e87798acd4669a1e0a19d4f  /mnt/snap2/foobar
> 
>   $ umount /mnt
>   $ mkfs.btrfs -f /dev/sdc
>   $ mount /dev/sdc /mnt
> 
>   $ btrfs receive -f /mnt/1.snap /mnt
>   $ btrfs receive -f /mnt/2.snap /mnt
> 
>   $ stat --format %s /mnt/snap2/foobar
>   3145728
>   # --> should be 1Mb and not 3Mb (which was the end offset of hole
>   #     punch operation)
>   $ md5sum /mnt/snap2/foobar
>   117baf295297c2a995f92da725b0b651  /mnt/snap2/foobar
>   # --> should be d31659e82e87798acd4669a1e0a19d4f as in the original fs
> 
> This issue actually happens only since commit ffa7c4296e93 ("Btrfs: send,
> do not issue unnecessary truncate operations"), but before that commit we
> were issuing a write operation full of zeroes (to "punch" a hole) which
> was extending the file size beyond the correct value and then immediately
> issue a truncate operation to the correct size and undoing the previous
> write operation. Since the send protocol does not support fallocate, for
> extent preallocation and hole punching, fix this by not even attempting
> to send a "hole" (regular write full of zeroes) if it starts at an offset
> greater then or equals to the file's size. This approach, besides being
> much more simple then making send issue the truncate operation, adds the
> benefit of avoiding the useless pair of write of zeroes and truncate
> operations, saving time and IO at the receiver and reducing the size of
> the send stream.
> 
> A test case for fstests follows soon.
> 
> CC: sta...@vger.kernel.org # 4.17+
> Signed-off-by: Filipe Manana <fdman...@suse.com>

Added to misc-next, thanks.
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to