diff --git a/src/policy.hpp b/src/policy.hpp index 84b7a857..fe32e874 100644 --- a/src/policy.hpp +++ b/src/policy.hpp @@ -24,6 +24,11 @@ #include "fs.hpp" #include "category.hpp" +#define POLICY_SUCCESS 0 +#define POLICY_FAIL -1 +#define POLICY_SUCCEEDED(RV) ((RV) == POLICY_SUCCESS) +#define POLICY_FAILED(RV) ((RV) == POLICY_FAIL) + namespace mergerfs { class Policy diff --git a/src/policy_all.cpp b/src/policy_all.cpp index 3314e3c5..85314a04 100644 --- a/src/policy_all.cpp +++ b/src/policy_all.cpp @@ -24,6 +24,7 @@ #include "fs_path.hpp" #include "policy.hpp" +#include "success_fail.hpp" using std::string; using std::vector; @@ -46,28 +47,14 @@ _all(const vector &basepaths, fs::path::make(basepath,fusepath,fullpath); rv = ::lstat(fullpath.c_str(),&st); - if(rv == 0) + if(LSTAT_SUCCEEDED(rv)) paths.push_back(basepath); } if(paths.empty()) - return (errno=ENOENT,-1); + return (errno=ENOENT,POLICY_FAIL); - return 0; -} - -static -int -_all_create(const vector &basepaths, - vector &paths) -{ - if(basepaths.empty()) - return (errno=ENOENT,-1); - - for(size_t i = 0, ei = basepaths.size(); i != ei; i++) - paths.push_back(&basepaths[i]); - - return 0; + return POLICY_SUCCESS; } namespace mergerfs @@ -79,9 +66,9 @@ namespace mergerfs const size_t minfreespace, vector &paths) { - if(type == Category::Enum::create) - return _all_create(basepaths,paths); + const char *fp = + ((type == Category::Enum::create) ? "" : fusepath); - return _all(basepaths,fusepath,paths); + return _all(basepaths,fp,paths); } } diff --git a/src/policy_einval.cpp b/src/policy_einval.cpp index aa5bdd44..1f799916 100644 --- a/src/policy_einval.cpp +++ b/src/policy_einval.cpp @@ -33,6 +33,6 @@ namespace mergerfs const size_t minfreespace, vector &paths) { - return (errno=EINVAL,-1); + return (errno=EINVAL,POLICY_FAIL); } } diff --git a/src/policy_enosys.cpp b/src/policy_enosys.cpp index a85ed5fb..ba946ce3 100644 --- a/src/policy_enosys.cpp +++ b/src/policy_enosys.cpp @@ -33,6 +33,6 @@ namespace mergerfs const size_t minfreespace, vector &paths) { - return (errno=ENOSYS,-1); + return (errno=ENOSYS,POLICY_FAIL); } } diff --git a/src/policy_enotsup.cpp b/src/policy_enotsup.cpp index 8a2da928..450ea5b6 100644 --- a/src/policy_enotsup.cpp +++ b/src/policy_enotsup.cpp @@ -33,6 +33,6 @@ namespace mergerfs const size_t minfreespace, vector &paths) { - return (errno=ENOTSUP,-1); + return (errno=ENOTSUP,POLICY_FAIL); } } diff --git a/src/policy_eplfs.cpp b/src/policy_eplfs.cpp index 59624f61..3fde1e65 100644 --- a/src/policy_eplfs.cpp +++ b/src/policy_eplfs.cpp @@ -25,6 +25,7 @@ #include "fs_path.hpp" #include "policy.hpp" +#include "success_fail.hpp" using std::string; using std::vector; @@ -74,16 +75,16 @@ _eplfs(const Category::Enum::Type type, fs::path::make(basepath,fusepath,fullpath); rv = ::statvfs(fullpath.c_str(),&fsstats); - if(rv == 0) + if(STATVFS_SUCCEEDED(rv)) _calc_lfs(fsstats,basepath,minfreespace,eplfs,eplfsbasepath); } if(eplfsbasepath == NULL) - return -ENOENT; + return (errno=ENOENT,POLICY_FAIL); paths.push_back(eplfsbasepath); - return 0; + return POLICY_SUCCESS; } namespace mergerfs @@ -100,7 +101,7 @@ namespace mergerfs ((type == Category::Enum::create) ? minfreespace : 0); rv = _eplfs(type,basepaths,fusepath,minfs,paths); - if(rv != 0) + if(POLICY_FAILED(rv)) rv = Policy::Func::lfs(type,basepaths,fusepath,minfreespace,paths); return rv; diff --git a/src/policy_epmfs.cpp b/src/policy_epmfs.cpp index 42a76313..3d727fd0 100644 --- a/src/policy_epmfs.cpp +++ b/src/policy_epmfs.cpp @@ -25,6 +25,7 @@ #include "fs_path.hpp" #include "policy.hpp" +#include "success_fail.hpp" using std::string; using std::vector; @@ -51,46 +52,12 @@ _calc_mfs(const statvfs_t &fsstats, } } -static -int -_epmfs_create(const vector &basepaths, - const char *fusepath, - const size_t minfreespace, - vector &paths) -{ - int rv; - string fullpath; - statvfs_t fsstats; - fsblkcnt_t epmfs; - const string *epmfsbasepath; - - epmfs = 0; - epmfsbasepath = NULL; - for(size_t i = 0, ei = basepaths.size(); i != ei; i++) - { - const string *basepath = &basepaths[i]; - - fs::path::make(basepath,fusepath,fullpath); - - rv = ::statvfs(fullpath.c_str(),&fsstats); - if(rv == 0) - _calc_mfs(fsstats,basepath,minfreespace,epmfs,epmfsbasepath); - } - - if(epmfsbasepath == NULL) - return Policy::Func::mfs(Category::Enum::create,basepaths,fusepath,minfreespace,paths); - - paths.push_back(epmfsbasepath); - - return 0; -} - static int _epmfs(const vector &basepaths, const char *fusepath, + const size_t minfreespace, vector &paths) - { int rv; string fullpath; @@ -107,16 +74,16 @@ _epmfs(const vector &basepaths, fs::path::make(basepath,fusepath,fullpath); rv = ::statvfs(fullpath.c_str(),&fsstats); - if(rv == 0) - _calc_mfs(fsstats,basepath,0,epmfs,epmfsbasepath); + if(STATVFS_SUCCEEDED(rv)) + _calc_mfs(fsstats,basepath,minfreespace,epmfs,epmfsbasepath); } if(epmfsbasepath == NULL) - return (errno=ENOENT,-1); + return (errno=ENOENT,POLICY_FAIL); paths.push_back(epmfsbasepath); - return 0; + return POLICY_SUCCESS; } namespace mergerfs @@ -128,9 +95,14 @@ namespace mergerfs const size_t minfreespace, vector &paths) { - if(type == Category::Enum::create) - return _epmfs_create(basepaths,fusepath,minfreespace,paths); + int rv; + const size_t minfs = + ((type == Category::Enum::create) ? minfreespace : 0); + + rv = _epmfs(basepaths,fusepath,minfs,paths); + if(POLICY_FAILED(rv)) + rv = Policy::Func::mfs(type,basepaths,fusepath,minfreespace,paths); - return _epmfs(basepaths,fusepath,paths); + return rv; } } diff --git a/src/policy_erofs.cpp b/src/policy_erofs.cpp index 269cef50..3411f97f 100644 --- a/src/policy_erofs.cpp +++ b/src/policy_erofs.cpp @@ -33,6 +33,6 @@ namespace mergerfs const size_t minfreespace, vector &paths) { - return (errno=EROFS,-1); + return (errno=EROFS,POLICY_FAIL); } } diff --git a/src/policy_exdev.cpp b/src/policy_exdev.cpp index 1090545c..9be2ef2e 100644 --- a/src/policy_exdev.cpp +++ b/src/policy_exdev.cpp @@ -33,6 +33,6 @@ namespace mergerfs const size_t minfreespace, vector &paths) { - return (errno=EXDEV,-1); + return (errno=EXDEV,POLICY_FAIL); } } diff --git a/src/policy_ff.cpp b/src/policy_ff.cpp index c24656f1..eb75790d 100644 --- a/src/policy_ff.cpp +++ b/src/policy_ff.cpp @@ -24,6 +24,7 @@ #include "fs_path.hpp" #include "policy.hpp" +#include "success_fail.hpp" using std::string; using std::vector; @@ -46,29 +47,15 @@ _ff(const vector &basepaths, fs::path::make(basepath,fusepath,fullpath); rv = ::lstat(fullpath.c_str(),&st); - if(rv == -1) + if(LSTAT_FAILED(rv)) continue; paths.push_back(basepath); - return 0; + return POLICY_SUCCESS; } - return (errno=ENOENT,-1); -} - -static -int -_ff_create(const vector &basepaths, - const char *fusepath, - vector &paths) -{ - if(basepaths.empty()) - return (errno=ENOENT,-1); - - paths.push_back(&basepaths[0]); - - return 0; + return (errno=ENOENT,POLICY_FAIL); } namespace mergerfs @@ -80,9 +67,9 @@ namespace mergerfs const size_t minfreespace, vector &paths) { - if(type == Category::Enum::create) - return _ff_create(basepaths,fusepath,paths); + const char *fp = + ((type == Category::Enum::create) ? "" : fusepath); - return _ff(basepaths,fusepath,paths); + return _ff(basepaths,fp,paths); } } diff --git a/src/policy_ffwp.cpp b/src/policy_ffwp.cpp index 70d48e27..f5ad7746 100644 --- a/src/policy_ffwp.cpp +++ b/src/policy_ffwp.cpp @@ -24,6 +24,7 @@ #include "fs_path.hpp" #include "policy.hpp" +#include "success_fail.hpp" using std::string; using std::vector; @@ -48,10 +49,10 @@ _ffwp(const vector &basepaths, fs::path::make(basepath,fusepath,fullpath); rv = ::lstat(fullpath.c_str(),&st); - if(rv == 0) + if(LSTAT_SUCCEEDED(rv)) { paths.push_back(basepath); - return 0; + return POLICY_SUCCESS; } else if(errno == EACCES) { @@ -60,11 +61,11 @@ _ffwp(const vector &basepaths, } if(fallback == NULL) - return (errno=ENOENT,-1); + return (errno=ENOENT,POLICY_FAIL); paths.push_back(fallback); - return 0; + return POLICY_SUCCESS; } namespace mergerfs diff --git a/src/policy_fwfs.cpp b/src/policy_fwfs.cpp index 2cf09087..d41a4e56 100644 --- a/src/policy_fwfs.cpp +++ b/src/policy_fwfs.cpp @@ -22,6 +22,7 @@ #include "fs_path.hpp" #include "policy.hpp" +#include "success_fail.hpp" using std::string; using std::vector; @@ -31,44 +32,10 @@ using mergerfs::Category; static int -_fwfs_create(const Category::Enum::Type type, - const vector &basepaths, - const char *fusepath, - const size_t minfreespace, - vector &paths) -{ - int rv; - struct statvfs fsstats; - - for(size_t i = 0, size = basepaths.size(); i != size; i++) - { - const string &basepath = basepaths[i]; - - rv = ::statvfs(basepath.c_str(),&fsstats); - if(rv == 0) - { - fsblkcnt_t spaceavail; - - spaceavail = (fsstats.f_frsize * fsstats.f_bavail); - if(spaceavail < minfreespace) - continue; - - paths.push_back(&basepath); - - return 0; - } - } - - return Policy::Func::mfs(type,basepaths,fusepath,minfreespace,paths); -} - -static -int -_fwfs(const Category::Enum::Type type, - const vector &basepaths, - const char *fusepath, - const size_t minfreespace, - vector &paths) +_fwfs(const vector &basepaths, + const char *fusepath, + const size_t minfreespace, + vector &paths) { int rv; string fullpath; @@ -81,7 +48,7 @@ _fwfs(const Category::Enum::Type type, fs::path::make(basepath,fusepath,fullpath); rv = ::statvfs(fullpath.c_str(),&fsstats); - if(rv == 0) + if(STATVFS_SUCCEEDED(rv)) { fsblkcnt_t spaceavail; @@ -91,11 +58,11 @@ _fwfs(const Category::Enum::Type type, paths.push_back(basepath); - return 0; + return POLICY_SUCCESS; } } - return Policy::Func::mfs(type,basepaths,fusepath,minfreespace,paths); + return (errno=ENOENT,POLICY_FAIL); } namespace mergerfs @@ -107,9 +74,14 @@ namespace mergerfs const size_t minfreespace, vector &paths) { - if(type == Category::Enum::create) - return _fwfs_create(type,basepaths,fusepath,minfreespace,paths); + int rv; + const char *fp = + ((type == Category::Enum::create) ? "" : fusepath); + + rv = _fwfs(basepaths,fp,minfreespace,paths); + if(POLICY_FAILED(rv)) + rv = Policy::Func::mfs(type,basepaths,fusepath,minfreespace,paths); - return _fwfs(type,basepaths,fusepath,minfreespace,paths); + return rv; } } diff --git a/src/policy_invalid.cpp b/src/policy_invalid.cpp index cf9e5dc6..5af64b6a 100644 --- a/src/policy_invalid.cpp +++ b/src/policy_invalid.cpp @@ -34,6 +34,6 @@ namespace mergerfs const size_t minfreespace, vector &paths) { - return (errno=EINVAL,-1); + return (errno=EINVAL,POLICY_FAIL); } } diff --git a/src/policy_lfs.cpp b/src/policy_lfs.cpp index f92a2e90..0e5f6c20 100644 --- a/src/policy_lfs.cpp +++ b/src/policy_lfs.cpp @@ -25,6 +25,7 @@ #include "fs_path.hpp" #include "policy.hpp" +#include "success_fail.hpp" using std::string; using std::vector; @@ -33,63 +34,38 @@ using mergerfs::Policy; using mergerfs::Category; static -int -_lfs_create(const Category::Enum::Type type, - const vector &basepaths, - const char *fusepath, - const size_t minfreespace, - vector &paths) +void +_calc_lfs(const struct statvfs &fsstats, + const string *basepath, + const size_t minfreespace, + fsblkcnt_t &lfs, + const string *&lfsbasepath) { - int rv; - fsblkcnt_t lfs; - const string *lfsstr; - struct statvfs fsstats; + fsblkcnt_t spaceavail; - lfs = -1; - lfsstr = NULL; - for(size_t i = 0, ei = basepaths.size(); i != ei; i++) + spaceavail = (fsstats.f_frsize * fsstats.f_bavail); + if((spaceavail > minfreespace) && (spaceavail < lfs)) { - const string &basepath = basepaths[i]; - - rv = ::statvfs(basepath.c_str(),&fsstats); - if(rv == 0) - { - fsblkcnt_t spaceavail; - - spaceavail = (fsstats.f_frsize * fsstats.f_bavail); - if((spaceavail > minfreespace) && - (spaceavail < lfs)) - { - lfs = spaceavail; - lfsstr = &basepath; - } - } + lfs = spaceavail; + lfsbasepath = basepath; } - - if(lfsstr == NULL) - return Policy::Func::mfs(type,basepaths,fusepath,minfreespace,paths); - - paths.push_back(lfsstr); - - return 0; } static int -_lfs(const Category::Enum::Type type, - const vector &basepaths, - const char *fusepath, - const size_t minfreespace, - vector &paths) +_lfs(const vector &basepaths, + const char *fusepath, + const size_t minfreespace, + vector &paths) { int rv; string fullpath; struct statvfs fsstats; fsblkcnt_t lfs; - const string *lfsstr; + const string *lfsbasepath; lfs = -1; - lfsstr = NULL; + lfsbasepath = NULL; for(size_t i = 0, ei = basepaths.size(); i != ei; i++) { const string *basepath = &basepaths[i]; @@ -97,26 +73,16 @@ _lfs(const Category::Enum::Type type, fs::path::make(basepath,fusepath,fullpath); rv = ::statvfs(fullpath.c_str(),&fsstats); - if(rv == 0) - { - fsblkcnt_t spaceavail; - - spaceavail = (fsstats.f_frsize * fsstats.f_bavail); - if((spaceavail > minfreespace) && - (spaceavail < lfs)) - { - lfs = spaceavail; - lfsstr = basepath; - } - } + if(STATVFS_SUCCEEDED(rv)) + _calc_lfs(fsstats,basepath,minfreespace,lfs,lfsbasepath); } - if(lfsstr == NULL) - return Policy::Func::mfs(type,basepaths,fusepath,minfreespace,paths); + if(lfsbasepath == NULL) + return (errno=ENOENT,POLICY_FAIL); - paths.push_back(lfsstr); + paths.push_back(lfsbasepath); - return 0; + return POLICY_SUCCESS; } namespace mergerfs @@ -128,9 +94,14 @@ namespace mergerfs const size_t minfreespace, vector &paths) { - if(type == Category::Enum::create) - return _lfs_create(type,basepaths,fusepath,minfreespace,paths); + int rv; + const char *fp = + ((type == Category::Enum::create) ? "" : fusepath); + + rv = _lfs(basepaths,fp,minfreespace,paths); + if(POLICY_FAILED(rv)) + rv = Policy::Func::mfs(type,basepaths,fusepath,minfreespace,paths); - return _lfs(type,basepaths,fusepath,minfreespace,paths); + return rv; } } diff --git a/src/policy_mfs.cpp b/src/policy_mfs.cpp index ff87118c..3773e412 100644 --- a/src/policy_mfs.cpp +++ b/src/policy_mfs.cpp @@ -22,48 +22,27 @@ #include "fs_path.hpp" #include "policy.hpp" +#include "success_fail.hpp" using std::string; using std::vector; using std::size_t; static -int -_mfs_create(const vector &basepaths, - const char *fusepath, - vector &paths) +void +_calc_mfs(const struct statvfs &fsstats, + const string *basepath, + fsblkcnt_t &mfs, + const string *&mfsbasepath) { - int rv; - struct statvfs fsstats; - fsblkcnt_t mfs; - const string *mfsstr; + fsblkcnt_t spaceavail; - mfs = 0; - mfsstr = NULL; - for(size_t i = 0, ei = basepaths.size(); i != ei; i++) + spaceavail = (fsstats.f_frsize * fsstats.f_bavail); + if(spaceavail > mfs) { - const string &basepath = basepaths[i]; - - rv = ::statvfs(basepath.c_str(),&fsstats); - if(rv == 0) - { - fsblkcnt_t spaceavail; - - spaceavail = (fsstats.f_frsize * fsstats.f_bavail); - if(spaceavail > mfs) - { - mfs = spaceavail; - mfsstr = &basepath; - } - } + mfs = spaceavail; + mfsbasepath = basepath; } - - if(mfsstr == NULL) - return (errno=ENOENT,-1); - - paths.push_back(mfsstr); - - return 0; } static @@ -76,10 +55,10 @@ _mfs(const vector &basepaths, string fullpath; struct statvfs fsstats; fsblkcnt_t mfs; - const string *mfsstr; + const string *mfsbasepath; mfs = 0; - mfsstr = NULL; + mfsbasepath = NULL; for(size_t i = 0, ei = basepaths.size(); i != ei; i++) { const string *basepath = &basepaths[i]; @@ -87,25 +66,16 @@ _mfs(const vector &basepaths, fs::path::make(basepath,fusepath,fullpath); rv = ::statvfs(fullpath.c_str(),&fsstats); - if(rv == 0) - { - fsblkcnt_t spaceavail; - - spaceavail = (fsstats.f_frsize * fsstats.f_bavail); - if(spaceavail > mfs) - { - mfs = spaceavail; - mfsstr = basepath; - } - } + if(STATVFS_SUCCEEDED(rv)) + _calc_mfs(fsstats,basepath,mfs,mfsbasepath); } - if(mfsstr == NULL) - return (errno=ENOENT,-1); + if(mfsbasepath == NULL) + return (errno=ENOENT,POLICY_FAIL); - paths.push_back(mfsstr); + paths.push_back(mfsbasepath); - return 0; + return POLICY_SUCCESS; } namespace mergerfs @@ -117,9 +87,9 @@ namespace mergerfs const size_t minfreespace, vector &paths) { - if(type == Category::Enum::create) - return _mfs_create(basepaths,fusepath,paths); + const char *fp = + ((type == Category::Enum::create) ? "" : fusepath); - return _mfs(basepaths,fusepath,paths); + return _mfs(basepaths,fp,paths); } } diff --git a/src/policy_newest.cpp b/src/policy_newest.cpp index 716a6110..9cbf3692 100644 --- a/src/policy_newest.cpp +++ b/src/policy_newest.cpp @@ -25,6 +25,7 @@ #include "fs_path.hpp" #include "policy.hpp" +#include "success_fail.hpp" using std::string; using std::vector; @@ -40,10 +41,10 @@ _newest(const vector &basepaths, struct stat st; string fullpath; time_t newest; - const string *neweststr; + const string *newestbasepath; newest = std::numeric_limits::min(); - neweststr = NULL; + newestbasepath = NULL; for(size_t i = 0, ei = basepaths.size(); i != ei; i++) { const string *basepath = &basepaths[i]; @@ -51,19 +52,19 @@ _newest(const vector &basepaths, fs::path::make(basepath,fusepath,fullpath); rv = ::lstat(fullpath.c_str(),&st); - if(rv == 0 && st.st_mtime >= newest) + if(LSTAT_SUCCEEDED(rv) && (st.st_mtime >= newest)) { - newest = st.st_mtime; - neweststr = basepath; + newest = st.st_mtime; + newestbasepath = basepath; } } - if(neweststr == NULL) - return (errno=ENOENT,-1); + if(newestbasepath == NULL) + return (errno=ENOENT,POLICY_FAIL); - paths.push_back(neweststr); + paths.push_back(newestbasepath); - return 0; + return POLICY_SUCCESS; } namespace mergerfs diff --git a/src/policy_rand.cpp b/src/policy_rand.cpp index 62b02637..2ae770d2 100644 --- a/src/policy_rand.cpp +++ b/src/policy_rand.cpp @@ -21,6 +21,7 @@ #include #include "policy.hpp" +#include "success_fail.hpp" using std::string; using std::vector; @@ -38,11 +39,9 @@ namespace mergerfs int rv; rv = Policy::Func::all(type,basepaths,fusepath,minfreespace,paths); - if(rv == -1) - return -1; + if(POLICY_SUCCEEDED(rv)) + std::random_shuffle(paths.begin(),paths.end()); - std::random_shuffle(paths.begin(),paths.end()); - - return 0; + return rv; } } diff --git a/src/success_fail.hpp b/src/success_fail.hpp new file mode 100644 index 00000000..9809f37a --- /dev/null +++ b/src/success_fail.hpp @@ -0,0 +1,32 @@ +/* + Copyright (c) 2016, Antonio SJ Musumeci + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#ifndef __MERGERFS_SUCCESS_FAIL_HPP__ + +#define STATVFS_SUCCESS 0 +#define STATVFS_SUCCEEDED(RV) ((RV) == STATVFS_SUCCESS) + +#define STAT_SUCCESS 0 +#define STAT_SUCCEEDED(RV) ((RV) == STAT_SUCCESS) +#define STAT_FAIL -1 +#define STAT_FAILED(RV) ((RV) == STAT_FAIL) + +#define LSTAT_SUCCESS 0 +#define LSTAT_SUCCEEDED(RV) ((RV) == LSTAT_SUCCESS) +#define LSTAT_FAIL -1 +#define LSTAT_FAILED(RV) ((RV) == LSTAT_FAIL) + +#endif /*__MERGERFS_SUCCESS_FAIL_HPP__ */