diff options
Diffstat (limited to 'libre/linux-libre-pae/0004-Btrfs-send-fix-emission-of-invalid-clone-operations-.patch')
-rw-r--r-- | libre/linux-libre-pae/0004-Btrfs-send-fix-emission-of-invalid-clone-operations-.patch | 92 |
1 files changed, 0 insertions, 92 deletions
diff --git a/libre/linux-libre-pae/0004-Btrfs-send-fix-emission-of-invalid-clone-operations-.patch b/libre/linux-libre-pae/0004-Btrfs-send-fix-emission-of-invalid-clone-operations-.patch deleted file mode 100644 index 26c10a8df..000000000 --- a/libre/linux-libre-pae/0004-Btrfs-send-fix-emission-of-invalid-clone-operations-.patch +++ /dev/null @@ -1,92 +0,0 @@ -From d0910be3493b40233c513c9ad01ac0878ae26a48 Mon Sep 17 00:00:00 2001 -From: Filipe Manana <fdmanana@suse.com> -Date: Wed, 29 Jan 2020 17:09:53 +0000 -Subject: [PATCH 4/5] Btrfs: send, fix emission of invalid clone operations - within the same file - -When doing an incremental send and a file has extents shared with itself -at different file offsets, it's possible for send to emit clone operations -that will fail at the destination because the source range goes beyond the -file's current size. This happens when the file size has increased in the -send snapshot, there is a hole between the shared extents and both shared -extents are at file offsets which are greater the file's size in the -parent snapshot. - -Example: - - $ mkfs.btrfs -f /dev/sdb - $ mount /dev/sdb /mnt/sdb - - $ xfs_io -f -c "pwrite -S 0xf1 0 64K" /mnt/sdb/foobar - $ btrfs subvolume snapshot -r /mnt/sdb /mnt/sdb/base - $ btrfs send -f /tmp/1.snap /mnt/sdb/base - - # Create a 320K extent at file offset 512K. - $ xfs_io -c "pwrite -S 0xab 512K 64K" /mnt/sdb/foobar - $ xfs_io -c "pwrite -S 0xcd 576K 64K" /mnt/sdb/foobar - $ xfs_io -c "pwrite -S 0xef 640K 64K" /mnt/sdb/foobar - $ xfs_io -c "pwrite -S 0x64 704K 64K" /mnt/sdb/foobar - $ xfs_io -c "pwrite -S 0x73 768K 64K" /mnt/sdb/foobar - - # Clone part of that 320K extent into a lower file offset (192K). - # This file offset is greater than the file's size in the parent - # snapshot (64K). Also the clone range is a bit behind the offset of - # the 320K extent so that we leave a hole between the shared extents. - $ xfs_io -c "reflink /mnt/sdb/foobar 448K 192K 192K" /mnt/sdb/foobar - - $ btrfs subvolume snapshot -r /mnt/sdb /mnt/sdb/incr - $ btrfs send -p /mnt/sdb/base -f /tmp/2.snap /mnt/sdb/incr - - $ mkfs.btrfs -f /dev/sdc - $ mount /dev/sdc /mnt/sdc - - $ btrfs receive -f /tmp/1.snap /mnt/sdc - $ btrfs receive -f /tmp/2.snap /mnt/sdc - ERROR: failed to clone extents to foobar: Invalid argument - -The problem is that after processing the extent at file offset 256K, which -refers to the first 128K of the 320K extent created by the buffered write -operations, we have 'cur_inode_next_write_offset' set to 384K, which -corresponds to the end offset of the partially shared extent (256K + 128K) -and to the current file size in the receiver. Then when we process the -extent at offset 512K, we do extent backreference iteration to figure out -if we can clone the extent from some other inode or from the same inode, -and we consider the extent at offset 256K of the same inode as a valid -source for a clone operation, which is not correct because at that point -the current file size in the receiver is 384K, which corresponds to the -end of last processed extent (at file offset 256K), so using a clone -source range from 256K to 256K + 320K is invalid because that goes past -the current size of the file (384K) - this makes the receiver get an --EINVAL error when attempting the clone operation. - -So fix this by excluding clone sources that have a range that goes beyond -the current file size in the receiver when iterating extent backreferences. - -A test case for fstests follows soon. - -Fixes: 11f2069c113e02 ("Btrfs: send, allow clone operations within the same file") -CC: stable@vger.kernel.org # 5.5+ -Reviewed-by: Josef Bacik <josef@toxicpanda.com> -Signed-off-by: Filipe Manana <fdmanana@suse.com> -Signed-off-by: David Sterba <dsterba@suse.com> ---- - fs/btrfs/send.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c -index 091e5bc8c7ea..a055b657cb85 100644 ---- a/fs/btrfs/send.c -+++ b/fs/btrfs/send.c -@@ -1269,7 +1269,8 @@ static int __iterate_backrefs(u64 ino, u64 offset, u64 root, void *ctx_) - * destination of the stream. - */ - if (ino == bctx->cur_objectid && -- offset >= bctx->sctx->cur_inode_next_write_offset) -+ offset + bctx->extent_len > -+ bctx->sctx->cur_inode_next_write_offset) - return 0; - } - --- -2.25.0 - |