Browse Source

use references to srcmounts rather than copies

pull/219/head
Antonio SJ Musumeci 9 years ago
parent
commit
6086620e23
  1. 11
      src/access.cpp
  2. 53
      src/chmod.cpp
  3. 55
      src/chown.cpp
  4. 68
      src/create.cpp
  5. 4
      src/fallocate.cpp
  6. 4
      src/flush.cpp
  7. 20
      src/fs.cpp
  8. 4
      src/fs.hpp
  9. 11
      src/fs_clonepath.cpp
  10. 2
      src/fs_clonepath.hpp
  11. 5
      src/fs_movefile.cpp
  12. 62
      src/fs_path.cpp
  13. 35
      src/fs_path.hpp
  14. 11
      src/getattr.cpp
  15. 24
      src/getxattr.cpp
  16. 18
      src/ioctl.cpp
  17. 163
      src/link.cpp
  18. 21
      src/listxattr.cpp
  19. 85
      src/mkdir.cpp
  20. 89
      src/mknod.cpp
  21. 38
      src/open.cpp
  22. 48
      src/policy.hpp
  23. 19
      src/policy_all.cpp
  24. 4
      src/policy_einval.cpp
  25. 4
      src/policy_enosys.cpp
  26. 4
      src/policy_enotsup.cpp
  27. 56
      src/policy_epmfs.cpp
  28. 4
      src/policy_erofs.cpp
  29. 4
      src/policy_exdev.cpp
  30. 29
      src/policy_ff.cpp
  31. 23
      src/policy_ffwp.cpp
  32. 30
      src/policy_fwfs.cpp
  33. 4
      src/policy_invalid.cpp
  34. 40
      src/policy_lfs.cpp
  35. 40
      src/policy_mfs.cpp
  36. 26
      src/policy_newest.cpp
  37. 4
      src/policy_rand.cpp
  38. 5
      src/readdir.cpp
  39. 37
      src/readlink.cpp
  40. 64
      src/removexattr.cpp
  41. 114
      src/rename.cpp
  42. 52
      src/rmdir.cpp
  43. 72
      src/setxattr.cpp
  44. 10
      src/str.cpp
  45. 4
      src/str.hpp
  46. 88
      src/symlink.cpp
  47. 53
      src/truncate.cpp
  48. 51
      src/unlink.cpp
  49. 53
      src/utimens.cpp

11
src/access.cpp

@ -35,19 +35,20 @@ int
_access(Policy::Func::Search searchFunc,
const vector<string> &srcmounts,
const size_t minfreespace,
const string &fusepath,
const char *fusepath,
const int mask)
{
int rv;
string path;
string fullpath;
vector<const string*> 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);
}

53
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<const string*> &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<string> &srcmounts,
const size_t minfreespace,
const string &fusepath,
const char *fusepath,
const mode_t mode)
{
int rv;
int error;
vector<string> paths;
vector<const string*> 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

55
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<const string*> &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<string> &srcmounts,
const size_t minfreespace,
const string &fusepath,
const char *fusepath,
const uid_t uid,
const gid_t gid)
{
int rv;
int error;
vector<string> paths;
vector<const string*> 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

68
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<uint64_t>(new FileInfo(fd));
return 0;
}
static
int
_create(Policy::Func::Search searchFunc,
Policy::Func::Create createFunc,
const vector<string> &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<string> createpath;
vector<string> existingpath;
string fullpath;
string fusedirpath;
const char *fusedirpathcstr;
vector<const string*> createpaths;
vector<const string*> 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<uint64_t>(new FileInfo(fd));
return 0;
return _create_core(*existingpaths[0],*createpaths[0],
fusepath,fusedirpathcstr,
mode,flags,fh);
}
namespace mergerfs

4
src/fallocate.cpp

@ -16,10 +16,6 @@
#if FALLOCATE
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <fuse.h>
#include <errno.h>

4
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);
}

20
src/fs.cpp

@ -40,16 +40,16 @@ namespace fs
{
void
findallfiles(const vector<string> &srcmounts,
const string &fusepath,
const char *fusepath,
vector<string> &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<string> &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;

4
src/fs.hpp

@ -27,11 +27,11 @@ namespace fs
using std::vector;
void findallfiles(const vector<string> &srcmounts,
const string &fusepath,
const char *fusepath,
vector<string> &paths);
int findonfs(const vector<string> &srcmounts,
const string &fusepath,
const char *fusepath,
const int fd,
string &basepath);

11
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)
{

2
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);
}

