From 6086620e23dff65c35c83fd7892b753c64c354d1 Mon Sep 17 00:00:00 2001 From: Antonio SJ Musumeci Date: Fri, 29 Jan 2016 16:54:39 -0500 Subject: [PATCH] use references to srcmounts rather than copies --- src/access.cpp | 11 +-- src/chmod.cpp | 53 ++++++++++---- src/chown.cpp | 55 ++++++++++---- src/create.cpp | 68 +++++++++++------ src/fallocate.cpp | 4 - src/flush.cpp | 4 +- src/fs.cpp | 20 ++--- src/fs.hpp | 4 +- src/fs_clonepath.cpp | 11 +-- src/fs_clonepath.hpp | 2 +- src/fs_movefile.cpp | 5 +- src/fs_path.cpp | 62 ++-------------- src/fs_path.hpp | 35 +++------ src/getattr.cpp | 11 +-- src/getxattr.cpp | 24 +++--- src/ioctl.cpp | 18 +++-- src/link.cpp | 163 ++++++++++++++++++++++++----------------- src/listxattr.cpp | 21 +++--- src/mkdir.cpp | 85 ++++++++++++++------- src/mknod.cpp | 89 +++++++++++++++------- src/open.cpp | 38 ++++++---- src/policy.hpp | 48 +++++------- src/policy_all.cpp | 19 ++--- src/policy_einval.cpp | 4 +- src/policy_enosys.cpp | 4 +- src/policy_enotsup.cpp | 4 +- src/policy_epmfs.cpp | 56 +++++++------- src/policy_erofs.cpp | 4 +- src/policy_exdev.cpp | 4 +- src/policy_ff.cpp | 29 ++++---- src/policy_ffwp.cpp | 23 +++--- src/policy_fwfs.cpp | 30 ++++---- src/policy_invalid.cpp | 4 +- src/policy_lfs.cpp | 40 +++++----- src/policy_mfs.cpp | 40 +++++----- src/policy_newest.cpp | 26 ++++--- src/policy_rand.cpp | 4 +- src/readdir.cpp | 5 +- src/readlink.cpp | 37 +++++++--- src/removexattr.cpp | 64 +++++++++++----- src/rename.cpp | 114 ++++++++++++++-------------- src/rmdir.cpp | 52 +++++++++---- src/setxattr.cpp | 72 +++++++++++++----- src/str.cpp | 10 ++- src/str.hpp | 4 + src/symlink.cpp | 88 +++++++++++++++------- src/truncate.cpp | 53 ++++++++++---- src/unlink.cpp | 51 +++++++++---- src/utimens.cpp | 53 ++++++++++---- 49 files changed, 1029 insertions(+), 696 deletions(-) diff --git a/src/access.cpp b/src/access.cpp index 5d23057c..cd2e9c17 100644 --- a/src/access.cpp +++ b/src/access.cpp @@ -35,19 +35,20 @@ int _access(Policy::Func::Search searchFunc, const vector &srcmounts, const size_t minfreespace, - const string &fusepath, + const char *fusepath, const int mask) { int rv; - string path; + string fullpath; + vector basepaths; - rv = searchFunc(srcmounts,fusepath,minfreespace,path); + rv = searchFunc(srcmounts,fusepath,minfreespace,basepaths); if(rv == -1) return -errno; - fs::path::append(path,fusepath); + fs::path::make(basepaths[0],fusepath,fullpath); - rv = ::eaccess(path.c_str(),mask); + rv = ::eaccess(fullpath.c_str(),mask); return ((rv == -1) ? -errno : 0); } diff --git a/src/chmod.cpp b/src/chmod.cpp index 2b9a06f6..a25c960f 100644 --- a/src/chmod.cpp +++ b/src/chmod.cpp @@ -30,33 +30,56 @@ using std::string; using std::vector; using mergerfs::Policy; +static +int +_chmod_loop_core(const string *basepath, + const char *fusepath, + const mode_t mode, + const int error) +{ + int rv; + string fullpath; + + fs::path::make(basepath,fusepath,fullpath); + + rv = ::chmod(fullpath.c_str(),mode); + + return calc_error(rv,error,errno); +} + +static +int +_chmod_loop(const vector &basepaths, + const char *fusepath, + const mode_t mode) +{ + int error; + + error = -1; + for(size_t i = 0, ei = basepaths.size(); i != ei; i++) + { + error = _chmod_loop_core(basepaths[i],fusepath,mode,error); + } + + return -error; +} + static int _chmod(Policy::Func::Action actionFunc, const vector &srcmounts, const size_t minfreespace, - const string &fusepath, + const char *fusepath, const mode_t mode) { int rv; - int error; - vector paths; + vector basepaths; - rv = actionFunc(srcmounts,fusepath,minfreespace,paths); + rv = actionFunc(srcmounts,fusepath,minfreespace,basepaths); if(rv == -1) return -errno; - error = -1; - for(size_t i = 0, ei = paths.size(); i != ei; i++) - { - fs::path::append(paths[i],fusepath); - - rv = ::chmod(paths[i].c_str(),mode); - - error = calc_error(rv,error,errno); - } - - return -error; + return _chmod_loop(basepaths,fusepath,mode); } namespace mergerfs diff --git a/src/chown.cpp b/src/chown.cpp index ffa714c1..dec28c59 100644 --- a/src/chown.cpp +++ b/src/chown.cpp @@ -32,34 +32,59 @@ using std::vector; using mergerfs::Policy; using mergerfs::Config; +static +int +_chown_loop_core(const string *basepath, + const char *fusepath, + const uid_t uid, + const gid_t gid, + const int error) +{ + int rv; + string fullpath; + + fs::path::make(basepath,fusepath,fullpath); + + rv = ::lchown(fullpath.c_str(),uid,gid); + + return calc_error(rv,error,errno); +} + +static +int +_chown_loop(const vector &basepaths, + const char *fusepath, + const uid_t uid, + const gid_t gid) +{ + int error; + + error = -1; + for(size_t i = 0, ei = basepaths.size(); i != ei; i++) + { + error = _chown_loop_core(basepaths[i],fusepath,uid,gid,error); + } + + return -error; +} + static int _chown(Policy::Func::Action actionFunc, const vector &srcmounts, const size_t minfreespace, - const string &fusepath, + const char *fusepath, const uid_t uid, const gid_t gid) { int rv; - int error; - vector paths; + vector basepaths; - rv = actionFunc(srcmounts,fusepath,minfreespace,paths); + rv = actionFunc(srcmounts,fusepath,minfreespace,basepaths); if(rv == -1) return -errno; - error = -1; - for(size_t i = 0, ei = paths.size(); i != ei; i++) - { - fs::path::append(paths[i],fusepath); - - rv = ::lchown(paths[i].c_str(),uid,gid); - - error = calc_error(rv,error,errno); - } - - return -error; + return _chown_loop(basepaths,fusepath,uid,gid); } namespace mergerfs diff --git a/src/create.cpp b/src/create.cpp index 298d3793..a1e2455c 100644 --- a/src/create.cpp +++ b/src/create.cpp @@ -36,47 +36,69 @@ using std::vector; using mergerfs::Policy; using namespace mergerfs; +static +int +_create_core(const string &existingpath, + const string &createpath, + const char *fusepath, + const char *fusedirpath, + const mode_t mode, + const int flags, + uint64_t &fh) +{ + int fd; + string fullpath; + + if(createpath != existingpath) + { + const ugid::SetRootGuard ugidGuard; + fs::clonepath(existingpath,createpath,fusedirpath); + } + + fs::path::make(&createpath,fusepath,fullpath); + + fd = ::open(fullpath.c_str(),flags,mode); + if(fd == -1) + return -errno; + + fh = reinterpret_cast(new FileInfo(fd)); + + return 0; +} + static int _create(Policy::Func::Search searchFunc, Policy::Func::Create createFunc, const vector &srcmounts, const size_t minfreespace, - const string &fusepath, + const char *fusepath, const mode_t mode, const int flags, uint64_t &fh) { - int fd; int rv; - string dirname; - vector createpath; - vector existingpath; + string fullpath; + string fusedirpath; + const char *fusedirpathcstr; + vector createpaths; + vector existingpaths; - dirname = fs::path::dirname(fusepath); - rv = searchFunc(srcmounts,dirname,minfreespace,existingpath); - if(rv == -1) - return -errno; + fusedirpath = fusepath; + fs::path::dirname(fusedirpath); + fusedirpathcstr = fusedirpath.c_str(); - rv = createFunc(srcmounts,dirname,minfreespace,createpath); + rv = searchFunc(srcmounts,fusedirpathcstr,minfreespace,existingpaths); if(rv == -1) return -errno; - if(createpath[0] != existingpath[0]) - { - const ugid::SetRootGuard ugidGuard; - fs::clonepath(existingpath[0],createpath[0],dirname); - } - - fs::path::append(createpath[0],fusepath); - - fd = ::open(createpath[0].c_str(),flags,mode); - if(fd == -1) + rv = createFunc(srcmounts,fusedirpathcstr,minfreespace,createpaths); + if(rv == -1) return -errno; - fh = reinterpret_cast(new FileInfo(fd)); - - return 0; + return _create_core(*existingpaths[0],*createpaths[0], + fusepath,fusedirpathcstr, + mode,flags,fh); } namespace mergerfs diff --git a/src/fallocate.cpp b/src/fallocate.cpp index c6f6b774..5026daf3 100644 --- a/src/fallocate.cpp +++ b/src/fallocate.cpp @@ -16,10 +16,6 @@ #if FALLOCATE -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - #include #include diff --git a/src/flush.cpp b/src/flush.cpp index 98b30e03..0305e2aa 100644 --- a/src/flush.cpp +++ b/src/flush.cpp @@ -27,11 +27,11 @@ _flush(const int fd) { int rv; - rv = dup(fd); + rv = ::dup(fd); if(rv == -1) errno = EIO; else - rv = close(rv); + rv = ::close(rv); return ((rv == -1) ? -errno : 0); } diff --git a/src/fs.cpp b/src/fs.cpp index 5fc3ab8e..27a1775b 100644 --- a/src/fs.cpp +++ b/src/fs.cpp @@ -40,16 +40,16 @@ namespace fs { void findallfiles(const vector &srcmounts, - const string &fusepath, + const char *fusepath, vector &paths) { + int rv; + string fullpath; + struct stat st; + for(size_t i = 0, ei = srcmounts.size(); i != ei; i++) { - int rv; - string fullpath; - struct stat st; - - fs::path::make(srcmounts[i],fusepath,fullpath); + fs::path::make(&srcmounts[i],fusepath,fullpath); rv = ::lstat(fullpath.c_str(),&st); if(rv == 0) @@ -59,12 +59,12 @@ namespace fs int findonfs(const vector &srcmounts, - const string &fusepath, + const char *fusepath, const int fd, string &basepath) { int rv; - string tmppath; + string fullpath; unsigned long fsid; struct statvfs buf; @@ -75,9 +75,9 @@ namespace fs fsid = buf.f_fsid; for(int i = 0, ei = srcmounts.size(); i != ei; i++) { - fs::path::make(srcmounts[i],fusepath,tmppath); + fs::path::make(&srcmounts[i],fusepath,fullpath); - rv = ::statvfs(tmppath.c_str(),&buf); + rv = ::statvfs(fullpath.c_str(),&buf); if(rv == -1) continue; diff --git a/src/fs.hpp b/src/fs.hpp index ea0a7c26..31933201 100644 --- a/src/fs.hpp +++ b/src/fs.hpp @@ -27,11 +27,11 @@ namespace fs using std::vector; void findallfiles(const vector &srcmounts, - const string &fusepath, + const char *fusepath, vector &paths); int findonfs(const vector &srcmounts, - const string &fusepath, + const char *fusepath, const int fd, string &basepath); diff --git a/src/fs_clonepath.cpp b/src/fs_clonepath.cpp index 652acf4a..09baf04c 100644 --- a/src/fs_clonepath.cpp +++ b/src/fs_clonepath.cpp @@ -49,7 +49,7 @@ namespace fs int clonepath(const string &fromsrc, const string &tosrc, - const string &relative) + const char *relative) { int rv; struct stat st; @@ -57,22 +57,23 @@ namespace fs string frompath; string dirname; - dirname = fs::path::dirname(relative); + dirname = relative; + fs::path::dirname(dirname); if(!dirname.empty()) { - rv = clonepath(fromsrc,tosrc,dirname); + rv = clonepath(fromsrc,tosrc,dirname.c_str()); if(rv == -1) return -1; } - fs::path::make(fromsrc,relative,frompath); + fs::path::make(&fromsrc,relative,frompath); rv = ::stat(frompath.c_str(),&st); if(rv == -1) return -1; else if(!S_ISDIR(st.st_mode)) return (errno = ENOTDIR,-1); - fs::path::make(tosrc,relative,topath); + fs::path::make(&tosrc,relative,topath); rv = ::mkdir(topath.c_str(),st.st_mode); if(rv == -1) { diff --git a/src/fs_clonepath.hpp b/src/fs_clonepath.hpp index 4f4e1750..007277f9 100644 --- a/src/fs_clonepath.hpp +++ b/src/fs_clonepath.hpp @@ -20,5 +20,5 @@ namespace fs { int clonepath(const std::string &from, const std::string &to, - const std::string &relative); + const char *relative); } diff --git a/src/fs_movefile.cpp b/src/fs_movefile.cpp index 13793b68..6f1589c0 100644 --- a/src/fs_movefile.cpp +++ b/src/fs_movefile.cpp @@ -66,8 +66,9 @@ namespace fs if(rv == -1) return -1; - fusedir = fs::path::dirname(fusepath); - rv = fs::clonepath(fdin_path,fdout_path,fusedir); + fusedir = fusepath; + fs::path::dirname(fusedir); + rv = fs::clonepath(fdin_path,fdout_path,fusedir.c_str()); if(rv == -1) return -1; diff --git a/src/fs_path.cpp b/src/fs_path.cpp index d6970902..e707dcb3 100644 --- a/src/fs_path.cpp +++ b/src/fs_path.cpp @@ -29,15 +29,14 @@ namespace fs { namespace path { - string - dirname(const string &path) + void + dirname(string &path) { - string parent = path; string::reverse_iterator i; string::reverse_iterator bi; - bi = parent.rend(); - i = parent.rbegin(); + bi = path.rend(); + i = path.rbegin(); while(*i == '/' && i != bi) i++; @@ -47,9 +46,7 @@ namespace fs while(*i == '/' && i != bi) i++; - parent.erase(i.base(),parent.end()); - - return parent; + path.erase(i.base(),path.end()); } string @@ -57,54 +54,5 @@ namespace fs { return path.substr(path.find_last_of('/')+1); } - - bool - is_empty(const string &path) - { - DIR *dir; - struct dirent *de; - - dir = ::opendir(path.c_str()); - if(!dir) - return false; - - while((de = ::readdir(dir))) - { - const char *d_name = de->d_name; - - if(d_name[0] == '.' && - ((d_name[1] == '\0') || - (d_name[1] == '.' && d_name[2] == '\0'))) - continue; - - ::closedir(dir); - - return false; - } - - ::closedir(dir); - - return true; - } - - bool - exists(const vector &paths, - const string &fusepath) - { - for(size_t i = 0, ei = paths.size(); i != ei; i++) - { - int rv; - string path; - struct stat st; - - fs::path::make(paths[i],fusepath,path); - - rv = ::lstat(path.c_str(),&st); - if(rv == 0) - return true; - } - - return false; - } } } diff --git a/src/fs_path.hpp b/src/fs_path.hpp index b3a5af65..9a79c3be 100644 --- a/src/fs_path.hpp +++ b/src/fs_path.hpp @@ -25,42 +25,27 @@ namespace fs namespace path { using std::string; - using std::vector; - string dirname(const string &path); - string basename(const string &path); - - bool is_empty(const string &path); - - bool exists(vector::const_iterator begin, - vector::const_iterator end, - const string &fusepath); - bool exists(const vector &srcmounts, - const string &fusepath); + void dirname(string &path); - inline - string - make(const string &base, - const string &suffix) - { - return base + suffix; - } + string basename(const string &path); inline void - make(const string &base, - const string &suffix, - string &output) + append(string &base, + const char *suffix) { - output = base + suffix; + base += suffix; } inline void - append(string &base, - const string &suffix) + make(const string *base, + const char *suffix, + string &output) { - base += suffix; + output = *base; + output += suffix; } } }; diff --git a/src/getattr.cpp b/src/getattr.cpp index 6cde7f64..7df15af3 100644 --- a/src/getattr.cpp +++ b/src/getattr.cpp @@ -63,19 +63,20 @@ int _getattr(Policy::Func::Search searchFunc, const vector &srcmounts, const size_t minfreespace, - const string &fusepath, + const char *fusepath, struct stat &buf) { int rv; - vector path; + string fullpath; + vector basepaths; - rv = searchFunc(srcmounts,fusepath,minfreespace,path); + rv = searchFunc(srcmounts,fusepath,minfreespace,basepaths); if(rv == -1) return -errno; - fs::path::append(path[0],fusepath); + fs::path::make(basepaths[0],fusepath,fullpath); - rv = ::lstat(path[0].c_str(),&buf); + rv = ::lstat(fullpath.c_str(),&buf); return ((rv == -1) ? -errno : 0); } diff --git a/src/getxattr.cpp b/src/getxattr.cpp index 46ae37ca..94094225 100644 --- a/src/getxattr.cpp +++ b/src/getxattr.cpp @@ -43,14 +43,14 @@ using namespace mergerfs; static int _lgetxattr(const string &path, - const string &name, + const char *attrname, void *value, const size_t size) { #ifndef WITHOUT_XATTR int rv; - rv = ::lgetxattr(path.c_str(),name.c_str(),value,size); + rv = ::lgetxattr(path.c_str(),attrname,value,size); return ((rv == -1) ? -errno : rv); #else @@ -161,7 +161,7 @@ _getxattr_pid(string &attrvalue) static int _getxattr_controlfile(const Config &config, - const string &attrname, + const char *attrname, char *buf, const size_t count) { @@ -236,7 +236,7 @@ _getxattr_from_string(char *destbuf, static int _getxattr_user_mergerfs_allpaths(const vector &srcmounts, - const string &fusepath, + const char *fusepath, char *buf, const size_t count) { @@ -253,10 +253,10 @@ _getxattr_user_mergerfs_allpaths(const vector &srcmounts, static int _getxattr_user_mergerfs(const string &basepath, - const string &fusepath, + const char *fusepath, const string &fullpath, const vector &srcmounts, - const string &attrname, + const char *attrname, char *buf, const size_t count) { @@ -281,23 +281,23 @@ int _getxattr(Policy::Func::Search searchFunc, const vector &srcmounts, const size_t minfreespace, - const string &fusepath, - const string &attrname, + const char *fusepath, + const char *attrname, char *buf, const size_t count) { int rv; string fullpath; - vector basepath; + vector basepaths; - rv = searchFunc(srcmounts,fusepath,minfreespace,basepath); + rv = searchFunc(srcmounts,fusepath,minfreespace,basepaths); if(rv == -1) return -errno; - fs::path::make(basepath[0],fusepath,fullpath); + fs::path::make(basepaths[0],fusepath,fullpath); if(str::isprefix(attrname,"user.mergerfs.")) - rv = _getxattr_user_mergerfs(basepath[0],fusepath,fullpath,srcmounts,attrname,buf,count); + rv = _getxattr_user_mergerfs(*basepaths[0],fusepath,fullpath,srcmounts,attrname,buf,count); else rv = _lgetxattr(fullpath,attrname,buf,count); diff --git a/src/ioctl.cpp b/src/ioctl.cpp index 81eeda73..4b35b1dd 100644 --- a/src/ioctl.cpp +++ b/src/ioctl.cpp @@ -61,21 +61,23 @@ int _ioctl_dir_base(Policy::Func::Search searchFunc, const vector &srcmounts, const size_t minfreespace, - const string &fusepath, + const char *fusepath, const int cmd, void *data) { int fd; int rv; - vector path; + string fullpath; + vector basepaths; - rv = searchFunc(srcmounts,fusepath,minfreespace,path); + rv = searchFunc(srcmounts,fusepath,minfreespace,basepaths); if(rv == -1) return -errno; - fs::path::append(path[0],fusepath); + fs::path::make(basepaths[0],fusepath,fullpath); - fd = ::open(path[0].c_str(),O_RDWR|O_NOATIME|O_DIRECTORY); + const int flags = O_RDWR | O_NOATIME | O_DIRECTORY; + fd = ::open(fullpath.c_str(),flags); if(fd == -1) return -errno; @@ -88,9 +90,9 @@ _ioctl_dir_base(Policy::Func::Search searchFunc, static int -_ioctl_dir(const string &fusepath, - const int cmd, - void *data) +_ioctl_dir(const char *fusepath, + const int cmd, + void *data) { const fuse_context *fc = fuse_get_context(); const Config &config = Config::get(fc); diff --git a/src/link.cpp b/src/link.cpp index d701b5f8..e5b32b34 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -36,12 +36,12 @@ using namespace mergerfs; static int -_link_create_path_one(const string &oldbasepath, - const string &newbasepath, - const string &oldfusepath, - const string &newfusepath, - const string &newfusedirpath, - const int error) +_link_create_path_core(const string &oldbasepath, + const string &newbasepath, + const char *oldfusepath, + const char *newfusepath, + const string &newfusedirpath, + const int error) { int rv; string oldfullpath; @@ -50,53 +50,66 @@ _link_create_path_one(const string &oldbasepath, if(oldbasepath != newbasepath) { const ugid::SetRootGuard ugidGuard; - fs::clonepath(newbasepath,oldbasepath,newfusedirpath); + fs::clonepath(newbasepath,oldbasepath,newfusedirpath.c_str()); } - fs::path::make(oldbasepath,oldfusepath,oldfullpath); - fs::path::make(oldbasepath,newfusepath,newfullpath); + fs::path::make(&oldbasepath,oldfusepath,oldfullpath); + fs::path::make(&oldbasepath,newfusepath,newfullpath); rv = ::link(oldfullpath.c_str(),newfullpath.c_str()); return calc_error(rv,error,errno); } +static +int +_link_create_path_loop(const vector &oldbasepaths, + const string &newbasepath, + const char *oldfusepath, + const char *newfusepath, + const string &newfusedirpath) +{ + int error; + + error = -1; + for(size_t i = 0, ei = oldbasepaths.size(); i != ei; i++) + { + error = _link_create_path_core(*oldbasepaths[i],newbasepath, + oldfusepath,newfusepath, + newfusedirpath, + error); + } + + return -error; +} + static int _link_create_path(Policy::Func::Search searchFunc, Policy::Func::Action actionFunc, const vector &srcmounts, const size_t minfreespace, - const string &oldfusepath, - const string &newfusepath) + const char *oldfusepath, + const char *newfusepath) { int rv; - int error; - string newbasepath; - vector toremove; - vector oldbasepaths; + string newfusedirpath; + vector oldbasepaths; + vector newbasepaths; rv = actionFunc(srcmounts,oldfusepath,minfreespace,oldbasepaths); if(rv == -1) return -errno; - const string newfusedirpath = fs::path::dirname(newfusepath); - rv = searchFunc(srcmounts,newfusedirpath,minfreespace,newbasepath); + newfusedirpath = newfusepath; + fs::path::dirname(newfusedirpath); + rv = searchFunc(srcmounts,newfusedirpath.c_str(),minfreespace,newbasepaths); if(rv == -1) return -errno; - error = -1; - for(size_t i = 0, ei = oldbasepaths.size(); i != ei; i++) - { - const string &oldbasepath = oldbasepaths[i]; - - error = _link_create_path_one(oldbasepath,newbasepath, - oldfusepath,newfusepath, - newfusedirpath, - error); - } - - return -error; + return _link_create_path_loop(oldbasepaths,*newbasepaths[0], + oldfusepath,newfusepath, + newfusedirpath); } static @@ -106,25 +119,28 @@ _clonepath_if_would_create(Policy::Func::Search searchFunc, const vector &srcmounts, const size_t minfreespace, const string &oldbasepath, - const string &oldfusepath, - const string &newfusepath) + const char *oldfusepath, + const char *newfusepath) { int rv; - string newbasepath; string newfusedirpath; + const char *newfusedirpathcstr; + vector newbasepath; - newfusedirpath = fs::path::dirname(newfusepath); + newfusedirpath = newfusepath; + fs::path::dirname(newfusedirpath); + newfusedirpathcstr = newfusedirpath.c_str(); - rv = createFunc(srcmounts,newfusedirpath,minfreespace,newbasepath); + rv = createFunc(srcmounts,newfusedirpathcstr,minfreespace,newbasepath); if(rv != -1) { - if(oldbasepath == newbasepath) + if(oldbasepath == *newbasepath[0]) { - rv = searchFunc(srcmounts,newfusedirpath,minfreespace,newbasepath); + rv = searchFunc(srcmounts,newfusedirpathcstr,minfreespace,newbasepath); if(rv != -1) { const ugid::SetRootGuard ugidGuard; - fs::clonepath(newbasepath,oldbasepath,newfusedirpath); + fs::clonepath(*newbasepath[0],oldbasepath,newfusedirpathcstr); } } else @@ -139,28 +155,29 @@ _clonepath_if_would_create(Policy::Func::Search searchFunc, static int -_link_preserve_path_one(Policy::Func::Search searchFunc, - Policy::Func::Create createFunc, - const vector &srcmounts, - const size_t minfreespace, - const string &oldbasepath, - const string &oldfusepath, - const string &newfusepath, - const int error) +_link_preserve_path_core(Policy::Func::Search searchFunc, + Policy::Func::Create createFunc, + const vector &srcmounts, + const size_t minfreespace, + const string &oldbasepath, + const char *oldfusepath, + const char *newfusepath, + const int error) { int rv; string oldfullpath; string newfullpath; - fs::path::make(oldbasepath,oldfusepath,oldfullpath); - fs::path::make(oldbasepath,newfusepath,newfullpath); + fs::path::make(&oldbasepath,oldfusepath,oldfullpath); + fs::path::make(&oldbasepath,newfusepath,newfullpath); rv = ::link(oldfullpath.c_str(),newfullpath.c_str()); if((rv == -1) && (errno == ENOENT)) { rv = _clonepath_if_would_create(searchFunc,createFunc, srcmounts,minfreespace, - oldbasepath,oldfusepath,newfusepath); + oldbasepath, + oldfusepath,newfusepath); if(rv != -1) rv = ::link(oldfullpath.c_str(),newfullpath.c_str()); } @@ -168,6 +185,31 @@ _link_preserve_path_one(Policy::Func::Search searchFunc, return calc_error(rv,error,errno); } +static +int +_link_preserve_path_loop(Policy::Func::Search searchFunc, + Policy::Func::Create createFunc, + const vector &srcmounts, + const size_t minfreespace, + const char *oldfusepath, + const char *newfusepath, + const vector &oldbasepaths) +{ + int error; + + error = -1; + for(size_t i = 0, ei = oldbasepaths.size(); i != ei; i++) + { + error = _link_preserve_path_core(searchFunc,createFunc, + srcmounts,minfreespace, + *oldbasepaths[i], + oldfusepath,newfusepath, + error); + } + + return -error; +} + static int _link_preserve_path(Policy::Func::Search searchFunc, @@ -175,31 +217,20 @@ _link_preserve_path(Policy::Func::Search searchFunc, Policy::Func::Create createFunc, const vector &srcmounts, const size_t minfreespace, - const string &oldfusepath, - const string &newfusepath) + const char *oldfusepath, + const char *newfusepath) { int rv; - int error; - vector toremove; - vector oldbasepaths; + vector oldbasepaths; rv = actionFunc(srcmounts,oldfusepath,minfreespace,oldbasepaths); if(rv == -1) return -errno; - error = -1; - for(size_t i = 0, ei = oldbasepaths.size(); i != ei; i++) - { - const string &oldbasepath = oldbasepaths[i]; - - error = _link_preserve_path_one(searchFunc,createFunc, - srcmounts,minfreespace, - oldbasepath, - oldfusepath,newfusepath, - error); - } - - return -error; + return _link_preserve_path_loop(searchFunc,createFunc, + srcmounts,minfreespace, + oldfusepath,newfusepath, + oldbasepaths); } namespace mergerfs diff --git a/src/listxattr.cpp b/src/listxattr.cpp index 2cd310a2..7f66df70 100644 --- a/src/listxattr.cpp +++ b/src/listxattr.cpp @@ -69,32 +69,31 @@ _listxattr_controlfile(char *list, return xattrs.size(); } +#ifndef WITHOUT_XATTR static int _listxattr(Policy::Func::Search searchFunc, const vector &srcmounts, const size_t minfreespace, - const string &fusepath, + const char *fusepath, char *list, const size_t size) { -#ifndef WITHOUT_XATTR int rv; - vector path; + string fullpath; + vector basepaths; - rv = searchFunc(srcmounts,fusepath,minfreespace,path); + rv = searchFunc(srcmounts,fusepath,minfreespace,basepaths); if(rv == -1) return -errno; - fs::path::append(path[0],fusepath); + fs::path::make(basepaths[0],fusepath,fullpath); - rv = ::llistxattr(path[0].c_str(),list,size); + rv = ::llistxattr(fullpath.c_str(),list,size); return ((rv == -1) ? -errno : rv); -#else - return -ENOTSUP; -#endif } +#endif namespace mergerfs { @@ -111,6 +110,7 @@ namespace mergerfs if(fusepath == config.controlfile) return _listxattr_controlfile(list,size); +#ifndef WITHOUT_XATTR const ugid::Set ugid(fc->uid,fc->gid); const rwlock::ReadGuard readlock(&config.srcmountslock); @@ -120,6 +120,9 @@ namespace mergerfs fusepath, list, size); +#else + return -ENOTSUP; +#endif } } } diff --git a/src/mkdir.cpp b/src/mkdir.cpp index 6b940fd2..47d021e8 100644 --- a/src/mkdir.cpp +++ b/src/mkdir.cpp @@ -35,49 +35,80 @@ using std::vector; using mergerfs::Policy; using namespace mergerfs; +static +int +_mkdir_loop_core(const string &existingpath, + const string &createpath, + const char *fusepath, + const char *fusedirpath, + const mode_t mode, + const int error) +{ + int rv; + string fullpath; + + if(createpath != existingpath) + { + const ugid::SetRootGuard ugidGuard; + fs::clonepath(existingpath,createpath,fusedirpath); + } + + fs::path::make(&createpath,fusepath,fullpath); + + rv = ::mkdir(fullpath.c_str(),mode); + + return calc_error(rv,error,errno); +} + +static +int +_mkdir_loop(const string &existingpath, + const vector &createpaths, + const char *fusepath, + const char *fusedirpath, + const mode_t mode) +{ + int error; + + error = -1; + for(size_t i = 0, ei = createpaths.size(); i != ei; i++) + { + error = _mkdir_loop_core(existingpath,*createpaths[i], + fusepath,fusedirpath,mode,error); + } + + return -error; +} + static int _mkdir(Policy::Func::Search searchFunc, Policy::Func::Create createFunc, const vector &srcmounts, const size_t minfreespace, - const string &fusepath, + const char *fusepath, const mode_t mode) { int rv; - int error; - string dirname; - string existingpath; - vector createpaths; + string fusedirpath; + const char *fusedirpathcstr; + vector createpaths; + vector existingpaths; - dirname = fs::path::dirname(fusepath); - rv = searchFunc(srcmounts,dirname,minfreespace,existingpath); + fusedirpath = fusepath; + fs::path::dirname(fusedirpath); + fusedirpathcstr = fusedirpath.c_str(); + + rv = searchFunc(srcmounts,fusedirpathcstr,minfreespace,existingpaths); if(rv == -1) return -errno; - rv = createFunc(srcmounts,dirname,minfreespace,createpaths); + rv = createFunc(srcmounts,fusedirpathcstr,minfreespace,createpaths); if(rv == -1) return -errno; - error = -1; - for(size_t i = 0, ei = createpaths.size(); i != ei; i++) - { - string &createpath = createpaths[i]; - - if(createpath != existingpath) - { - const ugid::SetRootGuard ugidGuard; - fs::clonepath(existingpath,createpath,dirname); - } - - fs::path::append(createpath,fusepath); - - rv = ::mkdir(createpath.c_str(),mode); - - error = calc_error(rv,error,errno); - } - - return -error; + return _mkdir_loop(*existingpaths[0],createpaths, + fusepath,fusedirpathcstr,mode); } namespace mergerfs diff --git a/src/mknod.cpp b/src/mknod.cpp index 539d78f0..d032c3b1 100644 --- a/src/mknod.cpp +++ b/src/mknod.cpp @@ -36,50 +36,85 @@ using std::string; using std::vector; using namespace mergerfs; +static +int +_mknod_loop_core(const string &existingpath, + const string &createpath, + const char *fusepath, + const char *fusedirpath, + const mode_t mode, + const dev_t dev, + const int error) +{ + int rv; + string fullpath; + + if(createpath != existingpath) + { + const ugid::SetRootGuard ugidGuard; + fs::clonepath(existingpath,createpath,fusedirpath); + } + + fs::path::make(&createpath,fusepath,fullpath); + + rv = ::mknod(fullpath.c_str(),mode,dev); + + return calc_error(rv,error,errno); +} + +static +int +_mknod_loop(const string &existingpath, + const vector &createpaths, + const char *fusepath, + const char *fusedirpath, + const mode_t mode, + const dev_t dev) +{ + int error; + + error = -1; + for(size_t i = 0, ei = createpaths.size(); i != ei; i++) + { + error = _mknod_loop_core(existingpath,*createpaths[i], + fusepath,fusedirpath, + mode,dev,error); + } + + return -error; +} + static int _mknod(Policy::Func::Search searchFunc, Policy::Func::Create createFunc, const vector &srcmounts, const size_t minfreespace, - const string &fusepath, + const char *fusepath, const mode_t mode, const dev_t dev) { int rv; - int error; - string dirname; - string existingpath; - vector createpaths; + string fusedirpath; + const char *fusedirpathcstr; + vector createpaths; + vector existingpaths; - dirname = fs::path::dirname(fusepath); - rv = searchFunc(srcmounts,dirname,minfreespace,existingpath); + fusedirpath = fusepath; + fs::path::dirname(fusedirpath); + fusedirpathcstr = fusedirpath.c_str(); + + rv = searchFunc(srcmounts,fusedirpathcstr,minfreespace,existingpaths); if(rv == -1) return -errno; - rv = createFunc(srcmounts,dirname,minfreespace,createpaths); + rv = createFunc(srcmounts,fusedirpathcstr,minfreespace,createpaths); if(rv == -1) return -errno; - error = -1; - for(size_t i = 0, ei = createpaths.size(); i != ei; i++) - { - string &createpath = createpaths[i]; - - if(createpath != existingpath) - { - const ugid::SetRootGuard ugidGuard; - fs::clonepath(existingpath,createpath,dirname); - } - - fs::path::append(createpath,fusepath); - - rv = ::mknod(createpath.c_str(),mode,dev); - - error = calc_error(rv,error,errno); - } - - return -error; + return _mknod_loop(*existingpaths[0],createpaths, + fusepath,fusedirpathcstr, + mode,dev); } namespace mergerfs diff --git a/src/open.cpp b/src/open.cpp index 8b12ef62..2fcc8cdb 100644 --- a/src/open.cpp +++ b/src/open.cpp @@ -33,32 +33,44 @@ using std::string; using std::vector; using mergerfs::Policy; +static +int +_open_core(const string *basepath, + const char *fusepath, + const int flags, + uint64_t &fh) +{ + int fd; + string fullpath; + + fs::path::make(basepath,fusepath,fullpath); + + fd = ::open(fullpath.c_str(),flags); + if(fd == -1) + return -errno; + + fh = reinterpret_cast(new FileInfo(fd)); + + return 0; +} + static int _open(Policy::Func::Search searchFunc, const vector &srcmounts, const size_t minfreespace, - const string &fusepath, + const char *fusepath, const int flags, uint64_t &fh) { - int fd; int rv; - vector path; + vector basepaths; - rv = searchFunc(srcmounts,fusepath,minfreespace,path); + rv = searchFunc(srcmounts,fusepath,minfreespace,basepaths); if(rv == -1) return -errno; - fs::path::append(path[0],fusepath); - - fd = ::open(path[0].c_str(),flags); - if(fd == -1) - return -errno; - - fh = reinterpret_cast(new FileInfo(fd)); - - return 0; + return _open_core(basepaths[0],fusepath,flags,fh); } namespace mergerfs diff --git a/src/policy.hpp b/src/policy.hpp index cea267a9..bf7cf5ff 100644 --- a/src/policy.hpp +++ b/src/policy.hpp @@ -61,12 +61,13 @@ namespace mergerfs typedef std::string string; typedef std::size_t size_t; typedef std::vector strvec; + typedef std::vector cstrptrvec; typedef const string cstring; typedef const size_t csize_t; typedef const strvec cstrvec; typedef const Category::Enum::Type CType; - typedef int (*Ptr)(CType,cstrvec&,cstring&,csize_t,strvec&); + typedef int (*Ptr)(CType,cstrvec &,const char *,csize_t,cstrptrvec &); template class Base @@ -77,24 +78,11 @@ namespace mergerfs {} int - operator()(cstrvec& b,cstring& c,csize_t d,strvec& e) + operator()(cstrvec &b,const char *c,csize_t d,cstrptrvec &e) { return func(T,b,c,d,e); } - int - operator()(cstrvec& b,cstring& c,csize_t d,string& e) - { - int rv; - strvec vec; - - rv = func(T,b,c,d,vec); - if(!vec.empty()) - e = vec[0]; - - return rv; - } - private: const Ptr func; }; @@ -103,21 +91,21 @@ namespace mergerfs typedef Base Create; typedef Base Search; - static int all(CType,cstrvec&,cstring&,csize_t,strvec&); - static int einval(CType,cstrvec&,cstring&,csize_t,strvec&); - static int enosys(CType,cstrvec&,cstring&,csize_t,strvec&); - static int enotsup(CType,cstrvec&,cstring&,csize_t,strvec&); - static int epmfs(CType,cstrvec&,cstring&,csize_t,strvec&); - static int erofs(CType,cstrvec&,cstring&,csize_t,strvec&); - static int exdev(CType,cstrvec&,cstring&,csize_t,strvec&); - static int ff(CType,cstrvec&,cstring&,csize_t,strvec&); - static int ffwp(CType,cstrvec&,cstring&,csize_t,strvec&); - static int fwfs(CType,cstrvec&,cstring&,csize_t,strvec&); - static int invalid(CType,cstrvec&,cstring&,csize_t,strvec&); - static int lfs(CType,cstrvec&,cstring&,csize_t,strvec&); - static int mfs(CType,cstrvec&,cstring&,csize_t,strvec&); - static int newest(CType,cstrvec&,cstring&,csize_t,strvec&); - static int rand(CType,cstrvec&,cstring&,csize_t,strvec&); + static int all(CType,cstrvec&,const char*,csize_t,cstrptrvec&); + static int einval(CType,cstrvec&,const char*,csize_t,cstrptrvec&); + static int enosys(CType,cstrvec&,const char *,csize_t,cstrptrvec&); + static int enotsup(CType,cstrvec&,const char *,csize_t,cstrptrvec&); + static int epmfs(CType,cstrvec&,const char *,csize_t,cstrptrvec&); + static int erofs(CType,cstrvec&,const char *,csize_t,cstrptrvec&); + static int exdev(CType,cstrvec&,const char *,csize_t,cstrptrvec&); + static int ff(CType,cstrvec&,const char *,csize_t,cstrptrvec&); + static int ffwp(CType,cstrvec&,const char *,csize_t,cstrptrvec&); + static int fwfs(CType,cstrvec&,const char *,csize_t,cstrptrvec&); + static int invalid(CType,cstrvec&,const char *,csize_t,cstrptrvec&); + static int lfs(CType,cstrvec&,const char *,csize_t,cstrptrvec&); + static int mfs(CType,cstrvec&,const char *,csize_t,cstrptrvec&); + static int newest(CType,cstrvec&,const char *,csize_t,cstrptrvec&); + static int rand(CType,cstrvec&,const char *,csize_t,cstrptrvec&); }; private: diff --git a/src/policy_all.cpp b/src/policy_all.cpp index 2d80abad..3314e3c5 100644 --- a/src/policy_all.cpp +++ b/src/policy_all.cpp @@ -31,9 +31,9 @@ using std::size_t; static int -_all(const vector &basepaths, - const string &fusepath, - vector &paths) +_all(const vector &basepaths, + const char *fusepath, + vector &paths) { int rv; struct stat st; @@ -41,7 +41,7 @@ _all(const vector &basepaths, for(size_t i = 0, ei = basepaths.size(); i != ei; i++) { - const string &basepath = basepaths[i]; + const string *basepath = &basepaths[i]; fs::path::make(basepath,fusepath,fullpath); @@ -58,13 +58,14 @@ _all(const vector &basepaths, static int -_all_create(const vector &basepaths, - vector &paths) +_all_create(const vector &basepaths, + vector &paths) { if(basepaths.empty()) return (errno=ENOENT,-1); - paths = basepaths; + for(size_t i = 0, ei = basepaths.size(); i != ei; i++) + paths.push_back(&basepaths[i]); return 0; } @@ -74,9 +75,9 @@ namespace mergerfs int Policy::Func::all(const Category::Enum::Type type, const vector &basepaths, - const string &fusepath, + const char *fusepath, const size_t minfreespace, - vector &paths) + vector &paths) { if(type == Category::Enum::create) return _all_create(basepaths,paths); diff --git a/src/policy_einval.cpp b/src/policy_einval.cpp index 85678845..aa5bdd44 100644 --- a/src/policy_einval.cpp +++ b/src/policy_einval.cpp @@ -29,9 +29,9 @@ namespace mergerfs int Policy::Func::einval(const Category::Enum::Type type, const vector &basepaths, - const string &fusepath, + const char *fusepath, const size_t minfreespace, - vector &paths) + vector &paths) { return (errno=EINVAL,-1); } diff --git a/src/policy_enosys.cpp b/src/policy_enosys.cpp index 171f37ce..a85ed5fb 100644 --- a/src/policy_enosys.cpp +++ b/src/policy_enosys.cpp @@ -29,9 +29,9 @@ namespace mergerfs int Policy::Func::enosys(const Category::Enum::Type type, const vector &basepaths, - const string &fusepath, + const char *fusepath, const size_t minfreespace, - vector &paths) + vector &paths) { return (errno=ENOSYS,-1); } diff --git a/src/policy_enotsup.cpp b/src/policy_enotsup.cpp index d3e103e6..8a2da928 100644 --- a/src/policy_enotsup.cpp +++ b/src/policy_enotsup.cpp @@ -29,9 +29,9 @@ namespace mergerfs int Policy::Func::enotsup(const Category::Enum::Type type, const vector &basepaths, - const string &fusepath, + const char *fusepath, const size_t minfreespace, - vector &paths) + vector &paths) { return (errno=ENOTSUP,-1); } diff --git a/src/policy_epmfs.cpp b/src/policy_epmfs.cpp index 03318091..42a76313 100644 --- a/src/policy_epmfs.cpp +++ b/src/policy_epmfs.cpp @@ -34,13 +34,12 @@ using mergerfs::Category; typedef struct statvfs statvfs_t; static -inline void -_calc_mfs(const statvfs_t &fsstats, - const string &basepath, - const size_t minfreespace, - fsblkcnt_t &mfs, - string &mfsbasepath) +_calc_mfs(const statvfs_t &fsstats, + const string *basepath, + const size_t minfreespace, + fsblkcnt_t &mfs, + const string *&mfsbasepath) { fsblkcnt_t spaceavail; @@ -54,22 +53,22 @@ _calc_mfs(const statvfs_t &fsstats, static int -_epmfs_create(const vector &basepaths, - const string &fusepath, - const size_t minfreespace, - vector &paths) - +_epmfs_create(const vector &basepaths, + const char *fusepath, + const size_t minfreespace, + vector &paths) { - int rv; + int rv; + string fullpath; + statvfs_t fsstats; fsblkcnt_t epmfs; - string epmfsbasepath; - string fullpath; - statvfs_t fsstats; + const string *epmfsbasepath; epmfs = 0; + epmfsbasepath = NULL; for(size_t i = 0, ei = basepaths.size(); i != ei; i++) { - const string &basepath = basepaths[i]; + const string *basepath = &basepaths[i]; fs::path::make(basepath,fusepath,fullpath); @@ -78,7 +77,7 @@ _epmfs_create(const vector &basepaths, _calc_mfs(fsstats,basepath,minfreespace,epmfs,epmfsbasepath); } - if(epmfsbasepath.empty()) + if(epmfsbasepath == NULL) return Policy::Func::mfs(Category::Enum::create,basepaths,fusepath,minfreespace,paths); paths.push_back(epmfsbasepath); @@ -88,21 +87,22 @@ _epmfs_create(const vector &basepaths, static int -_epmfs(const vector &basepaths, - const string &fusepath, - vector &paths) +_epmfs(const vector &basepaths, + const char *fusepath, + vector &paths) { - int rv; + int rv; + string fullpath; + statvfs_t fsstats; fsblkcnt_t epmfs; - string epmfsbasepath; - string fullpath; - statvfs_t fsstats; + const string *epmfsbasepath; epmfs = 0; + epmfsbasepath = NULL; for(size_t i = 0, ei = basepaths.size(); i != ei; i++) { - const string &basepath = basepaths[i]; + const string *basepath = &basepaths[i]; fs::path::make(basepath,fusepath,fullpath); @@ -111,7 +111,7 @@ _epmfs(const vector &basepaths, _calc_mfs(fsstats,basepath,0,epmfs,epmfsbasepath); } - if(epmfsbasepath.empty()) + if(epmfsbasepath == NULL) return (errno=ENOENT,-1); paths.push_back(epmfsbasepath); @@ -124,9 +124,9 @@ namespace mergerfs int Policy::Func::epmfs(const Category::Enum::Type type, const vector &basepaths, - const string &fusepath, + const char *fusepath, const size_t minfreespace, - vector &paths) + vector &paths) { if(type == Category::Enum::create) return _epmfs_create(basepaths,fusepath,minfreespace,paths); diff --git a/src/policy_erofs.cpp b/src/policy_erofs.cpp index 38481dc0..269cef50 100644 --- a/src/policy_erofs.cpp +++ b/src/policy_erofs.cpp @@ -29,9 +29,9 @@ namespace mergerfs int Policy::Func::erofs(const Category::Enum::Type type, const vector &basepaths, - const string &fusepath, + const char *fusepath, const size_t minfreespace, - vector &paths) + vector &paths) { return (errno=EROFS,-1); } diff --git a/src/policy_exdev.cpp b/src/policy_exdev.cpp index 858ccd72..1090545c 100644 --- a/src/policy_exdev.cpp +++ b/src/policy_exdev.cpp @@ -29,9 +29,9 @@ namespace mergerfs int Policy::Func::exdev(const Category::Enum::Type type, const vector &basepaths, - const string &fusepath, + const char *fusepath, const size_t minfreespace, - vector &paths) + vector &paths) { return (errno=EXDEV,-1); } diff --git a/src/policy_ff.cpp b/src/policy_ff.cpp index 3eadad66..c24656f1 100644 --- a/src/policy_ff.cpp +++ b/src/policy_ff.cpp @@ -31,18 +31,19 @@ using std::size_t; static int -_ff(const vector &basepaths, - const string &fusepath, - vector &paths) +_ff(const vector &basepaths, + const char *fusepath, + vector &paths) { + int rv; + string fullpath; + struct stat st; + for(size_t i = 0, ei = basepaths.size(); i != ei; i++) { - int rv; - struct stat st; - string fullpath; - const string &basepath = basepaths[i]; + const string *basepath = &basepaths[i]; - fullpath = fs::path::make(basepath,fusepath); + fs::path::make(basepath,fusepath,fullpath); rv = ::lstat(fullpath.c_str(),&st); if(rv == -1) @@ -58,14 +59,14 @@ _ff(const vector &basepaths, static int -_ff_create(const vector &basepaths, - const string &fusepath, - vector &paths) +_ff_create(const vector &basepaths, + const char *fusepath, + vector &paths) { if(basepaths.empty()) return (errno=ENOENT,-1); - paths.push_back(basepaths[0]); + paths.push_back(&basepaths[0]); return 0; } @@ -75,9 +76,9 @@ namespace mergerfs int Policy::Func::ff(const Category::Enum::Type type, const vector &basepaths, - const string &fusepath, + const char *fusepath, const size_t minfreespace, - vector &paths) + vector &paths) { if(type == Category::Enum::create) return _ff_create(basepaths,fusepath,paths); diff --git a/src/policy_ffwp.cpp b/src/policy_ffwp.cpp index a09ba164..70d48e27 100644 --- a/src/policy_ffwp.cpp +++ b/src/policy_ffwp.cpp @@ -31,18 +31,19 @@ using std::size_t; static int -_ffwp(const vector &basepaths, - const string &fusepath, - vector &paths) +_ffwp(const vector &basepaths, + const char *fusepath, + vector &paths) { - string fallback; + int rv; + struct stat st; + string fullpath; + const string *fallback; + fallback = NULL; for(size_t i = 0, ei = basepaths.size(); i != ei; i++) { - int rv; - struct stat st; - string fullpath; - const string &basepath = basepaths[i]; + const string *basepath = &basepaths[i]; fs::path::make(basepath,fusepath,fullpath); @@ -58,7 +59,7 @@ _ffwp(const vector &basepaths, } } - if(fallback.empty()) + if(fallback == NULL) return (errno=ENOENT,-1); paths.push_back(fallback); @@ -71,9 +72,9 @@ namespace mergerfs int Policy::Func::ffwp(const Category::Enum::Type type, const vector &basepaths, - const string &fusepath, + const char *fusepath, const size_t minfreespace, - vector &paths) + vector &paths) { return _ffwp(basepaths,fusepath,paths); } diff --git a/src/policy_fwfs.cpp b/src/policy_fwfs.cpp index 161d4b28..2cf09087 100644 --- a/src/policy_fwfs.cpp +++ b/src/policy_fwfs.cpp @@ -33,15 +33,16 @@ static int _fwfs_create(const Category::Enum::Type type, const vector &basepaths, - const string &fusepath, + const char *fusepath, const size_t minfreespace, - vector &paths) + vector &paths) { + int rv; + struct statvfs fsstats; + for(size_t i = 0, size = basepaths.size(); i != size; i++) { - int rv; - struct statvfs fsstats; - const string &basepath = basepaths[i]; + const string &basepath = basepaths[i]; rv = ::statvfs(basepath.c_str(),&fsstats); if(rv == 0) @@ -52,7 +53,7 @@ _fwfs_create(const Category::Enum::Type type, if(spaceavail < minfreespace) continue; - paths.push_back(basepath); + paths.push_back(&basepath); return 0; } @@ -65,16 +66,17 @@ static int _fwfs(const Category::Enum::Type type, const vector &basepaths, - const string &fusepath, + const char *fusepath, const size_t minfreespace, - vector &paths) + vector &paths) { + int rv; + string fullpath; + struct statvfs fsstats; + for(size_t i = 0, size = basepaths.size(); i != size; i++) { - int rv; - string fullpath; - struct statvfs fsstats; - const string &basepath = basepaths[i]; + const string *basepath = &basepaths[i]; fs::path::make(basepath,fusepath,fullpath); @@ -101,9 +103,9 @@ namespace mergerfs int Policy::Func::fwfs(const Category::Enum::Type type, const vector &basepaths, - const string &fusepath, + const char *fusepath, const size_t minfreespace, - vector &paths) + vector &paths) { if(type == Category::Enum::create) return _fwfs_create(type,basepaths,fusepath,minfreespace,paths); diff --git a/src/policy_invalid.cpp b/src/policy_invalid.cpp index a8da42b4..cf9e5dc6 100644 --- a/src/policy_invalid.cpp +++ b/src/policy_invalid.cpp @@ -30,9 +30,9 @@ namespace mergerfs int Policy::Func::invalid(const Category::Enum::Type type, const vector &basepaths, - const string &fusepath, + const char *fusepath, const size_t minfreespace, - vector &rv) + vector &paths) { return (errno=EINVAL,-1); } diff --git a/src/policy_lfs.cpp b/src/policy_lfs.cpp index 4b7985fc..f92a2e90 100644 --- a/src/policy_lfs.cpp +++ b/src/policy_lfs.cpp @@ -36,18 +36,19 @@ static int _lfs_create(const Category::Enum::Type type, const vector &basepaths, - const string &fusepath, + const char *fusepath, const size_t minfreespace, - vector &paths) + vector &paths) { + int rv; fsblkcnt_t lfs; - string lfsstr; + const string *lfsstr; + struct statvfs fsstats; - lfs = -1; + lfs = -1; + lfsstr = NULL; for(size_t i = 0, ei = basepaths.size(); i != ei; i++) { - int rv; - struct statvfs fsstats; const string &basepath = basepaths[i]; rv = ::statvfs(basepath.c_str(),&fsstats); @@ -60,12 +61,12 @@ _lfs_create(const Category::Enum::Type type, (spaceavail < lfs)) { lfs = spaceavail; - lfsstr = basepath; + lfsstr = &basepath; } } } - if(lfsstr.empty()) + if(lfsstr == NULL) return Policy::Func::mfs(type,basepaths,fusepath,minfreespace,paths); paths.push_back(lfsstr); @@ -77,20 +78,21 @@ static int _lfs(const Category::Enum::Type type, const vector &basepaths, - const string &fusepath, + const char *fusepath, const size_t minfreespace, - vector &paths) + vector &paths) { + int rv; + string fullpath; + struct statvfs fsstats; fsblkcnt_t lfs; - string lfsstr; + const string *lfsstr; - lfs = -1; + lfs = -1; + lfsstr = NULL; for(size_t i = 0, ei = basepaths.size(); i != ei; i++) { - int rv; - string fullpath; - struct statvfs fsstats; - const string &basepath = basepaths[i]; + const string *basepath = &basepaths[i]; fs::path::make(basepath,fusepath,fullpath); @@ -109,7 +111,7 @@ _lfs(const Category::Enum::Type type, } } - if(lfsstr.empty()) + if(lfsstr == NULL) return Policy::Func::mfs(type,basepaths,fusepath,minfreespace,paths); paths.push_back(lfsstr); @@ -122,9 +124,9 @@ namespace mergerfs int Policy::Func::lfs(const Category::Enum::Type type, const vector &basepaths, - const string &fusepath, + const char *fusepath, const size_t minfreespace, - vector &paths) + vector &paths) { if(type == Category::Enum::create) return _lfs_create(type,basepaths,fusepath,minfreespace,paths); diff --git a/src/policy_mfs.cpp b/src/policy_mfs.cpp index d156f914..ff87118c 100644 --- a/src/policy_mfs.cpp +++ b/src/policy_mfs.cpp @@ -29,18 +29,19 @@ using std::size_t; static int -_mfs_create(const vector &basepaths, - const string &fusepath, - vector &paths) +_mfs_create(const vector &basepaths, + const char *fusepath, + vector &paths) { + int rv; + struct statvfs fsstats; fsblkcnt_t mfs; - string mfsstr; + const string *mfsstr; mfs = 0; + mfsstr = NULL; for(size_t i = 0, ei = basepaths.size(); i != ei; i++) { - int rv; - struct statvfs fsstats; const string &basepath = basepaths[i]; rv = ::statvfs(basepath.c_str(),&fsstats); @@ -52,12 +53,12 @@ _mfs_create(const vector &basepaths, if(spaceavail > mfs) { mfs = spaceavail; - mfsstr = basepath; + mfsstr = &basepath; } } } - if(mfsstr.empty()) + if(mfsstr == NULL) return (errno=ENOENT,-1); paths.push_back(mfsstr); @@ -67,20 +68,21 @@ _mfs_create(const vector &basepaths, static int -_mfs(const vector &basepaths, - const string &fusepath, - vector &paths) +_mfs(const vector &basepaths, + const char *fusepath, + vector &paths) { + int rv; + string fullpath; + struct statvfs fsstats; fsblkcnt_t mfs; - string mfsstr; + const string *mfsstr; mfs = 0; + mfsstr = NULL; for(size_t i = 0, ei = basepaths.size(); i != ei; i++) { - int rv; - string fullpath; - struct statvfs fsstats; - const string &basepath = basepaths[i]; + const string *basepath = &basepaths[i]; fs::path::make(basepath,fusepath,fullpath); @@ -98,7 +100,7 @@ _mfs(const vector &basepaths, } } - if(mfsstr.empty()) + if(mfsstr == NULL) return (errno=ENOENT,-1); paths.push_back(mfsstr); @@ -111,9 +113,9 @@ namespace mergerfs int Policy::Func::mfs(const Category::Enum::Type type, const vector &basepaths, - const string &fusepath, + const char *fusepath, const size_t minfreespace, - vector &paths) + vector &paths) { if(type == Category::Enum::create) return _mfs_create(basepaths,fusepath,paths); diff --git a/src/policy_newest.cpp b/src/policy_newest.cpp index e056c8a4..716a6110 100644 --- a/src/policy_newest.cpp +++ b/src/policy_newest.cpp @@ -32,19 +32,21 @@ using std::size_t; static int -_newest(const vector &basepaths, - const string &fusepath, - vector &paths) +_newest(const vector &basepaths, + const char *fusepath, + vector &paths) { - time_t newest = std::numeric_limits::min(); - string neweststr; + int rv; + struct stat st; + string fullpath; + time_t newest; + const string *neweststr; + newest = std::numeric_limits::min(); + neweststr = NULL; for(size_t i = 0, ei = basepaths.size(); i != ei; i++) { - int rv; - struct stat st; - string fullpath; - const string &basepath = basepaths[i]; + const string *basepath = &basepaths[i]; fs::path::make(basepath,fusepath,fullpath); @@ -56,7 +58,7 @@ _newest(const vector &basepaths, } } - if(neweststr.empty()) + if(neweststr == NULL) return (errno=ENOENT,-1); paths.push_back(neweststr); @@ -69,9 +71,9 @@ namespace mergerfs int Policy::Func::newest(const Category::Enum::Type type, const vector &basepaths, - const string &fusepath, + const char *fusepath, const size_t minfreespace, - vector &paths) + vector &paths) { return _newest(basepaths,fusepath,paths); } diff --git a/src/policy_rand.cpp b/src/policy_rand.cpp index a3f7f151..62b02637 100644 --- a/src/policy_rand.cpp +++ b/src/policy_rand.cpp @@ -31,9 +31,9 @@ namespace mergerfs int Policy::Func::rand(const Category::Enum::Type type, const vector &basepaths, - const string &fusepath, + const char *fusepath, const size_t minfreespace, - vector &paths) + vector &paths) { int rv; diff --git a/src/readdir.cpp b/src/readdir.cpp index bc2a5488..bf0fd3e1 100644 --- a/src/readdir.cpp +++ b/src/readdir.cpp @@ -41,7 +41,7 @@ using std::pair; static int _readdir(const vector &srcmounts, - const string &dirname, + const char *dirname, void *buf, const fuse_fill_dir_t filler) { @@ -53,7 +53,8 @@ _readdir(const vector &srcmounts, DIR *dh; string basepath; - fs::path::make(srcmounts[i],dirname,basepath); + fs::path::make(&srcmounts[i],dirname,basepath); + dh = ::opendir(basepath.c_str()); if(!dh) continue; diff --git a/src/readlink.cpp b/src/readlink.cpp index b38f6d24..5bc30201 100644 --- a/src/readlink.cpp +++ b/src/readlink.cpp @@ -31,31 +31,44 @@ using std::string; using std::vector; using mergerfs::Policy; +static +int +_readlink_core(const string *basepath, + const char *fusepath, + char *buf, + const size_t size) +{ + int rv; + string fullpath; + + fs::path::make(basepath,fusepath,fullpath); + + rv = ::readlink(fullpath.c_str(),buf,size); + if(rv == -1) + return -errno; + + buf[rv] = '\0'; + + return 0; +} + static int _readlink(Policy::Func::Search searchFunc, const vector &srcmounts, const size_t minfreespace, - const string &fusepath, + const char *fusepath, char *buf, const size_t size) { int rv; - vector path; - - rv = searchFunc(srcmounts,fusepath,minfreespace,path); - if(rv == -1) - return -errno; - - fs::path::append(path[0],fusepath); + vector basepaths; - rv = ::readlink(path[0].c_str(),buf,size); + rv = searchFunc(srcmounts,fusepath,minfreespace,basepaths); if(rv == -1) return -errno; - buf[rv] = '\0'; - - return 0; + return _readlink_core(basepaths[0],fusepath,buf,size); } namespace mergerfs diff --git a/src/removexattr.cpp b/src/removexattr.cpp index 5b5b1544..5b1857b6 100644 --- a/src/removexattr.cpp +++ b/src/removexattr.cpp @@ -33,38 +33,60 @@ using std::string; using std::vector; using mergerfs::Policy; +#ifndef WITHOUT_XATTR +static +int +_removexattr_loop_core(const string *basepath, + const char *fusepath, + const char *attrname, + const int error) +{ + int rv; + string fullpath; + + fs::path::make(basepath,fusepath,fullpath); + + rv = ::lremovexattr(fullpath.c_str(),attrname); + + return calc_error(rv,error,errno); +} + +static +int +_removexattr_loop(const vector &basepaths, + const char *fusepath, + const char *attrname) +{ + int error; + + error = -1; + + for(size_t i = 0, ei = basepaths.size(); i != ei; i++) + { + error = _removexattr_loop_core(basepaths[i],fusepath,attrname,error); + } + + return -error; +} + static int _removexattr(Policy::Func::Action actionFunc, const vector &srcmounts, const size_t minfreespace, - const string &fusepath, + const char *fusepath, const char *attrname) { -#ifndef WITHOUT_XATTR int rv; - int error; - vector paths; + vector basepaths; - rv = actionFunc(srcmounts,fusepath,minfreespace,paths); + rv = actionFunc(srcmounts,fusepath,minfreespace,basepaths); if(rv == -1) return -errno; - error = -1; - for(size_t i = 0, ei = paths.size(); i != ei; i++) - { - fs::path::append(paths[i],fusepath); - - rv = ::lremovexattr(paths[i].c_str(),attrname); - - error = calc_error(rv,error,errno); - } - - return -error; -#else - return -ENOTSUP; -#endif + return _removexattr_loop(basepaths,fusepath,attrname); } +#endif namespace mergerfs { @@ -74,6 +96,7 @@ namespace mergerfs removexattr(const char *fusepath, const char *attrname) { +#ifndef WITHOUT_XATTR const fuse_context *fc = fuse_get_context(); const Config &config = Config::get(fc); @@ -88,6 +111,9 @@ namespace mergerfs config.minfreespace, fusepath, attrname); +#else + return -ENOTSUP; +#endif } } } diff --git a/src/rename.cpp b/src/rename.cpp index c07b427c..255ffbc6 100644 --- a/src/rename.cpp +++ b/src/rename.cpp @@ -38,10 +38,16 @@ using namespace mergerfs; static bool -member(const vector &haystack, - const string &needle) +member(const vector &haystack, + const string &needle) { - return (std::find(haystack.begin(),haystack.end(),needle) != haystack.end()); + for(size_t i = 0, ei = haystack.size(); i != ei; i++) + { + if(*haystack[i] == needle) + return true; + } + + return false; } static @@ -54,21 +60,21 @@ _remove(const vector &toremove) static void -_rename_create_path_one(const vector &oldbasepaths, - const string &oldbasepath, - const string &newbasepath, - const string &oldfusepath, - const string &newfusepath, - const string &newfusedirpath, - int &error, - vector &tounlink) +_rename_create_path_core(const vector &oldbasepaths, + const string &oldbasepath, + const string &newbasepath, + const char *oldfusepath, + const char *newfusepath, + const string &newfusedirpath, + int &error, + vector &tounlink) { int rv; bool ismember; string oldfullpath; string newfullpath; - fs::path::make(oldbasepath,newfusepath,newfullpath); + fs::path::make(&oldbasepath,newfusepath,newfullpath); ismember = member(oldbasepaths,oldbasepath); if(ismember) @@ -76,10 +82,10 @@ _rename_create_path_one(const vector &oldbasepaths, if(oldbasepath != newbasepath) { const ugid::SetRootGuard ugidGuard; - fs::clonepath(newbasepath,oldbasepath,newfusedirpath); + fs::clonepath(newbasepath,oldbasepath,newfusedirpath.c_str()); } - fs::path::make(oldbasepath,oldfusepath,oldfullpath); + fs::path::make(&oldbasepath,oldfusepath,oldfullpath); rv = ::rename(oldfullpath.c_str(),newfullpath.c_str()); error = calc_error(rv,error,errno); @@ -98,21 +104,22 @@ _rename_create_path(Policy::Func::Search searchFunc, Policy::Func::Action actionFunc, const vector &srcmounts, const size_t minfreespace, - const string &oldfusepath, - const string &newfusepath) + const char *oldfusepath, + const char *newfusepath) { int rv; int error; - string newbasepath; vector toremove; - vector oldbasepaths; + vector newbasepath; + vector oldbasepaths; rv = actionFunc(srcmounts,oldfusepath,minfreespace,oldbasepaths); if(rv == -1) return -errno; - const string newfusedirpath = fs::path::dirname(newfusepath); - rv = searchFunc(srcmounts,newfusedirpath,minfreespace,newbasepath); + string newfusedirpath = newfusepath; + fs::path::dirname(newfusedirpath); + rv = searchFunc(srcmounts,newfusedirpath.c_str(),minfreespace,newbasepath); if(rv == -1) return -errno; @@ -121,10 +128,11 @@ _rename_create_path(Policy::Func::Search searchFunc, { const string &oldbasepath = srcmounts[i]; - _rename_create_path_one(oldbasepaths,oldbasepath,newbasepath, - oldfusepath,newfusepath, - newfusedirpath, - error,toremove); + _rename_create_path_core(oldbasepaths, + oldbasepath,*newbasepath[0], + oldfusepath,newfusepath, + newfusedirpath, + error,toremove); } if(error == 0) @@ -140,25 +148,25 @@ _clonepath_if_would_create(Policy::Func::Search searchFunc, const vector &srcmounts, const size_t minfreespace, const string &oldbasepath, - const string &oldfusepath, - const string &newfusepath) + const char *oldfusepath, + const char *newfusepath) { int rv; - string newbasepath; string newfusedirpath; + vector newbasepath; - newfusedirpath = fs::path::dirname(newfusepath); - - rv = createFunc(srcmounts,newfusedirpath,minfreespace,newbasepath); + newfusedirpath = newfusepath; + fs::path::dirname(newfusedirpath); + rv = createFunc(srcmounts,newfusedirpath.c_str(),minfreespace,newbasepath); if(rv != -1) { - if(oldbasepath == newbasepath) + if(oldbasepath == *newbasepath[0]) { - rv = searchFunc(srcmounts,newfusedirpath,minfreespace,newbasepath); + rv = searchFunc(srcmounts,newfusedirpath.c_str(),minfreespace,newbasepath); if(rv != -1) { const ugid::SetRootGuard ugidGuard; - fs::clonepath(newbasepath,oldbasepath,newfusedirpath); + fs::clonepath(*newbasepath[0],oldbasepath,newfusedirpath.c_str()); } } else @@ -173,29 +181,29 @@ _clonepath_if_would_create(Policy::Func::Search searchFunc, static void -_rename_preserve_path_one(Policy::Func::Search searchFunc, - Policy::Func::Create createFunc, - const vector &srcmounts, - const size_t minfreespace, - const vector &oldbasepaths, - const string &oldbasepath, - const string &oldfusepath, - const string &newfusepath, - int &error, - vector &toremove) +_rename_preserve_path_core(Policy::Func::Search searchFunc, + Policy::Func::Create createFunc, + const vector &srcmounts, + const size_t minfreespace, + const vector &oldbasepaths, + const string &oldbasepath, + const char *oldfusepath, + const char *newfusepath, + int &error, + vector &toremove) { int rv; bool ismember; string newfullpath; - fs::path::make(oldbasepath,newfusepath,newfullpath); + fs::path::make(&oldbasepath,newfusepath,newfullpath); ismember = member(oldbasepaths,oldbasepath); if(ismember) { string oldfullpath; - fs::path::make(oldbasepath,oldfusepath,oldfullpath); + fs::path::make(&oldbasepath,oldfusepath,oldfullpath); rv = ::rename(oldfullpath.c_str(),newfullpath.c_str()); if((rv == -1) && (errno == ENOENT)) @@ -224,13 +232,13 @@ _rename_preserve_path(Policy::Func::Search searchFunc, Policy::Func::Create createFunc, const vector &srcmounts, const size_t minfreespace, - const string &oldfusepath, - const string &newfusepath) + const char *oldfusepath, + const char *newfusepath) { int rv; int error; vector toremove; - vector oldbasepaths; + vector oldbasepaths; rv = actionFunc(srcmounts,oldfusepath,minfreespace,oldbasepaths); if(rv == -1) @@ -241,11 +249,11 @@ _rename_preserve_path(Policy::Func::Search searchFunc, { const string &oldbasepath = srcmounts[i]; - _rename_preserve_path_one(searchFunc,createFunc, - srcmounts,minfreespace, - oldbasepaths,oldbasepath, - oldfusepath,newfusepath, - error,toremove); + _rename_preserve_path_core(searchFunc,createFunc, + srcmounts,minfreespace, + oldbasepaths,oldbasepath, + oldfusepath,newfusepath, + error,toremove); } if(error == 0) diff --git a/src/rmdir.cpp b/src/rmdir.cpp index c87e184b..39523fd9 100644 --- a/src/rmdir.cpp +++ b/src/rmdir.cpp @@ -33,32 +33,54 @@ using mergerfs::Policy; static int -_rmdir(Policy::Func::Action actionFunc, - const vector &srcmounts, - const size_t minfreespace, - const string &fusepath) +_rmdir_loop_core(const string *basepath, + const char *fusepath, + const int error) { int rv; - int error; - vector paths; + string fullpath; - rv = actionFunc(srcmounts,fusepath,minfreespace,paths); - if(rv == -1) - return -errno; + fs::path::make(basepath,fusepath,fullpath); - error = -1; - for(size_t i = 0, ei = paths.size(); i != ei; i++) - { - fs::path::append(paths[i],fusepath); + rv = ::rmdir(fullpath.c_str()); - rv = ::rmdir(paths[i].c_str()); + return calc_error(rv,error,errno); +} + + +static +int +_rmdir_loop(const vector &basepaths, + const char *fusepath) +{ + int error; - error = calc_error(rv,error,errno); + error = -1; + for(size_t i = 0, ei = basepaths.size(); i != ei; i++) + { + error = _rmdir_loop_core(basepaths[i],fusepath,error); } return -error; } +static +int +_rmdir(Policy::Func::Action actionFunc, + const vector &srcmounts, + const size_t minfreespace, + const char *fusepath) +{ + int rv; + vector basepaths; + + rv = actionFunc(srcmounts,fusepath,minfreespace,basepaths); + if(rv == -1) + return -errno; + + return _rmdir_loop(basepaths,fusepath); +} + namespace mergerfs { namespace fuse diff --git a/src/setxattr.cpp b/src/setxattr.cpp index a156391d..c807c3d0 100644 --- a/src/setxattr.cpp +++ b/src/setxattr.cpp @@ -287,41 +287,73 @@ _setxattr_controlfile(Config &config, return -EINVAL; } +#ifndef WITHOUT_XATTR + +static +int +_setxattr_loop_core(const string *basepath, + const char *fusepath, + const char *attrname, + const char *attrval, + const size_t attrvalsize, + const int flags, + const int error) +{ + int rv; + string fullpath; + + fs::path::make(basepath,fusepath,fullpath); + + rv = ::lsetxattr(fullpath.c_str(),attrname,attrval,attrvalsize,flags); + + return calc_error(rv,error,errno); +} + +static +int +_setxattr_loop(const vector &basepaths, + const char *fusepath, + const char *attrname, + const char *attrval, + const size_t attrvalsize, + const int flags) +{ + int error; + + error = -1; + for(size_t i = 0, ei = basepaths.size(); i != ei; i++) + { + error = _setxattr_loop_core(basepaths[i],fusepath, + attrname,attrval,attrvalsize,flags, + error); + } + + return -error; +} + static int _setxattr(Policy::Func::Action actionFunc, const vector &srcmounts, const size_t minfreespace, - const string &fusepath, + const char *fusepath, const char *attrname, const char *attrval, const size_t attrvalsize, const int flags) { -#ifndef WITHOUT_XATTR int rv; - int error; - vector paths; + vector basepaths; - rv = actionFunc(srcmounts,fusepath,minfreespace,paths); + rv = actionFunc(srcmounts,fusepath,minfreespace,basepaths); if(rv == -1) return -errno; - error = -1; - for(size_t i = 0, ei = paths.size(); i != ei; i++) - { - fs::path::append(paths[i],fusepath); - - rv = ::lsetxattr(paths[i].c_str(),attrname,attrval,attrvalsize,flags); - - error = calc_error(rv,error,errno); - } + return _setxattr_loop(basepaths,fusepath,attrname,attrval,attrvalsize,flags); +} - return -error; -#else - return -ENOTSUP; #endif -} + namespace mergerfs { namespace fuse @@ -342,6 +374,7 @@ namespace mergerfs string(attrval,attrvalsize), flags); +#ifndef WITHOUT_XATTR const ugid::Set ugid(fc->uid,fc->gid); const rwlock::ReadGuard readlock(&config.srcmountslock); @@ -353,6 +386,9 @@ namespace mergerfs attrval, attrvalsize, flags); +#else + return -ENOTSUP; +#endif } } } diff --git a/src/str.cpp b/src/str.cpp index 53d4e45d..1618f490 100644 --- a/src/str.cpp +++ b/src/str.cpp @@ -28,7 +28,7 @@ namespace str { void split(vector &result, - const string &str, + const char *str, const char delimiter) { string part; @@ -38,6 +38,14 @@ namespace str result.push_back(part); } + void + split(vector &result, + const string &str, + const char delimiter) + { + return split(result,str.c_str(),delimiter); + } + string join(const vector &vec, const size_t substridx, diff --git a/src/str.hpp b/src/str.hpp index d7cb143f..92dca191 100644 --- a/src/str.hpp +++ b/src/str.hpp @@ -20,6 +20,10 @@ namespace str { void + split(std::vector &result, + const char *str, + const char delimiter); + void split(std::vector &result, const std::string &str, const char delimiter); diff --git a/src/symlink.cpp b/src/symlink.cpp index 331751c9..8917591b 100644 --- a/src/symlink.cpp +++ b/src/symlink.cpp @@ -33,49 +33,81 @@ using std::vector; using mergerfs::Policy; using namespace mergerfs; +static +int +_symlink_loop_core(const string &existingpath, + const string &newbasepath, + const char *oldpath, + const char *newpath, + const char *newdirpath, + const int error) +{ + int rv; + string fullnewpath; + + if(newbasepath != existingpath) + { + const ugid::SetRootGuard ugidGuard; + fs::clonepath(existingpath,newbasepath,newdirpath); + } + + fs::path::make(&newbasepath,newpath,fullnewpath); + + rv = ::symlink(oldpath,fullnewpath.c_str()); + + return calc_error(rv,error,errno); +} + +static +int +_symlink_loop(const string &existingpath, + const vector newbasepaths, + const char *oldpath, + const char *newpath, + const char *newdirpath) +{ + int error; + + error = -1; + for(size_t i = 0, ei = newbasepaths.size(); i != ei; i++) + { + error = _symlink_loop_core(existingpath,*newbasepaths[i], + oldpath,newpath,newdirpath, + error); + } + + return -error; +} + static int _symlink(Policy::Func::Search searchFunc, Policy::Func::Create createFunc, const vector &srcmounts, const size_t minfreespace, - const string &oldpath, - const string &newpath) + const char *oldpath, + const char *newpath) { int rv; - int error; - string dirname; - string existingpath; - vector newpathdirs; + string newdirpath; + const char *newdirpathcstr; + vector newbasepaths; + vector existingpaths; - dirname = fs::path::dirname(newpath); - rv = searchFunc(srcmounts,dirname,minfreespace,existingpath); + newdirpath = newpath; + fs::path::dirname(newdirpath); + newdirpathcstr = newdirpath.c_str(); + + rv = searchFunc(srcmounts,newdirpathcstr,minfreespace,existingpaths); if(rv == -1) return -errno; - rv = createFunc(srcmounts,dirname,minfreespace,newpathdirs); + rv = createFunc(srcmounts,newdirpathcstr,minfreespace,newbasepaths); if(rv == -1) return -errno; - error = -1; - for(size_t i = 0, ei = newpathdirs.size(); i != ei; i++) - { - string &newpathdir = newpathdirs[i]; - - if(newpathdir != existingpath) - { - const ugid::SetRootGuard ugidGuard; - fs::clonepath(existingpath,newpathdir,dirname); - } - - fs::path::append(newpathdir,newpath); - - rv = symlink(oldpath.c_str(),newpathdir.c_str()); - - error = calc_error(rv,error,errno); - } - - return -error; + return _symlink_loop(*existingpaths[0],newbasepaths, + oldpath,newpath,newdirpathcstr); } namespace mergerfs diff --git a/src/truncate.cpp b/src/truncate.cpp index 50049196..67b7c5ad 100644 --- a/src/truncate.cpp +++ b/src/truncate.cpp @@ -33,33 +33,56 @@ using std::string; using std::vector; using mergerfs::Policy; +static +int +_truncate_loop_core(const string *basepath, + const char *fusepath, + const off_t size, + const int error) +{ + int rv; + string fullpath; + + fs::path::make(basepath,fusepath,fullpath); + + rv = ::truncate(fullpath.c_str(),size); + + return calc_error(rv,error,errno); +} + +static +int +_truncate_loop(const vector &basepaths, + const char *fusepath, + const off_t size) +{ + int error; + + error = -1; + for(size_t i = 0, ei = basepaths.size(); i != ei; i++) + { + error = _truncate_loop_core(basepaths[0],fusepath,size,error); + } + + return -error; +} + static int _truncate(Policy::Func::Action actionFunc, const vector &srcmounts, const size_t minfreespace, - const string &fusepath, + const char *fusepath, const off_t size) { int rv; - int error; - vector paths; + vector basepaths; - rv = actionFunc(srcmounts,fusepath,minfreespace,paths); + rv = actionFunc(srcmounts,fusepath,minfreespace,basepaths); if(rv == -1) return -errno; - error = -1; - for(size_t i = 0, ei = paths.size(); i != ei; i++) - { - fs::path::append(paths[i],fusepath); - - rv = ::truncate(paths[i].c_str(),size); - - error = calc_error(rv,error,errno); - } - - return -error; + return _truncate_loop(basepaths,fusepath,size); } namespace mergerfs diff --git a/src/unlink.cpp b/src/unlink.cpp index 03c7ee68..f035569d 100644 --- a/src/unlink.cpp +++ b/src/unlink.cpp @@ -34,32 +34,53 @@ using mergerfs::Policy; static int -_unlink(Policy::Func::Action actionFunc, - const vector &srcmounts, - const size_t minfreespace, - const string &fusepath) +_unlink_loop_core(const string *basepath, + const char *fusepath, + const int error) { int rv; - int error; - vector paths; + string fullpath; - rv = actionFunc(srcmounts,fusepath,minfreespace,paths); - if(rv == -1) - return -errno; + fs::path::make(basepath,fusepath,fullpath); - error = -1; - for(size_t i = 0, ei = paths.size(); i != ei; i++) - { - fs::path::append(paths[i],fusepath); + rv = ::unlink(fullpath.c_str()); - rv = ::unlink(paths[i].c_str()); + return calc_error(rv,error,errno); +} - error = calc_error(rv,error,errno); +static +int +_unlink_loop(const vector &basepaths, + const char *fusepath) +{ + int error; + + error = -1; + for(size_t i = 0, ei = basepaths.size(); i != ei; i++) + { + error = _unlink_loop_core(basepaths[i],fusepath,error); } return -error; } +static +int +_unlink(Policy::Func::Action actionFunc, + const vector &srcmounts, + const size_t minfreespace, + const char *fusepath) +{ + int rv; + vector basepaths; + + rv = actionFunc(srcmounts,fusepath,minfreespace,basepaths); + if(rv == -1) + return -errno; + + return _unlink_loop(basepaths,fusepath); +} + namespace mergerfs { namespace fuse diff --git a/src/utimens.cpp b/src/utimens.cpp index 792845d2..ddc27576 100644 --- a/src/utimens.cpp +++ b/src/utimens.cpp @@ -33,33 +33,56 @@ using std::string; using std::vector; using mergerfs::Policy; +static +int +_utimens_loop_core(const string *basepath, + const char *fusepath, + const timespec ts[2], + const int error) +{ + int rv; + string fullpath; + + fs::path::make(basepath,fusepath,fullpath); + + rv = ::utimensat(0,fullpath.c_str(),ts,AT_SYMLINK_NOFOLLOW); + + return calc_error(rv,error,errno); +} + +static +int +_utimens_loop(const vector &basepaths, + const char *fusepath, + const timespec ts[2]) +{ + int error; + + error = -1; + for(size_t i = 0, ei = basepaths.size(); i != ei; i++) + { + error = _utimens_loop_core(basepaths[i],fusepath,ts,error); + } + + return -error; +} + static int _utimens(Policy::Func::Action actionFunc, const vector &srcmounts, const size_t minfreespace, - const string &fusepath, + const char *fusepath, const timespec ts[2]) { int rv; - int error; - vector paths; + vector basepaths; - rv = actionFunc(srcmounts,fusepath,minfreespace,paths); + rv = actionFunc(srcmounts,fusepath,minfreespace,basepaths); if(rv == -1) return -errno; - error = -1; - for(size_t i = 0, ei = paths.size(); i != ei; i++) - { - fs::path::append(paths[i],fusepath); - - rv = ::utimensat(0,paths[i].c_str(),ts,AT_SYMLINK_NOFOLLOW); - - error = calc_error(rv,error,errno); - } - - return -error; + return _utimens_loop(basepaths,fusepath,ts); } namespace mergerfs