From cb35a374ac3aafc7d0761b6796e5ac9ebce1678f Mon Sep 17 00:00:00 2001 From: Antonio SJ Musumeci Date: Wed, 11 May 2016 11:43:26 -0400 Subject: [PATCH] rework fallocate logic --- src/fallocate.cpp | 20 +++----------------- src/fs_clonefile.cpp | 34 ++++++++++------------------------ src/fs_fallocate.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/fs_fallocate.hpp | 29 +++++++++++++++++++++++++++++ src/fs_sendfile.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ src/fs_sendfile.hpp | 28 ++++++++++++++++++++++++++++ 6 files changed, 154 insertions(+), 41 deletions(-) create mode 100644 src/fs_fallocate.cpp create mode 100644 src/fs_fallocate.hpp create mode 100644 src/fs_sendfile.cpp create mode 100644 src/fs_sendfile.hpp diff --git a/src/fallocate.cpp b/src/fallocate.cpp index 5026daf3..349bcecc 100644 --- a/src/fallocate.cpp +++ b/src/fallocate.cpp @@ -19,8 +19,8 @@ #include #include -#include +#include "fs_fallocate.hpp" #include "fileinfo.hpp" static @@ -32,22 +32,7 @@ _fallocate(const int fd, { int rv; -#ifdef _GNU_SOURCE - rv = ::fallocate(fd,mode,offset,len); -#elif defined _XOPEN_SOURCE >= 600 || _POSIX_C_SOURCE >= 200112L - if(mode) - { - rv = -1; - errno = EOPNOTSUPP; - } - else - { - rv = ::posix_fallocate(fd,offset,len); - } -#else - rv = -1; - errno = EOPNOTSUPP; -#endif + rv = fs::fallocate(fd,mode,offset,len); return ((rv == -1) ? -errno : 0); } @@ -65,6 +50,7 @@ namespace mergerfs { FileInfo *fi = reinterpret_cast(ffi->fh); + return _fallocate(fi->fd, mode, offset, diff --git a/src/fs_clonefile.cpp b/src/fs_clonefile.cpp index 886728cd..48707ae2 100644 --- a/src/fs_clonefile.cpp +++ b/src/fs_clonefile.cpp @@ -14,20 +14,19 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include +#include #include -#include #include +#include #include -#include -#include -#ifdef __linux__ -#include -#endif #include #include #include "fs_attr.hpp" +#include "fs_fallocate.hpp" +#include "fs_sendfile.hpp" #include "fs_xattr.hpp" using std::string; @@ -35,20 +34,6 @@ using std::vector; namespace fs { - static - ssize_t - sendfile(const int fdin, - const int fdout, - const size_t count) - { -#if defined __linux__ - off_t offset = 0; - return ::sendfile(fdout,fdin,&offset,count); -#else - return (errno=EINVAL,-1); -#endif - } - int writen(const int fd, const char *buf, @@ -69,7 +54,7 @@ namespace fs } nleft -= nwritten; - buf += nwritten; + buf += nwritten; } return count; @@ -91,6 +76,8 @@ namespace fs bufsize = (blocksize * 16); buf.resize(bufsize); + ::lseek(fdin,0,SEEK_SET); + totalwritten = 0; while(totalwritten < count) { @@ -99,8 +86,7 @@ namespace fs { if(errno == EINTR) continue; - else - return -1; + return -1; } nw = writen(fdout,&buf[0],nr); @@ -125,7 +111,7 @@ namespace fs ::posix_fadvise(fdin,0,count,POSIX_FADV_WILLNEED); ::posix_fadvise(fdin,0,count,POSIX_FADV_SEQUENTIAL); - ::posix_fallocate(fdout,0,count); + fs::fallocate(fdout,0,0,count); rv = fs::sendfile(fdin,fdout,count); if((rv == -1) && ((errno == EINVAL) || (errno == ENOSYS))) diff --git a/src/fs_fallocate.cpp b/src/fs_fallocate.cpp new file mode 100644 index 00000000..32ea9e31 --- /dev/null +++ b/src/fs_fallocate.cpp @@ -0,0 +1,44 @@ +/* + Copyright (c) 2016, Antonio SJ Musumeci + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#include +#include + +#include "fs_fallocate.hpp" + +namespace fs +{ + int + fallocate(const int fd, + const int mode, + const off_t offset, + const off_t len) + { + int rv; + +#ifdef __linux__ + rv = ::fallocate(fd,mode,offset,len); +#elif _XOPEN_SOURCE >= 600 || _POSIX_C_SOURCE >= 200112L + rv = (mode ? + (errno=EOPNOTSUPP,-1) : + (::posix_fallocate(fd,offset,len))); +#else + rv = (errno=EOPNOTSUPP,-1); +#endif + + return rv; + } +} diff --git a/src/fs_fallocate.hpp b/src/fs_fallocate.hpp new file mode 100644 index 00000000..0e3cf3aa --- /dev/null +++ b/src/fs_fallocate.hpp @@ -0,0 +1,29 @@ +/* + Copyright (c) 2016, Antonio SJ Musumeci + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#ifndef __FS_FALLOCATE_HPP__ +#define __FS_FALLOCATE_HPP__ + +namespace fs +{ + int + fallocate(const int fd, + const int mode, + const off_t offset, + const off_t len); +} + +#endif // __FS_FALLOCATE_HPP__ diff --git a/src/fs_sendfile.cpp b/src/fs_sendfile.cpp new file mode 100644 index 00000000..db8c14b5 --- /dev/null +++ b/src/fs_sendfile.cpp @@ -0,0 +1,40 @@ +/* + Copyright (c) 2016, Antonio SJ Musumeci + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#include + +#if defined __linux__ +#include +#endif + +#include "fs_sendfile.hpp" + +namespace fs +{ + ssize_t + sendfile(const int fdin, + const int fdout, + const size_t count) + { +#if defined __linux__ + off_t offset = 0; + + return ::sendfile(fdout,fdin,&offset,count); +#else + return (errno=EINVAL,-1); +#endif + } +} diff --git a/src/fs_sendfile.hpp b/src/fs_sendfile.hpp new file mode 100644 index 00000000..eb814966 --- /dev/null +++ b/src/fs_sendfile.hpp @@ -0,0 +1,28 @@ +/* + Copyright (c) 2016, Antonio SJ Musumeci + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#ifndef __FS_SENDFILE_HPP__ +#define __FS_SENDFILE_HPP__ + +namespace fs +{ + ssize_t + sendfile(const int fdin, + const int fdout, + const size_t count); +} + +#endif // __FS_SENDFILE_HPP__