5
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;

62
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<string> &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;
}
}
}

35
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<string>::const_iterator begin,
vector<string>::const_iterator end,
const string &fusepath);
bool exists(const vector<string> &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;
}
}
};

11
src/getattr.cpp

@ -63,19 +63,20 @@ int
_getattr(Policy::Func::Search searchFunc,
const vector<string> &srcmounts,
const size_t minfreespace,
const string &fusepath,
const char *fusepath,
struct stat &buf)
{
int rv;
vector<string> path;
string fullpath;
vector<const string*> 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);
}

24
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<string> &srcmounts,
const string &fusepath,
const char *fusepath,
char *buf,
const size_t count)
{
@ -253,10 +253,10 @@ _getxattr_user_mergerfs_allpaths(const vector<string> &srcmounts,
static
int
_getxattr_user_mergerfs(const string &basepath,
const string &fusepath,
const char *fusepath,
const string &fullpath,
const vector<string> &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<string> &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<string> basepath;
vector<const string*> 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);

18
src/ioctl.cpp

@ -61,21 +61,23 @@ int
_ioctl_dir_base(Policy::Func::Search searchFunc,
const vector<string> &srcmounts,
const size_t minfreespace,
const string &fusepath,
const char *fusepath,
const int cmd,
void *data)
{
int fd;
int rv;
vector<string> path;
string fullpath;
vector<const string*> 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);

163
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<const string*> &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<string> &srcmounts,
const size_t minfreespace,
const string &oldfusepath,
const string &newfusepath)
const char *oldfusepath,
const char *newfusepath)
{
int rv;
int error;
string newbasepath;
vector<string> toremove;
vector<string> oldbasepaths;
string newfusedirpath;
vector<const string*> oldbasepaths;
vector<const string*> 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<string> &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<const string*> 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<string> &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<string> &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<string> &srcmounts,
const size_t minfreespace,
const char *oldfusepath,
const char *newfusepath,
const vector<const string*> &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<string> &srcmounts,
const size_t minfreespace,
const string &oldfusepath,
const string &newfusepath)
const char *oldfusepath,
const char *newfusepath)
{
int rv;
int error;
vector<string> toremove;
vector<string> oldbasepaths;
vector<const string*> 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

21
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<string> &srcmounts,
const size_t minfreespace,
const string &fusepath,
const char *fusepath,
char *list,
const size_t size)
{
#ifndef WITHOUT_XATTR
int rv;
vector<string> path;
string fullpath;
vector<const string*> 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
}
}
}

85
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<const string*> &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<string> &srcmounts,
const size_t minfreespace,
const string &fusepath,
const char *fusepath,
const mode_t mode)
{
int rv;
int error;
string dirname;
string existingpath;
vector<string> createpaths;
string fusedirpath;
const char *fusedirpathcstr;
vector<const string*> createpaths;
vector<const string*> 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

89
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<const string*> &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<string> &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<string> createpaths;
string fusedirpath;
const char *fusedirpathcstr;
vector<const string*> createpaths;
vector<const string*> 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

38
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<uint64_t>(new FileInfo(fd));
return 0;
}
static
int
_open(Policy::Func::Search searchFunc,
const vector<string> &srcmounts,
const size_t minfreespace,
const string &fusepath,
const char *fusepath,
const int flags,
uint64_t &fh)
{
int fd;
int rv;
vector<string> path;
vector<const string*> 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<uint64_t>(new FileInfo(fd));
return 0;
return _open_core(basepaths[0],fusepath,flags,fh);
}
namespace mergerfs

48
src/policy.hpp

@ -61,12 +61,13 @@ namespace mergerfs
typedef std::string string;
typedef std::size_t size_t;
typedef std::vector<string> strvec;
typedef std::vector<const string*> 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 <CType T>
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<Category::Enum::create> Create;
typedef Base<Category::Enum::search> 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:

19
src/policy_all.cpp

