git » libjio » commit 0e1690d

btrfs: Copy length must also be page-aligned

author Alberto Bertogli
2009-10-10 19:52:46 UTC
committer Alberto Bertogli
2009-10-10 20:36:27 UTC
parent 9519d02e1306be0dd8a63fa869e0f6561a959013

btrfs: Copy length must also be page-aligned

Signed-off-by: Alberto Bertogli <albertito@blitiri.com.ar>

libjio/btrfs.c +19 -1

diff --git a/libjio/btrfs.c b/libjio/btrfs.c
index 2647df5..b8fccdf 100644
--- a/libjio/btrfs.c
+++ b/libjio/btrfs.c
@@ -5,6 +5,7 @@
 #include "btrfs.h"
 #include "trans.h"
 #include "journal.h"
+#include "common.h"
 
 
 /* Wrapper around btrfs' clone_range ioctl() */
@@ -28,6 +29,7 @@ ssize_t attempt_btrfs_clone_ranges(int fd, struct operation *head_op,
 		struct journal_op *jop)
 {
 	ssize_t r, written;
+	size_t clone_len;
 	struct operation *op;
 	off_t journal_off;
 
@@ -37,12 +39,28 @@ ssize_t attempt_btrfs_clone_ranges(int fd, struct operation *head_op,
 		/* skip the header + padding */
 		journal_off += BSZ;
 
-		r = btrfs_clone_range(jop->fd, journal_off, op->len, fd,
+		/* clone must end in block size boundary too */
+		clone_len = op->len - op->len % BSZ;
+
+		r = btrfs_clone_range(jop->fd, journal_off, clone_len, fd,
 				op->offset);
 		if (r != 0) {
 			perror("btrfs_clone_range");
 			return -1;
 		}
+
+		/* copy the remainder data by hand */
+		if (op->len - clone_len) {
+			r = spwrite(fd, (unsigned char *) op->buf + clone_len,
+					op->len - clone_len,
+					op->offset + clone_len);
+			if (r != op->len - clone_len) {
+				perror("btrfs remainder");
+				return -1;
+			}
+			printf("btrfs clone rem ok: %zu\n", r);
+		}
+
 		written += op->len;
 
 		/* skip the data + padding */