diff --git a/src/fuse_create.cpp b/src/fuse_create.cpp index ce9d71d2..7cb81ed3 100644 --- a/src/fuse_create.cpp +++ b/src/fuse_create.cpp @@ -14,198 +14,23 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "toml.hpp" - -#include "config.hpp" -#include "errno.hpp" -#include "fileinfo.hpp" -#include "fs_acl.hpp" -#include "fs_clonepath.hpp" -#include "fs_open.hpp" -#include "fs_path.hpp" #include "state.hpp" #include "ugid.hpp" #include "fuse.h" -#include -#include - -using std::string; -using std::vector; - - -namespace l -{ - /* - The kernel expects being able to issue read requests when running - with writeback caching enabled so we must change O_WRONLY to - O_RDWR. - - With writeback caching enabled the kernel handles O_APPEND. Could - be an issue if the underlying file changes out of band but that is - true of any caching. - */ - static - void - tweak_flags_writeback_cache(int *flags_) - { - if((*flags_ & O_ACCMODE) == O_WRONLY) - *flags_ = ((*flags_ & ~O_ACCMODE) | O_RDWR); - if(*flags_ & O_APPEND) - *flags_ &= ~O_APPEND; - } - - static - void - config_to_ffi_flags(Config::Read &cfg_, - fuse_file_info_t *ffi_) - { - switch(cfg_->cache_files) - { - case CacheFiles::ENUM::LIBFUSE: - ffi_->direct_io = cfg_->direct_io; - ffi_->keep_cache = cfg_->kernel_cache; - ffi_->auto_cache = cfg_->auto_cache; - break; - case CacheFiles::ENUM::OFF: - ffi_->direct_io = 1; - ffi_->keep_cache = 0; - ffi_->auto_cache = 0; - break; - case CacheFiles::ENUM::PARTIAL: - ffi_->direct_io = 0; - ffi_->keep_cache = 0; - ffi_->auto_cache = 0; - break; - case CacheFiles::ENUM::FULL: - ffi_->direct_io = 0; - ffi_->keep_cache = 1; - ffi_->auto_cache = 0; - break; - case CacheFiles::ENUM::AUTO_FULL: - ffi_->direct_io = 0; - ffi_->keep_cache = 0; - ffi_->auto_cache = 1; - break; - } - } - - static - int - create_core(const string &fullpath_, - mode_t mode_, - const mode_t umask_, - const int flags_) - { - if(!fs::acl::dir_has_defaults(fullpath_)) - mode_ &= ~umask_; - - return fs::open(fullpath_,flags_,mode_); - } - - static - int - create_core(const string &createpath_, - const char *fusepath_, - const mode_t mode_, - const mode_t umask_, - const int flags_, - uint64_t *fh_) - { - int rv; - string fullpath; - - fullpath = fs::path::make(createpath_,fusepath_); - - rv = l::create_core(fullpath,mode_,umask_,flags_); - if(rv == -1) - return -errno; - - *fh_ = reinterpret_cast(new FileInfo(rv,fusepath_)); - - return 0; - } - - static - int - create(const Policy::Search &searchFunc_, - const Policy::Create &createFunc_, - const Branches &branches_, - const char *fusepath_, - const mode_t mode_, - const mode_t umask_, - const int flags_, - uint64_t *fh_) - { - int rv; - string fullpath; - string fusedirpath; - StrVec createpaths; - StrVec existingpaths; - - fusedirpath = fs::path::dirname(fusepath_); - - rv = searchFunc_(branches_,fusedirpath,&existingpaths); - if(rv == -1) - return -errno; - - rv = createFunc_(branches_,fusedirpath,&createpaths); - if(rv == -1) - return -errno; - - rv = fs::clonepath_as_root(existingpaths[0],createpaths[0],fusedirpath); - if(rv == -1) - return -errno; - - return l::create_core(createpaths[0], - fusepath_, - mode_, - umask_, - flags_, - fh_); - } -} namespace FUSE::CREATE { - int - create2(const char *fusepath_, - mode_t mode_, - fuse_file_info_t *ffi_) - { - Config::Read cfg; - const fuse_context *fc = fuse_get_context(); - const ugid::Set ugid(fc->uid,fc->gid); - - l::config_to_ffi_flags(cfg,ffi_); - - if(cfg->writeback_cache) - l::tweak_flags_writeback_cache(&ffi_->flags); - - return l::create(cfg->func.getattr.policy, - cfg->func.create.policy, - cfg->branches, - fusepath_, - mode_, - fc->umask, - ffi_->flags, - &ffi_->fh); - } - int create(const char *fusepath_, mode_t mode_, fuse_file_info_t *ffi_) { State s; - gfs::path fusepath(fusepath_); const fuse_context *fc = fuse_get_context(); const ugid::Set ugid(fc->uid,fc->gid); - if(s->writeback_cache) - l::tweak_flags_writeback_cache(&ffi_->flags); - - return s->create(fusepath,mode_,fc->umask,ffi_); + return s->create(&fusepath_[1],mode_,fc->umask,ffi_); } } diff --git a/src/fuse_init.cpp b/src/fuse_init.cpp index 0f2bb0ef..ddecc9ff 100644 --- a/src/fuse_init.cpp +++ b/src/fuse_init.cpp @@ -14,8 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "config.hpp" #include "ugid.hpp" +#include "state.hpp" #include "fuse.h" @@ -51,7 +51,7 @@ namespace l void want_if_capable(fuse_conn_info *conn_, const int flag_, - ConfigBOOL *want_) + bool *want_) { if(*want_ && l::capable(conn_,flag_)) { @@ -65,16 +65,16 @@ namespace l static void want_if_capable_max_pages(fuse_conn_info *conn_, - Config::Write &cfg_) + State &s_) { if(l::capable(conn_,FUSE_CAP_MAX_PAGES)) { l::want(conn_,FUSE_CAP_MAX_PAGES); - conn_->max_pages = cfg_->fuse_msg_size; + conn_->max_pages = s_->fuse_msg_size; } else { - cfg_->fuse_msg_size = FUSE_DEFAULT_MAX_PAGES_PER_REQ; + s_->fuse_msg_size = FUSE_DEFAULT_MAX_PAGES_PER_REQ; } } } @@ -84,23 +84,34 @@ namespace FUSE::INIT void * init(fuse_conn_info *conn_) { - Config::Write cfg; + State s; + bool async_read; + bool posix_acl; + bool wb_cache; + bool readdirplus; + bool cache_symlinks; + async_read = toml::find_or(s->config_toml,"fuse","async-read",true); + posix_acl = toml::find_or(s->config_toml,"fuse","posix-acl",false); + wb_cache = toml::find_or(s->config_toml,"cache","writeback",false); + readdirplus = toml::find_or(s->config_toml,"func","readdir","readdirplus",false); + cache_symlinks = toml::find_or(s->config_toml,"cache","symlinks",false); + ugid::init(); 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_ASYNC_READ,&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_CACHE_SYMLINKS,&cache_symlinks); l::want_if_capable(conn_,FUSE_CAP_DONT_MASK); 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_READDIR_PLUS,&cfg->readdirplus); + l::want_if_capable(conn_,FUSE_CAP_READDIR_PLUS,&readdirplus); //l::want_if_capable(conn_,FUSE_CAP_READDIR_PLUS_AUTO); - l::want_if_capable(conn_,FUSE_CAP_POSIX_ACL,&cfg->posix_acl); - l::want_if_capable(conn_,FUSE_CAP_WRITEBACK_CACHE,&cfg->writeback_cache); - l::want_if_capable_max_pages(conn_,cfg); + l::want_if_capable(conn_,FUSE_CAP_POSIX_ACL,&posix_acl); + l::want_if_capable(conn_,FUSE_CAP_WRITEBACK_CACHE,&wb_cache); + l::want_if_capable_max_pages(conn_,s); conn_->want &= ~FUSE_CAP_POSIX_LOCKS; conn_->want &= ~FUSE_CAP_FLOCK_LOCKS; diff --git a/src/fuse_link.cpp b/src/fuse_link.cpp index a3d39473..f3585a25 100644 --- a/src/fuse_link.cpp +++ b/src/fuse_link.cpp @@ -14,129 +14,12 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "config.hpp" -#include "errno.hpp" -#include "fs_clonepath.hpp" -#include "fs_link.hpp" -#include "fs_lstat.hpp" -#include "fs_path.hpp" -#include "fuse_getattr.hpp" -#include "fuse_symlink.hpp" #include "state.hpp" #include "ugid.hpp" #include "fuse.h" -namespace l -{ - static - int - link_exdev_rel_symlink(const char *oldpath_, - const char *newpath_, - struct stat *st_, - fuse_timeouts_t *timeouts_) - { - int rv; - gfs::path target(oldpath_); - gfs::path linkpath(newpath_); - - target = target.lexically_relative(linkpath.parent_path()); - - rv = FUSE::SYMLINK::symlink(target.c_str(),linkpath.c_str()); - if(rv == 0) - rv = FUSE::GETATTR::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_base_symlink(const char *oldpath_, - const char *newpath_, - struct stat *st_, - fuse_timeouts_t *timeouts_) - { - int rv; - StrVec basepaths; - gfs::path target; - - target = "FIXME"; - - rv = FUSE::SYMLINK::symlink(target.c_str(),newpath_); - if(rv == 0) - rv = FUSE::GETATTR::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 gfs::path &mount_, - const char *oldpath_, - const char *newpath_, - struct stat *st_, - fuse_timeouts_t *timeouts_) - { - int rv; - gfs::path target; - - target = mount_ / &oldpath_[1]; - - rv = FUSE::SYMLINK::symlink(target.c_str(),newpath_); - if(rv == 0) - rv = FUSE::GETATTR::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(State &s_, - const char *oldpath_, - const char *newpath_, - struct stat *st_, - fuse_timeouts_t *timeouts_) - { - switch(s_->link_exdev) - { - case LinkEXDEV::INVALID: - case LinkEXDEV::PASSTHROUGH: - return -EXDEV; - case LinkEXDEV::REL_SYMLINK: - return l::link_exdev_rel_symlink(oldpath_, - newpath_, - st_, - timeouts_); - case LinkEXDEV::ABS_BASE_SYMLINK: - return l::link_exdev_abs_base_symlink(oldpath_, - newpath_, - st_, - timeouts_); - case LinkEXDEV::ABS_POOL_SYMLINK: - return l::link_exdev_abs_pool_symlink(s_->mountpoint, - oldpath_, - newpath_, - st_, - timeouts_); - } - - return -EXDEV; - } -} - namespace FUSE::LINK { int @@ -155,8 +38,8 @@ namespace FUSE::LINK oldpath = &oldpath_[1]; newpath = &newpath_[1]; rv = s->link(oldpath,newpath); - if(rv == -EXDEV) - return l::link_exdev(s,oldpath_,newpath_,st_,timeouts_); + if(rv < 0) + return rv; return s->getattr(newpath,st_,timeouts_); } diff --git a/src/fuse_mkdir.cpp b/src/fuse_mkdir.cpp index b4c1652e..d761a4ae 100644 --- a/src/fuse_mkdir.cpp +++ b/src/fuse_mkdir.cpp @@ -14,137 +14,11 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "config.hpp" -#include "errno.hpp" -#include "fs_acl.hpp" -#include "fs_clonepath.hpp" -#include "fs_mkdir.hpp" -#include "fs_path.hpp" -#include "ghc/filesystem.hpp" -#include "policy.hpp" #include "state.hpp" #include "ugid.hpp" #include "fuse.h" -#include - -using std::string; - - -namespace error -{ - 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; - } -} - -namespace l -{ - static - int - mkdir_core(const 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 string &createpath_, - const char *fusepath_, - const mode_t mode_, - const mode_t umask_, - const int error_) - { - int rv; - 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 string &existingpath_, - const StrVec &createpaths_, - const char *fusepath_, - const string &fusedirpath_, - const mode_t mode_, - const mode_t umask_) - { - int rv; - int error; - - error = -1; - for(size_t i = 0, ei = createpaths_.size(); i != ei; i++) - { - rv = fs::clonepath_as_root(existingpath_,createpaths_[i],fusedirpath_); - if(rv == -1) - error = error::calc(rv,error,errno); - else - error = l::mkdir_loop_core(createpaths_[i], - 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; - string fusedirpath; - StrVec createpaths; - StrVec existingpaths; - - fusedirpath = fs::path::dirname(fusepath_); - - rv = getattrPolicy_(branches_,fusedirpath.c_str(),&existingpaths); - if(rv == -1) - return -errno; - - rv = mkdirPolicy_(branches_,fusedirpath.c_str(),&createpaths); - if(rv == -1) - return -errno; - - return l::mkdir_loop(existingpaths[0], - createpaths, - fusepath_, - fusedirpath, - mode_, - umask_); - } -} namespace FUSE::MKDIR { @@ -153,11 +27,9 @@ namespace FUSE::MKDIR mode_t mode_) { State s; - gfs::path fusepath; const fuse_context *fc = fuse_get_context(); const ugid::Set ugid(fc->uid,fc->gid); - fusepath = &fusepath_[1]; - return s->mkdir(fusepath,mode_,fc->umask); + return s->mkdir(&fusepath_[1],mode_,fc->umask); } } diff --git a/src/fuse_readdir_plus.cpp b/src/fuse_readdir_plus.cpp deleted file mode 100644 index 7363bf18..00000000 --- a/src/fuse_readdir_plus.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* - ISC License - - Copyright (c) 2020, 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 "fuse_readdir_plus_linux.hpp" -#include "fuse_readdir_plus_posix.hpp" - -#include "config.hpp" -#include "dirinfo.hpp" -#include "rwlock.hpp" -#include "ugid.hpp" - -#include "fuse.h" - - -namespace FUSE::READDIR_PLUS -{ - int - readdir_plus(const fuse_file_info_t *ffi_, - fuse_dirents_t *buf_) - { - Config::Read cfg; - DirInfo *di = reinterpret_cast(ffi_->fh); - const fuse_context *fc = fuse_get_context(); - const ugid::Set ugid(fc->uid,fc->gid); - - switch(cfg->readdir) - { - case ReadDir::ENUM::LINUX: - return FUSE::READDIR_PLUS_LINUX::readdir_plus_linux(cfg->branches, - di->fusepath.c_str(), - cfg->cache_entry, - cfg->cache_attr, - buf_); - default: - case ReadDir::ENUM::POSIX: - return FUSE::READDIR_PLUS_POSIX::readdir_plus_posix(cfg->branches, - di->fusepath.c_str(), - cfg->cache_entry, - cfg->cache_attr, - buf_); - } - } -} diff --git a/src/fuse_readdirplus.cpp b/src/fuse_readdirplus.cpp new file mode 100644 index 00000000..41792dfb --- /dev/null +++ b/src/fuse_readdirplus.cpp @@ -0,0 +1,37 @@ +/* + ISC License + + Copyright (c) 2022, 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 "state.hpp" +#include "ugid.hpp" + +#include "fuse.h" + + +namespace FUSE::READDIRPLUS +{ + int + readdirplus(const fuse_file_info_t *ffi_, + fuse_dirents_t *buf_) + { + State s; + const fuse_context *fc = fuse_get_context(); + const ugid::Set ugid(fc->uid,fc->gid); + + return s->readdirplus(ffi_,buf_); + } +} diff --git a/src/fuse_readdir_plus.hpp b/src/fuse_readdirplus.hpp similarity index 87% rename from src/fuse_readdir_plus.hpp rename to src/fuse_readdirplus.hpp index 83cee2b1..a9d182fc 100644 --- a/src/fuse_readdir_plus.hpp +++ b/src/fuse_readdirplus.hpp @@ -19,9 +19,9 @@ #include "fuse.h" -namespace FUSE::READDIR_PLUS +namespace FUSE::READDIRPLUS { int - readdir_plus(const fuse_file_info_t *ffi, - fuse_dirents_t *buf); + readdirplus(const fuse_file_info_t *ffi, + fuse_dirents_t *buf); } diff --git a/src/fuse_readdirplus_policy.hpp b/src/fuse_readdirplus_policy.hpp new file mode 100644 index 00000000..5f2d8c18 --- /dev/null +++ b/src/fuse_readdirplus_policy.hpp @@ -0,0 +1,48 @@ +/* + ISC License + + Copyright (c) 2022, 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 "fuse_readdirplus_policy_base.hpp" +#include "fuse_readdirplus_policy_factory.hpp" + +#include "fuse.h" + + +namespace FUSE::READDIRPLUS +{ + class Policy + { + public: + Policy(const toml::value &toml_) + { + _readdirplus = POLICY::factory(toml_); + } + + public: + int + operator()(const fuse_file_info_t *ffi_, + fuse_dirents_t *buf_) + { + return (*_readdirplus)(ffi_,buf_); + } + + private: + POLICY::Base::Ptr _readdirplus; + }; +} diff --git a/src/fuse_readdirplus_policy_base.hpp b/src/fuse_readdirplus_policy_base.hpp new file mode 100644 index 00000000..9f3b9c06 --- /dev/null +++ b/src/fuse_readdirplus_policy_base.hpp @@ -0,0 +1,37 @@ +/* + ISC License + + Copyright (c) 2022, 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 "fuse.h" + +#include + + +namespace FUSE::READDIRPLUS::POLICY +{ + class Base + { + public: + typedef std::shared_ptr Ptr; + + public: + virtual int operator()(const fuse_file_info_t *ffi, + fuse_dirents_t *buf) = 0; + }; +} diff --git a/src/fuse_readdirplus_policy_enosys.cpp b/src/fuse_readdirplus_policy_enosys.cpp new file mode 100644 index 00000000..f66a9fc7 --- /dev/null +++ b/src/fuse_readdirplus_policy_enosys.cpp @@ -0,0 +1,34 @@ +/* + ISC License + + Copyright (c) 2022, 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 "fuse_readdirplus_policy_enosys.hpp" + +#include "errno.hpp" + + +FUSE::READDIRPLUS::POLICY::enosys::enosys(const toml::value &toml_) +{ + +} + +int +FUSE::READDIRPLUS::POLICY::enosys::operator()(const fuse_file_info_t *ffi_, + fuse_dirents_t *buf_) +{ + return -ENOSYS; +} diff --git a/src/fuse_readdirplus_policy_enosys.hpp b/src/fuse_readdirplus_policy_enosys.hpp new file mode 100644 index 00000000..a7ff48d9 --- /dev/null +++ b/src/fuse_readdirplus_policy_enosys.hpp @@ -0,0 +1,39 @@ +/* + ISC License + + Copyright (c) 2022, 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 "fuse_readdirplus_policy_base.hpp" + +#include "branches.hpp" + +#include "toml.hpp" + + +namespace FUSE::READDIRPLUS::POLICY +{ + class enosys : public Base + { + public: + enosys(const toml::value &); + + public: + int operator()(const fuse_file_info_t *ffi, + fuse_dirents_t *buf) final; + }; +} diff --git a/src/fuse_readdirplus_policy_factory.cpp b/src/fuse_readdirplus_policy_factory.cpp new file mode 100644 index 00000000..7bb89cb8 --- /dev/null +++ b/src/fuse_readdirplus_policy_factory.cpp @@ -0,0 +1,39 @@ +/* + ISC License + + Copyright (c) 2022, 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 "fuse_readdirplus_policy_factory.hpp" + +#include "fuse_readdirplus_policy_enosys.hpp" + +#include + + +namespace FUSE::READDIRPLUS::POLICY +{ + Base::Ptr + factory(const toml::value &toml_) + { + std::string str; + + str = toml::find_or(toml_,"func","readdirplus","policy","enosys"); + if(str == "enosys") + return std::make_shared(toml_); + + throw std::runtime_error("readdirplus"); + } +} diff --git a/src/fuse_readdirplus_policy_factory.hpp b/src/fuse_readdirplus_policy_factory.hpp new file mode 100644 index 00000000..60d90201 --- /dev/null +++ b/src/fuse_readdirplus_policy_factory.hpp @@ -0,0 +1,30 @@ +/* + ISC License + + Copyright (c) 2022, 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 "fuse_readdirplus_policy_base.hpp" + +#include "toml.hpp" + + +namespace FUSE::READDIRPLUS::POLICY +{ + Base::Ptr + factory(const toml::value &); +} diff --git a/src/fuse_readdir_plus_linux.cpp b/src/fuse_readdirplus_policy_linux.cpp similarity index 90% rename from src/fuse_readdir_plus_linux.cpp rename to src/fuse_readdirplus_policy_linux.cpp index 222cd7a5..5fa3e640 100644 --- a/src/fuse_readdir_plus_linux.cpp +++ b/src/fuse_readdirplus_policy_linux.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fuse_readdirplus_policy_linux.hpp" + #include "branches.hpp" #include "errno.hpp" #include "fs_close.hpp" @@ -137,15 +139,16 @@ namespace l } } -namespace FUSE::READDIR_PLUS_LINUX + +FUSE::READDIRPLUS::POLICY::linux::linux(const toml::value &toml_) + : _branches(toml_) { - int - readdir_plus_linux(const Branches::CPtr &branches_, - const char *dirname_, - const uint64_t entry_timeout_, - const uint64_t attr_timeout_, - fuse_dirents_t *buf_) - { - return l::readdir_plus(branches_,dirname_,entry_timeout_,attr_timeout_,buf_); - } + +} + +int +FUSE::READDIRPLUS::POLICY::linux::operator()(const fuse_file_info_t *ffi_, + fuse_dirents_t *buf_) +{ + return -ENOENT; } diff --git a/src/fuse_readdir_plus_posix.hpp b/src/fuse_readdirplus_policy_linux.hpp similarity index 72% rename from src/fuse_readdir_plus_posix.hpp rename to src/fuse_readdirplus_policy_linux.hpp index 8fa0e2b9..2876de68 100644 --- a/src/fuse_readdir_plus_posix.hpp +++ b/src/fuse_readdirplus_policy_linux.hpp @@ -18,19 +18,25 @@ #pragma once +#include "fuse_readdirplus_policy_base.hpp" + #include "branches.hpp" #include "fuse.h" -#include - -namespace FUSE::READDIR_PLUS_POSIX +namespace FUSE::READDIRPLUS::POLICY { - int - readdir_plus_posix(const Branches::CPtr &branches, - const char *dirname, - const uint64_t entry_timeout, - const uint64_t attr_timeout, - fuse_dirents_t *buf); + class linux : public Base + { + public: + linux(const toml::value &); + + public: + int operator()(const fuse_file_info_t *ffi, + fuse_dirents_t *buf) final; + + private: + Branches2 _branches; + }; } diff --git a/src/fuse_readdir_plus_posix.cpp b/src/fuse_readdirplus_policy_posix.cpp similarity index 89% rename from src/fuse_readdir_plus_posix.cpp rename to src/fuse_readdirplus_policy_posix.cpp index edd0213b..a7d384b8 100644 --- a/src/fuse_readdir_plus_posix.cpp +++ b/src/fuse_readdirplus_policy_posix.cpp @@ -16,6 +16,8 @@ #define _DEFAULT_SOURCE +#include "fuse_readdirplus_policy_posix.hpp" + #include "branches.hpp" #include "errno.hpp" #include "fs_closedir.hpp" @@ -128,15 +130,16 @@ namespace l } } -namespace FUSE::READDIR_PLUS_POSIX + +FUSE::READDIRPLUS::POLICY::POSIX::POSIX(const toml::value &toml_) + : _branches(toml_) { - int - readdir_plus_posix(const Branches::CPtr &branches_, - const char *dirname_, - const uint64_t entry_timeout_, - const uint64_t attr_timeout_, - fuse_dirents_t *buf_) - { - return l::readdir_plus(branches_,dirname_,entry_timeout_,attr_timeout_,buf_); - } + +} + +int +FUSE::READDIRPLUS::POLICY::POSIX::operator()(const fuse_file_info_t *ffi_, + fuse_dirents_t *buf_) +{ + return -ENOENT; } diff --git a/src/fuse_readdir_plus_linux.hpp b/src/fuse_readdirplus_policy_posix.hpp similarity index 67% rename from src/fuse_readdir_plus_linux.hpp rename to src/fuse_readdirplus_policy_posix.hpp index 8fa270ab..bd28792e 100644 --- a/src/fuse_readdir_plus_linux.hpp +++ b/src/fuse_readdirplus_policy_posix.hpp @@ -1,7 +1,7 @@ /* ISC License - Copyright (c) 2020, Antonio SJ Musumeci + Copyright (c) 2022, 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 @@ -18,19 +18,25 @@ #pragma once +#include "fuse_readdirplus_policy_base.hpp" + #include "branches.hpp" #include "fuse.h" -#include - -namespace FUSE::READDIR_PLUS_LINUX +namespace FUSE::READDIRPLUS::POLICY { - int - readdir_plus_linux(const Branches::CPtr &branches, - const char *dirname, - const uint64_t entry_timeout, - const uint64_t attr_timeout, - fuse_dirents_t *buf); + class POSIX : public Base + { + public: + POSIX(const toml::value &); + + public: + int operator()(const fuse_file_info_t *ffi, + fuse_dirents_t *buf) final; + + private: + Branches2 _branches; + }; } diff --git a/src/fuse_statfs.cpp b/src/fuse_statfs.cpp index a7fc340d..85ee9880 100644 --- a/src/fuse_statfs.cpp +++ b/src/fuse_statfs.cpp @@ -14,135 +14,11 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "errno.hpp" -#include "fs_lstat.hpp" -#include "fs_path.hpp" -#include "fs_statvfs.hpp" -#include "statvfs_util.hpp" +#include "state.hpp" #include "ugid.hpp" #include "fuse.h" -#include -#include -#include -#include -#include - -using std::string; -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::CPtr &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; - } -} namespace FUSE::STATFS { diff --git a/src/fuse_statfs_policy_branch.cpp b/src/fuse_statfs_policy_branch.cpp new file mode 100644 index 00000000..190855f7 --- /dev/null +++ b/src/fuse_statfs_policy_branch.cpp @@ -0,0 +1,33 @@ +/* + ISC License + + Copyright (c) 2022, 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 "fuse_statfs_policy_branch.hpp" + + +FUSE::STATFS::POLICY::Branch::Branch(const toml::value &toml_) + : _branches(toml_) +{ + +} + +int +FUSE::STATFS::POLICY::Branch::operator()(const gfs::path &fusepath_, + struct statvfs *fsstat) +{ + return 0; +} diff --git a/src/fuse_statfs_policy_full.hpp b/src/fuse_statfs_policy_full.hpp index bb472c00..0f697ad6 100644 --- a/src/fuse_statfs_policy_full.hpp +++ b/src/fuse_statfs_policy_full.hpp @@ -18,7 +18,11 @@ #pragma once -#include "fuse_statfs_policy_full.hpp" +#include "fuse_statfs_policy_base.hpp" + +#include "branches.hpp" + +#include "toml.hpp" namespace FUSE::STATFS::POLICY diff --git a/src/fuse_symlink.cpp b/src/fuse_symlink.cpp index 344e44e4..c886ab49 100644 --- a/src/fuse_symlink.cpp +++ b/src/fuse_symlink.cpp @@ -14,130 +14,11 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "config.hpp" -#include "errno.hpp" -#include "fs_clonepath.hpp" -#include "fs_lstat.hpp" -#include "fs_path.hpp" -#include "fs_inode.hpp" -#include "fs_symlink.hpp" -#include "fuse_getattr.hpp" -#include "ugid.hpp" #include "state.hpp" +#include "ugid.hpp" #include "fuse.h" -#include - -#include -#include - -using std::string; - - -namespace error -{ - 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; - } -} - -namespace l -{ - static - int - symlink_loop_core(const string &newbasepath_, - const char *target_, - const char *linkpath_, - struct stat *st_, - const int error_) - { - int rv; - string fullnewpath; - - fullnewpath = fs::path::make(newbasepath_,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(linkpath_,st_); - } - - return error::calc(rv,error_,errno); - } - - static - int - symlink_loop(const string &existingpath_, - const StrVec &newbasepaths_, - const char *target_, - const char *linkpath_, - const string &newdirpath_, - struct stat *st_) - { - int rv; - int error; - - error = -1; - for(size_t i = 0, ei = newbasepaths_.size(); i != ei; i++) - { - rv = fs::clonepath_as_root(existingpath_,newbasepaths_[i],newdirpath_); - if(rv == -1) - error = error::calc(rv,error,errno); - else - error = l::symlink_loop_core(newbasepaths_[i], - 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; - StrVec newbasepaths; - StrVec existingpaths; - - newdirpath = fs::path::dirname(linkpath_); - - rv = searchFunc_(branches_,newdirpath,&existingpaths); - if(rv == -1) - return -errno; - - rv = createFunc_(branches_,newdirpath,&newbasepaths); - if(rv == -1) - return -errno; - - return l::symlink_loop(existingpaths[0],newbasepaths, - target_,linkpath_,newdirpath,st_); - } -} namespace FUSE::SYMLINK { @@ -147,35 +28,10 @@ namespace FUSE::SYMLINK struct stat *st_, fuse_timeouts_t *timeouts_) { - int rv; - Config::Read cfg; - const fuse_context *fc = fuse_get_context(); + State s; + 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(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; + return s->symlink(target_,&linkpath_[1],st_,timeouts_); } } diff --git a/src/fuse_symlink.hpp b/src/fuse_symlink.hpp index d00232ec..d30b590d 100644 --- a/src/fuse_symlink.hpp +++ b/src/fuse_symlink.hpp @@ -18,9 +18,6 @@ #include "fuse.h" -#include "toml.hpp" - -#include namespace FUSE::SYMLINK { diff --git a/src/fuse_symlink_policy.hpp b/src/fuse_symlink_policy.hpp index 4acd89ba..0dd865b2 100644 --- a/src/fuse_symlink_policy.hpp +++ b/src/fuse_symlink_policy.hpp @@ -37,9 +37,11 @@ namespace FUSE::SYMLINK public: int operator()(const char *target_, - const gfs::path &linkpath_) + const gfs::path &linkpath_, + struct stat *st_ = NULL, + fuse_timeouts_t *timeouts_ = NULL) { - return (*_symlink)(target_,linkpath_); + return (*_symlink)(target_,linkpath_,st_,timeouts_); } private: diff --git a/src/fuse_symlink_policy_base.hpp b/src/fuse_symlink_policy_base.hpp index faf81e9e..a3dfb030 100644 --- a/src/fuse_symlink_policy_base.hpp +++ b/src/fuse_symlink_policy_base.hpp @@ -20,6 +20,8 @@ #include "fs_path.hpp" +#include "fuse.h" + #include @@ -32,6 +34,8 @@ namespace FUSE::SYMLINK::POLICY public: virtual int operator()(const char *target, - const gfs::path &linkpath) = 0; + const gfs::path &linkpath, + struct stat *st_ = NULL, + fuse_timeouts_t *timeouts_ = NULL) = 0; }; } diff --git a/src/fuse_symlink_policy_epff.cpp b/src/fuse_symlink_policy_epff.cpp index 654323d8..9431c522 100644 --- a/src/fuse_symlink_policy_epff.cpp +++ b/src/fuse_symlink_policy_epff.cpp @@ -29,7 +29,9 @@ FUSE::SYMLINK::POLICY::EPFF::EPFF(const toml::value &toml_) int FUSE::SYMLINK::POLICY::EPFF::operator()(const char *target_, - const gfs::path &linkpath_) + const gfs::path &linkpath_, + struct stat *st_, + fuse_timeouts_t *timeouts_) { int rv; gfs::path fullpath; diff --git a/src/fuse_symlink_policy_epff.hpp b/src/fuse_symlink_policy_epff.hpp index 8e690bbe..f7352973 100644 --- a/src/fuse_symlink_policy_epff.hpp +++ b/src/fuse_symlink_policy_epff.hpp @@ -32,7 +32,9 @@ namespace FUSE::SYMLINK::POLICY public: int operator()(const char *target, - const gfs::path &linkpath) final; + const gfs::path &linkpath, + struct stat *st, + fuse_timeouts_t *timeouts) final; private: Branches2 _branches; diff --git a/src/fuse_symlink_policy_ff.cpp b/src/fuse_symlink_policy_ff.cpp index 037a4fae..b775cf92 100644 --- a/src/fuse_symlink_policy_ff.cpp +++ b/src/fuse_symlink_policy_ff.cpp @@ -32,7 +32,9 @@ FUSE::SYMLINK::POLICY::FF::FF(const toml::value &toml_) int FUSE::SYMLINK::POLICY::FF::operator()(const char *target_, - const gfs::path &linkpath_) + const gfs::path &linkpath_, + struct stat *st_, + fuse_timeouts_t *timeouts_) { int rv; gfs::path fullpath; diff --git a/src/fuse_symlink_policy_ff.hpp b/src/fuse_symlink_policy_ff.hpp index f168a11f..405e33ce 100644 --- a/src/fuse_symlink_policy_ff.hpp +++ b/src/fuse_symlink_policy_ff.hpp @@ -32,7 +32,9 @@ namespace FUSE::SYMLINK::POLICY public: int operator()(const char *target, - const gfs::path &linkpath) final; + const gfs::path &linkpath, + struct stat *st, + fuse_timeouts_t *timeouts) final; private: Branches2 _branches; diff --git a/src/fuse_utimens.cpp b/src/fuse_utimens.cpp index 7a3f85d8..7302ec84 100644 --- a/src/fuse_utimens.cpp +++ b/src/fuse_utimens.cpp @@ -14,132 +14,22 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "config.hpp" -#include "errno.hpp" -#include "fs_lutimens.hpp" -#include "fs_path.hpp" -#include "policy_rv.hpp" +#include "state.hpp" #include "ugid.hpp" #include "fuse.h" -#include - -#include - -using std::string; - - -namespace l -{ - static - int - get_error(const PolicyRV &prv_, - const string &basepath_) - { - for(int i = 0, ei = prv_.success.size(); i < ei; i++) - { - if(prv_.success[i].basepath == basepath_) - return prv_.success[i].rv; - } - - for(int i = 0, ei = prv_.error.size(); i < ei; i++) - { - if(prv_.error[i].basepath == basepath_) - return prv_.error[i].rv; - } - - return 0; - } - - 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 StrVec &basepaths_, - const char *fusepath_, - const timespec ts_[2], - PolicyRV *prv_) - { - for(size_t i = 0, ei = basepaths_.size(); i != ei; i++) - { - l::utimens_loop_core(basepaths_[i],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; - StrVec basepaths; - - rv = utimensPolicy_(branches_,fusepath_,&basepaths); - if(rv == -1) - return -errno; - - l::utimens_loop(basepaths,fusepath_,ts_,&prv); - if(prv.error.empty()) - return 0; - if(prv.success.empty()) - return prv.error[0].rv; - - basepaths.clear(); - rv = getattrPolicy_(branches_,fusepath_,&basepaths); - if(rv == -1) - return -errno; - - return l::get_error(prv,basepaths[0]); - } -} namespace FUSE::UTIMENS { - int - config(const toml::value &toml_) - { - std::string val; - Config::Write cfg; - - val = toml::find(toml_,"func","utimens","policy"); - - cfg->func.utimens.from_string(val); - - return 0; - } - int utimens(const char *fusepath_, const timespec ts_[2]) { - Config::Read cfg; + State s; 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_); + return s->utimens(&fusepath_[1],ts_); } } diff --git a/src/fuse_utimens_policy.hpp b/src/fuse_utimens_policy.hpp index c05651aa..c0f92661 100644 --- a/src/fuse_utimens_policy.hpp +++ b/src/fuse_utimens_policy.hpp @@ -18,25 +18,31 @@ #pragma once -#include "fuse_utimens_func_base.hpp" +#include "fuse_utimens_policy_base.hpp" +#include "fuse_utimens_policy_factory.hpp" #include "toml.hpp" -#include - namespace FUSE::UTIMENS { - class Func + class Policy { public: - Func(const toml::value &); + Policy(const toml::value &toml_) + { + _utimens = POLICY::factory(toml_); + } public: - int operator()(const char *fusepath, - const timespec ts_[2]); + int + operator()(const gfs::path &fusepath_, + const timespec ts_[2]) + { + return (*_utimens)(fusepath_,ts_); + } private: - FuncBase::Ptr _utimens; + POLICY::Base::Ptr _utimens; }; } diff --git a/src/fuse_utimens_policy_base.hpp b/src/fuse_utimens_policy_base.hpp index 8606b4fb..01fcb672 100644 --- a/src/fuse_utimens_policy_base.hpp +++ b/src/fuse_utimens_policy_base.hpp @@ -20,6 +20,8 @@ #include "fs_path.hpp" +#include "fuse.h" + #include diff --git a/src/mergerfs.cpp b/src/mergerfs.cpp index 568d53f8..007e2bc1 100644 --- a/src/mergerfs.cpp +++ b/src/mergerfs.cpp @@ -54,7 +54,7 @@ #include "fuse_prepare_hide.hpp" #include "fuse_read_buf.hpp" #include "fuse_readdir.hpp" -#include "fuse_readdir_plus.hpp" +#include "fuse_readdirplus.hpp" #include "fuse_readlink.hpp" #include "fuse_release.hpp" #include "fuse_releasedir.hpp" @@ -84,8 +84,7 @@ namespace l { static void - get_fuse_operations(struct fuse_operations &ops_, - const bool nullrw_) + get_fuse_operations(struct fuse_operations &ops_) { ops_.access = FUSE::ACCESS::access; ops_.bmap = FUSE::BMAP::bmap; @@ -118,9 +117,9 @@ namespace l ops_.opendir = FUSE::OPENDIR::opendir; ops_.poll = FUSE::POLL::poll;; ops_.prepare_hide = FUSE::PREPARE_HIDE::prepare_hide; - ops_.read_buf = (nullrw_ ? FUSE::READ_BUF::read_buf_null : FUSE::READ_BUF::read_buf); + // ops_.read_buf = FUSE::READ::read; ops_.readdir = FUSE::READDIR::readdir; - ops_.readdir_plus = FUSE::READDIR_PLUS::readdir_plus; + ops_.readdir_plus = FUSE::READDIRPLUS::readdirplus; ops_.readlink = FUSE::READLINK::readlink; ops_.release = FUSE::RELEASE::release; ops_.releasedir = FUSE::RELEASEDIR::releasedir; @@ -133,7 +132,7 @@ namespace l ops_.truncate = FUSE::TRUNCATE::truncate; ops_.unlink = FUSE::UNLINK::unlink; ops_.utimens = FUSE::UTIMENS::utimens; - ops_.write_buf = (nullrw_ ? FUSE::WRITE_BUF::write_buf_null : FUSE::WRITE_BUF::write_buf); + // ops_.write_buf = FUSE::WRITE::write; return; } @@ -165,7 +164,7 @@ namespace l args.allocated = 0; l::setup_resources(); - l::get_fuse_operations(ops,false); + l::get_fuse_operations(ops); return fuse_main(args.argc, args.argv, diff --git a/src/state.cpp b/src/state.cpp index 9632affb..9bd73378 100644 --- a/src/state.cpp +++ b/src/state.cpp @@ -40,15 +40,18 @@ StateBase::StateBase(const toml::value &toml_) mknod(toml_), open(toml_), readdir(toml_), + readdirplus(toml_), readlink(toml_), removexattr(toml_), rename(toml_), rmdir(toml_), setxattr(toml_), + statfs(toml_), symlink(toml_), truncate(toml_), - write(toml_), - unlink(toml_) + unlink(toml_), + utimens(toml_), + write(toml_) { mountpoint = toml::find(toml_,"filesystem","mountpoint"); diff --git a/src/state.hpp b/src/state.hpp index 46a803d3..05fcf4dc 100644 --- a/src/state.hpp +++ b/src/state.hpp @@ -31,14 +31,17 @@ #include "fuse_mknod_policy.hpp" #include "fuse_open_policy.hpp" #include "fuse_readdir_policy.hpp" +#include "fuse_readdirplus_policy.hpp" #include "fuse_readlink_policy.hpp" #include "fuse_removexattr_policy.hpp" #include "fuse_rename_policy.hpp" #include "fuse_rmdir_policy.hpp" #include "fuse_setxattr_policy.hpp" +#include "fuse_statfs_policy.hpp" #include "fuse_symlink_policy.hpp" #include "fuse_truncate_policy.hpp" #include "fuse_unlink_policy.hpp" +#include "fuse_utimens_policy.hpp" #include "fuse_write_policy.hpp" #include "branches.hpp" @@ -46,7 +49,7 @@ #include "link_exdev_enum.hpp" #include "rename_exdev_enum.hpp" -#include "ghc/filesystem.hpp" +#include "fs_path.hpp" #include #include @@ -64,6 +67,14 @@ public: public: StateBase(const toml::value &); +public: + uint64_t fuse_msg_size; + +public: + bool async_read; + bool cache_symlinks; + bool posix_acl; + public: int entry_cache_timeout; int neg_entry_cache_timeout; @@ -80,7 +91,7 @@ public: bool security_capability; public: - ghc::filesystem::path mountpoint; + gfs::path mountpoint; Branches2 branches; public: @@ -107,19 +118,21 @@ public: FUSE::MKNOD::Policy mknod; FUSE::OPEN::Policy open; FUSE::READDIR::Policy readdir; + FUSE::READDIRPLUS::Policy readdirplus; FUSE::READLINK::Policy readlink; FUSE::REMOVEXATTR::Policy removexattr; FUSE::RENAME::Policy rename; FUSE::RMDIR::Policy rmdir; FUSE::SETXATTR::Policy setxattr; + FUSE::STATFS::Policy statfs; FUSE::SYMLINK::Policy symlink; FUSE::TRUNCATE::Policy truncate; FUSE::UNLINK::Policy unlink; + FUSE::UTIMENS::Policy utimens; FUSE::WRITE::Policy write; - public: - const toml::value _toml; + const toml::value config_toml; }; class State