@ -31,9 +31,9 @@ using std::size_t;
static
int
_all(const vector<string> &basepaths,
const string &fusepath,
vector<string> &paths)
_all(const vector<string> &basepaths,
const char *fusepath,
vector<const string*> &paths)
{
int rv;
struct stat st;
@ -41,7 +41,7 @@ _all(const vector<string> &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<string> &basepaths,
static
int
_all_create(const vector<string> &basepaths,
vector<string> &paths)
_all_create(const vector<string> &basepaths,
vector<const string*> &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<string> &basepaths,
const string &fusepath,
const char *fusepath,
const size_t minfreespace,
vector<string> &paths)
vector<const string*> &paths)
{
if(type == Category::Enum::create)
return _all_create(basepaths,paths);

4
src/policy_einval.cpp

@ -29,9 +29,9 @@ namespace mergerfs
int
Policy::Func::einval(const Category::Enum::Type type,
const vector<string> &basepaths,
const string &fusepath,
const char *fusepath,
const size_t minfreespace,
vector<string> &paths)
vector<const string*> &paths)
{
return (errno=EINVAL,-1);
}

4
src/policy_enosys.cpp

@ -29,9 +29,9 @@ namespace mergerfs
int
Policy::Func::enosys(const Category::Enum::Type type,
const vector<string> &basepaths,
const string &fusepath,
const char *fusepath,
const size_t minfreespace,
vector<string> &paths)
vector<const string*> &paths)
{
return (errno=ENOSYS,-1);
}

4
src/policy_enotsup.cpp

@ -29,9 +29,9 @@ namespace mergerfs
int
Policy::Func::enotsup(const Category::Enum::Type type,
const vector<string> &basepaths,
const string &fusepath,
const char *fusepath,
const size_t minfreespace,
vector<string> &paths)
vector<const string*> &paths)
{
return (errno=ENOTSUP,-1);
}

56
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<string> &basepaths,
const string &fusepath,
const size_t minfreespace,
vector<string> &paths)
_epmfs_create(const vector<string> &basepaths,
const char *fusepath,
const size_t minfreespace,
vector<const string*> &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<string> &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<string> &basepaths,
static
int
_epmfs(const vector<string> &basepaths,
const string &fusepath,
vector<string> &paths)
_epmfs(const vector<string> &basepaths,
const char *fusepath,
vector<const string*> &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<string> &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<string> &basepaths,
const string &fusepath,
const char *fusepath,
const size_t minfreespace,
vector<string> &paths)
vector<const string*> &paths)
{
if(type == Category::Enum::create)
return _epmfs_create(basepaths,fusepath,minfreespace,paths);

4
src/policy_erofs.cpp

@ -29,9 +29,9 @@ namespace mergerfs
int
Policy::Func::erofs(const Category::Enum::Type type,
const vector<string> &basepaths,
const string &fusepath,
const char *fusepath,
const size_t minfreespace,
vector<string> &paths)
vector<const string*> &paths)
{
return (errno=EROFS,-1);
}

4
src/policy_exdev.cpp

@ -29,9 +29,9 @@ namespace mergerfs
int
Policy::Func::exdev(const Category::Enum::Type type,
const vector<string> &basepaths,
const string &fusepath,
const char *fusepath,
const size_t minfreespace,
vector<string> &paths)
vector<const string*> &paths)
{
return (errno=EXDEV,-1);
}

29
src/policy_ff.cpp

@ -31,18 +31,19 @@ using std::size_t;
static
int
_ff(const vector<string> &basepaths,
const string &fusepath,
vector<string> &paths)
_ff(const vector<string> &basepaths,
const char *fusepath,
vector<const string*> &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<string> &basepaths,
static
int
_ff_create(const vector<string> &basepaths,
const string &fusepath,
vector<string> &paths)
_ff_create(const vector<string> &basepaths,
const char *fusepath,
vector<const string*> &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<string> &basepaths,
const string &fusepath,
const char *fusepath,
const size_t minfreespace,
vector<string> &paths)
vector<const string*> &paths)
{
if(type == Category::Enum::create)
return _ff_create(basepaths,fusepath,paths);

23
src/policy_ffwp.cpp

@ -31,18 +31,19 @@ using std::size_t;
static
int
_ffwp(const vector<string> &basepaths,
const string &fusepath,
vector<string> &paths)
_ffwp(const vector<string> &basepaths,
const char *fusepath,
vector<const string*> &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<string> &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<string> &basepaths,
const string &fusepath,
const char *fusepath,
const size_t minfreespace,
vector<string> &paths)
vector<const string*> &paths)
{
return _ffwp(basepaths,fusepath,paths);
}

30
src/policy_fwfs.cpp

