Browse Source

Merge pull request #78 from trapexit/typed-policies

Typed policies
pull/79/head
Antonio SJ Musumeci 9 years ago
parent
commit
1d798ad285
  1. 13
      src/access.cpp
  2. 13
      src/chmod.cpp
  3. 13
      src/chown.cpp
  4. 23
      src/create.cpp
  5. 46
      src/fs.cpp
  6. 28
      src/fs.hpp
  7. 10
      src/getattr.cpp
  8. 26
      src/getxattr.cpp
  9. 12
      src/ioctl.cpp
  10. 27
      src/link.cpp
  11. 10
      src/listxattr.cpp
  12. 2
      src/mergerfs.cpp
  13. 27
      src/mkdir.cpp
  14. 28
      src/mknod.cpp
  15. 8
      src/open.cpp
  16. 4
      src/option_parser.cpp
  17. 81
      src/policy.hpp
  18. 32
      src/policy_all.cpp
  19. 184
      src/policy_epmfs.cpp
  20. 39
      src/policy_ff.cpp
  21. 46
      src/policy_ffwp.cpp
  22. 68
      src/policy_fwfs.cpp
  23. 5
      src/policy_invalid.cpp
  24. 77
      src/policy_lfs.cpp
  25. 81
      src/policy_mfs.cpp
  26. 45
      src/policy_newest.cpp
  27. 7
      src/policy_rand.cpp
  28. 7
      src/readdir.cpp
  29. 10
      src/readlink.cpp
  30. 13
      src/removexattr.cpp
  31. 41
      src/rename.cpp
  32. 13
      src/rmdir.cpp
  33. 13
      src/setxattr.cpp
  34. 4
      src/statfs.cpp
  35. 15
      src/symlink.cpp
  36. 13
      src/truncate.cpp
  37. 13
      src/unlink.cpp
  38. 13
      src/utimens.cpp

13
src/access.cpp

