summaryrefslogtreecommitdiff
path: root/src/shared/copy.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2014-12-12 03:20:53 +0100
committerLennart Poettering <lennart@poettering.net>2014-12-12 13:35:32 +0100
commit0254b455e9730691e9f90d53afe860a0f3229f6d (patch)
tree24a0db68b4816f5538b705eca11b7e8ada3bee7c /src/shared/copy.c
parentf9ac15442e4132f00eca5495d53c17062aae13e0 (diff)
copy: teach copy_bytes() btrfs reflink magic
Diffstat (limited to 'src/shared/copy.c')
-rw-r--r--src/shared/copy.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/src/shared/copy.c b/src/shared/copy.c
index f22a94099..4c41f2fdd 100644
--- a/src/shared/copy.c
+++ b/src/shared/copy.c
@@ -27,10 +27,18 @@
int copy_bytes(int fdf, int fdt, off_t max_bytes) {
bool try_sendfile = true;
+ int r;
assert(fdf >= 0);
assert(fdt >= 0);
+ /* Try btrfs reflinks first. */
+ if (max_bytes == (off_t) -1) {
+ r = btrfs_reflink(fdf, fdt);
+ if (r >= 0)
+ return 0;
+ }
+
for (;;) {
size_t m = PIPE_BUF;
ssize_t n;
@@ -64,7 +72,6 @@ int copy_bytes(int fdf, int fdt, off_t max_bytes) {
/* As a fallback just copy bits by hand */
{
char buf[m];
- int r;
n = read(fdf, buf, m);
if (n < 0)
@@ -72,7 +79,7 @@ int copy_bytes(int fdf, int fdt, off_t max_bytes) {
if (n == 0) /* EOF */
break;
- r = loop_write(fdt, buf, n, false);
+ r = loop_write(fdt, buf, (size_t) n, false);
if (r < 0)
return r;