From fc3453932a28f5788affc13c28f68f517eb4d3bc Mon Sep 17 00:00:00 2001 From: Antonio SJ Musumeci Date: Thu, 20 Aug 2020 18:47:04 -0400 Subject: [PATCH] branches: add per branch minfreespace w/ original value as default example: /mnt/disk0=RW,1G:/mnt/disk1=RW,2G --- src/branch.cpp | 518 ++++++---- src/branch.hpp | 31 +- src/config.cpp | 2 +- src/from_string.cpp | 8 +- src/fs_findonfs.cpp | 20 +- src/fs_movefile.cpp | 9 +- src/fs_movefile.hpp | 2 - src/fuse_access.cpp | 4 +- src/fuse_chmod.cpp | 4 +- src/fuse_chown.cpp | 4 +- src/fuse_create.cpp | 6 +- src/fuse_getattr.cpp | 4 +- src/fuse_getxattr.cpp | 4 +- src/fuse_ioctl.cpp | 12 +- src/fuse_link.cpp | 23 +- src/fuse_listxattr.cpp | 4 +- src/fuse_mkdir.cpp | 6 +- src/fuse_mknod.cpp | 6 +- src/fuse_open.cpp | 4 +- src/fuse_readdir.cpp | 9 +- src/fuse_readdir_linux.cpp | 18 +- src/fuse_readdir_plus.cpp | 1 - src/fuse_readdir_plus_linux.cpp | 23 +- src/fuse_readdir_plus_posix.cpp | 28 +- src/fuse_readdir_posix.cpp | 24 +- src/fuse_readlink.cpp | 4 +- src/fuse_removexattr.cpp | 4 +- src/fuse_rename.cpp | 25 +- src/fuse_rmdir.cpp | 4 +- src/fuse_setxattr.cpp | 4 +- src/fuse_statfs.cpp | 11 +- src/fuse_symlink.cpp | 6 +- src/fuse_truncate.cpp | 4 +- src/fuse_unlink.cpp | 4 +- src/fuse_utimens.cpp | 4 +- src/fuse_write.cpp | 1 - src/fuse_write_buf.cpp | 1 - src/nonstd/optional.hpp | 1715 +++++++++++++++++++++++++++++++ src/num.cpp | 34 +- src/num.hpp | 5 + src/option_parser.cpp | 2 +- src/policy.hpp | 58 +- src/policy_all.cpp | 24 +- src/policy_cache.cpp | 5 +- src/policy_cache.hpp | 1 - src/policy_epall.cpp | 59 +- src/policy_epff.cpp | 59 +- src/policy_eplfs.cpp | 93 +- src/policy_eplus.cpp | 89 +- src/policy_epmfs.cpp | 89 +- src/policy_eppfrd.cpp | 81 +- src/policy_eprand.cpp | 3 +- src/policy_erofs.cpp | 1 - src/policy_ff.cpp | 24 +- src/policy_invalid.cpp | 1 - src/policy_lfs.cpp | 34 +- src/policy_lus.cpp | 36 +- src/policy_mfs.cpp | 34 +- src/policy_msplfs.cpp | 39 +- src/policy_msplus.cpp | 39 +- src/policy_mspmfs.cpp | 39 +- src/policy_msppfrd.cpp | 38 +- src/policy_newest.cpp | 89 +- src/policy_pfrd.cpp | 32 +- src/policy_rand.cpp | 3 +- src/rwlock.hpp | 16 +- src/str.cpp | 19 + src/str.hpp | 5 + 68 files changed, 2902 insertions(+), 710 deletions(-) create mode 100644 src/nonstd/optional.hpp diff --git a/src/branch.cpp b/src/branch.cpp index 943e967f..34d79442 100644 --- a/src/branch.cpp +++ b/src/branch.cpp @@ -18,8 +18,11 @@ #include "branch.hpp" #include "ef.hpp" +#include "from_string.hpp" #include "fs_glob.hpp" #include "fs_realpathize.hpp" +#include "nonstd/optional.hpp" +#include "num.hpp" #include "str.hpp" #include @@ -29,239 +32,381 @@ using std::string; using std::vector; +using nonstd::optional; -bool -Branch::ro(void) const -{ - return (mode == Branch::RO); -} -bool -Branch::nc(void) const +Branch::Branch(const uint64_t &default_minfreespace_) + : _default_minfreespace(&default_minfreespace_) { - return (mode == Branch::NC); } -bool -Branch::ro_or_nc(void) const -{ - return ((mode == Branch::RO) || - (mode == Branch::NC)); -} - -static -void -split(const std::string &s_, - std::string *instr_, - std::string *values_) +int +Branch::from_string(const std::string &str_) { - uint64_t offset; - - offset = s_.find_first_of('/'); - *instr_ = s_.substr(0,offset); - if(offset != std::string::npos) - *values_ = s_.substr(offset); + return -EINVAL; } -Branches::Branches() +std::string +Branch::to_string(void) const { - pthread_rwlock_init(&lock,NULL); -} + std::string rv; -static -void -parse(const string &str_, - Branches &branches_) -{ - string str; - Branch branch; - vector globbed; - - str = str_; - branch.mode = Branch::INVALID; - if(str::endswith(str,"=RO")) - branch.mode = Branch::RO; - ef(str::endswith(str,"=RW")) - branch.mode = Branch::RW; - ef(str::endswith(str,"=NC")) - branch.mode = Branch::NC; - - if(branch.mode != Branch::INVALID) - str.resize(str.size() - 3); - else - branch.mode = Branch::RW; - - fs::glob(str,&globbed); - fs::realpathize(&globbed); - for(size_t i = 0; i < globbed.size(); i++) + rv = path; + rv += '='; + switch(mode) { - branch.path = globbed[i]; - branches_.push_back(branch); + default: + case Branch::Mode::RW: + rv += "RW"; + break; + case Branch::Mode::RO: + rv += "RO"; + break; + case Branch::Mode::NC: + rv += "NC"; + break; } -} - -static -void -set(Branches &branches_, - const std::string &str_) -{ - vector paths; - - branches_.clear(); - str::split(str_,':',&paths); - - for(size_t i = 0; i < paths.size(); i++) + if(_minfreespace.has_value()) { - Branches tmp; - - parse(paths[i],tmp); - - branches_.insert(branches_.end(), - tmp.begin(), - tmp.end()); + rv += ','; + rv += num::humanize(_minfreespace.value()); } + + return rv; } -static void -add_begin(Branches &branches_, - const std::string &str_) +Branch::set_minfreespace(const uint64_t minfreespace_) { - vector paths; - - str::split(str_,':',&paths); - - for(size_t i = 0; i < paths.size(); i++) - { - Branches tmp; - - parse(paths[i],tmp); - - branches_.insert(branches_.begin(), - tmp.begin(), - tmp.end()); - } + _minfreespace = minfreespace_; } -static -void -add_end(Branches &branches_, - const std::string &str_) +uint64_t +Branch::minfreespace(void) const { - vector paths; - - str::split(str_,':',&paths); - - for(size_t i = 0; i < paths.size(); i++) - { - Branches tmp; - - parse(paths[i],tmp); - - branches_.insert(branches_.end(), - tmp.begin(), - tmp.end()); - } + if(_minfreespace.has_value()) + return _minfreespace.value(); + return *_default_minfreespace; } -static -void -erase_begin(Branches &branches_) +bool +Branch::ro(void) const { - branches_.erase(branches_.begin()); + return (mode == Branch::Mode::RO); } -static -void -erase_end(Branches &branches_) +bool +Branch::nc(void) const { - branches_.pop_back(); + return (mode == Branch::Mode::NC); } -static -void -erase_fnmatch(Branches &branches_, - const std::string &str_) +bool +Branch::ro_or_nc(void) const { - vector patterns; - - str::split(str_,':',&patterns); + return ((mode == Branch::Mode::RO) || + (mode == Branch::Mode::NC)); +} - for(Branches::iterator i = branches_.begin(); - i != branches_.end();) - { - int match = FNM_NOMATCH; +namespace l +{ + static + void + split(const std::string &s_, + std::string *instr_, + std::string *values_) + { + uint64_t offset; + + offset = s_.find_first_of('/'); + *instr_ = s_.substr(0,offset); + if(offset != std::string::npos) + *values_ = s_.substr(offset); + } +} - for(vector::const_iterator pi = patterns.begin(); - pi != patterns.end() && match != 0; - ++pi) - { - match = ::fnmatch(pi->c_str(),i->path.c_str(),0); - } +Branches::Branches(const uint64_t &default_minfreespace_) + : default_minfreespace(default_minfreespace_) +{ + pthread_rwlock_init(&lock,NULL); +} - i = ((match == 0) ? branches_.erase(i) : (i+1)); - } +namespace l +{ + static + int + parse_mode(const string &str_, + Branch::Mode *mode_) + { + if(str_ == "RW") + *mode_ = Branch::Mode::RW; + ef(str_ == "RO") + *mode_ = Branch::Mode::RO; + ef(str_ == "NC") + *mode_ = Branch::Mode::NC; + else + return -EINVAL; + + return 0; + } + + static + int + parse_minfreespace(const string &str_, + optional *minfreespace_) + { + int rv; + uint64_t uint64; + + rv = str::from(str_,&uint64); + if(rv < 0) + return rv; + + *minfreespace_ = uint64; + + return 0; + } + + static + int + parse_branch(const string &str_, + string *glob_, + Branch::Mode *mode_, + optional *minfreespace_) + { + int rv; + string options; + vector v; + + str::rsplit1(str_,'=',&v); + switch(v.size()) + { + case 1: + *glob_ = v[0]; + *mode_ = Branch::Mode::RW; + break; + case 2: + *glob_ = v[0]; + options = v[1]; + v.clear(); + str::split(options,',',&v); + switch(v.size()) + { + case 2: + rv = l::parse_minfreespace(v[1],minfreespace_); + if(rv < 0) + return rv; + case 1: + rv = l::parse_mode(v[0],mode_); + if(rv < 0) + return rv; + break; + case 0: + return -EINVAL; + } + break; + default: + return -EINVAL; + } + + return 0; + } + + static + int + parse(const string &str_, + const uint64_t &default_minfreespace_, + BranchVec *branches_) + { + int rv; + string glob; + vector globbed; + optional minfreespace; + Branch branch(default_minfreespace_); + + rv = l::parse_branch(str_,&glob,&branch.mode,&minfreespace); + if(rv < 0) + return rv; + + if(minfreespace.has_value()) + branch.set_minfreespace(minfreespace.value()); + + fs::glob(glob,&globbed); + fs::realpathize(&globbed); + for(size_t i = 0; i < globbed.size(); i++) + { + branch.path = globbed[i]; + branches_->push_back(branch); + } + + return 0; + } + + static + int + set(const std::string &str_, + Branches *branches_) + { + int rv; + vector paths; + BranchVec tmp_branchvec; + + str::split(str_,':',&paths); + + for(size_t i = 0; i < paths.size(); i++) + { + rv = l::parse(paths[i],branches_->default_minfreespace,&tmp_branchvec); + if(rv < 0) + return rv; + } + + branches_->vec.clear(); + branches_->vec.insert(branches_->vec.end(), + tmp_branchvec.begin(), + tmp_branchvec.end()); + + return 0; + } + + static + int + add_begin(const std::string &str_, + Branches *branches_) + { + int rv; + vector paths; + BranchVec tmp_branchvec; + + str::split(str_,':',&paths); + + for(size_t i = 0; i < paths.size(); i++) + { + rv = l::parse(paths[i],branches_->default_minfreespace,&tmp_branchvec); + if(rv < 0) + return rv; + } + + branches_->vec.insert(branches_->vec.begin(), + tmp_branchvec.begin(), + tmp_branchvec.end()); + + return 0; + } + + static + int + add_end(const std::string &str_, + Branches *branches_) + { + int rv; + vector paths; + BranchVec tmp_branchvec; + + str::split(str_,':',&paths); + + for(size_t i = 0; i < paths.size(); i++) + { + rv = l::parse(paths[i],branches_->default_minfreespace,&tmp_branchvec); + if(rv < 0) + return rv; + } + + branches_->vec.insert(branches_->vec.end(), + tmp_branchvec.begin(), + tmp_branchvec.end()); + + return 0; + } + + static + int + erase_begin(BranchVec *branches_) + { + branches_->erase(branches_->begin()); + + return 0; + } + + static + int + erase_end(BranchVec *branches_) + { + branches_->pop_back(); + + return 0; + } + + static + int + erase_fnmatch(const std::string &str_, + Branches *branches_) + { + vector patterns; + + str::split(str_,':',&patterns); + + for(BranchVec::iterator i = branches_->vec.begin(); + i != branches_->vec.end();) + { + int match = FNM_NOMATCH; + + for(vector::const_iterator pi = patterns.begin(); + pi != patterns.end() && match != 0; + ++pi) + { + match = ::fnmatch(pi->c_str(),i->path.c_str(),0); + } + + i = ((match == 0) ? branches_->vec.erase(i) : (i+1)); + } + + return 0; + } } int Branches::from_string(const std::string &s_) { - rwlock::WriteGuard guard(&lock); + rwlock::WriteGuard guard(lock); + std::string instr; std::string values; - ::split(s_,&instr,&values); + l::split(s_,&instr,&values); if(instr == "+") - ::add_end(*this,values); - ef(instr == "+<") - ::add_begin(*this,values); - ef(instr == "+>") - ::add_end(*this,values); - ef(instr == "-") - ::erase_fnmatch(*this,values); - ef(instr == "-<") - ::erase_begin(*this); - ef(instr == "->") - ::erase_end(*this); - ef(instr == "=") - ::set(*this,values); - ef(instr.empty()) - ::set(*this,values); - else - return -EINVAL; - - return 0; + return l::add_end(values,this); + if(instr == "+<") + return l::add_begin(values,this); + if(instr == "+>") + return l::add_end(values,this); + if(instr == "-") + return l::erase_fnmatch(values,this); + if(instr == "-<") + return l::erase_begin(&vec); + if(instr == "->") + return l::erase_end(&vec); + if(instr == "=") + return l::set(values,this); + if(instr.empty()) + return l::set(values,this); + + return -EINVAL; } string Branches::to_string(void) const { - rwlock::ReadGuard guard(&lock); + rwlock::ReadGuard guard(lock); + string tmp; - for(size_t i = 0; i < size(); i++) + for(size_t i = 0; i < vec.size(); i++) { - const Branch &branch = (*this)[i]; - - tmp += branch.path; - - tmp += '='; - switch(branch.mode) - { - default: - case Branch::RW: - tmp += "RW"; - break; - case Branch::RO: - tmp += "RO"; - break; - case Branch::NC: - tmp += "NC"; - break; - } + const Branch &branch = vec[i]; + tmp += branch.to_string(); tmp += ':'; } @@ -274,11 +419,11 @@ Branches::to_string(void) const void Branches::to_paths(vector &vec_) const { - rwlock::ReadGuard guard(&lock); + rwlock::ReadGuard guard(lock); - for(size_t i = 0; i < size(); i++) + for(size_t i = 0; i < vec.size(); i++) { - const Branch &branch = (*this)[i]; + const Branch &branch = vec[i]; vec_.push_back(branch.path); } @@ -299,12 +444,13 @@ SrcMounts::from_string(const std::string &s_) std::string SrcMounts::to_string(void) const { - rwlock::ReadGuard guard(&_branches.lock); + rwlock::ReadGuard guard(_branches.lock); + std::string rv; - for(uint64_t i = 0; i < _branches.size(); i++) + for(uint64_t i = 0; i < _branches.vec.size(); i++) { - rv += _branches[i].path; + rv += _branches.vec[i].path; rv += ':'; } diff --git a/src/branch.hpp b/src/branch.hpp index 34eea2cc..421f0e3c 100644 --- a/src/branch.hpp +++ b/src/branch.hpp @@ -20,16 +20,25 @@ #include "rwlock.hpp" #include "tofrom_string.hpp" +#include "nonstd/optional.hpp" #include #include +#include #include -class Branch +class Branch : public ToFromString { public: - enum Mode + Branch(const uint64_t &default_minfreespace); + +public: + int from_string(const std::string &str); + std::string to_string(void) const; + +public: + enum class Mode { INVALID, RO, @@ -37,18 +46,30 @@ public: NC }; +public: Mode mode; std::string path; + uint64_t minfreespace() const; +public: + void set_minfreespace(const uint64_t minfreespace); + +public: bool ro(void) const; bool nc(void) const; bool ro_or_nc(void) const; + +private: + nonstd::optional _minfreespace; + const uint64_t *_default_minfreespace; }; -class Branches : public std::vector, public ToFromString +typedef std::vector BranchVec; + +class Branches : public ToFromString { public: - Branches(); + Branches(const uint64_t &default_minfreespace_); public: int from_string(const std::string &str); @@ -59,6 +80,8 @@ public: public: mutable pthread_rwlock_t lock; + BranchVec vec; + const uint64_t &default_minfreespace; }; class SrcMounts : public ToFromString diff --git a/src/config.cpp b/src/config.cpp index 28bec9a6..6c8e1064 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -67,7 +67,7 @@ Config::Config() async_read(true), auto_cache(false), - branches(), + branches(minfreespace), cache_attr(1), cache_entry(1), cache_files(CacheFiles::ENUM::LIBFUSE), diff --git a/src/from_string.cpp b/src/from_string.cpp index 73425cce..796f9256 100644 --- a/src/from_string.cpp +++ b/src/from_string.cpp @@ -67,22 +67,22 @@ namespace str { case 'k': case 'K': - tmp *= 1024; + tmp *= 1024ULL; break; case 'm': case 'M': - tmp *= (1024 * 1024); + tmp *= (1024ULL * 1024ULL); break; case 'g': case 'G': - tmp *= (1024 * 1024 * 1024); + tmp *= (1024ULL * 1024ULL * 1024ULL); break; case 't': case 'T': - tmp *= (1024ULL * 1024 * 1024 * 1024); + tmp *= (1024ULL * 1024ULL * 1024ULL * 1024ULL); break; case '\0': diff --git a/src/fs_findonfs.cpp b/src/fs_findonfs.cpp index ce2bc1ae..e52c7333 100644 --- a/src/fs_findonfs.cpp +++ b/src/fs_findonfs.cpp @@ -24,10 +24,11 @@ #include -namespace fs +namespace l { + static int - findonfs(const Branches &branches_, + findonfs(const BranchVec &branches_, const std::string &fusepath_, const int fd_, std::string *basepath_) @@ -37,7 +38,6 @@ namespace fs struct stat st; std::string fullpath; const Branch *branch; - const rwlock::ReadGuard guard(&branches_.lock); rv = fs::fstat(fd_,&st); if(rv == -1) @@ -65,3 +65,17 @@ namespace fs return (errno=ENOENT,-1); } } + +namespace fs +{ + int + findonfs(const Branches &branches_, + const std::string &fusepath_, + const int fd_, + std::string *basepath_) + { + rwlock::ReadGuard guard(branches_.lock); + + return l::findonfs(branches_.vec,fusepath_,fd_,basepath_); + } +} diff --git a/src/fs_movefile.cpp b/src/fs_movefile.cpp index 059e044f..2c2c13e2 100644 --- a/src/fs_movefile.cpp +++ b/src/fs_movefile.cpp @@ -49,7 +49,6 @@ namespace l int movefile(Policy::Func::Create createFunc_, const Branches &branches_, - const uint64_t minfreepsace_, const string &fusepath_, int *origfd_) { @@ -73,7 +72,7 @@ namespace l if(rv == -1) return -1; - rv = createFunc_(branches_,fusepath_,minfreepsace_,&fdout_path); + rv = createFunc_(branches_,fusepath_,&fdout_path); if(rv == -1) return -1; @@ -135,22 +134,20 @@ namespace fs int movefile(const Policy *policy_, const Branches &basepaths_, - const uint64_t minfreepsace_, const string &fusepath_, int *origfd_) { - return l::movefile(policy_,basepaths_,minfreepsace_,fusepath_,origfd_); + return l::movefile(policy_,basepaths_,fusepath_,origfd_); } int movefile_as_root(const Policy *policy_, const Branches &basepaths_, - const uint64_t minfreepsace_, const string &fusepath_, int *origfd_) { const ugid::Set ugid(0,0); - return fs::movefile(policy_,basepaths_,minfreepsace_,fusepath_,origfd_); + return fs::movefile(policy_,basepaths_,fusepath_,origfd_); } } diff --git a/src/fs_movefile.hpp b/src/fs_movefile.hpp index cf7489f4..7b21312e 100644 --- a/src/fs_movefile.hpp +++ b/src/fs_movefile.hpp @@ -26,14 +26,12 @@ namespace fs int movefile(const Policy *policy, const Branches &branches, - const uint64_t minfreepsace, const std::string &fusepath, int *origfd); int movefile_as_root(const Policy *policy, const Branches &branches, - const uint64_t minfreepsace, const std::string &fusepath, int *origfd); } diff --git a/src/fuse_access.cpp b/src/fuse_access.cpp index 44c1ad7a..e9705ce3 100644 --- a/src/fuse_access.cpp +++ b/src/fuse_access.cpp @@ -32,7 +32,6 @@ namespace l int access(Policy::Func::Search searchFunc, const Branches &branches_, - const uint64_t minfreespace, const char *fusepath, const int mask) { @@ -40,7 +39,7 @@ namespace l string fullpath; vector basepaths; - rv = searchFunc(branches_,fusepath,minfreespace,&basepaths); + rv = searchFunc(branches_,fusepath,&basepaths); if(rv == -1) return -errno; @@ -64,7 +63,6 @@ namespace FUSE return l::access(config.func.access.policy, config.branches, - config.minfreespace, fusepath, mask); } diff --git a/src/fuse_chmod.cpp b/src/fuse_chmod.cpp index 1f9ad487..e7017bea 100644 --- a/src/fuse_chmod.cpp +++ b/src/fuse_chmod.cpp @@ -71,14 +71,13 @@ namespace l int chmod(Policy::Func::Action actionFunc_, const Branches &branches_, - const uint64_t minfreespace_, const char *fusepath_, const mode_t mode_) { int rv; vector basepaths; - rv = actionFunc_(branches_,fusepath_,minfreespace_,&basepaths); + rv = actionFunc_(branches_,fusepath_,&basepaths); if(rv == -1) return -errno; @@ -98,7 +97,6 @@ namespace FUSE return l::chmod(config.func.chmod.policy, config.branches, - config.minfreespace, fusepath_, mode_); } diff --git a/src/fuse_chown.cpp b/src/fuse_chown.cpp index 947451a5..768d0397 100644 --- a/src/fuse_chown.cpp +++ b/src/fuse_chown.cpp @@ -71,7 +71,6 @@ namespace l int chown(Policy::Func::Action actionFunc_, const Branches &branches_, - const uint64_t minfreespace_, const char *fusepath_, const uid_t uid_, const gid_t gid_) @@ -79,7 +78,7 @@ namespace l int rv; vector basepaths; - rv = actionFunc_(branches_,fusepath_,minfreespace_,&basepaths); + rv = actionFunc_(branches_,fusepath_,&basepaths); if(rv == -1) return -errno; @@ -100,7 +99,6 @@ namespace FUSE return l::chown(config.func.chown.policy, config.branches, - config.minfreespace, fusepath_, uid_, gid_); diff --git a/src/fuse_create.cpp b/src/fuse_create.cpp index 2d039773..e57d0f29 100644 --- a/src/fuse_create.cpp +++ b/src/fuse_create.cpp @@ -128,7 +128,6 @@ namespace l create(Policy::Func::Search searchFunc_, Policy::Func::Create createFunc_, const Branches &branches_, - const uint64_t minfreespace_, const char *fusepath_, const mode_t mode_, const mode_t umask_, @@ -143,11 +142,11 @@ namespace l fusedirpath = fs::path::dirname(fusepath_); - rv = searchFunc_(branches_,fusedirpath,minfreespace_,&existingpaths); + rv = searchFunc_(branches_,fusedirpath,&existingpaths); if(rv == -1) return -errno; - rv = createFunc_(branches_,fusedirpath,minfreespace_,&createpaths); + rv = createFunc_(branches_,fusedirpath,&createpaths); if(rv == -1) return -errno; @@ -183,7 +182,6 @@ namespace FUSE return l::create(config.func.getattr.policy, config.func.create.policy, config.branches, - config.minfreespace, fusepath_, mode_, fc->umask, diff --git a/src/fuse_getattr.cpp b/src/fuse_getattr.cpp index c7b38632..54669a09 100644 --- a/src/fuse_getattr.cpp +++ b/src/fuse_getattr.cpp @@ -61,7 +61,6 @@ namespace l int getattr(Policy::Func::Search searchFunc_, const Branches &branches_, - const uint64_t minfreespace_, const char *fusepath_, struct stat *st_, const bool symlinkify_, @@ -71,7 +70,7 @@ namespace l string fullpath; vector basepaths; - rv = searchFunc_(branches_,fusepath_,minfreespace_,&basepaths); + rv = searchFunc_(branches_,fusepath_,&basepaths); if(rv == -1) return -errno; @@ -108,7 +107,6 @@ namespace FUSE rv = l::getattr(config.func.getattr.policy, config.branches, - config.minfreespace, fusepath_, st_, config.symlinkify, diff --git a/src/fuse_getxattr.cpp b/src/fuse_getxattr.cpp index 1493f995..e0fd6ca8 100644 --- a/src/fuse_getxattr.cpp +++ b/src/fuse_getxattr.cpp @@ -165,7 +165,6 @@ namespace l int getxattr(Policy::Func::Search searchFunc_, const Branches &branches_, - const size_t minfreespace_, const char *fusepath_, const char *attrname_, char *buf_, @@ -175,7 +174,7 @@ namespace l string fullpath; vector basepaths; - rv = searchFunc_(branches_,fusepath_,minfreespace_,&basepaths); + rv = searchFunc_(branches_,fusepath_,&basepaths); if(rv == -1) return -errno; @@ -222,7 +221,6 @@ namespace FUSE return l::getxattr(config.func.getxattr.policy, config.branches, - config.minfreespace, fusepath_, attrname_, buf_, diff --git a/src/fuse_ioctl.cpp b/src/fuse_ioctl.cpp index 2bbf94c3..de7cb971 100644 --- a/src/fuse_ioctl.cpp +++ b/src/fuse_ioctl.cpp @@ -136,7 +136,6 @@ namespace l int ioctl_dir_base(Policy::Func::Search searchFunc_, const Branches &branches_, - const uint64_t minfreespace_, const char *fusepath_, const uint32_t cmd_, void *data_, @@ -147,7 +146,7 @@ namespace l string fullpath; vector basepaths; - rv = searchFunc_(branches_,fusepath_,minfreespace_,&basepaths); + rv = searchFunc_(branches_,fusepath_,&basepaths); if(rv == -1) return -errno; @@ -178,7 +177,6 @@ namespace l return l::ioctl_dir_base(config.func.open.policy, config.branches, - config.minfreespace, di->fusepath.c_str(), cmd_, data_, @@ -257,14 +255,13 @@ namespace l int file_basepath(Policy::Func::Search searchFunc_, const Branches &branches_, - const uint64_t minfreespace_, const char *fusepath_, void *data_) { int rv; vector basepaths; - rv = searchFunc_(branches_,fusepath_,minfreespace_,&basepaths); + rv = searchFunc_(branches_,fusepath_,&basepaths); if(rv == -1) return -errno; @@ -281,7 +278,6 @@ namespace l return l::file_basepath(config.func.open.policy, config.branches, - config.minfreespace, fusepath.c_str(), data_); } @@ -300,7 +296,6 @@ namespace l int file_fullpath(Policy::Func::Search searchFunc_, const Branches &branches_, - const uint64_t minfreespace_, const string &fusepath_, void *data_) { @@ -308,7 +303,7 @@ namespace l string fullpath; vector basepaths; - rv = searchFunc_(branches_,fusepath_,minfreespace_,&basepaths); + rv = searchFunc_(branches_,fusepath_,&basepaths); if(rv == -1) return -errno; @@ -327,7 +322,6 @@ namespace l return l::file_fullpath(config.func.open.policy, config.branches, - config.minfreespace, fusepath, data_); } diff --git a/src/fuse_link.cpp b/src/fuse_link.cpp index 8f7bf6d8..ea2dea4f 100644 --- a/src/fuse_link.cpp +++ b/src/fuse_link.cpp @@ -83,7 +83,6 @@ namespace l link_create_path(Policy::Func::Search searchFunc_, Policy::Func::Action actionFunc_, const Branches &branches_, - const uint64_t minfreespace_, const char *oldfusepath_, const char *newfusepath_) { @@ -92,13 +91,13 @@ namespace l vector oldbasepaths; vector newbasepaths; - rv = actionFunc_(branches_,oldfusepath_,minfreespace_,&oldbasepaths); + rv = actionFunc_(branches_,oldfusepath_,&oldbasepaths); if(rv == -1) return -errno; newfusedirpath = fs::path::dirname(newfusepath_); - rv = searchFunc_(branches_,newfusedirpath,minfreespace_,&newbasepaths); + rv = searchFunc_(branches_,newfusedirpath,&newbasepaths); if(rv == -1) return -errno; @@ -112,7 +111,6 @@ namespace l clonepath_if_would_create(Policy::Func::Search searchFunc_, Policy::Func::Create createFunc_, const Branches &branches_, - const uint64_t minfreespace_, const string &oldbasepath_, const char *oldfusepath_, const char *newfusepath_) @@ -123,14 +121,14 @@ namespace l newfusedirpath = fs::path::dirname(newfusepath_); - rv = createFunc_(branches_,newfusedirpath,minfreespace_,&newbasepath); + rv = createFunc_(branches_,newfusedirpath,&newbasepath); if(rv == -1) return -1; if(oldbasepath_ != newbasepath[0]) return (errno=EXDEV,-1); - rv = searchFunc_(branches_,newfusedirpath,minfreespace_,&newbasepath); + rv = searchFunc_(branches_,newfusedirpath,&newbasepath); if(rv == -1) return -1; @@ -142,7 +140,6 @@ namespace l link_preserve_path_core(Policy::Func::Search searchFunc_, Policy::Func::Create createFunc_, const Branches &branches_, - const uint64_t minfreespace_, const string &oldbasepath_, const char *oldfusepath_, const char *newfusepath_, @@ -159,7 +156,7 @@ namespace l if((rv == -1) && (errno == ENOENT)) { rv = l::clonepath_if_would_create(searchFunc_,createFunc_, - branches_,minfreespace_, + branches_, oldbasepath_, oldfusepath_,newfusepath_); if(rv != -1) @@ -174,7 +171,6 @@ namespace l link_preserve_path_loop(Policy::Func::Search searchFunc_, Policy::Func::Create createFunc_, const Branches &branches_, - const uint64_t minfreespace_, const char *oldfusepath_, const char *newfusepath_, const vector &oldbasepaths_) @@ -185,7 +181,7 @@ namespace l for(size_t i = 0, ei = oldbasepaths_.size(); i != ei; i++) { error = l::link_preserve_path_core(searchFunc_,createFunc_, - branches_,minfreespace_, + branches_, oldbasepaths_[i], oldfusepath_,newfusepath_, error); @@ -200,19 +196,18 @@ namespace l Policy::Func::Action actionFunc_, Policy::Func::Create createFunc_, const Branches &branches_, - const uint64_t minfreespace_, const char *oldfusepath_, const char *newfusepath_) { int rv; vector oldbasepaths; - rv = actionFunc_(branches_,oldfusepath_,minfreespace_,&oldbasepaths); + rv = actionFunc_(branches_,oldfusepath_,&oldbasepaths); if(rv == -1) return -errno; return l::link_preserve_path_loop(searchFunc_,createFunc_, - branches_,minfreespace_, + branches_, oldfusepath_,newfusepath_, oldbasepaths); } @@ -233,14 +228,12 @@ namespace FUSE config.func.link.policy, config.func.create.policy, config.branches, - config.minfreespace, from_, to_); return l::link_create_path(config.func.link.policy, config.func.create.policy, config.branches, - config.minfreespace, from_, to_); } diff --git a/src/fuse_listxattr.cpp b/src/fuse_listxattr.cpp index a68d8a4f..29b3f57c 100644 --- a/src/fuse_listxattr.cpp +++ b/src/fuse_listxattr.cpp @@ -59,7 +59,6 @@ namespace l int listxattr(Policy::Func::Search searchFunc_, const Branches &branches_, - const uint64_t minfreespace_, const char *fusepath_, char *list_, const size_t size_) @@ -68,7 +67,7 @@ namespace l string fullpath; vector basepaths; - rv = searchFunc_(branches_,fusepath_,minfreespace_,&basepaths); + rv = searchFunc_(branches_,fusepath_,&basepaths); if(rv == -1) return -errno; @@ -107,7 +106,6 @@ namespace FUSE return l::listxattr(config.func.listxattr.policy, config.branches, - config.minfreespace, fusepath_, list_, size_); diff --git a/src/fuse_mkdir.cpp b/src/fuse_mkdir.cpp index b6ff1e70..3eb89307 100644 --- a/src/fuse_mkdir.cpp +++ b/src/fuse_mkdir.cpp @@ -97,7 +97,6 @@ namespace l mkdir(Policy::Func::Search searchFunc_, Policy::Func::Create createFunc_, const Branches &branches_, - const uint64_t minfreespace_, const char *fusepath_, const mode_t mode_, const mode_t umask_) @@ -109,11 +108,11 @@ namespace l fusedirpath = fs::path::dirname(fusepath_); - rv = searchFunc_(branches_,fusedirpath,minfreespace_,&existingpaths); + rv = searchFunc_(branches_,fusedirpath,&existingpaths); if(rv == -1) return -errno; - rv = createFunc_(branches_,fusedirpath,minfreespace_,&createpaths); + rv = createFunc_(branches_,fusedirpath,&createpaths); if(rv == -1) return -errno; @@ -139,7 +138,6 @@ namespace FUSE return l::mkdir(config.func.getattr.policy, config.func.mkdir.policy, config.branches, - config.minfreespace, fusepath_, mode_, fc->umask); diff --git a/src/fuse_mknod.cpp b/src/fuse_mknod.cpp index 02477090..2173c9fa 100644 --- a/src/fuse_mknod.cpp +++ b/src/fuse_mknod.cpp @@ -99,7 +99,6 @@ namespace l mknod(Policy::Func::Search searchFunc_, Policy::Func::Create createFunc_, const Branches &branches_, - const uint64_t minfreespace_, const char *fusepath_, const mode_t mode_, const mode_t umask_, @@ -112,11 +111,11 @@ namespace l fusedirpath = fs::path::dirname(fusepath_); - rv = searchFunc_(branches_,fusedirpath,minfreespace_,&existingpaths); + rv = searchFunc_(branches_,fusedirpath,&existingpaths); if(rv == -1) return -errno; - rv = createFunc_(branches_,fusedirpath,minfreespace_,&createpaths); + rv = createFunc_(branches_,fusedirpath,&createpaths); if(rv == -1) return -errno; @@ -140,7 +139,6 @@ namespace FUSE return l::mknod(config.func.getattr.policy, config.func.mknod.policy, config.branches, - config.minfreespace, fusepath_, mode_, fc->umask, diff --git a/src/fuse_open.cpp b/src/fuse_open.cpp index d0aded13..2a4cd628 100644 --- a/src/fuse_open.cpp +++ b/src/fuse_open.cpp @@ -183,7 +183,6 @@ namespace l open(Policy::Func::Search searchFunc_, PolicyCache &cache, const Branches &branches_, - const uint64_t minfreespace_, const char *fusepath_, const int flags_, const bool link_cow_, @@ -193,7 +192,7 @@ namespace l int rv; string basepath; - rv = cache(searchFunc_,branches_,fusepath_,minfreespace_,&basepath); + rv = cache(searchFunc_,branches_,fusepath_,&basepath); if(rv == -1) return -errno; @@ -219,7 +218,6 @@ namespace FUSE return l::open(config.func.open.policy, config.open_cache, config.branches, - config.minfreespace, fusepath_, ffi_->flags, config.link_cow, diff --git a/src/fuse_readdir.cpp b/src/fuse_readdir.cpp index 5212a03f..fd8c8713 100644 --- a/src/fuse_readdir.cpp +++ b/src/fuse_readdir.cpp @@ -32,11 +32,10 @@ namespace FUSE readdir(fuse_file_info *ffi_, fuse_dirents_t *buf_) { - DirInfo *di = reinterpret_cast(ffi_->fh); - const fuse_context *fc = fuse_get_context(); - const Config &config = Config::ro(); - const ugid::Set ugid(fc->uid,fc->gid); - const rwlock::ReadGuard guard(&config.branches.lock); + DirInfo *di = reinterpret_cast(ffi_->fh); + const fuse_context *fc = fuse_get_context(); + const Config &config = Config::ro(); + const ugid::Set ugid(fc->uid,fc->gid); switch(config.readdir) { diff --git a/src/fuse_readdir_linux.cpp b/src/fuse_readdir_linux.cpp index e2544602..4d0cf062 100644 --- a/src/fuse_readdir_linux.cpp +++ b/src/fuse_readdir_linux.cpp @@ -26,6 +26,7 @@ #include "hashset.hpp" #include "linux_dirent64.h" #include "mempools.hpp" +#include "rwlock.hpp" #include #include @@ -52,9 +53,9 @@ namespace l static int - readdir(const Branches &branches_, - const char *dirname_, - fuse_dirents_t *buf_) + readdir(const BranchVec &branches_, + const char *dirname_, + fuse_dirents_t *buf_) { int rv; dev_t dev; @@ -121,6 +122,17 @@ namespace l return 0; } + + static + int + readdir(const Branches &branches_, + const char *dirname_, + fuse_dirents_t *buf_) + { + rwlock::ReadGuard guard(branches_.lock); + + return l::readdir(branches_.vec,dirname_,buf_); + } } namespace FUSE diff --git a/src/fuse_readdir_plus.cpp b/src/fuse_readdir_plus.cpp index 6b12c324..e445bf1b 100644 --- a/src/fuse_readdir_plus.cpp +++ b/src/fuse_readdir_plus.cpp @@ -36,7 +36,6 @@ namespace FUSE const fuse_context *fc = fuse_get_context(); const Config &config = Config::ro(); const ugid::Set ugid(fc->uid,fc->gid); - const rwlock::ReadGuard guard(&config.branches.lock); switch(config.readdir) { diff --git a/src/fuse_readdir_plus_linux.cpp b/src/fuse_readdir_plus_linux.cpp index b399ba05..ad643a5f 100644 --- a/src/fuse_readdir_plus_linux.cpp +++ b/src/fuse_readdir_plus_linux.cpp @@ -53,11 +53,11 @@ namespace l static int - readdir_plus(const Branches &branches_, - const char *dirname_, - const uint64_t entry_timeout_, - const uint64_t attr_timeout_, - fuse_dirents_t *buf_) + readdir_plus(const BranchVec &branches_, + const char *dirname_, + const uint64_t entry_timeout_, + const uint64_t attr_timeout_, + fuse_dirents_t *buf_) { int rv; dev_t dev; @@ -136,6 +136,19 @@ namespace l return 0; } + + static + int + readdir_plus(const Branches &branches_, + const char *dirname_, + const uint64_t entry_timeout_, + const uint64_t attr_timeout_, + fuse_dirents_t *buf_) + { + rwlock::ReadGuard guard(branches_.lock); + + return l::readdir_plus(branches_.vec,dirname_,entry_timeout_,attr_timeout_,buf_); + } } namespace FUSE diff --git a/src/fuse_readdir_plus_posix.cpp b/src/fuse_readdir_plus_posix.cpp index ba801fc3..6f809684 100644 --- a/src/fuse_readdir_plus_posix.cpp +++ b/src/fuse_readdir_plus_posix.cpp @@ -28,6 +28,7 @@ #include "fs_readdir.hpp" #include "fs_stat.hpp" #include "hashset.hpp" +#include "rwlock.hpp" #include #include @@ -57,11 +58,11 @@ namespace l static int - readdir_plus(const Branches &branches_, - const char *dirname_, - const uint64_t entry_timeout_, - const uint64_t attr_timeout_, - fuse_dirents_t *buf_) + readdir_plus(const BranchVec &branches_, + const char *dirname_, + const uint64_t entry_timeout_, + const uint64_t attr_timeout_, + fuse_dirents_t *buf_) { dev_t dev; HashSet names; @@ -126,6 +127,23 @@ namespace l return 0; } + + static + int + readdir_plus(const Branches &branches_, + const char *dirname_, + const uint64_t entry_timeout_, + const uint64_t attr_timeout_, + fuse_dirents_t *buf_) + { + rwlock::ReadGuard guard(branches_.lock); + + return l::readdir_plus(branches_.vec, + dirname_, + entry_timeout_, + attr_timeout_, + buf_); + } } namespace FUSE diff --git a/src/fuse_readdir_posix.cpp b/src/fuse_readdir_posix.cpp index 2bf916ae..ba944a83 100644 --- a/src/fuse_readdir_posix.cpp +++ b/src/fuse_readdir_posix.cpp @@ -19,14 +19,15 @@ #include "branch.hpp" #include "errno.hpp" #include "fs_closedir.hpp" +#include "fs_devid.hpp" #include "fs_dirfd.hpp" +#include "fs_inode.hpp" #include "fs_opendir.hpp" +#include "fs_path.hpp" #include "fs_readdir.hpp" #include "fs_stat.hpp" -#include "fs_devid.hpp" -#include "fs_inode.hpp" -#include "fs_path.hpp" #include "hashset.hpp" +#include "rwlock.hpp" #include #include @@ -56,9 +57,9 @@ namespace l static int - readdir(const Branches &branches_, - const char *dirname_, - fuse_dirents_t *buf_) + readdir(const BranchVec &branches_, + const char *dirname_, + fuse_dirents_t *buf_) { dev_t dev; HashSet names; @@ -109,6 +110,17 @@ namespace l return 0; } + + static + int + readdir(const Branches &branches_, + const char *dirname_, + fuse_dirents_t *buf_) + { + rwlock::ReadGuard guard(branches_.lock); + + return l::readdir(branches_.vec,dirname_,buf_); + } } namespace FUSE diff --git a/src/fuse_readlink.cpp b/src/fuse_readlink.cpp index bec7de49..8cebea19 100644 --- a/src/fuse_readlink.cpp +++ b/src/fuse_readlink.cpp @@ -94,7 +94,6 @@ namespace l int readlink(Policy::Func::Search searchFunc_, const Branches &branches_, - const uint64_t minfreespace_, const char *fusepath_, char *buf_, const size_t size_, @@ -104,7 +103,7 @@ namespace l int rv; vector basepaths; - rv = searchFunc_(branches_,fusepath_,minfreespace_,&basepaths); + rv = searchFunc_(branches_,fusepath_,&basepaths); if(rv == -1) return -errno; @@ -126,7 +125,6 @@ namespace FUSE return l::readlink(config.func.readlink.policy, config.branches, - config.minfreespace, fusepath_, buf_, size_, diff --git a/src/fuse_removexattr.cpp b/src/fuse_removexattr.cpp index 987108c4..4e7c5f38 100644 --- a/src/fuse_removexattr.cpp +++ b/src/fuse_removexattr.cpp @@ -70,14 +70,13 @@ namespace l int removexattr(Policy::Func::Action actionFunc_, const Branches &branches_, - const uint64_t minfreespace_, const char *fusepath_, const char *attrname_) { int rv; vector basepaths; - rv = actionFunc_(branches_,fusepath_,minfreespace_,&basepaths); + rv = actionFunc_(branches_,fusepath_,&basepaths); if(rv == -1) return -errno; @@ -103,7 +102,6 @@ namespace FUSE return l::removexattr(config.func.removexattr.policy, config.branches, - config.minfreespace, fusepath_, attrname_); } diff --git a/src/fuse_rename.cpp b/src/fuse_rename.cpp index 13c9852b..ff4d1541 100644 --- a/src/fuse_rename.cpp +++ b/src/fuse_rename.cpp @@ -99,7 +99,6 @@ int _rename_create_path(Policy::Func::Search searchFunc, Policy::Func::Action actionFunc, const Branches &branches_, - const uint64_t minfreespace, const char *oldfusepath, const char *newfusepath) { @@ -111,13 +110,13 @@ _rename_create_path(Policy::Func::Search searchFunc, vector oldbasepaths; vector branches; - rv = actionFunc(branches_,oldfusepath,minfreespace,&oldbasepaths); + rv = actionFunc(branches_,oldfusepath,&oldbasepaths); if(rv == -1) return -errno; newfusedirpath = fs::path::dirname(newfusepath); - rv = searchFunc(branches_,newfusedirpath,minfreespace,&newbasepath); + rv = searchFunc(branches_,newfusedirpath,&newbasepath); if(rv == -1) return -errno; @@ -146,14 +145,13 @@ static int _clonepath(Policy::Func::Search searchFunc, const Branches &branches_, - const uint64_t minfreespace, const string &dstbasepath, const string &fusedirpath) { int rv; vector srcbasepath; - rv = searchFunc(branches_,fusedirpath,minfreespace,&srcbasepath); + rv = searchFunc(branches_,fusedirpath,&srcbasepath); if(rv == -1) return -errno; @@ -167,7 +165,6 @@ int _clonepath_if_would_create(Policy::Func::Search searchFunc, Policy::Func::Create createFunc, const Branches &branches_, - const uint64_t minfreespace, const string &oldbasepath, const char *oldfusepath, const char *newfusepath) @@ -178,12 +175,12 @@ _clonepath_if_would_create(Policy::Func::Search searchFunc, newfusedirpath = fs::path::dirname(newfusepath); - rv = createFunc(branches_,newfusedirpath,minfreespace,&newbasepath); + rv = createFunc(branches_,newfusedirpath,&newbasepath); if(rv == -1) return rv; if(oldbasepath == newbasepath[0]) - return _clonepath(searchFunc,branches_,minfreespace,oldbasepath,newfusedirpath); + return _clonepath(searchFunc,branches_,oldbasepath,newfusedirpath); return (errno=EXDEV,-1); } @@ -193,7 +190,6 @@ void _rename_preserve_path_core(Policy::Func::Search searchFunc, Policy::Func::Create createFunc, const Branches &branches_, - const uint64_t minfreespace, const vector &oldbasepaths, const string &oldbasepath, const char *oldfusepath, @@ -218,8 +214,8 @@ _rename_preserve_path_core(Policy::Func::Search searchFunc, if((rv == -1) && (errno == ENOENT)) { rv = _clonepath_if_would_create(searchFunc,createFunc, - branches_,minfreespace, - oldbasepath,oldfusepath,newfusepath); + branches_,oldbasepath, + oldfusepath,newfusepath); if(rv == 0) rv = fs::rename(oldfullpath,newfullpath); } @@ -240,7 +236,6 @@ _rename_preserve_path(Policy::Func::Search searchFunc, Policy::Func::Action actionFunc, Policy::Func::Create createFunc, const Branches &branches_, - const uint64_t minfreespace, const char *oldfusepath, const char *newfusepath) { @@ -250,7 +245,7 @@ _rename_preserve_path(Policy::Func::Search searchFunc, vector oldbasepaths; vector branches; - rv = actionFunc(branches_,oldfusepath,minfreespace,&oldbasepaths); + rv = actionFunc(branches_,oldfusepath,&oldbasepaths); if(rv == -1) return -errno; @@ -262,7 +257,7 @@ _rename_preserve_path(Policy::Func::Search searchFunc, const string &oldbasepath = branches[i]; _rename_preserve_path_core(searchFunc,createFunc, - branches_,minfreespace, + branches_, oldbasepaths,oldbasepath, oldfusepath,newfusepath, error,toremove); @@ -291,14 +286,12 @@ namespace FUSE config.func.rename.policy, config.func.create.policy, config.branches, - config.minfreespace, oldpath, newpath); return _rename_create_path(config.func.getattr.policy, config.func.rename.policy, config.branches, - config.minfreespace, oldpath, newpath); } diff --git a/src/fuse_rmdir.cpp b/src/fuse_rmdir.cpp index a6fc5353..295acf55 100644 --- a/src/fuse_rmdir.cpp +++ b/src/fuse_rmdir.cpp @@ -69,13 +69,12 @@ namespace l int rmdir(Policy::Func::Action actionFunc_, const Branches &branches_, - const uint64_t minfreespace_, const char *fusepath_) { int rv; vector basepaths; - rv = actionFunc_(branches_,fusepath_,minfreespace_,&basepaths); + rv = actionFunc_(branches_,fusepath_,&basepaths); if(rv == -1) return -errno; @@ -94,7 +93,6 @@ namespace FUSE return l::rmdir(config.func.rmdir.policy, config.branches, - config.minfreespace, fusepath_); } } diff --git a/src/fuse_setxattr.cpp b/src/fuse_setxattr.cpp index 4fcd0b66..577b3709 100644 --- a/src/fuse_setxattr.cpp +++ b/src/fuse_setxattr.cpp @@ -124,7 +124,6 @@ namespace l int setxattr(Policy::Func::Action actionFunc, const Branches &branches_, - const uint64_t minfreespace, const char *fusepath, const char *attrname, const char *attrval, @@ -134,7 +133,7 @@ namespace l int rv; vector basepaths; - rv = actionFunc(branches_,fusepath,minfreespace,&basepaths); + rv = actionFunc(branches_,fusepath,&basepaths); if(rv == -1) return -errno; @@ -171,7 +170,6 @@ namespace FUSE return l::setxattr(config.func.setxattr.policy, config.branches, - config.minfreespace, fusepath, attrname, attrval, diff --git a/src/fuse_statfs.cpp b/src/fuse_statfs.cpp index 1ba6afa5..0c15f7bf 100644 --- a/src/fuse_statfs.cpp +++ b/src/fuse_statfs.cpp @@ -19,6 +19,7 @@ #include "fs_lstat.hpp" #include "fs_path.hpp" #include "fs_statvfs.hpp" +#include "rwlock.hpp" #include "statvfs_util.hpp" #include "ugid.hpp" @@ -84,6 +85,8 @@ namespace l const StatFSIgnore ignore_, struct statvfs *fsstat_) { + rwlock::ReadGuard guard(branches_.lock); + int rv; string fullpath; struct stat st; @@ -96,11 +99,11 @@ namespace l min_bsize = std::numeric_limits::max(); min_frsize = std::numeric_limits::max(); min_namemax = std::numeric_limits::max(); - for(size_t i = 0, ei = branches_.size(); i < ei; i++) + for(size_t i = 0, ei = branches_.vec.size(); i < ei; i++) { fullpath = ((mode_ == StatFS::ENUM::FULL) ? - fs::path::make(branches_[i].path,fusepath_) : - branches_[i].path); + fs::path::make(branches_.vec[i].path,fusepath_) : + branches_.vec[i].path); rv = fs::lstat(fullpath,&st); if(rv == -1) @@ -117,7 +120,7 @@ namespace l if(stvfs.f_namemax && (min_namemax > stvfs.f_namemax)) min_namemax = stvfs.f_namemax; - if(l::should_ignore(ignore_,&branches_[i],StatVFS::readonly(stvfs))) + if(l::should_ignore(ignore_,&branches_.vec[i],StatVFS::readonly(stvfs))) { stvfs.f_bavail = 0; stvfs.f_favail = 0; diff --git a/src/fuse_symlink.cpp b/src/fuse_symlink.cpp index efd6b421..e1ac7108 100644 --- a/src/fuse_symlink.cpp +++ b/src/fuse_symlink.cpp @@ -83,7 +83,6 @@ namespace l symlink(Policy::Func::Search searchFunc_, Policy::Func::Create createFunc_, const Branches &branches_, - const uint64_t minfreespace_, const char *oldpath_, const char *newpath_) { @@ -94,11 +93,11 @@ namespace l newdirpath = fs::path::dirname(newpath_); - rv = searchFunc_(branches_,newdirpath,minfreespace_,&existingpaths); + rv = searchFunc_(branches_,newdirpath,&existingpaths); if(rv == -1) return -errno; - rv = createFunc_(branches_,newdirpath,minfreespace_,&newbasepaths); + rv = createFunc_(branches_,newdirpath,&newbasepaths); if(rv == -1) return -errno; @@ -120,7 +119,6 @@ namespace FUSE return l::symlink(config.func.getattr.policy, config.func.symlink.policy, config.branches, - config.minfreespace, oldpath_, newpath_); } diff --git a/src/fuse_truncate.cpp b/src/fuse_truncate.cpp index aa118fc4..24ae7256 100644 --- a/src/fuse_truncate.cpp +++ b/src/fuse_truncate.cpp @@ -72,14 +72,13 @@ namespace l int truncate(Policy::Func::Action actionFunc_, const Branches &branches_, - const uint64_t minfreespace_, const char *fusepath_, const off_t size_) { int rv; vector basepaths; - rv = actionFunc_(branches_,fusepath_,minfreespace_,&basepaths); + rv = actionFunc_(branches_,fusepath_,&basepaths); if(rv == -1) return -errno; @@ -99,7 +98,6 @@ namespace FUSE return l::truncate(config.func.truncate.policy, config.branches, - config.minfreespace, fusepath_, size_); } diff --git a/src/fuse_unlink.cpp b/src/fuse_unlink.cpp index 291bd199..0897cec6 100644 --- a/src/fuse_unlink.cpp +++ b/src/fuse_unlink.cpp @@ -69,13 +69,12 @@ namespace l int unlink(Policy::Func::Action actionFunc_, const Branches &branches_, - const uint64_t minfreespace_, const char *fusepath_) { int rv; vector basepaths; - rv = actionFunc_(branches_,fusepath_,minfreespace_,&basepaths); + rv = actionFunc_(branches_,fusepath_,&basepaths); if(rv == -1) return -errno; @@ -96,7 +95,6 @@ namespace FUSE return l::unlink(config.func.unlink.policy, config.branches, - config.minfreespace, fusepath_); } } diff --git a/src/fuse_utimens.cpp b/src/fuse_utimens.cpp index c6d8bbf9..29b088f3 100644 --- a/src/fuse_utimens.cpp +++ b/src/fuse_utimens.cpp @@ -71,14 +71,13 @@ namespace l int utimens(Policy::Func::Action actionFunc_, const Branches &branches_, - const uint64_t minfreespace_, const char *fusepath_, const timespec ts_[2]) { int rv; vector basepaths; - rv = actionFunc_(branches_,fusepath_,minfreespace_,&basepaths); + rv = actionFunc_(branches_,fusepath_,&basepaths); if(rv == -1) return -errno; @@ -98,7 +97,6 @@ namespace FUSE return l::utimens(config.func.utimens.policy, config.branches, - config.minfreespace, fusepath_, ts_); } diff --git a/src/fuse_write.cpp b/src/fuse_write.cpp index f1806f66..3dfe4195 100644 --- a/src/fuse_write.cpp +++ b/src/fuse_write.cpp @@ -92,7 +92,6 @@ namespace l rv = fs::movefile_as_root(config.moveonenospc.policy, config.branches, - config.minfreespace, fi_->fusepath, &fi_->fd); if(rv == -1) diff --git a/src/fuse_write_buf.cpp b/src/fuse_write_buf.cpp index d21d839e..7c88a006 100644 --- a/src/fuse_write_buf.cpp +++ b/src/fuse_write_buf.cpp @@ -74,7 +74,6 @@ namespace l rv = fs::movefile_as_root(config.moveonenospc.policy, config.branches, - config.minfreespace, fi_->fusepath, &fi_->fd); if(rv == -1) diff --git a/src/nonstd/optional.hpp b/src/nonstd/optional.hpp new file mode 100644 index 00000000..133673a9 --- /dev/null +++ b/src/nonstd/optional.hpp @@ -0,0 +1,1715 @@ +// +// Copyright (c) 2014-2018 Martin Moene +// +// https://github.com/martinmoene/optional-lite +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#pragma once + +#ifndef NONSTD_OPTIONAL_LITE_HPP +#define NONSTD_OPTIONAL_LITE_HPP + +#define optional_lite_MAJOR 3 +#define optional_lite_MINOR 2 +#define optional_lite_PATCH 0 + +#define optional_lite_VERSION optional_STRINGIFY(optional_lite_MAJOR) "." optional_STRINGIFY(optional_lite_MINOR) "." optional_STRINGIFY(optional_lite_PATCH) + +#define optional_STRINGIFY( x ) optional_STRINGIFY_( x ) +#define optional_STRINGIFY_( x ) #x + +// optional-lite configuration: + +#define optional_OPTIONAL_DEFAULT 0 +#define optional_OPTIONAL_NONSTD 1 +#define optional_OPTIONAL_STD 2 + +#if !defined( optional_CONFIG_SELECT_OPTIONAL ) +# define optional_CONFIG_SELECT_OPTIONAL ( optional_HAVE_STD_OPTIONAL ? optional_OPTIONAL_STD : optional_OPTIONAL_NONSTD ) +#endif + +// Control presence of exception handling (try and auto discover): + +#ifndef optional_CONFIG_NO_EXCEPTIONS +# if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND) +# define optional_CONFIG_NO_EXCEPTIONS 0 +# else +# define optional_CONFIG_NO_EXCEPTIONS 1 +# endif +#endif + +// C++ language version detection (C++20 is speculative): +// Note: VC14.0/1900 (VS2015) lacks too much from C++14. + +#ifndef optional_CPLUSPLUS +# if defined(_MSVC_LANG ) && !defined(__clang__) +# define optional_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG ) +# else +# define optional_CPLUSPLUS __cplusplus +# endif +#endif + +#define optional_CPP98_OR_GREATER ( optional_CPLUSPLUS >= 199711L ) +#define optional_CPP11_OR_GREATER ( optional_CPLUSPLUS >= 201103L ) +#define optional_CPP11_OR_GREATER_ ( optional_CPLUSPLUS >= 201103L ) +#define optional_CPP14_OR_GREATER ( optional_CPLUSPLUS >= 201402L ) +#define optional_CPP17_OR_GREATER ( optional_CPLUSPLUS >= 201703L ) +#define optional_CPP20_OR_GREATER ( optional_CPLUSPLUS >= 202000L ) + +// C++ language version (represent 98 as 3): + +#define optional_CPLUSPLUS_V ( optional_CPLUSPLUS / 100 - (optional_CPLUSPLUS > 200000 ? 2000 : 1994) ) + +// Use C++17 std::optional if available and requested: + +#if optional_CPP17_OR_GREATER && defined(__has_include ) +# if __has_include( ) +# define optional_HAVE_STD_OPTIONAL 1 +# else +# define optional_HAVE_STD_OPTIONAL 0 +# endif +#else +# define optional_HAVE_STD_OPTIONAL 0 +#endif + +#define optional_USES_STD_OPTIONAL ( (optional_CONFIG_SELECT_OPTIONAL == optional_OPTIONAL_STD) || ((optional_CONFIG_SELECT_OPTIONAL == optional_OPTIONAL_DEFAULT) && optional_HAVE_STD_OPTIONAL) ) + +// +// in_place: code duplicated in any-lite, expected-lite, optional-lite, value-ptr-lite, variant-lite: +// + +#ifndef nonstd_lite_HAVE_IN_PLACE_TYPES +#define nonstd_lite_HAVE_IN_PLACE_TYPES 1 + +// C++17 std::in_place in : + +#if optional_CPP17_OR_GREATER + +#include + +namespace nonstd { + +using std::in_place; +using std::in_place_type; +using std::in_place_index; +using std::in_place_t; +using std::in_place_type_t; +using std::in_place_index_t; + +#define nonstd_lite_in_place_t( T) std::in_place_t +#define nonstd_lite_in_place_type_t( T) std::in_place_type_t +#define nonstd_lite_in_place_index_t(K) std::in_place_index_t + +#define nonstd_lite_in_place( T) std::in_place_t{} +#define nonstd_lite_in_place_type( T) std::in_place_type_t{} +#define nonstd_lite_in_place_index(K) std::in_place_index_t{} + +} // namespace nonstd + +#else // optional_CPP17_OR_GREATER + +#include + +namespace nonstd { +namespace detail { + +template< class T > +struct in_place_type_tag {}; + +template< std::size_t K > +struct in_place_index_tag {}; + +} // namespace detail + +struct in_place_t {}; + +template< class T > +inline in_place_t in_place( detail::in_place_type_tag /*unused*/ = detail::in_place_type_tag() ) +{ + return in_place_t(); +} + +template< std::size_t K > +inline in_place_t in_place( detail::in_place_index_tag /*unused*/ = detail::in_place_index_tag() ) +{ + return in_place_t(); +} + +template< class T > +inline in_place_t in_place_type( detail::in_place_type_tag /*unused*/ = detail::in_place_type_tag() ) +{ + return in_place_t(); +} + +template< std::size_t K > +inline in_place_t in_place_index( detail::in_place_index_tag /*unused*/ = detail::in_place_index_tag() ) +{ + return in_place_t(); +} + +// mimic templated typedef: + +#define nonstd_lite_in_place_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag ) +#define nonstd_lite_in_place_type_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag ) +#define nonstd_lite_in_place_index_t(K) nonstd::in_place_t(&)( nonstd::detail::in_place_index_tag ) + +#define nonstd_lite_in_place( T) nonstd::in_place_type +#define nonstd_lite_in_place_type( T) nonstd::in_place_type +#define nonstd_lite_in_place_index(K) nonstd::in_place_index + +} // namespace nonstd + +#endif // optional_CPP17_OR_GREATER +#endif // nonstd_lite_HAVE_IN_PLACE_TYPES + +// +// Using std::optional: +// + +#if optional_USES_STD_OPTIONAL + +#include + +namespace nonstd { + + using std::optional; + using std::bad_optional_access; + using std::hash; + + using std::nullopt; + using std::nullopt_t; + + using std::operator==; + using std::operator!=; + using std::operator<; + using std::operator<=; + using std::operator>; + using std::operator>=; + using std::make_optional; + using std::swap; +} + +#else // optional_USES_STD_OPTIONAL + +#include +#include + +// optional-lite alignment configuration: + +#ifndef optional_CONFIG_MAX_ALIGN_HACK +# define optional_CONFIG_MAX_ALIGN_HACK 0 +#endif + +#ifndef optional_CONFIG_ALIGN_AS +// no default, used in #if defined() +#endif + +#ifndef optional_CONFIG_ALIGN_AS_FALLBACK +# define optional_CONFIG_ALIGN_AS_FALLBACK double +#endif + +// Compiler warning suppression: + +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wundef" +#elif defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wundef" +#elif defined(_MSC_VER ) +# pragma warning( push ) +#endif + +// half-open range [lo..hi): +#define optional_BETWEEN( v, lo, hi ) ( (lo) <= (v) && (v) < (hi) ) + +// Compiler versions: +// +// MSVC++ 6.0 _MSC_VER == 1200 optional_COMPILER_MSVC_VERSION == 60 (Visual Studio 6.0) +// MSVC++ 7.0 _MSC_VER == 1300 optional_COMPILER_MSVC_VERSION == 70 (Visual Studio .NET 2002) +// MSVC++ 7.1 _MSC_VER == 1310 optional_COMPILER_MSVC_VERSION == 71 (Visual Studio .NET 2003) +// MSVC++ 8.0 _MSC_VER == 1400 optional_COMPILER_MSVC_VERSION == 80 (Visual Studio 2005) +// MSVC++ 9.0 _MSC_VER == 1500 optional_COMPILER_MSVC_VERSION == 90 (Visual Studio 2008) +// MSVC++ 10.0 _MSC_VER == 1600 optional_COMPILER_MSVC_VERSION == 100 (Visual Studio 2010) +// MSVC++ 11.0 _MSC_VER == 1700 optional_COMPILER_MSVC_VERSION == 110 (Visual Studio 2012) +// MSVC++ 12.0 _MSC_VER == 1800 optional_COMPILER_MSVC_VERSION == 120 (Visual Studio 2013) +// MSVC++ 14.0 _MSC_VER == 1900 optional_COMPILER_MSVC_VERSION == 140 (Visual Studio 2015) +// MSVC++ 14.1 _MSC_VER >= 1910 optional_COMPILER_MSVC_VERSION == 141 (Visual Studio 2017) +// MSVC++ 14.2 _MSC_VER >= 1920 optional_COMPILER_MSVC_VERSION == 142 (Visual Studio 2019) + +#if defined(_MSC_VER ) && !defined(__clang__) +# define optional_COMPILER_MSVC_VER (_MSC_VER ) +# define optional_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900 ) ) ) +#else +# define optional_COMPILER_MSVC_VER 0 +# define optional_COMPILER_MSVC_VERSION 0 +#endif + +#define optional_COMPILER_VERSION( major, minor, patch ) ( 10 * (10 * (major) + (minor) ) + (patch) ) + +#if defined(__GNUC__) && !defined(__clang__) +# define optional_COMPILER_GNUC_VERSION optional_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) +#else +# define optional_COMPILER_GNUC_VERSION 0 +#endif + +#if defined(__clang__) +# define optional_COMPILER_CLANG_VERSION optional_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__) +#else +# define optional_COMPILER_CLANG_VERSION 0 +#endif + +#if optional_BETWEEN(optional_COMPILER_MSVC_VERSION, 70, 140 ) +# pragma warning( disable: 4345 ) // initialization behavior changed +#endif + +#if optional_BETWEEN(optional_COMPILER_MSVC_VERSION, 70, 150 ) +# pragma warning( disable: 4814 ) // in C++14 'constexpr' will not imply 'const' +#endif + +// Presence of language and library features: + +#define optional_HAVE(FEATURE) ( optional_HAVE_##FEATURE ) + +#ifdef _HAS_CPP0X +# define optional_HAS_CPP0X _HAS_CPP0X +#else +# define optional_HAS_CPP0X 0 +#endif + +// Unless defined otherwise below, consider VC14 as C++11 for optional-lite: + +#if optional_COMPILER_MSVC_VER >= 1900 +# undef optional_CPP11_OR_GREATER +# define optional_CPP11_OR_GREATER 1 +#endif + +#define optional_CPP11_90 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1500) +#define optional_CPP11_100 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1600) +#define optional_CPP11_110 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1700) +#define optional_CPP11_120 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1800) +#define optional_CPP11_140 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1900) +#define optional_CPP11_141 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1910) + +#define optional_CPP11_140_490 ((optional_CPP11_OR_GREATER_ && optional_COMPILER_GNUC_VERSION >= 490) || (optional_COMPILER_MSVC_VER >= 1910)) + +#define optional_CPP14_000 (optional_CPP14_OR_GREATER) +#define optional_CPP17_000 (optional_CPP17_OR_GREATER) + +// Presence of C++11 language features: + +#define optional_HAVE_CONSTEXPR_11 optional_CPP11_140 +#define optional_HAVE_IS_DEFAULT optional_CPP11_140 +#define optional_HAVE_NOEXCEPT optional_CPP11_140 +#define optional_HAVE_NULLPTR optional_CPP11_100 +#define optional_HAVE_REF_QUALIFIER optional_CPP11_140_490 +#define optional_HAVE_INITIALIZER_LIST optional_CPP11_140 + +// Presence of C++14 language features: + +#define optional_HAVE_CONSTEXPR_14 optional_CPP14_000 + +// Presence of C++17 language features: + +#define optional_HAVE_NODISCARD optional_CPP17_000 + +// Presence of C++ library features: + +#define optional_HAVE_CONDITIONAL optional_CPP11_120 +#define optional_HAVE_REMOVE_CV optional_CPP11_120 +#define optional_HAVE_TYPE_TRAITS optional_CPP11_90 + +#define optional_HAVE_TR1_TYPE_TRAITS (!! optional_COMPILER_GNUC_VERSION ) +#define optional_HAVE_TR1_ADD_POINTER (!! optional_COMPILER_GNUC_VERSION ) + +// C++ feature usage: + +#if optional_HAVE( CONSTEXPR_11 ) +# define optional_constexpr constexpr +#else +# define optional_constexpr /*constexpr*/ +#endif + +#if optional_HAVE( IS_DEFAULT ) +# define optional_is_default = default; +#else +# define optional_is_default {} +#endif + +#if optional_HAVE( CONSTEXPR_14 ) +# define optional_constexpr14 constexpr +#else +# define optional_constexpr14 /*constexpr*/ +#endif + +#if optional_HAVE( NODISCARD ) +# define optional_nodiscard [[nodiscard]] +#else +# define optional_nodiscard /*[[nodiscard]]*/ +#endif + +#if optional_HAVE( NOEXCEPT ) +# define optional_noexcept noexcept +#else +# define optional_noexcept /*noexcept*/ +#endif + +#if optional_HAVE( NULLPTR ) +# define optional_nullptr nullptr +#else +# define optional_nullptr NULL +#endif + +#if optional_HAVE( REF_QUALIFIER ) +// NOLINTNEXTLINE( bugprone-macro-parentheses ) +# define optional_ref_qual & +# define optional_refref_qual && +#else +# define optional_ref_qual /*&*/ +# define optional_refref_qual /*&&*/ +#endif + +// additional includes: + +#if optional_CONFIG_NO_EXCEPTIONS +// already included: +#else +# include +#endif + +#if optional_CPP11_OR_GREATER +# include +#endif + +#if optional_HAVE( INITIALIZER_LIST ) +# include +#endif + +#if optional_HAVE( TYPE_TRAITS ) +# include +#elif optional_HAVE( TR1_TYPE_TRAITS ) +# include +#endif + +// Method enabling + +#if optional_CPP11_OR_GREATER + +#define optional_REQUIRES_0(...) \ + template< bool B = (__VA_ARGS__), typename std::enable_if::type = 0 > + +#define optional_REQUIRES_T(...) \ + , typename std::enable_if< (__VA_ARGS__), int >::type = 0 + +#define optional_REQUIRES_R(R, ...) \ + typename std::enable_if< (__VA_ARGS__), R>::type + +#define optional_REQUIRES_A(...) \ + , typename std::enable_if< (__VA_ARGS__), void*>::type = nullptr + +#endif + +// +// optional: +// + +namespace nonstd { namespace optional_lite { + +namespace std11 { + +#if optional_CPP11_OR_GREATER + using std::move; +#else + template< typename T > T & move( T & t ) { return t; } +#endif + +#if optional_HAVE( CONDITIONAL ) + using std::conditional; +#else + template< bool B, typename T, typename F > struct conditional { typedef T type; }; + template< typename T, typename F > struct conditional { typedef F type; }; +#endif // optional_HAVE_CONDITIONAL + +// gcc < 5: +#if optional_CPP11_OR_GREATER +#if optional_BETWEEN( optional_COMPILER_GNUC_VERSION, 1, 500 ) + template< typename T > struct is_trivially_copy_constructible : std::true_type{}; + template< typename T > struct is_trivially_move_constructible : std::true_type{}; +#else + using std::is_trivially_copy_constructible; + using std::is_trivially_move_constructible; +#endif +#endif +} // namespace std11 + +#if optional_CPP11_OR_GREATER + +/// type traits C++17: + +namespace std17 { + +#if optional_CPP17_OR_GREATER + +using std::is_swappable; +using std::is_nothrow_swappable; + +#elif optional_CPP11_OR_GREATER + +namespace detail { + +using std::swap; + +struct is_swappable +{ + template< typename T, typename = decltype( swap( std::declval(), std::declval() ) ) > + static std::true_type test( int /*unused*/ ); + + template< typename > + static std::false_type test(...); +}; + +struct is_nothrow_swappable +{ + // wrap noexcept(expr) in separate function as work-around for VC140 (VS2015): + + template< typename T > + static constexpr bool satisfies() + { + return noexcept( swap( std::declval(), std::declval() ) ); + } + + template< typename T > + static auto test( int /*unused*/ ) -> std::integral_constant()>{} + + template< typename > + static auto test(...) -> std::false_type; +}; + +} // namespace detail + +// is [nothow] swappable: + +template< typename T > +struct is_swappable : decltype( detail::is_swappable::test(0) ){}; + +template< typename T > +struct is_nothrow_swappable : decltype( detail::is_nothrow_swappable::test(0) ){}; + +#endif // optional_CPP17_OR_GREATER + +} // namespace std17 + +/// type traits C++20: + +namespace std20 { + +template< typename T > +struct remove_cvref +{ + typedef typename std::remove_cv< typename std::remove_reference::type >::type type; +}; + +} // namespace std20 + +#endif // optional_CPP11_OR_GREATER + +/// class optional + +template< typename T > +class optional; + +namespace detail { + +// C++11 emulation: + +struct nulltype{}; + +template< typename Head, typename Tail > +struct typelist +{ + typedef Head head; + typedef Tail tail; +}; + +#if optional_CONFIG_MAX_ALIGN_HACK + +// Max align, use most restricted type for alignment: + +#define optional_UNIQUE( name ) optional_UNIQUE2( name, __LINE__ ) +#define optional_UNIQUE2( name, line ) optional_UNIQUE3( name, line ) +#define optional_UNIQUE3( name, line ) name ## line + +#define optional_ALIGN_TYPE( type ) \ + type optional_UNIQUE( _t ); struct_t< type > optional_UNIQUE( _st ) + +template< typename T > +struct struct_t { T _; }; + +union max_align_t +{ + optional_ALIGN_TYPE( char ); + optional_ALIGN_TYPE( short int ); + optional_ALIGN_TYPE( int ); + optional_ALIGN_TYPE( long int ); + optional_ALIGN_TYPE( float ); + optional_ALIGN_TYPE( double ); + optional_ALIGN_TYPE( long double ); + optional_ALIGN_TYPE( char * ); + optional_ALIGN_TYPE( short int * ); + optional_ALIGN_TYPE( int * ); + optional_ALIGN_TYPE( long int * ); + optional_ALIGN_TYPE( float * ); + optional_ALIGN_TYPE( double * ); + optional_ALIGN_TYPE( long double * ); + optional_ALIGN_TYPE( void * ); + +#ifdef HAVE_LONG_LONG + optional_ALIGN_TYPE( long long ); +#endif + + struct Unknown; + + Unknown ( * optional_UNIQUE(_) )( Unknown ); + Unknown * Unknown::* optional_UNIQUE(_); + Unknown ( Unknown::* optional_UNIQUE(_) )( Unknown ); + + struct_t< Unknown ( * )( Unknown) > optional_UNIQUE(_); + struct_t< Unknown * Unknown::* > optional_UNIQUE(_); + struct_t< Unknown ( Unknown::* )(Unknown) > optional_UNIQUE(_); +}; + +#undef optional_UNIQUE +#undef optional_UNIQUE2 +#undef optional_UNIQUE3 + +#undef optional_ALIGN_TYPE + +#elif defined( optional_CONFIG_ALIGN_AS ) // optional_CONFIG_MAX_ALIGN_HACK + +// Use user-specified type for alignment: + +#define optional_ALIGN_AS( unused ) \ + optional_CONFIG_ALIGN_AS + +#else // optional_CONFIG_MAX_ALIGN_HACK + +// Determine POD type to use for alignment: + +#define optional_ALIGN_AS( to_align ) \ + typename type_of_size< alignment_types, alignment_of< to_align >::value >::type + +template< typename T > +struct alignment_of; + +template< typename T > +struct alignment_of_hack +{ + char c; + T t; + alignment_of_hack(); +}; + +template< size_t A, size_t S > +struct alignment_logic +{ + enum { value = A < S ? A : S }; +}; + +template< typename T > +struct alignment_of +{ + enum { value = alignment_logic< + sizeof( alignment_of_hack ) - sizeof(T), sizeof(T) >::value }; +}; + +template< typename List, size_t N > +struct type_of_size +{ + typedef typename std11::conditional< + N == sizeof( typename List::head ), + typename List::head, + typename type_of_size::type >::type type; +}; + +template< size_t N > +struct type_of_size< nulltype, N > +{ + typedef optional_CONFIG_ALIGN_AS_FALLBACK type; +}; + +template< typename T> +struct struct_t { T _; }; + +#define optional_ALIGN_TYPE( type ) \ + typelist< type , typelist< struct_t< type > + +struct Unknown; + +typedef + optional_ALIGN_TYPE( char ), + optional_ALIGN_TYPE( short ), + optional_ALIGN_TYPE( int ), + optional_ALIGN_TYPE( long ), + optional_ALIGN_TYPE( float ), + optional_ALIGN_TYPE( double ), + optional_ALIGN_TYPE( long double ), + + optional_ALIGN_TYPE( char *), + optional_ALIGN_TYPE( short * ), + optional_ALIGN_TYPE( int * ), + optional_ALIGN_TYPE( long * ), + optional_ALIGN_TYPE( float * ), + optional_ALIGN_TYPE( double * ), + optional_ALIGN_TYPE( long double * ), + + optional_ALIGN_TYPE( Unknown ( * )( Unknown ) ), + optional_ALIGN_TYPE( Unknown * Unknown::* ), + optional_ALIGN_TYPE( Unknown ( Unknown::* )( Unknown ) ), + + nulltype + > > > > > > > > > > > > > > + > > > > > > > > > > > > > > + > > > > > > + alignment_types; + +#undef optional_ALIGN_TYPE + +#endif // optional_CONFIG_MAX_ALIGN_HACK + +/// C++03 constructed union to hold value. + +template< typename T > +union storage_t +{ +//private: +// template< typename > friend class optional; + + typedef T value_type; + + storage_t() optional_is_default + + explicit storage_t( value_type const & v ) + { + construct_value( v ); + } + + void construct_value( value_type const & v ) + { + ::new( value_ptr() ) value_type( v ); + } + +#if optional_CPP11_OR_GREATER + + explicit storage_t( value_type && v ) + { + construct_value( std::move( v ) ); + } + + void construct_value( value_type && v ) + { + ::new( value_ptr() ) value_type( std::move( v ) ); + } + + template< class... Args > + void emplace( Args&&... args ) + { + ::new( value_ptr() ) value_type( std::forward(args)... ); + } + + template< class U, class... Args > + void emplace( std::initializer_list il, Args&&... args ) + { + ::new( value_ptr() ) value_type( il, std::forward(args)... ); + } + +#endif + + void destruct_value() + { + value_ptr()->~T(); + } + + optional_nodiscard value_type const * value_ptr() const + { + return as(); + } + + value_type * value_ptr() + { + return as(); + } + + optional_nodiscard value_type const & value() const optional_ref_qual + { + return * value_ptr(); + } + + value_type & value() optional_ref_qual + { + return * value_ptr(); + } + +#if optional_HAVE( REF_QUALIFIER ) + + optional_nodiscard value_type const && value() const optional_refref_qual + { + return std::move( value() ); + } + + value_type && value() optional_refref_qual + { + return std::move( value() ); + } + +#endif + +#if optional_CPP11_OR_GREATER + + using aligned_storage_t = typename std::aligned_storage< sizeof(value_type), alignof(value_type) >::type; + aligned_storage_t data; + +#elif optional_CONFIG_MAX_ALIGN_HACK + + typedef struct { unsigned char data[ sizeof(value_type) ]; } aligned_storage_t; + + max_align_t hack; + aligned_storage_t data; + +#else + typedef optional_ALIGN_AS(value_type) align_as_type; + + typedef struct { align_as_type data[ 1 + ( sizeof(value_type) - 1 ) / sizeof(align_as_type) ]; } aligned_storage_t; + aligned_storage_t data; + +# undef optional_ALIGN_AS + +#endif // optional_CONFIG_MAX_ALIGN_HACK + + optional_nodiscard void * ptr() optional_noexcept + { + return &data; + } + + optional_nodiscard void const * ptr() const optional_noexcept + { + return &data; + } + + template + optional_nodiscard U * as() + { + return reinterpret_cast( ptr() ); + } + + template + optional_nodiscard U const * as() const + { + return reinterpret_cast( ptr() ); + } +}; + +} // namespace detail + +/// disengaged state tag + +struct nullopt_t +{ + struct init{}; + explicit optional_constexpr nullopt_t( init /*unused*/ ) optional_noexcept {} +}; + +#if optional_HAVE( CONSTEXPR_11 ) +constexpr nullopt_t nullopt{ nullopt_t::init{} }; +#else +// extra parenthesis to prevent the most vexing parse: +const nullopt_t nullopt(( nullopt_t::init() )); +#endif + +/// optional access error + +#if ! optional_CONFIG_NO_EXCEPTIONS + +class bad_optional_access : public std::logic_error +{ +public: + explicit bad_optional_access() + : logic_error( "bad optional access" ) {} +}; + +#endif //optional_CONFIG_NO_EXCEPTIONS + +/// optional + +template< typename T> +class optional +{ +private: + template< typename > friend class optional; + + typedef void (optional::*safe_bool)() const; + +public: + typedef T value_type; + + // x.x.3.1, constructors + + // 1a - default construct + optional_constexpr optional() optional_noexcept + : has_value_( false ) + , contained() + {} + + // 1b - construct explicitly empty + // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions ) + optional_constexpr optional( nullopt_t /*unused*/ ) optional_noexcept + : has_value_( false ) + , contained() + {} + + // 2 - copy-construct +#if optional_CPP11_OR_GREATER + // template< typename U = T + // optional_REQUIRES_T( + // std::is_copy_constructible::value + // || std11::is_trivially_copy_constructible::value + // ) + // > +#endif + optional_constexpr14 optional( optional const & other ) + : has_value_( other.has_value() ) + { + if ( other.has_value() ) + { + contained.construct_value( other.contained.value() ); + } + } + +#if optional_CPP11_OR_GREATER + + // 3 (C++11) - move-construct from optional + template< typename U = T + optional_REQUIRES_T( + std::is_move_constructible::value + || std11::is_trivially_move_constructible::value + ) + > + optional_constexpr14 optional( optional && other ) + // NOLINTNEXTLINE( performance-noexcept-move-constructor ) + noexcept( std::is_nothrow_move_constructible::value ) + : has_value_( other.has_value() ) + { + if ( other.has_value() ) + { + contained.construct_value( std::move( other.contained.value() ) ); + } + } + + // 4a (C++11) - explicit converting copy-construct from optional + template< typename U + optional_REQUIRES_T( + std::is_constructible::value + && !std::is_constructible & >::value + && !std::is_constructible && >::value + && !std::is_constructible const & >::value + && !std::is_constructible const && >::value + && !std::is_convertible< optional & , T>::value + && !std::is_convertible< optional && , T>::value + && !std::is_convertible< optional const & , T>::value + && !std::is_convertible< optional const &&, T>::value + && !std::is_convertible< U const & , T>::value /*=> explicit */ + ) + > + explicit optional( optional const & other ) + : has_value_( other.has_value() ) + { + if ( other.has_value() ) + { + contained.construct_value( T{ other.contained.value() } ); + } + } +#endif // optional_CPP11_OR_GREATER + + // 4b (C++98 and later) - non-explicit converting copy-construct from optional + template< typename U +#if optional_CPP11_OR_GREATER + optional_REQUIRES_T( + std::is_constructible::value + && !std::is_constructible & >::value + && !std::is_constructible && >::value + && !std::is_constructible const & >::value + && !std::is_constructible const && >::value + && !std::is_convertible< optional & , T>::value + && !std::is_convertible< optional && , T>::value + && !std::is_convertible< optional const & , T>::value + && !std::is_convertible< optional const &&, T>::value + && std::is_convertible< U const & , T>::value /*=> non-explicit */ + ) +#endif // optional_CPP11_OR_GREATER + > + // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions ) + /*non-explicit*/ optional( optional const & other ) + : has_value_( other.has_value() ) + { + if ( other.has_value() ) + { + contained.construct_value( other.contained.value() ); + } + } + +#if optional_CPP11_OR_GREATER + + // 5a (C++11) - explicit converting move-construct from optional + template< typename U + optional_REQUIRES_T( + std::is_constructible::value + && !std::is_constructible & >::value + && !std::is_constructible && >::value + && !std::is_constructible const & >::value + && !std::is_constructible const && >::value + && !std::is_convertible< optional & , T>::value + && !std::is_convertible< optional && , T>::value + && !std::is_convertible< optional const & , T>::value + && !std::is_convertible< optional const &&, T>::value + && !std::is_convertible< U &&, T>::value /*=> explicit */ + ) + > + explicit optional( optional && other + ) + : has_value_( other.has_value() ) + { + if ( other.has_value() ) + { + contained.construct_value( T{ std::move( other.contained.value() ) } ); + } + } + + // 5a (C++11) - non-explicit converting move-construct from optional + template< typename U + optional_REQUIRES_T( + std::is_constructible::value + && !std::is_constructible & >::value + && !std::is_constructible && >::value + && !std::is_constructible const & >::value + && !std::is_constructible const && >::value + && !std::is_convertible< optional & , T>::value + && !std::is_convertible< optional && , T>::value + && !std::is_convertible< optional const & , T>::value + && !std::is_convertible< optional const &&, T>::value + && std::is_convertible< U &&, T>::value /*=> non-explicit */ + ) + > + // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions ) + /*non-explicit*/ optional( optional && other ) + : has_value_( other.has_value() ) + { + if ( other.has_value() ) + { + contained.construct_value( std::move( other.contained.value() ) ); + } + } + + // 6 (C++11) - in-place construct + template< typename... Args + optional_REQUIRES_T( + std::is_constructible::value + ) + > + optional_constexpr explicit optional( nonstd_lite_in_place_t(T), Args&&... args ) + : has_value_( true ) + , contained( T( std::forward(args)...) ) + {} + + // 7 (C++11) - in-place construct, initializer-list + template< typename U, typename... Args + optional_REQUIRES_T( + std::is_constructible&, Args&&...>::value + ) + > + optional_constexpr explicit optional( nonstd_lite_in_place_t(T), std::initializer_list il, Args&&... args ) + : has_value_( true ) + , contained( T( il, std::forward(args)...) ) + {} + + // 8a (C++11) - explicit move construct from value + template< typename U = T + optional_REQUIRES_T( + std::is_constructible::value + && !std::is_same::type, nonstd_lite_in_place_t(U)>::value + && !std::is_same::type, optional>::value + && !std::is_convertible::value /*=> explicit */ + ) + > + optional_constexpr explicit optional( U && value ) + : has_value_( true ) + , contained( T{ std::forward( value ) } ) + {} + + // 8b (C++11) - non-explicit move construct from value + template< typename U = T + optional_REQUIRES_T( + std::is_constructible::value + && !std::is_same::type, nonstd_lite_in_place_t(U)>::value + && !std::is_same::type, optional>::value + && std::is_convertible::value /*=> non-explicit */ + ) + > + // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions ) + optional_constexpr /*non-explicit*/ optional( U && value ) + : has_value_( true ) + , contained( std::forward( value ) ) + {} + +#else // optional_CPP11_OR_GREATER + + // 8 (C++98) + optional( value_type const & value ) + : has_value_( true ) + , contained( value ) + {} + +#endif // optional_CPP11_OR_GREATER + + // x.x.3.2, destructor + + ~optional() + { + if ( has_value() ) + { + contained.destruct_value(); + } + } + + // x.x.3.3, assignment + + // 1 (C++98and later) - assign explicitly empty + optional & operator=( nullopt_t /*unused*/) optional_noexcept + { + reset(); + return *this; + } + + // 2 (C++98and later) - copy-assign from optional +#if optional_CPP11_OR_GREATER + // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator ) + optional_REQUIRES_R( + optional &, + true +// std::is_copy_constructible::value +// && std::is_copy_assignable::value + ) + operator=( optional const & other ) + noexcept( + std::is_nothrow_move_assignable::value + && std::is_nothrow_move_constructible::value + ) +#else + optional & operator=( optional const & other ) +#endif + { + if ( (has_value() == true ) && (other.has_value() == false) ) { reset(); } + else if ( (has_value() == false) && (other.has_value() == true ) ) { initialize( *other ); } + else if ( (has_value() == true ) && (other.has_value() == true ) ) { contained.value() = *other; } + return *this; + } + +#if optional_CPP11_OR_GREATER + + // 3 (C++11) - move-assign from optional + // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator ) + optional_REQUIRES_R( + optional &, + true +// std::is_move_constructible::value +// && std::is_move_assignable::value + ) + operator=( optional && other ) noexcept + { + if ( (has_value() == true ) && (other.has_value() == false) ) { reset(); } + else if ( (has_value() == false) && (other.has_value() == true ) ) { initialize( std::move( *other ) ); } + else if ( (has_value() == true ) && (other.has_value() == true ) ) { contained.value() = std::move( *other ); } + return *this; + } + + // 4 (C++11) - move-assign from value + template< typename U = T > + // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator ) + optional_REQUIRES_R( + optional &, + std::is_constructible::value + && std::is_assignable::value + && !std::is_same::type, nonstd_lite_in_place_t(U)>::value + && !std::is_same::type, optional>::value + && !(std::is_scalar::value && std::is_same::type>::value) + ) + operator=( U && value ) + { + if ( has_value() ) + { + contained.value() = std::forward( value ); + } + else + { + initialize( T( std::forward( value ) ) ); + } + return *this; + } + +#else // optional_CPP11_OR_GREATER + + // 4 (C++98) - copy-assign from value + template< typename U /*= T*/ > + optional & operator=( U const & value ) + { + if ( has_value() ) contained.value() = value; + else initialize( T( value ) ); + return *this; + } + +#endif // optional_CPP11_OR_GREATER + + // 5 (C++98 and later) - converting copy-assign from optional + template< typename U > +#if optional_CPP11_OR_GREATER + // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator ) + optional_REQUIRES_R( + optional&, + std::is_constructible< T , U const &>::value + && std::is_assignable< T&, U const &>::value + && !std::is_constructible & >::value + && !std::is_constructible && >::value + && !std::is_constructible const & >::value + && !std::is_constructible const && >::value + && !std::is_convertible< optional & , T>::value + && !std::is_convertible< optional && , T>::value + && !std::is_convertible< optional const & , T>::value + && !std::is_convertible< optional const &&, T>::value + && !std::is_assignable< T&, optional & >::value + && !std::is_assignable< T&, optional && >::value + && !std::is_assignable< T&, optional const & >::value + && !std::is_assignable< T&, optional const && >::value + ) +#else + optional& +#endif // optional_CPP11_OR_GREATER + operator=( optional const & other ) + { + return *this = optional( other ); + } + +#if optional_CPP11_OR_GREATER + + // 6 (C++11) - converting move-assign from optional + template< typename U > + // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator ) + optional_REQUIRES_R( + optional&, + std::is_constructible< T , U>::value + && std::is_assignable< T&, U>::value + && !std::is_constructible & >::value + && !std::is_constructible && >::value + && !std::is_constructible const & >::value + && !std::is_constructible const && >::value + && !std::is_convertible< optional & , T>::value + && !std::is_convertible< optional && , T>::value + && !std::is_convertible< optional const & , T>::value + && !std::is_convertible< optional const &&, T>::value + && !std::is_assignable< T&, optional & >::value + && !std::is_assignable< T&, optional && >::value + && !std::is_assignable< T&, optional const & >::value + && !std::is_assignable< T&, optional const && >::value + ) + operator=( optional && other ) + { + return *this = optional( std::move( other ) ); + } + + // 7 (C++11) - emplace + template< typename... Args + optional_REQUIRES_T( + std::is_constructible::value + ) + > + T& emplace( Args&&... args ) + { + *this = nullopt; + contained.emplace( std::forward(args)... ); + has_value_ = true; + return contained.value(); + } + + // 8 (C++11) - emplace, initializer-list + template< typename U, typename... Args + optional_REQUIRES_T( + std::is_constructible&, Args&&...>::value + ) + > + T& emplace( std::initializer_list il, Args&&... args ) + { + *this = nullopt; + contained.emplace( il, std::forward(args)... ); + has_value_ = true; + return contained.value(); + } + +#endif // optional_CPP11_OR_GREATER + + // x.x.3.4, swap + + void swap( optional & other ) +#if optional_CPP11_OR_GREATER + noexcept( + std::is_nothrow_move_constructible::value + && std17::is_nothrow_swappable::value + ) +#endif + { + using std::swap; + if ( (has_value() == true ) && (other.has_value() == true ) ) { swap( **this, *other ); } + else if ( (has_value() == false) && (other.has_value() == true ) ) { initialize( std11::move(*other) ); other.reset(); } + else if ( (has_value() == true ) && (other.has_value() == false) ) { other.initialize( std11::move(**this) ); reset(); } + } + + // x.x.3.5, observers + + optional_constexpr value_type const * operator ->() const + { + return assert( has_value() ), + contained.value_ptr(); + } + + optional_constexpr14 value_type * operator ->() + { + return assert( has_value() ), + contained.value_ptr(); + } + + optional_constexpr value_type const & operator *() const optional_ref_qual + { + return assert( has_value() ), + contained.value(); + } + + optional_constexpr14 value_type & operator *() optional_ref_qual + { + return assert( has_value() ), + contained.value(); + } + +#if optional_HAVE( REF_QUALIFIER ) + + optional_constexpr value_type const && operator *() const optional_refref_qual + { + return std::move( **this ); + } + + optional_constexpr14 value_type && operator *() optional_refref_qual + { + return std::move( **this ); + } + +#endif + +#if optional_CPP11_OR_GREATER + optional_constexpr explicit operator bool() const optional_noexcept + { + return has_value(); + } +#else + optional_constexpr operator safe_bool() const optional_noexcept + { + return has_value() ? &optional::this_type_does_not_support_comparisons : 0; + } +#endif + + // NOLINTNEXTLINE( modernize-use-nodiscard ) + /*optional_nodiscard*/ optional_constexpr bool has_value() const optional_noexcept + { + return has_value_; + } + + // NOLINTNEXTLINE( modernize-use-nodiscard ) + /*optional_nodiscard*/ optional_constexpr14 value_type const & value() const optional_ref_qual + { +#if optional_CONFIG_NO_EXCEPTIONS + assert( has_value() ); +#else + if ( ! has_value() ) + { + throw bad_optional_access(); + } +#endif + return contained.value(); + } + + optional_constexpr14 value_type & value() optional_ref_qual + { +#if optional_CONFIG_NO_EXCEPTIONS + assert( has_value() ); +#else + if ( ! has_value() ) + { + throw bad_optional_access(); + } +#endif + return contained.value(); + } + +#if optional_HAVE( REF_QUALIFIER ) && ( !optional_COMPILER_GNUC_VERSION || optional_COMPILER_GNUC_VERSION >= 490 ) + + // NOLINTNEXTLINE( modernize-use-nodiscard ) + /*optional_nodiscard*/ optional_constexpr value_type const && value() const optional_refref_qual + { + return std::move( value() ); + } + + optional_constexpr14 value_type && value() optional_refref_qual + { + return std::move( value() ); + } + +#endif + +#if optional_CPP11_OR_GREATER + + template< typename U > + optional_constexpr value_type value_or( U && v ) const optional_ref_qual + { + return has_value() ? contained.value() : static_cast(std::forward( v ) ); + } + + template< typename U > + optional_constexpr14 value_type value_or( U && v ) optional_refref_qual + { + return has_value() ? std::move( contained.value() ) : static_cast(std::forward( v ) ); + } + +#else + + template< typename U > + optional_constexpr value_type value_or( U const & v ) const + { + return has_value() ? contained.value() : static_cast( v ); + } + +#endif // optional_CPP11_OR_GREATER + + // x.x.3.6, modifiers + + void reset() optional_noexcept + { + if ( has_value() ) + { + contained.destruct_value(); + } + + has_value_ = false; + } + +private: + void this_type_does_not_support_comparisons() const {} + + template< typename V > + void initialize( V const & value ) + { + assert( ! has_value() ); + contained.construct_value( value ); + has_value_ = true; + } + +#if optional_CPP11_OR_GREATER + template< typename V > + void initialize( V && value ) + { + assert( ! has_value() ); + contained.construct_value( std::move( value ) ); + has_value_ = true; + } + +#endif + +private: + bool has_value_; + detail::storage_t< value_type > contained; + +}; + +// Relational operators + +template< typename T, typename U > +inline optional_constexpr bool operator==( optional const & x, optional const & y ) +{ + return bool(x) != bool(y) ? false : !bool( x ) ? true : *x == *y; +} + +template< typename T, typename U > +inline optional_constexpr bool operator!=( optional const & x, optional const & y ) +{ + return !(x == y); +} + +template< typename T, typename U > +inline optional_constexpr bool operator<( optional const & x, optional const & y ) +{ + return (!y) ? false : (!x) ? true : *x < *y; +} + +template< typename T, typename U > +inline optional_constexpr bool operator>( optional const & x, optional const & y ) +{ + return (y < x); +} + +template< typename T, typename U > +inline optional_constexpr bool operator<=( optional const & x, optional const & y ) +{ + return !(y < x); +} + +template< typename T, typename U > +inline optional_constexpr bool operator>=( optional const & x, optional const & y ) +{ + return !(x < y); +} + +// Comparison with nullopt + +template< typename T > +inline optional_constexpr bool operator==( optional const & x, nullopt_t /*unused*/ ) optional_noexcept +{ + return (!x); +} + +template< typename T > +inline optional_constexpr bool operator==( nullopt_t /*unused*/, optional const & x ) optional_noexcept +{ + return (!x); +} + +template< typename T > +inline optional_constexpr bool operator!=( optional const & x, nullopt_t /*unused*/ ) optional_noexcept +{ + return bool(x); +} + +template< typename T > +inline optional_constexpr bool operator!=( nullopt_t /*unused*/, optional const & x ) optional_noexcept +{ + return bool(x); +} + +template< typename T > +inline optional_constexpr bool operator<( optional const & /*unused*/, nullopt_t /*unused*/ ) optional_noexcept +{ + return false; +} + +template< typename T > +inline optional_constexpr bool operator<( nullopt_t /*unused*/, optional const & x ) optional_noexcept +{ + return bool(x); +} + +template< typename T > +inline optional_constexpr bool operator<=( optional const & x, nullopt_t /*unused*/ ) optional_noexcept +{ + return (!x); +} + +template< typename T > +inline optional_constexpr bool operator<=( nullopt_t /*unused*/, optional const & /*unused*/ ) optional_noexcept +{ + return true; +} + +template< typename T > +inline optional_constexpr bool operator>( optional const & x, nullopt_t /*unused*/ ) optional_noexcept +{ + return bool(x); +} + +template< typename T > +inline optional_constexpr bool operator>( nullopt_t /*unused*/, optional const & /*unused*/ ) optional_noexcept +{ + return false; +} + +template< typename T > +inline optional_constexpr bool operator>=( optional const & /*unused*/, nullopt_t /*unused*/ ) optional_noexcept +{ + return true; +} + +template< typename T > +inline optional_constexpr bool operator>=( nullopt_t /*unused*/, optional const & x ) optional_noexcept +{ + return (!x); +} + +// Comparison with T + +template< typename T, typename U > +inline optional_constexpr bool operator==( optional const & x, U const & v ) +{ + return bool(x) ? *x == v : false; +} + +template< typename T, typename U > +inline optional_constexpr bool operator==( U const & v, optional const & x ) +{ + return bool(x) ? v == *x : false; +} + +template< typename T, typename U > +inline optional_constexpr bool operator!=( optional const & x, U const & v ) +{ + return bool(x) ? *x != v : true; +} + +template< typename T, typename U > +inline optional_constexpr bool operator!=( U const & v, optional const & x ) +{ + return bool(x) ? v != *x : true; +} + +template< typename T, typename U > +inline optional_constexpr bool operator<( optional const & x, U const & v ) +{ + return bool(x) ? *x < v : true; +} + +template< typename T, typename U > +inline optional_constexpr bool operator<( U const & v, optional const & x ) +{ + return bool(x) ? v < *x : false; +} + +template< typename T, typename U > +inline optional_constexpr bool operator<=( optional const & x, U const & v ) +{ + return bool(x) ? *x <= v : true; +} + +template< typename T, typename U > +inline optional_constexpr bool operator<=( U const & v, optional const & x ) +{ + return bool(x) ? v <= *x : false; +} + +template< typename T, typename U > +inline optional_constexpr bool operator>( optional const & x, U const & v ) +{ + return bool(x) ? *x > v : false; +} + +template< typename T, typename U > +inline optional_constexpr bool operator>( U const & v, optional const & x ) +{ + return bool(x) ? v > *x : true; +} + +template< typename T, typename U > +inline optional_constexpr bool operator>=( optional const & x, U const & v ) +{ + return bool(x) ? *x >= v : false; +} + +template< typename T, typename U > +inline optional_constexpr bool operator>=( U const & v, optional const & x ) +{ + return bool(x) ? v >= *x : true; +} + +// Specialized algorithms + +template< typename T +#if optional_CPP11_OR_GREATER + optional_REQUIRES_T( + std::is_move_constructible::value + && std17::is_swappable::value ) +#endif +> +void swap( optional & x, optional & y ) +#if optional_CPP11_OR_GREATER + noexcept( noexcept( x.swap(y) ) ) +#endif +{ + x.swap( y ); +} + +#if optional_CPP11_OR_GREATER + +template< typename T > +optional_constexpr optional< typename std::decay::type > make_optional( T && value ) +{ + return optional< typename std::decay::type >( std::forward( value ) ); +} + +template< typename T, typename...Args > +optional_constexpr optional make_optional( Args&&... args ) +{ + return optional( nonstd_lite_in_place(T), std::forward(args)...); +} + +template< typename T, typename U, typename... Args > +optional_constexpr optional make_optional( std::initializer_list il, Args&&... args ) +{ + return optional( nonstd_lite_in_place(T), il, std::forward(args)...); +} + +#else + +template< typename T > +optional make_optional( T const & value ) +{ + return optional( value ); +} + +#endif // optional_CPP11_OR_GREATER + +} // namespace optional_lite + +using optional_lite::optional; +using optional_lite::nullopt_t; +using optional_lite::nullopt; + +#if ! optional_CONFIG_NO_EXCEPTIONS +using optional_lite::bad_optional_access; +#endif + +using optional_lite::make_optional; + +} // namespace nonstd + +#if optional_CPP11_OR_GREATER + +// specialize the std::hash algorithm: + +namespace std { + +template< class T > +struct hash< nonstd::optional > +{ +public: + std::size_t operator()( nonstd::optional const & v ) const optional_noexcept + { + return bool( v ) ? std::hash{}( *v ) : 0; + } +}; + +} //namespace std + +#endif // optional_CPP11_OR_GREATER + +#if defined(__clang__) +# pragma clang diagnostic pop +#elif defined(__GNUC__) +# pragma GCC diagnostic pop +#elif defined(_MSC_VER ) +# pragma warning( pop ) +#endif + +#endif // optional_USES_STD_OPTIONAL + +#endif // NONSTD_OPTIONAL_LITE_HPP diff --git a/src/num.cpp b/src/num.cpp index 4483ad39..67ad43b7 100644 --- a/src/num.cpp +++ b/src/num.cpp @@ -14,11 +14,19 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "ef.hpp" + +#include + #include +#include #include #include -#include +#define KB (1024UL) +#define MB (KB * 1024UL) +#define GB (MB * 1024UL) +#define TB (GB * 1024UL) namespace num { @@ -98,3 +106,27 @@ namespace num return 0; } } + + namespace num +{ + std::string + humanize(const uint64_t bytes_) + { + char buf[64]; + + if(bytes_ < KB) + sprintf(buf,"%lu",bytes_); + ef(((bytes_ / TB) * TB) == bytes_) + sprintf(buf,"%luT",bytes_ / TB); + ef(((bytes_ / GB) * GB) == bytes_) + sprintf(buf,"%luG",bytes_ / GB); + ef(((bytes_ / MB) * MB) == bytes_) + sprintf(buf,"%luM",bytes_ / MB); + ef(((bytes_ / KB) * KB) == bytes_) + sprintf(buf,"%luK",bytes_ / KB); + else + sprintf(buf,"%lu",bytes_); + + return std::string(buf); + } +} diff --git a/src/num.hpp b/src/num.hpp index 2dc3f811..40ba30c2 100644 --- a/src/num.hpp +++ b/src/num.hpp @@ -26,3 +26,8 @@ namespace num int to_double(const std::string &str, double *value); int to_time_t(const std::string &str, time_t *value); } + +namespace num +{ + std::string humanize(const uint64_t bytes); +} diff --git a/src/option_parser.cpp b/src/option_parser.cpp index 8e308630..6878dcd4 100644 --- a/src/option_parser.cpp +++ b/src/option_parser.cpp @@ -419,7 +419,7 @@ option_processor(void *data_, return process_opt(data,arg_); case FUSE_OPT_KEY_NONOPT: - if(data->config->branches.empty()) + if(data->config->branches.vec.empty()) return process_branches(data,arg_); else return process_mount(data,arg_); diff --git a/src/policy.hpp b/src/policy.hpp index 1b90c3db..1663e618 100644 --- a/src/policy.hpp +++ b/src/policy.hpp @@ -66,7 +66,7 @@ public: typedef const uint64_t cuint64_t; typedef const strvec cstrvec; - typedef int (*Ptr)(Category,const Branches &,const char *,cuint64_t,strvec *); + typedef int (*Ptr)(Category,const Branches&,const char*,strvec *); template class Base @@ -81,26 +81,26 @@ public: {} int - operator()(const Branches &b,const char *c,cuint64_t d,strvec *e) + operator()(const Branches &a,const char *b,strvec *c) { - return func(T,b,c,d,e); + return func(T,a,b,c); } int - operator()(const Branches &b,const string &c,cuint64_t d,strvec *e) + operator()(const Branches &a,const string &b,strvec *c) { - return func(T,b,c.c_str(),d,e); + return func(T,a,b.c_str(),c); } int - operator()(const Branches &b,const char *c,cuint64_t d,string *e) + operator()(const Branches &a,const char *b,string *c) { int rv; strvec v; - rv = func(T,b,c,d,&v); + rv = func(T,a,b,&v); if(!v.empty()) - *e = v[0]; + *c = v[0]; return rv; } @@ -113,27 +113,27 @@ public: typedef Base Create; typedef Base Search; - static int invalid(Category,const Branches&,const char *,cuint64_t,strvec*); - static int all(Category,const Branches&,const char*,cuint64_t,strvec*); - static int epall(Category,const Branches&,const char*,cuint64_t,strvec*); - static int epff(Category,const Branches&,const char *,cuint64_t,strvec*); - static int eplfs(Category,const Branches&,const char *,cuint64_t,strvec*); - static int eplus(Category,const Branches&,const char *,cuint64_t,strvec*); - static int epmfs(Category,const Branches&,const char *,cuint64_t,strvec*); - static int eppfrd(Category,const Branches&,const char *,cuint64_t,strvec*); - static int eprand(Category,const Branches&,const char *,cuint64_t,strvec*); - static int erofs(Category,const Branches&,const char *,cuint64_t,strvec*); - static int ff(Category,const Branches&,const char *,cuint64_t,strvec*); - static int lfs(Category,const Branches&,const char *,cuint64_t,strvec*); - static int lus(Category,const Branches&,const char *,cuint64_t,strvec*); - static int mfs(Category,const Branches&,const char *,cuint64_t,strvec*); - static int msplfs(Category,const Branches&,const char *,cuint64_t,strvec*); - static int msplus(Category,const Branches&,const char *,cuint64_t,strvec*); - static int mspmfs(Category,const Branches&,const char *,cuint64_t,strvec*); - static int msppfrd(Category,const Branches&,const char *,cuint64_t,strvec*); - static int newest(Category,const Branches&,const char *,cuint64_t,strvec*); - static int pfrd(Category,const Branches&,const char *,cuint64_t,strvec*); - static int rand(Category,const Branches&,const char *,cuint64_t,strvec*); + static int invalid(Category,const Branches&,const char *,strvec*); + static int all(Category,const Branches&,const char*,strvec*); + static int epall(Category,const Branches&,const char*,strvec*); + static int epff(Category,const Branches&,const char *,strvec*); + static int eplfs(Category,const Branches&,const char *,strvec*); + static int eplus(Category,const Branches&,const char *,strvec*); + static int epmfs(Category,const Branches&,const char *,strvec*); + static int eppfrd(Category,const Branches&,const char *,strvec*); + static int eprand(Category,const Branches&,const char *,strvec*); + static int erofs(Category,const Branches&,const char *,strvec*); + static int ff(Category,const Branches&,const char *,strvec*); + static int lfs(Category,const Branches&,const char *,strvec*); + static int lus(Category,const Branches&,const char *,strvec*); + static int mfs(Category,const Branches&,const char *,strvec*); + static int msplfs(Category,const Branches&,const char *,strvec*); + static int msplus(Category,const Branches&,const char *,strvec*); + static int mspmfs(Category,const Branches&,const char *,strvec*); + static int msppfrd(Category,const Branches&,const char *,strvec*); + static int newest(Category,const Branches&,const char *,strvec*); + static int pfrd(Category,const Branches&,const char *,strvec*); + static int rand(Category,const Branches&,const char *,strvec*); }; private: diff --git a/src/policy_all.cpp b/src/policy_all.cpp index b417ebfd..92d86bfc 100644 --- a/src/policy_all.cpp +++ b/src/policy_all.cpp @@ -32,12 +32,9 @@ namespace all { static int - create(const Branches &branches_, - const uint64_t minfreespace_, - vector *paths_) + create(const BranchVec &branches_, + vector *paths_) { - rwlock::ReadGuard guard(&branches_.lock); - int rv; int error; fs::info_t info; @@ -55,7 +52,7 @@ namespace all error_and_continue(error,ENOENT); if(info.readonly) error_and_continue(error,EROFS); - if(info.spaceavail < minfreespace_) + if(info.spaceavail < branch->minfreespace()) error_and_continue(error,ENOSPC); paths_->push_back(branch->path); @@ -66,17 +63,26 @@ namespace all return 0; } + + static + int + create(const Branches &branches_, + vector *paths_) + { + rwlock::ReadGuard guard(branches_.lock); + + return all::create(branches_.vec,paths_); + } } int Policy::Func::all(const Category type_, const Branches &branches_, const char *fusepath_, - const uint64_t minfreespace_, vector *paths_) { if(type_ == Category::CREATE) - return all::create(branches_,minfreespace_,paths_); + return all::create(branches_,paths_); - return Policy::Func::epall(type_,branches_,fusepath_,minfreespace_,paths_); + return Policy::Func::epall(type_,branches_,fusepath_,paths_); } diff --git a/src/policy_cache.cpp b/src/policy_cache.cpp index 9bcd7d85..08645eab 100644 --- a/src/policy_cache.cpp +++ b/src/policy_cache.cpp @@ -94,7 +94,6 @@ int PolicyCache::operator()(Policy::Func::Search &func_, const Branches &branches_, const char *fusepath_, - const uint64_t minfreespace_, std::string *branch_) { int rv; @@ -103,7 +102,7 @@ PolicyCache::operator()(Policy::Func::Search &func_, string branch; if(timeout == 0) - return func_(branches_,fusepath_,minfreespace_,branch_); + return func_(branches_,fusepath_,branch_); now = l::get_time(); @@ -113,7 +112,7 @@ PolicyCache::operator()(Policy::Func::Search &func_, if((now - v->time) >= timeout) { pthread_mutex_unlock(&_lock); - rv = func_(branches_,fusepath_,minfreespace_,&branch); + rv = func_(branches_,fusepath_,&branch); if(rv == -1) return -1; diff --git a/src/policy_cache.hpp b/src/policy_cache.hpp index bcf66b98..dc7218d9 100644 --- a/src/policy_cache.hpp +++ b/src/policy_cache.hpp @@ -49,7 +49,6 @@ public: int operator()(Policy::Func::Search &func, const Branches &branches, const char *fusepath, - const uint64_t minfreespace, std::string *branch); public: diff --git a/src/policy_epall.cpp b/src/policy_epall.cpp index 353395f8..47c1992e 100644 --- a/src/policy_epall.cpp +++ b/src/policy_epall.cpp @@ -33,13 +33,10 @@ namespace epall { static int - create(const Branches &branches_, - const char *fusepath_, - const uint64_t minfreespace_, - vector *paths_) + create(const BranchVec &branches_, + const char *fusepath_, + vector *paths_) { - rwlock::ReadGuard guard(&branches_.lock); - int rv; int error; fs::info_t info; @@ -50,16 +47,16 @@ namespace epall { branch = &branches_[i]; - if(!fs::exists(branch->path,fusepath_)) - error_and_continue(error,ENOENT); 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 < minfreespace_) + if(info.spaceavail < branch->minfreespace()) error_and_continue(error,ENOSPC); paths_->push_back(branch->path); @@ -73,12 +70,21 @@ namespace epall static int - action(const Branches &branches_, + create(const Branches &branches_, const char *fusepath_, vector *paths_) { - rwlock::ReadGuard guard(&branches_.lock); + rwlock::ReadGuard guard(branches_.lock); + + return epall::create(branches_.vec,fusepath_,paths_); + } + static + int + action(const BranchVec &branches_, + const char *fusepath_, + vector *paths_) + { int rv; int error; bool readonly; @@ -89,10 +95,10 @@ namespace epall { branch = &branches_[i]; - if(!fs::exists(branch->path,fusepath_)) - error_and_continue(error,ENOENT); 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); @@ -110,12 +116,21 @@ namespace epall static int - search(const Branches &branches_, + action(const Branches &branches_, const char *fusepath_, vector *paths_) { - rwlock::ReadGuard guard(&branches_.lock); + rwlock::ReadGuard guard(branches_.lock); + + return epall::action(branches_.vec,fusepath_,paths_); + } + static + int + search(const BranchVec &branches_, + const char *fusepath_, + vector *paths_) + { const Branch *branch; for(size_t i = 0, ei = branches_.size(); i != ei; i++) @@ -133,19 +148,29 @@ namespace epall return 0; } + + static + int + search(const Branches &branches_, + const char *fusepath_, + vector *paths_) + { + rwlock::ReadGuard guard(branches_.lock); + + return epall::search(branches_.vec,fusepath_,paths_); + } } int Policy::Func::epall(const Category type_, const Branches &branches_, const char *fusepath_, - const uint64_t minfreespace_, vector *paths_) { switch(type_) { case Category::CREATE: - return epall::create(branches_,fusepath_,minfreespace_,paths_); + return epall::create(branches_,fusepath_,paths_); case Category::ACTION: return epall::action(branches_,fusepath_,paths_); case Category::SEARCH: diff --git a/src/policy_epff.cpp b/src/policy_epff.cpp index ea360f69..ac519c96 100644 --- a/src/policy_epff.cpp +++ b/src/policy_epff.cpp @@ -33,13 +33,10 @@ namespace epff { static int - create(const Branches &branches_, - const char *fusepath_, - const uint64_t minfreespace_, - vector *paths_) + create(const BranchVec &branches_, + const char *fusepath_, + vector *paths_) { - rwlock::ReadGuard guard(&branches_.lock); - int rv; int error; fs::info_t info; @@ -50,16 +47,16 @@ namespace epff { branch = &branches_[i]; - if(!fs::exists(branch->path,fusepath_)) - error_and_continue(error,ENOENT); 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 < minfreespace_) + if(info.spaceavail < branch->minfreespace()) error_and_continue(error,ENOSPC); paths_->push_back(branch->path); @@ -72,12 +69,21 @@ namespace epff static int - action(const Branches &branches_, + create(const Branches &branches_, const char *fusepath_, vector *paths_) { - rwlock::ReadGuard guard(&branches_.lock); + rwlock::ReadGuard guard(branches_.lock); + + return epff::create(branches_.vec,fusepath_,paths_); + } + static + int + action(const BranchVec &branches_, + const char *fusepath_, + vector *paths_) + { int rv; int error; bool readonly; @@ -88,10 +94,10 @@ namespace epff { branch = &branches_[i]; - if(!fs::exists(branch->path,fusepath_)) - error_and_continue(error,ENOENT); 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); @@ -108,12 +114,21 @@ namespace epff static int - search(const Branches &branches_, + action(const Branches &branches_, const char *fusepath_, vector *paths_) { - rwlock::ReadGuard guard(&branches_.lock); + rwlock::ReadGuard guard(branches_.lock); + + return epff::action(branches_.vec,fusepath_,paths_); + } + static + int + search(const BranchVec &branches_, + const char *fusepath_, + vector *paths_) + { const Branch *branch; for(size_t i = 0, ei = branches_.size(); i != ei; i++) @@ -130,19 +145,29 @@ namespace epff return (errno=ENOENT,-1); } + + static + int + search(const Branches &branches_, + const char *fusepath_, + vector *paths_) + { + rwlock::ReadGuard guard(branches_.lock); + + return epff::search(branches_.vec,fusepath_,paths_); + } } int Policy::Func::epff(const Category type_, const Branches &branches_, const char *fusepath_, - const uint64_t minfreespace_, vector *paths_) { switch(type_) { case Category::CREATE: - return epff::create(branches_,fusepath_,minfreespace_,paths_); + return epff::create(branches_,fusepath_,paths_); case Category::ACTION: return epff::action(branches_,fusepath_,paths_); case Category::SEARCH: diff --git a/src/policy_eplfs.cpp b/src/policy_eplfs.cpp index f44581bb..26164fdd 100644 --- a/src/policy_eplfs.cpp +++ b/src/policy_eplfs.cpp @@ -34,79 +34,85 @@ namespace eplfs { static int - create(const Branches &branches_, - const char *fusepath_, - const uint64_t minfreespace_, - vector *paths_) + create(const BranchVec &branches_, + const char *fusepath_, + vector *paths_) { - rwlock::ReadGuard guard(&branches_.lock); - int rv; int error; uint64_t eplfs; fs::info_t info; const Branch *branch; - const string *eplfsbasepath; + const string *basepath; error = ENOENT; eplfs = std::numeric_limits::max(); - eplfsbasepath = NULL; + basepath = NULL; for(size_t i = 0, ei = branches_.size(); i != ei; i++) { branch = &branches_[i]; - if(!fs::exists(branch->path,fusepath_)) - error_and_continue(error,ENOENT); 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 < minfreespace_) + if(info.spaceavail < branch->minfreespace()) error_and_continue(error,ENOSPC); if(info.spaceavail > eplfs) continue; eplfs = info.spaceavail; - eplfsbasepath = &branch->path; + basepath = &branch->path; } - if(eplfsbasepath == NULL) + if(basepath == NULL) return (errno=error,-1); - paths_->push_back(*eplfsbasepath); + paths_->push_back(*basepath); return 0; } static int - action(const Branches &branches_, + create(const Branches &branches_, const char *fusepath_, vector *paths_) { - rwlock::ReadGuard guard(&branches_.lock); + rwlock::ReadGuard guard(branches_.lock); + + return eplfs::create(branches_.vec,fusepath_,paths_); + } + static + int + action(const BranchVec &branches_, + const char *fusepath_, + vector *paths_) + { int rv; int error; uint64_t eplfs; fs::info_t info; const Branch *branch; - const string *eplfsbasepath; + const string *basepath; error = ENOENT; eplfs = std::numeric_limits::max(); - eplfsbasepath = NULL; + basepath = NULL; for(size_t i = 0, ei = branches_.size(); i != ei; i++) { branch = &branches_[i]; - if(!fs::exists(branch->path,fusepath_)) - error_and_continue(error,ENOENT); 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); @@ -116,33 +122,42 @@ namespace eplfs continue; eplfs = info.spaceavail; - eplfsbasepath = &branch->path; + basepath = &branch->path; } - if(eplfsbasepath == NULL) + if(basepath == NULL) return (errno=error,-1); - paths_->push_back(*eplfsbasepath); + paths_->push_back(*basepath); return 0; } static int - search(const Branches &branches_, - const char *fusepath_, - vector *paths_) + action(const Branches &branches_, + const char *fusepath_, + vector *paths_) { - rwlock::ReadGuard guard(&branches_.lock); + rwlock::ReadGuard guard(branches_.lock); + return eplfs::action(branches_.vec,fusepath_,paths_); + } + + static + int + search(const BranchVec &branches_, + const char *fusepath_, + vector *paths_) + { int rv; uint64_t eplfs; uint64_t spaceavail; const Branch *branch; - const string *eplfsbasepath; + const string *basepath; eplfs = std::numeric_limits::max(); - eplfsbasepath = NULL; + basepath = NULL; for(size_t i = 0, ei = branches_.size(); i != ei; i++) { branch = &branches_[i]; @@ -156,29 +171,39 @@ namespace eplfs continue; eplfs = spaceavail; - eplfsbasepath = &branch->path; + basepath = &branch->path; } - if(eplfsbasepath == NULL) + if(basepath == NULL) return (errno=ENOENT,-1); - paths_->push_back(*eplfsbasepath); + paths_->push_back(*basepath); return 0; } + + static + int + search(const Branches &branches_, + const char *fusepath_, + vector *paths_) + { + rwlock::ReadGuard guard(branches_.lock); + + return eplfs::search(branches_.vec,fusepath_,paths_); + } } int Policy::Func::eplfs(const Category type_, const Branches &branches_, const char *fusepath_, - const uint64_t minfreespace_, vector *paths_) { switch(type_) { case Category::CREATE: - return eplfs::create(branches_,fusepath_,minfreespace_,paths_); + return eplfs::create(branches_,fusepath_,paths_); case Category::ACTION: return eplfs::action(branches_,fusepath_,paths_); case Category::SEARCH: diff --git a/src/policy_eplus.cpp b/src/policy_eplus.cpp index 65a4ca3a..b8c79ab1 100644 --- a/src/policy_eplus.cpp +++ b/src/policy_eplus.cpp @@ -34,79 +34,85 @@ namespace eplus { static int - create(const Branches &branches_, - const char *fusepath_, - const uint64_t minfreespace_, - vector *paths_) + create(const BranchVec &branches_, + const char *fusepath_, + vector *paths_) { - rwlock::ReadGuard guard(&branches_.lock); - int rv; int error; uint64_t eplus; fs::info_t info; const Branch *branch; - const string *eplusbasepath; + const string *basepath; error = ENOENT; eplus = std::numeric_limits::max(); - eplusbasepath = NULL; + basepath = NULL; for(size_t i = 0, ei = branches_.size(); i != ei; i++) { branch = &branches_[i]; - if(!fs::exists(branch->path,fusepath_)) - error_and_continue(error,ENOENT); 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 < minfreespace_) + if(info.spaceavail < branch->minfreespace()) error_and_continue(error,ENOSPC); if(info.spaceused >= eplus) continue; eplus = info.spaceused; - eplusbasepath = &branch->path; + basepath = &branch->path; } - if(eplusbasepath == NULL) + if(basepath == NULL) return (errno=error,-1); - paths_->push_back(*eplusbasepath); + paths_->push_back(*basepath); return 0; } static int - action(const Branches &branches_, + create(const Branches &branches_, const char *fusepath_, vector *paths_) { - rwlock::ReadGuard guard(&branches_.lock); + rwlock::ReadGuard guard(branches_.lock); + + return eplus::create(branches_.vec,fusepath_,paths_); + } + static + int + action(const BranchVec &branches_, + const char *fusepath_, + vector *paths_) + { int rv; int error; uint64_t eplus; fs::info_t info; const Branch *branch; - const string *eplusbasepath; + const string *basepath; error = ENOENT; eplus = std::numeric_limits::max(); - eplusbasepath = NULL; + basepath = NULL; for(size_t i = 0, ei = branches_.size(); i != ei; i++) { branch = &branches_[i]; - if(!fs::exists(branch->path,fusepath_)) - error_and_continue(error,ENOENT); 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); @@ -116,33 +122,42 @@ namespace eplus continue; eplus = info.spaceused; - eplusbasepath = &branch->path; + basepath = &branch->path; } - if(eplusbasepath == NULL) + if(basepath == NULL) return (errno=error,-1); - paths_->push_back(*eplusbasepath); + paths_->push_back(*basepath); return 0; } static int - search(const Branches &branches_, + action(const Branches &branches_, const char *fusepath_, vector *paths_) { - rwlock::ReadGuard guard(&branches_.lock); + rwlock::ReadGuard guard(branches_.lock); + + return eplus::action(branches_.vec,fusepath_,paths_); + } + static + int + search(const BranchVec &branches_, + const char *fusepath_, + vector *paths_) + { int rv; uint64_t eplus; uint64_t spaceused; const Branch *branch; - const string *eplusbasepath; + const string *basepath; eplus = 0; - eplusbasepath = NULL; + basepath = NULL; for(size_t i = 0, ei = branches_.size(); i != ei; i++) { branch = &branches_[i]; @@ -156,29 +171,39 @@ namespace eplus continue; eplus = spaceused; - eplusbasepath = &branch->path; + basepath = &branch->path; } - if(eplusbasepath == NULL) + if(basepath == NULL) return (errno=ENOENT,-1); - paths_->push_back(*eplusbasepath); + paths_->push_back(*basepath); return 0; } + + static + int + search(const Branches &branches_, + const char *fusepath_, + vector *paths_) + { + rwlock::ReadGuard guard(branches_.lock); + + return eplus::search(branches_.vec,fusepath_,paths_); + } } int Policy::Func::eplus(const Category type_, const Branches &branches_, const char *fusepath_, - const uint64_t minfreespace_, vector *paths_) { switch(type_) { case Category::CREATE: - return eplus::create(branches_,fusepath_,minfreespace_,paths_); + return eplus::create(branches_,fusepath_,paths_); case Category::ACTION: return eplus::action(branches_,fusepath_,paths_); case Category::SEARCH: diff --git a/src/policy_epmfs.cpp b/src/policy_epmfs.cpp index b77604fa..b4e24919 100644 --- a/src/policy_epmfs.cpp +++ b/src/policy_epmfs.cpp @@ -34,79 +34,85 @@ namespace epmfs { static int - create(const Branches &branches_, - const char *fusepath_, - const uint64_t minfreespace_, - vector *paths_) + create(const BranchVec &branches_, + const char *fusepath_, + vector *paths_) { - rwlock::ReadGuard guard(&branches_.lock); - int rv; int error; uint64_t epmfs; fs::info_t info; const Branch *branch; - const string *epmfsbasepath; + const string *basepath; error = ENOENT; epmfs = std::numeric_limits::min(); - epmfsbasepath = NULL; + basepath = NULL; for(size_t i = 0, ei = branches_.size(); i != ei; i++) { branch = &branches_[i]; - if(!fs::exists(branch->path,fusepath_)) - error_and_continue(error,ENOENT); 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 < minfreespace_) + if(info.spaceavail < branch->minfreespace()) error_and_continue(error,ENOSPC); if(info.spaceavail < epmfs) continue; epmfs = info.spaceavail; - epmfsbasepath = &branch->path; + basepath = &branch->path; } - if(epmfsbasepath == NULL) + if(basepath == NULL) return (errno=error,-1); - paths_->push_back(*epmfsbasepath); + paths_->push_back(*basepath); return 0; } static int - action(const Branches &branches_, + create(const Branches &branches_, const char *fusepath_, vector *paths_) { - rwlock::ReadGuard guard(&branches_.lock); + rwlock::ReadGuard guard(branches_.lock); + + return epmfs::create(branches_.vec,fusepath_,paths_); + } + static + int + action(const BranchVec &branches_, + const char *fusepath_, + vector *paths_) + { int rv; int error; uint64_t epmfs; fs::info_t info; const Branch *branch; - const string *epmfsbasepath; + const string *basepath; error = ENOENT; epmfs = std::numeric_limits::min(); - epmfsbasepath = NULL; + basepath = NULL; for(size_t i = 0, ei = branches_.size(); i != ei; i++) { branch = &branches_[i]; - if(!fs::exists(branch->path,fusepath_)) - error_and_continue(error,ENOENT); 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); @@ -116,33 +122,42 @@ namespace epmfs continue; epmfs = info.spaceavail; - epmfsbasepath = &branch->path; + basepath = &branch->path; } - if(epmfsbasepath == NULL) + if(basepath == NULL) return (errno=error,-1); - paths_->push_back(*epmfsbasepath); + paths_->push_back(*basepath); return 0; } static int - search(const Branches &branches_, + action(const Branches &branches_, const char *fusepath_, vector *paths_) { - rwlock::ReadGuard guard(&branches_.lock); + rwlock::ReadGuard guard(branches_.lock); + + return epmfs::action(branches_.vec,fusepath_,paths_); + } + static + int + search(const BranchVec &branches_, + const char *fusepath_, + vector *paths_) + { int rv; uint64_t epmfs; uint64_t spaceavail; const Branch *branch; - const string *epmfsbasepath; + const string *basepath; epmfs = 0; - epmfsbasepath = NULL; + basepath = NULL; for(size_t i = 0, ei = branches_.size(); i != ei; i++) { branch = &branches_[i]; @@ -156,29 +171,39 @@ namespace epmfs continue; epmfs = spaceavail; - epmfsbasepath = &branch->path; + basepath = &branch->path; } - if(epmfsbasepath == NULL) + if(basepath == NULL) return (errno=ENOENT,-1); - paths_->push_back(*epmfsbasepath); + paths_->push_back(*basepath); return 0; } + + static + int + search(const Branches &branches_, + const char *fusepath_, + vector *paths_) + { + rwlock::ReadGuard guard(branches_.lock); + + return epmfs::search(branches_.vec,fusepath_,paths_); + } } int Policy::Func::epmfs(const Category type_, const Branches &branches_, const char *fusepath_, - const uint64_t minfreespace_, vector *paths_) { switch(type_) { case Category::CREATE: - return epmfs::create(branches_,fusepath_,minfreespace_,paths_); + return epmfs::create(branches_,fusepath_,paths_); case Category::ACTION: return epmfs::action(branches_,fusepath_,paths_); case Category::SEARCH: diff --git a/src/policy_eppfrd.cpp b/src/policy_eppfrd.cpp index 72cb2e3f..2c38efc2 100644 --- a/src/policy_eppfrd.cpp +++ b/src/policy_eppfrd.cpp @@ -42,18 +42,16 @@ namespace eppfrd { static int - get_branchinfo_create(const Branches &branches_, - const char *fusepath_, - const uint64_t minfreespace_, - BranchInfoVec *branchinfo_, - uint64_t *sum_) + get_branchinfo_create(const BranchVec &branches_, + const char *fusepath_, + BranchInfoVec *branchinfo_, + uint64_t *sum_) { int rv; int error; BranchInfo bi; fs::info_t info; const Branch *branch; - rwlock::ReadGuard guard(&branches_.lock); *sum_ = 0; error = ENOENT; @@ -70,7 +68,7 @@ namespace eppfrd error_and_continue(error,ENOENT); if(info.readonly) error_and_continue(error,EROFS); - if(info.spaceavail < minfreespace_) + if(info.spaceavail < branch->minfreespace()) error_and_continue(error,ENOSPC); *sum_ += info.spaceavail; @@ -85,18 +83,30 @@ namespace eppfrd static int - get_branchinfo_action(const Branches &branches_, + get_branchinfo_create(const Branches &branches_, const char *fusepath_, - const uint64_t minfreespace_, BranchInfoVec *branchinfo_, uint64_t *sum_) + { + rwlock::ReadGuard guard(branches_.lock); + + branchinfo_->reserve(branches_.vec.size()); + + return eppfrd::get_branchinfo_create(branches_.vec,fusepath_,branchinfo_,sum_); + } + + static + int + get_branchinfo_action(const BranchVec &branches_, + const char *fusepath_, + BranchInfoVec *branchinfo_, + uint64_t *sum_) { int rv; int error; BranchInfo bi; fs::info_t info; const Branch *branch; - rwlock::ReadGuard guard(&branches_.lock); *sum_ = 0; error = ENOENT; @@ -126,17 +136,29 @@ namespace eppfrd static int - get_branchinfo_search(const Branches &branches_, + get_branchinfo_action(const Branches &branches_, const char *fusepath_, - const uint64_t minfreespace_, BranchInfoVec *branchinfo_, uint64_t *sum_) + { + rwlock::ReadGuard guard(branches_.lock); + + branchinfo_->reserve(branches_.vec.size()); + + return eppfrd::get_branchinfo_action(branches_.vec,fusepath_,branchinfo_,sum_); + } + + static + int + get_branchinfo_search(const BranchVec &branches_, + const char *fusepath_, + BranchInfoVec *branchinfo_, + uint64_t *sum_) { int rv; BranchInfo bi; uint64_t spaceavail; const Branch *branch; - rwlock::ReadGuard guard(&branches_.lock); *sum_ = 0; for(size_t i = 0, ei = branches_.size(); i < ei; i++) @@ -159,6 +181,20 @@ namespace eppfrd return ENOENT; } + static + int + get_branchinfo_search(const Branches &branches_, + const char *fusepath_, + BranchInfoVec *branchinfo_, + uint64_t *sum_) + { + rwlock::ReadGuard guard(branches_.lock); + + branchinfo_->reserve(branches_.vec.size()); + + return eppfrd::get_branchinfo_search(branches_.vec,fusepath_,branchinfo_,sum_); + } + static const string* @@ -187,7 +223,6 @@ namespace eppfrd int create(const Branches &branches_, const char *fusepath_, - const uint64_t minfreespace_, vector *paths_) { int error; @@ -195,8 +230,7 @@ namespace eppfrd const string *basepath; BranchInfoVec branchinfo; - branchinfo.reserve(branches_.size()); - error = eppfrd::get_branchinfo_create(branches_,fusepath_,minfreespace_,&branchinfo,&sum); + error = eppfrd::get_branchinfo_create(branches_,fusepath_,&branchinfo,&sum); basepath = eppfrd::get_branch(branchinfo,sum); if(basepath == NULL) return (errno=error,-1); @@ -210,7 +244,6 @@ namespace eppfrd int action(const Branches &branches_, const char *fusepath_, - const uint64_t minfreespace_, vector *paths_) { int error; @@ -218,8 +251,7 @@ namespace eppfrd const string *basepath; BranchInfoVec branchinfo; - branchinfo.reserve(branches_.size()); - error = eppfrd::get_branchinfo_action(branches_,fusepath_,minfreespace_,&branchinfo,&sum); + error = eppfrd::get_branchinfo_action(branches_,fusepath_,&branchinfo,&sum); basepath = eppfrd::get_branch(branchinfo,sum); if(basepath == NULL) return (errno=error,-1); @@ -233,7 +265,6 @@ namespace eppfrd int search(const Branches &branches_, const char *fusepath_, - const uint64_t minfreespace_, vector *paths_) { int error; @@ -241,8 +272,7 @@ namespace eppfrd const string *basepath; BranchInfoVec branchinfo; - branchinfo.reserve(branches_.size()); - error = eppfrd::get_branchinfo_search(branches_,fusepath_,minfreespace_,&branchinfo,&sum); + error = eppfrd::get_branchinfo_search(branches_,fusepath_,&branchinfo,&sum); basepath = eppfrd::get_branch(branchinfo,sum); if(basepath == NULL) return (errno=error,-1); @@ -257,17 +287,16 @@ int Policy::Func::eppfrd(const Category type_, const Branches &branches_, const char *fusepath_, - const uint64_t minfreespace_, vector *paths_) { switch(type_) { case Category::CREATE: - return eppfrd::create(branches_,fusepath_,minfreespace_,paths_); + return eppfrd::create(branches_,fusepath_,paths_); case Category::ACTION: - return eppfrd::action(branches_,fusepath_,minfreespace_,paths_); + return eppfrd::action(branches_,fusepath_,paths_); default: case Category::SEARCH: - return eppfrd::search(branches_,fusepath_,minfreespace_,paths_); + return eppfrd::search(branches_,fusepath_,paths_); } } diff --git a/src/policy_eprand.cpp b/src/policy_eprand.cpp index 099162f1..65dd9ffa 100644 --- a/src/policy_eprand.cpp +++ b/src/policy_eprand.cpp @@ -28,12 +28,11 @@ int Policy::Func::eprand(const Category type_, const Branches &branches_, const char *fusepath_, - const uint64_t minfreespace_, vector *paths_) { int rv; - rv = Policy::Func::epall(type_,branches_,fusepath_,minfreespace_,paths_); + rv = Policy::Func::epall(type_,branches_,fusepath_,paths_); if(rv == 0) { std::random_shuffle(paths_->begin(),paths_->end()); diff --git a/src/policy_erofs.cpp b/src/policy_erofs.cpp index aa85d219..c7ee6682 100644 --- a/src/policy_erofs.cpp +++ b/src/policy_erofs.cpp @@ -27,7 +27,6 @@ int Policy::Func::erofs(const Category type_, const Branches &branches_, const char *fusepath_, - const uint64_t minfreespace_, vector *paths) { return (errno=EROFS,-1); diff --git a/src/policy_ff.cpp b/src/policy_ff.cpp index ea772a35..72a8f1e2 100644 --- a/src/policy_ff.cpp +++ b/src/policy_ff.cpp @@ -32,12 +32,9 @@ namespace ff { static int - create(const Branches &branches_, - const uint64_t minfreespace_, - vector *paths_) + create(const BranchVec &branches_, + vector *paths_) { - rwlock::ReadGuard guard(&branches_.lock); - int rv; int error; fs::info_t info; @@ -55,7 +52,7 @@ namespace ff error_and_continue(error,ENOENT); if(info.readonly) error_and_continue(error,EROFS); - if(info.spaceavail < minfreespace_) + if(info.spaceavail < branch->minfreespace()) error_and_continue(error,ENOSPC); paths_->push_back(branch->path); @@ -65,17 +62,26 @@ namespace ff return (errno=error,-1); } + + static + int + create(const Branches &branches_, + vector *paths_) + { + rwlock::ReadGuard guard(branches_.lock); + + return ff::create(branches_.vec,paths_); + } } int Policy::Func::ff(const Category type_, const Branches &branches_, const char *fusepath_, - const uint64_t minfreespace_, vector *paths_) { if(type_ == Category::CREATE) - return ff::create(branches_,minfreespace_,paths_); + return ff::create(branches_,paths_); - return Policy::Func::epff(type_,branches_,fusepath_,minfreespace_,paths_); + return Policy::Func::epff(type_,branches_,fusepath_,paths_); } diff --git a/src/policy_invalid.cpp b/src/policy_invalid.cpp index 588e424d..caedc24f 100644 --- a/src/policy_invalid.cpp +++ b/src/policy_invalid.cpp @@ -27,7 +27,6 @@ int Policy::Func::invalid(const Category type_, const Branches &branches_, const char *fusepath_, - const uint64_t minfreespace_, vector *paths_) { return (errno=EINVAL,-1); diff --git a/src/policy_lfs.cpp b/src/policy_lfs.cpp index 45e096d1..05000c18 100644 --- a/src/policy_lfs.cpp +++ b/src/policy_lfs.cpp @@ -33,22 +33,19 @@ namespace lfs { static int - create(const Branches &branches_, - const uint64_t minfreespace_, - vector *paths_) + create(const BranchVec &branches_, + vector *paths_) { - rwlock::ReadGuard guard(&branches_.lock); - int rv; int error; uint64_t lfs; fs::info_t info; const Branch *branch; - const string *lfsbasepath; + const string *basepath; error = ENOENT; lfs = std::numeric_limits::max(); - lfsbasepath = NULL; + basepath = NULL; for(size_t i = 0, ei = branches_.size(); i != ei; i++) { branch = &branches_[i]; @@ -60,33 +57,42 @@ namespace lfs error_and_continue(error,ENOENT); if(info.readonly) error_and_continue(error,EROFS); - if(info.spaceavail < minfreespace_) + if(info.spaceavail < branch->minfreespace()) error_and_continue(error,ENOSPC); if(info.spaceavail > lfs) continue; lfs = info.spaceavail; - lfsbasepath = &branch->path; + basepath = &branch->path; } - if(lfsbasepath == NULL) + if(basepath == NULL) return (errno=error,-1); - paths_->push_back(*lfsbasepath); + paths_->push_back(*basepath); return 0; } + + static + int + create(const Branches &branches_, + vector *paths_) + { + rwlock::ReadGuard guard(branches_.lock); + + return lfs::create(branches_.vec,paths_); + } } int Policy::Func::lfs(const Category type_, const Branches &branches_, const char *fusepath_, - const uint64_t minfreespace_, vector *paths_) { if(type_ == Category::CREATE) - return lfs::create(branches_,minfreespace_,paths_); + return lfs::create(branches_,paths_); - return Policy::Func::eplfs(type_,branches_,fusepath_,minfreespace_,paths_); + return Policy::Func::eplfs(type_,branches_,fusepath_,paths_); } diff --git a/src/policy_lus.cpp b/src/policy_lus.cpp index 74cca0f1..3576afad 100644 --- a/src/policy_lus.cpp +++ b/src/policy_lus.cpp @@ -33,22 +33,19 @@ namespace lus { static int - create(const Branches &branches_, - const uint64_t minfreespace_, - vector *paths_) + create(const BranchVec &branches_, + vector *paths_) { - rwlock::ReadGuard guard(&branches_.lock); - int rv; int error; uint64_t lus; fs::info_t info; const Branch *branch; - const string *lusbasepath; + const string *basepath; error = ENOENT; lus = std::numeric_limits::max(); - lusbasepath = NULL; + basepath = NULL; for(size_t i = 0, ei = branches_.size(); i != ei; i++) { branch = &branches_[i]; @@ -60,33 +57,42 @@ namespace lus error_and_continue(error,ENOENT); if(info.readonly) error_and_continue(error,EROFS); - if(info.spaceavail < minfreespace_) + if(info.spaceavail < branch->minfreespace()) error_and_continue(error,ENOSPC); if(info.spaceused >= lus) continue; - lus = info.spaceused; - lusbasepath = &branch->path; + lus = info.spaceused; + basepath = &branch->path; } - if(lusbasepath == NULL) + if(basepath == NULL) return (errno=error,-1); - paths_->push_back(*lusbasepath); + paths_->push_back(*basepath); return 0; } + + static + int + create(const Branches &branches_, + vector *paths_) + { + rwlock::ReadGuard guard(branches_.lock); + + return lus::create(branches_.vec,paths_); + } } int Policy::Func::lus(const Category type_, const Branches &branches_, const char *fusepath_, - const uint64_t minfreespace_, vector *paths_) { if(type_ == Category::CREATE) - return lus::create(branches_,minfreespace_,paths_); + return lus::create(branches_,paths_); - return Policy::Func::eplus(type_,branches_,fusepath_,minfreespace_,paths_); + return Policy::Func::eplus(type_,branches_,fusepath_,paths_); } diff --git a/src/policy_mfs.cpp b/src/policy_mfs.cpp index d286cf1b..ed766d95 100644 --- a/src/policy_mfs.cpp +++ b/src/policy_mfs.cpp @@ -32,22 +32,19 @@ namespace mfs { static int - create(const Branches &branches_, - const uint64_t minfreespace_, - vector *paths_) + create(const BranchVec &branches_, + vector *paths_) { - rwlock::ReadGuard guard(&branches_.lock); - int rv; int error; uint64_t mfs; fs::info_t info; const Branch *branch; - const string *mfsbasepath; + const string *basepath; error = ENOENT; mfs = 0; - mfsbasepath = NULL; + basepath = NULL; for(size_t i = 0, ei = branches_.size(); i != ei; i++) { branch = &branches_[i]; @@ -59,33 +56,42 @@ namespace mfs error_and_continue(error,ENOENT); if(info.readonly) error_and_continue(error,EROFS); - if(info.spaceavail < minfreespace_) + if(info.spaceavail < branch->minfreespace()) error_and_continue(error,ENOSPC); if(info.spaceavail < mfs) continue; mfs = info.spaceavail; - mfsbasepath = &branch->path; + basepath = &branch->path; } - if(mfsbasepath == NULL) + if(basepath == NULL) return (errno=error,-1); - paths_->push_back(*mfsbasepath); + paths_->push_back(*basepath); return 0; } + + static + int + create(const Branches &branches_, + vector *paths_) + { + rwlock::ReadGuard guard(branches_.lock); + + return mfs::create(branches_.vec,paths_); + } } int Policy::Func::mfs(const Category type_, const Branches &branches_, const char *fusepath_, - const uint64_t minfreespace_, vector *paths_) { if(type_ == Category::CREATE) - return mfs::create(branches_,minfreespace_,paths_); + return mfs::create(branches_,paths_); - return Policy::Func::epmfs(type_,branches_,fusepath_,minfreespace_,paths_); + return Policy::Func::epmfs(type_,branches_,fusepath_,paths_); } diff --git a/src/policy_msplfs.cpp b/src/policy_msplfs.cpp index a479e5eb..61cea2d4 100644 --- a/src/policy_msplfs.cpp +++ b/src/policy_msplfs.cpp @@ -36,10 +36,9 @@ namespace msplfs static const string* - create_1(const Branches &branches_, - const string &fusepath_, - const uint64_t minfreespace_, - int *err_) + create_1(const BranchVec &branches_, + const string &fusepath_, + int *err_) { int rv; uint64_t lfs; @@ -54,16 +53,16 @@ namespace msplfs { branch = &branches_[i]; - if(!fs::exists(branch->path,fusepath)) - error_and_continue(*err_,ENOENT); 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 < minfreespace_) + if(info.spaceavail < branch->minfreespace()) error_and_continue(*err_,ENOSPC); if(info.spaceavail > lfs) continue; @@ -77,21 +76,19 @@ namespace msplfs static int - create(const Branches &branches_, - const char *fusepath_, - const uint64_t minfreespace_, - vector *paths_) + create(const BranchVec &branches_, + const char *fusepath_, + vector *paths_) { int error; string fusepath; const string *basepath; - rwlock::ReadGuard guard(&branches_.lock); error = ENOENT; fusepath = fusepath_; do { - basepath = create_1(branches_,fusepath,minfreespace_,&error); + basepath = msplfs::create_1(branches_,fusepath,&error); if(basepath) break; @@ -106,17 +103,27 @@ namespace msplfs return 0; } + + static + int + create(const Branches &branches_, + const char *fusepath_, + vector *paths_) + { + rwlock::ReadGuard guard(branches_.lock); + + return msplfs::create(branches_.vec,fusepath_,paths_); + } } int Policy::Func::msplfs(const Category type_, const Branches &branches_, const char *fusepath_, - const uint64_t minfreespace_, vector *paths_) { if(type_ == Category::CREATE) - return msplfs::create(branches_,fusepath_,minfreespace_,paths_); + return msplfs::create(branches_,fusepath_,paths_); - return Policy::Func::eplfs(type_,branches_,fusepath_,minfreespace_,paths_); + return Policy::Func::eplfs(type_,branches_,fusepath_,paths_); } diff --git a/src/policy_msplus.cpp b/src/policy_msplus.cpp index 6fc641dd..48b4e59a 100644 --- a/src/policy_msplus.cpp +++ b/src/policy_msplus.cpp @@ -36,10 +36,9 @@ namespace msplus static const string* - create_1(const Branches &branches_, - const string &fusepath_, - const uint64_t minfreespace_, - int *err_) + create_1(const BranchVec &branches_, + const string &fusepath_, + int *err_) { int rv; uint64_t lus; @@ -54,16 +53,16 @@ namespace msplus { branch = &branches_[i]; - if(!fs::exists(branch->path,fusepath)) - error_and_continue(*err_,ENOENT); 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 < minfreespace_) + if(info.spaceavail < branch->minfreespace()) error_and_continue(*err_,ENOSPC); if(info.spaceused >= lus) continue; @@ -77,21 +76,19 @@ namespace msplus static int - create(const Branches &branches_, - const char *fusepath_, - const uint64_t minfreespace_, - vector *paths_) + create(const BranchVec &branches_, + const char *fusepath_, + vector *paths_) { int error; string fusepath; const string *basepath; - rwlock::ReadGuard guard(&branches_.lock); error = ENOENT; fusepath = fusepath_; do { - basepath = create_1(branches_,fusepath,minfreespace_,&error); + basepath = msplus::create_1(branches_,fusepath,&error); if(basepath) break; @@ -106,17 +103,27 @@ namespace msplus return 0; } + + static + int + create(const Branches &branches_, + const char *fusepath_, + vector *paths_) + { + rwlock::ReadGuard guard(branches_.lock); + + return msplus::create(branches_.vec,fusepath_,paths_); + } } int Policy::Func::msplus(const Category type_, const Branches &branches_, const char *fusepath_, - const uint64_t minfreespace_, vector *paths_) { if(type_ == Category::CREATE) - return msplus::create(branches_,fusepath_,minfreespace_,paths_); + return msplus::create(branches_,fusepath_,paths_); - return Policy::Func::eplus(type_,branches_,fusepath_,minfreespace_,paths_); + return Policy::Func::eplus(type_,branches_,fusepath_,paths_); } diff --git a/src/policy_mspmfs.cpp b/src/policy_mspmfs.cpp index f93a4439..4ce63608 100644 --- a/src/policy_mspmfs.cpp +++ b/src/policy_mspmfs.cpp @@ -36,10 +36,9 @@ namespace mspmfs static const string* - create_1(const Branches &branches_, - const string &fusepath_, - const uint64_t minfreespace_, - int *err_) + create_1(const BranchVec &branches_, + const string &fusepath_, + int *err_) { int rv; uint64_t mfs; @@ -54,16 +53,16 @@ namespace mspmfs { branch = &branches_[i]; - if(!fs::exists(branch->path,fusepath)) - error_and_continue(*err_,ENOENT); 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 < minfreespace_) + if(info.spaceavail < branch->minfreespace()) error_and_continue(*err_,ENOSPC); if(info.spaceavail < mfs) continue; @@ -77,21 +76,19 @@ namespace mspmfs static int - create(const Branches &branches_, - const char *fusepath_, - const uint64_t minfreespace_, - vector *paths_) + create(const BranchVec &branches_, + const char *fusepath_, + vector *paths_) { int error; string fusepath; const string *basepath; - rwlock::ReadGuard guard(&branches_.lock); error = ENOENT; fusepath = fusepath_; do { - basepath = create_1(branches_,fusepath,minfreespace_,&error); + basepath = mspmfs::create_1(branches_,fusepath,&error); if(basepath) break; @@ -106,17 +103,27 @@ namespace mspmfs return 0; } + + static + int + create(const Branches &branches_, + const char *fusepath_, + vector *paths_) + { + rwlock::ReadGuard guard(branches_.lock); + + return mspmfs::create(branches_.vec,fusepath_,paths_); + } } int Policy::Func::mspmfs(const Category type_, const Branches &branches_, const char *fusepath_, - const uint64_t minfreespace_, vector *paths_) { if(type_ == Category::CREATE) - return mspmfs::create(branches_,fusepath_,minfreespace_,paths_); + return mspmfs::create(branches_,fusepath_,paths_); - return Policy::Func::epmfs(type_,branches_,fusepath_,minfreespace_,paths_); + return Policy::Func::epmfs(type_,branches_,fusepath_,paths_); } diff --git a/src/policy_msppfrd.cpp b/src/policy_msppfrd.cpp index 971352a8..0fa7ccaf 100644 --- a/src/policy_msppfrd.cpp +++ b/src/policy_msppfrd.cpp @@ -44,18 +44,16 @@ namespace msppfrd { static int - create_1(const Branches &branches_, - const string &fusepath_, - const uint64_t minfreespace_, - BranchInfoVec *branchinfo_, - uint64_t *sum_) + create_1(const BranchVec &branches_, + const string &fusepath_, + BranchInfoVec *branchinfo_, + uint64_t *sum_) { int rv; int error; BranchInfo bi; fs::info_t info; const Branch *branch; - rwlock::ReadGuard guard(&branches_.lock); *sum_ = 0; error = ENOENT; @@ -72,7 +70,7 @@ namespace msppfrd error_and_continue(error,ENOENT); if(info.readonly) error_and_continue(error,EROFS); - if(info.spaceavail < minfreespace_) + if(info.spaceavail < branch->minfreespace()) error_and_continue(error,ENOSPC); *sum_ += info.spaceavail; @@ -85,11 +83,24 @@ namespace msppfrd return error; } + static + int + create_1(const Branches &branches_, + const string &fusepath_, + BranchInfoVec *branchinfo_, + uint64_t *sum_) + { + rwlock::ReadGuard guard(branches_.lock); + + branchinfo_->reserve(branches_.vec.size()); + + return msppfrd::create_1(branches_.vec,fusepath_,branchinfo_,sum_); + } + static int get_branchinfo(const Branches &branches_, const char *fusepath_, - const uint64_t minfreespace_, BranchInfoVec *branchinfo_, uint64_t *sum_) { @@ -99,7 +110,7 @@ namespace msppfrd fusepath = fusepath_; do { - error = msppfrd::create_1(branches_,fusepath,minfreespace_,branchinfo_,sum_); + error = msppfrd::create_1(branches_,fusepath,branchinfo_,sum_); if(branchinfo_->size()) return error; @@ -138,7 +149,6 @@ namespace msppfrd int create(const Branches &branches_, const char *fusepath_, - const uint64_t minfreespace_, vector *paths_) { int error; @@ -146,8 +156,7 @@ namespace msppfrd const string *basepath; BranchInfoVec branchinfo; - branchinfo.reserve(branches_.size()); - error = msppfrd::get_branchinfo(branches_,fusepath_,minfreespace_,&branchinfo,&sum); + error = msppfrd::get_branchinfo(branches_,fusepath_,&branchinfo,&sum); basepath = msppfrd::get_branch(branchinfo,sum); if(basepath == NULL) return (errno=error,-1); @@ -162,11 +171,10 @@ int Policy::Func::msppfrd(const Category type_, const Branches &branches_, const char *fusepath_, - const uint64_t minfreespace_, vector *paths_) { if(type_ == Category::CREATE) - return msppfrd::create(branches_,fusepath_,minfreespace_,paths_); + return msppfrd::create(branches_,fusepath_,paths_); - return Policy::Func::eppfrd(type_,branches_,fusepath_,minfreespace_,paths_); + return Policy::Func::eppfrd(type_,branches_,fusepath_,paths_); } diff --git a/src/policy_newest.cpp b/src/policy_newest.cpp index c3eced2b..520cc1c9 100644 --- a/src/policy_newest.cpp +++ b/src/policy_newest.cpp @@ -36,32 +36,29 @@ namespace newest { static int - create(const Branches &branches_, - const char *fusepath_, - const uint64_t minfreespace_, - vector *paths_) + create(const BranchVec &branches_, + const char *fusepath_, + vector *paths_) { - rwlock::ReadGuard guard(&branches_.lock); - int rv; int error; time_t newest; struct stat st; fs::info_t info; const Branch *branch; - const string *newestbasepath; + const string *basepath; error = ENOENT; newest = std::numeric_limits::min(); - newestbasepath = NULL; + basepath = NULL; for(size_t i = 0, ei = branches_.size(); i != ei; i++) { branch = &branches_[i]; - if(!fs::exists(branch->path,fusepath_,&st)) - error_and_continue(error,ENOENT); 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); @@ -69,48 +66,57 @@ namespace newest error_and_continue(error,ENOENT); if(info.readonly) error_and_continue(error,EROFS); - if(info.spaceavail < minfreespace_) + if(info.spaceavail < branch->minfreespace()) error_and_continue(error,ENOSPC); newest = st.st_mtime; - newestbasepath = &branch->path; + basepath = &branch->path; } - if(newestbasepath == NULL) + if(basepath == NULL) return (errno=error,-1); - paths_->push_back(*newestbasepath); + paths_->push_back(*basepath); return 0; } static int - action(const Branches &branches_, + create(const Branches &branches_, const char *fusepath_, vector *paths_) { - rwlock::ReadGuard guard(&branches_.lock); + rwlock::ReadGuard guard(branches_.lock); + + return newest::create(branches_.vec,fusepath_,paths_); + } + static + int + action(const BranchVec &branches_, + const char *fusepath_, + vector *paths_) + { int rv; int error; bool readonly; time_t newest; struct stat st; const Branch *branch; - const string *newestbasepath; + const string *basepath; error = ENOENT; newest = std::numeric_limits::min(); - newestbasepath = NULL; + basepath = NULL; for(size_t i = 0, ei = branches_.size(); i != ei; i++) { branch = &branches_[i]; - if(!fs::exists(branch->path,fusepath_,&st)) - error_and_continue(error,ENOENT); 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); @@ -120,32 +126,41 @@ namespace newest error_and_continue(error,EROFS); newest = st.st_mtime; - newestbasepath = &branch->path; + basepath = &branch->path; } - if(newestbasepath == NULL) + if(basepath == NULL) return (errno=error,-1); - paths_->push_back(*newestbasepath); + paths_->push_back(*basepath); return 0; } static int - search(const Branches &branches_, + action(const Branches &branches_, const char *fusepath_, vector *paths_) { - rwlock::ReadGuard guard(&branches_.lock); + rwlock::ReadGuard guard(branches_.lock); + + return newest::action(branches_.vec,fusepath_,paths_); + } + static + int + search(const BranchVec &branches_, + const char *fusepath_, + vector *paths_) + { time_t newest; struct stat st; const Branch *branch; - const string *newestbasepath; + const string *basepath; newest = std::numeric_limits::min(); - newestbasepath = NULL; + basepath = NULL; for(size_t i = 0, ei = branches_.size(); i != ei; i++) { branch = &branches_[i]; @@ -156,29 +171,39 @@ namespace newest continue; newest = st.st_mtime; - newestbasepath = &branch->path; + basepath = &branch->path; } - if(newestbasepath == NULL) + if(basepath == NULL) return (errno=ENOENT,-1); - paths_->push_back(*newestbasepath); + paths_->push_back(*basepath); return 0; } + + static + int + search(const Branches &branches_, + const char *fusepath_, + vector *paths_) + { + rwlock::ReadGuard guard(branches_.lock); + + return newest::search(branches_.vec,fusepath_,paths_); + } } int Policy::Func::newest(const Category type_, const Branches &branches_, const char *fusepath_, - const uint64_t minfreespace_, vector *paths_) { switch(type_) { case Category::CREATE: - return newest::create(branches_,fusepath_,minfreespace_,paths_); + return newest::create(branches_,fusepath_,paths_); case Category::ACTION: return newest::action(branches_,fusepath_,paths_); case Category::SEARCH: diff --git a/src/policy_pfrd.cpp b/src/policy_pfrd.cpp index 6272f6a8..ab22e278 100644 --- a/src/policy_pfrd.cpp +++ b/src/policy_pfrd.cpp @@ -40,17 +40,15 @@ namespace pfrd { static int - get_branchinfo(const Branches &branches_, - const uint64_t minfreespace_, - BranchInfoVec *branchinfo_, - uint64_t *sum_) + get_branchinfo(const BranchVec &branches_, + BranchInfoVec *branchinfo_, + uint64_t *sum_) { int rv; int error; BranchInfo bi; fs::info_t info; const Branch *branch; - rwlock::ReadGuard guard(&branches_.lock); *sum_ = 0; error = ENOENT; @@ -65,7 +63,7 @@ namespace pfrd error_and_continue(error,ENOENT); if(info.readonly) error_and_continue(error,EROFS); - if(info.spaceavail < minfreespace_) + if(info.spaceavail < branch->minfreespace()) error_and_continue(error,ENOSPC); *sum_ += info.spaceavail; @@ -78,6 +76,19 @@ namespace pfrd return error; } + static + int + get_branchinfo(const Branches &branches_, + BranchInfoVec *branchinfo_, + uint64_t *sum_) + { + rwlock::ReadGuard guard(branches_.lock); + + branchinfo_->reserve(branches_.vec.size()); + + return pfrd::get_branchinfo(branches_.vec,branchinfo_,sum_); + } + static const string* @@ -106,7 +117,6 @@ namespace pfrd int create(const Branches &branches_, const char *fusepath_, - const uint64_t minfreespace_, vector *paths_) { int error; @@ -114,8 +124,7 @@ namespace pfrd const string *basepath; BranchInfoVec branchinfo; - branchinfo.reserve(branches_.size()); - error = pfrd::get_branchinfo(branches_,minfreespace_,&branchinfo,&sum); + error = pfrd::get_branchinfo(branches_,&branchinfo,&sum); basepath = pfrd::get_branch(branchinfo,sum); if(basepath == NULL) return (errno=error,-1); @@ -130,11 +139,10 @@ int Policy::Func::pfrd(const Category type_, const Branches &branches_, const char *fusepath_, - const uint64_t minfreespace_, vector *paths_) { if(type_ == Category::CREATE) - return pfrd::create(branches_,fusepath_,minfreespace_,paths_); + return pfrd::create(branches_,fusepath_,paths_); - return Policy::Func::eppfrd(type_,branches_,fusepath_,minfreespace_,paths_); + return Policy::Func::eppfrd(type_,branches_,fusepath_,paths_); } diff --git a/src/policy_rand.cpp b/src/policy_rand.cpp index 2ffb2a92..160d39e5 100644 --- a/src/policy_rand.cpp +++ b/src/policy_rand.cpp @@ -28,12 +28,11 @@ int Policy::Func::rand(const Category type_, const Branches &branches_, const char *fusepath_, - const uint64_t minfreespace_, vector *paths_) { int rv; - rv = Policy::Func::all(type_,branches_,fusepath_,minfreespace_,paths_); + rv = Policy::Func::all(type_,branches_,fusepath_,paths_); if(rv == 0) { std::random_shuffle(paths_->begin(),paths_->end()); diff --git a/src/rwlock.hpp b/src/rwlock.hpp index a810ed22..98b77518 100644 --- a/src/rwlock.hpp +++ b/src/rwlock.hpp @@ -23,42 +23,42 @@ namespace rwlock class ReadGuard { public: - ReadGuard(pthread_rwlock_t *lock_) + ReadGuard(pthread_rwlock_t &lock_) : _lock(lock_) { - pthread_rwlock_rdlock(_lock); + pthread_rwlock_rdlock(&_lock); } ~ReadGuard() { - pthread_rwlock_unlock(_lock); + pthread_rwlock_unlock(&_lock); } private: ReadGuard(); private: - pthread_rwlock_t *_lock; + pthread_rwlock_t &_lock; }; class WriteGuard { public: - WriteGuard(pthread_rwlock_t *lock_) + WriteGuard(pthread_rwlock_t &lock_) : _lock(lock_) { - pthread_rwlock_wrlock(_lock); + pthread_rwlock_wrlock(&_lock); } ~WriteGuard() { - pthread_rwlock_unlock(_lock); + pthread_rwlock_unlock(&_lock); } private: WriteGuard(); private: - pthread_rwlock_t *_lock; + pthread_rwlock_t &_lock; }; } diff --git a/src/str.cpp b/src/str.cpp index 9d234048..de07ff2c 100644 --- a/src/str.cpp +++ b/src/str.cpp @@ -46,6 +46,25 @@ namespace str return str::split(str_.c_str(),delimiter_,result_); } + void + rsplit1(const string &str_, + const char delimiter_, + vector *result_) + { + std::size_t off; + + off = str_.rfind('='); + if(off == std::string::npos) + { + result_->push_back(str_); + } + else + { + result_->push_back(str_.substr(0,off)); + result_->push_back(str_.substr(off+1)); + } + } + void splitkv(const string &str_, const char delimiter_, diff --git a/src/str.hpp b/src/str.hpp index 10f4b305..c9a6f268 100644 --- a/src/str.hpp +++ b/src/str.hpp @@ -30,6 +30,11 @@ namespace str const char delimiter, std::vector *result); + void + rsplit1(const std::string &str, + const char delimiter, + std::vector *result); + void splitkv(const std::string &str, const char delimiter,