@ -42,23 +42,26 @@
using std::string;
using std::vector;
using mergerfs::Policy;
using mergerfs::Category;
static
int
_access(const Policy::Func::Ptr searchFunc,
_access(Policy::Func::Search searchFunc,
const vector<string> &srcmounts,
const size_t minfreespace,
const string &fusepath,
const int mask)
{
int rv;
Paths paths;
vector<string> path;
rv = searchFunc(srcmounts,fusepath,minfreespace,paths);
rv = searchFunc(srcmounts,fusepath,minfreespace,path);
if(rv == -1)
return -errno;
rv = ::eaccess(paths[0].full.c_str(),mask);
fs::path::append(path[0],fusepath);
rv = ::eaccess(path[0].c_str(),mask);
return ((rv == -1) ? -errno : 0);
}
@ -76,7 +79,7 @@ namespace mergerfs
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _access(*config.access,
return _access(config.access,
config.srcmounts,
config.minfreespace,
fusepath,

13
src/chmod.cpp

@ -39,7 +39,7 @@ using mergerfs::Policy;
static
int
_chmod(const Policy::Func::Ptr actionFunc,
_chmod(Policy::Func::Action actionFunc,
const vector<string> &srcmounts,
const size_t minfreespace,
const string &fusepath,
@ -47,17 +47,18 @@ _chmod(const Policy::Func::Ptr actionFunc,
{
int rv;
int error;
Paths paths;
vector<string> paths;
rv = actionFunc(srcmounts,fusepath,minfreespace,paths);
if(rv == -1)
return -errno;
error = 0;
for(Paths::const_iterator
i = paths.begin(), ei = paths.end(); i != ei; ++i)
for(size_t i = 0, ei = paths.size(); i != ei; i++)
{
rv = ::chmod(i->full.c_str(),mode);
fs::path::append(paths[i],fusepath);
rv = ::chmod(paths[i].c_str(),mode);
if(rv == -1)
error = errno;
}
@ -78,7 +79,7 @@ namespace mergerfs
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _chmod(*config.chmod,
return _chmod(config.chmod,
config.srcmounts,
config.minfreespace,
fusepath,

13
src/chown.cpp

@ -40,7 +40,7 @@ using mergerfs::Policy;
static
int
_chown(const Policy::Func::Ptr actionFunc,
_chown(Policy::Func::Action actionFunc,
const vector<string> &srcmounts,
const size_t minfreespace,
const string &fusepath,
@ -49,17 +49,18 @@ _chown(const Policy::Func::Ptr actionFunc,
{
int rv;
int error;
Paths paths;
vector<string> paths;
rv = actionFunc(srcmounts,fusepath,minfreespace,paths);
if(rv == -1)
return -errno;
error = 0;
for(Paths::const_iterator
i = paths.begin(), ei = paths.end(); i != ei; ++i)
for(size_t i = 0, ei = paths.size(); i != ei; i++)
{
rv = ::lchown(i->full.c_str(),uid,gid);
fs::path::append(paths[i],fusepath);
rv = ::lchown(paths[i].c_str(),uid,gid);
if(rv == -1)
error = errno;
}
@ -81,7 +82,7 @@ namespace mergerfs
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _chown(*config.chown,
return _chown(config.chown,
config.srcmounts,
config.minfreespace,
fusepath,

23
src/create.cpp

@ -43,8 +43,8 @@ using mergerfs::Policy;
static
int
_create(const Policy::Func::Ptr searchFunc,
const Policy::Func::Ptr createFunc,
_create(Policy::Func::Search searchFunc,
Policy::Func::Create createFunc,
const vector<string> &srcmounts,
const size_t minfreespace,
const string &fusepath,
@ -54,12 +54,11 @@ _create(const Policy::Func::Ptr searchFunc,
{
int fd;
int rv;
string path;
string dirname;
Paths createpath;
Paths existingpath;
vector<string> createpath;
vector<string> existingpath;
dirname = fs::dirname(fusepath);
dirname = fs::path::dirname(fusepath);
rv = searchFunc(srcmounts,dirname,minfreespace,existingpath);
if(rv == -1)
return -errno;
@ -68,15 +67,15 @@ _create(const Policy::Func::Ptr searchFunc,
if(rv == -1)
return -errno;
if(createpath[0].base != existingpath[0].base)
if(createpath[0] != existingpath[0])
{
const mergerfs::ugid::SetResetGuard ugid(0,0);
fs::clonepath(existingpath[0].base,createpath[0].base,dirname);
fs::clonepath(existingpath[0],createpath[0],dirname);
}
path = fs::make_path(createpath[0].base,fusepath);
fs::path::append(createpath[0],fusepath);
fd = ::open(path.c_str(),flags,mode);
fd = ::open(createpath[0].c_str(),flags,mode);
if(fd == -1)
return -errno;
@ -99,8 +98,8 @@ namespace mergerfs
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _create(*config.getattr,
*config.create,
return _create(config.getattr,
config.create,
config.srcmounts,
config.minfreespace,
fusepath,

46
src/fs.cpp

@ -62,6 +62,8 @@ random_element(Iter begin,
}
namespace fs
{
namespace path
{
string
dirname(const string &path)
@ -93,7 +95,7 @@ namespace fs
}
bool
dir_is_empty(const string &path)
is_empty(const string &path)
{
DIR *dir;
struct dirent *de;
@ -121,29 +123,18 @@ namespace fs
return true;
}
string
make_path(const string &base,
const string &suffix)
{
if(suffix[0] == '/' ||
*base.rbegin() == '/')
return base + suffix;
return base + '/' + suffix;
}
bool
path_exists(vector<string>::const_iterator begin,
vector<string>::const_iterator end,
exists(const vector<string> &paths,
const string &fusepath)
{
for(vector<string>::const_iterator
iter = begin; iter != end; ++iter)
for(size_t i = 0, ei = paths.size(); i != ei; i++)
{
int rv;
string path;
struct stat st;
path = fs::make_path(*iter,fusepath);
path = fs::path::make(paths[i],fusepath);
rv = ::lstat(path.c_str(),&st);
if(rv == 0)
return true;
@ -151,14 +142,6 @@ namespace fs
return false;
}
bool
path_exists(const vector<string> &srcmounts,
const string &fusepath)
{
return path_exists(srcmounts.begin(),
srcmounts.end(),
fusepath);
}
void
@ -166,16 +149,14 @@ namespace fs
const string &fusepath,
vector<string> &paths)
{
for(vector<string>::const_iterator
iter = srcmounts.begin(), eiter = srcmounts.end();
iter != eiter;
++iter)
for(size_t i = 0, ei = srcmounts.size(); i != ei; i++)
{
int rv;
string fullpath;
struct stat st;
fullpath = fs::make_path(*iter,fusepath);
fullpath = fs::path::make(srcmounts[i],fusepath);
rv = ::lstat(fullpath.c_str(),&st);
if(rv == 0)
paths.push_back(fullpath);
@ -450,7 +431,7 @@ namespace fs
string frompath;
string dirname;
dirname = fs::dirname(relative);
dirname = fs::path::dirname(relative);
if(!dirname.empty())
{
rv = clonepath(fromsrc,tosrc,dirname);
@ -458,15 +439,14 @@ namespace fs
return -1;
}
frompath = fs::make_path(fromsrc,relative);
frompath = fs::path::make(fromsrc,relative);
rv = ::stat(frompath.c_str(),&st);
if(rv == -1)
return -1;
else if(!S_ISDIR(st.st_mode))
return (errno = ENOTDIR,-1);
topath = fs::make_path(tosrc,relative);
topath = fs::path::make(tosrc,relative);
rv = ::mkdir(topath.c_str(),st.st_mode);
if(rv == -1)
{

28
src/fs.hpp

@ -38,20 +38,36 @@ namespace fs
using std::vector;
using std::map;
namespace path
{
string dirname(const string &path);
string basename(const string &path);
bool dir_is_empty(const string &path);
string make_path(const string &base,
const string &suffix);
bool is_empty(const string &path);
bool path_exists(vector<string>::const_iterator begin,
bool exists(vector<string>::const_iterator begin,
vector<string>::const_iterator end,
const string &fusepath);
bool path_exists(const vector<string> &srcmounts,
bool exists(const vector<string> &srcmounts,
const string &fusepath);
inline
string
make(const string &base,
const string &suffix)
{
return base + suffix;
}
inline
void
append(string &base,
const string &suffix)
{
base += suffix;
}
}
void findallfiles(const vector<string> &srcmounts,
const string &fusepath,
vector<string> &paths);

10
src/getattr.cpp

@ -66,20 +66,22 @@ _getattr_controlfile(struct stat &buf)
static
int
_getattr(const Policy::Func::Ptr searchFunc,
_getattr(Policy::Func::Search searchFunc,
const vector<string> &srcmounts,
const size_t minfreespace,
const string &fusepath,
struct stat &buf)
{
int rv;
Paths path;
vector<string> path;
rv = searchFunc(srcmounts,fusepath,minfreespace,path);
if(rv == -1)
return -errno;
rv = ::lstat(path[0].full.c_str(),&buf);
fs::path::append(path[0],fusepath);
rv = ::lstat(path[0].c_str(),&buf);
return ((rv == -1) ? -errno : 0);
}
@ -101,7 +103,7 @@ namespace mergerfs
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _getattr(*config.getattr,
return _getattr(config.getattr,
config.srcmounts,
config.minfreespace,
fusepath,

26
src/getxattr.cpp

@ -167,9 +167,10 @@ _getxattr_user_mergerfs_allpaths(const vector<string> &srcmounts,
static
int
_getxattr_user_mergerfs(const Path &path,
const vector<string> &srcmounts,
_getxattr_user_mergerfs(const string &basepath,
const string &fusepath,
const string &fullpath,
const vector<string> &srcmounts,
const char *attrname,
char *buf,
const size_t count)
@ -177,20 +178,20 @@ _getxattr_user_mergerfs(const Path &path,
const char *attrbasename = &attrname[sizeof("user.mergerfs")];
if(!strcmp(attrbasename,"basepath"))
return ::_getxattr_from_string(buf,count,path.base);
return ::_getxattr_from_string(buf,count,basepath);
else if(!strcmp(attrbasename,"fullpath"))
return ::_getxattr_from_string(buf,count,path.full);
return ::_getxattr_from_string(buf,count,fullpath);
else if(!strcmp(attrbasename,"relpath"))
return ::_getxattr_from_string(buf,count,fusepath);
else if(!strcmp(attrbasename,"allpaths"))
return ::_getxattr_user_mergerfs_allpaths(srcmounts,fusepath,buf,count);
return ::lgetxattr(path.full.c_str(),attrname,buf,count);
return ::lgetxattr(fullpath.c_str(),attrname,buf,count);
}
static
int
_getxattr(const Policy::Func::Ptr searchFunc,
_getxattr(Policy::Func::Search searchFunc,
const vector<string> &srcmounts,
const size_t minfreespace,
const string &fusepath,
@ -200,16 +201,19 @@ _getxattr(const Policy::Func::Ptr searchFunc,
{
#ifndef WITHOUT_XATTR
int rv;
Paths path;
vector<string> basepath;
string fullpath;
rv = searchFunc(srcmounts,fusepath,minfreespace,path);
rv = searchFunc(srcmounts,fusepath,minfreespace,basepath);
if(rv == -1)
return -errno;
fullpath = fs::path::make(basepath[0],fusepath);
if(!strncmp("user.mergerfs.",attrname,sizeof("user.mergerfs.")-1))
rv = _getxattr_user_mergerfs(path[0],srcmounts,fusepath,attrname,buf,count);
rv = _getxattr_user_mergerfs(basepath[0],fusepath,fullpath,srcmounts,attrname,buf,count);
else
rv = ::lgetxattr(path[0].full.c_str(),attrname,buf,count);
rv = ::lgetxattr(fullpath.c_str(),attrname,buf,count);
return ((rv == -1) ? -errno : rv);
#else
@ -239,7 +243,7 @@ namespace mergerfs
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _getxattr(*config.getxattr,
return _getxattr(config.getxattr,
config.srcmounts,
config.minfreespace,
fusepath,

12
src/ioctl.cpp

@ -82,7 +82,7 @@ _ioctl(const int fd,
#ifdef FUSE_IOCTL_DIR
static
int
_ioctl_dir_base(const Policy::Func::Ptr searchFunc,
_ioctl_dir_base(Policy::Func::Search searchFunc,
const vector<string> &srcmounts,
const size_t minfreespace,
const string &fusepath,
@ -93,19 +93,21 @@ _ioctl_dir_base(const Policy::Func::Ptr searchFunc,
{
int fd;
int rv;
Paths path;
vector<string> path;
rv = searchFunc(srcmounts,fusepath,minfreespace,path);
if(rv == -1)
return -errno;
fd = ::open(path[0].full.c_str(),flags);
fs::path::append(path[0],fusepath);
fd = ::open(path[0].c_str(),flags);
if(fd == -1)
return -errno;
rv = _ioctl(fd,cmd,arg,flags,data);
close(fd);
::close(fd);
return rv;
}
@ -123,7 +125,7 @@ _ioctl_dir(const string &fusepath,
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _ioctl_dir_base(*config.getattr,
return _ioctl_dir_base(config.getattr,
config.srcmounts,
config.minfreespace,
fusepath,

27
src/link.cpp

@ -41,7 +41,7 @@ using mergerfs::Policy;
static
int
_single_link(const Policy::Func::Ptr searchFunc,
_single_link(Policy::Func::Search searchFunc,
const vector<string> &srcmounts,
const size_t minfreespace,
const string &base,
@ -49,23 +49,23 @@ _single_link(const Policy::Func::Ptr searchFunc,
const string &newpath)
{
int rv;
const string fulloldpath = fs::make_path(base,oldpath);
const string fullnewpath = fs::make_path(base,newpath);
const string fulloldpath = fs::path::make(base,oldpath);
const string fullnewpath = fs::path::make(base,newpath);
rv = ::link(fulloldpath.c_str(),fullnewpath.c_str());
if(rv == -1 && errno == ENOENT)
{
string newpathdir;
Paths foundpath;
vector<string> foundpath;
newpathdir = fs::dirname(newpath);
newpathdir = fs::path::dirname(newpath);
rv = searchFunc(srcmounts,newpathdir,minfreespace,foundpath);
if(rv == -1)
return -1;
{
const mergerfs::ugid::SetResetGuard ugid(0,0);
fs::clonepath(foundpath[0].base,base,newpathdir);
fs::clonepath(foundpath[0],base,newpathdir);
}
rv = ::link(fulloldpath.c_str(),fullnewpath.c_str());
@ -76,8 +76,8 @@ _single_link(const Policy::Func::Ptr searchFunc,
static
int
_link(const Policy::Func::Ptr searchFunc,
const Policy::Func::Ptr actionFunc,
_link(Policy::Func::Search searchFunc,
Policy::Func::Action actionFunc,
const vector<string> &srcmounts,
const size_t minfreespace,
const string &oldpath,
@ -85,17 +85,16 @@ _link(const Policy::Func::Ptr searchFunc,
{
int rv;
int error;
Paths oldpaths;
vector<string> oldpaths;
rv = actionFunc(srcmounts,oldpath,minfreespace,oldpaths);
if(rv == -1)
return -errno;
error = 0;
for(Paths::const_iterator
i = oldpaths.begin(), ei = oldpaths.end(); i != ei; ++i)
for(size_t i = 0, ei = oldpaths.size(); i != ei; i++)
{
rv = _single_link(searchFunc,srcmounts,minfreespace,i->base,oldpath,newpath);
rv = _single_link(searchFunc,srcmounts,minfreespace,oldpaths[i],oldpath,newpath);
if(rv == -1)
error = errno;
}
@ -116,8 +115,8 @@ namespace mergerfs
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _link(*config.getattr,
*config.link,
return _link(config.getattr,
config.link,
config.srcmounts,
config.minfreespace,
from,

10
src/listxattr.cpp

@ -69,7 +69,7 @@ _listxattr_controlfile(char *list,
static
int
_listxattr(const Policy::Func::Ptr searchFunc,
_listxattr(Policy::Func::Search searchFunc,
const vector<string> &srcmounts,
const size_t minfreespace,
const string &fusepath,
@ -78,13 +78,15 @@ _listxattr(const Policy::Func::Ptr searchFunc,
{
#ifndef WITHOUT_XATTR
int rv;
Paths path;
vector<string> path;
rv = searchFunc(srcmounts,fusepath,minfreespace,path);
if(rv == -1)
return -errno;
rv = ::llistxattr(path[0].full.c_str(),list,size);
fs::path::append(path[0],fusepath);
rv = ::llistxattr(path[0].c_str(),list,size);
return ((rv == -1) ? -errno : rv);
#else
@ -110,7 +112,7 @@ namespace mergerfs
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _listxattr(*config.listxattr,
return _listxattr(config.listxattr,
config.srcmounts,
config.minfreespace,
fusepath,

2
src/mergerfs.cpp

@ -80,7 +80,7 @@ namespace local
getappname(const int argc,
char * const *argv)
{
return fs::basename(argv[0]);
return fs::path::basename(argv[0]);
}
static

27
src/mkdir.cpp

@ -42,8 +42,8 @@ using mergerfs::Policy;
static
int
_mkdir(const Policy::Func::Ptr searchFunc,
const Policy::Func::Ptr createFunc,
_mkdir(Policy::Func::Search searchFunc,
Policy::Func::Create createFunc,
const vector<string> &srcmounts,
const size_t minfreespace,
const string &fusepath,
@ -53,10 +53,10 @@ _mkdir(const Policy::Func::Ptr searchFunc,
int error;
string dirname;
string fullpath;
Paths createpaths;
Paths existingpath;
vector<string> createpaths;
vector<string> existingpath;
dirname = fs::dirname(fusepath);
dirname = fs::path::dirname(fusepath);
rv = searchFunc(srcmounts,dirname,minfreespace,existingpath);
if(rv == -1)
return -errno;
@ -66,18 +66,19 @@ _mkdir(const Policy::Func::Ptr searchFunc,
return -errno;
error = 0;
for(Paths::const_iterator
i = createpaths.begin(), ei = createpaths.end(); i != ei; ++i)
for(size_t i = 0, ei = createpaths.size(); i != ei; i++)
{
if(i->base != existingpath[0].base)
string &createpath = createpaths[i];
if(createpath != existingpath[0])
{
const mergerfs::ugid::SetResetGuard ugid(0,0);
fs::clonepath(existingpath[0].base,i->base,dirname);
fs::clonepath(existingpath[0],createpath,dirname);
}
fullpath = fs::make_path(i->base,fusepath);
fs::path::append(createpath,fusepath);
rv = ::mkdir(fullpath.c_str(),mode);
rv = ::mkdir(createpath.c_str(),mode);
if(rv == -1)
error = errno;
}
@ -98,8 +99,8 @@ namespace mergerfs
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _mkdir(*config.getattr,
*config.mkdir,
return _mkdir(config.getattr,
config.mkdir,
config.srcmounts,
config.minfreespace,
fusepath,

28
src/mknod.cpp

@ -44,8 +44,8 @@ using mergerfs::Policy;
static
int
_mknod(const Policy::Func::Ptr searchFunc,
const Policy::Func::Ptr createFunc,
_mknod(Policy::Func::Search searchFunc,
Policy::Func::Create createFunc,
const vector<string> &srcmounts,
const size_t minfreespace,
const string &fusepath,
@ -55,11 +55,10 @@ _mknod(const Policy::Func::Ptr searchFunc,
int rv;
int error;
string dirname;
string fullpath;
Paths createpaths;
Paths existingpath;
vector<string> createpaths;
vector<string> existingpath;
dirname = fs::dirname(fusepath);
dirname = fs::path::dirname(fusepath);
rv = searchFunc(srcmounts,dirname,minfreespace,existingpath);
if(rv == -1)
return -errno;
@ -69,18 +68,19 @@ _mknod(const Policy::Func::Ptr searchFunc,
return -errno;
error = 0;
for(Paths::const_iterator
i = createpaths.begin(), ei = createpaths.end(); i != ei; ++i)
for(size_t i = 0, ei = createpaths.size(); i != ei; i++)
{
if(i->base != existingpath[0].base)
string &createpath = createpaths[0];
if(createpath != existingpath[0])
{
const mergerfs::ugid::SetResetGuard ugid(0,0);
fs::clonepath(existingpath[0].base,i->base,dirname);
fs::clonepath(existingpath[0],createpath,dirname);
}
fullpath = fs::make_path(i->base,fusepath);
fs::path::append(createpath,fusepath);
rv = ::mknod(fullpath.c_str(),mode,dev);
rv = ::mknod(createpath.c_str(),mode,dev);
if(rv == -1)
error = errno;
}
@ -102,8 +102,8 @@ namespace mergerfs
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _mknod(*config.getattr,
*config.mknod,
return _mknod(config.getattr,
config.mknod,
config.srcmounts,
config.minfreespace,
fusepath,

8
src/open.cpp

@ -42,7 +42,7 @@ using mergerfs::Policy;
static
int
_open(const Policy::Func::Ptr searchFunc,
_open(Policy::Func::Search searchFunc,
const vector<string> &srcmounts,
const size_t minfreespace,
const string &fusepath,
@ -51,13 +51,13 @@ _open(const Policy::Func::Ptr searchFunc,
{
int fd;
int rv;
Paths path;
vector<string> path;
rv = searchFunc(srcmounts,fusepath,minfreespace,path);
if(rv == -1)
return -errno;
fd = ::open(path[0].full.c_str(),flags);
fd = ::open(path[0].c_str(),flags);
if(fd == -1)
return -errno;
@ -79,7 +79,7 @@ namespace mergerfs
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _open(*config.open,
return _open(config.open,
config.srcmounts,
config.minfreespace,
fusepath,

4
src/option_parser.cpp

@ -121,8 +121,8 @@ parse_and_process_minfreespace(const std::string &value,
minfreespace *= (1024 * 1024);
break;
case 'b':
case 'B':
case 'g':
case 'G':
minfreespace *= (1024 * 1024 * 1024);
break;

81
src/policy.hpp

@ -31,6 +31,7 @@
#include "path.hpp"
#include "fs.hpp"
#include "category.hpp"
namespace mergerfs
{
@ -61,19 +62,74 @@ namespace mergerfs
typedef std::string string;
typedef std::size_t size_t;
typedef std::vector<string> strvec;
typedef const string cstring;
typedef const size_t csize_t;
typedef const strvec cstrvec;
typedef const Category::Enum::Type CType;
typedef int (*Ptr)(const strvec&,const string&,const size_t,Paths&);
static int invalid(const strvec&,const string&,const size_t,Paths&);
static int all(const strvec&,const string&,const size_t,Paths&);
static int epmfs(const strvec&,const string&,const size_t,Paths&);
static int ff(const strvec&,const string&,const size_t,Paths&);
static int ffwp(const strvec&,const string&,const size_t,Paths&);
static int fwfs(const strvec&,const string&,const size_t,Paths&);
static int lfs(const strvec&,const string&,const size_t,Paths&);
static int mfs(const strvec&,const string&,const size_t,Paths&);
static int newest(const strvec&,const string&,const size_t,Paths&);
static int rand(const strvec&,const string&,const size_t,Paths&);
typedef int (*Ptr)(CType,cstrvec&,cstring&,csize_t,strvec&);
class Action
{
public:
Action(const Policy *p)
: func(p->_func)
{}
int
operator()(cstrvec& b,cstring& c,csize_t d,strvec& e)
{
return func(Category::Enum::action,b,c,d,e);
}
private:
const Ptr func;
};
class Create
{
public:
Create(const Policy *p)
: func(p->_func)
{}
int
operator()(cstrvec& b,cstring& c,csize_t d,strvec& e)
{
return func(Category::Enum::create,b,c,d,e);
}
private:
const Ptr func;
};
class Search
{
public:
Search(const Policy *p)
: func(p->_func)
{}
int
operator()(cstrvec& b,cstring& c,csize_t d,strvec& e)
{
return func(Category::Enum::search,b,c,d,e);
}
private:
const Ptr func;
};
static int invalid(CType,cstrvec&,cstring&,csize_t,strvec&);
static int all(CType,cstrvec&,cstring&,csize_t,strvec&);
static int epmfs(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 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&);
};
private:
@ -124,6 +180,7 @@ namespace mergerfs
public:
static const std::vector<Policy> _policies_;
static const Policy * const policies;
static const Policy &invalid;
static const Policy &all;
static const Policy &epmfs;

32
src/policy_all.cpp

@ -36,30 +36,40 @@ using std::string;
using std::vector;
using std::size_t;
namespace mergerfs
{
static
int
Policy::Func::all(const vector<string> &basepaths,
_all(const vector<string> &basepaths,
const string &fusepath,
const size_t minfreespace,
Paths &paths)
vector<string> &paths)
{
int rv;
struct stat st;
string fullpath;
for(vector<string>::const_iterator
iter = basepaths.begin(), eiter = basepaths.end();
iter != eiter;
++iter)
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
{
fullpath = fs::make_path(*iter,fusepath);
const char *basepath;
basepath = basepaths[i].c_str();
fullpath = fs::path::make(basepath,fusepath);
rv = ::lstat(fullpath.c_str(),&st);
if(rv == 0)
paths.push_back(Path(*iter,fullpath));
paths.push_back(basepath);
}
return paths.empty() ? (errno=ENOENT,-1) : 0;
}
namespace mergerfs
{
int
Policy::Func::all(const Category::Enum::Type type,
const vector<string> &basepaths,
const string &fusepath,
const size_t minfreespace,
vector<string> &paths)
{
return _all(basepaths,fusepath,paths);
}
}

184
src/policy_epmfs.cpp

@ -37,68 +37,172 @@ using std::string;
using std::vector;
using std::size_t;
namespace mergerfs
{
int
Policy::Func::epmfs(const vector<string> &basepaths,
const string &fusepath,
const size_t minfreespace,
Paths &paths)
static
inline
void
_calc_epmfs(const struct statvfs &fsstats,
const char *basepath,
fsblkcnt_t &epmfs,
const char *&epmfsbasepath,
fsblkcnt_t &mfs,
const char *&mfsbasepath)
{
fsblkcnt_t existingmfs;
fsblkcnt_t generalmfs;
string fullpath;
string generalmfspath;
string existingmfspath;
vector<string>::const_iterator iter = basepaths.begin();
vector<string>::const_iterator eiter = basepaths.end();
fsblkcnt_t spaceavail;
if(iter == eiter)
return (errno = ENOENT,-1);
spaceavail = (fsstats.f_frsize * fsstats.f_bavail);
if(spaceavail > epmfs)
{
epmfs = spaceavail;
epmfsbasepath = basepath;
}
existingmfs = 0;
generalmfs = 0;
do
if(spaceavail > mfs)
{
int rv;
struct statvfs fsstats;
const string &mountpoint = *iter;
mfs = spaceavail;
mfsbasepath = basepath;
}
}
rv = ::statvfs(mountpoint.c_str(),&fsstats);
if(rv == 0)
static
inline
void
_calc_mfs(const struct statvfs &fsstats,
const char *basepath,
fsblkcnt_t &mfs,
const char *&mfsbasepath)
{
fsblkcnt_t spaceavail;
struct stat st;
spaceavail = (fsstats.f_frsize * fsstats.f_bavail);
if(spaceavail > generalmfs)
if(spaceavail > mfs)
{
generalmfs = spaceavail;
generalmfspath = mountpoint;
mfs = spaceavail;
mfsbasepath = basepath;
}
}
fullpath = fs::make_path(mountpoint,fusepath);
rv = ::lstat(fullpath.c_str(),&st);
if(rv == 0)
static
inline
int
_try_statvfs(const char *basepath,
const string &fullpath,
fsblkcnt_t &epmfs,
const char *&epmfsbasepath,
fsblkcnt_t &mfs,
const char *&mfsbasepath)
{
if(spaceavail > existingmfs)
int rv;
struct statvfs fsstats;
rv = ::statvfs(fullpath.c_str(),&fsstats);
if(rv == 0)
_calc_epmfs(fsstats,basepath,epmfs,epmfsbasepath,mfs,mfsbasepath);
return rv;
}
static
inline
int
_try_statvfs(const char *basepath,
fsblkcnt_t &mfs,
const char *&mfsbasepath)
{
existingmfs = spaceavail;
existingmfspath = mountpoint;
int rv;
struct statvfs fsstats;
rv = ::statvfs(basepath,&fsstats);
if(rv == 0)
_calc_mfs(fsstats,basepath,mfs,mfsbasepath);
return rv;
}
static
int
_epmfs_create(const vector<string> &basepaths,
const string &fusepath,
vector<string> &paths)
{
fsblkcnt_t epmfs;
fsblkcnt_t mfs;
const char *basepath;
const char *mfsbasepath;
const char *epmfsbasepath;
string fullpath;
mfs = 0;
epmfs = 0;
mfsbasepath = NULL;
epmfsbasepath = NULL;
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
{
int rv;
basepath = basepaths[i].c_str();
fullpath = fs::path::make(basepath,fusepath);
rv = _try_statvfs(basepath,fusepath,epmfs,epmfsbasepath,mfs,mfsbasepath);
if(rv == -1)
_try_statvfs(basepath,mfs,mfsbasepath);
}
if(epmfsbasepath == NULL)
epmfsbasepath = mfsbasepath;
paths.push_back(epmfsbasepath);
return 0;
}
++iter;
static
int
_epmfs(const vector<string> &basepaths,
const string &fusepath,
vector<string> &paths)
{
fsblkcnt_t epmfs;
const char *basepath;
const char *epmfsbasepath;
string fullpath;
epmfs = 0;
epmfsbasepath = NULL;
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
{
int rv;
struct statvfs fsstats;
basepath = basepaths[i].c_str();
fullpath = fs::path::make(basepath,fusepath);
rv = ::statvfs(fullpath.c_str(),&fsstats);
if(rv == 0)
_calc_mfs(fsstats,basepath,epmfs,epmfsbasepath);
}
while(iter != eiter);
if(existingmfspath.empty())
existingmfspath = generalmfspath;
if(epmfsbasepath == NULL)
return (errno=ENOENT,-1);
paths.push_back(Path(existingmfspath,
fullpath));
paths.push_back(epmfsbasepath);
return 0;
}
namespace mergerfs
{
int
Policy::Func::epmfs(const Category::Enum::Type type,
const vector<string> &basepaths,
const string &fusepath,
const size_t minfreespace,
vector<string> &paths)
{
if(type == Category::Enum::create)
return _epmfs_create(basepaths,fusepath,paths);
return _epmfs(basepaths,fusepath,paths);
}
}

39
src/policy_ff.cpp

@ -37,34 +37,43 @@ using std::string;
using std::vector;
using std::size_t;
namespace mergerfs
{
static
int
Policy::Func::ff(const vector<string> &basepaths,
_ff(const vector<string> &basepaths,
const string &fusepath,
const size_t minfreespace,
Paths &paths)
vector<string> &paths)
{
errno = ENOENT;
for(vector<string>::const_iterator
iter = basepaths.begin(), eiter = basepaths.end();
iter != eiter;
++iter)
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
{
int rv;
struct stat st;
const char *basepath;
string fullpath;
fullpath = fs::make_path(*iter,fusepath);
basepath = basepaths[i].c_str();
fullpath = fs::path::make(basepath,fusepath);
rv = ::lstat(fullpath.c_str(),&st);
if(rv == 0)
{
paths.push_back(Path(*iter,fullpath));
if(rv == -1)
continue;
paths.push_back(basepath);
return 0;
}
return (errno=ENOENT,-1);
}
return -1;
namespace mergerfs
{
int
Policy::Func::ff(const Category::Enum::Type type,
const vector<string> &basepaths,
const string &fusepath,
const size_t minfreespace,
vector<string> &paths)
{
return _ff(basepaths,fusepath,paths);
}
}

46
src/policy_ffwp.cpp

@ -36,44 +36,54 @@ using std::string;
using std::vector;
using std::size_t;
namespace mergerfs
{
static
int
Policy::Func::ffwp(const vector<string> &basepaths,
_ffwp(const vector<string> &basepaths,
const string &fusepath,
const size_t minfreespace,
Paths &paths)
vector<string> &paths)
{
Path fallback;
const char *fallback;
errno = ENOENT;
for(vector<string>::const_iterator
iter = basepaths.begin(), eiter = basepaths.end();
iter != eiter;
++iter)
fallback = NULL;
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
{
int rv;
struct stat st;
const char *basepath;
string fullpath;
fullpath = fs::make_path(*iter,fusepath);
basepath = basepaths[i].c_str();
fullpath = fs::path::make(basepath,fusepath);
rv = ::lstat(fullpath.c_str(),&st);
if(rv == 0)
{
paths.push_back(Path(*iter,fullpath));
paths.push_back(basepath);
return 0;
}
else if(errno == EACCES)
{
fallback.base = *iter;
fallback.full = fullpath;
fallback = basepath;
}
}
if(!fallback.base.empty())
return (paths.push_back(fallback),0);
if(fallback == NULL)
return (errno=ENOENT,-1);
paths.push_back(fallback);
return 0;
}
return -1;
namespace mergerfs
{
int
Policy::Func::ffwp(const Category::Enum::Type type,
const vector<string> &basepaths,
const string &fusepath,
const size_t minfreespace,
vector<string> &paths)
{
return _ffwp(basepaths,fusepath,paths);
}
}

68
src/policy_fwfs.cpp

@ -33,14 +33,16 @@
using std::string;
using std::vector;
using std::size_t;
using mergerfs::Policy;
using mergerfs::Category;
namespace mergerfs
{
static
int
Policy::Func::fwfs(const vector<string> &basepaths,
_fwfs_create(const Category::Enum::Type type,
const vector<string> &basepaths,
const string &fusepath,
const size_t minfreespace,
Paths &paths)
vector<string> &paths)
{
for(size_t i = 0, size = basepaths.size(); i != size; i++)
{
@ -55,15 +57,65 @@ namespace mergerfs
fsblkcnt_t spaceavail;
spaceavail = (fsstats.f_frsize * fsstats.f_bavail);
if(spaceavail > minfreespace)
if(spaceavail < minfreespace)
continue;
paths.push_back(basepath);
return 0;
}
}
return Policy::Func::mfs(type,basepaths,fusepath,minfreespace,paths);
}
static
int
_fwfs(const Category::Enum::Type type,
const vector<string> &basepaths,
const string &fusepath,
const size_t minfreespace,
vector<string> &paths)
{
paths.push_back(Path(basepath,
fs::make_path(basepath,fusepath)));
for(size_t i = 0, size = basepaths.size(); i != size; i++)
{
int rv;
string fullpath;
const char *basepath;
struct statvfs fsstats;
basepath = basepaths[i].c_str();
fullpath = fs::path::make(basepath,fusepath);
rv = ::statvfs(fullpath.c_str(),&fsstats);
if(rv == 0)
{
fsblkcnt_t spaceavail;
spaceavail = (fsstats.f_frsize * fsstats.f_bavail);
if(spaceavail < minfreespace)
continue;
paths.push_back(basepath);
return 0;
}
}
return Policy::Func::mfs(type,basepaths,fusepath,minfreespace,paths);
}
return mfs(basepaths,fusepath,minfreespace,paths);
namespace mergerfs
{
int
Policy::Func::fwfs(const Category::Enum::Type type,
const vector<string> &basepaths,
const string &fusepath,
const size_t minfreespace,
vector<string> &paths)
{
if(type == Category::Enum::create)
return _fwfs_create(type,basepaths,fusepath,minfreespace,paths);
return _fwfs(type,basepaths,fusepath,minfreespace,paths);
}
}

5
src/policy_invalid.cpp

@ -36,10 +36,11 @@ using std::size_t;
namespace mergerfs
{
int
Policy::Func::invalid(const vector<string> &basepaths,
Policy::Func::invalid(const Category::Enum::Type type,
const vector<string> &basepaths,
const string &fusepath,
const size_t minfreespace,
Paths &rv)
vector<string> &rv)
{
return (errno = EINVAL,-1);
}

77
src/policy_lfs.cpp

@ -36,21 +36,23 @@
using std::string;
using std::vector;
using std::size_t;
using mergerfs::Policy;
using mergerfs::Category;
namespace mergerfs
{
static
int
Policy::Func::lfs(const vector<string> &basepaths,
_lfs_create(const Category::Enum::Type type,
const vector<string> &basepaths,
const string &fusepath,
const size_t minfreespace,
Paths &paths)
vector<string> &paths)
{
fsblkcnt_t lfs;
const char *lfsstr;
lfs = -1;
lfsstr = NULL;
for(size_t i = 0, size = basepaths.size(); i != size; i++)
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
{
int rv;
const char *basepath;
@ -73,11 +75,70 @@ namespace mergerfs
}
if(lfsstr == NULL)
return Policy::Func::mfs(basepaths,fusepath,minfreespace,paths);
return Policy::Func::mfs(type,basepaths,fusepath,minfreespace,paths);
paths.push_back(lfsstr);
return 0;
}
static
int
_lfs(const Category::Enum::Type type,
const vector<string> &basepaths,
const string &fusepath,
const size_t minfreespace,
vector<string> &paths)
{
fsblkcnt_t lfs;
const char *lfsstr;
lfs = -1;
lfsstr = NULL;
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
{
int rv;
string fullpath;
const char *basepath;
struct statvfs fsstats;
basepath = basepaths[i].c_str();
fullpath = fs::path::make(basepath,fusepath);
rv = ::statvfs(fullpath.c_str(),&fsstats);
if(rv == 0)
{
fsblkcnt_t spaceavail;
spaceavail = (fsstats.f_frsize * fsstats.f_bavail);
if((spaceavail > minfreespace) &&
(spaceavail < lfs))
{
lfs = spaceavail;
lfsstr = basepath;
}
}
}
if(lfsstr == NULL)
return Policy::Func::mfs(type,basepaths,fusepath,minfreespace,paths);
paths.push_back(Path(lfsstr,
fs::make_path(lfsstr,fusepath)));
paths.push_back(lfsstr);
return 0;
}
namespace mergerfs
{
int
Policy::Func::lfs(const Category::Enum::Type type,
const vector<string> &basepaths,
const string &fusepath,
const size_t minfreespace,
vector<string> &paths)
{
if(type == Category::Enum::create)
return _lfs_create(type,basepaths,fusepath,minfreespace,paths);
return _lfs(type,basepaths,fusepath,minfreespace,paths);
}
}

81
src/policy_mfs.cpp

@ -34,26 +34,67 @@ using std::string;
using std::vector;
using std::size_t;
namespace mergerfs
static
int
_mfs_create(const vector<string> &basepaths,
const string &fusepath,
vector<string> &paths)
{
fsblkcnt_t mfs;
const char *mfsstr;
mfs = 0;
mfsstr = NULL;
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
{
int rv;
const char *basepath;
struct statvfs fsstats;
basepath = basepaths[i].c_str();
rv = ::statvfs(basepath,&fsstats);
if(rv == 0)
{
fsblkcnt_t spaceavail;
spaceavail = (fsstats.f_frsize * fsstats.f_bavail);
if(spaceavail > mfs)
{
mfs = spaceavail;
mfsstr = basepath;
}
}
}
if(mfsstr == NULL)
return (errno=ENOENT,-1);
paths.push_back(mfsstr);
return 0;
}
static
int
Policy::Func::mfs(const vector<string> &basepaths,
_mfs(const vector<string> &basepaths,
const string &fusepath,
const size_t minfreespace,
Paths &paths)
vector<string> &paths)
{
fsblkcnt_t mfs;
size_t mfsidx;
const char *mfsstr;
mfs = 0;
for(size_t i = 0, size = basepaths.size();
i != size;
i++)
mfsstr = NULL;
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
{
int rv;
string fullpath;
const char *basepath;
struct statvfs fsstats;
rv = ::statvfs(basepaths[i].c_str(),&fsstats);
basepath = basepaths[i].c_str();
fullpath = fs::path::make(basepath,fusepath);
rv = ::statvfs(fullpath.c_str(),&fsstats);
if(rv == 0)
{
fsblkcnt_t spaceavail;
@ -62,17 +103,31 @@ namespace mergerfs
if(spaceavail > mfs)
{
mfs = spaceavail;
mfsidx = i;
mfsstr = basepath;
}
}
}
if(mfs == 0)
if(mfsstr == NULL)
return (errno=ENOENT,-1);
paths.push_back(Path(basepaths[mfsidx],
fs::make_path(basepaths[mfsidx],fusepath)));
paths.push_back(mfsstr);
return 0;
}
namespace mergerfs
{
int
Policy::Func::mfs(const Category::Enum::Type type,
const vector<string> &basepaths,
const string &fusepath,
const size_t minfreespace,
vector<string> &paths)
{
if(type == Category::Enum::create)
return _mfs_create(basepaths,fusepath,paths);
return _mfs(basepaths,fusepath,paths);
}
}

45
src/policy_newest.cpp

@ -36,43 +36,52 @@ using std::string;
using std::vector;
using std::size_t;
namespace mergerfs
{
static
int
Policy::Func::newest(const vector<string> &basepaths,
_newest(const vector<string> &basepaths,
const string &fusepath,
const size_t minfreespace,
Paths &paths)
vector<string> &paths)
{
time_t newest;
string npath;
vector<string>::const_iterator niter;
const char *neweststr;
newest = 0;
errno = ENOENT;
for(vector<string>::const_iterator
iter = basepaths.begin(), eiter = basepaths.end();
iter != eiter;
++iter)
neweststr = NULL;
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
{
int rv;
struct stat st;
const char *basepath;
string fullpath;
fullpath = fs::make_path(*iter,fusepath);
basepath = basepaths[i].c_str();
fullpath = fs::path::make(basepath,fusepath);
rv = ::lstat(fullpath.c_str(),&st);
if(rv == 0 && st.st_mtime > newest)
{
newest = st.st_mtime;
niter = iter;
npath = fullpath;
neweststr = basepath;
}
}
if(newest)
return (paths.push_back(Path(*niter,npath)),0);
if(neweststr == NULL)
return (errno=ENOENT,-1);
paths.push_back(neweststr);
return 0;
}
return -1;
namespace mergerfs
{
int
Policy::Func::newest(const Category::Enum::Type type,
const vector<string> &basepaths,
const string &fusepath,
const size_t minfreespace,
vector<string> &paths)
{
return _newest(basepaths,fusepath,paths);
}
}

7
src/policy_rand.cpp

@ -37,14 +37,15 @@ using std::size_t;
namespace mergerfs
{
int
Policy::Func::rand(const vector<string> &basepaths,
Policy::Func::rand(const Category::Enum::Type type,
const vector<string> &basepaths,
const string &fusepath,
const size_t minfreespace,
Paths &paths)
vector<string> &paths)
{
int rv;
rv = Policy::Func::all(basepaths,fusepath,minfreespace,paths);
rv = Policy::Func::all(type,basepaths,fusepath,minfreespace,paths);
if(rv == -1)
return -1;

7
src/readdir.cpp

@ -57,15 +57,12 @@ _readdir(const vector<string> &srcmounts,
set<string> found;
struct stat st = {0};
for(vector<string>::const_iterator
iter = srcmounts.begin(), enditer = srcmounts.end();
iter != enditer;
++iter)
for(size_t i = 0, ei = srcmounts.size(); i != ei; i++)
{
DIR *dh;
string basepath;
basepath = fs::make_path(*iter,dirname);
basepath = fs::path::make(srcmounts[i],dirname);
dh = ::opendir(basepath.c_str());
if(!dh)
continue;

10
src/readlink.cpp

@ -41,7 +41,7 @@ using mergerfs::Policy;
static
int
_readlink(const Policy::Func::Ptr searchFunc,
_readlink(Policy::Func::Search searchFunc,
const vector<string> &srcmounts,
const size_t minfreespace,
const string &fusepath,
@ -49,13 +49,15 @@ _readlink(const Policy::Func::Ptr searchFunc,
const size_t size)
{
int rv;
Paths path;
vector<string> path;
rv = searchFunc(srcmounts,fusepath,minfreespace,path);
if(rv == -1)
return -errno;
rv = ::readlink(path[0].full.c_str(),buf,size);
fs::path::append(path[0],fusepath);
rv = ::readlink(path[0].c_str(),buf,size);
if(rv == -1)
return -errno;
@ -78,7 +80,7 @@ namespace mergerfs
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _readlink(*config.readlink,
return _readlink(config.readlink,
config.srcmounts,
config.minfreespace,
fusepath,

13
src/removexattr.cpp

@ -42,7 +42,7 @@ using mergerfs::Policy;
static
int
_removexattr(const Policy::Func::Ptr actionFunc,
_removexattr(Policy::Func::Action actionFunc,
const vector<string> &srcmounts,
const size_t minfreespace,
const string &fusepath,
@ -51,17 +51,18 @@ _removexattr(const Policy::Func::Ptr actionFunc,
#ifndef WITHOUT_XATTR
int rv;
int error;
Paths paths;
vector<string> paths;
rv = actionFunc(srcmounts,fusepath,minfreespace,paths);
if(rv == -1)
return -errno;
error = 0;
for(Paths::const_iterator
i = paths.begin(), ei = paths.end(); i != ei; ++i)
for(size_t i = 0, ei = paths.size(); i != ei; i++)
{
rv = ::lremovexattr(i->full.c_str(),attrname);
fs::path::append(paths[i],fusepath);
rv = ::lremovexattr(paths[i].c_str(),attrname);
if(rv == -1)
error = errno;
}
@ -89,7 +90,7 @@ namespace mergerfs
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _removexattr(*config.removexattr,
return _removexattr(config.removexattr,
config.srcmounts,
config.minfreespace,
fusepath,

41
src/rename.cpp

@ -42,32 +42,33 @@ using mergerfs::Policy;
static
int
_single_rename(const Policy::Func::Ptr searchFunc,
_single_rename(Policy::Func::Search searchFunc,
const vector<string> &srcmounts,
const size_t minfreespace,
const Path &oldpath,
const string &oldbasepath,
const string &oldfullpath,
const string &newpath)
{
int rv;
const string fullnewpath = fs::make_path(oldpath.base,newpath);
const string newfullpath = fs::path::make(oldbasepath,newpath);
rv = ::rename(oldpath.full.c_str(),fullnewpath.c_str());
rv = ::rename(oldfullpath.c_str(),newfullpath.c_str());
if(rv == -1 && errno == ENOENT)
{
string dirname;
Paths newpathdir;
vector<string> newpathdir;
dirname = fs::dirname(newpath);
dirname = fs::path::dirname(newpath);
rv = searchFunc(srcmounts,dirname,minfreespace,newpathdir);
if(rv == -1)
return -1;
{
const mergerfs::ugid::SetResetGuard ugid(0,0);
fs::clonepath(newpathdir[0].base,oldpath.base,dirname);
fs::clonepath(newpathdir[0],oldbasepath,dirname);
}
rv = ::rename(oldpath.full.c_str(),fullnewpath.c_str());
rv = ::rename(oldfullpath.c_str(),newfullpath.c_str());
}
return rv;
@ -75,26 +76,28 @@ _single_rename(const Policy::Func::Ptr searchFunc,
static
int
_rename(const Policy::Func::Ptr searchFunc,
const Policy::Func::Ptr actionFunc,
_rename(Policy::Func::Search searchFunc,
Policy::Func::Action actionFunc,
const vector<string> &srcmounts,
const size_t minfreespace,
const string &oldpath,
const string &newpath)
const string &oldfusepath,
const string &newfusepath)
{
int rv;
int error;
Paths oldpaths;
vector<string> oldbasepaths;
rv = actionFunc(srcmounts,oldpath,minfreespace,oldpaths);
rv = actionFunc(srcmounts,oldfusepath,minfreespace,oldbasepaths);
if(rv == -1)
return -errno;
error = 0;
for(Paths::const_iterator
i = oldpaths.begin(), ei = oldpaths.end(); i != ei; ++i)
for(size_t i = 0, ei = oldbasepaths.size(); i != ei; i++)
{
rv = _single_rename(searchFunc,srcmounts,minfreespace,*i,newpath);
const string oldfullpath = fs::path::make(oldbasepaths[i],oldfusepath);
rv = _single_rename(searchFunc,srcmounts,minfreespace,
oldbasepaths[i],oldfullpath,newfusepath);
if(rv == -1)
error = errno;
}
@ -115,8 +118,8 @@ namespace mergerfs
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _rename(*config.getattr,
*config.rename,
return _rename(config.getattr,
config.rename,
config.srcmounts,
config.minfreespace,
oldpath,

13
src/rmdir.cpp

@ -40,24 +40,25 @@ using mergerfs::Policy;
static
int
_rmdir(const Policy::Func::Ptr actionFunc,
_rmdir(Policy::Func::Action actionFunc,
const vector<string> &srcmounts,
const size_t minfreespace,
const string &fusepath)
{
int rv;
int error;
Paths paths;
vector<string> paths;
rv = actionFunc(srcmounts,fusepath,minfreespace,paths);
if(rv == -1)
return -errno;
error = 0;
for(Paths::const_iterator
i = paths.begin(), ei = paths.end(); i != ei; ++i)
for(size_t i = 0, ei = paths.size(); i != ei; i++)
{
rv = ::rmdir(i->full.c_str());
fs::path::append(paths[i],fusepath);
rv = ::rmdir(paths[i].c_str());
if(rv == -1)
error = errno;
}
@ -77,7 +78,7 @@ namespace mergerfs
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readguard(&config.srcmountslock);
return _rmdir(*config.rmdir,
return _rmdir(config.rmdir,
config.srcmounts,
config.minfreespace,
fusepath);

13
src/setxattr.cpp

@ -240,7 +240,7 @@ _setxattr_controlfile(config::Config &config,
static
int
_setxattr(const Policy::Func::Ptr actionFunc,
_setxattr(Policy::Func::Action actionFunc,
const vector<string> &srcmounts,
const size_t minfreespace,
const string &fusepath,
@ -252,17 +252,18 @@ _setxattr(const Policy::Func::Ptr actionFunc,
#ifndef WITHOUT_XATTR
int rv;
int error;
Paths paths;
vector<string> paths;
rv = actionFunc(srcmounts,fusepath,minfreespace,paths);
if(rv == -1)
return -errno;
error = 0;
for(Paths::const_iterator
i = paths.begin(), ei = paths.end(); i != ei; ++i)
for(size_t i = 0, ei = paths.size(); i != ei; i++)
{
rv = ::lsetxattr(i->full.c_str(),attrname,attrval,attrvalsize,flags);
fs::path::append(paths[i],fusepath);
rv = ::lsetxattr(paths[i].c_str(),attrname,attrval,attrvalsize,flags);
if(rv == -1)
error = errno;
}
@ -301,7 +302,7 @@ namespace mergerfs
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _setxattr(*config.setxattr,
return _setxattr(config.setxattr,
config.srcmounts,
config.minfreespace,
fusepath,

4
src/statfs.cpp

@ -82,11 +82,11 @@ _statfs(const vector<string> &srcmounts,
vector<string>::const_iterator iter;
vector<string>::const_iterator enditer;
for(iter = srcmounts.begin(), enditer = srcmounts.end(); iter != enditer; ++iter)
for(size_t i = 0, ei = srcmounts.size(); i != ei; i++)
{
int rv;
struct statvfs fsstat;
rv = ::statvfs(iter->c_str(),&fsstat);
rv = ::statvfs(srcmounts[i].c_str(),&fsstat);
if(rv != 0)
continue;

15
src/symlink.cpp

@ -40,7 +40,7 @@ using mergerfs::Policy;
static
int
_symlink(const Policy::Func::Ptr createFunc,
_symlink(Policy::Func::Create createFunc,
const vector<string> &srcmounts,
const size_t minfreespace,
const string &oldpath,
@ -49,20 +49,19 @@ _symlink(const Policy::Func::Ptr createFunc,
int rv;
int error;
string newpathdir;
Paths newpathdirs;
vector<string> newpathdirs;
newpathdir = fs::dirname(newpath);
newpathdir = fs::path::dirname(newpath);
rv = createFunc(srcmounts,newpathdir,minfreespace,newpathdirs);
if(rv == -1)
return -errno;
error = 0;
for(Paths::iterator
i = newpathdirs.begin(), ei = newpathdirs.end(); i != ei; ++i)
for(size_t i = 0, ei = newpathdirs.size(); i != ei; i++)
{
i->full = fs::make_path(i->base,newpath);
fs::path::append(newpathdirs[i],newpath);
rv = symlink(oldpath.c_str(),i->full.c_str());
rv = symlink(oldpath.c_str(),newpathdirs[i].c_str());
if(rv == -1)
error = errno;
}
@ -83,7 +82,7 @@ namespace mergerfs
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _symlink(*config.symlink,
return _symlink(config.symlink,
config.srcmounts,
config.minfreespace,
oldpath,

13
src/truncate.cpp

@ -42,7 +42,7 @@ using mergerfs::Policy;
static
int
_truncate(const Policy::Func::Ptr actionFunc,
_truncate(Policy::Func::Action actionFunc,
const vector<string> &srcmounts,
const size_t minfreespace,
const string &fusepath,
@ -50,17 +50,18 @@ _truncate(const Policy::Func::Ptr actionFunc,
{
int rv;
int error;
Paths paths;
vector<string> paths;
rv = actionFunc(srcmounts,fusepath,minfreespace,paths);
if(rv == -1)
return -errno;
error = 0;
for(Paths::const_iterator
i = paths.begin(), ei = paths.end(); i != ei; ++i)
for(size_t i = 0, ei = paths.size(); i != ei; i++)
{
rv = ::truncate(i->full.c_str(),size);
fs::path::append(paths[i],fusepath);
rv = ::truncate(paths[i].c_str(),size);
if(rv == -1)
error = errno;
}
@ -81,7 +82,7 @@ namespace mergerfs
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _truncate(*config.truncate,
return _truncate(config.truncate,
config.srcmounts,
config.minfreespace,
fusepath,

13
src/unlink.cpp

@ -41,24 +41,25 @@ using mergerfs::Policy;
static
int
_unlink(const Policy::Func::Ptr actionFunc,
_unlink(Policy::Func::Action actionFunc,
const vector<string> &srcmounts,
const size_t minfreespace,
const string &fusepath)
{
int rv;
int error;
Paths paths;
vector<string> paths;
rv = actionFunc(srcmounts,fusepath,minfreespace,paths);
if(rv == -1)
return -errno;
error = 0;
for(Paths::const_iterator
i = paths.begin(), ei = paths.end(); i != ei; ++i)
for(size_t i = 0, ei = paths.size(); i != ei; i++)
{
rv = ::unlink(i->full.c_str());
fs::path::append(paths[i],fusepath);
rv = ::unlink(paths[i].c_str());
if(rv == -1)
error = errno;
}
@ -78,7 +79,7 @@ namespace mergerfs
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _unlink(*config.unlink,
return _unlink(config.unlink,
config.srcmounts,
config.minfreespace,
fusepath);

13
src/utimens.cpp

@ -42,7 +42,7 @@ using mergerfs::Policy;
static
int
_utimens(const Policy::Func::Ptr actionFunc,
_utimens(Policy::Func::Action actionFunc,
const vector<string> &srcmounts,
const size_t minfreespace,
const string &fusepath,
@ -50,17 +50,18 @@ _utimens(const Policy::Func::Ptr actionFunc,
{
int rv;
int error;
Paths paths;
vector<string> paths;
rv = actionFunc(srcmounts,fusepath,minfreespace,paths);
if(rv == -1)
return -errno;
error = 0;
for(Paths::const_iterator
i = paths.begin(), ei = paths.end(); i != ei; ++i)
for(size_t i = 0, ei = paths.size(); i != ei; i++)
{
rv = ::utimensat(0,i->full.c_str(),ts,AT_SYMLINK_NOFOLLOW);
fs::path::append(paths[i],fusepath);
rv = ::utimensat(0,paths[i].c_str(),ts,AT_SYMLINK_NOFOLLOW);
if(rv == -1)
error = errno;
}
@ -81,7 +82,7 @@ namespace mergerfs
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _utimens(*config.utimens,
return _utimens(config.utimens,
config.srcmounts,
config.minfreespace,
fusepath,

Loading…
Cancel
Save