From 30bc0e2791d1593043531988fe1c88500f3d77c3 Mon Sep 17 00:00:00 2001 From: Josh Durgin Date: Sun, 20 Oct 2013 10:46:49 -0700 Subject: [PATCH] safe_io: add functions for handling splice Like the other functions, these don't handle non-blocking I/O. Signed-off-by: Josh Durgin --- configure.ac | 6 ++++++ src/common/safe_io.c | 34 ++++++++++++++++++++++++++++++++++ src/common/safe_io.h | 13 +++++++++++++ 3 files changed, 53 insertions(+) diff --git a/configure.ac b/configure.ac index 58c5e1b94a634..91c623abdaf16 100644 --- a/configure.ac +++ b/configure.ac @@ -536,6 +536,12 @@ AC_CHECK_FUNC([fallocate], []) +# splice/tee +AC_CHECK_FUNC([splice], + [AC_DEFINE([CEPH_HAVE_SPLICE], [], [splice(2) is supported])], + []) + +AC_CHECK_HEADERS([arpa/nameser_compat.h]) AC_CHECK_HEADERS([sys/prctl.h]) AC_CHECK_FUNCS([prctl]) diff --git a/src/common/safe_io.c b/src/common/safe_io.c index afee82edf0778..16cc7293d9cd3 100644 --- a/src/common/safe_io.c +++ b/src/common/safe_io.c @@ -117,6 +117,40 @@ ssize_t safe_pwrite(int fd, const void *buf, size_t count, off_t offset) return 0; } +#ifdef CEPH_HAVE_SPLICE +ssize_t safe_splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, + size_t len, unsigned int flags) +{ + size_t cnt = 0; + + while (cnt < len) { + ssize_t r = splice(fd_in, off_in, fd_out, off_out, len - cnt, flags); + if (r <= 0) { + if (r == 0) { + // EOF + return cnt; + } + if (errno == EINTR) + continue; + return -errno; + } + cnt += r; + } + return cnt; +} + +ssize_t safe_splice_exact(int fd_in, loff_t *off_in, int fd_out, + loff_t *off_out, size_t len, unsigned int flags) +{ + ssize_t ret = safe_splice(fd_in, off_in, fd_out, off_out, len, flags); + if (ret < 0) + return ret; + if ((size_t)ret != len) + return -EDOM; + return 0; +} +#endif + int safe_write_file(const char *base, const char *file, const char *val, size_t vallen) { diff --git a/src/common/safe_io.h b/src/common/safe_io.h index a4c9bc7a72f91..c45589eee7e05 100644 --- a/src/common/safe_io.h +++ b/src/common/safe_io.h @@ -15,6 +15,7 @@ #ifndef CEPH_SAFE_IO #define CEPH_SAFE_IO +#include "acconfig.h" #include "common/compiler_extensions.h" #include @@ -35,6 +36,18 @@ extern "C" { WARN_UNUSED_RESULT; ssize_t safe_pwrite(int fd, const void *buf, size_t count, off_t offset) WARN_UNUSED_RESULT; +#ifdef CEPH_HAVE_SPLICE + /* + * Similar to the above (non-exact version) and below (exact version). + * See splice(2) for parameter descriptions. + */ + ssize_t safe_splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, + size_t len, unsigned int flags) + WARN_UNUSED_RESULT; + ssize_t safe_splice_exact(int fd_in, loff_t *off_in, int fd_out, + loff_t *off_out, size_t len, unsigned int flags) + WARN_UNUSED_RESULT; +#endif /* * Same as the above functions, but return -EDOM unless exactly the requested -- 2.39.5