diff --git a/LICENSE b/LICENSE index 2f46d03d..c1ec0aba 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,7 @@ /* ISC License - Copyright (c) 2024, Antonio SJ Musumeci + Copyright (c) 2025, 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 diff --git a/src/error.hpp b/src/error.hpp new file mode 100644 index 00000000..e81df6e9 --- /dev/null +++ b/src/error.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include "errno.hpp" + +#include + + +struct Err +{ +private: + std::optional _err; + +public: + Err() + { + } + + operator int() + { + return (_err.has_value() ? _err.value() : -ENOENT); + } + + Err& + operator=(int v_) + { + if(!_err.has_value()) + _err = v_; + else if(v_ >= 0) + _err = v_; + + return *this; + } +}; diff --git a/src/fs_acl.cpp b/src/fs_acl.cpp index 3737bc16..818f193c 100644 --- a/src/fs_acl.cpp +++ b/src/fs_acl.cpp @@ -16,29 +16,25 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fs_acl.hpp" + #include "fs_lgetxattr.hpp" #include "fs_path.hpp" #include -const char POSIX_ACL_DEFAULT_XATTR[] = "system.posix_acl_default"; +constexpr const char POSIX_ACL_DEFAULT_XATTR[] = "system.posix_acl_default"; -namespace fs +bool +fs::acl::dir_has_defaults(const std::string &fullpath_) { - namespace acl - { - bool - dir_has_defaults(const std::string &fullpath_) - { - int rv; - std::string dirpath; + int rv; + std::string dirpath; - dirpath = fs::path::dirname(fullpath_); + dirpath = fs::path::dirname(fullpath_); - rv = fs::lgetxattr(dirpath,POSIX_ACL_DEFAULT_XATTR,NULL,0); + rv = fs::lgetxattr(dirpath,POSIX_ACL_DEFAULT_XATTR,NULL,0); - return (rv != -1); - } - } + return (rv >= 0); } diff --git a/src/fs_attr_linux.icpp b/src/fs_attr_linux.icpp index a5a3c3c6..6133d6ed 100644 --- a/src/fs_attr_linux.icpp +++ b/src/fs_attr_linux.icpp @@ -37,7 +37,7 @@ _get_fs_ioc_flags(const int fd, rv = fs::ioctl(fd,FS_IOC_GETFLAGS,(void*)&flags); if(rv == -EINVAL) - rv = ENOTSUP; + rv = -ENOTSUP; return rv; } @@ -52,8 +52,8 @@ _get_fs_ioc_flags(const string &file, const int openflags = O_RDONLY|O_NONBLOCK; fd = fs::open(file,openflags); - if(fd == -1) - return -errno; + if(fd < 0) + return fd; rv = ::_get_fs_ioc_flags(fd,flags); if(rv < 0) @@ -74,7 +74,7 @@ _set_fs_ioc_flags(const int fd, rv = fs::ioctl(fd,FS_IOC_SETFLAGS,(void*)&flags); if(rv == -EINVAL) - rv = ENOTSUP; + rv = -ENOTSUP; return rv; } @@ -89,8 +89,8 @@ _set_fs_ioc_flags(const string &file, const int openflags = O_RDONLY|O_NONBLOCK; fd = fs::open(file,openflags); - if(fd == -1) - return -errno; + if(fd < 0) + return fd; rv = ::_set_fs_ioc_flags(fd,flags); if(rv < 0) diff --git a/src/fs_attr_unsupported.icpp b/src/fs_attr_unsupported.icpp index 4a5c37bb..a743af8d 100644 --- a/src/fs_attr_unsupported.icpp +++ b/src/fs_attr_unsupported.icpp @@ -14,27 +14,21 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "errno.hpp" +#include "fs_attr.hpp" -#include +#include "errno.hpp" -namespace fs +int +fs::attr::copy(const int fdin, + const int fdout) { - namespace attr - { - int - copy(const int fdin, - const int fdout) - { - return (errno=ENOTSUP,-1); - } + return -ENOTSUP; +} - int - copy(const std::string &from, - const std::string &to) - { - return (errno=ENOTSUP,-1); - } - } +int +fs::attr::copy(const std::string &from, + const std::string &to) +{ + return -ENOTSUP; } diff --git a/src/fs_clonepath.cpp b/src/fs_clonepath.cpp index bee9e27c..5827597e 100644 --- a/src/fs_clonepath.cpp +++ b/src/fs_clonepath.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fs_clonepath.hpp" + #include "errno.h" #include "fs_attr.hpp" #include "fs_clonepath.hpp" @@ -30,131 +32,124 @@ using std::string; -namespace l +static +bool +_ignorable_error(const int err_) { - static - bool - ignorable_error(const int err_) - { - switch(err_) - { - case ENOTTY: - case ENOTSUP: + switch(err_) + { + case ENOTTY: + case ENOTSUP: #if ENOTSUP != EOPNOTSUPP - case EOPNOTSUPP: + case EOPNOTSUPP: #endif - return true; - } + return true; + } - return false; - } + return false; } -namespace fs +/* + Attempts to clone a path. + The directories which already exist are left alone. + The new directories have metadata set to match the original if + possible. Optionally ignore errors on metadata copies. +*/ +int +fs::clonepath(const string &srcpath_, + const string &dstpath_, + const char *relpath_, + const bool return_metadata_errors_) { - /* - Attempts to clone a path. - The directories which already exist are left alone. - The new directories have metadata set to match the original if - possible. Optionally ignore errors on metadata copies. - */ - int - clonepath(const string &fromsrc_, - const string &tosrc_, - const char *relative_, - const bool return_metadata_errors_) - { - int rv; - struct stat st; - string topath; - string frompath; - string dirname; - - if((relative_ == NULL) || (relative_[0] == '\0')) - return 0; - - dirname = fs::path::dirname(relative_); - if(dirname != "/") - { - rv = fs::clonepath(fromsrc_,tosrc_,dirname,return_metadata_errors_); - if(rv == -1) - return -1; - } - - frompath = fs::path::make(fromsrc_,relative_); - rv = fs::lstat(frompath,&st); - if(rv == -1) - return -1; - else if(!S_ISDIR(st.st_mode)) - return (errno=ENOTDIR,-1); - - topath = fs::path::make(tosrc_,relative_); - rv = fs::mkdir(topath,st.st_mode); - if(rv == -1) - { - if(errno == EEXIST) - return 0; - else - return -1; - } - - // it may not support it... it's fine... - rv = fs::attr::copy(frompath,topath); - if(return_metadata_errors_ && (rv < 0) && !l::ignorable_error(-rv)) - return -1; - - // it may not support it... it's fine... - rv = fs::xattr::copy(frompath,topath); - if(return_metadata_errors_ && (rv == -1) && !l::ignorable_error(errno)) - return -1; - - rv = fs::lchown_check_on_error(topath,st); - if(return_metadata_errors_ && (rv == -1)) - return -1; - - rv = fs::lutimens(topath,st); - if(return_metadata_errors_ && (rv == -1)) - return -1; + int rv; + struct stat st; + string dstpath; + string srcpath; + string dirname; + if((relpath_ == NULL) || (relpath_[0] == '\0')) return 0; - } - - int - clonepath(const string &from_, - const string &to_, - const string &relative_, - const bool return_metadata_errors_) - { - return fs::clonepath(from_, - to_, - relative_.c_str(), - return_metadata_errors_); - } - - int - clonepath_as_root(const string &from_, - const string &to_, - const char *relative_, - const bool return_metadata_errors_) - { - if((relative_ == NULL) || (relative_[0] == '\0')) - return 0; - if(from_ == to_) - return 0; + dirname = fs::path::dirname(relpath_); + if(dirname != "/") { - const ugid::SetRootGuard ugidGuard; - - return fs::clonepath(from_,to_,relative_,return_metadata_errors_); + rv = fs::clonepath(srcpath_,dstpath_,dirname,return_metadata_errors_); + if(rv < 0) + return rv; } - } - - int - clonepath_as_root(const string &from_, - const string &to_, - const string &relative_, - const bool return_metadata_errors_) - { - return fs::clonepath_as_root(from_,to_,relative_.c_str(),return_metadata_errors_); - } + + srcpath = fs::path::make(srcpath_,relpath_); + rv = fs::lstat(srcpath,&st); + if(rv < 0) + return rv; + else if(!S_ISDIR(st.st_mode)) + return -ENOTDIR; + + dstpath = fs::path::make(dstpath_,relpath_); + rv = fs::mkdir(dstpath,st.st_mode); + if(rv < 0) + return ((rv == -EEXIST) ? 0 : rv); + + // it may not support it... it's fine... + rv = fs::attr::copy(srcpath,dstpath); + if(return_metadata_errors_ && (rv < 0) && !::_ignorable_error(-rv)) + return rv; + + // it may not support it... it's fine... + rv = fs::xattr::copy(srcpath,dstpath); + if(return_metadata_errors_ && (rv < 0) && !::_ignorable_error(-rv)) + return rv; + + rv = fs::lchown_check_on_error(dstpath,st); + if(return_metadata_errors_ && (rv < 0)) + return rv; + + rv = fs::lutimens(dstpath,st); + if(return_metadata_errors_ && (rv < 0)) + return rv; + + return 0; +} + +int +fs::clonepath(const string &srcpath_, + const string &dstpath_, + const string &relpath_, + const bool return_metadata_errors_) +{ + return fs::clonepath(srcpath_, + dstpath_, + relpath_.c_str(), + return_metadata_errors_); +} + +int +fs::clonepath_as_root(const string &srcpath_, + const string &dstpath_, + const char *relpath_, + const bool return_metadata_errors_) +{ + if((relpath_ == NULL) || (relpath_[0] == '\0')) + return 0; + if(srcpath_ == dstpath_) + return 0; + + const ugid::SetRootGuard ugid_guard; + + return fs::clonepath(srcpath_, + dstpath_, + relpath_, + return_metadata_errors_); +} + +int +fs::clonepath_as_root(const string &srcpath_, + const string &dstpath_, + const string &relpath_, + const bool return_metadata_errors_) +{ + return fs::clonepath_as_root(srcpath_, + dstpath_, + relpath_.c_str(), + return_metadata_errors_); } diff --git a/src/fs_clonepath.hpp b/src/fs_clonepath.hpp index 8ad68c97..00b717f3 100644 --- a/src/fs_clonepath.hpp +++ b/src/fs_clonepath.hpp @@ -21,21 +21,21 @@ namespace fs { - int clonepath(const std::string &from, - const std::string &to, - const char *relative, + int clonepath(const std::string &srcpath, + const std::string &dstpath, + const char *relpath, const bool return_metadata_errors = false); - int clonepath(const std::string &from, - const std::string &to, - const std::string &relative, + int clonepath(const std::string &srcpath, + const std::string &dstpath, + const std::string &relpath, const bool return_metadata_errors = false); - int clonepath_as_root(const std::string &from, - const std::string &to, - const char *relative, + int clonepath_as_root(const std::string &srcpath, + const std::string &dstpath, + const char *relpath, const bool return_metadata_errors = false); - int clonepath_as_root(const std::string &from, - const std::string &to, - const std::string &relative, + int clonepath_as_root(const std::string &srcpath, + const std::string &dstpath, + const std::string &relpath, const bool return_metadata_errors = false); } diff --git a/src/fs_close.hpp b/src/fs_close.hpp index 646482fa..260a48b3 100644 --- a/src/fs_close.hpp +++ b/src/fs_close.hpp @@ -18,16 +18,24 @@ #pragma once +#include "to_neg_errno.hpp" + #include namespace fs { - static - inline - int - close(const int fd_) - { - return ::close(fd_); - } + static inline int close(const int fd); +} + +static +inline +int +fs::close(const int fd_) +{ + int rv; + + rv = ::close(fd_); + + return ::to_neg_errno(rv); } diff --git a/src/fs_closedir.hpp b/src/fs_closedir.hpp index f7fc081f..fb081791 100644 --- a/src/fs_closedir.hpp +++ b/src/fs_closedir.hpp @@ -18,17 +18,25 @@ #pragma once +#include "to_neg_errno.hpp" + #include #include namespace fs { - static - inline - int - closedir(DIR *dirp_) - { - return ::closedir(dirp_); - } + static inline int closedir(DIR *dirp); +} + +static +inline +int +fs::closedir(DIR *dirp_) +{ + int rv; + + rv = ::closedir(dirp_); + + return ::to_neg_errno(rv); } diff --git a/src/fs_copy_file_range_linux.icpp b/src/fs_copy_file_range_linux.icpp index 79103443..1bf8b185 100644 --- a/src/fs_copy_file_range_linux.icpp +++ b/src/fs_copy_file_range_linux.icpp @@ -16,11 +16,13 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fs_copy_file_range.hpp" + #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif -#include "errno.hpp" +#include "to_neg_errno.hpp" #include @@ -31,66 +33,60 @@ #include -namespace l +static +int64_t +_copy_file_range_(int src_fd_, + int64_t *src_off_, + int tgt_fd_, + int64_t *tgt_off_, + const uint64_t len_, + const unsigned int flags_) { - static - int64_t - copy_file_range_(int src_fd_, - int64_t *src_off_, - int tgt_fd_, - int64_t *tgt_off_, - const uint64_t len_, - const unsigned int flags_) - { #ifdef SYS_copy_file_range - int64_t rv; - loff_t src_off; - loff_t tgt_off; - loff_t *src_off_ptr; - loff_t *tgt_off_ptr; + int64_t rv; + loff_t src_off; + loff_t tgt_off; + loff_t *src_off_ptr; + loff_t *tgt_off_ptr; - src_off = ((src_off_ == NULL) ? 0 : *src_off_); - tgt_off = ((tgt_off_ == NULL) ? 0 : *tgt_off_); - src_off_ptr = ((src_off_ == NULL) ? NULL : &src_off); - tgt_off_ptr = ((tgt_off_ == NULL) ? NULL : &tgt_off); - rv = ::syscall(SYS_copy_file_range, - src_fd_, - src_off_ptr, - tgt_fd_, - tgt_off_ptr, - len_, - flags_); + src_off = ((src_off_ == NULL) ? 0 : *src_off_); + tgt_off = ((tgt_off_ == NULL) ? 0 : *tgt_off_); + src_off_ptr = ((src_off_ == NULL) ? NULL : &src_off); + tgt_off_ptr = ((tgt_off_ == NULL) ? NULL : &tgt_off); + rv = ::syscall(SYS_copy_file_range, + src_fd_, + src_off_ptr, + tgt_fd_, + tgt_off_ptr, + len_, + flags_); - if(rv != -1) - { - if(src_off_ != NULL) - *src_off_ = src_off; - if(tgt_off_ != NULL) - *tgt_off_ = tgt_off; - } + if(rv != -1) + { + if(src_off_ != NULL) + *src_off_ = src_off; + if(tgt_off_ != NULL) + *tgt_off_ = tgt_off; + } - return rv; + return ::to_neg_errno(rv); #else - return (errno=EOPNOTSUPP,-1); + return -EOPNOTSUPP; #endif - } } -namespace fs +int64_t +fs::copy_file_range(const int src_fd_, + int64_t *src_off_, + const int tgt_fd_, + int64_t *tgt_off_, + const uint64_t len_, + const unsigned int flags_) { - int64_t - copy_file_range(const int src_fd_, - int64_t *src_off_, - const int tgt_fd_, - int64_t *tgt_off_, - const uint64_t len_, - const unsigned int flags_) - { - return l::copy_file_range_(src_fd_, - src_off_, - tgt_fd_, - tgt_off_, - len_, - flags_); - } + return ::_copy_file_range_(src_fd_, + src_off_, + tgt_fd_, + tgt_off_, + len_, + flags_); } diff --git a/src/fs_copy_file_range_unsupported.icpp b/src/fs_copy_file_range_unsupported.icpp index 2e87ecb7..a72fe655 100644 --- a/src/fs_copy_file_range_unsupported.icpp +++ b/src/fs_copy_file_range_unsupported.icpp @@ -16,7 +16,9 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "errno.h" +#include "fs_copy_file_range.hpp" + +#include "errno.hpp" #include @@ -24,25 +26,22 @@ #include -namespace fs +ssize_t +fs::copy_file_range(const int fd_in_, + int64_t *off_in_, + const int fd_out_, + int64_t *off_out_, + const size_t len_, + const unsigned int flags_) +{ + return -EOPNOTSUPP; +} + +ssize_t +fs::copy_file_range(const int fd_in_, + const int fd_out_, + const size_t len_, + const unsigned int flags_) { - ssize_t - copy_file_range(const int fd_in_, - int64_t *off_in_, - const int fd_out_, - int64_t *off_out_, - const size_t len_, - const unsigned int flags_) - { - return (errno=EOPNOTSUPP,-1); - } - - ssize_t - copy_file_range(const int fd_in_, - const int fd_out_, - const size_t len_, - const unsigned int flags_) - { - return (errno=EOPNOTSUPP,-1); - } + return -EOPNOTSUPP; } diff --git a/src/fs_copydata.cpp b/src/fs_copydata.cpp index b49c9fe3..7db437f5 100644 --- a/src/fs_copydata.cpp +++ b/src/fs_copydata.cpp @@ -16,40 +16,33 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "errno.hpp" +#include "fs_copydata.hpp" + #include "fs_copydata_copy_file_range.hpp" #include "fs_copydata_readwrite.hpp" #include "fs_fadvise.hpp" -#include "fs_fallocate.hpp" #include "fs_ficlone.hpp" #include -namespace fs +int +fs::copydata(const int src_fd_, + const int dst_fd_, + const size_t count_) { - int - copydata(const int src_fd_, - const int dst_fd_, - const size_t count_) - { - int rv; - - rv = fs::fallocate(dst_fd_,0,0,count_); - if((rv == -1) && (errno == ENOSPC)) - return rv; - - rv = fs::ficlone(src_fd_,dst_fd_); - if(rv != -1) - return rv; - - fs::fadvise_willneed(src_fd_,0,count_); - fs::fadvise_sequential(src_fd_,0,count_); - - rv = fs::copydata_copy_file_range(src_fd_,dst_fd_,count_); - if(rv != -1) - return rv; - - return fs::copydata_readwrite(src_fd_,dst_fd_,count_); - } + int rv; + + rv = fs::ficlone(src_fd_,dst_fd_); + if(rv >= 0) + return rv; + + fs::fadvise_willneed(src_fd_,0,count_); + fs::fadvise_sequential(src_fd_,0,count_); + + rv = fs::copydata_copy_file_range(src_fd_,dst_fd_,count_); + if(rv >= 0) + return rv; + + return fs::copydata_readwrite(src_fd_,dst_fd_,count_); } diff --git a/src/fs_copydata_copy_file_range.cpp b/src/fs_copydata_copy_file_range.cpp index d066ddc6..04b163a6 100644 --- a/src/fs_copydata_copy_file_range.cpp +++ b/src/fs_copydata_copy_file_range.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fs_copydata_copy_file_range.hpp" + #include "errno.hpp" #include "fs_copy_file_range.hpp" #include "fs_fstat.hpp" @@ -38,29 +40,28 @@ _copydata_copy_file_range(const int src_fd_, do { rv = fs::copy_file_range(src_fd_,&src_off,dst_fd_,&dst_off,nleft,0); - if((rv == -1) && (errno == EINTR)) + if(rv == -EINTR) continue; - if((rv == -1) && (errno == EAGAIN)) + if(rv == -EAGAIN) continue; - if(rv == -1) - return -1; + if(rv == 0) + break; + if(rv < 0) + return rv; nleft -= rv; } while(nleft > 0); - return size_; + return (size_ - nleft); } -namespace fs +s64 +fs::copydata_copy_file_range(const int src_fd_, + const int dst_fd_, + const u64 count_) { - s64 - copydata_copy_file_range(const int src_fd_, - const int dst_fd_, - const u64 count_) - { - return ::_copydata_copy_file_range(src_fd_, - dst_fd_, - count_); - } + return ::_copydata_copy_file_range(src_fd_, + dst_fd_, + count_); } diff --git a/src/fs_copydata_readwrite.cpp b/src/fs_copydata_readwrite.cpp index e59e450f..19f346b8 100644 --- a/src/fs_copydata_readwrite.cpp +++ b/src/fs_copydata_readwrite.cpp @@ -38,19 +38,21 @@ _writen(const int fd_, do { rv = fs::write(fd_,buf_,nleft); - if((rv == -1) && (errno == EINTR)) + if(rv == -EINTR) continue; - if((rv == -1) && (errno == EAGAIN)) + if(rv == -EAGAIN) continue; - if(rv == -1) - return -1; + if(rv == 0) + break; + if(rv < 0) + return rv; nleft -= rv; buf_ += rv; } while(nleft > 0); - return size_; + return (size_ - nleft); } static @@ -74,16 +76,16 @@ _copydata_readwrite(const int src_fd_, nr = fs::read(src_fd_,&buf[0],bufsize); if(nr == 0) return totalwritten; - if((nr == -1) && (errno == EINTR)) + if(nr == -EINTR) continue; - if((nr == -1) && (errno == EAGAIN)) + if(nr == -EAGAIN) continue; - if(nr == -1) - return -1; + if(nr < 0) + return nr; nw = ::_writen(dst_fd_,&buf[0],nr); - if(nw == -1) - return -1; + if(nw < 0) + return nw; totalwritten += nw; } @@ -92,15 +94,12 @@ _copydata_readwrite(const int src_fd_, } -namespace fs +s64 +fs::copydata_readwrite(const int src_fd_, + const int dst_fd_, + const u64 count_) { - s64 - copydata_readwrite(const int src_fd_, - const int dst_fd_, - const u64 count_) - { - return ::_copydata_readwrite(src_fd_, - dst_fd_, - count_); - } + return ::_copydata_readwrite(src_fd_, + dst_fd_, + count_); } diff --git a/src/fs_copyfile.cpp b/src/fs_copyfile.cpp index 4747232f..83046827 100644 --- a/src/fs_copyfile.cpp +++ b/src/fs_copyfile.cpp @@ -1,3 +1,21 @@ +/* + ISC License + + Copyright (c) 2025, 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 "fs_copyfile.hpp" #include "fs_attr.hpp" @@ -46,28 +64,28 @@ fs::copyfile(const int src_fd_, int rv; rv = fs::copydata(src_fd_,dst_fd_,src_st_.st_size); - if(rv == -1) - return -1; + if(rv < 0) + return rv; rv = fs::xattr::copy(src_fd_,dst_fd_); - if((rv == -1) && !::_ignorable_error(errno)) - return -1; + if((rv < 0) && !::_ignorable_error(-rv)) + return rv; rv = fs::attr::copy(src_fd_,dst_fd_,FS_ATTR_CLEAR_IMMUTABLE); if((rv < 0) && !::_ignorable_error(-rv)) - return -1; + return rv; rv = fs::fchown_check_on_error(dst_fd_,src_st_); - if(rv == -1) - return -1; + if(rv < 0) + return rv; rv = fs::fchmod_check_on_error(dst_fd_,src_st_); - if(rv == -1) - return -1; + if(rv < 0) + return rv; rv = fs::futimens(dst_fd_,src_st_); - if(rv == -1) - return -1; + if(rv < 0) + return rv; return 0; } diff --git a/src/fs_cow.cpp b/src/fs_cow.cpp index fef70a55..26f20e6a 100644 --- a/src/fs_cow.cpp +++ b/src/fs_cow.cpp @@ -63,7 +63,7 @@ fs::cow::is_eligible(const char *fullpath_, return false; rv = fs::lstat(fullpath_,&st); - if(rv == -1) + if(rv < 0) return false; return fs::cow::is_eligible(st); diff --git a/src/fs_devid.hpp b/src/fs_devid.hpp index b2b2efc3..26d4f059 100644 --- a/src/fs_devid.hpp +++ b/src/fs_devid.hpp @@ -34,7 +34,7 @@ namespace fs rv = fs::fstat(fd_,&st); if(rv < 0) - return -1; + return rv; return st.st_dev; } diff --git a/src/fs_dirfd.hpp b/src/fs_dirfd.hpp index 06aca2ed..c1105591 100644 --- a/src/fs_dirfd.hpp +++ b/src/fs_dirfd.hpp @@ -18,6 +18,8 @@ #pragma once +#include "to_neg_errno.hpp" + #include #include @@ -29,6 +31,10 @@ namespace fs int dirfd(DIR *dh_) { - return ::dirfd(dh_); + int rv; + + rv = ::dirfd(dh_); + + return ::to_neg_errno(rv); } } diff --git a/src/fs_dup.hpp b/src/fs_dup.hpp index fdb82c66..f4089c15 100644 --- a/src/fs_dup.hpp +++ b/src/fs_dup.hpp @@ -18,6 +18,8 @@ #pragma once +#include "to_neg_errno.hpp" + #include @@ -28,6 +30,10 @@ namespace fs int dup(const int fd_) { - return ::dup(fd_); + int rv; + + rv = ::dup(fd_); + + return ::to_neg_errno(rv); } } diff --git a/src/fs_dup2.hpp b/src/fs_dup2.hpp index d073ec3a..d97ddfab 100644 --- a/src/fs_dup2.hpp +++ b/src/fs_dup2.hpp @@ -18,6 +18,8 @@ #pragma once +#include "to_neg_errno.hpp" + #include @@ -33,6 +35,6 @@ namespace fs rv = ::dup2(oldfd_,newfd_); - return ((rv == -1) ? -errno : rv); + return ::to_neg_errno(rv); } } diff --git a/src/fs_faccessat.hpp b/src/fs_faccessat.hpp index 80329f47..d767b2a5 100644 --- a/src/fs_faccessat.hpp +++ b/src/fs_faccessat.hpp @@ -18,6 +18,8 @@ #pragma once +#include "to_neg_errno.hpp" + #include #include @@ -34,7 +36,11 @@ namespace fs const int mode_, const int flags_) { - return ::faccessat(dirfd_,path_,mode_,flags_); + int rv; + + rv = ::faccessat(dirfd_,path_,mode_,flags_); + + return ::to_neg_errno(rv); } static diff --git a/src/fs_fadvise_posix.icpp b/src/fs_fadvise_posix.icpp index 15bc8601..ccc82eba 100644 --- a/src/fs_fadvise_posix.icpp +++ b/src/fs_fadvise_posix.icpp @@ -26,6 +26,13 @@ namespace fs const off_t len_, const int advice_) { - return ::posix_fadvise(fd_,offset_,len_,advice_); + int rv; + + rv = ::posix_fadvise(fd_,offset_,len_,advice_); + + // On success, zero is returned. + // On error, an error number is returned. + // Return negative error number like other calls. + return -rv; } } diff --git a/src/fs_fadvise_unsupported.icpp b/src/fs_fadvise_unsupported.icpp index 40617b01..2f6d0a7b 100644 --- a/src/fs_fadvise_unsupported.icpp +++ b/src/fs_fadvise_unsupported.icpp @@ -14,7 +14,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "errno.hpp" +#include namespace fs @@ -26,6 +26,6 @@ namespace fs const off_t len_, const int advice_) { - return (errno=EOPNOTSUPP,-1); + return -EOPNOTSUPP; } } diff --git a/src/fs_fallocate_linux.icpp b/src/fs_fallocate_linux.icpp index f3eb2821..f7bb3127 100644 --- a/src/fs_fallocate_linux.icpp +++ b/src/fs_fallocate_linux.icpp @@ -14,7 +14,9 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include +#include "to_neg_errno.hpp" + +#include namespace fs @@ -25,6 +27,10 @@ namespace fs const off_t offset_, const off_t len_) { - return ::fallocate(fd_,mode_,offset_,len_); + int rv; + + rv = ::fallocate(fd_,mode_,offset_,len_); + + return ::to_neg_errno(rv); } } diff --git a/src/fs_fallocate_osx.icpp b/src/fs_fallocate_osx.icpp index 746d7fb4..eafacaf7 100644 --- a/src/fs_fallocate_osx.icpp +++ b/src/fs_fallocate_osx.icpp @@ -14,48 +14,44 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "errno.hpp" +#include "fs_fcntl.hpp" +#include "fs_ftruncate.hpp" -#include #include -namespace l +static +int +_fallocate_core(const int fd_, + const off_t offset_, + const off_t len_) { - static - int - fallocate_core(const int fd_, - const off_t offset_, - const off_t len_) - { - int rv; - fstore_t store = {F_ALLOCATECONTIG,F_PEOFPOSMODE,offset,len,0}; - - rv = ::fcntl(fd_,F_PREALLOCATE,&store); - if(rv == -1) - { - store.fst_flags = F_ALLOCATEALL; - rv = ::fcntl(fd_,F_PREALLOCATE,&store); - } - - if(rv == -1) - return rv; - - return ::ftruncate(fd_,(offset_+len_)); - } + int rv; + fstore_t store = {F_ALLOCATECONTIG,F_PEOFPOSMODE,offset,len,0}; + + rv = fs::fcntl(fd_,F_PREALLOCATE,&store); + if(rv < 0) + { + store.fst_flags = F_ALLOCATEALL; + rv = fs::fcntl(fd_,F_PREALLOCATE,&store); + } + + if(rv < 0) + return rv; + + rv = fs::ftruncate(fd_,(offset_+len_)); + + return rv; } -namespace fs +int +fs::fallocate(const int fd_, + const int mode_, + const off_t offset_, + const off_t len_) { - int - fallocate(const int fd_, - const int mode_, - const off_t offset_, - const off_t len_) - { - if(mode_) - return (errno=EOPNOTSUPP,-1); - - return l::fallocate_core(fd_,offset_,len_); - } + if(mode_) + return -EOPNOTSUPP; + + return ::_fallocate_core(fd_,offset_,len_); } diff --git a/src/fs_fallocate_posix.icpp b/src/fs_fallocate_posix.icpp index bbd2678c..055b5ddc 100644 --- a/src/fs_fallocate_posix.icpp +++ b/src/fs_fallocate_posix.icpp @@ -27,9 +27,16 @@ namespace fs const off_t offset_, const off_t len_) { + int rv; + if(mode_) - return (errno=EOPNOTSUPP,-1); + return -EOPNOTSUPP; + + rv = ::posix_fallocate(fd_,offset_,len_); - return ::posix_fallocate(fd_,offset_,len_); + // Returns zero on success. + // Error number on failure. + // Return -errno. + return -rv; } } diff --git a/src/fs_fallocate_unsupported.icpp b/src/fs_fallocate_unsupported.icpp index c4211986..b0c61d17 100644 --- a/src/fs_fallocate_unsupported.icpp +++ b/src/fs_fallocate_unsupported.icpp @@ -16,6 +16,8 @@ #include "errno.hpp" +#include + namespace fs { @@ -25,6 +27,6 @@ namespace fs const off_t offset_, const off_t len_) { - return (errno=EOPNOTSUPP,-1); + return -EOPNOTSUPP; } } diff --git a/src/fs_fchmod.hpp b/src/fs_fchmod.hpp index 91ef0b89..eef69c90 100644 --- a/src/fs_fchmod.hpp +++ b/src/fs_fchmod.hpp @@ -19,6 +19,7 @@ #pragma once #include "fs_fstat.hpp" +#include "to_neg_errno.hpp" #include @@ -33,7 +34,11 @@ namespace fs fchmod(const int fd_, const mode_t mode_) { - return ::fchmod(fd_,mode_); + int rv; + + rv = ::fchmod(fd_,mode_); + + return ::to_neg_errno(rv); } static @@ -42,7 +47,7 @@ namespace fs fchmod(const int fd_, const struct stat &st_) { - return ::fchmod(fd_,st_.st_mode); + return fs::fchmod(fd_,st_.st_mode); } static @@ -54,20 +59,20 @@ namespace fs int rv; rv = fs::fchmod(fd_,st_); - if(rv == -1) + if(rv < 0) { - int error; + int err; struct stat tmpst; - error = errno; + err = rv; rv = fs::fstat(fd_,&tmpst); if(rv < 0) - return -1; + return rv; if((st_.st_mode & MODE_BITS) != (tmpst.st_mode & MODE_BITS)) - return (errno=error,-1); + return err; } - return 0; + return rv; } } diff --git a/src/fs_fchmodat.hpp b/src/fs_fchmodat.hpp index e6e5ec9d..4c092265 100644 --- a/src/fs_fchmodat.hpp +++ b/src/fs_fchmodat.hpp @@ -18,7 +18,9 @@ #pragma once -#include +#include "fs_fchmodat.hpp" + +#include "to_neg_errno.hpp" #include #include @@ -34,7 +36,11 @@ namespace fs const mode_t mode_, const int flags_) { - return ::fchmodat(dirfd_,pathname_,mode_,flags_); + int rv; + + rv = ::fchmodat(dirfd_,pathname_,mode_,flags_); + + return ::to_neg_errno(rv); } static diff --git a/src/fs_fchown.hpp b/src/fs_fchown.hpp index 0f45d0f8..8a6b3ed2 100644 --- a/src/fs_fchown.hpp +++ b/src/fs_fchown.hpp @@ -18,7 +18,7 @@ #pragma once -#include "errno.hpp" +#include "to_neg_errno.hpp" #include "fs_fstat.hpp" #include @@ -35,7 +35,11 @@ namespace fs const uid_t uid_, const gid_t gid_) { - return ::fchown(fd_,uid_,gid_); + int rv; + + rv = ::fchown(fd_,uid_,gid_); + + return ::to_neg_errno(rv); } static @@ -56,19 +60,19 @@ namespace fs int rv; rv = fs::fchown(fd_,st_); - if(rv == -1) + if(rv < 0) { - int error; + int err; struct stat tmpst; - error = errno; + err = rv; rv = fs::fstat(fd_,&tmpst); if(rv < 0) - return -1; + return err; if((st_.st_uid != tmpst.st_uid) || (st_.st_gid != tmpst.st_gid)) - return (errno=error,-1); + return err; } return 0; diff --git a/src/fs_fcntl.hpp b/src/fs_fcntl.hpp index 59d6b231..7be20d69 100644 --- a/src/fs_fcntl.hpp +++ b/src/fs_fcntl.hpp @@ -1,5 +1,25 @@ +/* + ISC License + + Copyright (c) 2025, 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. +*/ + #pragma once +#include "to_neg_errno.hpp" + #include namespace fs @@ -14,7 +34,7 @@ namespace fs rv = ::fcntl(fd_,op_); - return ((rv == -1) ? -errno : rv); + return ::to_neg_errno(rv); } static @@ -28,7 +48,7 @@ namespace fs rv = ::fcntl(fd_,op_,arg_); - return ((rv == -1) ? -errno : rv); + return ::to_neg_errno(rv); } static @@ -53,6 +73,5 @@ namespace fs #else return -ENOTSUP; #endif - } } diff --git a/src/fs_fdatasync.hpp b/src/fs_fdatasync.hpp index ac6183c1..1178a34b 100644 --- a/src/fs_fdatasync.hpp +++ b/src/fs_fdatasync.hpp @@ -22,7 +22,7 @@ #define _GNU_SOURCE #endif -#include "errno.hpp" +#include "to_neg_errno.hpp" #include @@ -35,9 +35,13 @@ namespace fs fdatasync(const int fd_) { #if _POSIX_SYNCHRONIZED_IO > 0 - return ::fdatasync(fd_); + int rv; + + rv = ::fdatasync(fd_); + + return ::to_neg_errno(rv); #else - return (errno=ENOSYS,-1); + return -ENOSYS; #endif } } diff --git a/src/fs_fgetxattr.hpp b/src/fs_fgetxattr.hpp index 7530d5d6..48411b90 100644 --- a/src/fs_fgetxattr.hpp +++ b/src/fs_fgetxattr.hpp @@ -18,7 +18,7 @@ #pragma once -#include "errno.hpp" +#include "to_neg_errno.hpp" #include "xattr.hpp" #include @@ -37,12 +37,16 @@ namespace fs const size_t size_) { #ifdef USE_XATTR - return ::fgetxattr(fd_, - attrname_, - value_, - size_); + int rv; + + rv = ::fgetxattr(fd_, + attrname_, + value_, + size_); + + return ::to_neg_errno(rv); #else - return (errno=ENOTSUP,-1); + return -ENOTSUP; #endif } diff --git a/src/fs_ficlone_unsupported.icpp b/src/fs_ficlone_unsupported.icpp index e7b864f5..1c16dbe2 100644 --- a/src/fs_ficlone_unsupported.icpp +++ b/src/fs_ficlone_unsupported.icpp @@ -25,6 +25,6 @@ namespace fs ficlone(const int src_fd_, const int dst_fd_) { - return (errno=EOPNOTSUPP,-1); + return -EOPNOTSUPP; } } diff --git a/src/fs_file_size.cpp b/src/fs_file_size.cpp index ca94e14d..9557fcec 100644 --- a/src/fs_file_size.cpp +++ b/src/fs_file_size.cpp @@ -31,7 +31,7 @@ namespace fs rv = fs::fstat(fd_,&st); if(rv < 0) - return -1; + return rv; return st.st_size; } diff --git a/src/fs_file_unchanged.hpp b/src/fs_file_unchanged.hpp index 17d7b57c..a9d83008 100644 --- a/src/fs_file_unchanged.hpp +++ b/src/fs_file_unchanged.hpp @@ -1,3 +1,21 @@ +/* + ISC License + + Copyright (c) 2025, 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. +*/ + #pragma once #include "fs_fstat.hpp" diff --git a/src/fs_findallfiles.cpp b/src/fs_findallfiles.cpp index fc15f445..9cc9e50c 100644 --- a/src/fs_findallfiles.cpp +++ b/src/fs_findallfiles.cpp @@ -16,6 +16,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fs_findallfiles.hpp" + #include "fs_exists.hpp" #include "fs_path.hpp" @@ -23,23 +25,20 @@ #include -namespace fs +void +fs::findallfiles(const std::vector &basepaths_, + const char *fusepath_, + std::vector *paths_) { - void - findallfiles(const std::vector &basepaths_, - const char *fusepath_, - std::vector *paths_) - { - std::string fullpath; - - for(size_t i = 0, ei = basepaths_.size(); i != ei; i++) - { - fullpath = fs::path::make(basepaths_[i],fusepath_); - - if(!fs::exists(fullpath)) - continue; - - paths_->push_back(fullpath); - } - } + std::string fullpath; + + for(const auto &basepath : basepaths_) + { + fullpath = fs::path::make(basepath,fusepath_); + + if(!fs::exists(fullpath)) + continue; + + paths_->push_back(fullpath); + } } diff --git a/src/fs_findonfs.cpp b/src/fs_findonfs.cpp index b662348f..e4d10880 100644 --- a/src/fs_findonfs.cpp +++ b/src/fs_findonfs.cpp @@ -16,6 +16,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fs_findonfs.hpp" + #include "branches.hpp" #include "errno.hpp" #include "fs_fstat.hpp" @@ -25,53 +27,48 @@ #include -namespace l +static +int +_findonfs(const Branches::Ptr &branches_, + const std::string &fusepath_, + const int fd_, + std::string *basepath_) { - static - int - findonfs(const Branches::Ptr &branches_, - const std::string &fusepath_, - const int fd_, - std::string *basepath_) - { - int rv; - dev_t dev; - struct stat st; - std::string fullpath; - - rv = fs::fstat(fd_,&st); - if(rv < 0) - return -1; - - dev = st.st_dev; - for(const auto &branch : *branches_) - { - fullpath = fs::path::make(branch.path,fusepath_); - - rv = fs::lstat(fullpath,&st); - if(rv == -1) - continue; - - if(st.st_dev != dev) - continue; - - *basepath_ = branch.path; - - return 0; - } - - return (errno=ENOENT,-1); - } + int rv; + dev_t dev; + struct stat st; + std::string fullpath; + + rv = fs::fstat(fd_,&st); + if(rv < 0) + return rv; + + dev = st.st_dev; + for(const auto &branch : *branches_) + { + fullpath = fs::path::make(branch.path,fusepath_); + + rv = fs::lstat(fullpath,&st); + if(rv < 0) + continue; + + if(st.st_dev != dev) + continue; + + *basepath_ = branch.path; + + return 0; + } + + return -ENOENT; } -namespace fs + +int +fs::findonfs(const Branches::Ptr &branches_, + const std::string &fusepath_, + const int fd_, + std::string *basepath_) { - int - findonfs(const Branches::Ptr &branches_, - const std::string &fusepath_, - const int fd_, - std::string *basepath_) - { - return l::findonfs(branches_,fusepath_,fd_,basepath_); - } + return ::_findonfs(branches_,fusepath_,fd_,basepath_); } diff --git a/src/fs_flistxattr.hpp b/src/fs_flistxattr.hpp index 1a9f6ae8..ff28cef0 100644 --- a/src/fs_flistxattr.hpp +++ b/src/fs_flistxattr.hpp @@ -18,7 +18,7 @@ #pragma once -#include "errno.hpp" +#include "to_neg_errno.hpp" #include "xattr.hpp" #include @@ -34,9 +34,13 @@ namespace fs const size_t size_) { #ifdef USE_XATTR - return ::flistxattr(fd_,list_,size_); + int rv; + + rv = ::flistxattr(fd_,list_,size_); + + return ::to_neg_errno(rv); #else - return (errno=ENOTSUP,-1); + return -ENOTSUP; #endif } } diff --git a/src/fs_flock.hpp b/src/fs_flock.hpp index a6fd59f8..d02f216b 100644 --- a/src/fs_flock.hpp +++ b/src/fs_flock.hpp @@ -18,6 +18,8 @@ #pragma once +#include "to_neg_errno.hpp" + #include @@ -29,6 +31,10 @@ namespace fs flock(const int fd_, const int operation_) { - return ::flock(fd_,operation_); + int rv; + + rv = ::flock(fd_,operation_); + + return ::to_neg_errno(rv); } } diff --git a/src/fs_fsetxattr.hpp b/src/fs_fsetxattr.hpp index c2f2e129..08cae58a 100644 --- a/src/fs_fsetxattr.hpp +++ b/src/fs_fsetxattr.hpp @@ -18,7 +18,7 @@ #pragma once -#include "errno.hpp" +#include "to_neg_errno.hpp" #include "xattr.hpp" #include @@ -38,9 +38,13 @@ namespace fs const int flags_) { #ifdef USE_XATTR - return ::fsetxattr(fd_,name_,value_,size_,flags_); + int rv; + + rv = ::fsetxattr(fd_,name_,value_,size_,flags_); + + return ::to_neg_errno(rv); #else - return (errno=ENOTSUP,-1); + return -ENOTSUP; #endif } diff --git a/src/fs_fstat.hpp b/src/fs_fstat.hpp index 4733c56b..87ebe1ee 100644 --- a/src/fs_fstat.hpp +++ b/src/fs_fstat.hpp @@ -19,7 +19,8 @@ #pragma once -#include +#include "to_neg_errno.hpp" + #include #include #include @@ -37,6 +38,6 @@ namespace fs rv = ::fstat(fd_,st_); - return ((rv == -1) ? -errno : rv); + return ::to_neg_errno(rv); } } diff --git a/src/fs_fstatat.hpp b/src/fs_fstatat.hpp index e7d0ee9c..b6ab8ca6 100644 --- a/src/fs_fstatat.hpp +++ b/src/fs_fstatat.hpp @@ -18,10 +18,9 @@ #pragma once -#include +#include "to_neg_errno.hpp" + #include -#include -#include namespace fs @@ -41,7 +40,7 @@ namespace fs statbuf_, flags_); - return ((rv == -1) ? -errno : rv); + return ::to_neg_errno(rv); } static diff --git a/src/fs_fstatvfs.hpp b/src/fs_fstatvfs.hpp new file mode 100644 index 00000000..1c0eebb2 --- /dev/null +++ b/src/fs_fstatvfs.hpp @@ -0,0 +1,40 @@ +/* + ISC License + + Copyright (c) 2019, 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. +*/ + +#pragma once + +#include "to_neg_errno.hpp" + +#include + + +namespace fs +{ + static + inline + int + fstatvfs(const int fd_, + struct statvfs *st_) + { + int rv; + + rv = ::fstatvfs(fd_,st_); + + return ::to_neg_errno(rv); + } +} diff --git a/src/fs_fsync.hpp b/src/fs_fsync.hpp index 91374487..93902daf 100644 --- a/src/fs_fsync.hpp +++ b/src/fs_fsync.hpp @@ -18,6 +18,8 @@ #pragma once +#include "to_neg_errno.hpp" + #include @@ -28,6 +30,10 @@ namespace fs int fsync(const int fd_) { - return ::fsync(fd_); + int rv; + + rv = ::fsync(fd_); + + return ::to_neg_errno(rv); } } diff --git a/src/fs_ftruncate.hpp b/src/fs_ftruncate.hpp index ec2c17a3..245ff6f4 100644 --- a/src/fs_ftruncate.hpp +++ b/src/fs_ftruncate.hpp @@ -18,7 +18,8 @@ #pragma once -#include +#include "to_neg_errno.hpp" + #include @@ -30,6 +31,10 @@ namespace fs ftruncate(const int fd_, const off_t size_) { - return ::ftruncate(fd_,size_); + int rv; + + rv = ::ftruncate(fd_,size_); + + return ::to_neg_errno(rv); } } diff --git a/src/fs_futimens_freebsd_11.hpp b/src/fs_futimens_freebsd_11.hpp index d3e25247..edbc6dc8 100644 --- a/src/fs_futimens_freebsd_11.hpp +++ b/src/fs_futimens_freebsd_11.hpp @@ -18,6 +18,8 @@ #pragma once +#include "to_neg_errno.hpp" + #include @@ -29,6 +31,10 @@ namespace fs futimens(const int fd_, const struct timespec ts_[2]) { - return ::futimens(fd_,ts_); + int rv; + + rv = ::futimens(fd_,ts_); + + return ::to_neg_errno(rv); } } diff --git a/src/fs_futimens_generic.hpp b/src/fs_futimens_generic.hpp index f8deba71..61620246 100644 --- a/src/fs_futimens_generic.hpp +++ b/src/fs_futimens_generic.hpp @@ -34,228 +34,225 @@ #endif -namespace l +static +inline +bool +_can_call_lutimes(const int dirfd_, + const std::string &path_, + const int flags_) { - static - inline - bool - can_call_lutimes(const int dirfd_, - const std::string &path_, - const int flags_) - { - return ((flags_ == AT_SYMLINK_NOFOLLOW) && - ((dirfd_ == AT_FDCWD) || - (path_[0] == '/'))); - } + return ((flags_ == AT_SYMLINK_NOFOLLOW) && + ((dirfd_ == AT_FDCWD) || + (path_[0] == '/'))); +} - static - inline - bool - should_ignore(const struct timespec ts_[2]) - { - return ((ts_ != NULL) && - (ts_[0].tv_nsec == UTIME_OMIT) && - (ts_[1].tv_nsec == UTIME_OMIT)); - } +static +inline +bool +_should_ignore(const struct timespec ts_[2]) +{ + return ((ts_ != NULL) && + (ts_[0].tv_nsec == UTIME_OMIT) && + (ts_[1].tv_nsec == UTIME_OMIT)); +} - static - inline - bool - should_be_set_to_now(const struct timespec ts_[2]) - { - return ((ts_ == NULL) || - ((ts_[0].tv_nsec == UTIME_NOW) && - (ts_[1].tv_nsec == UTIME_NOW))); - } +static +inline +bool +_should_be_set_to_now(const struct timespec ts_[2]) +{ + return ((ts_ == NULL) || + ((ts_[0].tv_nsec == UTIME_NOW) && + (ts_[1].tv_nsec == UTIME_NOW))); +} - static - inline - bool - timespec_invalid(const struct timespec &ts_) - { - return (((ts_.tv_nsec < 0) || - (ts_.tv_nsec > 999999999)) && - ((ts_.tv_nsec != UTIME_NOW) && - (ts_.tv_nsec != UTIME_OMIT))); - } +static +inline +bool +_timespec_invalid(const struct timespec &ts_) +{ + return (((ts_.tv_nsec < 0) || + (ts_.tv_nsec > 999999999)) && + ((ts_.tv_nsec != UTIME_NOW) && + (ts_.tv_nsec != UTIME_OMIT))); +} - static - inline - bool - timespec_invalid(const struct timespec ts_[2]) - { - return ((ts_ != NULL) && - (l::timespec_invalid(ts_[0]) || - l::timespec_invalid(ts_[1]))); - } +static +inline +bool +_timespec_invalid(const struct timespec ts_[2]) +{ + return ((ts_ != NULL) && + (::_timespec_invalid(ts_[0]) || + ::_timespec_invalid(ts_[1]))); +} - static - inline - bool - flags_invalid(const int flags_) - { - return ((flags_ & ~AT_SYMLINK_NOFOLLOW) != 0); - } +static +inline +bool +_flags_invalid(const int flags_) +{ + return ((flags_ & ~AT_SYMLINK_NOFOLLOW) != 0); +} - static - inline - bool - any_timespec_is_utime_omit(const struct timespec ts_[2]) - { - return ((ts_[0].tv_nsec == UTIME_OMIT) || - (ts_[1].tv_nsec == UTIME_OMIT)); - } +static +inline +bool +_any_timespec_is_utime_omit(const struct timespec ts_[2]) +{ + return ((ts_[0].tv_nsec == UTIME_OMIT) || + (ts_[1].tv_nsec == UTIME_OMIT)); +} - static - inline - bool - any_timespec_is_utime_now(const struct timespec ts_[2]) - { - return ((ts_[0].tv_nsec == UTIME_NOW) || - (ts_[1].tv_nsec == UTIME_NOW)); - } +static +inline +bool +_any_timespec_is_utime_now(const struct timespec ts_[2]) +{ + return ((ts_[0].tv_nsec == UTIME_NOW) || + (ts_[1].tv_nsec == UTIME_NOW)); +} - static - inline - int - set_utime_omit_to_current_value(const int dirfd_, - const std::string &path_, - const struct timespec ts_[2], - struct timeval tv_[2], - const int flags_) - { - int rv; - struct stat st; - timespec *atime; - timespec *mtime; +static +inline +int +_set_utime_omit_to_current_value(const int dirfd_, + const std::string &path_, + const struct timespec ts_[2], + struct timeval tv_[2], + const int flags_) +{ + int rv; + struct stat st; + timespec *atime; + timespec *mtime; - if(!l::any_timespec_is_utime_omit(ts_)) - return 0; + if(!::_any_timespec_is_utime_omit(ts_)) + return 0; - rv = fs::fstatat(dirfd_,path_,&st,flags_); - if(rv < 0) - return rv; + rv = fs::fstatat(dirfd_,path_,&st,flags_); + if(rv < 0) + return rv; - atime = fs::stat_atime(st); - mtime = fs::stat_mtime(st); + atime = fs::stat_atime(st); + mtime = fs::stat_mtime(st); - if(ts_[0].tv_nsec == UTIME_OMIT) - TIMESPEC_TO_TIMEVAL(&tv[0],atime); - if(ts_[1].tv_nsec == UTIME_OMIT) - TIMESPEC_TO_TIMEVAL(&tv[1],mtime); + if(ts_[0].tv_nsec == UTIME_OMIT) + TIMESPEC_TO_TIMEVAL(&tv[0],atime); + if(ts_[1].tv_nsec == UTIME_OMIT) + TIMESPEC_TO_TIMEVAL(&tv[1],mtime); - return 0; - } + return 0; +} - static - inline - int - set_utime_omit_to_current_value(const int fd_, - const struct timespec ts_[2], - struct timeval tv_[2]) - { - int rv; - struct stat st; - timespec *atime; - timespec *mtime; +static +inline +int +_set_utime_omit_to_current_value(const int fd_, + const struct timespec ts_[2], + struct timeval tv_[2]) +{ + int rv; + struct stat st; + timespec *atime; + timespec *mtime; - if(!l::any_timespec_is_utime_omit(ts_)) - return 0; + if(!::_any_timespec_is_utime_omit(ts_)) + return 0; - rv = fs::fstat(fd_,&st); - if(rv == -1) - return -1; + rv = fs::fstat(fd_,&st); + if(rv < 0) + return rv; - atime = fs::stat_atime(st); - mtime = fs::stat_mtime(st); + atime = fs::stat_atime(st); + mtime = fs::stat_mtime(st); - if(ts_[0].tv_nsec == UTIME_OMIT) - TIMESPEC_TO_TIMEVAL(&tv_[0],atime); - if(ts_[1].tv_nsec == UTIME_OMIT) - TIMESPEC_TO_TIMEVAL(&tv_[1],mtime); + if(ts_[0].tv_nsec == UTIME_OMIT) + TIMESPEC_TO_TIMEVAL(&tv_[0],atime); + if(ts_[1].tv_nsec == UTIME_OMIT) + TIMESPEC_TO_TIMEVAL(&tv_[1],mtime); - return 0; - } + return 0; +} - static - inline - int - set_utime_now_to_now(const struct timespec ts_[2], - struct timeval tv_[2]) - { - int rv; - struct timeval now; +static +inline +int +_set_utime_now_to_now(const struct timespec ts_[2], + struct timeval tv_[2]) +{ + int rv; + struct timeval now; - if(l::any_timespec_is_utime_now(ts_)) - return 0; + if(::_any_timespec_is_utime_now(ts_)) + return 0; - rv = time::gettimeofday(&now,NULL); - if(rv == -1) - return -1; + rv = time::gettimeofday(&now,NULL); + if(rv < 0) + return rv; - if(ts_[0].tv_nsec == UTIME_NOW) - tv_[0] = now; - if(ts_[1].tv_nsec == UTIME_NOW) - tv_[1] = now; + if(ts_[0].tv_nsec == UTIME_NOW) + tv_[0] = now; + if(ts_[1].tv_nsec == UTIME_NOW) + tv_[1] = now; - return 0; - } + return 0; +} - static - inline - int - convert_timespec_to_timeval(const int dirfd_, - const std::string &path_, - const struct timespec ts_[2], - struct timeval tv_[2], - struct timeval **tvp_, - const int flags_) - { - int rv; +static +inline +int +_convert_timespec_to_timeval(const int dirfd_, + const std::string &path_, + const struct timespec ts_[2], + struct timeval tv_[2], + struct timeval **tvp_, + const int flags_) +{ + int rv; - if(l::should_be_set_to_now(ts_)) - return (tvp=NULL,0); + if(::_should_be_set_to_now(ts_)) + return (tvp=NULL,0); - TIMESPEC_TO_TIMEVAL(&tv_[0],&ts_[0]); - TIMESPEC_TO_TIMEVAL(&tv_[1],&ts_[1]); + TIMESPEC_TO_TIMEVAL(&tv_[0],&ts_[0]); + TIMESPEC_TO_TIMEVAL(&tv_[1],&ts_[1]); - rv = l::set_utime_omit_to_current_value(dirfd_,path_,ts_,tv_,flags_); - if(rv == -1) - return -1; + rv = ::_set_utime_omit_to_current_value(dirfd_,path_,ts_,tv_,flags_); + if(rv < 0) + return rv; - rv = l::set_utime_now_to_now(ts_,tv_); - if(rv == -1) - return -1; + rv = ::_set_utime_now_to_now(ts_,tv_); + if(rv < 0) + return rv; - return (*tvp_=tv_,0); - } + return (*tvp_=tv_,0); +} - static - inline - int - convert_timespec_to_timeval(const int fd_, - const struct timespec ts_[2], - struct timeval tv_[2], - struct timeval **tvp_) - { - int rv; +static +inline +int +_convert_timespec_to_timeval(const int fd_, + const struct timespec ts_[2], + struct timeval tv_[2], + struct timeval **tvp_) +{ + int rv; - if(l::should_be_set_to_now(ts_)) - return (*tvp=NULL,0); + if(::_should_be_set_to_now(ts_)) + return (*tvp=NULL,0); - TIMESPEC_TO_TIMEVAL(&tv_[0],&ts_[0]); - TIMESPEC_TO_TIMEVAL(&tv_[1],&ts_[1]); + TIMESPEC_TO_TIMEVAL(&tv_[0],&ts_[0]); + TIMESPEC_TO_TIMEVAL(&tv_[1],&ts_[1]); - rv = l::set_utime_omit_to_current_value(fd_,ts_,tv_); - if(rv == -1) - return -1; + rv = ::_set_utime_omit_to_current_value(fd_,ts_,tv_); + if(rv < 0) + return rv; - rv = l::set_utime_now_to_now(ts_,tv_); - if(rv == -1) - return -1; + rv = ::_set_utime_now_to_now(ts_,tv_); + if(rv < 0) + return rv; - return (*tvp=tv,0); - } + return (*tvp=tv,0); } namespace fs @@ -270,15 +267,15 @@ namespace fs struct timeval tv[2]; struct timeval *tvp; - if(l::timespec_invalid(ts_)) - return (errno=EINVAL,-1); - if(l::should_ignore(ts_)) + if(::_timespec_invalid(ts_)) + return -EINVAL; + if(::_should_ignore(ts_)) return 0; - rv = l::convert_timespec_to_timeval(fd_,ts_,tv,&tvp); - if(rv == -1) - return -1; + rv = ::_convert_timespec_to_timeval(fd_,ts_,tv,&tvp); + if(rv < 0) + return rv; - return ::futimes(fd_,tvp); + return fs::futimes(fd_,tvp); } } diff --git a/src/fs_futimens_linux.hpp b/src/fs_futimens_linux.hpp index d3e25247..edbc6dc8 100644 --- a/src/fs_futimens_linux.hpp +++ b/src/fs_futimens_linux.hpp @@ -18,6 +18,8 @@ #pragma once +#include "to_neg_errno.hpp" + #include @@ -29,6 +31,10 @@ namespace fs futimens(const int fd_, const struct timespec ts_[2]) { - return ::futimens(fd_,ts_); + int rv; + + rv = ::futimens(fd_,ts_); + + return ::to_neg_errno(rv); } } diff --git a/src/fs_futimesat_generic.icpp b/src/fs_futimesat_generic.icpp index acf49095..dfae194a 100644 --- a/src/fs_futimesat_generic.icpp +++ b/src/fs_futimesat_generic.icpp @@ -16,6 +16,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "to_neg_errno.hpp" + #include #include @@ -27,6 +29,10 @@ namespace fs const char *pathname_, const struct timeval times_[2]) { - return ::futimesat(dirfd_,pathname_,times_); + int rv; + + rv = ::futimesat(dirfd_,pathname_,times_); + + return ::to_neg_errno(rv); } } diff --git a/src/fs_futimesat_osx.icpp b/src/fs_futimesat_osx.icpp index b96b4623..d62508c1 100644 --- a/src/fs_futimesat_osx.icpp +++ b/src/fs_futimesat_osx.icpp @@ -16,6 +16,10 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fs_fstat.hpp" +#include "fs_fcntl.hpp" +#include "fs_utimes.hpp" + #include #include #include @@ -38,24 +42,24 @@ namespace l int rv; struct stat st; - rv = ::fstat(dirfd_,&st); - if(rv == -1) - return -1; + rv = fs::fstat(dirfd_,&st); + if(rv < 0) + return rv; if(!S_ISDIR(st.st_mode)) - return (errno=ENOTDIR,-1); + return -ENOTDIR; - rv = ::fcntl(dirfd_,F_GETPATH,fullpath); - if(rv == -1) - return -1; + rv = fs::fcntl(dirfd_,F_GETPATH,fullpath); + if(rv < 0) + return rv; rv = ::strlcat(fullpath_,"/",MAXPATHLEN); if(rv > MAXPATHLEN) - return (errno=ENAMETOOLONG,-1); + return -ENAMETOOLONG; rv = ::strlcat(fullpath_,path_,MAXPATHLEN); if(rv > MAXPATHLEN) - return (errno=ENAMETOOLONG,-1); + return -ENAMETOOLONG; return 0; } @@ -74,15 +78,15 @@ namespace fs if((dirfd_ == AT_FDCWD) || ((pathname_ != NULL) && (pathname_[0] == '/'))) - return ::utimes(pathname_,times_); + return fs::utimes(pathname_,times_); if(dirfd_ < 0) - return (errno=EBADF,-1); + return -EBADF; rv = l::getpath(dirfd_,pathname_,fullpath); - if(rv == -1) - return -1; + if(rv < 0) + return rv; - return ::utimes(fullpath,times_); + return fs::utimes(fullpath,times_); } } diff --git a/src/fs_getdents64.cpp b/src/fs_getdents64.cpp index 0015cc07..dda24de3 100644 --- a/src/fs_getdents64.cpp +++ b/src/fs_getdents64.cpp @@ -16,7 +16,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "errno.hpp" +#include "to_neg_errno.hpp" #if defined __linux__ #include @@ -27,14 +27,18 @@ namespace fs { int - getdents_64(unsigned int fd_, - void *dirp_, - unsigned int count_) + getdents64(unsigned int fd_, + void *dirp_, + unsigned int count_) { #if defined SYS_getdents64 - return ::syscall(SYS_getdents64,fd_,dirp_,count_); + int rv; + + rv = ::syscall(SYS_getdents64,fd_,dirp_,count_); + + return ::to_neg_errno(rv); #else - return (errno=ENOTSUP,-1); + return -ENOTSUP; #endif } } diff --git a/src/fs_getdents64.hpp b/src/fs_getdents64.hpp index f328c431..e608bf73 100644 --- a/src/fs_getdents64.hpp +++ b/src/fs_getdents64.hpp @@ -22,7 +22,7 @@ namespace fs { int - getdents_64(unsigned int fd, - void *dirp, - unsigned int count); + getdents64(unsigned int fd, + void *dirp, + unsigned int count); } diff --git a/src/fs_getfl.cpp b/src/fs_getfl.cpp index f84676a6..92d6474a 100644 --- a/src/fs_getfl.cpp +++ b/src/fs_getfl.cpp @@ -16,7 +16,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include +#include "fs_fcntl.hpp" namespace fs @@ -24,6 +24,6 @@ namespace fs int getfl(const int fd_) { - return ::fcntl(fd_,F_GETFL,0); + return fs::fcntl(fd_,F_GETFL,0); } } diff --git a/src/fs_glob.cpp b/src/fs_glob.cpp index 9f0e1546..43d96895 100644 --- a/src/fs_glob.cpp +++ b/src/fs_glob.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fs_glob.hpp" + #include #include @@ -31,21 +33,18 @@ using std::vector; #define GLOB_ONLYDIR 0 #endif -namespace fs +void +fs::glob(const string &pattern_, + vector *strs_) { - void - glob(const string &pattern_, - vector *strs_) - { - int flags; - glob_t gbuf = {0}; + int flags; + glob_t gbuf = {0}; - flags = (GLOB_BRACE|GLOB_ONLYDIR); - ::glob(pattern_.c_str(),flags,NULL,&gbuf); + flags = (GLOB_BRACE|GLOB_ONLYDIR); + ::glob(pattern_.c_str(),flags,NULL,&gbuf); - for(size_t i = 0; i < gbuf.gl_pathc; i++) - strs_->push_back(gbuf.gl_pathv[i]); + for(size_t i = 0; i < gbuf.gl_pathc; i++) + strs_->push_back(gbuf.gl_pathv[i]); - ::globfree(&gbuf); - } + ::globfree(&gbuf); } diff --git a/src/fs_has_space.cpp b/src/fs_has_space.cpp index 3ce5bc18..865ef77d 100644 --- a/src/fs_has_space.cpp +++ b/src/fs_has_space.cpp @@ -16,6 +16,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fs_has_space.hpp" + #include "fs_statvfs.hpp" #include "statvfs_util.hpp" @@ -23,19 +25,16 @@ #include -namespace fs +bool +fs::has_space(const std::string &str_, + const int64_t size_) { - bool - has_space(const std::string &str_, - const int64_t size_) - { - int rv; - struct statvfs st; - - rv = fs::statvfs(str_,&st); - if(rv == -1) - return false; - - return (StatVFS::spaceavail(st) > size_); - } + int rv; + struct statvfs st; + + rv = fs::statvfs(str_,&st); + if(rv < 0) + return false; + + return (StatVFS::spaceavail(st) > size_); } diff --git a/src/fs_info.cpp b/src/fs_info.cpp index 6368036e..d5d5f4ee 100644 --- a/src/fs_info.cpp +++ b/src/fs_info.cpp @@ -16,6 +16,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fs_info.hpp" + #include "fs_info_t.hpp" #include "fs_path.hpp" #include "fs_stat.hpp" @@ -29,23 +31,20 @@ using std::string; -namespace fs +int +fs::info(const string &path_, + fs::info_t *info_) { - int - info(const string &path_, - fs::info_t *info_) - { - int rv; - struct statvfs st; - - rv = fs::statvfs_cache(path_.c_str(),&st); - if(rv == 0) - { - info_->readonly = StatVFS::readonly(st); - info_->spaceavail = StatVFS::spaceavail(st); - info_->spaceused = StatVFS::spaceused(st); - } - - return rv; - } + int rv; + struct statvfs st; + + rv = fs::statvfs_cache(path_.c_str(),&st); + if(rv == 0) + { + info_->readonly = StatVFS::readonly(st); + info_->spaceavail = StatVFS::spaceavail(st); + info_->spaceused = StatVFS::spaceused(st); + } + + return rv; } diff --git a/src/fs_inode.cpp b/src/fs_inode.cpp index 7301fb91..4d0cc3c2 100644 --- a/src/fs_inode.cpp +++ b/src/fs_inode.cpp @@ -31,18 +31,18 @@ typedef uint64_t (*inodefunc_t)(const std::string_view, const mode_t, const ino_t); -static uint64_t hybrid_hash(const std::string_view, - const std::string_view, - const mode_t, - const ino_t); +static uint64_t _hybrid_hash(const std::string_view, + const std::string_view, + const mode_t, + const ino_t); -static inodefunc_t g_func = hybrid_hash; +static inodefunc_t g_func = ::_hybrid_hash; static uint32_t -h64_to_h32(uint64_t h_) +_h64_to_h32(uint64_t h_) { h_ ^= (h_ >> 32); h_ *= 0x9E3779B9; @@ -51,20 +51,20 @@ h64_to_h32(uint64_t h_) static uint64_t -passthrough(const std::string_view branch_path_, - const std::string_view fusepath_, - const mode_t mode_, - const ino_t ino_) +_passthrough(const std::string_view branch_path_, + const std::string_view fusepath_, + const mode_t mode_, + const ino_t ino_) { return ino_; } static uint64_t -path_hash(const std::string_view branch_path_, - const std::string_view fusepath_, - const mode_t mode_, - const ino_t ino_) +_path_hash(const std::string_view branch_path_, + const std::string_view fusepath_, + const mode_t mode_, + const ino_t ino_) { uint64_t seed; @@ -75,27 +75,27 @@ path_hash(const std::string_view branch_path_, static uint64_t -path_hash32(const std::string_view branch_path_, - const std::string_view fusepath_, - const mode_t mode_, - const ino_t ino_) +_path_hash32(const std::string_view branch_path_, + const std::string_view fusepath_, + const mode_t mode_, + const ino_t ino_) { uint64_t h; - h = path_hash(branch_path_, - fusepath_, - mode_, - ino_); + h = ::_path_hash(branch_path_, + fusepath_, + mode_, + ino_); - return h64_to_h32(h); + return ::_h64_to_h32(h); } static uint64_t -devino_hash(const std::string_view branch_path_, - const std::string_view fusepath_, - const mode_t mode_, - const ino_t ino_) +_devino_hash(const std::string_view branch_path_, + const std::string_view fusepath_, + const mode_t mode_, + const ino_t ino_) { uint64_t seed; @@ -107,122 +107,116 @@ devino_hash(const std::string_view branch_path_, static uint64_t -devino_hash32(const std::string_view branch_path_, - const std::string_view fusepath_, - const mode_t mode_, - const ino_t ino_) +_devino_hash32(const std::string_view branch_path_, + const std::string_view fusepath_, + const mode_t mode_, + const ino_t ino_) { uint64_t h; - h = devino_hash(branch_path_, - fusepath_, - mode_, - ino_); + h = ::_devino_hash(branch_path_, + fusepath_, + mode_, + ino_); - return h64_to_h32(h); + return ::_h64_to_h32(h); } static uint64_t -hybrid_hash(const std::string_view branch_path_, - const std::string_view fusepath_, - const mode_t mode_, - const ino_t ino_) +_hybrid_hash(const std::string_view branch_path_, + const std::string_view fusepath_, + const mode_t mode_, + const ino_t ino_) { return (S_ISDIR(mode_) ? - path_hash(branch_path_,fusepath_,mode_,ino_) : - devino_hash(branch_path_,fusepath_,mode_,ino_)); + ::_path_hash(branch_path_,fusepath_,mode_,ino_) : + ::_devino_hash(branch_path_,fusepath_,mode_,ino_)); } static uint64_t -hybrid_hash32(const std::string_view branch_path_, - const std::string_view fusepath_, - const mode_t mode_, - const ino_t ino_) +_hybrid_hash32(const std::string_view branch_path_, + const std::string_view fusepath_, + const mode_t mode_, + const ino_t ino_) { return (S_ISDIR(mode_) ? - path_hash32(branch_path_,fusepath_,mode_,ino_) : - devino_hash32(branch_path_,fusepath_,mode_,ino_)); + ::_path_hash32(branch_path_,fusepath_,mode_,ino_) : + ::_devino_hash32(branch_path_,fusepath_,mode_,ino_)); +} + +int +fs::inode::set_algo(const std::string &algo_) +{ + if(algo_ == "passthrough") + g_func = ::_passthrough; + ef(algo_ == "path-hash") + g_func = ::_path_hash; + ef(algo_ == "path-hash32") + g_func = ::_path_hash32; + ef(algo_ == "devino-hash") + g_func = ::_devino_hash; + ef(algo_ == "devino-hash32") + g_func = ::_devino_hash32; + ef(algo_ == "hybrid-hash") + g_func = ::_hybrid_hash; + ef(algo_ == "hybrid-hash32") + g_func = ::_hybrid_hash32; + else + return -EINVAL; + + return 0; } -namespace fs +std::string +fs::inode::get_algo(void) +{ + if(g_func == ::_passthrough) + return "passthrough"; + if(g_func == ::_path_hash) + return "path-hash"; + if(g_func == ::_path_hash32) + return "path-hash32"; + if(g_func == ::_devino_hash) + return "devino-hash"; + if(g_func == ::_devino_hash32) + return "devino-hash32"; + if(g_func == ::_hybrid_hash) + return "hybrid-hash"; + if(g_func == ::_hybrid_hash32) + return "hybrid-hash32"; + + return {}; +} + +uint64_t +fs::inode::calc(const std::string_view branch_path_, + const std::string_view fusepath_, + const mode_t mode_, + const ino_t ino_) { - namespace inode - { - int - set_algo(const std::string &algo_) - { - if(algo_ == "passthrough") - g_func = passthrough; - ef(algo_ == "path-hash") - g_func = path_hash; - ef(algo_ == "path-hash32") - g_func = path_hash32; - ef(algo_ == "devino-hash") - g_func = devino_hash; - ef(algo_ == "devino-hash32") - g_func = devino_hash32; - ef(algo_ == "hybrid-hash") - g_func = hybrid_hash; - ef(algo_ == "hybrid-hash32") - g_func = hybrid_hash32; - else - return -EINVAL; - - return 0; - } - - std::string - get_algo(void) - { - if(g_func == passthrough) - return "passthrough"; - if(g_func == path_hash) - return "path-hash"; - if(g_func == path_hash32) - return "path-hash32"; - if(g_func == devino_hash) - return "devino-hash"; - if(g_func == devino_hash32) - return "devino-hash32"; - if(g_func == hybrid_hash) - return "hybrid-hash"; - if(g_func == hybrid_hash32) - return "hybrid-hash32"; - - return std::string(); - } - - uint64_t - calc(const std::string_view branch_path_, - const std::string_view fusepath_, - const mode_t mode_, - const ino_t ino_) - { - return g_func(branch_path_,fusepath_,mode_,ino_); - } - - void - calc(const std::string_view branch_path_, - const std::string_view fusepath_, - struct stat *st_) - { - st_->st_ino = calc(branch_path_, - fusepath_, - st_->st_mode, - st_->st_ino); - } - - void - calc(const std::string_view branch_path_, - const std::string_view fusepath_, - struct fuse_statx *st_) - { - st_->ino = calc(branch_path_, - fusepath_, - st_->mode, - st_->ino); - } - } + return g_func(branch_path_,fusepath_,mode_,ino_); +} + +void +fs::inode::calc(const std::string_view branch_path_, + const std::string_view fusepath_, + struct stat *st_) +{ + st_->st_ino = calc(branch_path_, + fusepath_, + st_->st_mode, + st_->st_ino); +} + +void +fs::inode::calc(const std::string_view branch_path_, + const std::string_view fusepath_, + struct fuse_statx *st_) +{ + st_->ino = calc(branch_path_, + fusepath_, + st_->mode, + st_->ino); } diff --git a/src/fs_ioctl.hpp b/src/fs_ioctl.hpp index 4d7d7f66..f5236438 100644 --- a/src/fs_ioctl.hpp +++ b/src/fs_ioctl.hpp @@ -18,7 +18,7 @@ #pragma once -#include "errno.hpp" +#include "to_neg_errno.hpp" #include @@ -35,7 +35,7 @@ namespace fs rv = ::ioctl(fd_,request_); - return ((rv == -1) ? -errno : rv); + return ::to_neg_errno(rv); } static @@ -49,7 +49,7 @@ namespace fs rv = ::ioctl(fd_,request_,data_); - return ((rv == -1) ? -errno : rv); + return ::to_neg_errno(rv); } static @@ -63,6 +63,6 @@ namespace fs rv = ::ioctl(fd_,request_,int_); - return ((rv == -1) ? -errno : rv); + return ::to_neg_errno(rv); } } diff --git a/src/fs_is_rofs.hpp b/src/fs_is_rofs.hpp index da178260..6ea0ff40 100644 --- a/src/fs_is_rofs.hpp +++ b/src/fs_is_rofs.hpp @@ -18,6 +18,7 @@ #pragma once +#include "fs_close.hpp" #include "fs_mktemp.hpp" #include "fs_statvfs.hpp" #include "fs_unlink.hpp" @@ -26,6 +27,8 @@ #include +#include + namespace fs { diff --git a/src/fs_lchmod.hpp b/src/fs_lchmod.hpp index 95012ab0..d611645f 100644 --- a/src/fs_lchmod.hpp +++ b/src/fs_lchmod.hpp @@ -19,11 +19,17 @@ #pragma once #include "fs_lstat.hpp" +#include "to_neg_errno.hpp" #include #include +#if defined __linux__ +#include +#include +#endif + #define MODE_BITS (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO) @@ -36,9 +42,18 @@ namespace fs const mode_t mode_) { #if defined __linux__ - return ::chmod(pathname_,mode_); + int rv; + const int flags = AT_SYMLINK_NOFOLLOW; + + rv = ::fchmodat(AT_FDCWD,pathname_,mode_,flags); + + return ::to_neg_errno(rv); #else - return ::lchmod(pathname_,mode_); + int rv; + + rv = ::lchmod(pathname_,mode_); + + return ::to_neg_errno(rv); #endif } @@ -60,18 +75,18 @@ namespace fs int rv; rv = fs::lchmod(path_,mode_); - if(rv == -1) + if(rv < 0) { - int error; + int err; struct stat st; - error = errno; + err = rv; rv = fs::lstat(path_,&st); - if(rv == -1) - return -1; + if(rv < 0) + return rv; if((st.st_mode & MODE_BITS) != (mode_ & MODE_BITS)) - return (errno=error,-1); + return err; } return 0; diff --git a/src/fs_lchown.hpp b/src/fs_lchown.hpp index 6091a269..24c9d0f1 100644 --- a/src/fs_lchown.hpp +++ b/src/fs_lchown.hpp @@ -19,6 +19,7 @@ #pragma once #include "fs_lstat.hpp" +#include "to_neg_errno.hpp" #include @@ -32,7 +33,11 @@ namespace fs const uid_t uid_, const gid_t gid_) { - return ::lchown(pathname_,uid_,gid_); + int rv; + + rv = ::lchown(pathname_,uid_,gid_); + + return ::to_neg_errno(rv); } static @@ -72,19 +77,19 @@ namespace fs int rv; rv = fs::lchown(path_,st_); - if(rv == -1) + if(rv < 0) { - int error; + int err; struct stat tmpst; - error = errno; + err = rv; rv = fs::lstat(path_,&tmpst); - if(rv == -1) - return -1; + if(rv < 0) + return err; if((st_.st_uid != tmpst.st_uid) || (st_.st_gid != tmpst.st_gid)) - return (errno=error,-1); + return err; } return 0; diff --git a/src/fs_lgetxattr.hpp b/src/fs_lgetxattr.hpp index 7d4fe8e1..96b0dfe7 100644 --- a/src/fs_lgetxattr.hpp +++ b/src/fs_lgetxattr.hpp @@ -18,7 +18,7 @@ #pragma once -#include "errno.hpp" +#include "to_neg_errno.hpp" #include "xattr.hpp" #include @@ -37,12 +37,16 @@ namespace fs const size_t size_) { #ifdef USE_XATTR - return ::lgetxattr(path_, - attrname_, - value_, - size_); + int rv; + + rv = ::lgetxattr(path_, + attrname_, + value_, + size_); + + return ::to_neg_errno(rv); #else - return (errno=ENOTSUP,-1); + return -ENOTSUP; #endif } diff --git a/src/fs_link.hpp b/src/fs_link.hpp index 8b41d4a2..f2dcdb9b 100644 --- a/src/fs_link.hpp +++ b/src/fs_link.hpp @@ -18,6 +18,8 @@ #pragma once +#include "to_neg_errno.hpp" + #include #include @@ -31,7 +33,11 @@ namespace fs link(const std::string &oldpath_, const std::string &newpath_) { - return ::link(oldpath_.c_str(), - newpath_.c_str()); + int rv; + + rv = ::link(oldpath_.c_str(), + newpath_.c_str()); + + return ::to_neg_errno(rv); } } diff --git a/src/fs_llistxattr.hpp b/src/fs_llistxattr.hpp index 18607f2c..30978e4c 100644 --- a/src/fs_llistxattr.hpp +++ b/src/fs_llistxattr.hpp @@ -18,7 +18,7 @@ #pragma once -#include "errno.hpp" +#include "to_neg_errno.hpp" #include "xattr.hpp" #include @@ -40,7 +40,7 @@ namespace fs rv = ::llistxattr(path_,list_,size_); - return ((rv == -1) ? -errno : rv); + return ::to_neg_errno(rv); #else return -ENOTSUP; #endif diff --git a/src/fs_lremovexattr.hpp b/src/fs_lremovexattr.hpp index 06258f9d..2f2e8a91 100644 --- a/src/fs_lremovexattr.hpp +++ b/src/fs_lremovexattr.hpp @@ -18,7 +18,7 @@ #pragma once -#include "errno.hpp" +#include "to_neg_errno.hpp" #include "xattr.hpp" #include @@ -33,9 +33,13 @@ namespace fs const char *attrname_) { #ifdef USE_XATTR - return ::lremovexattr(path_.c_str(),attrname_); + int rv; + + rv = ::lremovexattr(path_.c_str(),attrname_); + + return ::to_neg_errno(rv); #else - return (errno=ENOTSUP,-1); + return -ENOTSUP; #endif } } diff --git a/src/fs_lseek.hpp b/src/fs_lseek.hpp index 79bcfe3b..e47345a3 100644 --- a/src/fs_lseek.hpp +++ b/src/fs_lseek.hpp @@ -18,6 +18,8 @@ #pragma once +#include "to_neg_errno.hpp" + #include #include @@ -31,6 +33,10 @@ namespace fs const off_t offset_, const int whence_) { - return ::lseek(fd_,offset_,whence_); + off_t rv; + + rv = ::lseek(fd_,offset_,whence_); + + return ::to_neg_errno(rv); } } diff --git a/src/fs_lsetxattr.hpp b/src/fs_lsetxattr.hpp index ba3a7325..28e9e0b1 100644 --- a/src/fs_lsetxattr.hpp +++ b/src/fs_lsetxattr.hpp @@ -18,7 +18,7 @@ #pragma once -#include "errno.hpp" +#include "to_neg_errno.hpp" #include "xattr.hpp" #include @@ -38,13 +38,17 @@ namespace fs const int flags_) { #ifdef USE_XATTR - return ::lsetxattr(path_, - name_, - value_, - size_, - flags_); + int rv; + + rv = ::lsetxattr(path_, + name_, + value_, + size_, + flags_); + + return ::to_neg_errno(rv); #else - return (errno=ENOTSUP,-1); + return -ENOTSUP; #endif } diff --git a/src/fs_lstat.hpp b/src/fs_lstat.hpp index dd8e8384..574fd80b 100644 --- a/src/fs_lstat.hpp +++ b/src/fs_lstat.hpp @@ -18,6 +18,8 @@ #pragma once +#include "to_neg_errno.hpp" + #include #include @@ -33,7 +35,11 @@ namespace fs lstat(const char *path_, struct stat *st_) { - return ::lstat(path_,st_); + int rv; + + rv = ::lstat(path_,st_); + + return ::to_neg_errno(rv); } static diff --git a/src/fs_lstatvfs.hpp b/src/fs_lstatvfs.hpp new file mode 100644 index 00000000..400bdb5a --- /dev/null +++ b/src/fs_lstatvfs.hpp @@ -0,0 +1,55 @@ +/* + ISC License + + Copyright (c) 2019, 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. +*/ + +#pragma once + +#include "errno.hpp" +#include "fs_close.hpp" +#include "fs_open.hpp" +#include "fs_fstatvfs.hpp" + +#include +#include + +#ifndef O_PATH +# define O_PATH 0 +#endif + + +namespace fs +{ + static + inline + int + lstatvfs(const std::string &path_, + struct statvfs *st_) + { + int fd; + int rv; + + fd = fs::open(path_,O_RDONLY|O_NOFOLLOW|O_PATH); + if(fd < 0) + return fd; + + rv = fs::fstatvfs(fd,st_); + + fs::close(fd); + + return rv; + } +} diff --git a/src/fs_mkdir.hpp b/src/fs_mkdir.hpp index 530fe084..a16aa185 100644 --- a/src/fs_mkdir.hpp +++ b/src/fs_mkdir.hpp @@ -18,6 +18,8 @@ #pragma once +#include "to_neg_errno.hpp" + #include "fs_path.hpp" #include @@ -34,7 +36,11 @@ namespace fs mkdir(const char *path_, const mode_t mode_) { - return ::mkdir(path_,mode_); + int rv; + + rv = ::mkdir(path_,mode_); + + return ::to_neg_errno(rv); } static diff --git a/src/fs_mknod.hpp b/src/fs_mknod.hpp index 9bf80636..e1ecf6d7 100644 --- a/src/fs_mknod.hpp +++ b/src/fs_mknod.hpp @@ -18,14 +18,29 @@ #pragma once +#include "to_neg_errno.hpp" + #include #include #include -#include namespace fs { + static + inline + int + mknod(const char *path_, + const mode_t mode_, + const dev_t dev_) + { + int rv; + + rv = ::mknod(path_,mode_,dev_); + + return ::to_neg_errno(rv); + } + static inline int @@ -33,6 +48,6 @@ namespace fs const mode_t mode_, const dev_t dev_) { - return ::mknod(path_.c_str(),mode_,dev_); + return fs::mknod(path_.c_str(),mode_,dev_); } } diff --git a/src/fs_mktemp.cpp b/src/fs_mktemp.cpp index 4eed4b3f..90f2ee10 100644 --- a/src/fs_mktemp.cpp +++ b/src/fs_mktemp.cpp @@ -16,6 +16,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fs_mktemp.hpp" + #include "errno.hpp" #include "fs_open.hpp" #include "fs_path.hpp" @@ -36,77 +38,70 @@ static char const CHARS[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmno static size_t const CHARS_SIZE = (sizeof(CHARS) - 1); -namespace l +static +std::string +_generate_tmp_path(const std::string &dirpath_, + const std::string &filename_) +{ + long name_max; + size_t substr_len; + fs::Path path; + std::string filename; + + name_max = ::pathconf(dirpath_.c_str(),_PC_NAME_MAX); + if(name_max == -1) + name_max = NAME_MAX; + + substr_len = std::min(filename_.size(), + (size_t)(name_max - PAD_LEN - 2ULL)); + + filename = '.'; + filename += filename_.substr(0,substr_len); + filename += '_'; + for(size_t i = 0; i < PAD_LEN; i++) + filename += CHARS[RND::rand64(CHARS_SIZE)]; + + path = dirpath_; + path /= filename; + + return path.string(); +} + +std::tuple +fs::mktemp_in_dir(const std::string &dirpath_, + const std::string &filename_, + const int flags_) { - static - std::string - generate_tmp_path(const std::string &dirpath_, - const std::string &filename_) - { - long name_max; - size_t substr_len; - fs::Path path; - std::string filename; - - name_max = pathconf(dirpath_.c_str(),_PC_NAME_MAX); - if(name_max == -1) - name_max = NAME_MAX; - - substr_len = std::min(filename_.size(), - (size_t)(name_max - PAD_LEN - 2ULL)); - - filename = '.'; - filename += filename_.substr(0,substr_len); - filename += '_'; - for(size_t i = 0; i < PAD_LEN; i++) - filename += CHARS[RND::rand64(CHARS_SIZE)]; - - path = dirpath_; - path /= filename; - - return path.string(); - } + int fd; + int count; + int flags; + std::string tmp_filepath; + + count = MAX_ATTEMPTS; + flags = (flags_ | O_EXCL | O_CREAT); + while(count-- > 0) + { + tmp_filepath = ::_generate_tmp_path(dirpath_,filename_); + + fd = fs::open(tmp_filepath,flags,S_IRUSR|S_IWUSR); + if(fd == -EEXIST) + continue; + if(fd < 0) + return std::make_tuple(fd,std::string()); + + return std::make_tuple(fd,tmp_filepath); + } + + return std::make_tuple(-EEXIST,std::string()); } -namespace fs +std::tuple +fs::mktemp(const std::string &filepath_, + const int flags_) { - std::tuple - mktemp_in_dir(const std::string &dirpath_, - const std::string &filename_, - const int flags_) - { - int fd; - int count; - int flags; - std::string tmp_filepath; - - fd = -1; - count = MAX_ATTEMPTS; - flags = (flags_ | O_EXCL | O_CREAT); - while(count-- > 0) - { - tmp_filepath = l::generate_tmp_path(dirpath_,filename_); - - fd = fs::open(tmp_filepath,flags,S_IRUSR|S_IWUSR); - if((fd == -1) && (errno == EEXIST)) - continue; - if(fd == -1) - return std::make_tuple(-errno,std::string()); - - return std::make_tuple(fd,tmp_filepath); - } - - return std::make_tuple(-EEXIST,std::string()); - } - - std::tuple - mktemp(const std::string &filepath_, - const int flags_) - { - fs::Path filepath{filepath_}; - - return fs::mktemp_in_dir(filepath.parent_path(), - filepath.filename(), - flags_); - } + fs::Path filepath{filepath_}; + + return fs::mktemp_in_dir(filepath.parent_path(), + filepath.filename(), + flags_); } diff --git a/src/fs_mounts.cpp b/src/fs_mounts.cpp index 37cd5403..b77350b6 100644 --- a/src/fs_mounts.cpp +++ b/src/fs_mounts.cpp @@ -10,12 +10,12 @@ fs::mounts(fs::MountVec &mounts_) { FILE *f; - f = setmntent("/proc/mounts","r"); + f = ::setmntent("/proc/mounts","r"); if(f == NULL) return; struct mntent *entry; - while((entry = getmntent(f)) != NULL) + while((entry = ::getmntent(f)) != NULL) { fs::Mount m; @@ -27,7 +27,7 @@ fs::mounts(fs::MountVec &mounts_) mounts_.emplace_back(std::move(m)); } - endmntent(f); + ::endmntent(f); } #else void diff --git a/src/fs_movefile_and_open.cpp b/src/fs_movefile_and_open.cpp index f9ca12f1..aabac173 100644 --- a/src/fs_movefile_and_open.cpp +++ b/src/fs_movefile_and_open.cpp @@ -79,16 +79,16 @@ _movefile_and_open(const Policy::Create &createFunc_, src_branch = branchpath_; rv = createFunc_(branches_,fusepath_.c_str(),dst_branch); - if(rv == -1) - return -errno; + if(rv < 0) + return rv; origfd_flags = fs::getfl(origfd_); - if(origfd_flags == -1) - return -errno; + if(origfd_flags < 0) + return origfd_flags; src_size = fs::file_size(origfd_); - if(src_size == -1) - return -errno; + if(src_size < 0) + return src_size; if(fs::has_space(dst_branch[0]->path,src_size) == false) return -ENOSPC; @@ -96,7 +96,7 @@ _movefile_and_open(const Policy::Create &createFunc_, fusedir = fs::path::dirname(fusepath_); rv = fs::clonepath(src_branch,dst_branch[0]->path,fusedir); - if(rv == -1) + if(rv < 0) return -ENOSPC; src_filepath = fs::path::make(src_branch,fusepath_); @@ -108,7 +108,7 @@ _movefile_and_open(const Policy::Create &createFunc_, dstfd_flags = ::_cleanup_flags(origfd_flags); rv = fs::open(dst_filepath,dstfd_flags); - if(rv == -1) + if(rv < 0) return -ENOSPC; fs::unlink(src_filepath); diff --git a/src/fs_open.hpp b/src/fs_open.hpp index 02364361..0ac877ec 100644 --- a/src/fs_open.hpp +++ b/src/fs_open.hpp @@ -18,6 +18,8 @@ #pragma once +#include "to_neg_errno.hpp" + #include #include @@ -33,7 +35,11 @@ namespace fs open(const char *path_, const int flags_) { - return ::open(path_,flags_); + int rv; + + rv = ::open(path_,flags_); + + return ::to_neg_errno(rv); } static @@ -43,7 +49,11 @@ namespace fs const int flags_, const mode_t mode_) { - return ::open(path_,flags_,mode_); + int rv; + + rv = ::open(path_,flags_,mode_); + + return ::to_neg_errno(rv); } static diff --git a/src/fs_openat.hpp b/src/fs_openat.hpp index 13150834..0da7b598 100644 --- a/src/fs_openat.hpp +++ b/src/fs_openat.hpp @@ -18,10 +18,11 @@ #pragma once +#include "to_neg_errno.hpp" + #include #include -#include #include #include #include @@ -40,7 +41,7 @@ namespace fs rv = ::openat(dirfd_,pathname_,flags_,mode_); - return ((rv == -1) ? -errno : rv); + return ::to_neg_errno(rv); } static diff --git a/src/fs_opendir.hpp b/src/fs_opendir.hpp index a7f1197e..3d1ea835 100644 --- a/src/fs_opendir.hpp +++ b/src/fs_opendir.hpp @@ -26,11 +26,19 @@ namespace fs { + static + inline + DIR * + opendir(const char *name_) + { + return ::opendir(name_); + } + static inline DIR * opendir(const std::string &name_) { - return ::opendir(name_.c_str()); + return fs::opendir(name_.c_str()); } } diff --git a/src/fs_path.cpp b/src/fs_path.cpp index 90c65a5c..b72b6709 100644 --- a/src/fs_path.cpp +++ b/src/fs_path.cpp @@ -26,40 +26,34 @@ using std::string; -namespace fs +string +fs::path::dirname(const char *path_) { - namespace path - { - string - dirname(const char *path_) - { - string path(path_); + string path(path_); - return fs::path::dirname(path); - } + return fs::path::dirname(path); +} - string - dirname(const string &path_) - { - std::size_t i; +string +fs::path::dirname(const string &path_) +{ + std::size_t i; - i = path_.size() - 1; - while((i > 0) && (path_[i] == '/')) - i--; + i = path_.size() - 1; + while((i > 0) && (path_[i] == '/')) + i--; - while((i > 0) && (path_[i] != '/')) - i--; + while((i > 0) && (path_[i] != '/')) + i--; - while((i > 0) && (path_[i] == '/')) - i--; + while((i > 0) && (path_[i] == '/')) + i--; - return path_.substr(0,i+1); - } + return path_.substr(0,i+1); +} - string - basename(const string &path_) - { - return path_.substr(path_.find_last_of('/')+1); - } - } +string +fs::path::basename(const string &path_) +{ + return path_.substr(path_.find_last_of('/')+1); } diff --git a/src/fs_path.hpp b/src/fs_path.hpp index 5f175e44..e285d3af 100644 --- a/src/fs_path.hpp +++ b/src/fs_path.hpp @@ -86,4 +86,4 @@ namespace fs return (base_ + suffix_); } } -}; +} diff --git a/src/fs_pread.hpp b/src/fs_pread.hpp index b3258688..7f7e64a5 100644 --- a/src/fs_pread.hpp +++ b/src/fs_pread.hpp @@ -18,6 +18,8 @@ #pragma once +#include "to_neg_errno.hpp" + #include namespace fs @@ -33,6 +35,6 @@ namespace fs rv = ::pread(fd_,buf_,count_,offset_); - return ((rv == -1) ? -errno : rv); + return ::to_neg_errno(rv); } } diff --git a/src/fs_pwrite.hpp b/src/fs_pwrite.hpp index 9acc0f11..a3804295 100644 --- a/src/fs_pwrite.hpp +++ b/src/fs_pwrite.hpp @@ -18,6 +18,8 @@ #pragma once +#include "to_neg_errno.hpp" + #include @@ -34,9 +36,7 @@ namespace fs ssize_t rv; rv = ::pwrite(fd_,buf_,count_,offset_); - if(rv == -1) - return -errno; - return rv; + return ::to_neg_errno(rv); } } diff --git a/src/fs_read.hpp b/src/fs_read.hpp index c1021fe7..c3e1d059 100644 --- a/src/fs_read.hpp +++ b/src/fs_read.hpp @@ -18,6 +18,8 @@ #pragma once +#include "to_neg_errno.hpp" + #include @@ -30,17 +32,10 @@ namespace fs void *buf_, const size_t count_) { - return ::read(fd_,buf_,count_); - } + int rv; - static - inline - ssize_t - pread(const int fd_, - void *buf_, - const size_t count_, - const off_t offset_) - { - return ::pread(fd_,buf_,count_,offset_); + rv = ::read(fd_,buf_,count_); + + return ::to_neg_errno(rv); } } diff --git a/src/fs_readahead.cpp b/src/fs_readahead.cpp index 759983e4..d15f02d3 100644 --- a/src/fs_readahead.cpp +++ b/src/fs_readahead.cpp @@ -31,15 +31,13 @@ # include #endif -namespace l + +static +std::string +_generate_readahead_sys_path(const std::uint64_t major_, + const std::uint64_t minor_) { - static - std::string - generate_readahead_sys_path(const std::uint64_t major_, - const std::uint64_t minor_) - { - return fmt::format("/sys/class/bdi/{}:{}/read_ahead_kb",major_,minor_); - } + return fmt::format("/sys/class/bdi/{}:{}/read_ahead_kb",major_,minor_); } int @@ -50,7 +48,7 @@ fs::readahead(const std::uint64_t major_dev_, std::string syspath; std::ofstream ofs; - syspath = l::generate_readahead_sys_path(major_dev_,minor_dev_); + syspath = ::_generate_readahead_sys_path(major_dev_,minor_dev_); ofs.open(syspath); if(ofs) @@ -83,8 +81,8 @@ fs::readahead(const std::string path_, struct stat st; rv = fs::lstat(path_,&st); - if(rv == -1) - return -errno; + if(rv < 0) + return rv; return fs::readahead(st.st_dev,size_in_kb_); } diff --git a/src/fs_readlink.hpp b/src/fs_readlink.hpp index 0cd2df0f..b7ec62d3 100644 --- a/src/fs_readlink.hpp +++ b/src/fs_readlink.hpp @@ -18,6 +18,8 @@ #pragma once +#include "to_neg_errno.hpp" + #include #include @@ -27,11 +29,15 @@ namespace fs { static inline - int + ssize_t readlink(const std::string &path_, char *buf_, const size_t bufsiz_) { - return ::readlink(path_.c_str(),buf_,bufsiz_); + ssize_t rv; + + rv = ::readlink(path_.c_str(),buf_,bufsiz_); + + return ::to_neg_errno(rv); } } diff --git a/src/fs_realpathize.cpp b/src/fs_realpathize.cpp index fe85d2d2..53e3105e 100644 --- a/src/fs_realpathize.cpp +++ b/src/fs_realpathize.cpp @@ -16,28 +16,26 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fs_realpathize.hpp" + #include "fs_realpath.hpp" #include #include -namespace fs +void +fs::realpathize(std::vector *strs_) { - void - realpathize(std::vector *strs_) - { - char *rv; - - for(size_t i = 0; i < strs_->size(); i++) - { - rv = fs::realpath((*strs_)[i]); - if(rv == NULL) - continue; - - (*strs_)[i] = rv; - - ::free(rv); - } - } + char *rv; + char resolved_path[PATH_MAX]; + + for(size_t i = 0; i < strs_->size(); i++) + { + rv = fs::realpath((*strs_)[i],resolved_path); + if(rv == NULL) + continue; + + (*strs_)[i] = rv; + } } diff --git a/src/fs_remove.hpp b/src/fs_remove.hpp index b9d7f417..bc123b64 100644 --- a/src/fs_remove.hpp +++ b/src/fs_remove.hpp @@ -18,6 +18,8 @@ #pragma once +#include "to_neg_errno.hpp" + #include #include @@ -30,7 +32,11 @@ namespace fs int remove(const char *pathname_) { - return ::remove(pathname_); + int rv; + + rv = ::remove(pathname_); + + return ::to_neg_errno(rv); } static diff --git a/src/fs_rename.hpp b/src/fs_rename.hpp index a0fe92b3..16ce550e 100644 --- a/src/fs_rename.hpp +++ b/src/fs_rename.hpp @@ -18,6 +18,8 @@ #pragma once +#include "to_neg_errno.hpp" + #include @@ -29,7 +31,11 @@ namespace fs rename(const char *oldpath_, const char *newpath_) { - return ::rename(oldpath_,newpath_); + int rv; + + rv = ::rename(oldpath_,newpath_); + + return ::to_neg_errno(rv); } static diff --git a/src/fs_rmdir.hpp b/src/fs_rmdir.hpp index dd39a5b4..ac7dfa53 100644 --- a/src/fs_rmdir.hpp +++ b/src/fs_rmdir.hpp @@ -18,6 +18,8 @@ #pragma once +#include "to_neg_errno.hpp" + #include #include @@ -30,7 +32,11 @@ namespace fs int rmdir(const char *path_) { - return ::rmdir(path_); + int rv; + + rv = ::rmdir(path_); + + return ::to_neg_errno(rv); } static diff --git a/src/fs_sendfile_linux.icpp b/src/fs_sendfile_linux.icpp index 5f62c70a..9f5529bd 100644 --- a/src/fs_sendfile_linux.icpp +++ b/src/fs_sendfile_linux.icpp @@ -14,7 +14,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "errno.hpp" +#include "to_neg_errno.hpp" #include @@ -26,8 +26,11 @@ namespace fs const int fdout, const size_t count) { + ssize_t rv; off_t offset = 0; - return ::sendfile(fdout,fdin,&offset,count); + rv = ::sendfile(fdout,fdin,&offset,count); + + return ::to_neg_errno(rv); } } diff --git a/src/fs_sendfile_unsupported.icpp b/src/fs_sendfile_unsupported.icpp index 96a8827a..543daa48 100644 --- a/src/fs_sendfile_unsupported.icpp +++ b/src/fs_sendfile_unsupported.icpp @@ -14,18 +14,17 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fs_sendfile.hpp" + #include "errno.hpp" #include -namespace fs +ssize_t +fs::sendfile(const int fdin, + const int fdout, + const size_t count) { - ssize_t - sendfile(const int fdin, - const int fdout, - const size_t count) - { - return (errno=EINVAL,-1); - } + return -EINVAL; } diff --git a/src/fs_setfl.cpp b/src/fs_setfl.cpp index 7251c66b..46f45495 100644 --- a/src/fs_setfl.cpp +++ b/src/fs_setfl.cpp @@ -16,15 +16,14 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include +#include "fs_setfl.hpp" +#include "fs_fcntl.hpp" -namespace fs + +int +fs::setfl(const int fd_, + const mode_t mode_) { - int - setfl(const int fd_, - const mode_t mode_) - { - return ::fcntl(fd_,F_SETFL,mode_); - } + return fs::fcntl(fd_,F_SETFL,mode_); } diff --git a/src/fs_stat.hpp b/src/fs_stat.hpp index b1c7c864..0e85f7f3 100644 --- a/src/fs_stat.hpp +++ b/src/fs_stat.hpp @@ -18,6 +18,8 @@ #pragma once +#include "to_neg_errno.hpp" + #include #include @@ -33,7 +35,11 @@ namespace fs stat(const char *path_, struct stat *st_) { - return ::stat(path_,st_); + int rv; + + rv = ::stat(path_,st_); + + return ::to_neg_errno(rv); } static diff --git a/src/fs_statvfs.hpp b/src/fs_statvfs.hpp index db0c1cf1..45a95138 100644 --- a/src/fs_statvfs.hpp +++ b/src/fs_statvfs.hpp @@ -18,19 +18,12 @@ #pragma once -#include "errno.hpp" -#include "fs_close.hpp" -#include "fs_open.hpp" +#include "to_neg_errno.hpp" -#include #include #include -#ifndef O_PATH -# define O_PATH 0 -#endif - namespace fs { @@ -40,7 +33,11 @@ namespace fs statvfs(const char *path_, struct statvfs *st_) { - return ::statvfs(path_,st_); + int rv; + + rv = ::statvfs(path_,st_); + + return ::to_neg_errno(rv); } static @@ -51,33 +48,4 @@ namespace fs { return fs::statvfs(path_.c_str(),st_); } - - static - inline - int - fstatvfs(const int fd_, - struct statvfs *st_) - { - return ::fstatvfs(fd_,st_); - } - - static - inline - int - lstatvfs(const std::string &path_, - struct statvfs *st_) - { - int fd; - int rv; - - fd = fs::open(path_,O_RDONLY|O_NOFOLLOW|O_PATH); - if(fd == -1) - return -1; - - rv = fs::fstatvfs(fd,st_); - - fs::close(fd); - - return rv; - } } diff --git a/src/fs_statvfs_cache.cpp b/src/fs_statvfs_cache.cpp index 81477618..3585a30a 100644 --- a/src/fs_statvfs_cache.cpp +++ b/src/fs_statvfs_cache.cpp @@ -16,6 +16,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fs_statvfs_cache.hpp" + #include "fs_statvfs.hpp" #include "statvfs_util.hpp" @@ -42,104 +44,98 @@ static uint64_t g_timeout = 0; static statvfs_cache g_cache; static pthread_mutex_t g_cache_lock = PTHREAD_MUTEX_INITIALIZER; -namespace l +static +uint64_t +_get_time(void) { - static - uint64_t - get_time(void) - { - uint64_t rv; + uint64_t rv; - rv = ::time(NULL); + rv = ::time(NULL); - return rv; - } + return rv; } -namespace fs +uint64_t +fs::statvfs_cache_timeout(void) { - uint64_t - statvfs_cache_timeout(void) - { - return g_timeout; - } - - void - statvfs_cache_timeout(const uint64_t timeout_) - { - g_timeout = timeout_; - } - - int - statvfs_cache(const char *path_, - struct statvfs *st_) - { - int rv; - Element *e; - uint64_t now; - - if(g_timeout == 0) - return fs::statvfs(path_,st_); - - rv = 0; - now = l::get_time(); - - mutex_lock(&g_cache_lock); - - e = &g_cache[path_]; - - if((now - e->time) > g_timeout) - { - e->time = now; - rv = fs::statvfs(path_,&e->st); - } - - *st_ = e->st; - - mutex_unlock(&g_cache_lock); - - return rv; - } - - int - statvfs_cache_readonly(const std::string &path_, - bool *readonly_) - { - int rv; - struct statvfs st; - - rv = fs::statvfs_cache(path_.c_str(),&st); - if(rv == 0) - *readonly_ = StatVFS::readonly(st); - - return rv; - } - - int - statvfs_cache_spaceavail(const std::string &path_, - uint64_t *spaceavail_) - { - int rv; - struct statvfs st; - - rv = fs::statvfs_cache(path_.c_str(),&st); - if(rv == 0) - *spaceavail_ = StatVFS::spaceavail(st); - - return rv; - } - - int - statvfs_cache_spaceused(const std::string &path_, - uint64_t *spaceused_) - { - int rv; - struct statvfs st; - - rv = fs::statvfs_cache(path_.c_str(),&st); - if(rv == 0) - *spaceused_ = StatVFS::spaceused(st); - - return rv; - } + return g_timeout; +} + +void +fs::statvfs_cache_timeout(const uint64_t timeout_) +{ + g_timeout = timeout_; +} + +int +fs::statvfs_cache(const char *path_, + struct statvfs *st_) +{ + int rv; + Element *e; + uint64_t now; + + if(g_timeout == 0) + return fs::statvfs(path_,st_); + + rv = 0; + now = ::_get_time(); + + mutex_lock(&g_cache_lock); + + e = &g_cache[path_]; + + if((now - e->time) > g_timeout) + { + e->time = now; + rv = fs::statvfs(path_,&e->st); + } + + *st_ = e->st; + + mutex_unlock(&g_cache_lock); + + return rv; +} + +int +fs::statvfs_cache_readonly(const std::string &path_, + bool *readonly_) +{ + int rv; + struct statvfs st; + + rv = fs::statvfs_cache(path_.c_str(),&st); + if(rv == 0) + *readonly_ = StatVFS::readonly(st); + + return rv; +} + +int +fs::statvfs_cache_spaceavail(const std::string &path_, + uint64_t *spaceavail_) +{ + int rv; + struct statvfs st; + + rv = fs::statvfs_cache(path_.c_str(),&st); + if(rv == 0) + *spaceavail_ = StatVFS::spaceavail(st); + + return rv; +} + +int +fs::statvfs_cache_spaceused(const std::string &path_, + uint64_t *spaceused_) +{ + int rv; + struct statvfs st; + + rv = fs::statvfs_cache(path_.c_str(),&st); + if(rv == 0) + *spaceused_ = StatVFS::spaceused(st); + + return rv; } diff --git a/src/fs_statvfs_cache.hpp b/src/fs_statvfs_cache.hpp index d48d075d..9a68b742 100644 --- a/src/fs_statvfs_cache.hpp +++ b/src/fs_statvfs_cache.hpp @@ -22,6 +22,8 @@ #include +#include + namespace fs { diff --git a/src/fs_statx.hpp b/src/fs_statx.hpp index 8bdde2e3..9fb48eae 100644 --- a/src/fs_statx.hpp +++ b/src/fs_statx.hpp @@ -1,5 +1,7 @@ #pragma once +#include "to_neg_errno.hpp" + #include "fuse_kernel.h" #include @@ -35,7 +37,7 @@ namespace fs mask_, (struct statx*)st_); - return ((rv == -1) ? -errno : 0); + return ::to_neg_errno(rv); #else return -ENOSYS; #endif diff --git a/src/fs_symlink.hpp b/src/fs_symlink.hpp index b86e77b2..9c6cb0f2 100644 --- a/src/fs_symlink.hpp +++ b/src/fs_symlink.hpp @@ -18,6 +18,8 @@ #pragma once +#include "to_neg_errno.hpp" + #include #include @@ -31,7 +33,11 @@ namespace fs symlink(const char *target_, const char *linkpath_) { - return ::symlink(target_,linkpath_); + int rv; + + rv = ::symlink(target_,linkpath_); + + return ::to_neg_errno(rv); } static @@ -40,7 +46,8 @@ namespace fs symlink(const std::string &target_, const std::string &linkpath_) { - return ::symlink(target_.c_str(),linkpath_.c_str()); + return fs::symlink(target_.c_str(), + linkpath_.c_str()); } static @@ -49,6 +56,7 @@ namespace fs symlink(const char *target_, const std::string &linkpath_) { - return ::symlink(target_,linkpath_.c_str()); + return fs::symlink(target_, + linkpath_.c_str()); } } diff --git a/src/fs_truncate.hpp b/src/fs_truncate.hpp index 9a88ba60..dac9132e 100644 --- a/src/fs_truncate.hpp +++ b/src/fs_truncate.hpp @@ -18,6 +18,8 @@ #pragma once +#include "to_neg_errno.hpp" + #include #include @@ -32,7 +34,11 @@ namespace fs truncate(const char *path_, const off_t length_) { - return ::truncate(path_,length_); + int rv; + + rv = ::truncate(path_,length_); + + return ::to_neg_errno(rv); } static diff --git a/src/fs_umount2.hpp b/src/fs_umount2.hpp index 2d2dd047..02e0f389 100644 --- a/src/fs_umount2.hpp +++ b/src/fs_umount2.hpp @@ -18,6 +18,9 @@ #pragma once +#include "errno.hpp" +#include "to_neg_errno.hpp" + #ifdef __FreeBSD__ # include # include @@ -27,8 +30,6 @@ # include #endif -#include - #include namespace fs @@ -44,7 +45,7 @@ namespace fs rv = ::umount2(target_.c_str(), flags_); - return ((rv == -1) ? -errno : rv); + return ::to_neg_errno(rv); } static diff --git a/src/fs_unlink.hpp b/src/fs_unlink.hpp index 5fad40d2..4a6e594b 100644 --- a/src/fs_unlink.hpp +++ b/src/fs_unlink.hpp @@ -18,6 +18,8 @@ #pragma once +#include "to_neg_errno.hpp" + #include #include @@ -30,7 +32,11 @@ namespace fs int unlink(const char *path_) { - return ::unlink(path_); + int rv; + + rv = ::unlink(path_); + + return ::to_neg_errno(rv); } static diff --git a/src/fs_utimensat_freebsd.hpp b/src/fs_utimensat_freebsd.hpp index 251c3f56..46a04007 100644 --- a/src/fs_utimensat_freebsd.hpp +++ b/src/fs_utimensat_freebsd.hpp @@ -18,6 +18,8 @@ #pragma once +#include "to_neg_errno.hpp" + #include #include @@ -34,7 +36,11 @@ namespace fs const struct timespec times_[2], const int flags_) { - return ::utimensat(dirfd_,pathname_,times_,flags_); + int rv; + + rv = ::utimensat(dirfd_,pathname_,times_,flags_); + + return ::to_neg_errno(rv); } static diff --git a/src/fs_utimensat_generic.hpp b/src/fs_utimensat_generic.hpp index de274485..c37a21b2 100644 --- a/src/fs_utimensat_generic.hpp +++ b/src/fs_utimensat_generic.hpp @@ -37,228 +37,226 @@ #endif -namespace l +static +inline +bool +_can_call_lutimes(const int dirfd_, + const std::string &path_, + const int flags_) { - static - inline - bool - can_call_lutimes(const int dirfd_, - const std::string &path_, - const int flags_) - { - return ((flags_ == AT_SYMLINK_NOFOLLOW) && - ((dirfd_ == AT_FDCWD) || - (path_[0] == '/'))); - } + return ((flags_ == AT_SYMLINK_NOFOLLOW) && + ((dirfd_ == AT_FDCWD) || + (path_[0] == '/'))); +} - static - inline - bool - should_ignore(const struct timespec ts_[2]) - { - return ((ts_ != NULL) && - (ts_[0].tv_nsec == UTIME_OMIT) && - (ts_[1].tv_nsec == UTIME_OMIT)); - } +static +inline +bool +_should_ignore(const struct timespec ts_[2]) +{ + return ((ts_ != NULL) && + (ts_[0].tv_nsec == UTIME_OMIT) && + (ts_[1].tv_nsec == UTIME_OMIT)); +} - static - inline - bool - should_be_set_to_now(const struct timespec ts_[2]) - { - return ((ts_ == NULL) || - ((ts_[0].tv_nsec == UTIME_NOW) && - (ts_[1].tv_nsec == UTIME_NOW))); - } +static +inline +bool +_should_be_set_to_now(const struct timespec ts_[2]) +{ + return ((ts_ == NULL) || + ((ts_[0].tv_nsec == UTIME_NOW) && + (ts_[1].tv_nsec == UTIME_NOW))); +} - static - inline - bool - timespec_invalid(const struct timespec &ts_) - { - return (((ts_.tv_nsec < 0) || - (ts_.tv_nsec > 999999999)) && - ((ts_.tv_nsec != UTIME_NOW) && - (ts_.tv_nsec != UTIME_OMIT))); - } +static +inline +bool +_timespec_invalid(const struct timespec &ts_) +{ + return (((ts_.tv_nsec < 0) || + (ts_.tv_nsec > 999999999)) && + ((ts_.tv_nsec != UTIME_NOW) && + (ts_.tv_nsec != UTIME_OMIT))); +} - static - inline - bool - timespec_invalid(const struct timespec ts_[2]) - { - return ((ts_ != NULL) && - (l::timespec_invalid(ts_[0]) || - l::timespec_invalid(ts_[1]))); - } +static +inline +bool +_timespec_invalid(const struct timespec ts_[2]) +{ + return ((ts_ != NULL) && + (::_timespec_invalid(ts_[0]) || + ::_timespec_invalid(ts_[1]))); +} - static - inline - bool - flags_invalid(const int flags_) - { - return ((flags_ & ~AT_SYMLINK_NOFOLLOW) != 0); - } +static +inline +bool +_flags_invalid(const int flags_) +{ + return ((flags_ & ~AT_SYMLINK_NOFOLLOW) != 0); +} - static - inline - bool - any_timespec_is_utime_omit(const struct timespec ts_[2]) - { - return ((ts_[0].tv_nsec == UTIME_OMIT) || - (ts_[1].tv_nsec == UTIME_OMIT)); - } +static +inline +bool +_any_timespec_is_utime_omit(const struct timespec ts_[2]) +{ + return ((ts_[0].tv_nsec == UTIME_OMIT) || + (ts_[1].tv_nsec == UTIME_OMIT)); +} - static - inline - bool - any_timespec_is_utime_now(const struct timespec ts_[2]) - { - return ((ts_[0].tv_nsec == UTIME_NOW) || - (ts_[1].tv_nsec == UTIME_NOW)); - } +static +inline +bool +_any_timespec_is_utime_now(const struct timespec ts_[2]) +{ + return ((ts_[0].tv_nsec == UTIME_NOW) || + (ts_[1].tv_nsec == UTIME_NOW)); +} - static - inline - int - set_utime_omit_to_current_value(const int dirfd_, - const std::string &path_, - const struct timespec ts_[2], - struct timeval tv_[2], - const int flags_) - { - int rv; - struct stat st; - timespec *atime; - timespec *mtime; +static +inline +int +_set_utime_omit_to_current_value(const int dirfd_, + const std::string &path_, + const struct timespec ts_[2], + struct timeval tv_[2], + const int flags_) +{ + int rv; + struct stat st; + timespec *atime; + timespec *mtime; - if(!l::any_timespec_is_utime_omit(ts_)) - return 0; + if(!::_any_timespec_is_utime_omit(ts_)) + return 0; - rv = fs::fstatat(dirfd_,path_,&st,flags_); - if(rv < 0) - return rv; + rv = fs::fstatat(dirfd_,path_,&st,flags_); + if(rv < 0) + return rv; - atime = fs::stat_atime(st); - mtime = fs::stat_mtime(st); + atime = fs::stat_atime(st); + mtime = fs::stat_mtime(st); - if(ts_[0].tv_nsec == UTIME_OMIT) - TIMESPEC_TO_TIMEVAL(&tv[0],atime); - if(ts_[1].tv_nsec == UTIME_OMIT) - TIMESPEC_TO_TIMEVAL(&tv[1],mtime); + if(ts_[0].tv_nsec == UTIME_OMIT) + TIMESPEC_TO_TIMEVAL(&tv[0],atime); + if(ts_[1].tv_nsec == UTIME_OMIT) + TIMESPEC_TO_TIMEVAL(&tv[1],mtime); - return 0; - } + return 0; +} - static - inline - int - set_utime_omit_to_current_value(const int fd_, - const struct timespec ts_[2], - struct timeval tv_[2]) - { - int rv; - struct stat st; - timespec *atime; - timespec *mtime; +static +inline +int +_set_utime_omit_to_current_value(const int fd_, + const struct timespec ts_[2], + struct timeval tv_[2]) +{ + int rv; + struct stat st; + timespec *atime; + timespec *mtime; - if(!l::any_timespec_is_utime_omit(ts_)) - return 0; + if(!::_any_timespec_is_utime_omit(ts_)) + return 0; - rv = fs::fstat(fd_,&st); - if(rv == -1) - return -1; + rv = fs::fstat(fd_,&st); + if(rv < 0) + return rv; - atime = fs::stat_atime(st); - mtime = fs::stat_mtime(st); + atime = fs::stat_atime(st); + mtime = fs::stat_mtime(st); - if(ts_[0].tv_nsec == UTIME_OMIT) - TIMESPEC_TO_TIMEVAL(&tv_[0],atime); - if(ts_[1].tv_nsec == UTIME_OMIT) - TIMESPEC_TO_TIMEVAL(&tv_[1],mtime); + if(ts_[0].tv_nsec == UTIME_OMIT) + TIMESPEC_TO_TIMEVAL(&tv_[0],atime); + if(ts_[1].tv_nsec == UTIME_OMIT) + TIMESPEC_TO_TIMEVAL(&tv_[1],mtime); - return 0; - } + return 0; +} - static - inline - int - set_utime_now_to_now(const struct timespec ts_[2], - struct timeval tv_[2]) - { - int rv; - struct timeval now; +static +inline +int +_set_utime_now_to_now(const struct timespec ts_[2], + struct timeval tv_[2]) +{ + int rv; + struct timeval now; - if(l::any_timespec_is_utime_now(ts_)) - return 0; + if(::_any_timespec_is_utime_now(ts_)) + return 0; - rv = time::gettimeofday(&now,NULL); - if(rv == -1) - return -1; + rv = time::gettimeofday(&now,NULL); + if(rv < 0) + return rv; - if(ts_[0].tv_nsec == UTIME_NOW) - tv_[0] = now; - if(ts_[1].tv_nsec == UTIME_NOW) - tv_[1] = now; + if(ts_[0].tv_nsec == UTIME_NOW) + tv_[0] = now; + if(ts_[1].tv_nsec == UTIME_NOW) + tv_[1] = now; - return 0; - } + return 0; +} - static - inline - int - convert_timespec_to_timeval(const int dirfd_, - const std::string &path_, - const struct timespec ts_[2], - struct timeval tv_[2], - struct timeval **tvp_, - const int flags_) - { - int rv; +static +inline +int +_convert_timespec_to_timeval(const int dirfd_, + const std::string &path_, + const struct timespec ts_[2], + struct timeval tv_[2], + struct timeval **tvp_, + const int flags_) +{ + int rv; - if(l::should_be_set_to_now(ts_)) - return (tvp=NULL,0); + if(::_should_be_set_to_now(ts_)) + return (tvp=NULL,0); - TIMESPEC_TO_TIMEVAL(&tv_[0],&ts_[0]); - TIMESPEC_TO_TIMEVAL(&tv_[1],&ts_[1]); + TIMESPEC_TO_TIMEVAL(&tv_[0],&ts_[0]); + TIMESPEC_TO_TIMEVAL(&tv_[1],&ts_[1]); - rv = l::set_utime_omit_to_current_value(dirfd_,path_,ts_,tv_,flags_); - if(rv == -1) - return -1; + rv = ::_set_utime_omit_to_current_value(dirfd_,path_,ts_,tv_,flags_); + if(rv < 0) + return rv; - rv = l::set_utime_now_to_now(ts_,tv_); - if(rv == -1) - return -1; + rv = ::_set_utime_now_to_now(ts_,tv_); + if(rv < 0) + return rv; - return (*tvp_=tv_,0); - } + return (*tvp_=tv_,0); +} - static - inline - int - convert_timespec_to_timeval(const int fd_, - const struct timespec ts_[2], - struct timeval tv_[2], - struct timeval **tvp_) - { - int rv; +static +inline +int +_convert_timespec_to_timeval(const int fd_, + const struct timespec ts_[2], + struct timeval tv_[2], + struct timeval **tvp_) +{ + int rv; - if(l::should_be_set_to_now(ts_)) - return (*tvp=NULL,0); + if(::_should_be_set_to_now(ts_)) + return (*tvp=NULL,0); - TIMESPEC_TO_TIMEVAL(&tv_[0],&ts_[0]); - TIMESPEC_TO_TIMEVAL(&tv_[1],&ts_[1]); + TIMESPEC_TO_TIMEVAL(&tv_[0],&ts_[0]); + TIMESPEC_TO_TIMEVAL(&tv_[1],&ts_[1]); - rv = l::set_utime_omit_to_current_value(fd_,ts_,tv_); - if(rv == -1) - return -1; + rv = ::_set_utime_omit_to_current_value(fd_,ts_,tv_); + if(rv < 0) + return rv; - rv = l::set_utime_now_to_now(ts_,tv_); - if(rv == -1) - return -1; + rv = ::_set_utime_now_to_now(ts_,tv_); + if(rv < 0) + return rv; - return (*tvp=tv,0); - } + return (*tvp=tv,0); +} } namespace fs @@ -275,22 +273,22 @@ namespace fs struct timeval tv[2]; struct timeval *tvp; - if(l::flags_invalid(flags)) - return (errno=EINVAL,-1); - if(l::timespec_invalid(ts_)) - return (errno=EINVAL,-1); - if(l::should_ignore(ts_)) + if(::_flags_invalid(flags)) + return -EINVAL; + if(::_timespec_invalid(ts_)) + return -EINVAL; + if(::_should_ignore(ts_)) return 0; - rv = l::convert_timespec_to_timeval(dirfd_,path_,ts_,tv,&tvp,flags_); - if(rv == -1) - return -1; + rv = ::_convert_timespec_to_timeval(dirfd_,path_,ts_,tv,&tvp,flags_); + if(rv < 0) + return rv; if((flags_ & AT_SYMLINK_NOFOLLOW) == 0) return fs::futimesat(dirfd_,path_,tvp); - if(l::can_call_lutimes(dirfd_,path_,flags)) + if(::_can_call_lutimes(dirfd_,path_,flags)) return fs::lutimes(path_,tvp); - return (errno=ENOTSUP,-1); + return -ENOTSUP; } } diff --git a/src/fs_utimensat_linux.hpp b/src/fs_utimensat_linux.hpp index 251c3f56..46a04007 100644 --- a/src/fs_utimensat_linux.hpp +++ b/src/fs_utimensat_linux.hpp @@ -18,6 +18,8 @@ #pragma once +#include "to_neg_errno.hpp" + #include #include @@ -34,7 +36,11 @@ namespace fs const struct timespec times_[2], const int flags_) { - return ::utimensat(dirfd_,pathname_,times_,flags_); + int rv; + + rv = ::utimensat(dirfd_,pathname_,times_,flags_); + + return ::to_neg_errno(rv); } static diff --git a/src/fs_wait_for_mount.cpp b/src/fs_wait_for_mount.cpp index 448291ac..ff65d421 100644 --- a/src/fs_wait_for_mount.cpp +++ b/src/fs_wait_for_mount.cpp @@ -26,6 +26,7 @@ #include "fs_stat.hpp" #include +#include #include #include @@ -47,7 +48,7 @@ _branch_is_mounted(const struct stat &src_st_, fs::Path filepath; rv = fs::lgetxattr(branch_path_,"user.mergerfs.branch",NULL,0); - if(rv != -1) + if(rv >= 0) return true; filepath = branch_path_ / ".mergerfs.branch"; @@ -56,7 +57,7 @@ _branch_is_mounted(const struct stat &src_st_, return true; rv = fs::lgetxattr(branch_path_,"user.mergerfs.branch_mounts_here",NULL,0); - if(rv != -1) + if(rv >= 0) return false; filepath = branch_path_ / ".mergerfs.branch_mounts_here"; @@ -138,7 +139,7 @@ _wait_for_mount(const struct stat &src_st_, now = std::chrono::steady_clock::now(); } - for(auto const &path : failures) + for(const auto &path : failures) SysLog::notice("{} not ready within timeout",path.string()); return failures.size(); @@ -153,16 +154,16 @@ fs::wait_for_mount(const fs::Path &src_path_, struct stat src_st = {0}; rv = fs::stat(src_path_,&src_st); - if(rv == -1) + if(rv < 0) SysLog::error("Error stat'ing mount path: {} ({})", src_path_.string(), - strerror(errno)); + ::strerror(-rv)); for(auto &tgt_path : tgt_paths_) { int rv; - if(_branch_is_mounted(src_st,tgt_path)) + if(::_branch_is_mounted(src_st,tgt_path)) continue; rv = fs::mount(tgt_path); diff --git a/src/fs_write.hpp b/src/fs_write.hpp index ac329b57..ed90dd66 100644 --- a/src/fs_write.hpp +++ b/src/fs_write.hpp @@ -18,6 +18,8 @@ #pragma once +#include "to_neg_errno.hpp" + #include @@ -30,6 +32,10 @@ namespace fs const void *buf_, const size_t count_) { - return ::write(fd_,buf_,count_); + int rv; + + rv = ::write(fd_,buf_,count_); + + return ::to_neg_errno(rv); } } diff --git a/src/fs_xattr.cpp b/src/fs_xattr.cpp index e7ac84a3..63688661 100644 --- a/src/fs_xattr.cpp +++ b/src/fs_xattr.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fs_xattr.hpp" + #include "errno.hpp" #include "fs_close.hpp" #include "fs_fgetxattr.hpp" @@ -31,338 +33,327 @@ #include #include -using std::string; -using std::vector; -using std::map; -using std::istringstream; +using std::istringstream; -namespace fs +int +fs::xattr::list(const int fd_, + vector *attrs_) { - namespace xattr - { - int - list(const int fd_, - vector *attrs_) + ssize_t rv; + + rv = -ERANGE; + while(rv == -ERANGE) { - ssize_t rv; + rv = fs::flistxattr(fd_,NULL,0); + if(rv <= 0) + return rv; - rv = -1; - errno = ERANGE; - while((rv == -1) && (errno == ERANGE)) - { - rv = fs::flistxattr(fd_,NULL,0); - if(rv <= 0) - return rv; + attrs_->resize(rv); - attrs_->resize(rv); + rv = fs::flistxattr(fd_,&(*attrs_)[0],rv); + } - rv = fs::flistxattr(fd_,&(*attrs_)[0],rv); - } + return rv; +} - return rv; - } +int +fs::xattr::list(const string &path_, + vector *attrs_) +{ + ssize_t rv; - int - list(const string &path_, - vector *attrs_) + rv = -ERANGE; + while(rv == -ERANGE) { - ssize_t rv; + rv = fs::llistxattr(path_,NULL,0); + if(rv <= 0) + return rv; - rv = -1; - errno = ERANGE; - while((rv == -1) && (errno == ERANGE)) - { - rv = fs::llistxattr(path_,NULL,0); - if(rv <= 0) - return rv; + attrs_->resize(rv); - attrs_->resize(rv); + rv = fs::llistxattr(path_,&(*attrs_)[0],rv); + } - rv = fs::llistxattr(path_,&(*attrs_)[0],rv); - } + return rv; +} - return rv; - } +int +fs::xattr::list(const int fd_, + vector *attrvector_) +{ + int rv; + vector attrs; - int - list(const int fd_, - vector *attrvector_) + rv = fs::xattr::list(fd_,&attrs); + if(rv > 0) { - int rv; - vector attrs; + string tmp(attrs.begin(),attrs.end()); + str::split(tmp,'\0',attrvector_); + } - rv = fs::xattr::list(fd_,&attrs); - if(rv != -1) - { - string tmp(attrs.begin(),attrs.end()); - str::split(tmp,'\0',attrvector_); - } + return rv; +} - return rv; - } +int +fs::xattr::list(const string &path_, + vector *attrvector_) +{ + int rv; + vector attrs; - int - list(const string &path_, - vector *attrvector_) + rv = fs::xattr::list(path_,&attrs); + if(rv > 0) { - int rv; - vector attrs; + string tmp(attrs.begin(),attrs.end()); + str::split(tmp,'\0',attrvector_); + } - rv = fs::xattr::list(path_,&attrs); - if(rv != -1) - { - string tmp(attrs.begin(),attrs.end()); - str::split(tmp,'\0',attrvector_); - } + return rv; +} - return rv; - } +int +fs::xattr::list(const int fd_, + string *attrstr_) +{ + int rv; + vector attrs; - int - list(const int fd_, - string *attrstr_) - { - int rv; - vector attrs; + rv = fs::xattr::list(fd_,&attrs); + if(rv > 0) + *attrstr_ = string{attrs.begin(),attrs.end()}; - rv = fs::xattr::list(fd_,&attrs); - if(rv != -1) - *attrstr_ = string(attrs.begin(),attrs.end()); + return rv; +} - return rv; - } +int +fs::xattr::list(const string &path_, + string *attrstr_) +{ + int rv; + vector attrs; - int - list(const string &path_, - string *attrstr_) - { - int rv; - vector attrs; + rv = fs::xattr::list(path_,&attrs); + if(rv > 0) + *attrstr_ = string{attrs.begin(),attrs.end()}; - rv = fs::xattr::list(path_,&attrs); - if(rv != -1) - *attrstr_ = string(attrs.begin(),attrs.end()); + return rv; +} - return rv; - } +int +fs::xattr::get(const int fd_, + const string &attr_, + vector *value_) +{ + ssize_t rv; - int - get(const int fd_, - const string &attr_, - vector *value_) + rv = -ERANGE; + while(rv == -ERANGE) { - ssize_t rv; + rv = fs::fgetxattr(fd_,attr_,NULL,0); + if(rv <= 0) + return rv; - rv = -1; - errno = ERANGE; - while((rv == -1) && (errno == ERANGE)) - { - rv = fs::fgetxattr(fd_,attr_,NULL,0); - if(rv <= 0) - return rv; + value_->resize(rv); - value_->resize(rv); + rv = fs::fgetxattr(fd_,attr_,&(*value_)[0],rv); + } - rv = fs::fgetxattr(fd_,attr_,&(*value_)[0],rv); - } + return rv; +} - return rv; - } +int +fs::xattr::get(const string &path_, + const string &attr_, + vector *value_) +{ + ssize_t rv; - int - get(const string &path_, - const string &attr_, - vector *value_) + rv = -ERANGE; + while(rv == -ERANGE) { - ssize_t rv; + rv = fs::lgetxattr(path_,attr_,NULL,0); + if(rv <= 0) + return rv; - rv = -1; - errno = ERANGE; - while((rv == -1) && (errno == ERANGE)) - { - rv = fs::lgetxattr(path_,attr_,NULL,0); - if(rv <= 0) - return rv; + value_->resize(rv); - value_->resize(rv); + rv = fs::lgetxattr(path_,attr_,&(*value_)[0],rv); + } - rv = fs::lgetxattr(path_,attr_,&(*value_)[0],rv); - } + return rv; +} - return rv; - } +int +fs::xattr::get(const int fd_, + const string &attr_, + string *value_) +{ + int rv; + vector tmpvalue; - int - get(const int fd_, - const string &attr_, - string *value_) - { - int rv; - vector tmpvalue; + rv = fs::xattr::get(fd_,attr_,&tmpvalue); + if(rv > 0) + *value_ = string{tmpvalue.begin(),tmpvalue.end()}; - rv = get(fd_,attr_,&tmpvalue); - if(rv != -1) - *value_ = string(tmpvalue.begin(),tmpvalue.end()); + return rv; +} - return rv; - } +int +fs::xattr::get(const string &path_, + const string &attr_, + string *value_) +{ + int rv; + vector tmpvalue; - int - get(const string &path_, - const string &attr_, - string *value_) - { - int rv; - vector tmpvalue; + rv = fs::xattr::get(path_,attr_,&tmpvalue); + if(rv > 0) + *value_ = string{tmpvalue.begin(),tmpvalue.end()}; - rv = fs::xattr::get(path_,attr_,&tmpvalue); - if(rv != -1) - *value_ = string(tmpvalue.begin(),tmpvalue.end()); + return rv; +} - return rv; - } +int +fs::xattr::get(const int fd_, + map *attrs_) +{ + int rv; + string attrstr; - int - get(const int fd_, - map *attrs_) - { - int rv; - string attrstr; + rv = fs::xattr::list(fd_,&attrstr); + if(rv < 0) + return rv; - rv = fs::xattr::list(fd_,&attrstr); - if(rv == -1) - return -1; + { + string key; + std::istringstream ss(attrstr); + while(getline(ss,key,'\0')) { - string key; - istringstream ss(attrstr); - - while(getline(ss,key,'\0')) - { - string value; + string value; - rv = fs::xattr::get(fd_,key,&value); - if(rv != -1) - (*attrs_)[key] = value; - } + rv = fs::xattr::get(fd_,key,&value); + if(rv >= 0) + (*attrs_)[key] = value; } + } - return 0; - } + return 0; +} - int - get(const string &path_, - map *attrs_) - { - int rv; - string attrstr; +int +fs::xattr::get(const string &path_, + map *attrs_) +{ + int rv; + string attrstr; - rv = fs::xattr::list(path_,&attrstr); - if(rv == -1) - return -1; + rv = fs::xattr::list(path_,&attrstr); + if(rv < 0) + return rv; - { - string key; - istringstream ss(attrstr); + { + string key; + std::istringstream ss(attrstr); - while(getline(ss,key,'\0')) - { - string value; + while(getline(ss,key,'\0')) + { + string value; - rv = fs::xattr::get(path_,key,&value); - if(rv != -1) - (*attrs_)[key] = value; - } + rv = fs::xattr::get(path_,key,&value); + if(rv >= 0) + (*attrs_)[key] = value; } + } - return 0; - } + return 0; +} - int - set(const int fd_, - const string &key_, - const string &value_, - const int flags_) - { - return fs::fsetxattr(fd_, - key_, - value_.data(), - value_.size(), - flags_); - } +int +fs::xattr::set(const int fd_, + const string &key_, + const string &value_, + const int flags_) +{ + return fs::fsetxattr(fd_, + key_, + value_.data(), + value_.size(), + flags_); +} - int - set(const string &path_, - const string &key_, - const string &value_, - const int flags_) - { - return fs::lsetxattr(path_, - key_, - value_.data(), - value_.size(), - flags_); - } +int +fs::xattr::set(const string &path_, + const string &key_, + const string &value_, + const int flags_) +{ + return fs::lsetxattr(path_, + key_, + value_.data(), + value_.size(), + flags_); +} + +int +fs::xattr::set(const int fd_, + const map &attrs_) +{ + int rv; - int - set(const int fd_, - const map &attrs_) + for(const auto &[key,val] : attrs_) { - int rv; + rv = fs::xattr::set(fd_,key,val,0); + if(rv < 0) + return rv; + } - for(map::const_iterator - i = attrs_.begin(), ei = attrs_.end(); i != ei; ++i) - { - rv = fs::xattr::set(fd_,i->first,i->second,0); - if(rv == -1) - return -1; - } + return 0; +} - return 0; - } +int +fs::xattr::set(const string &path_, + const map &attrs_) +{ + int fd; + int rv; - int - set(const string &path_, - const map &attrs_) - { - int fd; + fd = fs::open(path_,O_RDONLY|O_NONBLOCK); + if(fd < 0) + return fd; - fd = fs::open(path_,O_RDONLY|O_NONBLOCK); - if(fd == -1) - return -1; + rv = fs::xattr::set(fd,attrs_); - fs::xattr::set(fd,attrs_); + fs::close(fd); - return fs::close(fd); - } + return rv; +} - int - copy(const int fdin_, - const int fdout_) - { - int rv; - map attrs; +int +fs::xattr::copy(const int fdin_, + const int fdout_) +{ + int rv; + map attrs; - rv = fs::xattr::get(fdin_,&attrs); - if(rv == -1) - return -1; + rv = fs::xattr::get(fdin_,&attrs); + if(rv < 0) + return rv; - return fs::xattr::set(fdout_,attrs); - } + return fs::xattr::set(fdout_,attrs); +} - int - copy(const string &from_, - const string &to_) - { - int rv; - map attrs; +int +fs::xattr::copy(const string &from_, + const string &to_) +{ + int rv; + map attrs; - rv = fs::xattr::get(from_,&attrs); - if(rv == -1) - return -1; + rv = fs::xattr::get(from_,&attrs); + if(rv < 0) + return rv; - return fs::xattr::set(to_,attrs); - } - } + return fs::xattr::set(to_,attrs); } diff --git a/src/fs_xattr.hpp b/src/fs_xattr.hpp index da7d2ba3..16b62b51 100644 --- a/src/fs_xattr.hpp +++ b/src/fs_xattr.hpp @@ -25,37 +25,50 @@ namespace fs { namespace xattr { + using std::map; using std::string; using std::vector; - using std::map; - - int list(const string &path, - vector *attrs); - int list(const string &path, - string *attrs); + int list(const int fd, + vector *attrs); + int list(const int fd, + vector *attrvec); + int list(const int fd, + string *attrstr); + int list(const string &path, + vector *attrs); + int list(const string &path, + string *attrs); int list(const string &path, vector *attrs); + int get(const int fd, + const string &attr_, + vector *val_); + int get(const int fd, + const string &attr, + string *val); + int get(const int fd, + map *attrs); int get(const string &path, const string &attr, vector *value); int get(const string &path, const string &attr, string *value); - int get(const string &path, map *attrs); - int set(const string &path, + int set(const int fd, const string &key, const string &value, const int flags); - int set(const int fd, + int set(const int fd, + const map &attrs); + int set(const string &path, const string &key, const string &value, const int flags); - int set(const string &path, const map &attrs); diff --git a/src/fuse_access.cpp b/src/fuse_access.cpp index 1680ef56..d7f9c861 100644 --- a/src/fuse_access.cpp +++ b/src/fuse_access.cpp @@ -42,14 +42,14 @@ namespace l std::vector branches; rv = searchFunc_(branches_,fusepath_,branches); - if(rv == -1) - return -errno; + if(rv < 0) + return rv; fullpath = fs::path::make(branches[0]->path,fusepath_); rv = fs::eaccess(fullpath,mask_); - return ((rv == -1) ? -errno : 0); + return rv; } } diff --git a/src/fuse_chmod.cpp b/src/fuse_chmod.cpp index a177d78a..a53294ac 100644 --- a/src/fuse_chmod.cpp +++ b/src/fuse_chmod.cpp @@ -73,8 +73,8 @@ namespace l std::vector branches; rv = actionFunc_(branches_,fusepath_,branches); - if(rv == -1) - return -errno; + if(rv < 0) + return rv; l::chmod_loop(branches,fusepath_,mode_,&prv); if(prv.errors.empty()) @@ -84,8 +84,8 @@ namespace l branches.clear(); rv = searchFunc_(branches_,fusepath_,branches); - if(rv == -1) - return -errno; + if(rv < 0) + return rv; return prv.get_error(branches[0]->path); } diff --git a/src/fuse_chown.cpp b/src/fuse_chown.cpp index df8e06a7..f458ebaa 100644 --- a/src/fuse_chown.cpp +++ b/src/fuse_chown.cpp @@ -75,8 +75,8 @@ namespace l std::vector branches; rv = actionFunc_(branches_,fusepath_,branches); - if(rv == -1) - return -errno; + if(rv < 0) + return rv; l::chown_loop(branches,fusepath_,uid_,gid_,&prv); if(prv.errors.empty()) @@ -86,8 +86,8 @@ namespace l branches.clear(); rv = searchFunc_(branches_,fusepath_,branches); - if(rv == -1) - return -errno; + if(rv < 0) + return rv; return prv.get_error(branches[0]->path); } diff --git a/src/fuse_copy_file_range.cpp b/src/fuse_copy_file_range.cpp index 34988d86..4ecb0163 100644 --- a/src/fuse_copy_file_range.cpp +++ b/src/fuse_copy_file_range.cpp @@ -43,7 +43,7 @@ namespace l size_, flags_); - return ((rv == -1) ? -errno : rv); + return rv; } } diff --git a/src/fuse_create.cpp b/src/fuse_create.cpp index c6ce4ff5..11fc0495 100644 --- a/src/fuse_create.cpp +++ b/src/fuse_create.cpp @@ -161,8 +161,8 @@ _create_core(const Branch *branch_, fullpath = fs::path::make(branch_->path,fusepath_); rv = ::_create_core(fullpath,mode_,umask_,ffi_->flags); - if(rv == -1) - return -errno; + if(rv < 0) + return rv; fi = new FileInfo(rv,branch_,fusepath_,ffi_->direct_io); @@ -190,18 +190,18 @@ _create(const Policy::Search &searchFunc_, fusedirpath = fs::path::dirname(fusepath_); rv = searchFunc_(branches_,fusedirpath,existingpaths); - if(rv == -1) - return -errno; + if(rv < 0) + return rv; rv = createFunc_(branches_,fusedirpath,createpaths); - if(rv == -1) - return -errno; + if(rv < 0) + return rv; rv = fs::clonepath_as_root(existingpaths[0]->path, createpaths[0]->path, fusedirpath); - if(rv == -1) - return -errno; + if(rv < 0) + return rv; return ::_create_core(createpaths[0], fusepath_, @@ -319,7 +319,7 @@ _create_update_lambda() return [=](auto &val_) { - fmt::print(stderr,"THIS SHOULD NOT HAPPEN"); + fmt::println(stderr,"THIS SHOULD NOT HAPPEN"); abort(); }; } diff --git a/src/fuse_fallocate.cpp b/src/fuse_fallocate.cpp index 2ce66055..7b3bad9d 100644 --- a/src/fuse_fallocate.cpp +++ b/src/fuse_fallocate.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fuse_fallocate.hpp" + #include "errno.hpp" #include "fileinfo.hpp" #include "fs_fallocate.hpp" @@ -21,36 +23,30 @@ #include "fuse.h" -namespace l +static +int +_fallocate(const int fd_, + const int mode_, + const off_t offset_, + const off_t len_) { - static - int - fallocate(const int fd_, - const int mode_, - const off_t offset_, - const off_t len_) - { - int rv; - - rv = fs::fallocate(fd_,mode_,offset_,len_); - - return ((rv == -1) ? -errno : 0); - } + int rv; + + rv = fs::fallocate(fd_,mode_,offset_,len_); + + return rv; } -namespace FUSE +int +FUSE::fallocate(const uint64_t fh_, + int mode_, + off_t offset_, + off_t len_) { - int - fallocate(const uint64_t fh_, - int mode_, - off_t offset_, - off_t len_) - { - FileInfo *fi = reinterpret_cast(fh_); - - return l::fallocate(fi->fd, - mode_, - offset_, - len_); - } + FileInfo *fi = reinterpret_cast(fh_); + + return ::_fallocate(fi->fd, + mode_, + offset_, + len_); } diff --git a/src/fuse_fchmod.cpp b/src/fuse_fchmod.cpp index 4b8558fc..6ffbdfc3 100644 --- a/src/fuse_fchmod.cpp +++ b/src/fuse_fchmod.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fuse_fchmod.hpp" + #include "errno.hpp" #include "fileinfo.hpp" #include "fs_fchmod.hpp" @@ -22,47 +24,39 @@ #include "fuse.h" -namespace l +static +int +_fchmod(const int fd_, + const mode_t mode_) { - static - int - fchmod(const int fd_, - const mode_t mode_) - { - int rv; + int rv; - rv = fs::fchmod(fd_,mode_); - if(rv == -1) - return -errno; + rv = fs::fchmod(fd_,mode_); - return rv; - } + return rv; } -namespace FUSE +int +FUSE::fchmod(const uint64_t fh_, + const mode_t mode_) { - int - fchmod(const uint64_t fh_, - const mode_t mode_) - { - uint64_t fh; - const fuse_context *fc = fuse_get_context(); + uint64_t fh; + const fuse_context *fc = fuse_get_context(); + + fh = fh_; + if(fh == 0) + { + state.open_files.cvisit(fc->nodeid, + [&](auto &val_) + { + fh = reinterpret_cast(val_.second.fi); + }); + } - fh = fh_; - if(fh == 0) - { - state.open_files.cvisit(fc->nodeid, - [&](auto &val_) - { - fh = reinterpret_cast(val_.second.fi); - }); - } + if(fh == 0) + return -ENOENT; - if(fh == 0) - return -ENOENT; - - FileInfo *fi = reinterpret_cast(fh); + FileInfo *fi = reinterpret_cast(fh); - return l::fchmod(fi->fd,mode_); - } + return ::_fchmod(fi->fd,mode_); } diff --git a/src/fuse_fchown.cpp b/src/fuse_fchown.cpp index 1cc92f97..d1698422 100644 --- a/src/fuse_fchown.cpp +++ b/src/fuse_fchown.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fuse_fchown.hpp" + #include "errno.hpp" #include "fileinfo.hpp" #include "fs_fchown.hpp" @@ -24,49 +26,41 @@ #include -namespace l +static +int +_fchown(const int fd_, + const uid_t uid_, + const gid_t gid_) { - static - int - fchown(const int fd_, - const uid_t uid_, - const gid_t gid_) - { - int rv; + int rv; - rv = fs::fchown(fd_,uid_,gid_); - if(rv == -1) - return -errno; + rv = fs::fchown(fd_,uid_,gid_); - return rv; - } + return rv; } -namespace FUSE +int +FUSE::fchown(const uint64_t fh_, + const uid_t uid_, + const gid_t gid_) { - int - fchown(const uint64_t fh_, - const uid_t uid_, - const gid_t gid_) - { - uint64_t fh; - const fuse_context *fc = fuse_get_context(); + uint64_t fh; + const fuse_context *fc = fuse_get_context(); - fh = fh_; - if(fh == 0) - { - state.open_files.cvisit(fc->nodeid, - [&](auto &val_) - { - fh = reinterpret_cast(val_.second.fi); - }); - } + fh = fh_; + if(fh == 0) + { + state.open_files.cvisit(fc->nodeid, + [&](auto &val_) + { + fh = reinterpret_cast(val_.second.fi); + }); + } - if(fh == 0) - return -ENOENT; + if(fh == 0) + return -ENOENT; - FileInfo *fi = reinterpret_cast(fh); + FileInfo *fi = reinterpret_cast(fh); - return l::fchown(fi->fd,uid_,gid_); - } + return ::_fchown(fi->fd,uid_,gid_); } diff --git a/src/fuse_fgetattr.cpp b/src/fuse_fgetattr.cpp index 9a1f4335..7b9413a5 100644 --- a/src/fuse_fgetattr.cpp +++ b/src/fuse_fgetattr.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fuse_fgetattr.hpp" + #include "config.hpp" #include "errno.hpp" #include "fileinfo.hpp" @@ -23,14 +25,13 @@ #include "fuse.h" + static int _fgetattr(const FileInfo *fi_, - struct stat *st_, - fuse_timeouts_t *timeout_) + struct stat *st_) { int rv; - Config::Read cfg; rv = fs::fstat(fi_->fd,st_); if(rv < 0) @@ -40,40 +41,44 @@ _fgetattr(const FileInfo *fi_, fi_->fusepath, st_); - timeout_->entry = ((rv >= 0) ? - cfg->cache_entry : - cfg->cache_negative_entry); - timeout_->attr = cfg->cache_attr; - return rv; } -namespace FUSE +int +FUSE::fgetattr(const uint64_t fh_, + struct stat *st_, + fuse_timeouts_t *timeout_) { - int - fgetattr(const uint64_t fh_, - struct stat *st_, - fuse_timeouts_t *timeout_) - { - uint64_t fh; - const fuse_context *fc = fuse_get_context(); - - fh = fh_; - if(fh == 0) - { - state.open_files.cvisit(fc->nodeid, - [&](auto &val_) - { - fh = reinterpret_cast(val_.second.fi); - }); - } - - if(fh == 0) + int rv; + uint64_t fh; + Config::Read cfg; + const fuse_context *fc = fuse_get_context(); + + fh = fh_; + if(fh == 0) + { + state.open_files.cvisit(fc->nodeid, + [&](const auto &val_) + { + fh = reinterpret_cast(val_.second.fi); + }); + } + + if(fh == 0) + { + timeout_->entry = cfg->cache_negative_entry; return -ENOENT; - - FileInfo *fi = reinterpret_cast(fh); + } + + FileInfo *fi = reinterpret_cast(fh); + + rv = ::_fgetattr(fi,st_); + + timeout_->entry = ((rv >= 0) ? + cfg->cache_entry : + cfg->cache_negative_entry); + timeout_->attr = cfg->cache_attr; - return ::_fgetattr(fi,st_,timeout_); - } + return rv; } diff --git a/src/fuse_flock.cpp b/src/fuse_flock.cpp index 4a6a2bb3..f8ea6e77 100644 --- a/src/fuse_flock.cpp +++ b/src/fuse_flock.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fuse_flock.hpp" + #include "errno.hpp" #include "fileinfo.hpp" #include "fs_flock.hpp" @@ -21,29 +23,23 @@ #include "fuse.h" -namespace l +static +int +_flock(const int fd_, + const int operation_) { - static - int - flock(const int fd_, - const int operation_) - { - int rv; + int rv; - rv = fs::flock(fd_,operation_); + rv = fs::flock(fd_,operation_); - return ((rv == -1) ? -errno : 0); - } + return rv; } -namespace FUSE +int +FUSE::flock(const fuse_file_info_t *ffi_, + int op_) { - int - flock(const fuse_file_info_t *ffi_, - int op_) - { - FileInfo* fi = reinterpret_cast(ffi_->fh); - - return l::flock(fi->fd,op_); - } + FileInfo* fi = reinterpret_cast(ffi_->fh); + + return ::_flock(fi->fd,op_); } diff --git a/src/fuse_flush.cpp b/src/fuse_flush.cpp index 37dc87b2..99559190 100644 --- a/src/fuse_flush.cpp +++ b/src/fuse_flush.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fuse_flush.hpp" + #include "errno.hpp" #include "fileinfo.hpp" #include "fs_close.hpp" @@ -22,31 +24,23 @@ #include "fuse.h" -namespace l +static +int +_flush(const int fd_) { - static - int - flush(const int fd_) - { - int rv; - - rv = fs::dup(fd_); - if(rv == -1) - errno = EIO; - else - rv = fs::close(rv); - - return ((rv == -1) ? -errno : 0); - } + int rv; + + rv = fs::dup(fd_); + if(rv < 0) + return -EIO; + + return fs::close(rv); } -namespace FUSE +int +FUSE::flush(const fuse_file_info_t *ffi_) { - int - flush(const fuse_file_info_t *ffi_) - { - FileInfo *fi = reinterpret_cast(ffi_->fh); + FileInfo *fi = reinterpret_cast(ffi_->fh); - return l::flush(fi->fd); - } + return ::_flush(fi->fd); } diff --git a/src/fuse_fsync.cpp b/src/fuse_fsync.cpp index 77d789dc..dba3a7f2 100644 --- a/src/fuse_fsync.cpp +++ b/src/fuse_fsync.cpp @@ -14,10 +14,13 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fuse_fsync.hpp" + #include "errno.hpp" #include "fileinfo.hpp" #include "fs_fdatasync.hpp" #include "fs_fsync.hpp" +#include "to_neg_errno.hpp" #include "fuse.h" @@ -25,31 +28,25 @@ #include -namespace l +static +int +_fsync(const int fd_, + const int isdatasync_) { - static - int - fsync(const int fd_, - const int isdatasync_) - { - int rv; - - rv = (isdatasync_ ? - fs::fdatasync(fd_) : - fs::fsync(fd_)); - - return ((rv == -1) ? -errno : 0); - } + int rv; + + rv = (isdatasync_ ? + fs::fdatasync(fd_) : + fs::fsync(fd_)); + + return ::to_neg_errno(rv); } -namespace FUSE +int +FUSE::fsync(const uint64_t fh_, + int isdatasync_) { - int - fsync(const uint64_t fh_, - int isdatasync_) - { - FileInfo *fi = reinterpret_cast(fh_); - - return l::fsync(fi->fd,isdatasync_); - } + FileInfo *fi = reinterpret_cast(fh_); + + return ::_fsync(fi->fd,isdatasync_); } diff --git a/src/fuse_fsyncdir.cpp b/src/fuse_fsyncdir.cpp index 1388b410..69f0c7ed 100644 --- a/src/fuse_fsyncdir.cpp +++ b/src/fuse_fsyncdir.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fuse_fsyncdir.hpp" + #include "errno.hpp" #include "dirinfo.hpp" #include "fs_fsync.hpp" @@ -24,30 +26,19 @@ #include -namespace l +static +int +_fsyncdir(const DirInfo *di_, + const int isdatasync_) { - static - int - fsyncdir(const DirInfo *di_, - const int isdatasync_) - { - int rv; - - rv = -1; - errno = ENOSYS; - - return ((rv == -1) ? -errno : 0); - } + return -ENOSYS; } -namespace FUSE +int +FUSE::fsyncdir(const fuse_file_info_t *ffi_, + int isdatasync_) { - int - fsyncdir(const fuse_file_info_t *ffi_, - int isdatasync_) - { - DirInfo *di = reinterpret_cast(ffi_->fh); - - return l::fsyncdir(di,isdatasync_); - } + DirInfo *di = reinterpret_cast(ffi_->fh); + + return ::_fsyncdir(di,isdatasync_); } diff --git a/src/fuse_ftruncate.cpp b/src/fuse_ftruncate.cpp index 3212e702..1719b575 100644 --- a/src/fuse_ftruncate.cpp +++ b/src/fuse_ftruncate.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fuse_ftruncate.hpp" + #include "errno.hpp" #include "fileinfo.hpp" #include "fs_ftruncate.hpp" @@ -22,42 +24,36 @@ #include "fuse.h" -namespace l +static +int +_ftruncate(const int fd_, + const off_t size_) { - static - int - ftruncate(const int fd_, - const off_t size_) - { - int rv; + int rv; - rv = fs::ftruncate(fd_,size_); + rv = fs::ftruncate(fd_,size_); - return ((rv == -1) ? -errno : 0); - } + return rv; } -namespace FUSE +int +FUSE::ftruncate(const uint64_t fh_, + off_t size_) { - int - ftruncate(const uint64_t fh_, - off_t size_) - { - uint64_t fh; - const fuse_context *fc = fuse_get_context(); - - fh = fh_; - if(fh == 0) - { - state.open_files.cvisit(fc->nodeid, - [&](auto &val_) - { - fh = reinterpret_cast(val_.second.fi); - }); - } - - FileInfo *fi = reinterpret_cast(fh); - - return l::ftruncate(fi->fd,size_); - } + uint64_t fh; + const fuse_context *fc = fuse_get_context(); + + fh = fh_; + if(fh == 0) + { + state.open_files.cvisit(fc->nodeid, + [&](auto &val_) + { + fh = reinterpret_cast(val_.second.fi); + }); + } + + FileInfo *fi = reinterpret_cast(fh); + + return ::_ftruncate(fi->fd,size_); } diff --git a/src/fuse_futimens.cpp b/src/fuse_futimens.cpp index e0fd9016..85da68ba 100644 --- a/src/fuse_futimens.cpp +++ b/src/fuse_futimens.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fuse_futimens.hpp" + #include "errno.hpp" #include "fileinfo.hpp" #include "fs_futimens.hpp" @@ -24,44 +26,36 @@ #include -namespace l +static +int +_futimens(const int fd_, + const struct timespec ts_[2]) { - static - int - futimens(const int fd_, - const struct timespec ts_[2]) - { - int rv; + int rv; - rv = fs::futimens(fd_,ts_); - if(rv == -1) - return -errno; + rv = fs::futimens(fd_,ts_); - return rv; - } + return rv; } -namespace FUSE +int +FUSE::futimens(const uint64_t fh_, + const struct timespec ts_[2]) { - int - futimens(const uint64_t fh_, - const struct timespec ts_[2]) - { - uint64_t fh; - const fuse_context *fc = fuse_get_context(); - - fh = fh_; - if(fh == 0) - { - state.open_files.cvisit(fc->nodeid, - [&](auto &val_) - { - fh = reinterpret_cast(val_.second.fi); - }); - } - - FileInfo *fi = reinterpret_cast(fh); - - return l::futimens(fi->fd,ts_); - } + uint64_t fh; + const fuse_context *fc = fuse_get_context(); + + fh = fh_; + if(fh == 0) + { + state.open_files.cvisit(fc->nodeid, + [&](const auto &val_) + { + fh = reinterpret_cast(val_.second.fi); + }); + } + + FileInfo *fi = reinterpret_cast(fh); + + return ::_futimens(fi->fd,ts_); } diff --git a/src/fuse_getattr.cpp b/src/fuse_getattr.cpp index 347a5d60..a97ffe95 100644 --- a/src/fuse_getattr.cpp +++ b/src/fuse_getattr.cpp @@ -36,172 +36,168 @@ using std::string; -namespace l +static +void +_set_stat_if_leads_to_dir(const std::string &path_, + struct stat *st_) { - static - void - set_stat_if_leads_to_dir(const std::string &path_, - struct stat *st_) - { - int rv; - struct stat st; + int rv; + struct stat st; - rv = fs::stat(path_,&st); - if(rv == -1) - return; + rv = fs::stat(path_,&st); + if(rv < 0) + return; + + if(S_ISDIR(st.st_mode)) + *st_ = st; - if(S_ISDIR(st.st_mode)) - *st_ = st; + return; +} +static +void +_set_stat_if_leads_to_reg(const std::string &path_, + struct stat *st_) +{ + int rv; + struct stat st; + + rv = fs::stat(path_,&st); + if(rv < 0) return; - } - static - void - set_stat_if_leads_to_reg(const std::string &path_, - struct stat *st_) - { - int rv; - struct stat st; + if(S_ISREG(st.st_mode)) + *st_ = st; - rv = fs::stat(path_,&st); - if(rv == -1) - return; + return; +} - if(S_ISREG(st.st_mode)) - *st_ = st; +static +int +_getattr_fake_root(struct stat *st_) +{ + st_->st_dev = 0; + st_->st_ino = 0; + st_->st_mode = (S_IFDIR|S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); + st_->st_nlink = 2; + st_->st_uid = 0; + st_->st_gid = 0; + st_->st_rdev = 0; + st_->st_size = 0; + st_->st_blksize = 512; + st_->st_blocks = 0; + st_->st_atime = 0; + st_->st_mtime = 0; + st_->st_ctime = 0; + + return 0; +} - return; - } - - static - int - getattr_fake_root(struct stat *st_) - { - st_->st_dev = 0; - st_->st_ino = 0; - st_->st_mode = (S_IFDIR|S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); - st_->st_nlink = 2; - st_->st_uid = 0; - st_->st_gid = 0; - st_->st_rdev = 0; - st_->st_size = 0; - st_->st_blksize = 512; - st_->st_blocks = 0; - st_->st_atime = 0; - st_->st_mtime = 0; - st_->st_ctime = 0; - - return 0; - } - - static - int - getattr_controlfile(struct stat *st_) - { - static const uid_t uid = ::getuid(); - static const gid_t gid = ::getgid(); - static const time_t now = ::time(NULL); - - st_->st_dev = 0; - st_->st_ino = 0; - st_->st_mode = (S_IFREG|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH); - st_->st_nlink = 1; - st_->st_uid = uid; - st_->st_gid = gid; - st_->st_rdev = 0; - st_->st_size = 0; - st_->st_blksize = 512; - st_->st_blocks = 0; - st_->st_atime = now; - st_->st_mtime = now; - st_->st_ctime = now; - - return 0; - } - - static - int - getattr(const Policy::Search &searchFunc_, - const Branches &branches_, - const char *fusepath_, - struct stat *st_, - const bool symlinkify_, - const time_t symlinkify_timeout_, - FollowSymlinks followsymlinks_) - { - int rv; - string fullpath; - std::vector branches; - - rv = searchFunc_(branches_,fusepath_,branches); - if(rv == -1) - return -errno; - - fullpath = fs::path::make(branches[0]->path,fusepath_); - - switch(followsymlinks_) - { - case FollowSymlinks::ENUM::NEVER: - rv = fs::lstat(fullpath,st_); - break; - case FollowSymlinks::ENUM::DIRECTORY: - rv = fs::lstat(fullpath,st_); - if(S_ISLNK(st_->st_mode)) - l::set_stat_if_leads_to_dir(fullpath,st_); - break; - case FollowSymlinks::ENUM::REGULAR: +static +int +_getattr_controlfile(struct stat *st_) +{ + static const uid_t uid = ::getuid(); + static const gid_t gid = ::getgid(); + static const time_t now = ::time(NULL); + + st_->st_dev = 0; + st_->st_ino = 0; + st_->st_mode = (S_IFREG|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH); + st_->st_nlink = 1; + st_->st_uid = uid; + st_->st_gid = gid; + st_->st_rdev = 0; + st_->st_size = 0; + st_->st_blksize = 512; + st_->st_blocks = 0; + st_->st_atime = now; + st_->st_mtime = now; + st_->st_ctime = now; + + return 0; +} + +static +int +_getattr(const Policy::Search &searchFunc_, + const Branches &branches_, + const char *fusepath_, + struct stat *st_, + const bool symlinkify_, + const time_t symlinkify_timeout_, + FollowSymlinks followsymlinks_) +{ + int rv; + string fullpath; + std::vector branches; + + rv = searchFunc_(branches_,fusepath_,branches); + if(rv < 0) + return rv; + + fullpath = fs::path::make(branches[0]->path,fusepath_); + + switch(followsymlinks_) + { + case FollowSymlinks::ENUM::NEVER: + rv = fs::lstat(fullpath,st_); + break; + case FollowSymlinks::ENUM::DIRECTORY: + rv = fs::lstat(fullpath,st_); + if(S_ISLNK(st_->st_mode)) + ::_set_stat_if_leads_to_dir(fullpath,st_); + break; + case FollowSymlinks::ENUM::REGULAR: + rv = fs::lstat(fullpath,st_); + if(S_ISLNK(st_->st_mode)) + ::_set_stat_if_leads_to_reg(fullpath,st_); + break; + case FollowSymlinks::ENUM::ALL: + rv = fs::stat(fullpath,st_); + if(rv < 0) rv = fs::lstat(fullpath,st_); - if(S_ISLNK(st_->st_mode)) - l::set_stat_if_leads_to_reg(fullpath,st_); - break; - case FollowSymlinks::ENUM::ALL: - rv = fs::stat(fullpath,st_); - if(rv != 0) - rv = fs::lstat(fullpath,st_); - break; - } - - if(rv == -1) - return -errno; - - if(symlinkify_ && symlinkify::can_be_symlink(*st_,symlinkify_timeout_)) - symlinkify::convert(fullpath,st_); - - fs::inode::calc(branches[0]->path,fusepath_,st_); - - return 0; - } - - int - getattr(const char *fusepath_, - struct stat *st_, - fuse_timeouts_t *timeout_) - { - int rv; - Config::Read cfg; - const fuse_context *fc = fuse_get_context(); - const ugid::Set ugid(fc->uid,fc->gid); - - rv = l::getattr(cfg->func.getattr.policy, - cfg->branches, - fusepath_, - st_, - cfg->symlinkify, - cfg->symlinkify_timeout, - cfg->follow_symlinks); - if((rv < 0) && Config::is_rootdir(fusepath_)) - return l::getattr_fake_root(st_); - - timeout_->entry = ((rv >= 0) ? - cfg->cache_entry : - cfg->cache_negative_entry); - timeout_->attr = cfg->cache_attr; + break; + } + if(rv < 0) return rv; - } + + if(symlinkify_ && symlinkify::can_be_symlink(*st_,symlinkify_timeout_)) + symlinkify::convert(fullpath,st_); + + fs::inode::calc(branches[0]->path,fusepath_,st_); + + return 0; } +int +_getattr(const char *fusepath_, + struct stat *st_, + fuse_timeouts_t *timeout_) +{ + int rv; + Config::Read cfg; + const fuse_context *fc = fuse_get_context(); + const ugid::Set ugid(fc->uid,fc->gid); + + rv = ::_getattr(cfg->func.getattr.policy, + cfg->branches, + fusepath_, + st_, + cfg->symlinkify, + cfg->symlinkify_timeout, + cfg->follow_symlinks); + if((rv < 0) && Config::is_rootdir(fusepath_)) + return ::_getattr_fake_root(st_); + + timeout_->entry = ((rv >= 0) ? + cfg->cache_entry : + cfg->cache_negative_entry); + timeout_->attr = cfg->cache_attr; + + return rv; +} int FUSE::getattr(const char *fusepath_, @@ -209,7 +205,7 @@ FUSE::getattr(const char *fusepath_, fuse_timeouts_t *timeout_) { if(Config::is_ctrl_file(fusepath_)) - return l::getattr_controlfile(st_); + return ::_getattr_controlfile(st_); - return l::getattr(fusepath_,st_,timeout_); + return ::_getattr(fusepath_,st_,timeout_); } diff --git a/src/fuse_getxattr.cpp b/src/fuse_getxattr.cpp index 32156538..43eb3feb 100644 --- a/src/fuse_getxattr.cpp +++ b/src/fuse_getxattr.cpp @@ -38,156 +38,138 @@ static const char SECURITY_CAPABILITY[] = "security.capability"; -namespace l +static +bool +_is_attrname_security_capability(const char *attrname_) { - static - bool - is_attrname_security_capability(const char *attrname_) - { - return (strcmp(attrname_,SECURITY_CAPABILITY) == 0); - } - - static - int - lgetxattr(const std::string &path_, - const char *attrname_, - void *value_, - const size_t size_) - { - int rv; - - rv = fs::lgetxattr(path_,attrname_,value_,size_); - - return ((rv == -1) ? -errno : rv); - } - - static - int - getxattr_ctrl_file(Config::Read &cfg_, - const char *attrname_, - char *buf_, - const size_t count_) - { - int rv; - std::string key; - std::string val; - - if(!Config::is_mergerfs_xattr(attrname_)) - return -ENOATTR; - - key = Config::prune_ctrl_xattr(attrname_); - rv = cfg_->get(key,&val); - if(rv < 0) - return rv; - - if(count_ == 0) - return val.size(); - - if(count_ < val.size()) - return -ERANGE; - - memcpy(buf_,val.c_str(),val.size()); - - return (int)val.size(); - } - - static - int - getxattr_from_string(char *destbuf_, - const size_t destbufsize_, - const std::string &src_) - { - const size_t srcbufsize = src_.size(); - - if(destbufsize_ == 0) - return srcbufsize; - - if(srcbufsize > destbufsize_) - return -ERANGE; - - memcpy(destbuf_,src_.data(),srcbufsize); + return (strcmp(attrname_,SECURITY_CAPABILITY) == 0); +} - return srcbufsize; - } - - static - int - getxattr_user_mergerfs_allpaths(const Branches::Ptr &branches_, - const char *fusepath_, - char *buf_, - const size_t count_) - { - std::string concated; - StrVec paths; - StrVec branches; - - branches_->to_paths(branches); - - fs::findallfiles(branches,fusepath_,&paths); - - concated = str::join(paths,'\0'); - - return l::getxattr_from_string(buf_,count_,concated); - } - - static - int - getxattr_user_mergerfs(const std::string &basepath_, - const char *fusepath_, - const std::string &fullpath_, - const Branches &branches_, - const char *attrname_, - char *buf_, - const size_t count_) - { - std::string key; - - key = Config::prune_ctrl_xattr(attrname_); - - if(key == "basepath") - return l::getxattr_from_string(buf_,count_,basepath_); - if(key == "relpath") - return l::getxattr_from_string(buf_,count_,fusepath_); - if(key == "fullpath") - return l::getxattr_from_string(buf_,count_,fullpath_); - if(key == "allpaths") - return l::getxattr_user_mergerfs_allpaths(branches_,fusepath_,buf_,count_); +static +int +_getxattr_ctrl_file(Config::Read &cfg_, + const char *attrname_, + char *buf_, + const size_t count_) +{ + int rv; + std::string key; + std::string val; + if(!Config::is_mergerfs_xattr(attrname_)) return -ENOATTR; - } - - static - int - getxattr(const Policy::Search &searchFunc_, - const Branches &branches_, - const char *fusepath_, - const char *attrname_, - char *buf_, - const size_t count_) - { - int rv; - std::string fullpath; - std::vector branches; - - rv = searchFunc_(branches_,fusepath_,branches); - if(rv == -1) - return -errno; - - fullpath = fs::path::make(branches[0]->path,fusepath_); - - if(Config::is_mergerfs_xattr(attrname_)) - return l::getxattr_user_mergerfs(branches[0]->path, - fusepath_, - fullpath, - branches_, - attrname_, - buf_, - count_); - - return l::lgetxattr(fullpath,attrname_,buf_,count_); - } + + key = Config::prune_ctrl_xattr(attrname_); + rv = cfg_->get(key,&val); + if(rv < 0) + return rv; + + if(count_ == 0) + return val.size(); + + if(count_ < val.size()) + return -ERANGE; + + memcpy(buf_,val.c_str(),val.size()); + + return (int)val.size(); +} + +static +int +_getxattr_from_string(char *destbuf_, + const size_t destbufsize_, + const std::string &src_) +{ + const size_t srcbufsize = src_.size(); + + if(destbufsize_ == 0) + return srcbufsize; + + if(srcbufsize > destbufsize_) + return -ERANGE; + + memcpy(destbuf_,src_.data(),srcbufsize); + + return srcbufsize; } +static +int +_getxattr_user_mergerfs_allpaths(const Branches::Ptr &branches_, + const char *fusepath_, + char *buf_, + const size_t count_) +{ + std::string concated; + StrVec paths; + StrVec branches; + + branches_->to_paths(branches); + + fs::findallfiles(branches,fusepath_,&paths); + + concated = str::join(paths,'\0'); + + return ::_getxattr_from_string(buf_,count_,concated); +} + +static +int +_getxattr_user_mergerfs(const std::string &basepath_, + const char *fusepath_, + const std::string &fullpath_, + const Branches &branches_, + const char *attrname_, + char *buf_, + const size_t count_) +{ + std::string key; + + key = Config::prune_ctrl_xattr(attrname_); + + if(key == "basepath") + return ::_getxattr_from_string(buf_,count_,basepath_); + if(key == "relpath") + return ::_getxattr_from_string(buf_,count_,fusepath_); + if(key == "fullpath") + return ::_getxattr_from_string(buf_,count_,fullpath_); + if(key == "allpaths") + return ::_getxattr_user_mergerfs_allpaths(branches_,fusepath_,buf_,count_); + + return -ENOATTR; +} + +static +int +_getxattr(const Policy::Search &searchFunc_, + const Branches &branches_, + const char *fusepath_, + const char *attrname_, + char *buf_, + const size_t count_) +{ + int rv; + std::string fullpath; + std::vector branches; + + rv = searchFunc_(branches_,fusepath_,branches); + if(rv < 0) + return rv; + + fullpath = fs::path::make(branches[0]->path,fusepath_); + + if(Config::is_mergerfs_xattr(attrname_)) + return ::_getxattr_user_mergerfs(branches[0]->path, + fusepath_, + fullpath, + branches_, + attrname_, + buf_, + count_); + + return fs::lgetxattr(fullpath,attrname_,buf_,count_); +} int FUSE::getxattr(const char *fusepath_, @@ -198,13 +180,13 @@ FUSE::getxattr(const char *fusepath_, Config::Read cfg; if(Config::is_ctrl_file(fusepath_)) - return l::getxattr_ctrl_file(cfg, + return ::_getxattr_ctrl_file(cfg, attrname_, attrvalue_, attrvalue_size_); if((cfg->security_capability == false) && - l::is_attrname_security_capability(attrname_)) + ::_is_attrname_security_capability(attrname_)) return -ENOATTR; if(cfg->xattr.to_int()) @@ -213,7 +195,7 @@ FUSE::getxattr(const char *fusepath_, const fuse_context *fc = fuse_get_context(); const ugid::Set ugid(fc->uid,fc->gid); - return l::getxattr(cfg->func.getxattr.policy, + return ::_getxattr(cfg->func.getxattr.policy, cfg->branches, fusepath_, attrname_, diff --git a/src/fuse_init.cpp b/src/fuse_init.cpp index 17db856c..c6b04e5f 100644 --- a/src/fuse_init.cpp +++ b/src/fuse_init.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fuse_init.hpp" + #include "config.hpp" #include "fs_readahead.hpp" #include "procfs.hpp" @@ -31,213 +33,208 @@ #include -namespace l +static +void +_want(fuse_conn_info *conn_, + const int flag_) +{ + conn_->want |= flag_; +} + +static +bool +_capable(fuse_conn_info *conn_, + const int flag_) +{ + return !!(conn_->capable & flag_); +} + +static +void +_want_if_capable(fuse_conn_info *conn_, + const int flag_) { - static - void - want(fuse_conn_info *conn_, - const int flag_) - { - conn_->want |= flag_; - } - - static - bool - capable(fuse_conn_info *conn_, - const int flag_) - { - return !!(conn_->capable & flag_); - } - - static - void - want_if_capable(fuse_conn_info *conn_, - const int flag_) - { - if(capable(conn_,flag_)) - want(conn_,flag_); - } - - static - void - want_if_capable(fuse_conn_info *conn_, - const int flag_, - ConfigBOOL *want_) - { - if(*want_ && l::capable(conn_,flag_)) - { - l::want(conn_,flag_); - return; - } - - *want_ = false; - } - - #define MAX_FUSE_MSG_SIZE 65535 - static const char MAX_PAGES_LIMIT_FILEPATH[] = "/proc/sys/fs/fuse/max_pages_limit"; - - static - void - want_if_capable_max_pages(fuse_conn_info *conn_, - Config::Write &cfg_) - { - std::fstream f; - uint64_t max_pages_limit; - - if(fs::exists(MAX_PAGES_LIMIT_FILEPATH)) - { - if(cfg_->fuse_msg_size > MAX_FUSE_MSG_SIZE) - SysLog::info("fuse_msg_size > {}: setting it to {}", - MAX_FUSE_MSG_SIZE, - MAX_FUSE_MSG_SIZE); - cfg_->fuse_msg_size = std::min((uint64_t)cfg_->fuse_msg_size, - (uint64_t)MAX_FUSE_MSG_SIZE); - - f.open(MAX_PAGES_LIMIT_FILEPATH,f.in|f.out); - if(f.is_open()) - { - f >> max_pages_limit; - SysLog::info("{} currently set to {}", - MAX_PAGES_LIMIT_FILEPATH, - max_pages_limit); - if(cfg_->fuse_msg_size > max_pages_limit) - { - f.seekp(0); - f << (uint64_t)cfg_->fuse_msg_size; - f.flush(); - SysLog::info("{} changed to {}", - MAX_PAGES_LIMIT_FILEPATH, - (uint64_t)cfg_->fuse_msg_size); - } - f.close(); - } - else - { - if(cfg_->fuse_msg_size != FUSE_DEFAULT_MAX_MAX_PAGES) - SysLog::info("unable to open {}",MAX_PAGES_LIMIT_FILEPATH); - } - } - else - { - if(cfg_->fuse_msg_size > FUSE_DEFAULT_MAX_MAX_PAGES) - SysLog::info("fuse_msg_size request {} > {}: setting it to {}", - (uint64_t)cfg_->fuse_msg_size, - FUSE_DEFAULT_MAX_MAX_PAGES, - FUSE_DEFAULT_MAX_MAX_PAGES); - cfg_->fuse_msg_size = std::min((uint64_t)cfg_->fuse_msg_size, - (uint64_t)FUSE_DEFAULT_MAX_MAX_PAGES); - } - - if(l::capable(conn_,FUSE_CAP_MAX_PAGES)) - { - l::want(conn_,FUSE_CAP_MAX_PAGES); - conn_->max_pages = cfg_->fuse_msg_size; - SysLog::info("requesting max pages size of {}", - (uint64_t)cfg_->fuse_msg_size); - } - else - { - cfg_->fuse_msg_size = FUSE_DEFAULT_MAX_PAGES_PER_REQ; - } - } - - static - void - readahead(const fs::Path path_, - const int readahead_) - { - int rv; - - rv = fs::readahead(path_,readahead_); - if(rv == 0) - SysLog::info("{} - readahead set to {}",path_.string(),readahead_); - else - SysLog::error("{} - unable to set readahead",path_.string()); - } - - static - void - set_readahead_on_mount_and_branches() - { - Config::Read cfg; - Branches::Ptr branches; - - if((uint64_t)cfg->readahead == 0) + if(::_capable(conn_,flag_)) + ::_want(conn_,flag_); +} + +static +void +_want_if_capable(fuse_conn_info *conn_, + const int flag_, + ConfigBOOL *want_) +{ + if(*want_ && ::_capable(conn_,flag_)) + { + ::_want(conn_,flag_); return; + } - l::readahead(cfg->mountpoint,cfg->readahead); + *want_ = false; +} - branches = cfg->branches; - for(auto const &branch : *branches) - l::readahead(branch.path,cfg->readahead); - } +#define MAX_FUSE_MSG_SIZE 65535 +static const char MAX_PAGES_LIMIT_FILEPATH[] = "/proc/sys/fs/fuse/max_pages_limit"; - // Spawn a thread to do this because before init returns calls to - // set the value will block leading to a deadlock. This is just - // easier. - static - void - spawn_thread_to_set_readahead() - { - std::thread readahead_thread(l::set_readahead_on_mount_and_branches); +static +void +_want_if_capable_max_pages(fuse_conn_info *conn_, + Config::Write &cfg_) +{ + std::fstream f; + uint64_t max_pages_limit; + + if(fs::exists(MAX_PAGES_LIMIT_FILEPATH)) + { + if(cfg_->fuse_msg_size > MAX_FUSE_MSG_SIZE) + SysLog::info("fuse_msg_size > {}: setting it to {}", + MAX_FUSE_MSG_SIZE, + MAX_FUSE_MSG_SIZE); + cfg_->fuse_msg_size = std::min((uint64_t)cfg_->fuse_msg_size, + (uint64_t)MAX_FUSE_MSG_SIZE); + + f.open(MAX_PAGES_LIMIT_FILEPATH,f.in|f.out); + if(f.is_open()) + { + f >> max_pages_limit; + SysLog::info("{} currently set to {}", + MAX_PAGES_LIMIT_FILEPATH, + max_pages_limit); + if(cfg_->fuse_msg_size > max_pages_limit) + { + f.seekp(0); + f << (uint64_t)cfg_->fuse_msg_size; + f.flush(); + SysLog::info("{} changed to {}", + MAX_PAGES_LIMIT_FILEPATH, + (uint64_t)cfg_->fuse_msg_size); + } + f.close(); + } + else + { + if(cfg_->fuse_msg_size != FUSE_DEFAULT_MAX_MAX_PAGES) + SysLog::info("unable to open {}",MAX_PAGES_LIMIT_FILEPATH); + } + } + else + { + if(cfg_->fuse_msg_size > FUSE_DEFAULT_MAX_MAX_PAGES) + SysLog::info("fuse_msg_size request {} > {}: setting it to {}", + (uint64_t)cfg_->fuse_msg_size, + FUSE_DEFAULT_MAX_MAX_PAGES, + FUSE_DEFAULT_MAX_MAX_PAGES); + cfg_->fuse_msg_size = std::min((uint64_t)cfg_->fuse_msg_size, + (uint64_t)FUSE_DEFAULT_MAX_MAX_PAGES); + } + + if(::_capable(conn_,FUSE_CAP_MAX_PAGES)) + { + ::_want(conn_,FUSE_CAP_MAX_PAGES); + conn_->max_pages = cfg_->fuse_msg_size; + SysLog::info("requesting max pages size of {}", + (uint64_t)cfg_->fuse_msg_size); + } + else + { + cfg_->fuse_msg_size = FUSE_DEFAULT_MAX_PAGES_PER_REQ; + } +} + +static +void +_readahead(const fs::Path path_, + const int readahead_) +{ + int rv; + + rv = fs::readahead(path_,readahead_); + if(rv == 0) + SysLog::info("{} - readahead set to {}",path_.string(),readahead_); + else + SysLog::error("{} - unable to set readahead",path_.string()); +} + +static +void +_set_readahead_on_mount_and_branches() +{ + Config::Read cfg; + Branches::Ptr branches; + + if((uint64_t)cfg->readahead == 0) + return; + + ::_readahead(cfg->mountpoint,cfg->readahead); + + branches = cfg->branches; + for(auto const &branch : *branches) + ::_readahead(branch.path,cfg->readahead); +} + +// Spawn a thread to do this because before init returns calls to +// set the value will block leading to a deadlock. This is just +// easier. +static +void +_spawn_thread_to_set_readahead() +{ + std::thread readahead_thread(::_set_readahead_on_mount_and_branches); - readahead_thread.detach(); - } + readahead_thread.detach(); } -namespace FUSE +void * +FUSE::init(fuse_conn_info *conn_) { - void * - init(fuse_conn_info *conn_) - { - Config::Write cfg; - - procfs::init(); - ugid::init(); - - cfg->readdir.initialize(); - - l::want_if_capable(conn_,FUSE_CAP_ASYNC_DIO); - l::want_if_capable(conn_,FUSE_CAP_ASYNC_READ,&cfg->async_read); - l::want_if_capable(conn_,FUSE_CAP_ATOMIC_O_TRUNC); - l::want_if_capable(conn_,FUSE_CAP_BIG_WRITES); - l::want_if_capable(conn_,FUSE_CAP_CACHE_SYMLINKS,&cfg->cache_symlinks); - l::want_if_capable(conn_,FUSE_CAP_DIRECT_IO_ALLOW_MMAP,&cfg->direct_io_allow_mmap); - l::want_if_capable(conn_,FUSE_CAP_DONT_MASK); - l::want_if_capable(conn_,FUSE_CAP_EXPORT_SUPPORT,&cfg->export_support); - l::want_if_capable(conn_,FUSE_CAP_HANDLE_KILLPRIV,&cfg->handle_killpriv); - l::want_if_capable(conn_,FUSE_CAP_HANDLE_KILLPRIV_V2,&cfg->handle_killpriv_v2); - l::want_if_capable(conn_,FUSE_CAP_IOCTL_DIR); - l::want_if_capable(conn_,FUSE_CAP_PARALLEL_DIROPS); - l::want_if_capable(conn_,FUSE_CAP_PASSTHROUGH); - l::want_if_capable(conn_,FUSE_CAP_POSIX_ACL,&cfg->posix_acl); - l::want_if_capable(conn_,FUSE_CAP_READDIR_PLUS,&cfg->readdirplus); - l::want_if_capable(conn_,FUSE_CAP_WRITEBACK_CACHE,&cfg->writeback_cache); - // l::want_if_capable(conn_,FUSE_CAP_READDIR_PLUS_AUTO); - l::want_if_capable_max_pages(conn_,cfg); - conn_->want &= ~FUSE_CAP_POSIX_LOCKS; - conn_->want &= ~FUSE_CAP_FLOCK_LOCKS; - - l::spawn_thread_to_set_readahead(); - - if(!(conn_->capable & FUSE_CAP_PASSTHROUGH) && (cfg->passthrough != Passthrough::ENUM::OFF)) - { - SysLog::warning("passthrough enabled but not supported by kernel. disabling."); - cfg->passthrough = Passthrough::ENUM::OFF; - } - - if((cfg->passthrough != Passthrough::ENUM::OFF) && - (cfg->cache_files == CacheFiles::ENUM::OFF)) - { - SysLog::warning("passthrough enabled and cache.files disabled: passthrough will not function"); - } - - if((cfg->passthrough != Passthrough::ENUM::OFF) && - (cfg->writeback_cache == true)) - { - SysLog::warning("passthrough and cache.writeback are incompatible. "); - } - - return NULL; - } + Config::Write cfg; + + procfs::init(); + ugid::init(); + + cfg->readdir.initialize(); + + ::_want_if_capable(conn_,FUSE_CAP_ASYNC_DIO); + ::_want_if_capable(conn_,FUSE_CAP_ASYNC_READ,&cfg->async_read); + ::_want_if_capable(conn_,FUSE_CAP_ATOMIC_O_TRUNC); + ::_want_if_capable(conn_,FUSE_CAP_BIG_WRITES); + ::_want_if_capable(conn_,FUSE_CAP_CACHE_SYMLINKS,&cfg->cache_symlinks); + ::_want_if_capable(conn_,FUSE_CAP_DIRECT_IO_ALLOW_MMAP,&cfg->direct_io_allow_mmap); + ::_want_if_capable(conn_,FUSE_CAP_DONT_MASK); + ::_want_if_capable(conn_,FUSE_CAP_EXPORT_SUPPORT,&cfg->export_support); + ::_want_if_capable(conn_,FUSE_CAP_HANDLE_KILLPRIV,&cfg->handle_killpriv); + ::_want_if_capable(conn_,FUSE_CAP_HANDLE_KILLPRIV_V2,&cfg->handle_killpriv_v2); + ::_want_if_capable(conn_,FUSE_CAP_IOCTL_DIR); + ::_want_if_capable(conn_,FUSE_CAP_PARALLEL_DIROPS); + ::_want_if_capable(conn_,FUSE_CAP_PASSTHROUGH); + ::_want_if_capable(conn_,FUSE_CAP_POSIX_ACL,&cfg->posix_acl); + ::_want_if_capable(conn_,FUSE_CAP_READDIR_PLUS,&cfg->readdirplus); + ::_want_if_capable(conn_,FUSE_CAP_WRITEBACK_CACHE,&cfg->writeback_cache); + // ::_want_if_capable(conn_,FUSE_CAP_READDIR_PLUS_AUTO); + ::_want_if_capable_max_pages(conn_,cfg); + conn_->want &= ~FUSE_CAP_POSIX_LOCKS; + conn_->want &= ~FUSE_CAP_FLOCK_LOCKS; + + ::_spawn_thread_to_set_readahead(); + + if(!(conn_->capable & FUSE_CAP_PASSTHROUGH) && (cfg->passthrough != Passthrough::ENUM::OFF)) + { + SysLog::warning("passthrough enabled but not supported by kernel. disabling."); + cfg->passthrough = Passthrough::ENUM::OFF; + } + + if((cfg->passthrough != Passthrough::ENUM::OFF) && + (cfg->cache_files == CacheFiles::ENUM::OFF)) + { + SysLog::warning("passthrough enabled and cache.files disabled:" + " passthrough will not function"); + } + + if((cfg->passthrough != Passthrough::ENUM::OFF) && + (cfg->writeback_cache == true)) + { + SysLog::warning("passthrough and cache.writeback are incompatible."); + } + + return NULL; } diff --git a/src/fuse_ioctl.cpp b/src/fuse_ioctl.cpp index b65c305c..235bbb19 100644 --- a/src/fuse_ioctl.cpp +++ b/src/fuse_ioctl.cpp @@ -138,14 +138,14 @@ _ioctl_dir_base(const Policy::Search &searchFunc_, std::vector branches; rv = searchFunc_(branches_,fusepath_,branches); - if(rv == -1) - return -errno; + if(rv < 0) + return rv; fullpath = fs::path::make(branches[0]->path,fusepath_); fd = fs::open(fullpath,O_RDONLY|O_NOATIME|O_NONBLOCK); - if(fd == -1) - return -errno; + if(fd < 0) + return fd; rv = ::_ioctl(fd,cmd_,data_,out_bufsz_); @@ -181,7 +181,6 @@ _is_btrfs_ioctl_cmd(const unsigned long cmd_) return (_IOC_TYPE(cmd_) == BTRFS_IOCTL_MAGIC); } - int FUSE::ioctl(const fuse_file_info_t *ffi_, unsigned long cmd_, diff --git a/src/fuse_link.cpp b/src/fuse_link.cpp index 1b5eb0fa..eb882652 100644 --- a/src/fuse_link.cpp +++ b/src/fuse_link.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fuse_link.hpp" + #include "config.hpp" #include "errno.hpp" #include "fs_clonepath.hpp" @@ -27,330 +29,307 @@ #include "fuse.h" #include +#include #include #include -namespace error +static +int +_link_create_path_loop(const std::vector &oldbranches_, + const Branch *newbranch_, + const char *oldfusepath_, + const char *newfusepath_, + const std::string &newfusedirpath_) +{ + int rv; + int err; + std::string oldfullpath; + std::string newfullpath; + + err = -ENOENT; + for(const auto &oldbranch : oldbranches_) + { + oldfullpath = fs::path::make(oldbranch->path,oldfusepath_); + newfullpath = fs::path::make(oldbranch->path,newfusepath_); + + rv = fs::link(oldfullpath,newfullpath); + if(rv == -ENOENT) + { + rv = fs::clonepath_as_root(newbranch_->path,oldbranch->path,newfusedirpath_); + if(rv == 0) + rv = fs::link(oldfullpath,newfullpath); + } + + if(err < 0) + err = rv; + } + + return err; +} + +static +int +_link_create_path(const Policy::Search &searchFunc_, + const Policy::Action &actionFunc_, + const Branches &ibranches_, + const char *oldfusepath_, + const char *newfusepath_) +{ + int rv; + std::string newfusedirpath; + std::vector oldbranches; + std::vector newbranches; + + rv = actionFunc_(ibranches_,oldfusepath_,oldbranches); + if(rv < 0) + return rv; + + newfusedirpath = fs::path::dirname(newfusepath_); + + rv = searchFunc_(ibranches_,newfusedirpath,newbranches); + if(rv < 0) + return rv; + + return ::_link_create_path_loop(oldbranches,newbranches[0], + oldfusepath_,newfusepath_, + newfusedirpath); +} + +static +int +_link_preserve_path_core(const std::string &oldbasepath_, + const char *oldfusepath_, + const char *newfusepath_, + struct stat *st_) { - static - inline - int - calc(const int rv_, - const int prev_, - const int cur_) - { - if(rv_ == -1) - { - if(prev_ == 0) - return 0; - return cur_; - } - - return 0; - } + int rv; + std::string oldfullpath; + std::string newfullpath; + + oldfullpath = fs::path::make(oldbasepath_,oldfusepath_); + newfullpath = fs::path::make(oldbasepath_,newfusepath_); + + rv = fs::link(oldfullpath,newfullpath); + if(rv == -ENOENT) + rv = -EXDEV; + if((rv == 0) && (st_->st_ino == 0)) + rv = fs::lstat(oldfullpath,st_); + + return rv; } -namespace l +static +int +_link_preserve_path_loop(const std::vector &oldbranches_, + const char *oldfusepath_, + const char *newfusepath_, + struct stat *st_) { - static - int - link_create_path_loop(const std::vector &oldbranches_, - const Branch *newbranch_, - const char *oldfusepath_, - const char *newfusepath_, - const std::string &newfusedirpath_) - { - int rv; - int error; - std::string oldfullpath; - std::string newfullpath; - - error = -1; - for(auto &oldbranch : oldbranches_) - { - oldfullpath = fs::path::make(oldbranch->path,oldfusepath_); - newfullpath = fs::path::make(oldbranch->path,newfusepath_); - - rv = fs::link(oldfullpath,newfullpath); - if((rv == -1) && (errno == ENOENT)) - { - rv = fs::clonepath_as_root(newbranch_->path,oldbranch->path,newfusedirpath_); - if(rv == 0) - rv = fs::link(oldfullpath,newfullpath); - } - - error = error::calc(rv,error,errno); - } - - return -error; - } - - static - int - link_create_path(const Policy::Search &searchFunc_, - const Policy::Action &actionFunc_, - const Branches &ibranches_, - const char *oldfusepath_, - const char *newfusepath_) - { - int rv; - std::string newfusedirpath; - std::vector oldbranches; - std::vector newbranches; - - rv = actionFunc_(ibranches_,oldfusepath_,oldbranches); - if(rv == -1) - return -errno; - - newfusedirpath = fs::path::dirname(newfusepath_); - - rv = searchFunc_(ibranches_,newfusedirpath,newbranches); - if(rv == -1) - return -errno; - - return l::link_create_path_loop(oldbranches,newbranches[0], - oldfusepath_,newfusepath_, - newfusedirpath); - } - - static - int - link_preserve_path_core(const std::string &oldbasepath_, - const char *oldfusepath_, - const char *newfusepath_, - struct stat *st_, - const int error_) - { - int rv; - std::string oldfullpath; - std::string newfullpath; - - oldfullpath = fs::path::make(oldbasepath_,oldfusepath_); - newfullpath = fs::path::make(oldbasepath_,newfusepath_); - - rv = fs::link(oldfullpath,newfullpath); - if((rv == -1) && (errno == ENOENT)) - errno = EXDEV; - if((rv == 0) && (st_->st_ino == 0)) - rv = fs::lstat(oldfullpath,st_); - - return error::calc(rv,error_,errno); - } - - static - int - link_preserve_path_loop(const std::vector &oldbranches_, - const char *oldfusepath_, - const char *newfusepath_, - struct stat *st_) - { - int error; - - error = -1; - for(auto &oldbranch : oldbranches_) - { - error = l::link_preserve_path_core(oldbranch->path, - oldfusepath_, - newfusepath_, - st_, - error); - } - - return -error; - } - - static - int - link_preserve_path(const Policy::Action &actionFunc_, - const Branches &branches_, - const char *oldfusepath_, - const char *newfusepath_, - struct stat *st_) - { - int rv; - std::vector oldbranches; - - rv = actionFunc_(branches_,oldfusepath_,oldbranches); - if(rv == -1) - return -errno; - - return l::link_preserve_path_loop(oldbranches, + int rv; + int err; + + err = -ENOENT; + for(const auto &oldbranch : oldbranches_) + { + rv = ::_link_preserve_path_core(oldbranch->path, oldfusepath_, newfusepath_, st_); - } - - static - int - link(Config::Read &cfg_, - const char *oldpath_, - const char *newpath_, - struct stat *st_) - { - if(cfg_->func.create.policy.path_preserving() && !cfg_->ignorepponrename) - return l::link_preserve_path(cfg_->func.link.policy, - cfg_->branches, - oldpath_, - newpath_, - st_); - - return l::link_create_path(cfg_->func.getattr.policy, - cfg_->func.link.policy, - cfg_->branches, - oldpath_, - newpath_); - } - - static - int - link(Config::Read &cfg_, - const char *oldpath_, - const char *newpath_, - struct stat *st_, - fuse_timeouts_t *timeouts_) - { - int rv; - - rv = l::link(cfg_,oldpath_,newpath_,st_); - if(rv < 0) - return rv; - - return FUSE::getattr(newpath_,st_,timeouts_); - } - - static - int - link_exdev_rel_symlink(const char *oldpath_, - const char *newpath_, - struct stat *st_, - fuse_timeouts_t *timeouts_) - { - int rv; - fs::Path target(oldpath_); - fs::Path linkpath(newpath_); - - target = target.lexically_relative(linkpath.parent_path()); - - rv = FUSE::symlink(target.c_str(),linkpath.c_str()); - if(rv == 0) - rv = FUSE::getattr(oldpath_,st_,timeouts_); - - // Disable caching since we created a symlink but should be a regular. - timeouts_->attr = 0; - timeouts_->entry = 0; + if(err < 0) + err = rv; + } - return rv; - } - - static - int - link_exdev_abs_base_symlink(const Policy::Search &openPolicy_, - const Branches::Ptr &ibranches_, - const char *oldpath_, - const char *newpath_, - struct stat *st_, - fuse_timeouts_t *timeouts_) - { - int rv; - std::string target; - std::vector obranches; - - rv = openPolicy_(ibranches_,oldpath_,obranches); - if(rv == -1) - return -errno; - - target = fs::path::make(obranches[0]->path,oldpath_); - - rv = FUSE::symlink(target.c_str(),newpath_); - if(rv == 0) - rv = FUSE::getattr(oldpath_,st_,timeouts_); - - // Disable caching since we created a symlink but should be a regular. - timeouts_->attr = 0; - timeouts_->entry = 0; + return err; +} + +static +int +_link_preserve_path(const Policy::Action &actionFunc_, + const Branches &branches_, + const char *oldfusepath_, + const char *newfusepath_, + struct stat *st_) +{ + int rv; + std::vector oldbranches; + rv = actionFunc_(branches_,oldfusepath_,oldbranches); + if(rv < 0) return rv; - } - - static - int - link_exdev_abs_pool_symlink(const fs::Path mount_, - const char *oldpath_, - const char *newpath_, - struct stat *st_, - fuse_timeouts_t *timeouts_) - { - int rv; - StrVec basepaths; - std::string target; - - target = fs::path::make(mount_,oldpath_); - - rv = FUSE::symlink(target.c_str(),newpath_); - if(rv == 0) - rv = FUSE::getattr(oldpath_,st_,timeouts_); - - // Disable caching since we created a symlink but should be a regular. - timeouts_->attr = 0; - timeouts_->entry = 0; + return ::_link_preserve_path_loop(oldbranches, + oldfusepath_, + newfusepath_, + st_); +} + +static +int +_link(Config::Read &cfg_, + const char *oldpath_, + const char *newpath_, + struct stat *st_) +{ + if(cfg_->func.create.policy.path_preserving() && !cfg_->ignorepponrename) + return ::_link_preserve_path(cfg_->func.link.policy, + cfg_->branches, + oldpath_, + newpath_, + st_); + + return ::_link_create_path(cfg_->func.getattr.policy, + cfg_->func.link.policy, + cfg_->branches, + oldpath_, + newpath_); +} + +static +int +_link(Config::Read &cfg_, + const char *oldpath_, + const char *newpath_, + struct stat *st_, + fuse_timeouts_t *timeouts_) +{ + int rv; + + rv = ::_link(cfg_,oldpath_,newpath_,st_); + if(rv < 0) return rv; - } - - static - int - link_exdev(Config::Read &cfg_, - const char *oldpath_, - const char *newpath_, - struct stat *st_, - fuse_timeouts_t *timeouts_) - { - switch(cfg_->link_exdev) - { - case LinkEXDEV::ENUM::PASSTHROUGH: - return -EXDEV; - case LinkEXDEV::ENUM::REL_SYMLINK: - return l::link_exdev_rel_symlink(oldpath_, - newpath_, - st_, - timeouts_); - case LinkEXDEV::ENUM::ABS_BASE_SYMLINK: - return l::link_exdev_abs_base_symlink(cfg_->func.open.policy, - cfg_->branches, - oldpath_, - newpath_, - st_, - timeouts_); - case LinkEXDEV::ENUM::ABS_POOL_SYMLINK: - return l::link_exdev_abs_pool_symlink(cfg_->mountpoint, - oldpath_, - newpath_, - st_, - timeouts_); - } - - return -EXDEV; - } + + return FUSE::getattr(newpath_,st_,timeouts_); +} + +static +int +_link_exdev_rel_symlink(const char *oldpath_, + const char *newpath_, + struct stat *st_, + fuse_timeouts_t *timeouts_) +{ + int rv; + fs::Path target(oldpath_); + fs::Path linkpath(newpath_); + + target = target.lexically_relative(linkpath.parent_path()); + + rv = FUSE::symlink(target.c_str(),linkpath.c_str()); + if(rv == 0) + rv = FUSE::getattr(oldpath_,st_,timeouts_); + + // Disable caching since we created a symlink but should be a regular. + timeouts_->attr = 0; + timeouts_->entry = 0; + + return rv; } -namespace FUSE +static +int +_link_exdev_abs_base_symlink(const Policy::Search &openPolicy_, + const Branches::Ptr &ibranches_, + const char *oldpath_, + const char *newpath_, + struct stat *st_, + fuse_timeouts_t *timeouts_) { - int - link(const char *oldpath_, - const char *newpath_, - struct stat *st_, - fuse_timeouts_t *timeouts_) - { - int rv; - Config::Read cfg; - const fuse_context *fc = fuse_get_context(); - const ugid::Set ugid(fc->uid,fc->gid); - - rv = l::link(cfg,oldpath_,newpath_,st_,timeouts_); - if(rv == -EXDEV) - rv = l::link_exdev(cfg,oldpath_,newpath_,st_,timeouts_); + int rv; + std::string target; + std::vector obranches; + rv = openPolicy_(ibranches_,oldpath_,obranches); + if(rv < 0) return rv; - } + + target = fs::path::make(obranches[0]->path,oldpath_); + + rv = FUSE::symlink(target.c_str(),newpath_); + if(rv == 0) + rv = FUSE::getattr(oldpath_,st_,timeouts_); + + // Disable caching since we created a symlink but should be a regular. + timeouts_->attr = 0; + timeouts_->entry = 0; + + return rv; +} + +static +int +_link_exdev_abs_pool_symlink(const fs::Path mount_, + const char *oldpath_, + const char *newpath_, + struct stat *st_, + fuse_timeouts_t *timeouts_) +{ + int rv; + StrVec basepaths; + std::string target; + + target = fs::path::make(mount_,oldpath_); + + rv = FUSE::symlink(target.c_str(),newpath_); + if(rv == 0) + rv = FUSE::getattr(oldpath_,st_,timeouts_); + + // Disable caching since we created a symlink but should be a regular. + timeouts_->attr = 0; + timeouts_->entry = 0; + + return rv; +} + +static +int +_link_exdev(Config::Read &cfg_, + const char *oldpath_, + const char *newpath_, + struct stat *st_, + fuse_timeouts_t *timeouts_) +{ + switch(cfg_->link_exdev) + { + case LinkEXDEV::ENUM::PASSTHROUGH: + return -EXDEV; + case LinkEXDEV::ENUM::REL_SYMLINK: + return ::_link_exdev_rel_symlink(oldpath_, + newpath_, + st_, + timeouts_); + case LinkEXDEV::ENUM::ABS_BASE_SYMLINK: + return ::_link_exdev_abs_base_symlink(cfg_->func.open.policy, + cfg_->branches, + oldpath_, + newpath_, + st_, + timeouts_); + case LinkEXDEV::ENUM::ABS_POOL_SYMLINK: + return ::_link_exdev_abs_pool_symlink(cfg_->mountpoint, + oldpath_, + newpath_, + st_, + timeouts_); + } + + return -EXDEV; +} + +int +FUSE::link(const char *oldpath_, + const char *newpath_, + struct stat *st_, + fuse_timeouts_t *timeouts_) +{ + int rv; + Config::Read cfg; + const fuse_context *fc = fuse_get_context(); + const ugid::Set ugid(fc->uid,fc->gid); + + rv = ::_link(cfg,oldpath_,newpath_,st_,timeouts_); + if(rv == -EXDEV) + rv = ::_link_exdev(cfg,oldpath_,newpath_,st_,timeouts_); + + return rv; } diff --git a/src/fuse_listxattr.cpp b/src/fuse_listxattr.cpp index 701c1d24..fdd85c2e 100644 --- a/src/fuse_listxattr.cpp +++ b/src/fuse_listxattr.cpp @@ -109,8 +109,8 @@ _listxattr(const Policy::Search &searchFunc_, std::vector obranches; rv = searchFunc_(ibranches_,fusepath_,obranches); - if(rv == -1) - return -errno; + if(rv < 0) + return rv; if(size_ == 0) return ::_listxattr_size(obranches,fusepath_); diff --git a/src/fuse_mkdir.cpp b/src/fuse_mkdir.cpp index 29229f06..9324d60c 100644 --- a/src/fuse_mkdir.cpp +++ b/src/fuse_mkdir.cpp @@ -14,8 +14,11 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fuse_mkdir.hpp" + #include "config.hpp" #include "errno.hpp" +#include "error.hpp" #include "fs_acl.hpp" #include "fs_clonepath.hpp" #include "fs_mkdir.hpp" @@ -28,150 +31,124 @@ #include -namespace error +static +int +_mkdir_core(const std::string &fullpath_, + mode_t mode_, + const mode_t umask_) +{ + if(!fs::acl::dir_has_defaults(fullpath_)) + mode_ &= ~umask_; + + return fs::mkdir(fullpath_,mode_); +} + +static +int +_mkdir_loop_core(const std::string &createpath_, + const char *fusepath_, + const mode_t mode_, + const mode_t umask_) { - static - inline - int - calc(const int rv_, - const int prev_, - const int cur_) - { - if(rv_ == -1) - { - if(prev_ == 0) - return 0; - return cur_; - } - - return 0; - } + int rv; + std::string fullpath; + + fullpath = fs::path::make(createpath_,fusepath_); + + rv = ::_mkdir_core(fullpath,mode_,umask_); + + return rv; } -namespace l +static +int +_mkdir_loop(const Branch *existingbranch_, + const std::vector &createbranches_, + const char *fusepath_, + const std::string &fusedirpath_, + const mode_t mode_, + const mode_t umask_) { - static - int - mkdir_core(const std::string &fullpath_, - mode_t mode_, - const mode_t umask_) - { - if(!fs::acl::dir_has_defaults(fullpath_)) - mode_ &= ~umask_; - - return fs::mkdir(fullpath_,mode_); - } - - static - int - mkdir_loop_core(const std::string &createpath_, - const char *fusepath_, - const mode_t mode_, - const mode_t umask_, - const int error_) - { - int rv; - std::string fullpath; - - fullpath = fs::path::make(createpath_,fusepath_); - - rv = l::mkdir_core(fullpath,mode_,umask_); - - return error::calc(rv,error_,errno); - } - - static - int - mkdir_loop(const Branch *existingbranch_, - const std::vector &createbranches_, - const char *fusepath_, - const std::string &fusedirpath_, - const mode_t mode_, - const mode_t umask_) - { - int rv; - int error; - - error = -1; - for(auto &createbranch : createbranches_) - { - rv = fs::clonepath_as_root(existingbranch_->path, - createbranch->path, - fusedirpath_); - if(rv == -1) - error = error::calc(rv,error,errno); - else - error = l::mkdir_loop_core(createbranch->path, - fusepath_, - mode_, - umask_, - error); - } - - return -error; - } - - static - int - mkdir(const Policy::Search &getattrPolicy_, - const Policy::Create &mkdirPolicy_, - const Branches &branches_, - const char *fusepath_, - const mode_t mode_, - const mode_t umask_) - { - int rv; - std::string fusedirpath; - std::vector createbranches; - std::vector existingbranches; - - fusedirpath = fs::path::dirname(fusepath_); - - rv = getattrPolicy_(branches_,fusedirpath,existingbranches); - if(rv == -1) - return -errno; - - rv = mkdirPolicy_(branches_,fusedirpath,createbranches); - if(rv == -1) - return -errno; - - return l::mkdir_loop(existingbranches[0], - createbranches, - fusepath_, - fusedirpath, - mode_, - umask_); - } + int rv; + Err err; + + for(const auto &createbranch : createbranches_) + { + rv = fs::clonepath_as_root(existingbranch_->path, + createbranch->path, + fusedirpath_); + if(rv < 0) + { + err = rv; + continue; + } + + err = ::_mkdir_loop_core(createbranch->path, + fusepath_, + mode_, + umask_); + } + + return err; } -namespace FUSE +static +int +_mkdir(const Policy::Search &getattrPolicy_, + const Policy::Create &mkdirPolicy_, + const Branches &branches_, + const char *fusepath_, + const mode_t mode_, + const mode_t umask_) { - int - mkdir(const char *fusepath_, - mode_t mode_) - { - int rv; - Config::Read cfg; - const fuse_context *fc = fuse_get_context(); - const ugid::Set ugid(fc->uid,fc->gid); - - rv = l::mkdir(cfg->func.getattr.policy, - cfg->func.mkdir.policy, - cfg->branches, - fusepath_, - mode_, - fc->umask); - if(rv == -EROFS) - { - Config::Write()->branches.find_and_set_mode_ro(); - rv = l::mkdir(cfg->func.getattr.policy, - cfg->func.mkdir.policy, - cfg->branches, - fusepath_, - mode_, - fc->umask); - } + int rv; + std::string fusedirpath; + std::vector createbranches; + std::vector existingbranches; + fusedirpath = fs::path::dirname(fusepath_); + + rv = getattrPolicy_(branches_,fusedirpath,existingbranches); + if(rv < 0) + return rv; + + rv = mkdirPolicy_(branches_,fusedirpath,createbranches); + if(rv < 0) return rv; - } + + return ::_mkdir_loop(existingbranches[0], + createbranches, + fusepath_, + fusedirpath, + mode_, + umask_); +} + +int +FUSE::mkdir(const char *fusepath_, + mode_t mode_) +{ + int rv; + Config::Read cfg; + const fuse_context *fc = fuse_get_context(); + const ugid::Set ugid(fc->uid,fc->gid); + + rv = ::_mkdir(cfg->func.getattr.policy, + cfg->func.mkdir.policy, + cfg->branches, + fusepath_, + mode_, + fc->umask); + if(rv == -EROFS) + { + Config::Write()->branches.find_and_set_mode_ro(); + rv = ::_mkdir(cfg->func.getattr.policy, + cfg->func.mkdir.policy, + cfg->branches, + fusepath_, + mode_, + fc->umask); + } + + return rv; } diff --git a/src/fuse_mkdir.hpp b/src/fuse_mkdir.hpp index f2c515b2..e410a600 100644 --- a/src/fuse_mkdir.hpp +++ b/src/fuse_mkdir.hpp @@ -16,6 +16,8 @@ #pragma once +#include + namespace FUSE { diff --git a/src/fuse_mknod.cpp b/src/fuse_mknod.cpp index 71caa95c..e3806fbf 100644 --- a/src/fuse_mknod.cpp +++ b/src/fuse_mknod.cpp @@ -14,8 +14,11 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fuse_mknod.hpp" + #include "config.hpp" #include "errno.hpp" +#include "error.hpp" #include "fs_acl.hpp" #include "fs_mknod.hpp" #include "fs_clonepath.hpp" @@ -28,157 +31,134 @@ #include -namespace error +static +inline +int +_mknod_core(const std::string &fullpath_, + mode_t mode_, + const mode_t umask_, + const dev_t dev_) +{ + if(!fs::acl::dir_has_defaults(fullpath_)) + mode_ &= ~umask_; + + return fs::mknod(fullpath_,mode_,dev_); +} + +static +int +_mknod_loop_core(const std::string &createbranch_, + const char *fusepath_, + const mode_t mode_, + const mode_t umask_, + const dev_t dev_) { - static - inline - int - calc(const int rv_, - const int prev_, - const int cur_) - { - if(rv_ == -1) - { - if(prev_ == 0) - return 0; - return cur_; - } - - return 0; - } + int rv; + std::string fullpath; + + fullpath = fs::path::make(createbranch_,fusepath_); + + rv = ::_mknod_core(fullpath,mode_,umask_,dev_); + + return rv; } -namespace l +static +int +_mknod_loop(const std::string &existingbranch_, + const std::vector &createbranches_, + const char *fusepath_, + const std::string &fusedirpath_, + const mode_t mode_, + const mode_t umask_, + const dev_t dev_) { - static - inline - int - mknod_core(const std::string &fullpath_, - mode_t mode_, - const mode_t umask_, - const dev_t dev_) - { - if(!fs::acl::dir_has_defaults(fullpath_)) - mode_ &= ~umask_; - - return fs::mknod(fullpath_,mode_,dev_); - } - - static - int - mknod_loop_core(const std::string &createbranch_, - const char *fusepath_, - const mode_t mode_, - const mode_t umask_, - const dev_t dev_, - const int error_) - { - int rv; - std::string fullpath; - - fullpath = fs::path::make(createbranch_,fusepath_); - - rv = l::mknod_core(fullpath,mode_,umask_,dev_); - - return error::calc(rv,error_,errno); - } - - static - int - mknod_loop(const std::string &existingbranch_, - const std::vector &createbranches_, - const char *fusepath_, - const std::string &fusedirpath_, - const mode_t mode_, - const mode_t umask_, - const dev_t dev_) - { - int rv; - int error; - - error = -1; - for(auto &createbranch : createbranches_) - { - rv = fs::clonepath_as_root(existingbranch_, - createbranch->path, - fusedirpath_); - if(rv == -1) - error = error::calc(rv,error,errno); - else - error = l::mknod_loop_core(createbranch->path, - fusepath_, - mode_,umask_,dev_,error); - } - - return -error; - } - - static - int - mknod(const Policy::Search &searchFunc_, - const Policy::Create &createFunc_, - const Branches &branches_, - const char *fusepath_, - const mode_t mode_, - const mode_t umask_, - const dev_t dev_) - { - int rv; - std::string fusedirpath; - std::vector createbranches; - std::vector existingbranches; - - fusedirpath = fs::path::dirname(fusepath_); - - rv = searchFunc_(branches_,fusedirpath,existingbranches); - if(rv == -1) - return -errno; - - rv = createFunc_(branches_,fusedirpath,createbranches); - if(rv == -1) - return -errno; - - return l::mknod_loop(existingbranches[0]->path, - createbranches, - fusepath_, - fusedirpath, - mode_, - umask_, - dev_); - } + int rv; + Err err; + + for(const auto &createbranch : createbranches_) + { + rv = fs::clonepath_as_root(existingbranch_, + createbranch->path, + fusedirpath_); + if(rv < 0) + { + err = rv; + continue; + } + + err = ::_mknod_loop_core(createbranch->path, + fusepath_, + mode_, + umask_, + dev_); + } + + return err; } -namespace FUSE +static +int +_mknod(const Policy::Search &searchFunc_, + const Policy::Create &createFunc_, + const Branches &branches_, + const char *fusepath_, + const mode_t mode_, + const mode_t umask_, + const dev_t dev_) { - int - mknod(const char *fusepath_, - mode_t mode_, - dev_t rdev_) - { - int rv; - Config::Read cfg; - const fuse_context *fc = fuse_get_context(); - const ugid::Set ugid(fc->uid,fc->gid); - - rv = l::mknod(cfg->func.getattr.policy, - cfg->func.mknod.policy, - cfg->branches, - fusepath_, - mode_, - fc->umask, - rdev_); - if(rv == -EROFS) - { - Config::Write()->branches.find_and_set_mode_ro(); - rv = l::mknod(cfg->func.getattr.policy, - cfg->func.mknod.policy, - cfg->branches, - fusepath_, - mode_, - fc->umask, - rdev_); - } + int rv; + std::string fusedirpath; + std::vector createbranches; + std::vector existingbranches; + fusedirpath = fs::path::dirname(fusepath_); + + rv = searchFunc_(branches_,fusedirpath,existingbranches); + if(rv < 0) + return rv; + + rv = createFunc_(branches_,fusedirpath,createbranches); + if(rv < 0) return rv; - } + + return ::_mknod_loop(existingbranches[0]->path, + createbranches, + fusepath_, + fusedirpath, + mode_, + umask_, + dev_); +} + +int +FUSE::mknod(const char *fusepath_, + mode_t mode_, + dev_t rdev_) +{ + int rv; + Config::Read cfg; + const fuse_context *fc = fuse_get_context(); + const ugid::Set ugid(fc->uid,fc->gid); + + rv = ::_mknod(cfg->func.getattr.policy, + cfg->func.mknod.policy, + cfg->branches, + fusepath_, + mode_, + fc->umask, + rdev_); + if(rv == -EROFS) + { + Config::Write()->branches.find_and_set_mode_ro(); + rv = ::_mknod(cfg->func.getattr.policy, + cfg->func.mknod.policy, + cfg->branches, + fusepath_, + mode_, + fc->umask, + rdev_); + } + + return rv; } diff --git a/src/fuse_mknod.hpp b/src/fuse_mknod.hpp index 6350f310..138a0893 100644 --- a/src/fuse_mknod.hpp +++ b/src/fuse_mknod.hpp @@ -17,6 +17,8 @@ #pragma once +#include + namespace FUSE { diff --git a/src/fuse_open.cpp b/src/fuse_open.cpp index f5ad92e6..91d513a9 100644 --- a/src/fuse_open.cpp +++ b/src/fuse_open.cpp @@ -56,19 +56,19 @@ _lchmod_and_open_if_not_writable_and_empty(const std::string &fullpath_, struct stat st; rv = fs::lstat(fullpath_,&st); - if(rv == -1) - return (errno=EACCES,-1); + if(rv < 0) + return -EACCES; if(StatUtil::writable(st)) - return (errno=EACCES,-1); + return -EACCES; rv = fs::lchmod(fullpath_,(st.st_mode|S_IWUSR|S_IWGRP)); - if(rv == -1) - return (errno=EACCES,-1); + if(rv < 0) + return -EACCES; rv = fs::open(fullpath_,flags_); - if(rv == -1) - return (errno=EACCES,-1); + if(rv < 0) + return -EACCES; fs::fchmod(rv,st.st_mode); @@ -85,16 +85,16 @@ _nfsopenhack(const std::string &fullpath_, { default: case NFSOpenHack::ENUM::OFF: - return (errno=EACCES,-1); + return -EACCES; case NFSOpenHack::ENUM::GIT: if(::_rdonly(flags_)) - return (errno=EACCES,-1); + return -EACCES; if(fullpath_.find("/.git/") == std::string::npos) - return (errno=EACCES,-1); + return -EACCES; return ::_lchmod_and_open_if_not_writable_and_empty(fullpath_,flags_); case NFSOpenHack::ENUM::ALL: if(::_rdonly(flags_)) - return (errno=EACCES,-1); + return -EACCES; return ::_lchmod_and_open_if_not_writable_and_empty(fullpath_,flags_); } } @@ -204,7 +204,7 @@ _open_path(const std::string &filepath_, FileInfo *fi; fd = fs::openat(AT_FDCWD,filepath_,ffi_->flags); - if((fd < 0) && (fd == -EACCES)) + if(fd == -EACCES) fd = ::_nfsopenhack(filepath_,ffi_->flags,nfsopenhack_); if(fd < 0) return fd; @@ -251,8 +251,8 @@ _open(const Policy::Search &searchFunc_, std::vector obranches; rv = searchFunc_(ibranches_,fusepath_,obranches); - if(rv == -1) - return -errno; + if(rv < 0) + return rv; filepath = fs::path::make(obranches[0]->path,fusepath_); @@ -380,15 +380,15 @@ auto _open_insert_lambda(const fuse_context *fc_, const char *fusepath_, fuse_file_info_t *ffi_, - int *_rv_) + int *rv_) { return [=](auto &val_) { - *_rv_ = ::_open_for_insert_lambda(fc_, - fusepath_, - ffi_, - &val_.second); + *rv_ = ::_open_for_insert_lambda(fc_, + fusepath_, + ffi_, + &val_.second); }; } @@ -399,7 +399,7 @@ auto _open_update_lambda(const fuse_context *fc_, const char *fusepath_, fuse_file_info_t *ffi_, - int *_rv_) + int *rv_) { return [=](auto &val_) @@ -409,17 +409,17 @@ _open_update_lambda(const fuse_context *fc_, // to abort an insert. if(val_.second.ref_count <= 0) { - *_rv_ = ::_open_for_insert_lambda(fc_, - fusepath_, - ffi_, - &val_.second); + *rv_ = ::_open_for_insert_lambda(fc_, + fusepath_, + ffi_, + &val_.second); return; } - *_rv_ = ::_open_for_update_lambda(fc_, - fusepath_, - ffi_, - &val_.second); + *rv_ = ::_open_for_update_lambda(fc_, + fusepath_, + ffi_, + &val_.second); }; } diff --git a/src/fuse_opendir.cpp b/src/fuse_opendir.cpp index f46f3c41..54265b52 100644 --- a/src/fuse_opendir.cpp +++ b/src/fuse_opendir.cpp @@ -34,8 +34,8 @@ namespace FUSE if(cfg->cache_readdir) { - ffi_->keep_cache = 1; - ffi_->cache_readdir = 1; + ffi_->keep_cache = true; + ffi_->cache_readdir = true; } return 0; diff --git a/src/fuse_read.cpp b/src/fuse_read.cpp index 8d6bf126..2def4e7e 100644 --- a/src/fuse_read.cpp +++ b/src/fuse_read.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fuse_read.hpp" + #include "errno.hpp" #include "fileinfo.hpp" #include "fs_pread.hpp" @@ -24,59 +26,53 @@ #include -namespace l +static +int +_read_direct_io(const int fd_, + char *buf_, + const size_t size_, + const off_t offset_) { - static - int - read_direct_io(const int fd_, - char *buf_, - const size_t size_, - const off_t offset_) - { - int rv; - - rv = fs::pread(fd_,buf_,size_,offset_); - - return rv; - } - - static - int - read_cached(const int fd_, - char *buf_, - const size_t size_, - const off_t offset_) - { - int rv; - - rv = fs::pread(fd_,buf_,size_,offset_); - - return rv; - } + int rv; + + rv = fs::pread(fd_,buf_,size_,offset_); + + return rv; +} + +static +int +_read_cached(const int fd_, + char *buf_, + const size_t size_, + const off_t offset_) +{ + int rv; + + rv = fs::pread(fd_,buf_,size_,offset_); + + return rv; +} + +int +FUSE::read(const fuse_file_info_t *ffi_, + char *buf_, + size_t size_, + off_t offset_) +{ + FileInfo *fi = reinterpret_cast(ffi_->fh); + + if(fi->direct_io) + return ::_read_direct_io(fi->fd,buf_,size_,offset_); + + return ::_read_cached(fi->fd,buf_,size_,offset_); } -namespace FUSE +int +FUSE::read_null(const fuse_file_info_t *ffi_, + char *buf_, + size_t size_, + off_t offset_) { - int - read(const fuse_file_info_t *ffi_, - char *buf_, - size_t size_, - off_t offset_) - { - FileInfo *fi = reinterpret_cast(ffi_->fh); - - if(fi->direct_io) - return l::read_direct_io(fi->fd,buf_,size_,offset_); - - return l::read_cached(fi->fd,buf_,size_,offset_); - } - - int - read_null(const fuse_file_info_t *ffi_, - char *buf_, - size_t size_, - off_t offset_) - { - return size_; - } + return size_; } diff --git a/src/fuse_readdir_seq.cpp b/src/fuse_readdir_seq.cpp index 8aab7bfb..4382f4f6 100644 --- a/src/fuse_readdir_seq.cpp +++ b/src/fuse_readdir_seq.cpp @@ -18,6 +18,7 @@ #include "fuse_readdir_seq.hpp" +#include "error.hpp" #include "branches.hpp" #include "config.hpp" #include "dirinfo.hpp" @@ -39,101 +40,71 @@ #include -namespace l +static +uint64_t +_dirent_exact_namelen(const struct dirent *d_) { - struct Error - { - private: - int _err; - - public: - Error() - : _err(ENOENT) - { +#ifdef _D_EXACT_NAMLEN + return _D_EXACT_NAMLEN(d_); +#elif defined _DIRENT_HAVE_D_NAMLEN + return d_->d_namlen; +#else + return strlen(d_->d_name); +#endif +} - } +static +int +_readdir(const Branches::Ptr &branches_, + const std::string &rel_dirpath_, + fuse_dirents_t *buf_) +{ + Err err; + HashSet names; + std::string rel_filepath; + std::string abs_dirpath; - operator int() - { - return _err; - } + fuse_dirents_reset(buf_); - Error& - operator=(int v_) + for(const auto &branch : *branches_) { - if(_err != 0) - _err = v_; + int rv; + DIR *dh; - return *this; + abs_dirpath = fs::path::make(branch.path,rel_dirpath_); + + errno = 0; + dh = fs::opendir(abs_dirpath); + err = -errno; + if(!dh) + continue; + + DEFER{ fs::closedir(dh); }; + + rv = 0; + for(dirent *de = fs::readdir(dh); de; de = fs::readdir(dh)) + { + std::uint64_t namelen; + + namelen = ::_dirent_exact_namelen(de); + + rv = names.put(de->d_name,namelen); + if(rv == 0) + continue; + + rel_filepath = fs::path::make(rel_dirpath_,de->d_name); + de->d_ino = fs::inode::calc(branch.path, + rel_filepath, + DTTOIF(de->d_type), + de->d_ino); + + rv = fuse_dirents_add(buf_,de,namelen); + if(rv) + return -ENOMEM; + } } - }; - static - uint64_t - dirent_exact_namelen(const struct dirent *d_) - { -#ifdef _D_EXACT_NAMLEN - return _D_EXACT_NAMLEN(d_); -#elif defined _DIRENT_HAVE_D_NAMLEN - return d_->d_namlen; -#else - return strlen(d_->d_name); -#endif - } - - static - int - readdir(const Branches::Ptr &branches_, - const std::string &rel_dirpath_, - fuse_dirents_t *buf_) - { - Error error; - HashSet names; - std::string rel_filepath; - std::string abs_dirpath; - - fuse_dirents_reset(buf_); - - for(const auto &branch : *branches_) - { - int rv; - DIR *dh; - - abs_dirpath = fs::path::make(branch.path,rel_dirpath_); - - errno = 0; - dh = fs::opendir(abs_dirpath); - error = errno; - if(!dh) - continue; - - DEFER{ fs::closedir(dh); }; - - rv = 0; - for(dirent *de = fs::readdir(dh); de && !rv; de = fs::readdir(dh)) - { - std::uint64_t namelen; - - namelen = l::dirent_exact_namelen(de); - - rv = names.put(de->d_name,namelen); - if(rv == 0) - continue; - - rel_filepath = fs::path::make(rel_dirpath_,de->d_name); - de->d_ino = fs::inode::calc(branch.path, - rel_filepath, - DTTOIF(de->d_type), - de->d_ino); - - rv = fuse_dirents_add(buf_,de,namelen); - if(rv) - return -ENOMEM; - } - } - - return -error; - } + return err; } int @@ -145,7 +116,7 @@ FUSE::ReadDirSeq::operator()(fuse_file_info_t const *ffi_, const fuse_context *fc = fuse_get_context(); const ugid::Set ugid(fc->uid,fc->gid); - return l::readdir(cfg->branches, + return ::_readdir(cfg->branches, di->fusepath, buf_); } diff --git a/src/fuse_readlink.cpp b/src/fuse_readlink.cpp index e905a7a4..263dd0fb 100644 --- a/src/fuse_readlink.cpp +++ b/src/fuse_readlink.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fuse_readlink.hpp" + #include "config.hpp" #include "errno.hpp" #include "fs_lstat.hpp" @@ -29,111 +31,105 @@ using std::string; -namespace l +static +int +_readlink_core_standard(const string &fullpath_, + char *buf_, + const size_t size_) + +{ + int rv; + + rv = fs::readlink(fullpath_,buf_,size_); + if(rv < 0) + return rv; + + buf_[rv] = '\0'; + + return 0; +} + +static +int +_readlink_core_symlinkify(const string &fullpath_, + char *buf_, + const size_t size_, + const time_t symlinkify_timeout_) +{ + int rv; + struct stat st; + + rv = fs::lstat(fullpath_,&st); + if(rv < 0) + return rv; + + if(!symlinkify::can_be_symlink(st,symlinkify_timeout_)) + return ::_readlink_core_standard(fullpath_,buf_,size_); + + strncpy(buf_,fullpath_.c_str(),size_); + + return 0; +} + +static +int +_readlink_core(const string &basepath_, + const char *fusepath_, + char *buf_, + const size_t size_, + const bool symlinkify_, + const time_t symlinkify_timeout_) +{ + string fullpath; + + fullpath = fs::path::make(basepath_,fusepath_); + + if(symlinkify_) + return ::_readlink_core_symlinkify(fullpath,buf_,size_,symlinkify_timeout_); + + return ::_readlink_core_standard(fullpath,buf_,size_); +} + +static +int +_readlink(const Policy::Search &searchFunc_, + const Branches &ibranches_, + const char *fusepath_, + char *buf_, + const size_t size_, + const bool symlinkify_, + const time_t symlinkify_timeout_) { - static - int - readlink_core_standard(const string &fullpath_, - char *buf_, - const size_t size_) - - { - int rv; - - rv = fs::readlink(fullpath_,buf_,size_); - if(rv == -1) - return -errno; - - buf_[rv] = '\0'; - - return 0; - } - - static - int - readlink_core_symlinkify(const string &fullpath_, - char *buf_, - const size_t size_, - const time_t symlinkify_timeout_) - { - int rv; - struct stat st; - - rv = fs::lstat(fullpath_,&st); - if(rv == -1) - return -errno; - - if(!symlinkify::can_be_symlink(st,symlinkify_timeout_)) - return l::readlink_core_standard(fullpath_,buf_,size_); - - strncpy(buf_,fullpath_.c_str(),size_); - - return 0; - } - - static - int - readlink_core(const string &basepath_, - const char *fusepath_, - char *buf_, - const size_t size_, - const bool symlinkify_, - const time_t symlinkify_timeout_) - { - string fullpath; - - fullpath = fs::path::make(basepath_,fusepath_); - - if(symlinkify_) - return l::readlink_core_symlinkify(fullpath,buf_,size_,symlinkify_timeout_); - - return l::readlink_core_standard(fullpath,buf_,size_); - } - - static - int - readlink(const Policy::Search &searchFunc_, - const Branches &ibranches_, - const char *fusepath_, - char *buf_, - const size_t size_, - const bool symlinkify_, - const time_t symlinkify_timeout_) - { - int rv; - StrVec basepaths; - std::vector obranches; - - rv = searchFunc_(ibranches_,fusepath_,obranches); - if(rv == -1) - return -errno; - - return l::readlink_core(obranches[0]->path, - fusepath_, - buf_, - size_, - symlinkify_, - symlinkify_timeout_); - } + int rv; + StrVec basepaths; + std::vector obranches; + + rv = searchFunc_(ibranches_,fusepath_,obranches); + if(rv < 0) + return rv; + + return ::_readlink_core(obranches[0]->path, + fusepath_, + buf_, + size_, + symlinkify_, + symlinkify_timeout_); } -namespace FUSE +int +FUSE::readlink(const char *fusepath_, + char *buf_, + size_t size_) { - int - readlink(const char *fusepath_, - char *buf_, - size_t size_) - { - Config::Read cfg; - const fuse_context *fc = fuse_get_context(); - const ugid::Set ugid(fc->uid,fc->gid); - - return l::readlink(cfg->func.readlink.policy, - cfg->branches, - fusepath_, - buf_, - size_, - cfg->symlinkify, - cfg->symlinkify_timeout); - } + Config::Read cfg; + const fuse_context *fc = fuse_get_context(); + const ugid::Set ugid(fc->uid,fc->gid); + + return ::_readlink(cfg->func.readlink.policy, + cfg->branches, + fusepath_, + buf_, + size_, + cfg->symlinkify, + cfg->symlinkify_timeout); } diff --git a/src/fuse_readlink.hpp b/src/fuse_readlink.hpp index b7e5e6f2..60966ee1 100644 --- a/src/fuse_readlink.hpp +++ b/src/fuse_readlink.hpp @@ -16,6 +16,8 @@ #pragma once +#include + namespace FUSE { diff --git a/src/fuse_release.cpp b/src/fuse_release.cpp index cc6ace63..32c1e607 100644 --- a/src/fuse_release.cpp +++ b/src/fuse_release.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fuse_release.hpp" + #include "state.hpp" #include "config.hpp" @@ -97,13 +99,10 @@ _release(const fuse_context *fc_, return ::_release(fc_,fi,cfg->dropcacheonclose); } -namespace FUSE +int +FUSE::release(const fuse_file_info_t *ffi_) { - int - release(const fuse_file_info_t *ffi_) - { - const fuse_context *fc = fuse_get_context(); + const fuse_context *fc = fuse_get_context(); - return ::_release(fc,ffi_); - } + return ::_release(fc,ffi_); } diff --git a/src/fuse_releasedir.cpp b/src/fuse_releasedir.cpp index 8a7c15c5..bdc28f8a 100644 --- a/src/fuse_releasedir.cpp +++ b/src/fuse_releasedir.cpp @@ -14,31 +14,27 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fuse_releasedir.hpp" + #include "config.hpp" #include "dirinfo.hpp" #include "fuse.h" -namespace l +static +int +_releasedir(DirInfo *di_) { - static - int - releasedir(DirInfo *di_) - { - delete di_; - - return 0; - } + delete di_; + + return 0; } -namespace FUSE +int +FUSE::releasedir(const fuse_file_info_t *ffi_) { - int - releasedir(const fuse_file_info_t *ffi_) - { - DirInfo *di = reinterpret_cast(ffi_->fh); + DirInfo *di = reinterpret_cast(ffi_->fh); - return l::releasedir(di); - } + return ::_releasedir(di); } diff --git a/src/fuse_removexattr.cpp b/src/fuse_removexattr.cpp index 916c6bd3..350b2c7c 100644 --- a/src/fuse_removexattr.cpp +++ b/src/fuse_removexattr.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fuse_removexattr.hpp" + #include "config.hpp" #include "errno.hpp" #include "fs_lremovexattr.hpp" @@ -30,90 +32,84 @@ using std::string; using std::vector; -namespace l +static +void +_removexattr_loop_core(const string &basepath_, + const char *fusepath_, + const char *attrname_, + PolicyRV *prv_) +{ + string fullpath; + + fullpath = fs::path::make(basepath_,fusepath_); + + errno = 0; + fs::lremovexattr(fullpath,attrname_); + + prv_->insert(errno,basepath_); +} + +static +void +_removexattr_loop(const std::vector &branches_, + const char *fusepath_, + const char *attrname_, + PolicyRV *prv_) +{ + for(auto &branch : branches_) + { + ::_removexattr_loop_core(branch->path,fusepath_,attrname_,prv_); + } +} + +static +int +_removexattr(const Policy::Action &actionFunc_, + const Policy::Search &searchFunc_, + const Branches &ibranches_, + const char *fusepath_, + const char *attrname_) { - static - void - removexattr_loop_core(const string &basepath_, - const char *fusepath_, - const char *attrname_, - PolicyRV *prv_) - { - string fullpath; - - fullpath = fs::path::make(basepath_,fusepath_); - - errno = 0; - fs::lremovexattr(fullpath,attrname_); - - prv_->insert(errno,basepath_); - } - - static - void - removexattr_loop(const std::vector &branches_, - const char *fusepath_, - const char *attrname_, - PolicyRV *prv_) - { - for(auto &branch : branches_) - { - l::removexattr_loop_core(branch->path,fusepath_,attrname_,prv_); - } - } - - static - int - removexattr(const Policy::Action &actionFunc_, - const Policy::Search &searchFunc_, - const Branches &ibranches_, - const char *fusepath_, - const char *attrname_) - { - int rv; - PolicyRV prv; - std::vector obranches; - - rv = actionFunc_(ibranches_,fusepath_,obranches); - if(rv == -1) - return -errno; - - l::removexattr_loop(obranches,fusepath_,attrname_,&prv); - if(prv.errors.empty()) - return 0; - if(prv.successes.empty()) - return prv.errors[0].rv; - - obranches.clear(); - rv = searchFunc_(ibranches_,fusepath_,obranches); - if(rv == -1) - return -errno; - - return prv.get_error(obranches[0]->path); - } + int rv; + PolicyRV prv; + std::vector obranches; + + rv = actionFunc_(ibranches_,fusepath_,obranches); + if(rv < 0) + return rv; + + ::_removexattr_loop(obranches,fusepath_,attrname_,&prv); + if(prv.errors.empty()) + return 0; + if(prv.successes.empty()) + return prv.errors[0].rv; + + obranches.clear(); + rv = searchFunc_(ibranches_,fusepath_,obranches); + if(rv < 0) + return rv; + + return prv.get_error(obranches[0]->path); } -namespace FUSE +int +FUSE::removexattr(const char *fusepath_, + const char *attrname_) { - int - removexattr(const char *fusepath_, - const char *attrname_) - { - Config::Read cfg; - - if(Config::is_ctrl_file(fusepath_)) - return -ENOATTR; - - if(cfg->xattr.to_int()) - return -cfg->xattr.to_int(); - - const fuse_context *fc = fuse_get_context(); - const ugid::Set ugid(fc->uid,fc->gid); - - return l::removexattr(cfg->func.removexattr.policy, - cfg->func.getxattr.policy, - cfg->branches, - fusepath_, - attrname_); - } + Config::Read cfg; + + if(Config::is_ctrl_file(fusepath_)) + return -ENOATTR; + + if(cfg->xattr.to_int()) + return -cfg->xattr.to_int(); + + const fuse_context *fc = fuse_get_context(); + const ugid::Set ugid(fc->uid,fc->gid); + + return ::_removexattr(cfg->func.removexattr.policy, + cfg->func.getxattr.policy, + cfg->branches, + fusepath_, + attrname_); } diff --git a/src/fuse_rename.cpp b/src/fuse_rename.cpp index 6baad57b..eb1b122f 100644 --- a/src/fuse_rename.cpp +++ b/src/fuse_rename.cpp @@ -14,7 +14,10 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fuse_rename.hpp" + #include "config.hpp" +#include "error.hpp" #include "errno.hpp" #include "fs_clonepath.hpp" #include "fs_link.hpp" @@ -34,359 +37,332 @@ #include -namespace error +static +bool +_contains(const std::vector &haystack_, + const char *needle_) +{ + for(auto &hay : haystack_) + { + if(hay->path == needle_) + return true; + } + + return false; +} + +static +bool +_contains(const std::vector &haystack_, + const std::string &needle_) +{ + return ::_contains(haystack_,needle_.c_str()); +} + +static +void +_remove(const StrVec &toremove_) { - static - inline - int - calc(const int rv_, - const int prev_, - const int cur_) - { - if(rv_ == -1) - { - if(prev_ == 0) - return 0; - return cur_; - } - - return 0; - } + for(auto &path : toremove_) + fs::remove(path); +} + +static +int +_rename_create_path(const Policy::Search &searchPolicy_, + const Policy::Action &actionPolicy_, + const Branches::Ptr &branches_, + const std::filesystem::path &oldfusepath_, + const std::filesystem::path &newfusepath_) +{ + int rv; + Err err; + StrVec toremove; + std::vector newbranches; + std::vector oldbranches; + std::filesystem::path oldfullpath; + std::filesystem::path newfullpath; + + rv = actionPolicy_(branches_,oldfusepath_,oldbranches); + if(rv < 0) + return rv; + + rv = searchPolicy_(branches_,newfusepath_.parent_path(),newbranches); + if(rv < 0) + return rv; + + for(auto &branch : *branches_) + { + newfullpath = branch.path; + newfullpath += newfusepath_; + + if(!::_contains(oldbranches,branch.path)) + { + toremove.push_back(newfullpath); + continue; + } + + oldfullpath = branch.path; + oldfullpath += oldfusepath_; + + rv = fs::rename(oldfullpath,newfullpath); + if(rv < 0) + { + rv = fs::clonepath_as_root(newbranches[0]->path, + branch.path, + newfusepath_.parent_path()); + if(rv >= 0) + rv = fs::rename(oldfullpath,newfullpath); + } + + err = rv; + if(rv < 0) + toremove.push_back(oldfullpath); + } + + if(err == 0) + ::_remove(toremove); + + return err; } -namespace l +static +int +_rename_preserve_path(const Policy::Action &actionPolicy_, + const Branches::Ptr &branches_, + const std::filesystem::path &oldfusepath_, + const std::filesystem::path &newfusepath_) { - static - bool - contains(const std::vector &haystack_, - const char *needle_) - { - for(auto &hay : haystack_) - { - if(hay->path == needle_) - return true; - } - - return false; - } - - static - bool - contains(const std::vector &haystack_, - const std::string &needle_) - { - return l::contains(haystack_,needle_.c_str()); - } - - static - void - remove(const StrVec &toremove_) - { - for(auto &path : toremove_) - fs::remove(path); - } - - static - int - rename_create_path(const Policy::Search &searchPolicy_, - const Policy::Action &actionPolicy_, - const Branches::Ptr &branches_, - const std::filesystem::path &oldfusepath_, - const std::filesystem::path &newfusepath_) - { - int rv; - int error; - StrVec toremove; - std::vector newbranches; - std::vector oldbranches; - std::filesystem::path oldfullpath; - std::filesystem::path newfullpath; - - rv = actionPolicy_(branches_,oldfusepath_,oldbranches); - if(rv == -1) - return -errno; - - rv = searchPolicy_(branches_,newfusepath_.parent_path(),newbranches); - if(rv == -1) - return -errno; - - error = -1; - for(auto &branch : *branches_) - { - newfullpath = branch.path; - newfullpath += newfusepath_; - - if(!l::contains(oldbranches,branch.path)) - { - toremove.push_back(newfullpath); - continue; - } - - oldfullpath = branch.path; - oldfullpath += oldfusepath_; - - rv = fs::rename(oldfullpath,newfullpath); - if(rv == -1) - { - rv = fs::clonepath_as_root(newbranches[0]->path, - branch.path, - newfusepath_.parent_path()); - if(rv == 0) - rv = fs::rename(oldfullpath,newfullpath); - } - - error = error::calc(rv,error,errno); - if(rv == -1) + int rv; + bool success; + StrVec toremove; + std::vector oldbranches; + std::filesystem::path oldfullpath; + std::filesystem::path newfullpath; + + rv = actionPolicy_(branches_,oldfusepath_,oldbranches); + if(rv < 0) + return rv; + + success = false; + for(auto &branch : *branches_) + { + newfullpath = branch.path; + newfullpath += newfusepath_; + + if(!::_contains(oldbranches,branch.path)) + { + toremove.push_back(newfullpath); + continue; + } + + oldfullpath = branch.path; + oldfullpath += oldfusepath_; + + rv = fs::rename(oldfullpath,newfullpath); + if(rv < 0) + { toremove.push_back(oldfullpath); - } - - if(error == 0) - l::remove(toremove); - - return -error; - } - - static - int - rename_preserve_path(const Policy::Action &actionPolicy_, - const Branches::Ptr &branches_, - const std::filesystem::path &oldfusepath_, - const std::filesystem::path &newfusepath_) - { - int rv; - bool success; - StrVec toremove; - std::vector oldbranches; - std::filesystem::path oldfullpath; - std::filesystem::path newfullpath; - - rv = actionPolicy_(branches_,oldfusepath_,oldbranches); - if(rv == -1) - return -errno; - - success = false; - for(auto &branch : *branches_) - { - newfullpath = branch.path; - newfullpath += newfusepath_; - - if(!l::contains(oldbranches,branch.path)) - { - toremove.push_back(newfullpath); - continue; - } - - oldfullpath = branch.path; - oldfullpath += oldfusepath_; - - rv = fs::rename(oldfullpath,newfullpath); - if(rv == -1) - { - toremove.push_back(oldfullpath); - continue; - } - - success = true; - } - - // TODO: probably should try to be nuanced here. - if(success == false) - return -EXDEV; + continue; + } - l::remove(toremove); - - return 0; - } - - static - void - rename_exdev_rename_back(const std::vector &branches_, - const std::filesystem::path &oldfusepath_) - { - std::filesystem::path oldpath; - std::filesystem::path newpath; - - for(auto &branch : branches_) - { - oldpath = branch->path; - oldpath /= ".mergerfs_rename_exdev"; - oldpath += oldfusepath_; - - newpath = branch->path; - newpath += oldfusepath_; - - fs::rename(oldpath,newpath); - } - } - - static - int - rename_exdev_rename_target(const Policy::Action &actionPolicy_, - const Branches::Ptr &ibranches_, - const std::filesystem::path &oldfusepath_, - std::vector &obranches_) - { - int rv; - std::filesystem::path clonesrc; - std::filesystem::path clonetgt; - - rv = actionPolicy_(ibranches_,oldfusepath_,obranches_); - if(rv == -1) - return -errno; - - ugid::SetRootGuard ugidGuard; - for(auto &branch : obranches_) - { - clonesrc = branch->path; - clonetgt = branch->path; - clonetgt /= ".mergerfs_rename_exdev"; - - rv = fs::clonepath(clonesrc,clonetgt,oldfusepath_.parent_path()); - if((rv == -1) && (errno == ENOENT)) - { - fs::mkdir(clonetgt,01777); - rv = fs::clonepath(clonesrc,clonetgt,oldfusepath_.parent_path()); - } - - if(rv == -1) - goto error; - - clonesrc += oldfusepath_; - clonetgt += oldfusepath_; - - rv = fs::rename(clonesrc,clonetgt); - if(rv == -1) - goto error; - } - - return 0; - - error: - l::rename_exdev_rename_back(obranches_,oldfusepath_); + success = true; + } + // TODO: probably should try to be nuanced here. + if(success == false) return -EXDEV; - } - - static - int - rename_exdev_rel_symlink(const Policy::Action &actionPolicy_, - const Branches::Ptr &branches_, - const std::filesystem::path &oldfusepath_, - const std::filesystem::path &newfusepath_) - { - int rv; - std::filesystem::path target; - std::filesystem::path linkpath; - std::vector branches; - - rv = l::rename_exdev_rename_target(actionPolicy_,branches_,oldfusepath_,branches); - if(rv < 0) - return rv; - - linkpath = newfusepath_; - target = "/.mergerfs_rename_exdev"; - target += oldfusepath_; - target = target.lexically_relative(linkpath.parent_path()); - - rv = FUSE::symlink(target.c_str(),linkpath.c_str()); - if(rv < 0) - l::rename_exdev_rename_back(branches,oldfusepath_); + ::_remove(toremove); + + return 0; +} + +static +void +_rename_exdev_rename_back(const std::vector &branches_, + const std::filesystem::path &oldfusepath_) +{ + std::filesystem::path oldpath; + std::filesystem::path newpath; + + for(auto &branch : branches_) + { + oldpath = branch->path; + oldpath /= ".mergerfs_rename_exdev"; + oldpath += oldfusepath_; + + newpath = branch->path; + newpath += oldfusepath_; + + fs::rename(oldpath,newpath); + } +} + +static +int +_rename_exdev_rename_target(const Policy::Action &actionPolicy_, + const Branches::Ptr &ibranches_, + const std::filesystem::path &oldfusepath_, + std::vector &obranches_) +{ + int rv; + std::filesystem::path clonesrc; + std::filesystem::path clonetgt; + + rv = actionPolicy_(ibranches_,oldfusepath_,obranches_); + if(rv < 0) return rv; - } - - static - int - rename_exdev_abs_symlink(const Policy::Action &actionPolicy_, - const Branches::Ptr &branches_, - const std::filesystem::path &mount_, - const std::filesystem::path &oldfusepath_, - const std::filesystem::path &newfusepath_) - { - int rv; - std::filesystem::path target; - std::filesystem::path linkpath; - std::vector branches; - - rv = l::rename_exdev_rename_target(actionPolicy_,branches_,oldfusepath_,branches); - if(rv < 0) - return rv; - - linkpath = newfusepath_; - target = mount_; - target /= ".mergerfs_rename_exdev"; - target += oldfusepath_; - - rv = FUSE::symlink(target.c_str(),linkpath.c_str()); - if(rv < 0) - l::rename_exdev_rename_back(branches,oldfusepath_); + ugid::SetRootGuard ugidGuard; + for(auto &branch : obranches_) + { + clonesrc = branch->path; + clonetgt = branch->path; + clonetgt /= ".mergerfs_rename_exdev"; + + rv = fs::clonepath(clonesrc,clonetgt,oldfusepath_.parent_path()); + if(rv == -ENOENT) + { + fs::mkdir(clonetgt,01777); + rv = fs::clonepath(clonesrc,clonetgt,oldfusepath_.parent_path()); + } + + if(rv < 0) + goto error; + + clonesrc += oldfusepath_; + clonetgt += oldfusepath_; + + rv = fs::rename(clonesrc,clonetgt); + if(rv < 0) + goto error; + } + + return 0; + + error: + ::_rename_exdev_rename_back(obranches_,oldfusepath_); + + return -EXDEV; +} + +static +int +_rename_exdev_rel_symlink(const Policy::Action &actionPolicy_, + const Branches::Ptr &branches_, + const std::filesystem::path &oldfusepath_, + const std::filesystem::path &newfusepath_) +{ + int rv; + std::filesystem::path target; + std::filesystem::path linkpath; + std::vector branches; + + rv = ::_rename_exdev_rename_target(actionPolicy_,branches_,oldfusepath_,branches); + if(rv < 0) return rv; - } - - static - int - rename_exdev(Config::Read &cfg_, - const std::filesystem::path &oldfusepath_, - const std::filesystem::path &newfusepath_) - { - switch(cfg_->rename_exdev) - { - case RenameEXDEV::ENUM::PASSTHROUGH: - return -EXDEV; - case RenameEXDEV::ENUM::REL_SYMLINK: - return l::rename_exdev_rel_symlink(cfg_->func.rename.policy, - cfg_->branches, - oldfusepath_, - newfusepath_); - case RenameEXDEV::ENUM::ABS_SYMLINK: - return l::rename_exdev_abs_symlink(cfg_->func.rename.policy, - cfg_->branches, - cfg_->mountpoint, - oldfusepath_, - newfusepath_); - } - return -EXDEV; - } - - static - int - rename(Config::Read &cfg_, - const std::filesystem::path &oldpath_, - const std::filesystem::path &newpath_) - { - if(cfg_->func.create.policy.path_preserving() && !cfg_->ignorepponrename) - return l::rename_preserve_path(cfg_->func.rename.policy, - cfg_->branches, - oldpath_, - newpath_); - - return l::rename_create_path(cfg_->func.getattr.policy, - cfg_->func.rename.policy, - cfg_->branches, - oldpath_, - newpath_); - } + linkpath = newfusepath_; + target = "/.mergerfs_rename_exdev"; + target += oldfusepath_; + target = target.lexically_relative(linkpath.parent_path()); + + rv = FUSE::symlink(target.c_str(),linkpath.c_str()); + if(rv < 0) + ::_rename_exdev_rename_back(branches,oldfusepath_); + + return rv; } -namespace FUSE +static +int +_rename_exdev_abs_symlink(const Policy::Action &actionPolicy_, + const Branches::Ptr &branches_, + const std::filesystem::path &mount_, + const std::filesystem::path &oldfusepath_, + const std::filesystem::path &newfusepath_) { - int - rename(const char *oldfusepath_, - const char *newfusepath_) - { - int rv; - Config::Read cfg; - std::filesystem::path oldfusepath(oldfusepath_); - std::filesystem::path newfusepath(newfusepath_); - const fuse_context *fc = fuse_get_context(); - const ugid::Set ugid(fc->uid,fc->gid); - - rv = l::rename(cfg,oldfusepath,newfusepath); - if(rv == -EXDEV) - return l::rename_exdev(cfg,oldfusepath,newfusepath); + int rv; + std::filesystem::path target; + std::filesystem::path linkpath; + std::vector branches; + rv = ::_rename_exdev_rename_target(actionPolicy_,branches_,oldfusepath_,branches); + if(rv < 0) return rv; - } + + linkpath = newfusepath_; + target = mount_; + target /= ".mergerfs_rename_exdev"; + target += oldfusepath_; + + rv = FUSE::symlink(target.c_str(),linkpath.c_str()); + if(rv < 0) + ::_rename_exdev_rename_back(branches,oldfusepath_); + + return rv; +} + +static +int +_rename_exdev(Config::Read &cfg_, + const std::filesystem::path &oldfusepath_, + const std::filesystem::path &newfusepath_) +{ + switch(cfg_->rename_exdev) + { + case RenameEXDEV::ENUM::PASSTHROUGH: + return -EXDEV; + case RenameEXDEV::ENUM::REL_SYMLINK: + return ::_rename_exdev_rel_symlink(cfg_->func.rename.policy, + cfg_->branches, + oldfusepath_, + newfusepath_); + case RenameEXDEV::ENUM::ABS_SYMLINK: + return ::_rename_exdev_abs_symlink(cfg_->func.rename.policy, + cfg_->branches, + cfg_->mountpoint, + oldfusepath_, + newfusepath_); + } + + return -EXDEV; +} + +static +int +_rename(Config::Read &cfg_, + const std::filesystem::path &oldpath_, + const std::filesystem::path &newpath_) +{ + if(cfg_->func.create.policy.path_preserving() && !cfg_->ignorepponrename) + return ::_rename_preserve_path(cfg_->func.rename.policy, + cfg_->branches, + oldpath_, + newpath_); + + return ::_rename_create_path(cfg_->func.getattr.policy, + cfg_->func.rename.policy, + cfg_->branches, + oldpath_, + newpath_); +} + +int +FUSE::rename(const char *oldfusepath_, + const char *newfusepath_) +{ + int rv; + Config::Read cfg; + std::filesystem::path oldfusepath(oldfusepath_); + std::filesystem::path newfusepath(newfusepath_); + const fuse_context *fc = fuse_get_context(); + const ugid::Set ugid(fc->uid,fc->gid); + + rv = ::_rename(cfg,oldfusepath,newfusepath); + if(rv == -EXDEV) + return ::_rename_exdev(cfg,oldfusepath,newfusepath); + + return rv; } diff --git a/src/fuse_rmdir.cpp b/src/fuse_rmdir.cpp index 1b93ea4f..fd72ced3 100644 --- a/src/fuse_rmdir.cpp +++ b/src/fuse_rmdir.cpp @@ -14,8 +14,11 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fuse_rmdir.hpp" + #include "config.hpp" #include "errno.hpp" +#include "error.hpp" #include "fs_path.hpp" #include "fs_rmdir.hpp" #include "fs_unlink.hpp" @@ -31,101 +34,75 @@ using std::string; using std::vector; -namespace error +static +int +_should_unlink(int rv_, + FollowSymlinks followsymlinks_) +{ + return ((rv_ == -ENOTDIR) && + (followsymlinks_ != FollowSymlinks::ENUM::NEVER)); +} + +static +int +_rmdir_core(const string &basepath_, + const char *fusepath_, + const FollowSymlinks followsymlinks_) +{ + int rv; + string fullpath; + + fullpath = fs::path::make(basepath_,fusepath_); + + rv = fs::rmdir(fullpath); + if(::_should_unlink(rv,followsymlinks_)) + rv = fs::unlink(fullpath); + + return rv; +} + +static +int +_rmdir_loop(const std::vector &branches_, + const char *fusepath_, + const FollowSymlinks followsymlinks_) { - static - int - calc(const int rv_, - const int prev_, - const int cur_) - { - if(prev_ != 0) - return prev_; - if(rv_ == -1) - return cur_; - return 0; - } + Err err; + + for(auto &branch : branches_) + { + err = ::_rmdir_core(branch->path,fusepath_,followsymlinks_); + } + + return err; } -namespace l +static +int +_rmdir(const Policy::Action &actionFunc_, + const Branches &branches_, + const FollowSymlinks followsymlinks_, + const char *fusepath_) { - static - int - should_unlink(int rv_, - int errno_, - FollowSymlinks followsymlinks_) - { - return ((rv_ == -1) && - (errno_ == ENOTDIR) && - (followsymlinks_ != FollowSymlinks::ENUM::NEVER)); - } - - static - int - rmdir_core(const string &basepath_, - const char *fusepath_, - const FollowSymlinks followsymlinks_, - const int error_) - { - int rv; - string fullpath; - - fullpath = fs::path::make(basepath_,fusepath_); - - rv = fs::rmdir(fullpath); - if(l::should_unlink(rv,errno,followsymlinks_)) - rv = fs::unlink(fullpath); - - return error::calc(rv,error_,errno); - } - - static - int - rmdir_loop(const std::vector &branches_, - const char *fusepath_, - const FollowSymlinks followsymlinks_) - { - int error; - - error = 0; - for(auto &branch : branches_) - { - error = l::rmdir_core(branch->path,fusepath_,followsymlinks_,error); - } - - return -error; - } - - static - int - rmdir(const Policy::Action &actionFunc_, - const Branches &branches_, - const FollowSymlinks followsymlinks_, - const char *fusepath_) - { - int rv; - std::vector branches; - - rv = actionFunc_(branches_,fusepath_,branches); - if(rv == -1) - return -errno; - - return l::rmdir_loop(branches,fusepath_,followsymlinks_); - } + int rv; + std::vector branches; + + rv = actionFunc_(branches_,fusepath_,branches); + if(rv < 0) + return rv; + + return ::_rmdir_loop(branches,fusepath_,followsymlinks_); } -namespace FUSE +int +FUSE::rmdir(const char *fusepath_) { - int - rmdir(const char *fusepath_) - { - Config::Read cfg; - const fuse_context *fc = fuse_get_context(); - const ugid::Set ugid(fc->uid,fc->gid); - - return l::rmdir(cfg->func.rmdir.policy, - cfg->branches, - cfg->follow_symlinks, - fusepath_); - } + Config::Read cfg; + const fuse_context *fc = fuse_get_context(); + const ugid::Set ugid(fc->uid,fc->gid); + + return ::_rmdir(cfg->func.rmdir.policy, + cfg->branches, + cfg->follow_symlinks, + fusepath_); } diff --git a/src/fuse_setxattr.cpp b/src/fuse_setxattr.cpp index 105c34d3..73072014 100644 --- a/src/fuse_setxattr.cpp +++ b/src/fuse_setxattr.cpp @@ -163,8 +163,8 @@ _setxattr(const Policy::Action &setxattrPolicy_, std::vector branches; rv = setxattrPolicy_(branches_,fusepath_,branches); - if(rv == -1) - return -errno; + if(rv < 0) + return rv; ::_setxattr_loop(branches,fusepath_,attrname_,attrval_,attrvalsize_,flags_,&prv); if(prv.errors.empty()) @@ -174,8 +174,8 @@ _setxattr(const Policy::Action &setxattrPolicy_, branches.clear(); rv = getxattrPolicy_(branches_,fusepath_,branches); - if(rv == -1) - return -errno; + if(rv < 0) + return rv; return prv.get_error(branches[0]->path); } diff --git a/src/fuse_statfs.cpp b/src/fuse_statfs.cpp index b6642bbc..3869f3f6 100644 --- a/src/fuse_statfs.cpp +++ b/src/fuse_statfs.cpp @@ -14,11 +14,13 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fuse_statfs.hpp" + #include "config.hpp" #include "errno.hpp" #include "fs_lstat.hpp" #include "fs_path.hpp" -#include "fs_statvfs.hpp" +#include "fs_lstatvfs.hpp" #include "statvfs_util.hpp" #include "ugid.hpp" @@ -35,130 +37,124 @@ using std::map; using std::vector; -namespace l +static +void +_normalize_statvfs(struct statvfs *fsstat_, + const unsigned long min_bsize_, + const unsigned long min_frsize_, + const unsigned long min_namemax_) +{ + fsstat_->f_blocks = (fsblkcnt_t)((fsstat_->f_blocks * fsstat_->f_frsize) / min_frsize_); + fsstat_->f_bfree = (fsblkcnt_t)((fsstat_->f_bfree * fsstat_->f_frsize) / min_frsize_); + fsstat_->f_bavail = (fsblkcnt_t)((fsstat_->f_bavail * fsstat_->f_frsize) / min_frsize_); + fsstat_->f_bsize = min_bsize_; + fsstat_->f_frsize = min_frsize_; + fsstat_->f_namemax = min_namemax_; +} + +static +void +_merge_statvfs(struct statvfs * const out_, + const struct statvfs * const in_) +{ + out_->f_blocks += in_->f_blocks; + out_->f_bfree += in_->f_bfree; + out_->f_bavail += in_->f_bavail; + + out_->f_files += in_->f_files; + out_->f_ffree += in_->f_ffree; + out_->f_favail += in_->f_favail; +} + +static +bool +_should_ignore(const StatFSIgnore ignore_, + const Branch &branch_, + const bool readonly_) +{ + return ((((ignore_ == StatFSIgnore::ENUM::RO) || readonly_) && + (branch_.ro_or_nc())) || + ((ignore_ == StatFSIgnore::ENUM::NC) && (branch_.nc()))); +} + +static +int +_statfs(const Branches::Ptr &branches_, + const char *fusepath_, + const StatFS mode_, + const StatFSIgnore ignore_, + struct statvfs *fsstat_) { - static - void - normalize_statvfs(struct statvfs *fsstat_, - const unsigned long min_bsize_, - const unsigned long min_frsize_, - const unsigned long min_namemax_) - { - fsstat_->f_blocks = (fsblkcnt_t)((fsstat_->f_blocks * fsstat_->f_frsize) / min_frsize_); - fsstat_->f_bfree = (fsblkcnt_t)((fsstat_->f_bfree * fsstat_->f_frsize) / min_frsize_); - fsstat_->f_bavail = (fsblkcnt_t)((fsstat_->f_bavail * fsstat_->f_frsize) / min_frsize_); - fsstat_->f_bsize = min_bsize_; - fsstat_->f_frsize = min_frsize_; - fsstat_->f_namemax = min_namemax_; - } - - static - void - merge_statvfs(struct statvfs * const out_, - const struct statvfs * const in_) - { - out_->f_blocks += in_->f_blocks; - out_->f_bfree += in_->f_bfree; - out_->f_bavail += in_->f_bavail; - - out_->f_files += in_->f_files; - out_->f_ffree += in_->f_ffree; - out_->f_favail += in_->f_favail; - } - - static - bool - should_ignore(const StatFSIgnore ignore_, - const Branch &branch_, - const bool readonly_) - { - return ((((ignore_ == StatFSIgnore::ENUM::RO) || readonly_) && - (branch_.ro_or_nc())) || - ((ignore_ == StatFSIgnore::ENUM::NC) && (branch_.nc()))); - } - - static - int - statfs(const Branches::Ptr &branches_, - const char *fusepath_, - const StatFS mode_, - const StatFSIgnore ignore_, - struct statvfs *fsstat_) - { - int rv; - string fullpath; - struct stat st; - struct statvfs stvfs; - unsigned long min_bsize; - unsigned long min_frsize; - unsigned long min_namemax; - map fsstats; - - min_bsize = std::numeric_limits::max(); - min_frsize = std::numeric_limits::max(); - min_namemax = std::numeric_limits::max(); - for(const auto &branch : *branches_) - { - fullpath = ((mode_ == StatFS::ENUM::FULL) ? - fs::path::make(branch.path,fusepath_) : - branch.path); - - rv = fs::lstat(fullpath,&st); - if(rv == -1) - continue; - - rv = fs::lstatvfs(fullpath,&stvfs); - if(rv == -1) - continue; - - if(stvfs.f_bsize && (min_bsize > stvfs.f_bsize)) - min_bsize = stvfs.f_bsize; - if(stvfs.f_frsize && (min_frsize > stvfs.f_frsize)) - min_frsize = stvfs.f_frsize; - if(stvfs.f_namemax && (min_namemax > stvfs.f_namemax)) - min_namemax = stvfs.f_namemax; - - if(l::should_ignore(ignore_,branch,StatVFS::readonly(stvfs))) - { - stvfs.f_bavail = 0; - stvfs.f_favail = 0; - } - - fsstats.insert(std::make_pair(st.st_dev,stvfs)); - } - - map::iterator iter = fsstats.begin(); - map::iterator enditer = fsstats.end(); - if(iter != enditer) - { - *fsstat_ = iter->second; - l::normalize_statvfs(fsstat_,min_bsize,min_frsize,min_namemax); - - for(++iter; iter != enditer; ++iter) - { - l::normalize_statvfs(&iter->second,min_bsize,min_frsize,min_namemax); - l::merge_statvfs(fsstat_,&iter->second); - } - } - - return 0; - } + int rv; + string fullpath; + struct stat st; + struct statvfs stvfs; + unsigned long min_bsize; + unsigned long min_frsize; + unsigned long min_namemax; + map fsstats; + + min_bsize = std::numeric_limits::max(); + min_frsize = std::numeric_limits::max(); + min_namemax = std::numeric_limits::max(); + for(const auto &branch : *branches_) + { + fullpath = ((mode_ == StatFS::ENUM::FULL) ? + fs::path::make(branch.path,fusepath_) : + branch.path); + + rv = fs::lstat(fullpath,&st); + if(rv < 0) + continue; + + rv = fs::lstatvfs(fullpath,&stvfs); + if(rv < 0) + continue; + + if(stvfs.f_bsize && (min_bsize > stvfs.f_bsize)) + min_bsize = stvfs.f_bsize; + if(stvfs.f_frsize && (min_frsize > stvfs.f_frsize)) + min_frsize = stvfs.f_frsize; + if(stvfs.f_namemax && (min_namemax > stvfs.f_namemax)) + min_namemax = stvfs.f_namemax; + + if(::_should_ignore(ignore_,branch,StatVFS::readonly(stvfs))) + { + stvfs.f_bavail = 0; + stvfs.f_favail = 0; + } + + fsstats.insert(std::make_pair(st.st_dev,stvfs)); + } + + map::iterator iter = fsstats.begin(); + map::iterator enditer = fsstats.end(); + if(iter != enditer) + { + *fsstat_ = iter->second; + ::_normalize_statvfs(fsstat_,min_bsize,min_frsize,min_namemax); + + for(++iter; iter != enditer; ++iter) + { + ::_normalize_statvfs(&iter->second,min_bsize,min_frsize,min_namemax); + ::_merge_statvfs(fsstat_,&iter->second); + } + } + + return 0; } -namespace FUSE +int +FUSE::statfs(const char *fusepath_, + struct statvfs *st_) { - int - statfs(const char *fusepath_, - struct statvfs *st_) - { - Config::Read cfg; - const fuse_context *fc = fuse_get_context(); - const ugid::Set ugid(fc->uid,fc->gid); - - return l::statfs(cfg->branches, - fusepath_, - cfg->statfs, - cfg->statfs_ignore, - st_); - } + Config::Read cfg; + const fuse_context *fc = fuse_get_context(); + const ugid::Set ugid(fc->uid,fc->gid); + + return ::_statfs(cfg->branches, + fusepath_, + cfg->statfs, + cfg->statfs_ignore, + st_); } diff --git a/src/fuse_statx_supported.icpp b/src/fuse_statx_supported.icpp index 9f90e176..33731f59 100644 --- a/src/fuse_statx_supported.icpp +++ b/src/fuse_statx_supported.icpp @@ -129,8 +129,8 @@ _statx(const Policy::Search &searchFunc_, std::vector branches; rv = searchFunc_(branches_,fusepath_,branches); - if(rv == -1) - return -errno; + if(rv < 0) + return rv; fullpath = fs::path::make(branches[0]->path,fusepath_); diff --git a/src/fuse_symlink.cpp b/src/fuse_symlink.cpp index 2b416a15..a09fd87e 100644 --- a/src/fuse_symlink.cpp +++ b/src/fuse_symlink.cpp @@ -14,8 +14,11 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fuse_symlink.hpp" + #include "config.hpp" #include "errno.hpp" +#include "error.hpp" #include "fs_clonepath.hpp" #include "fs_lstat.hpp" #include "fs_path.hpp" @@ -34,163 +37,134 @@ using std::string; -namespace error +static +int +_symlink_loop_core(const std::string &newbranch_, + const char *target_, + const char *linkpath_, + struct stat *st_) { - static - inline - int - calc(const int rv_, - const int prev_, - const int cur_) - { - if(rv_ == -1) - { - if(prev_ == 0) - return 0; - return cur_; - } - - return 0; - } + int rv; + string fullnewpath; + + fullnewpath = fs::path::make(newbranch_,linkpath_); + + rv = fs::symlink(target_,fullnewpath); + if((rv >= 0) && (st_ != NULL) && (st_->st_ino == 0)) + { + fs::lstat(fullnewpath,st_); + if(st_->st_ino != 0) + fs::inode::calc(newbranch_,linkpath_,st_); + } + + return rv; } -namespace l +static +int +_symlink_loop(const std::string &existingbranch_, + const std::vector &newbranches_, + const char *target_, + const char *linkpath_, + const std::string &newdirpath_, + struct stat *st_) { - static - int - symlink_loop_core(const std::string &newbranch_, - const char *target_, - const char *linkpath_, - struct stat *st_, - const int error_) - { - int rv; - string fullnewpath; - - fullnewpath = fs::path::make(newbranch_,linkpath_); - - rv = fs::symlink(target_,fullnewpath); - if((rv != -1) && (st_ != NULL) && (st_->st_ino == 0)) - { - fs::lstat(fullnewpath,st_); - if(st_->st_ino != 0) - fs::inode::calc(newbranch_,linkpath_,st_); - } - - return error::calc(rv,error_,errno); - } - - static - int - symlink_loop(const std::string &existingbranch_, - const std::vector &newbranches_, - const char *target_, - const char *linkpath_, - const std::string &newdirpath_, - struct stat *st_) - { - int rv; - int error; - - error = -1; - for(auto &newbranch :newbranches_) - { - rv = fs::clonepath_as_root(existingbranch_, - newbranch->path, - newdirpath_); - if(rv == -1) - error = error::calc(rv,error,errno); - else - error = l::symlink_loop_core(newbranch->path, - target_, - linkpath_, - st_, - error); - } - - return -error; - } - - static - int - symlink(const Policy::Search &searchFunc_, - const Policy::Create &createFunc_, - const Branches &branches_, - const char *target_, - const char *linkpath_, - struct stat *st_) - { - int rv; - string newdirpath; - std::vector newbranches; - std::vector existingbranches; - - newdirpath = fs::path::dirname(linkpath_); - - rv = searchFunc_(branches_,newdirpath,existingbranches); - if(rv == -1) - return -errno; - - rv = createFunc_(branches_,newdirpath,newbranches); - if(rv == -1) - return -errno; - - return l::symlink_loop(existingbranches[0]->path, - newbranches, - target_, - linkpath_, - newdirpath, - st_); - } + int rv; + Err err; + + for(auto &newbranch :newbranches_) + { + rv = fs::clonepath_as_root(existingbranch_, + newbranch->path, + newdirpath_); + if(rv < 0) + err = rv; + else + err = ::_symlink_loop_core(newbranch->path, + target_, + linkpath_, + st_); + } + + return err; } -namespace FUSE +static +int +_symlink(const Policy::Search &searchFunc_, + const Policy::Create &createFunc_, + const Branches &branches_, + const char *target_, + const char *linkpath_, + struct stat *st_) { - int - symlink(const char *target_, - const char *linkpath_, - struct stat *st_, - fuse_timeouts_t *timeouts_) - { - int rv; - Config::Read cfg; - const fuse_context *fc = fuse_get_context(); - const ugid::Set ugid(fc->uid,fc->gid); - - rv = l::symlink(cfg->func.getattr.policy, - cfg->func.symlink.policy, - cfg->branches, - target_, - linkpath_, - st_); - if(rv == -EROFS) - { - Config::Write()->branches.find_and_set_mode_ro(); - rv = l::symlink(cfg->func.getattr.policy, - cfg->func.symlink.policy, - cfg->branches, - target_, - linkpath_, - st_); - } - - if(timeouts_ != NULL) - { - switch(cfg->follow_symlinks) - { - case FollowSymlinks::ENUM::NEVER: - timeouts_->entry = ((rv >= 0) ? - cfg->cache_entry : - cfg->cache_negative_entry); - timeouts_->attr = cfg->cache_attr; - break; - default: - timeouts_->entry = 0; - timeouts_->attr = 0; - break; - } - } + int rv; + string newdirpath; + std::vector newbranches; + std::vector existingbranches; + + newdirpath = fs::path::dirname(linkpath_); + rv = searchFunc_(branches_,newdirpath,existingbranches); + if(rv < 0) return rv; - } + + rv = createFunc_(branches_,newdirpath,newbranches); + if(rv < 0) + return rv; + + return ::_symlink_loop(existingbranches[0]->path, + newbranches, + target_, + linkpath_, + newdirpath, + st_); +} + +int +FUSE::symlink(const char *target_, + const char *linkpath_, + struct stat *st_, + fuse_timeouts_t *timeouts_) +{ + int rv; + Config::Read cfg; + const fuse_context *fc = fuse_get_context(); + const ugid::Set ugid(fc->uid,fc->gid); + + rv = ::_symlink(cfg->func.getattr.policy, + cfg->func.symlink.policy, + cfg->branches, + target_, + linkpath_, + st_); + if(rv == -EROFS) + { + Config::Write()->branches.find_and_set_mode_ro(); + rv = ::_symlink(cfg->func.getattr.policy, + cfg->func.symlink.policy, + cfg->branches, + target_, + linkpath_, + st_); + } + + if(timeouts_ != NULL) + { + switch(cfg->follow_symlinks) + { + case FollowSymlinks::ENUM::NEVER: + timeouts_->entry = ((rv >= 0) ? + cfg->cache_entry : + cfg->cache_negative_entry); + timeouts_->attr = cfg->cache_attr; + break; + default: + timeouts_->entry = 0; + timeouts_->attr = 0; + break; + } + } + + return rv; } diff --git a/src/fuse_truncate.cpp b/src/fuse_truncate.cpp index 9cc782c0..ec645069 100644 --- a/src/fuse_truncate.cpp +++ b/src/fuse_truncate.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fuse_truncate.hpp" + #include "config.hpp" #include "errno.hpp" #include "fs_path.hpp" @@ -31,83 +33,77 @@ using std::string; -namespace l +static +void +_truncate_loop_core(const string &basepath_, + const char *fusepath_, + const off_t size_, + PolicyRV *prv_) +{ + int rv; + string fullpath; + + fullpath = fs::path::make(basepath_,fusepath_); + + rv = fs::truncate(fullpath,size_); + + prv_->insert(rv,basepath_); +} + +static +void +_truncate_loop(const std::vector &branches_, + const char *fusepath_, + const off_t size_, + PolicyRV *prv_) +{ + for(auto &branch : branches_) + { + ::_truncate_loop_core(branch->path,fusepath_,size_,prv_); + } +} + +static +int +_truncate(const Policy::Action &actionFunc_, + const Policy::Search &searchFunc_, + const Branches &branches_, + const char *fusepath_, + const off_t size_) { - static - void - truncate_loop_core(const string &basepath_, - const char *fusepath_, - const off_t size_, - PolicyRV *prv_) - { - string fullpath; - - fullpath = fs::path::make(basepath_,fusepath_); - - errno = 0; - fs::truncate(fullpath,size_); - - prv_->insert(errno,basepath_); - } - - static - void - truncate_loop(const std::vector &branches_, - const char *fusepath_, - const off_t size_, - PolicyRV *prv_) - { - for(auto &branch : branches_) - { - l::truncate_loop_core(branch->path,fusepath_,size_,prv_); - } - } - - static - int - truncate(const Policy::Action &actionFunc_, - const Policy::Search &searchFunc_, - const Branches &branches_, - const char *fusepath_, - const off_t size_) - { - int rv; - PolicyRV prv; - std::vector branches; - - rv = actionFunc_(branches_,fusepath_,branches); - if(rv == -1) - return -errno; - - l::truncate_loop(branches,fusepath_,size_,&prv); - if(prv.errors.empty()) - return 0; - if(prv.successes.empty()) - return prv.errors[0].rv; - - branches.clear(); - rv = searchFunc_(branches_,fusepath_,branches); - if(rv == -1) - return -errno; - - return prv.get_error(branches[0]->path); - } + int rv; + PolicyRV prv; + std::vector branches; + + rv = actionFunc_(branches_,fusepath_,branches); + if(rv < 0) + return rv; + + ::_truncate_loop(branches,fusepath_,size_,&prv); + if(prv.errors.empty()) + return 0; + if(prv.successes.empty()) + return prv.errors[0].rv; + + branches.clear(); + rv = searchFunc_(branches_,fusepath_,branches); + if(rv < 0) + return rv; + + return prv.get_error(branches[0]->path); } -namespace FUSE +int +FUSE::truncate(const char *fusepath_, + off_t size_) { - int - truncate(const char *fusepath_, - off_t size_) - { - Config::Read cfg; - const fuse_context *fc = fuse_get_context(); - const ugid::Set ugid(fc->uid,fc->gid); - - return l::truncate(cfg->func.truncate.policy, - cfg->func.getattr.policy, - cfg->branches, - fusepath_, - size_); - } + Config::Read cfg; + const fuse_context *fc = fuse_get_context(); + const ugid::Set ugid(fc->uid,fc->gid); + + return ::_truncate(cfg->func.truncate.policy, + cfg->func.getattr.policy, + cfg->branches, + fusepath_, + size_); } diff --git a/src/fuse_unlink.cpp b/src/fuse_unlink.cpp index ff4c4a03..0069dfa3 100644 --- a/src/fuse_unlink.cpp +++ b/src/fuse_unlink.cpp @@ -14,8 +14,11 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fuse_unlink.hpp" + #include "config.hpp" #include "errno.hpp" +#include "error.hpp" #include "fs_path.hpp" #include "fs_unlink.hpp" #include "ugid.hpp" @@ -28,85 +31,48 @@ #include -namespace error +static +int +_unlink_loop(const std::vector &branches_, + const char *fusepath_) { - static - inline - int - calc(const int rv_, - const int prev_, - const int cur_) - { - if(prev_ != 0) - return prev_; - if(rv_ == -1) - return cur_; - return 0; - } + Err err; + std::string fullpath; + + for(const auto &branch : branches_) + { + fullpath = fs::path::make(branch->path,fusepath_); + + err = fs::unlink(fullpath); + } + + return err; } -namespace l +static +int +_unlink(const Policy::Action &unlinkPolicy_, + const Branches &branches_, + const char *fusepath_) { - static - int - unlink_loop_core(const std::string &branch_, - const char *fusepath_, - const int error_) - { - int rv; - std::string fullpath; - - fullpath = fs::path::make(branch_,fusepath_); - - rv = fs::unlink(fullpath); - - return error::calc(rv,error_,errno); - } - - static - int - unlink_loop(const std::vector &branches_, - const char *fusepath_) - { - int error; - - error = 0; - for(auto &branch : branches_) - { - error = l::unlink_loop_core(branch->path,fusepath_,error); - } - - return -error; - } - - static - int - unlink(const Policy::Action &unlinkPolicy_, - const Branches &branches_, - const char *fusepath_) - { - int rv; - std::vector branches; - - rv = unlinkPolicy_(branches_,fusepath_,branches); - if(rv == -1) - return -errno; - - return l::unlink_loop(branches,fusepath_); - } + int rv; + std::vector branches; + + rv = unlinkPolicy_(branches_,fusepath_,branches); + if(rv < 0) + return rv; + + return ::_unlink_loop(branches,fusepath_); } -namespace FUSE +int +FUSE::unlink(const char *fusepath_) { - int - unlink(const char *fusepath_) - { - Config::Read cfg; - const fuse_context *fc = fuse_get_context(); - const ugid::Set ugid(fc->uid,fc->gid); - - return l::unlink(cfg->func.unlink.policy, - cfg->branches, - fusepath_); - } + Config::Read cfg; + const fuse_context *fc = fuse_get_context(); + const ugid::Set ugid(fc->uid,fc->gid); + + return ::_unlink(cfg->func.unlink.policy, + cfg->branches, + fusepath_); } diff --git a/src/fuse_utimens.cpp b/src/fuse_utimens.cpp index 11ec58d3..a936dd32 100644 --- a/src/fuse_utimens.cpp +++ b/src/fuse_utimens.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fuse_utimens.hpp" + #include "config.hpp" #include "errno.hpp" #include "fs_lutimens.hpp" @@ -30,83 +32,77 @@ using std::string; -namespace l +static +void +_utimens_loop_core(const string &basepath_, + const char *fusepath_, + const timespec ts_[2], + PolicyRV *prv_) +{ + int rv; + string fullpath; + + fullpath = fs::path::make(basepath_,fusepath_); + + rv = fs::lutimens(fullpath,ts_); + + prv_->insert(rv,basepath_); +} + +static +void +_utimens_loop(const std::vector &branches_, + const char *fusepath_, + const timespec ts_[2], + PolicyRV *prv_) +{ + for(auto &branch : branches_) + { + ::_utimens_loop_core(branch->path,fusepath_,ts_,prv_); + } +} + +static +int +_utimens(const Policy::Action &utimensPolicy_, + const Policy::Search &getattrPolicy_, + const Branches &branches_, + const char *fusepath_, + const timespec ts_[2]) { - static - void - utimens_loop_core(const string &basepath_, - const char *fusepath_, - const timespec ts_[2], - PolicyRV *prv_) - { - string fullpath; - - fullpath = fs::path::make(basepath_,fusepath_); - - errno = 0; - fs::lutimens(fullpath,ts_); - - prv_->insert(errno,basepath_); - } - - static - void - utimens_loop(const std::vector &branches_, - const char *fusepath_, - const timespec ts_[2], - PolicyRV *prv_) - { - for(auto &branch : branches_) - { - l::utimens_loop_core(branch->path,fusepath_,ts_,prv_); - } - } - - static - int - utimens(const Policy::Action &utimensPolicy_, - const Policy::Search &getattrPolicy_, - const Branches &branches_, - const char *fusepath_, - const timespec ts_[2]) - { - int rv; - PolicyRV prv; - std::vector branches; - - rv = utimensPolicy_(branches_,fusepath_,branches); - if(rv == -1) - return -errno; - - l::utimens_loop(branches,fusepath_,ts_,&prv); - if(prv.errors.empty()) - return 0; - if(prv.successes.empty()) - return prv.errors[0].rv; - - branches.clear(); - rv = getattrPolicy_(branches_,fusepath_,branches); - if(rv == -1) - return -errno; - - return prv.get_error(branches[0]->path); - } + int rv; + PolicyRV prv; + std::vector branches; + + rv = utimensPolicy_(branches_,fusepath_,branches); + if(rv < 0) + return rv; + + ::_utimens_loop(branches,fusepath_,ts_,&prv); + if(prv.errors.empty()) + return 0; + if(prv.successes.empty()) + return prv.errors[0].rv; + + branches.clear(); + rv = getattrPolicy_(branches_,fusepath_,branches); + if(rv < 0) + return rv; + + return prv.get_error(branches[0]->path); } -namespace FUSE +int +FUSE::utimens(const char *fusepath_, + const timespec ts_[2]) { - int - utimens(const char *fusepath_, - const timespec ts_[2]) - { - Config::Read cfg; - const fuse_context *fc = fuse_get_context(); - const ugid::Set ugid(fc->uid,fc->gid); - - return l::utimens(cfg->func.utimens.policy, - cfg->func.getattr.policy, - cfg->branches, - fusepath_, - ts_); - } + Config::Read cfg; + const fuse_context *fc = fuse_get_context(); + const ugid::Set ugid(fc->uid,fc->gid); + + return ::_utimens(cfg->func.utimens.policy, + cfg->func.getattr.policy, + cfg->branches, + fusepath_, + ts_); } diff --git a/src/fuse_write.cpp b/src/fuse_write.cpp index 70b04cca..d8301f97 100644 --- a/src/fuse_write.cpp +++ b/src/fuse_write.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fuse_write.hpp" + #include "config.hpp" #include "errno.hpp" #include "fileinfo.hpp" @@ -26,181 +28,175 @@ #include "fuse.h" -namespace l +static +bool +_out_of_space(const ssize_t err_) { - static - bool - out_of_space(const ssize_t error_) - { - return ((error_ == -ENOSPC) || - (error_ == -EDQUOT)); - } - - static - int - move_and_pwrite(const char *buf_, - const size_t count_, - const off_t offset_, - FileInfo *fi_, - int err_) - { - int err; - ssize_t rv; - Config::Read cfg; - - if(cfg->moveonenospc.enabled == false) - return err_; - - rv = fs::movefile_and_open_as_root(cfg->moveonenospc.policy, - cfg->branches, - fi_->branch.path, - fi_->fusepath, - fi_->fd); - if(rv < 0) - return err_; - - err = fs::dup2(rv,fi_->fd); - fs::close(rv); - if(err < 0) - return err_; - - return fs::pwrite(fi_->fd,buf_,count_,offset_); - } - - static - int - move_and_pwriten(char const *buf_, - size_t const count_, - off_t const offset_, - FileInfo *fi_, - ssize_t const err_, - ssize_t const written_) - { - int err; - ssize_t rv; - Config::Read cfg; - - if(cfg->moveonenospc.enabled == false) - return err_; - - rv = fs::movefile_and_open_as_root(cfg->moveonenospc.policy, - cfg->branches, - fi_->branch.path, - fi_->fusepath, - fi_->fd); - if(rv < 0) - return err_; - - err = fs::dup2(rv,fi_->fd); - fs::close(rv); - if(err < 0) - return err_; - - rv = fs::pwriten(fi_->fd, - buf_ + written_, - count_ - written_, - offset_ + written_, - &err); - if(err < 0) - return err; - - return (written_ + rv); - } - - // When in direct_io mode write's return value should match that of - // the operation. - // 0 on EOF - // N bytes written (short writes included) - // -errno on error - // See libfuse/include/fuse.h for more details - static - int - write_direct_io(const char *buf_, - const size_t count_, - const off_t offset_, - FileInfo *fi_) - { - ssize_t rv; - - rv = fs::pwrite(fi_->fd,buf_,count_,offset_); - if(l::out_of_space(rv)) - rv = l::move_and_pwrite(buf_,count_,offset_,fi_,rv); + return ((err_ == -ENOSPC) || + (err_ == -EDQUOT)); +} - return rv; - } - - // When not in direct_io mode write's return value is more complex. - // 0 or less than `count` on EOF - // `count` on non-errors - // -errno on error - // See libfuse/include/fuse.h for more details - static - int - write_cached(const char *buf_, - const size_t count_, - const off_t offset_, - FileInfo *fi_) - { - int err; - ssize_t rv; - - rv = fs::pwriten(fi_->fd,buf_,count_,offset_,&err); - if(err == 0) - return rv; - if(err && !l::out_of_space(err)) - return err; - - rv = l::move_and_pwriten(buf_,count_,offset_,fi_,err,rv); +static +int +_move_and_pwrite(const char *buf_, + const size_t count_, + const off_t offset_, + FileInfo *fi_, + int err_) +{ + int err; + ssize_t rv; + Config::Read cfg; + + if(cfg->moveonenospc.enabled == false) + return err_; + + rv = fs::movefile_and_open_as_root(cfg->moveonenospc.policy, + cfg->branches, + fi_->branch.path, + fi_->fusepath, + fi_->fd); + if(rv < 0) + return err_; + + err = fs::dup2(rv,fi_->fd); + fs::close(rv); + if(err < 0) + return err_; + + return fs::pwrite(fi_->fd,buf_,count_,offset_); +} + +static +int +_move_and_pwriten(char const *buf_, + size_t const count_, + off_t const offset_, + FileInfo *fi_, + ssize_t const err_, + ssize_t const written_) +{ + int err; + ssize_t rv; + Config::Read cfg; + + if(cfg->moveonenospc.enabled == false) + return err_; + + rv = fs::movefile_and_open_as_root(cfg->moveonenospc.policy, + cfg->branches, + fi_->branch.path, + fi_->fusepath, + fi_->fd); + if(rv < 0) + return err_; + + err = fs::dup2(rv,fi_->fd); + fs::close(rv); + if(err < 0) + return err_; + + rv = fs::pwriten(fi_->fd, + buf_ + written_, + count_ - written_, + offset_ + written_, + &err); + if(err < 0) + return err; + + return (written_ + rv); +} + +// When in direct_io mode write's return value should match that of +// the operation. +// 0 on EOF +// N bytes written (short writes included) +// -errno on error +// See libfuse/include/fuse.h for more details +static +int +_write_direct_io(const char *buf_, + const size_t count_, + const off_t offset_, + FileInfo *fi_) +{ + ssize_t rv; + + rv = fs::pwrite(fi_->fd,buf_,count_,offset_); + if(::_out_of_space(rv)) + rv = ::_move_and_pwrite(buf_,count_,offset_,fi_,rv); + return rv; +} + +// When not in direct_io mode write's return value is more complex. +// 0 or less than `count` on EOF +// `count` on non-errors +// -errno on error +// See libfuse/include/fuse.h for more details +static +int +_write_cached(const char *buf_, + const size_t count_, + const off_t offset_, + FileInfo *fi_) +{ + int err; + ssize_t rv; + + rv = fs::pwriten(fi_->fd,buf_,count_,offset_,&err); + if(err == 0) return rv; - } - - static - int - write(const fuse_file_info_t *ffi_, - const char *buf_, - const size_t count_, - const off_t offset_) - { - FileInfo *fi; - - fi = reinterpret_cast(ffi_->fh); - - // Concurrent writes can only happen if: - // 1) writeback-cache is enabled and using page caching - // 2) parallel_direct_writes is enabled and file has `direct_io=true` - // Will look into selectively locking in the future - // A reader/writer lock would probably be the best option given - // the expense of the write itself in comparison. Alternatively, - // could change the move file behavior to use a known target file - // and have threads use O_EXCL and back off and wait for the - // transfer to complete before retrying. - std::lock_guard guard(fi->mutex); - - if(fi->direct_io) - return l::write_direct_io(buf_,count_,offset_,fi); - - return l::write_cached(buf_,count_,offset_,fi); - } + if(err && !::_out_of_space(err)) + return err; + + rv = ::_move_and_pwriten(buf_,count_,offset_,fi_,err,rv); + + return rv; +} + +static +int +_write(const fuse_file_info_t *ffi_, + const char *buf_, + const size_t count_, + const off_t offset_) +{ + FileInfo *fi; + + fi = reinterpret_cast(ffi_->fh); + + // Concurrent writes can only happen if: + // 1) writeback-cache is enabled and using page caching + // 2) parallel_direct_writes is enabled and file has `direct_io=true` + // Will look into selectively locking in the future + // A reader/writer lock would probably be the best option given + // the expense of the write itself in comparison. Alternatively, + // could change the move file behavior to use a known target file + // and have threads use O_EXCL and back off and wait for the + // transfer to complete before retrying. + std::lock_guard guard(fi->mutex); + + if(fi->direct_io) + return ::_write_direct_io(buf_,count_,offset_,fi); + + return ::_write_cached(buf_,count_,offset_,fi); +} + +int +FUSE::write(const fuse_file_info_t *ffi_, + const char *buf_, + size_t count_, + off_t offset_) +{ + return ::_write(ffi_,buf_,count_,offset_); } -namespace FUSE +int +FUSE::write_null(const fuse_file_info_t *ffi_, + const char *buf_, + size_t count_, + off_t offset_) { - int - write(const fuse_file_info_t *ffi_, - const char *buf_, - size_t count_, - off_t offset_) - { - return l::write(ffi_,buf_,count_,offset_); - } - - int - write_null(const fuse_file_info_t *ffi_, - const char *buf_, - size_t count_, - off_t offset_) - { - return count_; - } + return count_; } diff --git a/src/mergerfs_fsck.cpp b/src/mergerfs_fsck.cpp index 7e76eee9..e2558dc7 100644 --- a/src/mergerfs_fsck.cpp +++ b/src/mergerfs_fsck.cpp @@ -122,8 +122,8 @@ _compare_files(const std::string &mergerfs_path_, for(auto &pathstat : pathstats_) { rv = fs::lstat(pathstat.path,&pathstat.st); - if(rv == -1) - pathstat.st.st_size = -errno; + if(rv < 0) + pathstat.st.st_size = rv; } if(!::_files_differ(pathstats_,check_size_)) @@ -374,7 +374,7 @@ _fsck(const FS::path &path_, { paths.clear(); rv = ::_get_allpaths(de.path(),paths); - if(rv == -1) + if(rv < 0) continue; ::_compare_files(de.path(), diff --git a/src/policy_all.cpp b/src/policy_all.cpp index 2b948920..054e466d 100644 --- a/src/policy_all.cpp +++ b/src/policy_all.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "policy_all.hpp" + #include "errno.hpp" #include "fs_exists.hpp" #include "fs_info.hpp" @@ -27,38 +29,35 @@ using std::string; -namespace all +static +int +_create(const Branches::Ptr &ibranches_, + std::vector &obranches_) { - static - int - create(const Branches::Ptr &ibranches_, - std::vector &obranches_) - { - int rv; - int error; - fs::info_t info; + int rv; + int error; + fs::info_t info; - error = ENOENT; - for(auto &branch : *ibranches_) - { - if(branch.ro_or_nc()) - error_and_continue(error,EROFS); - rv = fs::info(branch.path,&info); - if(rv == -1) - error_and_continue(error,ENOENT); - if(info.readonly) - error_and_continue(error,EROFS); - if(info.spaceavail < branch.minfreespace()) - error_and_continue(error,ENOSPC); + error = ENOENT; + for(auto &branch : *ibranches_) + { + if(branch.ro_or_nc()) + error_and_continue(error,EROFS); + rv = fs::info(branch.path,&info); + if(rv < 0) + error_and_continue(error,ENOENT); + if(info.readonly) + error_and_continue(error,EROFS); + if(info.spaceavail < branch.minfreespace()) + error_and_continue(error,ENOSPC); - obranches_.push_back(&branch); - } + obranches_.push_back(&branch); + } - if(obranches_.empty()) - return (errno=error,-1); + if(obranches_.empty()) + return -error; - return 0; - } + return 0; } int @@ -74,7 +73,7 @@ Policy::All::Create::operator()(const Branches::Ptr &ibranches_, const char *fusepath_, std::vector &obranches_) const { - return ::all::create(ibranches_,obranches_); + return ::_create(ibranches_,obranches_); } int diff --git a/src/policy_epall.cpp b/src/policy_epall.cpp index 238e40ca..7944eb5e 100644 --- a/src/policy_epall.cpp +++ b/src/policy_epall.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "policy_epall.hpp" + #include "errno.hpp" #include "fs_exists.hpp" #include "fs_info.hpp" @@ -29,93 +31,90 @@ using std::string; -namespace epall +static +int +_create(const Branches::Ptr &branches_, + const char *fusepath_, + std::vector &paths_) +{ + int rv; + int error; + fs::info_t info; + + error = ENOENT; + for(auto &branch : *branches_) + { + if(branch.ro_or_nc()) + error_and_continue(error,EROFS); + if(!fs::exists(branch.path,fusepath_)) + error_and_continue(error,ENOENT); + rv = fs::info(branch.path,&info); + if(rv < 0) + error_and_continue(error,ENOENT); + if(info.readonly) + error_and_continue(error,EROFS); + if(info.spaceavail < branch.minfreespace()) + error_and_continue(error,ENOSPC); + + paths_.emplace_back(&branch); + } + + if(paths_.empty()) + return -error; + + return 0; +} + +static +int +_action(const Branches::Ptr &branches_, + const char *fusepath_, + std::vector &paths_) +{ + int rv; + int error; + bool readonly; + + error = ENOENT; + for(auto &branch : *branches_) + { + if(branch.ro()) + error_and_continue(error,EROFS); + if(!fs::exists(branch.path,fusepath_)) + error_and_continue(error,ENOENT); + rv = fs::statvfs_cache_readonly(branch.path,&readonly); + if(rv < 0) + error_and_continue(error,ENOENT); + if(readonly) + error_and_continue(error,EROFS); + + paths_.emplace_back(&branch); + } + + if(paths_.empty()) + return -error; + + return 0; +} + +static +int +_search(const Branches::Ptr &branches_, + const char *fusepath_, + std::vector &paths_) { - static - int - create(const Branches::Ptr &branches_, - const char *fusepath_, - std::vector &paths_) - { - int rv; - int error; - fs::info_t info; - - error = ENOENT; - for(auto &branch : *branches_) - { - if(branch.ro_or_nc()) - error_and_continue(error,EROFS); - if(!fs::exists(branch.path,fusepath_)) - error_and_continue(error,ENOENT); - rv = fs::info(branch.path,&info); - if(rv == -1) - error_and_continue(error,ENOENT); - if(info.readonly) - error_and_continue(error,EROFS); - if(info.spaceavail < branch.minfreespace()) - error_and_continue(error,ENOSPC); - - paths_.emplace_back(&branch); - } - - if(paths_.empty()) - return (errno=error,-1); - - return 0; - } - - static - int - action(const Branches::Ptr &branches_, - const char *fusepath_, - std::vector &paths_) - { - int rv; - int error; - bool readonly; - - error = ENOENT; - for(auto &branch : *branches_) - { - if(branch.ro()) - error_and_continue(error,EROFS); - if(!fs::exists(branch.path,fusepath_)) - error_and_continue(error,ENOENT); - rv = fs::statvfs_cache_readonly(branch.path,&readonly); - if(rv == -1) - error_and_continue(error,ENOENT); - if(readonly) - error_and_continue(error,EROFS); - - paths_.emplace_back(&branch); - } - - if(paths_.empty()) - return (errno=error,-1); - - return 0; - } - - static - int - search(const Branches::Ptr &branches_, - const char *fusepath_, - std::vector &paths_) - { - for(auto &branch : *branches_) - { - if(!fs::exists(branch.path,fusepath_)) - continue; - - paths_.push_back(&branch); - } - - if(paths_.empty()) - return (errno=ENOENT,-1); - - return 0; - } + for(auto &branch : *branches_) + { + if(!fs::exists(branch.path,fusepath_)) + continue; + + paths_.push_back(&branch); + } + + if(paths_.empty()) + return -ENOENT; + + return 0; } int @@ -123,7 +122,7 @@ Policy::EPAll::Action::operator()(const Branches::Ptr &branches_, const char *fusepath_, std::vector &paths_) const { - return ::epall::action(branches_,fusepath_,paths_); + return ::_action(branches_,fusepath_,paths_); } int @@ -131,7 +130,7 @@ Policy::EPAll::Create::operator()(const Branches::Ptr &branches_, const char *fusepath_, std::vector &paths_) const { - return ::epall::create(branches_,fusepath_,paths_); + return ::_create(branches_,fusepath_,paths_); } int @@ -139,5 +138,5 @@ Policy::EPAll::Search::operator()(const Branches::Ptr &branches_, const char *fusepath_, std::vector &paths_) const { - return ::epall::search(branches_,fusepath_,paths_); + return ::_search(branches_,fusepath_,paths_); } diff --git a/src/policy_epff.cpp b/src/policy_epff.cpp index 5689981f..1728364f 100644 --- a/src/policy_epff.cpp +++ b/src/policy_epff.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "policy_epff.hpp" + #include "branches.hpp" #include "errno.hpp" #include "fs_exists.hpp" @@ -31,90 +33,87 @@ using std::string; using std::vector; -namespace epff +static +int +_create(const Branches::Ptr &branches_, + const char *fusepath_, + std::vector &paths_) +{ + int rv; + int error; + fs::info_t info; + + error = ENOENT; + for(auto &branch : *branches_) + { + if(branch.ro_or_nc()) + error_and_continue(error,EROFS); + if(!fs::exists(branch.path,fusepath_)) + error_and_continue(error,ENOENT); + rv = fs::info(branch.path,&info); + if(rv < 0) + error_and_continue(error,ENOENT); + if(info.readonly) + error_and_continue(error,EROFS); + if(info.spaceavail < branch.minfreespace()) + error_and_continue(error,ENOSPC); + + paths_.push_back(&branch); + + return 0; + } + + return -error; +} + +static +int +_action(const Branches::Ptr &branches_, + const char *fusepath_, + std::vector &paths_) +{ + int rv; + int error; + bool readonly; + + error = ENOENT; + for(auto &branch : *branches_) + { + if(branch.ro()) + error_and_continue(error,EROFS); + if(!fs::exists(branch.path,fusepath_)) + error_and_continue(error,ENOENT); + rv = fs::statvfs_cache_readonly(branch.path,&readonly); + if(rv < 0) + error_and_continue(error,ENOENT); + if(readonly) + error_and_continue(error,EROFS); + + paths_.push_back(&branch); + + return 0; + } + + return -error; +} + +static +int +_search(const Branches::Ptr &branches_, + const char *fusepath_, + std::vector &paths_) { - static - int - create(const Branches::Ptr &branches_, - const char *fusepath_, - std::vector &paths_) - { - int rv; - int error; - fs::info_t info; - - error = ENOENT; - for(auto &branch : *branches_) - { - if(branch.ro_or_nc()) - error_and_continue(error,EROFS); - if(!fs::exists(branch.path,fusepath_)) - error_and_continue(error,ENOENT); - rv = fs::info(branch.path,&info); - if(rv == -1) - error_and_continue(error,ENOENT); - if(info.readonly) - error_and_continue(error,EROFS); - if(info.spaceavail < branch.minfreespace()) - error_and_continue(error,ENOSPC); - - paths_.push_back(&branch); - - return 0; - } - - return (errno=error,-1); - } - - static - int - action(const Branches::Ptr &branches_, - const char *fusepath_, - std::vector &paths_) - { - int rv; - int error; - bool readonly; - - error = ENOENT; - for(auto &branch : *branches_) - { - if(branch.ro()) - error_and_continue(error,EROFS); - if(!fs::exists(branch.path,fusepath_)) - error_and_continue(error,ENOENT); - rv = fs::statvfs_cache_readonly(branch.path,&readonly); - if(rv == -1) - error_and_continue(error,ENOENT); - if(readonly) - error_and_continue(error,EROFS); - - paths_.push_back(&branch); - - return 0; - } - - return (errno=error,-1); - } - - static - int - search(const Branches::Ptr &branches_, - const char *fusepath_, - std::vector &paths_) - { - for(auto &branch : *branches_) - { - if(!fs::exists(branch.path,fusepath_)) - continue; - - paths_.push_back(&branch); - - return 0; - } - - return (errno=ENOENT,-1); - } + for(auto &branch : *branches_) + { + if(!fs::exists(branch.path,fusepath_)) + continue; + + paths_.push_back(&branch); + + return 0; + } + + return -ENOENT; } int @@ -122,7 +121,7 @@ Policy::EPFF::Action::operator()(const Branches::Ptr &branches_, const char *fusepath_, std::vector &paths_) const { - return ::epff::action(branches_,fusepath_,paths_); + return ::_action(branches_,fusepath_,paths_); } int @@ -130,7 +129,7 @@ Policy::EPFF::Create::operator()(const Branches::Ptr &branches_, const char *fusepath_, std::vector &paths_) const { - return ::epff::create(branches_,fusepath_,paths_); + return ::_create(branches_,fusepath_,paths_); } int @@ -138,5 +137,5 @@ Policy::EPFF::Search::operator()(const Branches::Ptr &branches_, const char *fusepath_, std::vector &paths_) const { - return ::epff::search(branches_,fusepath_,paths_); + return ::_search(branches_,fusepath_,paths_); } diff --git a/src/policy_eplfs.cpp b/src/policy_eplfs.cpp index 8248bb8b..377b5bf0 100644 --- a/src/policy_eplfs.cpp +++ b/src/policy_eplfs.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "policy_eplfs.hpp" + #include "errno.hpp" #include "fs_exists.hpp" #include "fs_info.hpp" @@ -31,126 +33,123 @@ using std::string; using std::vector; -namespace eplfs +static +int +_create(const Branches::Ptr &branches_, + const char *fusepath_, + std::vector &paths_) +{ + int rv; + int error; + uint64_t eplfs; + Branch *obranch; + fs::info_t info; + + obranch = nullptr; + error = ENOENT; + eplfs = std::numeric_limits::max(); + for(auto &branch : *branches_) + { + if(branch.ro_or_nc()) + error_and_continue(error,EROFS); + if(!fs::exists(branch.path,fusepath_)) + error_and_continue(error,ENOENT); + rv = fs::info(branch.path,&info); + if(rv < 0) + error_and_continue(error,ENOENT); + if(info.readonly) + error_and_continue(error,EROFS); + if(info.spaceavail < branch.minfreespace()) + error_and_continue(error,ENOSPC); + if(info.spaceavail > eplfs) + continue; + + eplfs = info.spaceavail; + obranch = &branch; + } + + if(obranch == nullptr) + return -error; + + paths_.emplace_back(obranch); + + return 0; +} + +static +int +_action(const Branches::Ptr &branches_, + const char *fusepath_, + std::vector &paths_) +{ + int rv; + int error; + uint64_t eplfs; + Branch *obranch; + fs::info_t info; + + obranch = nullptr; + error = ENOENT; + eplfs = std::numeric_limits::max(); + for(auto &branch : *branches_) + { + if(branch.ro()) + error_and_continue(error,EROFS); + if(!fs::exists(branch.path,fusepath_)) + error_and_continue(error,ENOENT); + rv = fs::info(branch.path,&info); + if(rv < 0) + error_and_continue(error,ENOENT); + if(info.readonly) + error_and_continue(error,EROFS); + if(info.spaceavail > eplfs) + continue; + + eplfs = info.spaceavail; + obranch = &branch; + } + + if(obranch == nullptr) + return -error; + + paths_.emplace_back(obranch); + + return 0; +} + +static +int +_search(const Branches::Ptr &branches_, + const char *fusepath_, + std::vector &paths_) { - static - int - create(const Branches::Ptr &branches_, - const char *fusepath_, - std::vector &paths_) - { - int rv; - int error; - uint64_t eplfs; - Branch *obranch; - fs::info_t info; - - obranch = nullptr; - error = ENOENT; - eplfs = std::numeric_limits::max(); - for(auto &branch : *branches_) - { - if(branch.ro_or_nc()) - error_and_continue(error,EROFS); - if(!fs::exists(branch.path,fusepath_)) - error_and_continue(error,ENOENT); - rv = fs::info(branch.path,&info); - if(rv == -1) - error_and_continue(error,ENOENT); - if(info.readonly) - error_and_continue(error,EROFS); - if(info.spaceavail < branch.minfreespace()) - error_and_continue(error,ENOSPC); - if(info.spaceavail > eplfs) - continue; - - eplfs = info.spaceavail; - obranch = &branch; - } - - if(obranch == nullptr) - return (errno=error,-1); - - paths_.emplace_back(obranch); - - return 0; - } - - static - int - action(const Branches::Ptr &branches_, - const char *fusepath_, - std::vector &paths_) - { - int rv; - int error; - uint64_t eplfs; - Branch *obranch; - fs::info_t info; - - obranch = nullptr; - error = ENOENT; - eplfs = std::numeric_limits::max(); - for(auto &branch : *branches_) - { - if(branch.ro()) - error_and_continue(error,EROFS); - if(!fs::exists(branch.path,fusepath_)) - error_and_continue(error,ENOENT); - rv = fs::info(branch.path,&info); - if(rv == -1) - error_and_continue(error,ENOENT); - if(info.readonly) - error_and_continue(error,EROFS); - if(info.spaceavail > eplfs) - continue; - - eplfs = info.spaceavail; - obranch = &branch; - } - - if(obranch == nullptr) - return (errno=error,-1); - - paths_.emplace_back(obranch); - - return 0; - } - - static - int - search(const Branches::Ptr &branches_, - const char *fusepath_, - std::vector &paths_) - { - int rv; - uint64_t eplfs; - uint64_t spaceavail; - Branch *obranch; - - obranch = nullptr; - eplfs = std::numeric_limits::max(); - for(auto &branch : *branches_) - { - if(!fs::exists(branch.path,fusepath_)) - continue; - rv = fs::statvfs_cache_spaceavail(branch.path,&spaceavail); - if(rv == -1) - continue; - if(spaceavail > eplfs) - continue; - - eplfs = spaceavail; - obranch = &branch; - } - - if(obranch == nullptr) - return (errno=ENOENT,-1); - - paths_.emplace_back(obranch); - - return 0; - } + int rv; + uint64_t eplfs; + uint64_t spaceavail; + Branch *obranch; + + obranch = nullptr; + eplfs = std::numeric_limits::max(); + for(auto &branch : *branches_) + { + if(!fs::exists(branch.path,fusepath_)) + continue; + rv = fs::statvfs_cache_spaceavail(branch.path,&spaceavail); + if(rv < 0) + continue; + if(spaceavail > eplfs) + continue; + + eplfs = spaceavail; + obranch = &branch; + } + + if(obranch == nullptr) + return -ENOENT; + + paths_.emplace_back(obranch); + + return 0; } int @@ -158,7 +157,7 @@ Policy::EPLFS::Action::operator()(const Branches::Ptr &branches_, const char *fusepath_, std::vector &paths_) const { - return ::eplfs::action(branches_,fusepath_,paths_); + return ::_action(branches_,fusepath_,paths_); } int @@ -166,7 +165,7 @@ Policy::EPLFS::Create::operator()(const Branches::Ptr &branches_, const char *fusepath_, std::vector &paths_) const { - return ::eplfs::create(branches_,fusepath_,paths_); + return ::_create(branches_,fusepath_,paths_); } int @@ -174,5 +173,5 @@ Policy::EPLFS::Search::operator()(const Branches::Ptr &branches_, const char *fusepath_, std::vector &paths_) const { - return ::eplfs::search(branches_,fusepath_,paths_); + return ::_search(branches_,fusepath_,paths_); } diff --git a/src/policy_eplus.cpp b/src/policy_eplus.cpp index 9f686758..037093e1 100644 --- a/src/policy_eplus.cpp +++ b/src/policy_eplus.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "policy_eplus.hpp" + #include "errno.hpp" #include "fs_exists.hpp" #include "fs_info.hpp" @@ -29,126 +31,123 @@ using std::string; -namespace eplus +static +int +_create(const Branches::Ptr &branches_, + const char *fusepath_, + std::vector &paths_) +{ + int rv; + int error; + uint64_t eplus; + fs::info_t info; + Branch *obranch; + + obranch = nullptr; + error = ENOENT; + eplus = std::numeric_limits::max(); + for(auto &branch : *branches_) + { + if(branch.ro_or_nc()) + error_and_continue(error,EROFS); + if(!fs::exists(branch.path,fusepath_)) + error_and_continue(error,ENOENT); + rv = fs::info(branch.path,&info); + if(rv < 0) + error_and_continue(error,ENOENT); + if(info.readonly) + error_and_continue(error,EROFS); + if(info.spaceavail < branch.minfreespace()) + error_and_continue(error,ENOSPC); + if(info.spaceused >= eplus) + continue; + + eplus = info.spaceused; + obranch = &branch; + } + + if(obranch == nullptr) + return -error; + + paths_.emplace_back(obranch); + + return 0; +} + +static +int +_action(const Branches::Ptr &branches_, + const char *fusepath_, + std::vector &paths_) +{ + int rv; + int error; + uint64_t eplus; + fs::info_t info; + Branch *obranch; + + obranch = nullptr; + error = ENOENT; + eplus = std::numeric_limits::max(); + for(auto &branch : *branches_) + { + if(branch.ro()) + error_and_continue(error,EROFS); + if(!fs::exists(branch.path,fusepath_)) + error_and_continue(error,ENOENT); + rv = fs::info(branch.path,&info); + if(rv < 0) + error_and_continue(error,ENOENT); + if(info.readonly) + error_and_continue(error,EROFS); + if(info.spaceused >= eplus) + continue; + + eplus = info.spaceused; + obranch = &branch; + } + + if(obranch == nullptr) + return -error; + + paths_.emplace_back(obranch); + + return 0; +} + +static +int +_search(const Branches::Ptr &branches_, + const char *fusepath_, + std::vector &paths_) { - static - int - create(const Branches::Ptr &branches_, - const char *fusepath_, - std::vector &paths_) - { - int rv; - int error; - uint64_t eplus; - fs::info_t info; - Branch *obranch; - - obranch = nullptr; - error = ENOENT; - eplus = std::numeric_limits::max(); - for(auto &branch : *branches_) - { - if(branch.ro_or_nc()) - error_and_continue(error,EROFS); - if(!fs::exists(branch.path,fusepath_)) - error_and_continue(error,ENOENT); - rv = fs::info(branch.path,&info); - if(rv == -1) - error_and_continue(error,ENOENT); - if(info.readonly) - error_and_continue(error,EROFS); - if(info.spaceavail < branch.minfreespace()) - error_and_continue(error,ENOSPC); - if(info.spaceused >= eplus) - continue; - - eplus = info.spaceused; - obranch = &branch; - } - - if(obranch == nullptr) - return (errno=error,-1); - - paths_.emplace_back(obranch); - - return 0; - } - - static - int - action(const Branches::Ptr &branches_, - const char *fusepath_, - std::vector &paths_) - { - int rv; - int error; - uint64_t eplus; - fs::info_t info; - Branch *obranch; - - obranch = nullptr; - error = ENOENT; - eplus = std::numeric_limits::max(); - for(auto &branch : *branches_) - { - if(branch.ro()) - error_and_continue(error,EROFS); - if(!fs::exists(branch.path,fusepath_)) - error_and_continue(error,ENOENT); - rv = fs::info(branch.path,&info); - if(rv == -1) - error_and_continue(error,ENOENT); - if(info.readonly) - error_and_continue(error,EROFS); - if(info.spaceused >= eplus) - continue; - - eplus = info.spaceused; - obranch = &branch; - } - - if(obranch == nullptr) - return (errno=error,-1); - - paths_.emplace_back(obranch); - - return 0; - } - - static - int - search(const Branches::Ptr &branches_, - const char *fusepath_, - std::vector &paths_) - { - int rv; - uint64_t eplus; - uint64_t spaceused; - Branch *obranch; - - obranch = nullptr; - eplus = 0; - for(auto &branch : *branches_) - { - if(!fs::exists(branch.path,fusepath_)) - continue; - rv = fs::statvfs_cache_spaceused(branch.path,&spaceused); - if(rv == -1) - continue; - if(spaceused >= eplus) - continue; - - eplus = spaceused; - obranch = &branch; - } - - if(obranch == nullptr) - return (errno=ENOENT,-1); - - paths_.emplace_back(obranch); - - return 0; - } + int rv; + uint64_t eplus; + uint64_t spaceused; + Branch *obranch; + + obranch = nullptr; + eplus = 0; + for(auto &branch : *branches_) + { + if(!fs::exists(branch.path,fusepath_)) + continue; + rv = fs::statvfs_cache_spaceused(branch.path,&spaceused); + if(rv < 0) + continue; + if(spaceused >= eplus) + continue; + + eplus = spaceused; + obranch = &branch; + } + + if(obranch == nullptr) + return -ENOENT; + + paths_.emplace_back(obranch); + + return 0; } int @@ -156,7 +155,7 @@ Policy::EPLUS::Action::operator()(const Branches::Ptr &branches_, const char *fusepath_, std::vector &paths_) const { - return ::eplus::action(branches_,fusepath_,paths_); + return ::_action(branches_,fusepath_,paths_); } int @@ -164,7 +163,7 @@ Policy::EPLUS::Create::operator()(const Branches::Ptr &branches_, const char *fusepath_, std::vector &paths_) const { - return ::eplus::create(branches_,fusepath_,paths_); + return ::_create(branches_,fusepath_,paths_); } int @@ -172,5 +171,5 @@ Policy::EPLUS::Search::operator()(const Branches::Ptr &branches_, const char *fusepath_, std::vector &paths_) const { - return ::eplus::search(branches_,fusepath_,paths_); + return ::_search(branches_,fusepath_,paths_); } diff --git a/src/policy_epmfs.cpp b/src/policy_epmfs.cpp index a9ee4ebb..22c1bc6d 100644 --- a/src/policy_epmfs.cpp +++ b/src/policy_epmfs.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "policy_epmfs.hpp" + #include "errno.hpp" #include "fs_exists.hpp" #include "fs_info.hpp" @@ -30,126 +32,123 @@ using std::string; -namespace epmfs +static +int +_create(const Branches::Ptr &branches_, + const char *fusepath_, + std::vector &paths_) +{ + int rv; + int error; + uint64_t epmfs; + fs::info_t info; + Branch *obranch; + + obranch = nullptr; + error = ENOENT; + epmfs = std::numeric_limits::min(); + for(auto &branch : *branches_) + { + if(branch.ro_or_nc()) + error_and_continue(error,EROFS); + if(!fs::exists(branch.path,fusepath_)) + error_and_continue(error,ENOENT); + rv = fs::info(branch.path,&info); + if(rv < 0) + error_and_continue(error,ENOENT); + if(info.readonly) + error_and_continue(error,EROFS); + if(info.spaceavail < branch.minfreespace()) + error_and_continue(error,ENOSPC); + if(info.spaceavail < epmfs) + continue; + + epmfs = info.spaceavail; + obranch = &branch; + } + + if(obranch == nullptr) + return -error; + + paths_.emplace_back(obranch); + + return 0; +} + +static +int +_action(const Branches::Ptr &branches_, + const char *fusepath_, + std::vector &paths_) +{ + int rv; + int error; + uint64_t epmfs; + fs::info_t info; + Branch *obranch; + + obranch = nullptr; + error = ENOENT; + epmfs = std::numeric_limits::min(); + for(auto &branch : *branches_) + { + if(branch.ro()) + error_and_continue(error,EROFS); + if(!fs::exists(branch.path,fusepath_)) + error_and_continue(error,ENOENT); + rv = fs::info(branch.path,&info); + if(rv < 0) + error_and_continue(error,ENOENT); + if(info.readonly) + error_and_continue(error,EROFS); + if(info.spaceavail < epmfs) + continue; + + epmfs = info.spaceavail; + obranch = &branch; + } + + if(obranch == nullptr) + return -error; + + paths_.emplace_back(obranch); + + return 0; +} + +static +int +_search(const Branches::Ptr &branches_, + const char *fusepath_, + std::vector &paths_) { - static - int - create(const Branches::Ptr &branches_, - const char *fusepath_, - std::vector &paths_) - { - int rv; - int error; - uint64_t epmfs; - fs::info_t info; - Branch *obranch; - - obranch = nullptr; - error = ENOENT; - epmfs = std::numeric_limits::min(); - for(auto &branch : *branches_) - { - if(branch.ro_or_nc()) - error_and_continue(error,EROFS); - if(!fs::exists(branch.path,fusepath_)) - error_and_continue(error,ENOENT); - rv = fs::info(branch.path,&info); - if(rv == -1) - error_and_continue(error,ENOENT); - if(info.readonly) - error_and_continue(error,EROFS); - if(info.spaceavail < branch.minfreespace()) - error_and_continue(error,ENOSPC); - if(info.spaceavail < epmfs) - continue; - - epmfs = info.spaceavail; - obranch = &branch; - } - - if(obranch == nullptr) - return (errno=error,-1); - - paths_.emplace_back(obranch); - - return 0; - } - - static - int - action(const Branches::Ptr &branches_, - const char *fusepath_, - std::vector &paths_) - { - int rv; - int error; - uint64_t epmfs; - fs::info_t info; - Branch *obranch; - - obranch = nullptr; - error = ENOENT; - epmfs = std::numeric_limits::min(); - for(auto &branch : *branches_) - { - if(branch.ro()) - error_and_continue(error,EROFS); - if(!fs::exists(branch.path,fusepath_)) - error_and_continue(error,ENOENT); - rv = fs::info(branch.path,&info); - if(rv == -1) - error_and_continue(error,ENOENT); - if(info.readonly) - error_and_continue(error,EROFS); - if(info.spaceavail < epmfs) - continue; - - epmfs = info.spaceavail; - obranch = &branch; - } - - if(obranch == nullptr) - return (errno=error,-1); - - paths_.emplace_back(obranch); - - return 0; - } - - static - int - search(const Branches::Ptr &branches_, - const char *fusepath_, - std::vector &paths_) - { - int rv; - uint64_t epmfs; - uint64_t spaceavail; - Branch *obranch; - - obranch = nullptr; - epmfs = 0; - for(auto &branch : *branches_) - { - if(!fs::exists(branch.path,fusepath_)) - continue; - rv = fs::statvfs_cache_spaceavail(branch.path,&spaceavail); - if(rv == -1) - continue; - if(spaceavail < epmfs) - continue; - - epmfs = spaceavail; - obranch = &branch; - } - - if(obranch == nullptr) - return (errno=ENOENT,-1); - - paths_.emplace_back(obranch); - - return 0; - } + int rv; + uint64_t epmfs; + uint64_t spaceavail; + Branch *obranch; + + obranch = nullptr; + epmfs = 0; + for(auto &branch : *branches_) + { + if(!fs::exists(branch.path,fusepath_)) + continue; + rv = fs::statvfs_cache_spaceavail(branch.path,&spaceavail); + if(rv < 0) + continue; + if(spaceavail < epmfs) + continue; + + epmfs = spaceavail; + obranch = &branch; + } + + if(obranch == nullptr) + return -ENOENT; + + paths_.emplace_back(obranch); + + return 0; } int @@ -157,7 +156,7 @@ Policy::EPMFS::Action::operator()(const Branches::Ptr &branches_, const char *fusepath_, std::vector &paths_) const { - return ::epmfs::action(branches_,fusepath_,paths_); + return ::_action(branches_,fusepath_,paths_); } int @@ -165,7 +164,7 @@ Policy::EPMFS::Create::operator()(const Branches::Ptr &branches_, const char *fusepath_, std::vector &paths_) const { - return ::epmfs::create(branches_,fusepath_,paths_); + return ::_create(branches_,fusepath_,paths_); } int @@ -173,5 +172,5 @@ Policy::EPMFS::Search::operator()(const Branches::Ptr &branches_, const char *fusepath_, std::vector &paths_) const { - return ::epmfs::search(branches_,fusepath_,paths_); + return ::_search(branches_,fusepath_,paths_); } diff --git a/src/policy_eppfrd.cpp b/src/policy_eppfrd.cpp index bc162a68..63fae1d2 100644 --- a/src/policy_eppfrd.cpp +++ b/src/policy_eppfrd.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "policy_eppfrd.hpp" + #include "errno.hpp" #include "fs_exists.hpp" #include "fs_info.hpp" @@ -37,191 +39,188 @@ struct BranchInfo typedef std::vector BranchInfoVec; -namespace eppfrd +static +int +_get_branchinfo_create(const Branches::Ptr &branches_, + const char *fusepath_, + BranchInfoVec *branchinfo_, + uint64_t *sum_) +{ + int rv; + int error; + fs::info_t info; + + *sum_ = 0; + error = ENOENT; + for(auto &branch : *branches_) + { + if(branch.ro_or_nc()) + error_and_continue(error,EROFS); + if(!fs::exists(branch.path,fusepath_)) + error_and_continue(error,ENOENT); + rv = fs::info(branch.path,&info); + if(rv < 0) + error_and_continue(error,ENOENT); + if(info.readonly) + error_and_continue(error,EROFS); + if(info.spaceavail < branch.minfreespace()) + error_and_continue(error,ENOSPC); + + *sum_ += info.spaceavail; + + branchinfo_->push_back({info.spaceavail,&branch}); + } + + return -error; +} + +static +int +_get_branchinfo_action(const Branches::Ptr &branches_, + const char *fusepath_, + BranchInfoVec *branchinfo_, + uint64_t *sum_) +{ + int rv; + int error; + fs::info_t info; + + *sum_ = 0; + error = ENOENT; + for(auto &branch : *branches_) + { + if(branch.ro()) + error_and_continue(error,EROFS); + if(!fs::exists(branch.path,fusepath_)) + error_and_continue(error,ENOENT); + rv = fs::info(branch.path,&info); + if(rv < 0) + error_and_continue(error,ENOENT); + if(info.readonly) + error_and_continue(error,EROFS); + + *sum_ += info.spaceavail; + + branchinfo_->push_back({info.spaceavail,&branch}); + } + + return -error; +} + +static +int +_get_branchinfo_search(const Branches::Ptr &branches_, + const char *fusepath_, + BranchInfoVec *branchinfo_, + uint64_t *sum_) { - static - int - get_branchinfo_create(const Branches::Ptr &branches_, - const char *fusepath_, - BranchInfoVec *branchinfo_, - uint64_t *sum_) - { - int rv; - int error; - fs::info_t info; - - *sum_ = 0; - error = ENOENT; - for(auto &branch : *branches_) - { - if(branch.ro_or_nc()) - error_and_continue(error,EROFS); - if(!fs::exists(branch.path,fusepath_)) - error_and_continue(error,ENOENT); - rv = fs::info(branch.path,&info); - if(rv == -1) - error_and_continue(error,ENOENT); - if(info.readonly) - error_and_continue(error,EROFS); - if(info.spaceavail < branch.minfreespace()) - error_and_continue(error,ENOSPC); - - *sum_ += info.spaceavail; - - branchinfo_->push_back({info.spaceavail,&branch}); - } - - return error; - } - - static - int - get_branchinfo_action(const Branches::Ptr &branches_, - const char *fusepath_, - BranchInfoVec *branchinfo_, - uint64_t *sum_) - { - int rv; - int error; - fs::info_t info; - - *sum_ = 0; - error = ENOENT; - for(auto &branch : *branches_) - { - if(branch.ro()) - error_and_continue(error,EROFS); - if(!fs::exists(branch.path,fusepath_)) - error_and_continue(error,ENOENT); - rv = fs::info(branch.path,&info); - if(rv == -1) - error_and_continue(error,ENOENT); - if(info.readonly) - error_and_continue(error,EROFS); - - *sum_ += info.spaceavail; - - branchinfo_->push_back({info.spaceavail,&branch}); - } - - return error; - } - - static - int - get_branchinfo_search(const Branches::Ptr &branches_, - const char *fusepath_, - BranchInfoVec *branchinfo_, - uint64_t *sum_) - { - int rv; - uint64_t spaceavail; - - *sum_ = 0; - for(auto &branch : *branches_) - { - if(!fs::exists(branch.path,fusepath_)) - continue; - rv = fs::statvfs_cache_spaceavail(branch.path,&spaceavail); - if(rv == -1) - continue; - - *sum_ += spaceavail; - - branchinfo_->push_back({spaceavail,&branch}); - } - - return ENOENT; - } - - static - Branch* - get_branch(const BranchInfoVec &branchinfo_, - const uint64_t sum_) - { - uint64_t idx; - uint64_t threshold; - - if(sum_ == 0) - return NULL; - - idx = 0; - threshold = RND::rand64(sum_); - for(size_t i = 0; i < branchinfo_.size(); i++) - { - idx += branchinfo_[i].spaceavail; - - if(idx < threshold) - continue; - - return branchinfo_[i].branch; - } + int rv; + uint64_t spaceavail; + + *sum_ = 0; + for(auto &branch : *branches_) + { + if(!fs::exists(branch.path,fusepath_)) + continue; + rv = fs::statvfs_cache_spaceavail(branch.path,&spaceavail); + if(rv < 0) + continue; + *sum_ += spaceavail; + + branchinfo_->push_back({spaceavail,&branch}); + } + + return -ENOENT; +} + +static +Branch* +_get_branch(const BranchInfoVec &branchinfo_, + const uint64_t sum_) +{ + uint64_t idx; + uint64_t threshold; + + if(sum_ == 0) return NULL; - } - - static - int - create(const Branches::Ptr &branches_, - const char *fusepath_, - std::vector &paths_) - { - int error; - uint64_t sum; - Branch *branch; - BranchInfoVec branchinfo; - - error = eppfrd::get_branchinfo_create(branches_,fusepath_,&branchinfo,&sum); - branch = eppfrd::get_branch(branchinfo,sum); - if(!branch) - return (errno=error,-1); - - paths_.emplace_back(branch); - - return 0; - } - - static - int - action(const Branches::Ptr &branches_, - const char *fusepath_, - std::vector &paths_) - { - int error; - uint64_t sum; - Branch *branch; - BranchInfoVec branchinfo; - - error = eppfrd::get_branchinfo_action(branches_,fusepath_,&branchinfo,&sum); - branch = eppfrd::get_branch(branchinfo,sum); - if(!branch) - return (errno=error,-1); - - paths_.emplace_back(branch); - - return 0; - } - - static - int - search(const Branches::Ptr &branches_, - const char *fusepath_, - std::vector &paths_) - { - int error; - uint64_t sum; - Branch *branch; - BranchInfoVec branchinfo; - - error = eppfrd::get_branchinfo_search(branches_,fusepath_,&branchinfo,&sum); - branch = eppfrd::get_branch(branchinfo,sum); - if(!branch) - return (errno=error,-1); - - paths_.emplace_back(branch); - - return 0; - } + + idx = 0; + threshold = RND::rand64(sum_); + for(size_t i = 0; i < branchinfo_.size(); i++) + { + idx += branchinfo_[i].spaceavail; + + if(idx < threshold) + continue; + + return branchinfo_[i].branch; + } + + return NULL; +} + +static +int +_create(const Branches::Ptr &branches_, + const char *fusepath_, + std::vector &paths_) +{ + int err; + uint64_t sum; + Branch *branch; + BranchInfoVec branchinfo; + + err = ::_get_branchinfo_create(branches_,fusepath_,&branchinfo,&sum); + branch = ::_get_branch(branchinfo,sum); + if(!branch) + return err; + + paths_.emplace_back(branch); + + return 0; +} + +static +int +_action(const Branches::Ptr &branches_, + const char *fusepath_, + std::vector &paths_) +{ + int err; + uint64_t sum; + Branch *branch; + BranchInfoVec branchinfo; + + err = ::_get_branchinfo_action(branches_,fusepath_,&branchinfo,&sum); + branch = ::_get_branch(branchinfo,sum); + if(!branch) + return err; + + paths_.emplace_back(branch); + + return 0; +} + +static +int +_search(const Branches::Ptr &branches_, + const char *fusepath_, + std::vector &paths_) +{ + int err; + uint64_t sum; + Branch *branch; + BranchInfoVec branchinfo; + + err = ::_get_branchinfo_search(branches_,fusepath_,&branchinfo,&sum); + branch = ::_get_branch(branchinfo,sum); + if(!branch) + return err; + + paths_.emplace_back(branch); + + return 0; } int @@ -229,7 +228,7 @@ Policy::EPPFRD::Action::operator()(const Branches::Ptr &branches_, const char *fusepath_, std::vector &paths_) const { - return ::eppfrd::action(branches_,fusepath_,paths_); + return ::_action(branches_,fusepath_,paths_); } int @@ -237,7 +236,7 @@ Policy::EPPFRD::Create::operator()(const Branches::Ptr &branches_, const char *fusepath_, std::vector &paths_) const { - return ::eppfrd::create(branches_,fusepath_,paths_); + return ::_create(branches_,fusepath_,paths_); } int @@ -245,5 +244,5 @@ Policy::EPPFRD::Search::operator()(const Branches::Ptr &branches_, const char *fusepath_, std::vector &paths_) const { - return ::eppfrd::search(branches_,fusepath_,paths_); + return ::_search(branches_,fusepath_,paths_); } diff --git a/src/policy_eprand.cpp b/src/policy_eprand.cpp index e334e2bc..7ea2f142 100644 --- a/src/policy_eprand.cpp +++ b/src/policy_eprand.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "policy_eprand.hpp" + #include "errno.hpp" #include "policies.hpp" #include "policy.hpp" diff --git a/src/policy_erofs.cpp b/src/policy_erofs.cpp index 6bd53e45..733d2bd1 100644 --- a/src/policy_erofs.cpp +++ b/src/policy_erofs.cpp @@ -14,9 +14,10 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "policy_erofs.hpp" + #include "errno.hpp" #include "policy.hpp" -#include "policy_erofs.hpp" #include @@ -28,7 +29,7 @@ Policy::ERoFS::Action::operator()(const Branches::Ptr &branches_, const char *fusepath_, std::vector &paths_) const { - return (errno=EROFS,-1); + return -EROFS; } int @@ -36,7 +37,7 @@ Policy::ERoFS::Create::operator()(const Branches::Ptr &branches_, const char *fusepath_, std::vector &paths_) const { - return (errno=EROFS,-1); + return -EROFS; } int @@ -44,5 +45,5 @@ Policy::ERoFS::Search::operator()(const Branches::Ptr &branches_, const char *fusepath_, std::vector &paths_) const { - return (errno=EROFS,-1); + return -EROFS; } diff --git a/src/policy_ff.cpp b/src/policy_ff.cpp index 61881927..6195c38d 100644 --- a/src/policy_ff.cpp +++ b/src/policy_ff.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "policy_ff.hpp" + #include "errno.hpp" #include "fs_exists.hpp" #include "fs_info.hpp" @@ -26,37 +28,34 @@ #include -namespace ff +static +int +_create(const Branches::Ptr &ibranches_, + std::vector &obranches_) { - static - int - create(const Branches::Ptr &ibranches_, - std::vector &obranches_) - { - int rv; - int error; - fs::info_t info; - - error = ENOENT; - for(auto &branch : *ibranches_) - { - if(branch.ro_or_nc()) - error_and_continue(error,EROFS); - rv = fs::info(branch.path,&info); - if(rv == -1) - error_and_continue(error,ENOENT); - if(info.readonly) - error_and_continue(error,EROFS); - if(info.spaceavail < branch.minfreespace()) - error_and_continue(error,ENOSPC); - - obranches_.emplace_back(&branch); - - return 0; - } - - return (errno=error,-1); - } + int rv; + int error; + fs::info_t info; + + error = ENOENT; + for(auto &branch : *ibranches_) + { + if(branch.ro_or_nc()) + error_and_continue(error,EROFS); + rv = fs::info(branch.path,&info); + if(rv < 0) + error_and_continue(error,ENOENT); + if(info.readonly) + error_and_continue(error,EROFS); + if(info.spaceavail < branch.minfreespace()) + error_and_continue(error,ENOSPC); + + obranches_.emplace_back(&branch); + + return 0; + } + + return -error; } int @@ -72,7 +71,7 @@ Policy::FF::Create::operator()(const Branches::Ptr &branches_, const char *fusepath_, std::vector &paths_) const { - return ::ff::create(branches_,paths_); + return ::_create(branches_,paths_); } int @@ -90,5 +89,5 @@ Policy::FF::Search::operator()(const Branches::Ptr &branches_, return 0; } - return (errno=ENOENT,-1); + return -ENOENT; } diff --git a/src/policy_lfs.cpp b/src/policy_lfs.cpp index bf4f45c0..69a51456 100644 --- a/src/policy_lfs.cpp +++ b/src/policy_lfs.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "policy_lfs.hpp" + #include "errno.hpp" #include "fs_exists.hpp" #include "fs_info.hpp" @@ -28,47 +30,44 @@ #include -namespace lfs +static +int +_create(const Branches::Ptr &branches_, + std::vector &paths_) { - static - int - create(const Branches::Ptr &branches_, - std::vector &paths_) - { - int rv; - int error; - uint64_t lfs; - fs::info_t info; - Branch *obranch; + int rv; + int error; + uint64_t lfs; + fs::info_t info; + Branch *obranch; - obranch = nullptr; - error = ENOENT; - lfs = std::numeric_limits::max(); - for(auto &branch : *branches_) - { - if(branch.ro_or_nc()) - error_and_continue(error,EROFS); - rv = fs::info(branch.path,&info); - if(rv == -1) - error_and_continue(error,ENOENT); - if(info.readonly) - error_and_continue(error,EROFS); - if(info.spaceavail < branch.minfreespace()) - error_and_continue(error,ENOSPC); - if(info.spaceavail > lfs) - continue; + obranch = nullptr; + error = ENOENT; + lfs = std::numeric_limits::max(); + for(auto &branch : *branches_) + { + if(branch.ro_or_nc()) + error_and_continue(error,EROFS); + rv = fs::info(branch.path,&info); + if(rv < 0) + error_and_continue(error,ENOENT); + if(info.readonly) + error_and_continue(error,EROFS); + if(info.spaceavail < branch.minfreespace()) + error_and_continue(error,ENOSPC); + if(info.spaceavail > lfs) + continue; - lfs = info.spaceavail; - obranch = &branch; - } + lfs = info.spaceavail; + obranch = &branch; + } - if(!obranch) - return (errno=error,-1); + if(!obranch) + return -error; - paths_.push_back(obranch); + paths_.push_back(obranch); - return 0; - } + return 0; } int @@ -84,7 +83,7 @@ Policy::LFS::Create::operator()(const Branches::Ptr &branches_, const char *fusepath_, std::vector &paths_) const { - return ::lfs::create(branches_,paths_); + return ::_create(branches_,paths_); } int diff --git a/src/policy_lus.cpp b/src/policy_lus.cpp index 428a38e8..52410193 100644 --- a/src/policy_lus.cpp +++ b/src/policy_lus.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "policy_lus.hpp" + #include "errno.hpp" #include "fs_exists.hpp" #include "fs_info.hpp" @@ -31,47 +33,44 @@ using std::string; using std::vector; -namespace lus +static +int +_create(const Branches::Ptr &branches_, + std::vector &paths_) { - static - int - create(const Branches::Ptr &branches_, - std::vector &paths_) - { - int rv; - int error; - uint64_t lus; - fs::info_t info; - Branch *obranch; + int rv; + int error; + uint64_t lus; + fs::info_t info; + Branch *obranch; - obranch = nullptr; - error = ENOENT; - lus = std::numeric_limits::max(); - for(auto &branch : *branches_) - { - if(branch.ro_or_nc()) - error_and_continue(error,EROFS); - rv = fs::info(branch.path,&info); - if(rv == -1) - error_and_continue(error,ENOENT); - if(info.readonly) - error_and_continue(error,EROFS); - if(info.spaceavail < branch.minfreespace()) - error_and_continue(error,ENOSPC); - if(info.spaceused >= lus) - continue; + obranch = nullptr; + error = ENOENT; + lus = std::numeric_limits::max(); + for(auto &branch : *branches_) + { + if(branch.ro_or_nc()) + error_and_continue(error,EROFS); + rv = fs::info(branch.path,&info); + if(rv < 0) + error_and_continue(error,ENOENT); + if(info.readonly) + error_and_continue(error,EROFS); + if(info.spaceavail < branch.minfreespace()) + error_and_continue(error,ENOSPC); + if(info.spaceused >= lus) + continue; - lus = info.spaceused; - obranch = &branch; - } + lus = info.spaceused; + obranch = &branch; + } - if(!obranch) - return (errno=error,-1); + if(!obranch) + return -error; - paths_.push_back(obranch); + paths_.push_back(obranch); - return 0; - } + return 0; } int @@ -87,7 +86,7 @@ Policy::LUS::Create::operator()(const Branches::Ptr &branches_, const char *fusepath_, std::vector &paths_) const { - return ::lus::create(branches_,paths_); + return ::_create(branches_,paths_); } int diff --git a/src/policy_mfs.cpp b/src/policy_mfs.cpp index 0fee9047..049f68d5 100644 --- a/src/policy_mfs.cpp +++ b/src/policy_mfs.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "policy_mfs.hpp" + #include "errno.hpp" #include "fs_exists.hpp" #include "fs_info.hpp" @@ -26,47 +28,45 @@ using std::string; -namespace mfs + +static +int +_create(const Branches::Ptr &branches_, + std::vector &paths_) { - static - int - create(const Branches::Ptr &branches_, - std::vector &paths_) - { - int rv; - int error; - u64 mfs; - fs::info_t info; - Branch *obranch; - - obranch = nullptr; - error = ENOENT; - mfs = 0; - for(auto &branch : *branches_) - { - if(branch.ro_or_nc()) - error_and_continue(error,EROFS); - rv = fs::info(branch.path,&info); - if(rv == -1) - error_and_continue(error,ENOENT); - if(info.readonly) - error_and_continue(error,EROFS); - if(info.spaceavail < branch.minfreespace()) - error_and_continue(error,ENOSPC); - if(info.spaceavail < mfs) - continue; - - mfs = info.spaceavail; - obranch = &branch; - } - - if(!obranch) - return (errno=error,-1); - - paths_.push_back(obranch); - - return 0; - } + int rv; + int error; + u64 mfs; + fs::info_t info; + Branch *obranch; + + obranch = nullptr; + error = ENOENT; + mfs = 0; + for(auto &branch : *branches_) + { + if(branch.ro_or_nc()) + error_and_continue(error,EROFS); + rv = fs::info(branch.path,&info); + if(rv < 0) + error_and_continue(error,ENOENT); + if(info.readonly) + error_and_continue(error,EROFS); + if(info.spaceavail < branch.minfreespace()) + error_and_continue(error,ENOSPC); + if(info.spaceavail < mfs) + continue; + + mfs = info.spaceavail; + obranch = &branch; + } + + if(!obranch) + return -error; + + paths_.push_back(obranch); + + return 0; } int @@ -82,7 +82,7 @@ Policy::MFS::Create::operator()(const Branches::Ptr &branches_, const char *fusepath_, std::vector &paths_) const { - return ::mfs::create(branches_,paths_); + return ::_create(branches_,paths_); } int diff --git a/src/policy_msplfs.cpp b/src/policy_msplfs.cpp index ff782163..2918595e 100644 --- a/src/policy_msplfs.cpp +++ b/src/policy_msplfs.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "policy_msplfs.hpp" + #include "errno.hpp" #include "fs_exists.hpp" #include "fs_info.hpp" @@ -29,73 +31,70 @@ #include -namespace msplfs +static +Branch* +_create_1(const Branches::Ptr &branches_, + const std::string &fusepath_, + int *err_) +{ + int rv; + uint64_t lfs; + fs::info_t info; + Branch *obranch; + + obranch = nullptr; + lfs = std::numeric_limits::max(); + for(auto &branch : *branches_) + { + if(branch.ro_or_nc()) + error_and_continue(*err_,EROFS); + if(!fs::exists(branch.path,fusepath_)) + error_and_continue(*err_,ENOENT); + rv = fs::info(branch.path,&info); + if(rv < 0) + error_and_continue(*err_,ENOENT); + if(info.readonly) + error_and_continue(*err_,EROFS); + if(info.spaceavail < branch.minfreespace()) + error_and_continue(*err_,ENOSPC); + if(info.spaceavail > lfs) + continue; + + lfs = info.spaceavail; + obranch = &branch; + } + + return obranch; +} + +static +int +_create(const Branches::Ptr &branches_, + const char *fusepath_, + std::vector &paths_) { - static - Branch* - create_1(const Branches::Ptr &branches_, - const std::string &fusepath_, - int *err_) - { - int rv; - uint64_t lfs; - fs::info_t info; - Branch *obranch; - - obranch = nullptr; - lfs = std::numeric_limits::max(); - for(auto &branch : *branches_) - { - if(branch.ro_or_nc()) - error_and_continue(*err_,EROFS); - if(!fs::exists(branch.path,fusepath_)) - error_and_continue(*err_,ENOENT); - rv = fs::info(branch.path,&info); - if(rv == -1) - error_and_continue(*err_,ENOENT); - if(info.readonly) - error_and_continue(*err_,EROFS); - if(info.spaceavail < branch.minfreespace()) - error_and_continue(*err_,ENOSPC); - if(info.spaceavail > lfs) - continue; - - lfs = info.spaceavail; - obranch = &branch; - } - - return obranch; - } - - static - int - create(const Branches::Ptr &branches_, - const char *fusepath_, - std::vector &paths_) - { - int error; - Branch *branch; - std::string fusepath; - - error = ENOENT; - fusepath = fusepath_; - for(;;) - { - branch = msplfs::create_1(branches_,fusepath,&error); - if(branch) - break; - if(fusepath == "/") - break; - fusepath = fs::path::dirname(fusepath); - } - - if(!branch) - return (errno=error,-1); - - paths_.push_back(branch); - - return 0; - } + int error; + Branch *branch; + std::string fusepath; + + error = ENOENT; + fusepath = fusepath_; + for(;;) + { + branch = ::_create_1(branches_,fusepath,&error); + if(branch) + break; + if(fusepath == "/") + break; + fusepath = fs::path::dirname(fusepath); + } + + if(!branch) + return -error; + + paths_.push_back(branch); + + return 0; } int @@ -111,7 +110,7 @@ Policy::MSPLFS::Create::operator()(const Branches::Ptr &branches_, const char *fusepath_, std::vector &paths_) const { - return ::msplfs::create(branches_,fusepath_,paths_); + return ::_create(branches_,fusepath_,paths_); } int diff --git a/src/policy_msplus.cpp b/src/policy_msplus.cpp index b80f2d5f..b5340004 100644 --- a/src/policy_msplus.cpp +++ b/src/policy_msplus.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "policy_msplus.hpp" + #include "errno.hpp" #include "fs_exists.hpp" #include "fs_info.hpp" @@ -28,73 +30,70 @@ #include -namespace msplus +static +Branch* +_create_1(const Branches::Ptr &branches_, + const std::string &fusepath_, + int *err_) +{ + int rv; + uint64_t lus; + fs::info_t info; + Branch *obranch; + + obranch = nullptr; + lus = std::numeric_limits::max(); + for(auto &branch : *branches_) + { + if(branch.ro_or_nc()) + error_and_continue(*err_,-EROFS); + if(!fs::exists(branch.path,fusepath_)) + error_and_continue(*err_,-ENOENT); + rv = fs::info(branch.path,&info); + if(rv < 0) + error_and_continue(*err_,-ENOENT); + if(info.readonly) + error_and_continue(*err_,-EROFS); + if(info.spaceavail < branch.minfreespace()) + error_and_continue(*err_,-ENOSPC); + if(info.spaceused >= lus) + continue; + + lus = info.spaceused; + obranch = &branch; + } + + return obranch; +} + +static +int +_create(const Branches::Ptr &branches_, + const char *fusepath_, + std::vector &paths_) { - static - Branch* - create_1(const Branches::Ptr &branches_, - const std::string &fusepath_, - int *err_) - { - int rv; - uint64_t lus; - fs::info_t info; - Branch *obranch; - - obranch = nullptr; - lus = std::numeric_limits::max(); - for(auto &branch : *branches_) - { - if(branch.ro_or_nc()) - error_and_continue(*err_,EROFS); - if(!fs::exists(branch.path,fusepath_)) - error_and_continue(*err_,ENOENT); - rv = fs::info(branch.path,&info); - if(rv == -1) - error_and_continue(*err_,ENOENT); - if(info.readonly) - error_and_continue(*err_,EROFS); - if(info.spaceavail < branch.minfreespace()) - error_and_continue(*err_,ENOSPC); - if(info.spaceused >= lus) - continue; - - lus = info.spaceused; - obranch = &branch; - } - - return obranch; - } - - static - int - create(const Branches::Ptr &branches_, - const char *fusepath_, - std::vector &paths_) - { - int error; - Branch *branch; - std::string fusepath; - - error = ENOENT; - fusepath = fusepath_; - for(;;) - { - branch = msplus::create_1(branches_,fusepath,&error); - if(branch) - break; - if(fusepath == "/") - break; - fusepath = fs::path::dirname(fusepath); - } - - if(!branch) - return (errno=error,-1); - - paths_.emplace_back(branch); - - return 0; - } + int err; + Branch *branch; + std::string fusepath; + + err = -ENOENT; + fusepath = fusepath_; + for(;;) + { + branch = ::_create_1(branches_,fusepath,&err); + if(branch) + break; + if(fusepath == "/") + break; + fusepath = fs::path::dirname(fusepath); + } + + if(!branch) + return err; + + paths_.emplace_back(branch); + + return 0; } int @@ -110,7 +109,7 @@ Policy::MSPLUS::Create::operator()(const Branches::Ptr &branches_, const char *fusepath_, std::vector &paths_) const { - return ::msplus::create(branches_,fusepath_,paths_); + return ::_create(branches_,fusepath_,paths_); } int diff --git a/src/policy_mspmfs.cpp b/src/policy_mspmfs.cpp index 0a756022..2f93b681 100644 --- a/src/policy_mspmfs.cpp +++ b/src/policy_mspmfs.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "policy_mspmfs.hpp" + #include "errno.hpp" #include "fs_exists.hpp" #include "fs_info.hpp" @@ -29,73 +31,70 @@ #include -namespace mspmfs +static +Branch* +_create_1(const Branches::Ptr &branches_, + const std::string &fusepath_, + int *err_) +{ + int rv; + uint64_t mfs; + fs::info_t info; + Branch *obranch; + + obranch = nullptr; + mfs = std::numeric_limits::min(); + for(auto &branch : *branches_) + { + if(branch.ro_or_nc()) + error_and_continue(*err_,EROFS); + if(!fs::exists(branch.path,fusepath_)) + error_and_continue(*err_,ENOENT); + rv = fs::info(branch.path,&info); + if(rv < 0) + error_and_continue(*err_,ENOENT); + if(info.readonly) + error_and_continue(*err_,EROFS); + if(info.spaceavail < branch.minfreespace()) + error_and_continue(*err_,ENOSPC); + if(info.spaceavail < mfs) + continue; + + mfs = info.spaceavail; + obranch = &branch; + } + + return obranch; +} + +static +int +_create(const Branches::Ptr &branches_, + const char *fusepath_, + std::vector &paths_) { - static - Branch* - create_1(const Branches::Ptr &branches_, - const std::string &fusepath_, - int *err_) - { - int rv; - uint64_t mfs; - fs::info_t info; - Branch *obranch; - - obranch = nullptr; - mfs = std::numeric_limits::min(); - for(auto &branch : *branches_) - { - if(branch.ro_or_nc()) - error_and_continue(*err_,EROFS); - if(!fs::exists(branch.path,fusepath_)) - error_and_continue(*err_,ENOENT); - rv = fs::info(branch.path,&info); - if(rv == -1) - error_and_continue(*err_,ENOENT); - if(info.readonly) - error_and_continue(*err_,EROFS); - if(info.spaceavail < branch.minfreespace()) - error_and_continue(*err_,ENOSPC); - if(info.spaceavail < mfs) - continue; - - mfs = info.spaceavail; - obranch = &branch; - } - - return obranch; - } - - static - int - create(const Branches::Ptr &branches_, - const char *fusepath_, - std::vector &paths_) - { - int error; - std::string fusepath; - Branch *branch; - - error = ENOENT; - fusepath = fusepath_; - for(;;) - { - branch = mspmfs::create_1(branches_,fusepath,&error); - if(branch) - break; - if(fusepath == "/") - break; - fusepath = fs::path::dirname(fusepath); - } - - if(!branch) - return (errno=error,-1); - - paths_.emplace_back(branch); - - return 0; - } + int error; + std::string fusepath; + Branch *branch; + + error = ENOENT; + fusepath = fusepath_; + for(;;) + { + branch = ::_create_1(branches_,fusepath,&error); + if(branch) + break; + if(fusepath == "/") + break; + fusepath = fs::path::dirname(fusepath); + } + + if(!branch) + return -error; + + paths_.emplace_back(branch); + + return 0; } int @@ -111,7 +110,7 @@ Policy::MSPMFS::Create::operator()(const Branches::Ptr &branches_, const char *fusepath_, std::vector &paths_) const { - return ::mspmfs::create(branches_,fusepath_,paths_); + return ::_create(branches_,fusepath_,paths_); } int diff --git a/src/policy_msppfrd.cpp b/src/policy_msppfrd.cpp index 3a4322bd..55d41195 100644 --- a/src/policy_msppfrd.cpp +++ b/src/policy_msppfrd.cpp @@ -16,6 +16,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "policy_msppfrd.hpp" + #include "errno.hpp" #include "fs_exists.hpp" #include "fs_info.hpp" @@ -39,113 +41,110 @@ struct BranchInfo typedef std::vector BranchInfoVec; -namespace msppfrd +static +int +_create_1(const Branches::Ptr &branches_, + const std::string &fusepath_, + BranchInfoVec *branchinfo_, + uint64_t *sum_) { - static - int - create_1(const Branches::Ptr &branches_, - const std::string &fusepath_, - BranchInfoVec *branchinfo_, - uint64_t *sum_) - { - int rv; - int error; - fs::info_t info; - - *sum_ = 0; - error = ENOENT; - for(auto &branch : *branches_) - { - if(branch.ro_or_nc()) - error_and_continue(error,EROFS); - if(!fs::exists(branch.path,fusepath_)) - error_and_continue(error,ENOENT); - rv = fs::info(branch.path,&info); - if(rv == -1) - error_and_continue(error,ENOENT); - if(info.readonly) - error_and_continue(error,EROFS); - if(info.spaceavail < branch.minfreespace()) - error_and_continue(error,ENOSPC); - - *sum_ += info.spaceavail; - - branchinfo_->push_back({info.spaceavail,&branch}); - } - - return error; - } - - static - int - get_branchinfo(const Branches::Ptr &branches_, - const char *fusepath_, - BranchInfoVec *branchinfo_, - uint64_t *sum_) - { - int error; - std::string fusepath; - - fusepath = fusepath_; - for(;;) - { - error = msppfrd::create_1(branches_,fusepath,branchinfo_,sum_); - if(branchinfo_->size()) - break; - if(fusepath == "/") - break; - fusepath = fs::path::dirname(fusepath); - } - - return error; - } - - static - Branch* - get_branch(const BranchInfoVec &branchinfo_, - const uint64_t sum_) - { - uint64_t idx; - uint64_t threshold; - - if(sum_ == 0) - return nullptr; - - idx = 0; - threshold = RND::rand64(sum_); - for(size_t i = 0; i < branchinfo_.size(); i++) - { - idx += branchinfo_[i].spaceavail; - - if(idx < threshold) - continue; - - return branchinfo_[i].branch; - } + int rv; + int error; + fs::info_t info; + + *sum_ = 0; + error = ENOENT; + for(auto &branch : *branches_) + { + if(branch.ro_or_nc()) + error_and_continue(error,EROFS); + if(!fs::exists(branch.path,fusepath_)) + error_and_continue(error,ENOENT); + rv = fs::info(branch.path,&info); + if(rv < 0) + error_and_continue(error,ENOENT); + if(info.readonly) + error_and_continue(error,EROFS); + if(info.spaceavail < branch.minfreespace()) + error_and_continue(error,ENOSPC); + + *sum_ += info.spaceavail; + + branchinfo_->push_back({info.spaceavail,&branch}); + } + + return -error; +} +static +int +_get_branchinfo(const Branches::Ptr &branches_, + const char *fusepath_, + BranchInfoVec *branchinfo_, + uint64_t *sum_) +{ + int rv; + std::string fusepath; + + fusepath = fusepath_; + for(;;) + { + rv = ::_create_1(branches_,fusepath,branchinfo_,sum_); + if(branchinfo_->size()) + break; + if(fusepath == "/") + break; + fusepath = fs::path::dirname(fusepath); + } + + return rv; +} + +static +Branch* +_get_branch(const BranchInfoVec &branchinfo_, + const uint64_t sum_) +{ + uint64_t idx; + uint64_t threshold; + + if(sum_ == 0) return nullptr; - } - - static - int - create(const Branches::Ptr &branches_, - const char *fusepath_, - std::vector &paths_) - { - int error; - uint64_t sum; - Branch *branch; - BranchInfoVec branchinfo; - - error = msppfrd::get_branchinfo(branches_,fusepath_,&branchinfo,&sum); - branch = msppfrd::get_branch(branchinfo,sum); - if(!branch) - return (errno=error,-1); - - paths_.emplace_back(branch); - - return 0; - } + + idx = 0; + threshold = RND::rand64(sum_); + for(const auto &branchinfo : branchinfo_) + { + idx += branchinfo.spaceavail; + + if(idx < threshold) + continue; + + return branchinfo.branch; + } + + return nullptr; +} + +static +int +_create(const Branches::Ptr &branches_, + const char *fusepath_, + std::vector &paths_) +{ + int rv; + uint64_t sum; + Branch *branch; + BranchInfoVec branchinfo; + + rv = ::_get_branchinfo(branches_,fusepath_,&branchinfo,&sum); + branch = ::_get_branch(branchinfo,sum); + if(!branch) + return rv; + + paths_.emplace_back(branch); + + return 0; } int @@ -161,7 +160,7 @@ Policy::MSPPFRD::Create::operator()(const Branches::Ptr &branches_, const char *fusepath_, std::vector &paths_) const { - return ::msppfrd::create(branches_,fusepath_,paths_); + return ::_create(branches_,fusepath_,paths_); } int diff --git a/src/policy_newest.cpp b/src/policy_newest.cpp index 542c9d9f..8dc0b99f 100644 --- a/src/policy_newest.cpp +++ b/src/policy_newest.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "policy_newest.hpp" + #include "errno.hpp" #include "fs_exists.hpp" #include "fs_info.hpp" @@ -31,124 +33,121 @@ using std::string; -namespace newest +static +int +_create(const Branches::Ptr &branches_, + const char *fusepath_, + std::vector &paths_) +{ + int rv; + int err; + time_t newest; + struct stat st; + fs::info_t info; + Branch *obranch; + + obranch = nullptr; + err = ENOENT; + newest = std::numeric_limits::min(); + for(auto &branch : *branches_) + { + if(branch.ro_or_nc()) + error_and_continue(err,EROFS); + if(!fs::exists(branch.path,fusepath_,&st)) + error_and_continue(err,ENOENT); + if(st.st_mtime < newest) + continue; + rv = fs::info(branch.path,&info); + if(rv < 0) + error_and_continue(err,ENOENT); + if(info.readonly) + error_and_continue(err,EROFS); + if(info.spaceavail < branch.minfreespace()) + error_and_continue(err,ENOSPC); + + newest = st.st_mtime; + obranch = &branch; + } + + if(!obranch) + return -err; + + paths_.emplace_back(obranch); + + return 0; +} + +static +int +_action(const Branches::Ptr &branches_, + const char *fusepath_, + std::vector &paths_) +{ + int rv; + int err; + bool readonly; + time_t newest; + struct stat st; + Branch *obranch; + + obranch = nullptr; + err = ENOENT; + newest = std::numeric_limits::min(); + for(auto &branch : *branches_) + { + if(branch.ro()) + error_and_continue(err,EROFS); + if(!fs::exists(branch.path,fusepath_,&st)) + error_and_continue(err,ENOENT); + if(st.st_mtime < newest) + continue; + rv = fs::statvfs_cache_readonly(branch.path,&readonly); + if(rv < 0) + error_and_continue(err,ENOENT); + if(readonly) + error_and_continue(err,EROFS); + + newest = st.st_mtime; + obranch = &branch; + } + + if(!obranch) + return -err; + + paths_.emplace_back(obranch); + + return 0; +} + +static +int +_search(const Branches::Ptr &branches_, + const char *fusepath_, + std::vector &paths_) { - static - int - create(const Branches::Ptr &branches_, - const char *fusepath_, - std::vector &paths_) - { - int rv; - int error; - time_t newest; - struct stat st; - fs::info_t info; - Branch *obranch; - - obranch = nullptr; - error = ENOENT; - newest = std::numeric_limits::min(); - for(auto &branch : *branches_) - { - if(branch.ro_or_nc()) - error_and_continue(error,EROFS); - if(!fs::exists(branch.path,fusepath_,&st)) - error_and_continue(error,ENOENT); - if(st.st_mtime < newest) - continue; - rv = fs::info(branch.path,&info); - if(rv == -1) - error_and_continue(error,ENOENT); - if(info.readonly) - error_and_continue(error,EROFS); - if(info.spaceavail < branch.minfreespace()) - error_and_continue(error,ENOSPC); - - newest = st.st_mtime; - obranch = &branch; - } - - if(!obranch) - return (errno=error,-1); - - paths_.emplace_back(obranch); - - return 0; - } - - static - int - action(const Branches::Ptr &branches_, - const char *fusepath_, - std::vector &paths_) - { - int rv; - int error; - bool readonly; - time_t newest; - struct stat st; - Branch *obranch; - - obranch = nullptr; - error = ENOENT; - newest = std::numeric_limits::min(); - for(auto &branch : *branches_) - { - if(branch.ro()) - error_and_continue(error,EROFS); - if(!fs::exists(branch.path,fusepath_,&st)) - error_and_continue(error,ENOENT); - if(st.st_mtime < newest) - continue; - rv = fs::statvfs_cache_readonly(branch.path,&readonly); - if(rv == -1) - error_and_continue(error,ENOENT); - if(readonly) - error_and_continue(error,EROFS); - - newest = st.st_mtime; - obranch = &branch; - } - - if(!obranch) - return (errno=error,-1); - - paths_.emplace_back(obranch); - - return 0; - } - - static - int - search(const Branches::Ptr &branches_, - const char *fusepath_, - std::vector &paths_) - { - time_t newest; - struct stat st; - Branch *obranch; - - obranch = nullptr; - newest = std::numeric_limits::min(); - for(auto &branch : *branches_) - { - if(!fs::exists(branch.path,fusepath_,&st)) - continue; - if(st.st_mtime < newest) - continue; - - newest = st.st_mtime; - obranch = &branch; - } - - if(!obranch) - return (errno=ENOENT,-1); - - paths_.emplace_back(obranch); - - return 0; - } + time_t newest; + struct stat st; + Branch *obranch; + + obranch = nullptr; + newest = std::numeric_limits::min(); + for(auto &branch : *branches_) + { + if(!fs::exists(branch.path,fusepath_,&st)) + continue; + if(st.st_mtime < newest) + continue; + + newest = st.st_mtime; + obranch = &branch; + } + + if(!obranch) + return -ENOENT; + + paths_.emplace_back(obranch); + + return 0; } int @@ -156,7 +155,7 @@ Policy::Newest::Action::operator()(const Branches::Ptr &branches_, const char *fusepath_, std::vector &paths_) const { - return ::newest::action(branches_,fusepath_,paths_); + return ::_action(branches_,fusepath_,paths_); } int @@ -164,7 +163,7 @@ Policy::Newest::Create::operator()(const Branches::Ptr &branches_, const char *fusepath_, std::vector &paths_) const { - return ::newest::create(branches_,fusepath_,paths_); + return ::_create(branches_,fusepath_,paths_); } int @@ -172,5 +171,5 @@ Policy::Newest::Search::operator()(const Branches::Ptr &branches_, const char *fusepath_, std::vector &paths_) const { - return ::newest::search(branches_,fusepath_,paths_); + return ::_search(branches_,fusepath_,paths_); } diff --git a/src/policy_pfrd.cpp b/src/policy_pfrd.cpp index 5631a0d3..49530056 100644 --- a/src/policy_pfrd.cpp +++ b/src/policy_pfrd.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "policy_pfrd.hpp" + #include "errno.hpp" #include "fs_info.hpp" #include "fs_path.hpp" @@ -36,86 +38,83 @@ struct BranchInfo typedef std::vector BranchInfoVec; -namespace pfrd +static +int +_get_branchinfo(const Branches::Ptr &branches_, + BranchInfoVec *branchinfo_, + uint64_t *sum_) { - static - int - get_branchinfo(const Branches::Ptr &branches_, - BranchInfoVec *branchinfo_, - uint64_t *sum_) - { - int rv; - int error; - fs::info_t info; - - *sum_ = 0; - error = ENOENT; - for(auto &branch : *branches_) - { - if(branch.ro_or_nc()) - error_and_continue(error,EROFS); - rv = fs::info(branch.path,&info); - if(rv == -1) - error_and_continue(error,ENOENT); - if(info.readonly) - error_and_continue(error,EROFS); - if(info.spaceavail < branch.minfreespace()) - error_and_continue(error,ENOSPC); - - *sum_ += info.spaceavail; - - branchinfo_->push_back({info.spaceavail,&branch}); - } - - return error; - } - - static - Branch* - get_branch(const BranchInfoVec &branchinfo_, - const uint64_t sum_) - { - uint64_t idx; - uint64_t threshold; - - if(sum_ == 0) - return nullptr; - - idx = 0; - threshold = RND::rand64(sum_); - for(auto &bi : branchinfo_) - { - idx += bi.spaceavail; - - if(idx < threshold) - continue; - - return bi.branch; - } + int rv; + int err; + fs::info_t info; + + *sum_ = 0; + err = ENOENT; + for(auto &branch : *branches_) + { + if(branch.ro_or_nc()) + error_and_continue(err,EROFS); + rv = fs::info(branch.path,&info); + if(rv < 0) + error_and_continue(err,ENOENT); + if(info.readonly) + error_and_continue(err,EROFS); + if(info.spaceavail < branch.minfreespace()) + error_and_continue(err,ENOSPC); + + *sum_ += info.spaceavail; + + branchinfo_->push_back({info.spaceavail,&branch}); + } + + return -err; +} +static +Branch* +_get_branch(const BranchInfoVec &branchinfo_, + const uint64_t sum_) +{ + uint64_t idx; + uint64_t threshold; + + if(sum_ == 0) return nullptr; - } - - static - int - create(const Branches::Ptr &branches_, - const char *fusepath_, - std::vector &paths_) - { - int error; - uint64_t sum; - Branch *branch; - BranchInfoVec branchinfo; - - error = pfrd::get_branchinfo(branches_,&branchinfo,&sum); - branch = pfrd::get_branch(branchinfo,sum); - if(!branch) - return (errno=error,-1); - - paths_.emplace_back(branch); - - return 0; - } + + idx = 0; + threshold = RND::rand64(sum_); + for(const auto &bi : branchinfo_) + { + idx += bi.spaceavail; + + if(idx < threshold) + continue; + + return bi.branch; + } + + return nullptr; +} + +static +int +_create(const Branches::Ptr &branches_, + const char *fusepath_, + std::vector &paths_) +{ + int err; + uint64_t sum; + Branch *branch; + BranchInfoVec branchinfo; + + err = ::_get_branchinfo(branches_,&branchinfo,&sum); + branch = ::_get_branch(branchinfo,sum); + if(!branch) + return err; + + paths_.emplace_back(branch); + + return 0; } int @@ -131,7 +130,7 @@ Policy::PFRD::Create::operator()(const Branches::Ptr &branches_, const char *fusepath_, std::vector &paths_) const { - return ::pfrd::create(branches_,fusepath_,paths_); + return ::_create(branches_,fusepath_,paths_); } int diff --git a/src/policy_rand.cpp b/src/policy_rand.cpp index 8a6d9a2e..94cc3d6a 100644 --- a/src/policy_rand.cpp +++ b/src/policy_rand.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "policy_rand.hpp" + #include "errno.hpp" #include "policy.hpp" #include "policy_rand.hpp" diff --git a/src/policy_rv.hpp b/src/policy_rv.hpp index 71d1341b..3abcbdb0 100644 --- a/src/policy_rv.hpp +++ b/src/policy_rv.hpp @@ -40,13 +40,13 @@ struct PolicyRV std::vector errors; void - insert(const int err_, + insert(const int rv_, const std::string &basepath_) { - if(err_ == 0) - successes.push_back({err_,basepath_}); + if(rv_ >= 0) + successes.push_back({rv_,basepath_}); else - errors.push_back({-err_,basepath_}); + errors.push_back({rv_,basepath_}); } int @@ -64,6 +64,6 @@ struct PolicyRV return e.rv; } - return 0; + return -ENOENT; } }; diff --git a/src/procfs.cpp b/src/procfs.cpp index 1a96c9b2..52a9a4c2 100644 --- a/src/procfs.cpp +++ b/src/procfs.cpp @@ -35,12 +35,16 @@ _open_proc_self_fd() int procfs::init() { - if(g_PROCFS_DIR_FD != -1) + int rv; + + if(g_PROCFS_DIR_FD >= 0) return 0; - g_PROCFS_DIR_FD = fs::open(PROCFS_PATH,O_PATH|O_DIRECTORY); - if(g_PROCFS_DIR_FD == -1) - return -errno; + rv = fs::open(PROCFS_PATH,O_PATH|O_DIRECTORY); + if(rv < 0) + return rv; + + g_PROCFS_DIR_FD = rv; #if defined(__linux__) ::_open_proc_self_fd(); @@ -65,7 +69,7 @@ procfs::get_name(const int tid_) return {}; rv = fs::read(fd,commpath.data(),commpath.size()); - if(rv == -1) + if(rv < 0) return {}; // Overwrite the newline with NUL diff --git a/src/resources.cpp b/src/resources.cpp index 734b25a4..3df5d2d4 100644 --- a/src/resources.cpp +++ b/src/resources.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "errno.hpp" + #include #include #include @@ -43,7 +45,7 @@ namespace resources rv = ::getrlimit(resource,&rlim); if(rv == -1) - return -1; + return -errno; rv = 0; rlim.rlim_cur = rlim.rlim_max; @@ -72,8 +74,11 @@ namespace resources int setpriority(const int prio) { + int rv; const int SELF = 0; - return ::setpriority(PRIO_PROCESS,SELF,prio); + rv = ::setpriority(PRIO_PROCESS,SELF,prio); + + return ((rv == -1) ? -errno : rv); } } diff --git a/src/to_neg_errno.hpp b/src/to_neg_errno.hpp new file mode 100644 index 00000000..afdc81a0 --- /dev/null +++ b/src/to_neg_errno.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include + + +template +static +inline +T +to_neg_errno(const T rv_, + const int errno_) +{ + return ((rv_ == (T)-1) ? -errno_ : rv_); +} + +template +static +inline +T +to_neg_errno(const T rv_) +{ + return ::to_neg_errno(rv_,errno); +}