btrfs-progs: send: use splice syscall instead of read/write to transfer buffer

We can utilize the splice syscall as the source descriptor is a pipe and
avoid read/write through userspace. The original implementation is kept
but shall be removed in the future.

Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
David Sterba 2016-11-02 14:54:10 +01:00
parent f6f9cd0cb7
commit ba23855cdc
1 changed files with 33 additions and 1 deletions

View File

@ -197,6 +197,7 @@ static int add_clone_source(struct btrfs_send *sctx, u64 root_id)
return 0;
}
#if 0
static int write_buf(int fd, const char *buf, size_t size)
{
int ret;
@ -224,7 +225,7 @@ out:
return ret;
}
static void *dump_thread(void *arg)
static void *dump_thread_copy(void *arg)
{
int ret;
struct btrfs_send *sctx = (struct btrfs_send*)arg;
@ -249,6 +250,37 @@ static void *dump_thread(void *arg)
goto out;
}
out:
if (ret < 0)
exit(-ret);
return ERR_PTR(ret);
}
#endif
static void* dump_thread(void *arg)
{
int ret;
struct btrfs_send *sctx = (struct btrfs_send*)arg;
while (1) {
ssize_t sbytes;
/* Source is a pipe, output is either file or stdout */
sbytes = splice(sctx->send_fd, NULL, sctx->dump_fd,
NULL, SEND_BUFFER_SIZE, SPLICE_F_MORE);
if (sbytes < 0) {
ret = -errno;
error("failed to read stream from kernel: %s",
strerror(-ret));
goto out;
}
if (!sbytes) {
ret = 0;
goto out;
}
}
out:
if (ret < 0)
exit(-ret);