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