diff --git a/src/access.cpp b/src/access.cpp index dab24164..86418d94 100644 --- a/src/access.cpp +++ b/src/access.cpp @@ -45,11 +45,11 @@ using mergerfs::Policy; static int -_access(const Policy::FuncPtr searchFunc, - const vector &srcmounts, - const size_t minfreespace, - const string &fusepath, - const int mask) +_access(const Policy::Func::Ptr searchFunc, + const vector &srcmounts, + const size_t minfreespace, + const string &fusepath, + const int mask) { int rv; Paths paths; diff --git a/src/chmod.cpp b/src/chmod.cpp index bd54befe..ecd57ae4 100644 --- a/src/chmod.cpp +++ b/src/chmod.cpp @@ -39,11 +39,11 @@ using mergerfs::Policy; static int -_chmod(const Policy::FuncPtr actionFunc, - const vector &srcmounts, - const size_t minfreespace, - const string &fusepath, - const mode_t mode) +_chmod(const Policy::Func::Ptr actionFunc, + const vector &srcmounts, + const size_t minfreespace, + const string &fusepath, + const mode_t mode) { int rv; int error; diff --git a/src/chown.cpp b/src/chown.cpp index f08f29e9..19469d6a 100644 --- a/src/chown.cpp +++ b/src/chown.cpp @@ -40,12 +40,12 @@ using mergerfs::Policy; static int -_chown(const Policy::FuncPtr actionFunc, - const vector &srcmounts, - const size_t minfreespace, - const string &fusepath, - const uid_t uid, - const gid_t gid) +_chown(const Policy::Func::Ptr actionFunc, + const vector &srcmounts, + const size_t minfreespace, + const string &fusepath, + const uid_t uid, + const gid_t gid) { int rv; int error; diff --git a/src/create.cpp b/src/create.cpp index 7f018958..80a1a836 100644 --- a/src/create.cpp +++ b/src/create.cpp @@ -43,14 +43,14 @@ using mergerfs::Policy; static int -_create(const Policy::FuncPtr searchFunc, - const Policy::FuncPtr createFunc, - const vector &srcmounts, - const size_t minfreespace, - const string &fusepath, - const mode_t mode, - const int flags, - uint64_t &fh) +_create(const Policy::Func::Ptr searchFunc, + const Policy::Func::Ptr createFunc, + const vector &srcmounts, + const size_t minfreespace, + const string &fusepath, + const mode_t mode, + const int flags, + uint64_t &fh) { int fd; int rv; diff --git a/src/fs.cpp b/src/fs.cpp index cb7bc451..3e41b4bb 100644 --- a/src/fs.cpp +++ b/src/fs.cpp @@ -28,7 +28,6 @@ #include #include #include -#include #include #include @@ -514,341 +513,4 @@ namespace fs globfree(&gbuf); } - - namespace find - { - int - invalid(const vector &basepaths, - const string &fusepath, - const size_t minfreespace, - Paths &rv) - { - return (errno = EINVAL,-1); - } - - int - ff(const vector &basepaths, - const string &fusepath, - const size_t minfreespace, - Paths &paths) - { - errno = ENOENT; - for(vector::const_iterator - iter = basepaths.begin(), eiter = basepaths.end(); - iter != eiter; - ++iter) - { - int rv; - struct stat st; - string fullpath; - - fullpath = fs::make_path(*iter,fusepath); - - rv = ::lstat(fullpath.c_str(),&st); - if(rv == 0) - { - paths.push_back(Path(*iter,fullpath)); - return 0; - } - } - - return -1; - } - - int - ffwp(const vector &basepaths, - const string &fusepath, - const size_t minfreespace, - Paths &paths) - { - Path fallback; - - errno = ENOENT; - for(vector::const_iterator - iter = basepaths.begin(), eiter = basepaths.end(); - iter != eiter; - ++iter) - { - int rv; - struct stat st; - string fullpath; - - fullpath = fs::make_path(*iter,fusepath); - - rv = ::lstat(fullpath.c_str(),&st); - if(rv == 0) - { - paths.push_back(Path(*iter,fullpath)); - return 0; - } - else if(errno == EACCES) - { - fallback.base = *iter; - fallback.full = fullpath; - } - } - - if(!fallback.base.empty()) - return (paths.push_back(fallback),0); - - return -1; - } - - int - fwfs(const vector &basepaths, - const string &fusepath, - const size_t minfreespace, - Paths &paths) - { - for(size_t i = 0, size = basepaths.size(); i != size; i++) - { - int rv; - const char *basepath; - struct statvfs fsstats; - - basepath = basepaths[i].c_str(); - rv = ::statvfs(basepath,&fsstats); - if(rv == 0) - { - fsblkcnt_t spaceavail; - - spaceavail = (fsstats.f_frsize * fsstats.f_bavail); - if(spaceavail > minfreespace) - { - paths.push_back(Path(basepath, - fs::make_path(basepath,fusepath))); - return 0; - } - } - } - - return mfs(basepaths,fusepath,minfreespace,paths); - } - - int - newest(const vector &basepaths, - const string &fusepath, - const size_t minfreespace, - Paths &paths) - { - time_t newest; - string npath; - vector::const_iterator niter; - - newest = 0; - errno = ENOENT; - for(vector::const_iterator - iter = basepaths.begin(), eiter = basepaths.end(); - iter != eiter; - ++iter) - { - int rv; - struct stat st; - string fullpath; - - fullpath = fs::make_path(*iter,fusepath); - - rv = ::lstat(fullpath.c_str(),&st); - if(rv == 0 && st.st_mtime > newest) - { - newest = st.st_mtime; - niter = iter; - npath = fullpath; - } - } - - if(newest) - return (paths.push_back(Path(*niter,npath)),0); - - return -1; - } - - int - lfs(const vector &basepaths, - const string &fusepath, - const size_t minfreespace, - Paths &paths) - { - fsblkcnt_t lfs; - const char *lfsstr; - - lfs = -1; - lfsstr = NULL; - for(size_t i = 0, size = basepaths.size(); i != size; i++) - { - int rv; - const char *basepath; - struct statvfs fsstats; - - basepath = basepaths[i].c_str(); - rv = ::statvfs(basepath,&fsstats); - if(rv == 0) - { - fsblkcnt_t spaceavail; - - spaceavail = (fsstats.f_frsize * fsstats.f_bavail); - if((spaceavail > minfreespace) && - (spaceavail < lfs)) - { - lfs = spaceavail; - lfsstr = basepath; - } - } - } - - if(lfsstr == NULL) - return mfs(basepaths,fusepath,minfreespace,paths); - - paths.push_back(Path(lfsstr, - fs::make_path(lfsstr,fusepath))); - - return 0; - } - - - int - mfs(const vector &basepaths, - const string &fusepath, - const size_t minfreespace, - Paths &paths) - { - fsblkcnt_t mfs; - size_t mfsidx; - - mfs = 0; - for(size_t i = 0, size = basepaths.size(); - i != size; - i++) - { - int rv; - struct statvfs fsstats; - - rv = ::statvfs(basepaths[i].c_str(),&fsstats); - if(rv == 0) - { - fsblkcnt_t spaceavail; - - spaceavail = (fsstats.f_frsize * fsstats.f_bavail); - if(spaceavail > mfs) - { - mfs = spaceavail; - mfsidx = i; - } - } - } - - if(mfs == 0) - return (errno=ENOENT,-1); - - paths.push_back(Path(basepaths[mfsidx], - fs::make_path(basepaths[mfsidx],fusepath))); - - return 0; - } - - int - epmfs(const vector &basepaths, - const string &fusepath, - const size_t minfreespace, - Paths &paths) - { - fsblkcnt_t existingmfs; - fsblkcnt_t generalmfs; - string fullpath; - string generalmfspath; - string existingmfspath; - vector::const_iterator iter = basepaths.begin(); - vector::const_iterator eiter = basepaths.end(); - - if(iter == eiter) - return (errno = ENOENT,-1); - - existingmfs = 0; - generalmfs = 0; - do - { - int rv; - struct statvfs fsstats; - const string &mountpoint = *iter; - - rv = ::statvfs(mountpoint.c_str(),&fsstats); - if(rv == 0) - { - fsblkcnt_t spaceavail; - struct stat st; - - spaceavail = (fsstats.f_frsize * fsstats.f_bavail); - if(spaceavail > generalmfs) - { - generalmfs = spaceavail; - generalmfspath = mountpoint; - } - - fullpath = fs::make_path(mountpoint,fusepath); - rv = ::lstat(fullpath.c_str(),&st); - if(rv == 0) - { - if(spaceavail > existingmfs) - { - existingmfs = spaceavail; - existingmfspath = mountpoint; - } - } - } - - ++iter; - } - while(iter != eiter); - - if(existingmfspath.empty()) - existingmfspath = generalmfspath; - - paths.push_back(Path(existingmfspath, - fullpath)); - - return 0; - } - - int - all(const vector &basepaths, - const string &fusepath, - const size_t minfreespace, - Paths &paths) - { - int rv; - struct stat st; - string fullpath; - - for(vector::const_iterator - iter = basepaths.begin(), eiter = basepaths.end(); - iter != eiter; - ++iter) - { - fullpath = fs::make_path(*iter,fusepath); - - rv = ::lstat(fullpath.c_str(),&st); - if(rv == 0) - paths.push_back(Path(*iter,fullpath)); - } - - return paths.empty() ? (errno=ENOENT,-1) : 0; - } - - int - rand(const vector &basepaths, - const string &fusepath, - const size_t minfreespace, - Paths &paths) - { - int rv; - - rv = all(basepaths,fusepath,minfreespace,paths); - if(rv == -1) - return -1; - - std::random_shuffle(paths.begin(),paths.end()); - - return 0; - } - } }; diff --git a/src/fs.hpp b/src/fs.hpp index bbd0e6fc..1ef65b31 100644 --- a/src/fs.hpp +++ b/src/fs.hpp @@ -97,50 +97,6 @@ namespace fs void glob(const vector &patterns, vector &strs); - - namespace find - { - int invalid(const vector &basepaths, - const string &fusepath, - const size_t minfreespace, - Paths &path); - int all(const vector &basepaths, - const string &fusepath, - const size_t minfreespace, - Paths &path); - int ff(const vector &basepaths, - const string &fusepath, - const size_t minfreespace, - Paths &path); - int ffwp(const vector &paths, - const string &fusepath, - const size_t minfreespace, - Paths &path); - int fwfs(const vector &paths, - const string &fusepath, - const size_t minfreespace, - Paths &path); - int newest(const vector &paths, - const string &fusepath, - const size_t minfreespace, - Paths &path); - int lfs(const vector &paths, - const string &fusepath, - const size_t minfreespace, - Paths &path); - int mfs(const vector &paths, - const string &fusepath, - const size_t minfreespace, - Paths &path); - int epmfs(const vector &paths, - const string &fusepath, - const size_t minfreespace, - Paths &path); - int rand(const vector &paths, - const string &fusepath, - const size_t minfreespace, - Paths &path); - } }; #endif // __FS_HPP__ diff --git a/src/getattr.cpp b/src/getattr.cpp index 25169505..fd471c5b 100644 --- a/src/getattr.cpp +++ b/src/getattr.cpp @@ -66,11 +66,11 @@ _getattr_controlfile(struct stat &buf) static int -_getattr(const Policy::FuncPtr searchFunc, - const vector &srcmounts, - const size_t minfreespace, - const string &fusepath, - struct stat &buf) +_getattr(const Policy::Func::Ptr searchFunc, + const vector &srcmounts, + const size_t minfreespace, + const string &fusepath, + struct stat &buf) { int rv; Paths path; diff --git a/src/getxattr.cpp b/src/getxattr.cpp index 61d2621f..9f277e90 100644 --- a/src/getxattr.cpp +++ b/src/getxattr.cpp @@ -190,13 +190,13 @@ _getxattr_user_mergerfs(const Path &path, static int -_getxattr(const Policy::FuncPtr searchFunc, - const vector &srcmounts, - const size_t minfreespace, - const string &fusepath, - const char *attrname, - char *buf, - const size_t count) +_getxattr(const Policy::Func::Ptr searchFunc, + const vector &srcmounts, + const size_t minfreespace, + const string &fusepath, + const char *attrname, + char *buf, + const size_t count) { #ifndef WITHOUT_XATTR int rv; diff --git a/src/ioctl.cpp b/src/ioctl.cpp index fa82494e..41947431 100644 --- a/src/ioctl.cpp +++ b/src/ioctl.cpp @@ -82,14 +82,14 @@ _ioctl(const int fd, #ifdef FUSE_IOCTL_DIR static int -_ioctl_dir_base(const Policy::FuncPtr searchFunc, - const vector &srcmounts, - const size_t minfreespace, - const string &fusepath, - const int cmd, - void *arg, - const unsigned int flags, - void *data) +_ioctl_dir_base(const Policy::Func::Ptr searchFunc, + const vector &srcmounts, + const size_t minfreespace, + const string &fusepath, + const int cmd, + void *arg, + const unsigned int flags, + void *data) { int fd; int rv; diff --git a/src/link.cpp b/src/link.cpp index 15d88f41..8f53a18c 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -41,12 +41,12 @@ using mergerfs::Policy; static int -_single_link(const Policy::FuncPtr searchFunc, - const vector &srcmounts, - const size_t minfreespace, - const string &base, - const string &oldpath, - const string &newpath) +_single_link(const Policy::Func::Ptr searchFunc, + const vector &srcmounts, + const size_t minfreespace, + const string &base, + const string &oldpath, + const string &newpath) { int rv; const string fulloldpath = fs::make_path(base,oldpath); @@ -76,12 +76,12 @@ _single_link(const Policy::FuncPtr searchFunc, static int -_link(const Policy::FuncPtr searchFunc, - const Policy::FuncPtr actionFunc, - const vector &srcmounts, - const size_t minfreespace, - const string &oldpath, - const string &newpath) +_link(const Policy::Func::Ptr searchFunc, + const Policy::Func::Ptr actionFunc, + const vector &srcmounts, + const size_t minfreespace, + const string &oldpath, + const string &newpath) { int rv; int error; diff --git a/src/listxattr.cpp b/src/listxattr.cpp index ab4e96d2..59428cc8 100644 --- a/src/listxattr.cpp +++ b/src/listxattr.cpp @@ -69,12 +69,12 @@ _listxattr_controlfile(char *list, static int -_listxattr(const Policy::FuncPtr searchFunc, - const vector &srcmounts, - const size_t minfreespace, - const string &fusepath, - char *list, - const size_t size) +_listxattr(const Policy::Func::Ptr searchFunc, + const vector &srcmounts, + const size_t minfreespace, + const string &fusepath, + char *list, + const size_t size) { #ifndef WITHOUT_XATTR int rv; diff --git a/src/mkdir.cpp b/src/mkdir.cpp index cfa3e38d..fb8caf23 100644 --- a/src/mkdir.cpp +++ b/src/mkdir.cpp @@ -42,12 +42,12 @@ using mergerfs::Policy; static int -_mkdir(const Policy::FuncPtr searchFunc, - const Policy::FuncPtr createFunc, - const vector &srcmounts, - const size_t minfreespace, - const string &fusepath, - const mode_t mode) +_mkdir(const Policy::Func::Ptr searchFunc, + const Policy::Func::Ptr createFunc, + const vector &srcmounts, + const size_t minfreespace, + const string &fusepath, + const mode_t mode) { int rv; int error; diff --git a/src/mknod.cpp b/src/mknod.cpp index 79ff80f1..21ab3f7d 100644 --- a/src/mknod.cpp +++ b/src/mknod.cpp @@ -44,13 +44,13 @@ using mergerfs::Policy; static int -_mknod(const Policy::FuncPtr searchFunc, - const Policy::FuncPtr createFunc, - const vector &srcmounts, - const size_t minfreespace, - const string &fusepath, - const mode_t mode, - const dev_t dev) +_mknod(const Policy::Func::Ptr searchFunc, + const Policy::Func::Ptr createFunc, + const vector &srcmounts, + const size_t minfreespace, + const string &fusepath, + const mode_t mode, + const dev_t dev) { int rv; int error; diff --git a/src/open.cpp b/src/open.cpp index e81e998a..b06cec3d 100644 --- a/src/open.cpp +++ b/src/open.cpp @@ -42,12 +42,12 @@ using mergerfs::Policy; static int -_open(const Policy::FuncPtr searchFunc, - const vector &srcmounts, - const size_t minfreespace, - const string &fusepath, - const int flags, - uint64_t &fh) +_open(const Policy::Func::Ptr searchFunc, + const vector &srcmounts, + const size_t minfreespace, + const string &fusepath, + const int flags, + uint64_t &fh) { int fd; int rv; diff --git a/src/policy.cpp b/src/policy.cpp index 4ca300cd..6428e705 100644 --- a/src/policy.cpp +++ b/src/policy.cpp @@ -28,7 +28,7 @@ #include "fs.hpp" #include "buildvector.hpp" -#define POLICY(X) (Policy(Policy::Enum::X,#X,fs::find::X)) +#define POLICY(X) (Policy(Policy::Enum::X,#X,Policy::Func::X)) namespace mergerfs { diff --git a/src/policy.hpp b/src/policy.hpp index 6807aee8..a40b069c 100644 --- a/src/policy.hpp +++ b/src/policy.hpp @@ -37,8 +37,6 @@ namespace mergerfs class Policy { public: - typedef int (*FuncPtr)(const std::vector&,const std::string&,const std::size_t,Paths&); - struct Enum { enum Type @@ -58,10 +56,30 @@ namespace mergerfs }; }; + struct Func + { + typedef std::string string; + typedef std::size_t size_t; + typedef std::vector strvec; + + typedef int (*Ptr)(const strvec&,const string&,const size_t,Paths&); + + static int invalid(const strvec&,const string&,const size_t,Paths&); + static int all(const strvec&,const string&,const size_t,Paths&); + static int epmfs(const strvec&,const string&,const size_t,Paths&); + static int ff(const strvec&,const string&,const size_t,Paths&); + static int ffwp(const strvec&,const string&,const size_t,Paths&); + static int fwfs(const strvec&,const string&,const size_t,Paths&); + static int lfs(const strvec&,const string&,const size_t,Paths&); + static int mfs(const strvec&,const string&,const size_t,Paths&); + static int newest(const strvec&,const string&,const size_t,Paths&); + static int rand(const strvec&,const string&,const size_t,Paths&); + }; + private: Enum::Type _enum; std::string _str; - FuncPtr _func; + Func::Ptr _func; public: Policy() @@ -73,7 +91,7 @@ namespace mergerfs Policy(const Enum::Type enum_, const std::string &str_, - const FuncPtr func_) + const Func::Ptr func_) : _enum(enum_), _str(str_), _func(func_) @@ -83,14 +101,14 @@ namespace mergerfs public: operator const Enum::Type() const { return _enum; } operator const std::string&() const { return _str; } - operator const FuncPtr() const { return _func; } + operator const Func::Ptr() const { return _func; } operator const Policy*() const { return this; } bool operator==(const Enum::Type enum_) const { return _enum == enum_; } bool operator==(const std::string &str_) const { return _str == str_; } - bool operator==(const FuncPtr func_) const + bool operator==(const Func::Ptr func_) const { return _func == func_; } bool operator!=(const Policy &r) const diff --git a/src/policy_all.cpp b/src/policy_all.cpp new file mode 100644 index 00000000..9260651c --- /dev/null +++ b/src/policy_all.cpp @@ -0,0 +1,65 @@ +/* + The MIT License (MIT) + + Copyright (c) 2014 Antonio SJ Musumeci + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#include +#include +#include +#include + +#include +#include + +#include "policy.hpp" + +using std::string; +using std::vector; +using std::size_t; + +namespace mergerfs +{ + int + Policy::Func::all(const vector &basepaths, + const string &fusepath, + const size_t minfreespace, + Paths &paths) + { + int rv; + struct stat st; + string fullpath; + + for(vector::const_iterator + iter = basepaths.begin(), eiter = basepaths.end(); + iter != eiter; + ++iter) + { + fullpath = fs::make_path(*iter,fusepath); + + rv = ::lstat(fullpath.c_str(),&st); + if(rv == 0) + paths.push_back(Path(*iter,fullpath)); + } + + return paths.empty() ? (errno=ENOENT,-1) : 0; + } +} diff --git a/src/policy_epmfs.cpp b/src/policy_epmfs.cpp new file mode 100644 index 00000000..b6456f5d --- /dev/null +++ b/src/policy_epmfs.cpp @@ -0,0 +1,104 @@ +/* + The MIT License (MIT) + + Copyright (c) 2014 Antonio SJ Musumeci + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#include +#include +#include +#include +#include + +#include +#include + +#include "policy.hpp" + +using std::string; +using std::vector; +using std::size_t; + +namespace mergerfs +{ + int + Policy::Func::epmfs(const vector &basepaths, + const string &fusepath, + const size_t minfreespace, + Paths &paths) + { + fsblkcnt_t existingmfs; + fsblkcnt_t generalmfs; + string fullpath; + string generalmfspath; + string existingmfspath; + vector::const_iterator iter = basepaths.begin(); + vector::const_iterator eiter = basepaths.end(); + + if(iter == eiter) + return (errno = ENOENT,-1); + + existingmfs = 0; + generalmfs = 0; + do + { + int rv; + struct statvfs fsstats; + const string &mountpoint = *iter; + + rv = ::statvfs(mountpoint.c_str(),&fsstats); + if(rv == 0) + { + fsblkcnt_t spaceavail; + struct stat st; + + spaceavail = (fsstats.f_frsize * fsstats.f_bavail); + if(spaceavail > generalmfs) + { + generalmfs = spaceavail; + generalmfspath = mountpoint; + } + + fullpath = fs::make_path(mountpoint,fusepath); + rv = ::lstat(fullpath.c_str(),&st); + if(rv == 0) + { + if(spaceavail > existingmfs) + { + existingmfs = spaceavail; + existingmfspath = mountpoint; + } + } + } + + ++iter; + } + while(iter != eiter); + + if(existingmfspath.empty()) + existingmfspath = generalmfspath; + + paths.push_back(Path(existingmfspath, + fullpath)); + + return 0; + } +} diff --git a/src/policy_ff.cpp b/src/policy_ff.cpp new file mode 100644 index 00000000..a555ee1c --- /dev/null +++ b/src/policy_ff.cpp @@ -0,0 +1,70 @@ +/* + The MIT License (MIT) + + Copyright (c) 2014 Antonio SJ Musumeci + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#include +#include +#include +#include + +#include +#include + +#include "path.hpp" +#include "policy.hpp" + +using std::string; +using std::vector; +using std::size_t; + +namespace mergerfs +{ + int + Policy::Func::ff(const vector &basepaths, + const string &fusepath, + const size_t minfreespace, + Paths &paths) + { + errno = ENOENT; + for(vector::const_iterator + iter = basepaths.begin(), eiter = basepaths.end(); + iter != eiter; + ++iter) + { + int rv; + struct stat st; + string fullpath; + + fullpath = fs::make_path(*iter,fusepath); + + rv = ::lstat(fullpath.c_str(),&st); + if(rv == 0) + { + paths.push_back(Path(*iter,fullpath)); + return 0; + } + } + + return -1; + } +} diff --git a/src/policy_ffwp.cpp b/src/policy_ffwp.cpp new file mode 100644 index 00000000..fc908c45 --- /dev/null +++ b/src/policy_ffwp.cpp @@ -0,0 +1,79 @@ +/* + The MIT License (MIT) + + Copyright (c) 2014 Antonio SJ Musumeci + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#include +#include +#include +#include + +#include +#include + +#include "policy.hpp" + +using std::string; +using std::vector; +using std::size_t; + +namespace mergerfs +{ + int + Policy::Func::ffwp(const vector &basepaths, + const string &fusepath, + const size_t minfreespace, + Paths &paths) + { + Path fallback; + + errno = ENOENT; + for(vector::const_iterator + iter = basepaths.begin(), eiter = basepaths.end(); + iter != eiter; + ++iter) + { + int rv; + struct stat st; + string fullpath; + + fullpath = fs::make_path(*iter,fusepath); + + rv = ::lstat(fullpath.c_str(),&st); + if(rv == 0) + { + paths.push_back(Path(*iter,fullpath)); + return 0; + } + else if(errno == EACCES) + { + fallback.base = *iter; + fallback.full = fullpath; + } + } + + if(!fallback.base.empty()) + return (paths.push_back(fallback),0); + + return -1; + } +} diff --git a/src/policy_fwfs.cpp b/src/policy_fwfs.cpp new file mode 100644 index 00000000..517060d1 --- /dev/null +++ b/src/policy_fwfs.cpp @@ -0,0 +1,69 @@ +/* + The MIT License (MIT) + + Copyright (c) 2014 Antonio SJ Musumeci + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#include +#include + +#include +#include + +#include "policy.hpp" + +using std::string; +using std::vector; +using std::size_t; + +namespace mergerfs +{ + int + Policy::Func::fwfs(const vector &basepaths, + const string &fusepath, + const size_t minfreespace, + Paths &paths) + { + for(size_t i = 0, size = basepaths.size(); i != size; i++) + { + int rv; + const char *basepath; + struct statvfs fsstats; + + basepath = basepaths[i].c_str(); + rv = ::statvfs(basepath,&fsstats); + if(rv == 0) + { + fsblkcnt_t spaceavail; + + spaceavail = (fsstats.f_frsize * fsstats.f_bavail); + if(spaceavail > minfreespace) + { + paths.push_back(Path(basepath, + fs::make_path(basepath,fusepath))); + return 0; + } + } + } + + return mfs(basepaths,fusepath,minfreespace,paths); + } +} diff --git a/src/policy_invalid.cpp b/src/policy_invalid.cpp new file mode 100644 index 00000000..829db3e5 --- /dev/null +++ b/src/policy_invalid.cpp @@ -0,0 +1,46 @@ +/* + The MIT License (MIT) + + Copyright (c) 2014 Antonio SJ Musumeci + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#include + +#include +#include + +#include "policy.hpp" + +using std::string; +using std::vector; +using std::size_t; + +namespace mergerfs +{ + int + Policy::Func::invalid(const vector &basepaths, + const string &fusepath, + const size_t minfreespace, + Paths &rv) + { + return (errno = EINVAL,-1); + } +} diff --git a/src/policy_lfs.cpp b/src/policy_lfs.cpp new file mode 100644 index 00000000..89cc22be --- /dev/null +++ b/src/policy_lfs.cpp @@ -0,0 +1,83 @@ +/* + The MIT License (MIT) + + Copyright (c) 2014 Antonio SJ Musumeci + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#include +#include +#include +#include +#include + +#include +#include + +#include "policy.hpp" + +using std::string; +using std::vector; +using std::size_t; + +namespace mergerfs +{ + int + Policy::Func::lfs(const vector &basepaths, + const string &fusepath, + const size_t minfreespace, + Paths &paths) + { + fsblkcnt_t lfs; + const char *lfsstr; + + lfs = -1; + lfsstr = NULL; + for(size_t i = 0, size = basepaths.size(); i != size; i++) + { + int rv; + const char *basepath; + struct statvfs fsstats; + + basepath = basepaths[i].c_str(); + rv = ::statvfs(basepath,&fsstats); + if(rv == 0) + { + fsblkcnt_t spaceavail; + + spaceavail = (fsstats.f_frsize * fsstats.f_bavail); + if((spaceavail > minfreespace) && + (spaceavail < lfs)) + { + lfs = spaceavail; + lfsstr = basepath; + } + } + } + + if(lfsstr == NULL) + return Policy::Func::mfs(basepaths,fusepath,minfreespace,paths); + + paths.push_back(Path(lfsstr, + fs::make_path(lfsstr,fusepath))); + + return 0; + } +} diff --git a/src/policy_mfs.cpp b/src/policy_mfs.cpp new file mode 100644 index 00000000..62c0596e --- /dev/null +++ b/src/policy_mfs.cpp @@ -0,0 +1,78 @@ +/* + The MIT License (MIT) + + Copyright (c) 2014 Antonio SJ Musumeci + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#include +#include + +#include +#include + +#include "policy.hpp" + +using std::string; +using std::vector; +using std::size_t; + +namespace mergerfs +{ + int + Policy::Func::mfs(const vector &basepaths, + const string &fusepath, + const size_t minfreespace, + Paths &paths) + { + fsblkcnt_t mfs; + size_t mfsidx; + + mfs = 0; + for(size_t i = 0, size = basepaths.size(); + i != size; + i++) + { + int rv; + struct statvfs fsstats; + + rv = ::statvfs(basepaths[i].c_str(),&fsstats); + if(rv == 0) + { + fsblkcnt_t spaceavail; + + spaceavail = (fsstats.f_frsize * fsstats.f_bavail); + if(spaceavail > mfs) + { + mfs = spaceavail; + mfsidx = i; + } + } + } + + if(mfs == 0) + return (errno=ENOENT,-1); + + paths.push_back(Path(basepaths[mfsidx], + fs::make_path(basepaths[mfsidx],fusepath))); + + return 0; + } +} diff --git a/src/policy_newest.cpp b/src/policy_newest.cpp new file mode 100644 index 00000000..d260aba7 --- /dev/null +++ b/src/policy_newest.cpp @@ -0,0 +1,78 @@ +/* + The MIT License (MIT) + + Copyright (c) 2014 Antonio SJ Musumeci + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#include +#include +#include +#include + +#include +#include + +#include "policy.hpp" + +using std::string; +using std::vector; +using std::size_t; + +namespace mergerfs +{ + int + Policy::Func::newest(const vector &basepaths, + const string &fusepath, + const size_t minfreespace, + Paths &paths) + { + time_t newest; + string npath; + vector::const_iterator niter; + + newest = 0; + errno = ENOENT; + for(vector::const_iterator + iter = basepaths.begin(), eiter = basepaths.end(); + iter != eiter; + ++iter) + { + int rv; + struct stat st; + string fullpath; + + fullpath = fs::make_path(*iter,fusepath); + + rv = ::lstat(fullpath.c_str(),&st); + if(rv == 0 && st.st_mtime > newest) + { + newest = st.st_mtime; + niter = iter; + npath = fullpath; + } + } + + if(newest) + return (paths.push_back(Path(*niter,npath)),0); + + return -1; + } +} diff --git a/src/policy_rand.cpp b/src/policy_rand.cpp new file mode 100644 index 00000000..b4fdc2d7 --- /dev/null +++ b/src/policy_rand.cpp @@ -0,0 +1,55 @@ +/* + The MIT License (MIT) + + Copyright (c) 2014 Antonio SJ Musumeci + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#include + +#include +#include +#include + +#include "policy.hpp" + +using std::string; +using std::vector; +using std::size_t; + +namespace mergerfs +{ + int + Policy::Func::rand(const vector &basepaths, + const string &fusepath, + const size_t minfreespace, + Paths &paths) + { + int rv; + + rv = Policy::Func::all(basepaths,fusepath,minfreespace,paths); + if(rv == -1) + return -1; + + std::random_shuffle(paths.begin(),paths.end()); + + return 0; + } +} diff --git a/src/readlink.cpp b/src/readlink.cpp index dc7ea697..8ca42216 100644 --- a/src/readlink.cpp +++ b/src/readlink.cpp @@ -41,12 +41,12 @@ using mergerfs::Policy; static int -_readlink(const Policy::FuncPtr searchFunc, - const vector &srcmounts, - const size_t minfreespace, - const string &fusepath, - char *buf, - const size_t size) +_readlink(const Policy::Func::Ptr searchFunc, + const vector &srcmounts, + const size_t minfreespace, + const string &fusepath, + char *buf, + const size_t size) { int rv; Paths path; diff --git a/src/removexattr.cpp b/src/removexattr.cpp index f1fc26ef..235bb1bf 100644 --- a/src/removexattr.cpp +++ b/src/removexattr.cpp @@ -42,11 +42,11 @@ using mergerfs::Policy; static int -_removexattr(const Policy::FuncPtr actionFunc, - const vector &srcmounts, - const size_t minfreespace, - const string &fusepath, - const char *attrname) +_removexattr(const Policy::Func::Ptr actionFunc, + const vector &srcmounts, + const size_t minfreespace, + const string &fusepath, + const char *attrname) { #ifndef WITHOUT_XATTR int rv; diff --git a/src/rename.cpp b/src/rename.cpp index f97372ac..e0e05299 100644 --- a/src/rename.cpp +++ b/src/rename.cpp @@ -42,11 +42,11 @@ using mergerfs::Policy; static int -_single_rename(const Policy::FuncPtr searchFunc, - const vector &srcmounts, - const size_t minfreespace, - const Path &oldpath, - const string &newpath) +_single_rename(const Policy::Func::Ptr searchFunc, + const vector &srcmounts, + const size_t minfreespace, + const Path &oldpath, + const string &newpath) { int rv; const string fullnewpath = fs::make_path(oldpath.base,newpath); @@ -75,12 +75,12 @@ _single_rename(const Policy::FuncPtr searchFunc, static int -_rename(const Policy::FuncPtr searchFunc, - const Policy::FuncPtr actionFunc, - const vector &srcmounts, - const size_t minfreespace, - const string &oldpath, - const string &newpath) +_rename(const Policy::Func::Ptr searchFunc, + const Policy::Func::Ptr actionFunc, + const vector &srcmounts, + const size_t minfreespace, + const string &oldpath, + const string &newpath) { int rv; int error; diff --git a/src/rmdir.cpp b/src/rmdir.cpp index 77890801..dd9e1abe 100644 --- a/src/rmdir.cpp +++ b/src/rmdir.cpp @@ -40,10 +40,10 @@ using mergerfs::Policy; static int -_rmdir(const Policy::FuncPtr actionFunc, - const vector &srcmounts, - const size_t minfreespace, - const string &fusepath) +_rmdir(const Policy::Func::Ptr actionFunc, + const vector &srcmounts, + const size_t minfreespace, + const string &fusepath) { int rv; int error; diff --git a/src/setxattr.cpp b/src/setxattr.cpp index ccdfda59..c2d5c870 100644 --- a/src/setxattr.cpp +++ b/src/setxattr.cpp @@ -240,14 +240,14 @@ _setxattr_controlfile(config::Config &config, static int -_setxattr(const Policy::FuncPtr actionFunc, - const vector &srcmounts, - const size_t minfreespace, - const string &fusepath, - const char *attrname, - const char *attrval, - const size_t attrvalsize, - const int flags) +_setxattr(const Policy::Func::Ptr actionFunc, + const vector &srcmounts, + const size_t minfreespace, + const string &fusepath, + const char *attrname, + const char *attrval, + const size_t attrvalsize, + const int flags) { #ifndef WITHOUT_XATTR int rv; diff --git a/src/symlink.cpp b/src/symlink.cpp index 18c97fa5..418310d0 100644 --- a/src/symlink.cpp +++ b/src/symlink.cpp @@ -40,11 +40,11 @@ using mergerfs::Policy; static int -_symlink(const Policy::FuncPtr createFunc, - const vector &srcmounts, - const size_t minfreespace, - const string &oldpath, - const string &newpath) +_symlink(const Policy::Func::Ptr createFunc, + const vector &srcmounts, + const size_t minfreespace, + const string &oldpath, + const string &newpath) { int rv; int error; diff --git a/src/truncate.cpp b/src/truncate.cpp index 17b0bd0c..70f0df6b 100644 --- a/src/truncate.cpp +++ b/src/truncate.cpp @@ -42,11 +42,11 @@ using mergerfs::Policy; static int -_truncate(const Policy::FuncPtr actionFunc, - const vector &srcmounts, - const size_t minfreespace, - const string &fusepath, - const off_t size) +_truncate(const Policy::Func::Ptr actionFunc, + const vector &srcmounts, + const size_t minfreespace, + const string &fusepath, + const off_t size) { int rv; int error; diff --git a/src/unlink.cpp b/src/unlink.cpp index 8c6e5c6b..e6965635 100644 --- a/src/unlink.cpp +++ b/src/unlink.cpp @@ -41,10 +41,10 @@ using mergerfs::Policy; static int -_unlink(const Policy::FuncPtr actionFunc, - const vector &srcmounts, - const size_t minfreespace, - const string &fusepath) +_unlink(const Policy::Func::Ptr actionFunc, + const vector &srcmounts, + const size_t minfreespace, + const string &fusepath) { int rv; int error; diff --git a/src/utimens.cpp b/src/utimens.cpp index 9eb82ac3..42f4bc99 100644 --- a/src/utimens.cpp +++ b/src/utimens.cpp @@ -42,11 +42,11 @@ using mergerfs::Policy; static int -_utimens(const Policy::FuncPtr actionFunc, - const vector &srcmounts, - const size_t minfreespace, - const string &fusepath, - const struct timespec ts[2]) +_utimens(const Policy::Func::Ptr actionFunc, + const vector &srcmounts, + const size_t minfreespace, + const string &fusepath, + const struct timespec ts[2]) { int rv; int error;