On Mon, Jul 30, 2018 at 12:39:58PM +0100, fdmanana@xxxxxxxxxx wrote:
> From: Filipe Manana <fdmanana@xxxxxxxx>
>
> 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: stable@xxxxxxxxxxxxxxx # 4.17+
> Signed-off-by: Filipe Manana <fdmanana@xxxxxxxx>
Added to misc-next, thanks.
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html