@ -33,15 +33,16 @@ static
int
_fwfs_create(const Category::Enum::Type type,
const vector<string> &basepaths,
const string &fusepath,
const char *fusepath,
const size_t minfreespace,
vector<string> &paths)
vector<const string*> &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<string> &basepaths,
const string &fusepath,
const char *fusepath,
const size_t minfreespace,
vector<string> &paths)
vector<const string*> &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<string> &basepaths,
const string &fusepath,
const char *fusepath,
const size_t minfreespace,
vector<string> &paths)
vector<const string*> &paths)
{
if(type == Category::Enum::create)
return _fwfs_create(type,basepaths,fusepath,minfreespace,paths);

4
src/policy_invalid.cpp

@ -30,9 +30,9 @@ namespace mergerfs
int
Policy::Func::invalid(const Category::Enum::Type type,
const vector<string> &basepaths,
const string &fusepath,
const char *fusepath,
const size_t minfreespace,
vector<string> &rv)
vector<const string*> &paths)
{
return (errno=EINVAL,-1);
}

40
src/policy_lfs.cpp

@ -36,18 +36,19 @@ static
int
_lfs_create(const Category::Enum::Type type,
const vector<string> &basepaths,
const string &fusepath,
const char *fusepath,
const size_t minfreespace,
vector<string> &paths)
vector<const string*> &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<string> &basepaths,
const string &fusepath,
const char *fusepath,
const size_t minfreespace,
vector<string> &paths)
vector<const string*> &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<string> &basepaths,
const string &fusepath,
const char *fusepath,
const size_t minfreespace,
vector<string> &paths)
vector<const string*> &paths)
{
if(type == Category::Enum::create)
return _lfs_create(type,basepaths,fusepath,minfreespace,paths);

40
src/policy_mfs.cpp

@ -29,18 +29,19 @@ using std::size_t;
static
int
_mfs_create(const vector<string> &basepaths,
const string &fusepath,
vector<string> &paths)
_mfs_create(const vector<string> &basepaths,
const char *fusepath,
vector<const string*> &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<string> &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<string> &basepaths,
static
int
_mfs(const vector<string> &basepaths,
const string &fusepath,
vector<string> &paths)
_mfs(const vector<string> &basepaths,
const char *fusepath,
vector<const string*> &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<string> &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<string> &basepaths,
const string &fusepath,
const char *fusepath,
const size_t minfreespace,
vector<string> &paths)
vector<const string*> &paths)
{
if(type == Category::Enum::create)
return _mfs_create(basepaths,fusepath,paths);

26
src/policy_newest.cpp

@ -32,19 +32,21 @@ using std::size_t;
static
int
_newest(const vector<string> &basepaths,
const string &fusepath,
vector<string> &paths)
_newest(const vector<string> &basepaths,
const char *fusepath,
vector<const string*> &paths)
{
time_t newest = std::numeric_limits<time_t>::min();
string neweststr;
int rv;
struct stat st;
string fullpath;
time_t newest;
const string *neweststr;
newest = std::numeric_limits<time_t>::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<string> &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<string> &basepaths,
const string &fusepath,
const char *fusepath,
const size_t minfreespace,
vector<string> &paths)
vector<const string*> &paths)
{
return _newest(basepaths,fusepath,paths);
}

4
src/policy_rand.cpp

@ -31,9 +31,9 @@ namespace mergerfs
int
Policy::Func::rand(const Category::Enum::Type type,
const vector<string> &basepaths,
const string &fusepath,
const char *fusepath,
const size_t minfreespace,
vector<string> &paths)
vector<const string*> &paths)
{
int rv;

5
src/readdir.cpp

@ -41,7 +41,7 @@ using std::pair;
static
int
_readdir(const vector<string> &srcmounts,
const string &dirname,
const char *dirname,
void *buf,
const fuse_fill_dir_t filler)
{
@ -53,7 +53,8 @@ _readdir(const vector<string> &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;

37
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<string> &srcmounts,
const size_t minfreespace,
const string &fusepath,
const char *fusepath,
char *buf,
const size_t size)
{
int rv;
vector<string> path;
rv = searchFunc(srcmounts,fusepath,minfreespace,path);
if(rv == -1)
return -errno;
fs::path::append(path[0],fusepath);
vector<const string*> 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

64
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<const string*> &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<string> &srcmounts,
const size_t minfreespace,
const string &fusepath,
const char *fusepath,
const char *attrname)
{
#ifndef WITHOUT_XATTR
int rv;
int error;
vector<string> paths;
vector<const string*> 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
}
}
}

