diff options
author | Niels de Vos <ndevos@redhat.com> | 2018-06-26 21:40:21 +0200 |
---|---|---|
committer | Nikolaus Rath <Nikolaus@rath.org> | 2018-11-19 12:33:56 +0000 |
commit | 2548c4b83a0871fb92b8ca55cf580a7c58c2f9c6 (patch) | |
tree | 609571da349b5a06c7fd555d7c8044744883a345 /example | |
parent | fe4f9428fc403fa8b99051f52d84ea5bd13f3855 (diff) | |
download | libfuse-2548c4b83a0871fb92b8ca55cf580a7c58c2f9c6.tar.gz |
examples: add copy_file_range() support to passthrough(_fh)
The passthrough example filesystem can be used for validating the API
and the implementation in the FUSE kernel module.
Diffstat (limited to 'example')
-rw-r--r-- | example/passthrough.c | 45 | ||||
-rw-r--r-- | example/passthrough_fh.c | 23 | ||||
-rw-r--r-- | example/passthrough_ll.c | 30 |
3 files changed, 98 insertions, 0 deletions
diff --git a/example/passthrough.c b/example/passthrough.c index b83c17f..da91930 100644 --- a/example/passthrough.c +++ b/example/passthrough.c @@ -29,6 +29,8 @@ #include <config.h> #endif +#define _GNU_SOURCE + #ifdef linux /* For pread()/pwrite()/utimensat() */ #define _XOPEN_SOURCE 700 @@ -445,6 +447,46 @@ static int xmp_removexattr(const char *path, const char *name) } #endif /* HAVE_SETXATTR */ +#ifdef HAVE_COPY_FILE_RANGE +static ssize_t xmp_copy_file_range(const char *path_in, + struct fuse_file_info *fi_in, + off_t offset_in, const char *path_out, + struct fuse_file_info *fi_out, + off_t offset_out, size_t len, int flags) +{ + int fd_in, fd_out; + ssize_t res; + + if(fi_in == NULL) + fd_in = open(path_in, O_RDONLY); + else + fd_in = fi_in->fh; + + if (fd_in == -1) + return -errno; + + if(fi_out == NULL) + fd_out = open(path_out, O_WRONLY); + else + fd_out = fi_out->fh; + + if (fd_out == -1) { + close(fd_in); + return -errno; + } + + res = copy_file_range(fd_in, &offset_in, fd_out, &offset_out, len, + flags); + if (res == -1) + res = -errno; + + close(fd_in); + close(fd_out); + + return res; +} +#endif + static struct fuse_operations xmp_oper = { .init = xmp_init, .getattr = xmp_getattr, @@ -480,6 +522,9 @@ static struct fuse_operations xmp_oper = { .listxattr = xmp_listxattr, .removexattr = xmp_removexattr, #endif +#ifdef HAVE_COPY_FILE_RANGE + .copy_file_range = xmp_copy_file_range, +#endif }; int main(int argc, char *argv[]) diff --git a/example/passthrough_fh.c b/example/passthrough_fh.c index 2b1ed1c..3fc80f8 100644 --- a/example/passthrough_fh.c +++ b/example/passthrough_fh.c @@ -576,6 +576,26 @@ static int xmp_flock(const char *path, struct fuse_file_info *fi, int op) return 0; } +#ifdef HAVE_COPY_FILE_RANGE +static ssize_t xmp_copy_file_range(const char *path_in, + struct fuse_file_info *fi_in, + off_t off_in, const char *path_out, + struct fuse_file_info *fi_out, + off_t off_out, size_t len, int flags) +{ + ssize_t res; + (void) path_in; + (void) path_out; + + res = copy_file_range(fi_in->fh, &off_in, fi_out->fh, &off_out, len, + flags); + if (res == -1) + return -errno; + + return res; +} +#endif + static struct fuse_operations xmp_oper = { .init = xmp_init, .getattr = xmp_getattr, @@ -620,6 +640,9 @@ static struct fuse_operations xmp_oper = { .lock = xmp_lock, #endif .flock = xmp_flock, +#ifdef HAVE_COPY_FILE_RANGE + .copy_file_range = xmp_copy_file_range, +#endif }; int main(int argc, char *argv[]) diff --git a/example/passthrough_ll.c b/example/passthrough_ll.c index 4091395..5cca531 100644 --- a/example/passthrough_ll.c +++ b/example/passthrough_ll.c @@ -37,6 +37,8 @@ #define _GNU_SOURCE #define FUSE_USE_VERSION 31 +#include "config.h" + #include <fuse_lowlevel.h> #include <unistd.h> #include <stdlib.h> @@ -1121,6 +1123,31 @@ out: fuse_reply_err(req, saverr); } +#ifdef HAVE_COPY_FILE_RANGE +static void lo_copy_file_range(fuse_req_t req, fuse_ino_t ino_in, off_t off_in, + struct fuse_file_info *fi_in, + fuse_ino_t ino_out, off_t off_out, + struct fuse_file_info *fi_out, size_t len, + int flags) +{ + ssize_t res; + + if (lo_debug(req)) + fprintf(stderr, "lo_copy_file_range(ino=%" PRIu64 "/fd=%lu, " + "off=%lu, ino=%" PRIu64 "/fd=%lu, " + "off=%lu, size=%zd, flags=0x%x)\n", + ino_in, fi_in->fh, off_in, ino_out, fi_out->fh, off_out, + len, flags); + + res = copy_file_range(fi_in->fh, &off_in, fi_out->fh, &off_out, len, + flags); + if (res < 0) + fuse_reply_err(req, -errno); + else + fuse_reply_write(req, res); +} +#endif + static struct fuse_lowlevel_ops lo_oper = { .init = lo_init, .lookup = lo_lookup, @@ -1155,6 +1182,9 @@ static struct fuse_lowlevel_ops lo_oper = { .listxattr = lo_listxattr, .setxattr = lo_setxattr, .removexattr = lo_removexattr, +#ifdef HAVE_COPY_FILE_RANGE + .copy_file_range = lo_copy_file_range, +#endif }; int main(int argc, char *argv[]) |