summaryrefslogtreecommitdiff
path: root/fs/btrfs/send.c
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2021-01-27 22:48:04 +0300
committerArnaldo Carvalho de Melo <acme@redhat.com>2021-01-27 22:48:04 +0300
commit70f0ba9f2435c1f8693a6d958d8f9cf95e80d94e (patch)
tree1d65c007c7b32c9a956d65c6f349c6f59ad525b7 /fs/btrfs/send.c
parentcd07e536b0201fceffd90a701bfb1e1fc07fcd34 (diff)
parent76c057c84d286140c6c416c3b4ba832cd1d8984e (diff)
downloadlinux-70f0ba9f2435c1f8693a6d958d8f9cf95e80d94e.tar.xz
Merge remote-tracking branch 'torvalds/master' into perf/core
To pick up fixes. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'fs/btrfs/send.c')
-rw-r--r--fs/btrfs/send.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index ae97f4dbaff3..78a35374d492 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -5512,6 +5512,21 @@ static int clone_range(struct send_ctx *sctx,
break;
offset += clone_len;
clone_root->offset += clone_len;
+
+ /*
+ * If we are cloning from the file we are currently processing,
+ * and using the send root as the clone root, we must stop once
+ * the current clone offset reaches the current eof of the file
+ * at the receiver, otherwise we would issue an invalid clone
+ * operation (source range going beyond eof) and cause the
+ * receiver to fail. So if we reach the current eof, bail out
+ * and fallback to a regular write.
+ */
+ if (clone_root->root == sctx->send_root &&
+ clone_root->ino == sctx->cur_ino &&
+ clone_root->offset >= sctx->cur_inode_next_write_offset)
+ break;
+
data_offset += clone_len;
next:
path->slots[0]++;