114
src/rename.cpp

@ -38,10 +38,16 @@ using namespace mergerfs;
static
bool
member(const vector<string> &haystack,
const string &needle)
member(const vector<const string*> &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<string> &toremove)
static
void
_rename_create_path_one(const vector<string> &oldbasepaths,
const string &oldbasepath,
const string &newbasepath,
const string &oldfusepath,
const string &newfusepath,
const string &newfusedirpath,
int &error,
vector<string> &tounlink)
_rename_create_path_core(const vector<const string*> &oldbasepaths,
const string &oldbasepath,
const string &newbasepath,
const char *oldfusepath,
const char *newfusepath,
const string &newfusedirpath,
int &error,
vector<string> &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<string> &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<string> &srcmounts,
const size_t minfreespace,
const string &oldfusepath,
const string &newfusepath)
const char *oldfusepath,
const char *newfusepath)
{
int rv;
int error;
string newbasepath;
vector<string> toremove;
vector<string> oldbasepaths;
vector<const string*> newbasepath;
vector<const string*> 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<string> &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<const string*> 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<string> &srcmounts,
const size_t minfreespace,
const vector<string> &oldbasepaths,
const string &oldbasepath,
const string &oldfusepath,
const string &newfusepath,
int &error,
vector<string> &toremove)
_rename_preserve_path_core(Policy::Func::Search searchFunc,
Policy::Func::Create createFunc,
const vector<string> &srcmounts,
const size_t minfreespace,
const vector<const string*> &oldbasepaths,
const string &oldbasepath,
const char *oldfusepath,
const char *newfusepath,
int &error,
vector<string> &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<string> &srcmounts,
const size_t minfreespace,
const string &oldfusepath,
const string &newfusepath)
const char *oldfusepath,
const char *newfusepath)
{
int rv;
int error;
vector<string> toremove;
vector<string> oldbasepaths;
vector<const string*> 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)

52
src/rmdir.cpp

@ -33,32 +33,54 @@ using mergerfs::Policy;
static
int
_rmdir(Policy::Func::Action actionFunc,
const vector<string> &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<string> 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<const string*> &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<string> &srcmounts,
const size_t minfreespace,
const char *fusepath)
{
int rv;
vector<const string*> basepaths;
rv = actionFunc(srcmounts,fusepath,minfreespace,basepaths);
if(rv == -1)
return -errno;
return _rmdir_loop(basepaths,fusepath);
}
namespace mergerfs
{
namespace fuse

72
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<const string*> &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<string> &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<string> paths;
vector<const string*> 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
}
}
}

10
src/str.cpp

@ -28,7 +28,7 @@ namespace str
{
void
split(vector<string> &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<string> &result,
const string &str,
const char delimiter)
{
return split(result,str.c_str(),delimiter);
}
string
join(const vector<string> &vec,
const size_t substridx,

4
src/str.hpp

@ -20,6 +20,10 @@
namespace str
{
void
split(std::vector<std::string> &result,
const char *str,
const char delimiter);
void
split(std::vector<std::string> &result,
const std::string &str,
const char delimiter);

88
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<const string*> 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<string> &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<string> newpathdirs;
string newdirpath;
const char *newdirpathcstr;
vector<const string*> newbasepaths;
vector<const string*> 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

53
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<const string*> &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<string> &srcmounts,
const size_t minfreespace,
const string &fusepath,
const char *fusepath,
const off_t size)
{
int rv;
int error;
vector<string> paths;
vector<const string*> 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

51
src/unlink.cpp

@ -34,32 +34,53 @@ using mergerfs::Policy;
static
int
_unlink(Policy::Func::Action actionFunc,
const vector<string> &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<string> 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<const string*> &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<string> &srcmounts,
const size_t minfreespace,
const char *fusepath)
{
int rv;
vector<const string*> basepaths;
rv = actionFunc(srcmounts,fusepath,minfreespace,basepaths);
if(rv == -1)
return -errno;
return _unlink_loop(basepaths,fusepath);
}
namespace mergerfs
{
namespace fuse

53
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<const string*> &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<string> &srcmounts,
const size_t minfreespace,
const string &fusepath,
const char *fusepath,
const timespec ts[2])
{
int rv;
int error;
vector<string> paths;
vector<const string*> 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

Loading…
Cancel
Save