Messages in this thread | | | Date | Mon, 30 Sep 2013 18:31:59 +0200 | From | Miklos Szeredi <> | Subject | Re: [RFC] extending splice for copy offloading |
| |
Here's an example "cp" app using direct splice (and without fallback to non-splice, which is obviously required unless the kernel is known to support direct splice).
Untested, but trivial enough...
The important part is, I think, that the app must not assume that the kernel can complete the request in one go.
Thanks, Miklos
---- #define _GNU_SOURCE
#include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <limits.h> #include <sys/stat.h> #include <err.h>
#ifndef SPLICE_F_DIRECT #define SPLICE_F_DIRECT (0x10) /* neither splice fd is a pipe */ #endif
int main(int argc, char *argv[]) { struct stat stbuf; int in_fd; int out_fd; int res; off_t off;
if (argc != 3) errx(1, "usage: %s from to", argv[0]);
in_fd = open(argv[1], O_RDONLY); if (in_fd == -1) err(1, "opening %s", argv[1]);
res = fstat(in_fd, &stbuf); if (res == -1) err(1, "fstat");
out_fd = open(argv[2], O_CREAT | O_WRONLY | O_TRUNC, stbuf.st_mode); if (out_fd == -1) err(1, "opening %s", argv[2]);
do { off_t in_off = off, out_off = off; ssize_t rres;
rres = splice(in_fd, &in_off, out_fd, &out_off, SSIZE_MAX, SPLICE_F_DIRECT); if (rres == -1) err(1, "splice"); if (rres == 0) break;
off += rres; } while (off < stbuf.st_size);
res = close(in_fd); if (res == -1) err(1, "close");
res = fsync(out_fd); if (res == -1) err(1, "fsync");
res = close(out_fd); if (res == -1) err(1, "close");
return 0; }
| |