Browse Source

Merge pull request #45 from trapexit/remove_all

Remove 'all' policy and simplify logic
pull/46/head
Antonio SJ Musumeci 10 years ago
parent
commit
58ec83dcd8
  1. 9
      README.md
  2. 4
      src/access.cpp
  3. 17
      src/chmod.cpp
  4. 17
      src/chown.cpp
  5. 10
      src/create.cpp
  6. 120
      src/fs.cpp
  7. 20
      src/fs.hpp
  8. 6
      src/getattr.cpp
  9. 10
      src/getxattr.cpp
  10. 6
      src/ioctl.cpp
  11. 40
      src/link.cpp
  12. 6
      src/listxattr.cpp
  13. 13
      src/mkdir.cpp
  14. 15
      src/mknod.cpp
  15. 8
      src/open.cpp
  16. 2
      src/policy.cpp
  17. 4
      src/policy.hpp
  18. 6
      src/readlink.cpp
  19. 17
      src/removexattr.cpp
  20. 6
      src/rename.cpp
  21. 17
      src/rmdir.cpp
  22. 17
      src/setxattr.cpp
  23. 12
      src/symlink.cpp
  24. 17
      src/truncate.cpp
  25. 17
      src/unlink.cpp
  26. 17
      src/utimens.cpp

9
README.md

@ -47,7 +47,7 @@ In /etc/fstab it'd look like the following:
# POLICIES # POLICIES
Filesystem calls are broken up into 4 functional categories: search, action, create, and none. These categories can be assigned a policy which dictates how [mergerfs](http://github.com/trapexit/mergerfs) behaves while when action on the filesystem. Any policy can be assigned to a category though some aren't terribly practical. For instance: rand (Random) may be useful for **create** but could lead to very odd behavior if used for **search** or **action**. Since the input for any policy is the source mounts and fusepath and the output a vector of targets the choice was made to simplify the implementation and allow a policies usage in any category. **NOTE:** In any policy which can return more than one location (currently only **all**) the first value will be used in **search** and **create** policies since they can only ever act on 1 filepath.
Filesystem calls are broken up into 3 categories: search, action, and create. There are also some calls which have no policy attached due to state being kept between calls. These categories can be assigned a policy which dictates how [mergerfs](http://github.com/trapexit/mergerfs) behaves. Any policy can be assigned to a category though some aren't terribly practical. For instance: rand (Random) may be useful for **create** but could lead to very odd behavior if used for **search** or **action**.
#### Functional classifications #### #### Functional classifications ####
| Class | FUSE calls | | Class | FUSE calls |
@ -60,13 +60,12 @@ Filesystem calls are broken up into 4 functional categories: search, action, cre
#### Policy descriptions #### #### Policy descriptions ####
| Policy | Description | | Policy | Description |
|--------------|-------------| |--------------|-------------|
| ff (first found) | Given the order the paths were provided at mount time act on the first one found (regardless if stat would return EACCES). |
| ffwp (first found w/ permissions) | Given the order the paths were provided at mount time act on the first one found which you have access (stat does not error with EACCES). |
| ff (first found) | Given the order of the paths act on the first one found (regardless if stat would return EACCES). |
| ffwp (first found w/ permissions) | Given the order of the paths act on the first one found which you have access (stat does not error with EACCES). |
| newest (newest file) | If multiple files exist return the one with the most recent mtime. | | newest (newest file) | If multiple files exist return the one with the most recent mtime. |
| all (all files found) | Attempt to apply the call to each file found. If any sub call succeeds the entire operation succeeds and other errors ignored. If all fail then the last error is reported. |
| mfs (most free space) | Assuming the path is found to exist (ENOENT would not be returned) use the drive with the most free space available. | | mfs (most free space) | Assuming the path is found to exist (ENOENT would not be returned) use the drive with the most free space available. |
| epmfs (existing path, most free space) | If the path exists in multiple locations use the one with the most free space. Otherwise fall back to mfs. | | epmfs (existing path, most free space) | If the path exists in multiple locations use the one with the most free space. Otherwise fall back to mfs. |
| rand (random) | Pick a destination at random. Again the dirname of the full path must exist somewhere. |
| rand (random) | Pick an existing destination at random. |
#### statvfs #### #### statvfs ####

4
src/access.cpp

@ -51,13 +51,13 @@ _access(const fs::SearchFunc searchFunc,
const int mask) const int mask)
{ {
int rv; int rv;
fs::PathVector path;
fs::Path path;
rv = searchFunc(srcmounts,fusepath,path); rv = searchFunc(srcmounts,fusepath,path);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
rv = ::eaccess(path[0].full.c_str(),mask);
rv = ::eaccess(path.full.c_str(),mask);
return ((rv == -1) ? -errno : 0); return ((rv == -1) ? -errno : 0);
} }

17
src/chmod.cpp

@ -45,24 +45,15 @@ _chmod(const fs::SearchFunc searchFunc,
const mode_t mode) const mode_t mode)
{ {
int rv; int rv;
int error;
fs::PathVector paths;
fs::Path path;
rv = searchFunc(srcmounts,fusepath,paths);
rv = searchFunc(srcmounts,fusepath,path);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
rv = -1;
error = 0;
for(fs::PathVector::const_iterator
i = paths.begin(), ei = paths.end(); i != ei; ++i)
{
rv &= ::chmod(i->full.c_str(),mode);
if(rv == -1)
error = errno;
}
rv = ::chmod(path.full.c_str(),mode);
return ((rv == -1) ? -error : 0);
return ((rv == -1) ? -errno : 0);
} }
namespace mergerfs namespace mergerfs

17
src/chown.cpp

@ -47,24 +47,15 @@ _chown(const fs::SearchFunc searchFunc,
const gid_t gid) const gid_t gid)
{ {
int rv; int rv;
int error;
fs::PathVector paths;
fs::Path path;
rv = searchFunc(srcmounts,fusepath,paths);
rv = searchFunc(srcmounts,fusepath,path);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
rv = -1;
error = 0;
for(fs::PathVector::const_iterator
i = paths.begin(), ei = paths.end(); i != ei; ++i)
{
rv &= ::lchown(i->full.c_str(),uid,gid);
if(rv == -1)
error = errno;
}
rv = ::lchown(path.full.c_str(),uid,gid);
return ((rv == -1) ? -error : 0);
return ((rv == -1) ? -errno : 0);
} }
namespace mergerfs namespace mergerfs

10
src/create.cpp

@ -57,8 +57,8 @@ _create(const fs::SearchFunc searchFunc,
int rv; int rv;
string path; string path;
string dirname; string dirname;
fs::PathVector createpath;
fs::PathVector existingpath;
fs::Path createpath;
fs::Path existingpath;
dirname = fs::dirname(fusepath); dirname = fs::dirname(fusepath);
rv = searchFunc(srcmounts,dirname,existingpath); rv = searchFunc(srcmounts,dirname,existingpath);
@ -69,13 +69,13 @@ _create(const fs::SearchFunc searchFunc,
if(rv == -1) if(rv == -1)
return -errno; return -errno;
if(createpath[0].base != existingpath[0].base)
if(createpath.base != existingpath.base)
{ {
const mergerfs::ugid::SetResetGuard ugid(0,0); const mergerfs::ugid::SetResetGuard ugid(0,0);
fs::clonepath(existingpath[0].base,createpath[0].base,dirname);
fs::clonepath(existingpath.base,createpath.base,dirname);
} }
path = fs::make_path(createpath[0].base,fusepath);
path = fs::make_path(createpath.base,fusepath);
fd = ::open(path.c_str(),flags,mode); fd = ::open(path.c_str(),flags,mode);
if(fd == -1) if(fd == -1)

120
src/fs.cpp

@ -500,7 +500,7 @@ namespace fs
int int
invalid(const vector<string> &basepaths, invalid(const vector<string> &basepaths,
const string &fusepath, const string &fusepath,
PathVector &paths)
Path &rv)
{ {
return (errno = EINVAL,-1); return (errno = EINVAL,-1);
} }
@ -508,7 +508,7 @@ namespace fs
int int
ff(const vector<string> &basepaths, ff(const vector<string> &basepaths,
const string &fusepath, const string &fusepath,
PathVector &paths)
Path &path)
{ {
errno = ENOENT; errno = ENOENT;
for(vector<string>::const_iterator for(vector<string>::const_iterator
@ -517,13 +517,18 @@ namespace fs
++iter) ++iter)
{ {
int rv; int rv;
string path;
struct stat st; struct stat st;
string fullpath;
path = fs::make_path(*iter,fusepath);
rv = ::lstat(path.c_str(),&st);
fullpath = fs::make_path(*iter,fusepath);
rv = ::lstat(fullpath.c_str(),&st);
if(rv == 0) if(rv == 0)
return (paths.push_back(Path(*iter,path)),0);
{
path.base = *iter;
path.full = fullpath;
return 0;
}
} }
return -1; return -1;
@ -532,7 +537,7 @@ namespace fs
int int
ffwp(const vector<string> &basepaths, ffwp(const vector<string> &basepaths,
const string &fusepath, const string &fusepath,
PathVector &paths)
Path &path)
{ {
Path fallback; Path fallback;
@ -543,24 +548,27 @@ namespace fs
++iter) ++iter)
{ {
int rv; int rv;
string path;
struct stat st; struct stat st;
string fullpath;
path = fs::make_path(*iter,fusepath);
rv = ::lstat(path.c_str(),&st);
fullpath = fs::make_path(*iter,fusepath);
rv = ::lstat(fullpath.c_str(),&st);
if(rv == 0) if(rv == 0)
{ {
return (paths.push_back(Path(*iter,path)),0);
path.base = *iter;
path.full = fullpath;
return 0;
} }
else if(errno == EACCES) else if(errno == EACCES)
{ {
fallback.base = *iter; fallback.base = *iter;
fallback.full = path;
fallback.full = fullpath;
} }
} }
if(!fallback.base.empty()) if(!fallback.base.empty())
return (paths.push_back(fallback),0);
return (path = fallback,0);
return -1; return -1;
} }
@ -568,7 +576,7 @@ namespace fs
int int
newest(const vector<string> &basepaths, newest(const vector<string> &basepaths,
const string &fusepath, const string &fusepath,
PathVector &paths)
Path &path)
{ {
time_t newest; time_t newest;
string npath; string npath;
@ -583,68 +591,46 @@ namespace fs
{ {
int rv; int rv;
struct stat st; struct stat st;
const string path = fs::make_path(*iter,fusepath);
string fullpath;
rv = ::lstat(path.c_str(),&st);
fullpath = fs::make_path(*iter,fusepath);
rv = ::lstat(fullpath.c_str(),&st);
if(rv == 0 && st.st_mtime > newest) if(rv == 0 && st.st_mtime > newest)
{ {
newest = st.st_mtime; newest = st.st_mtime;
niter = iter; niter = iter;
npath = path;
npath = fullpath;
} }
} }
if(newest) if(newest)
return (paths.push_back(Path(*niter,npath)),0);
return -1;
}
int
all(const vector<string> &basepaths,
const string &fusepath,
PathVector &paths)
{ {
errno = ENOENT;
for(vector<string>::const_iterator
iter = basepaths.begin(), eiter = basepaths.end();
iter != eiter;
++iter)
{
int rv;
string path;
struct stat st;
path = fs::make_path(*iter,fusepath);
rv = ::lstat(path.c_str(),&st);
if(rv == 0)
paths.push_back(Path(*iter,path));
path.base = *niter;
path.full = npath;
return 0;
} }
return paths.empty() ? -1 : 0;
return -1;
} }
int int
mfs(const vector<string> &basepaths, mfs(const vector<string> &basepaths,
const string &fusepath, const string &fusepath,
PathVector &paths)
Path &path)
{ {
fsblkcnt_t mfs; fsblkcnt_t mfs;
string mfspath;
string fullmfspath;
size_t mfsidx;
mfs = 0; mfs = 0;
errno = ENOENT;
for(vector<string>::const_iterator
iter = basepaths.begin(), eiter = basepaths.end();
iter != eiter;
++iter)
for(size_t i = 0, size = basepaths.size();
i != size;
i++)
{ {
int rv; int rv;
struct statvfs fsstats; struct statvfs fsstats;
const string &mountpoint = *iter;
rv = ::statvfs(mountpoint.c_str(),&fsstats);
rv = ::statvfs(basepaths[i].c_str(),&fsstats);
if(rv == 0) if(rv == 0)
{ {
fsblkcnt_t spaceavail; fsblkcnt_t spaceavail;
@ -653,17 +639,16 @@ namespace fs
if(spaceavail > mfs) if(spaceavail > mfs)
{ {
mfs = spaceavail; mfs = spaceavail;
mfspath = mountpoint;
mfsidx = i;
} }
} }
} }
if(mfs == 0) if(mfs == 0)
return -1;
return (errno=ENOENT,-1);
fullmfspath = fs::make_path(mfspath,fusepath);
paths.push_back(Path(mfspath,fullmfspath));
path.base = basepaths[mfsidx];
path.full = fs::make_path(path.base,fusepath);
return 0; return 0;
} }
@ -671,11 +656,11 @@ namespace fs
int int
epmfs(const vector<string> &basepaths, epmfs(const vector<string> &basepaths,
const string &fusepath, const string &fusepath,
PathVector &paths)
Path &path)
{ {
fsblkcnt_t existingmfs = 0; fsblkcnt_t existingmfs = 0;
fsblkcnt_t generalmfs = 0; fsblkcnt_t generalmfs = 0;
string path;
string fullpath;
string generalmfspath; string generalmfspath;
string existingmfspath; string existingmfspath;
vector<string>::const_iterator iter = basepaths.begin(); vector<string>::const_iterator iter = basepaths.begin();
@ -703,8 +688,8 @@ namespace fs
generalmfspath = mountpoint; generalmfspath = mountpoint;
} }
path = fs::make_path(mountpoint,fusepath);
rv = ::lstat(path.c_str(),&st);
fullpath = fs::make_path(mountpoint,fusepath);
rv = ::lstat(fullpath.c_str(),&st);
if(rv == 0) if(rv == 0)
{ {
if(spaceavail > existingmfs) if(spaceavail > existingmfs)
@ -722,7 +707,8 @@ namespace fs
if(existingmfspath.empty()) if(existingmfspath.empty())
existingmfspath = generalmfspath; existingmfspath = generalmfspath;
paths.push_back(Path(existingmfspath,path));
path.base = existingmfspath;
path.full = fullpath;
return 0; return 0;
} }
@ -730,19 +716,13 @@ namespace fs
int int
rand(const vector<string> &basepaths, rand(const vector<string> &basepaths,
const string &fusepath, const string &fusepath,
PathVector &paths)
Path &path)
{ {
string randombasepath;
string randomfullpath;
randombasepath = *random_element(basepaths.begin(),
path.base = *random_element(basepaths.begin(),
basepaths.end()); basepaths.end());
randomfullpath = fs::make_path(randombasepath,
path.full = fs::make_path(path.base,
fusepath); fusepath);
paths.push_back(Path(randombasepath,randomfullpath));
return 0; return 0;
} }
} }

20
src/fs.hpp

@ -48,8 +48,7 @@ namespace fs
string full; string full;
}; };
typedef vector<Path> PathVector;
typedef int (*SearchFunc)(const vector<string>&,const string&,PathVector&);
typedef int (*SearchFunc)(const vector<string>&,const string&,Path&);
string dirname(const string &path); string dirname(const string &path);
string basename(const string &path); string basename(const string &path);
@ -114,28 +113,25 @@ namespace fs
{ {
int invalid(const vector<string> &basepaths, int invalid(const vector<string> &basepaths,
const string &fusepath, const string &fusepath,
PathVector &paths);
Path &path);
int ff(const vector<string> &basepaths, int ff(const vector<string> &basepaths,
const string &fusepath, const string &fusepath,
PathVector &paths);
Path &path);
int ffwp(const vector<string> &paths, int ffwp(const vector<string> &paths,
const string &fusepath, const string &fusepath,
PathVector &rv);
Path &path);
int newest(const vector<string> &paths, int newest(const vector<string> &paths,
const string &fusepath, const string &fusepath,
PathVector &rv);
int all(const vector<string> &paths,
const string &fusepath,
PathVector &rv);
Path &path);
int mfs(const vector<string> &paths, int mfs(const vector<string> &paths,
const string &fusepath, const string &fusepath,
PathVector &rv);
Path &path);
int epmfs(const vector<string> &paths, int epmfs(const vector<string> &paths,
const string &fusepath, const string &fusepath,
PathVector &rv);
Path &path);
int rand(const vector<string> &paths, int rand(const vector<string> &paths,
const string &fusepath, const string &fusepath,
PathVector &rv);
Path &path);
} }
}; };

6
src/getattr.cpp

@ -71,13 +71,13 @@ _getattr(const fs::SearchFunc searchFunc,
struct stat &buf) struct stat &buf)
{ {
int rv; int rv;
fs::PathVector paths;
fs::Path path;
rv = searchFunc(srcmounts,fusepath,paths);
rv = searchFunc(srcmounts,fusepath,path);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
rv = ::lstat(paths[0].full.c_str(),&buf);
rv = ::lstat(path.full.c_str(),&buf);
return ((rv == -1) ? -errno : 0); return ((rv == -1) ? -errno : 0);
} }

10
src/getxattr.cpp

@ -107,18 +107,18 @@ _getxattr(const fs::SearchFunc searchFunc,
{ {
#ifndef WITHOUT_XATTR #ifndef WITHOUT_XATTR
int rv; int rv;
fs::PathVector paths;
fs::Path path;
rv = searchFunc(srcmounts,fusepath,paths);
rv = searchFunc(srcmounts,fusepath,path);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
if(!strcmp(attrname,"user.mergerfs.basepath")) if(!strcmp(attrname,"user.mergerfs.basepath"))
rv = ::_getxattr_from_string(buf,count,paths[0].base);
rv = ::_getxattr_from_string(buf,count,path.base);
else if(!strcmp(attrname,"user.mergerfs.fullpath")) else if(!strcmp(attrname,"user.mergerfs.fullpath"))
rv = ::_getxattr_from_string(buf,count,paths[0].full);
rv = ::_getxattr_from_string(buf,count,path.full);
else else
rv = ::lgetxattr(paths[0].full.c_str(),attrname,buf,count);
rv = ::lgetxattr(path.full.c_str(),attrname,buf,count);
return ((rv == -1) ? -errno : rv); return ((rv == -1) ? -errno : rv);
#else #else

6
src/ioctl.cpp

@ -93,13 +93,13 @@ _ioctl_dir_base(const fs::SearchFunc searchFunc,
{ {
int fd; int fd;
int rv; int rv;
fs::PathVector paths;
fs::Path path;
rv = searchFunc(srcmounts,fusepath,paths);
rv = searchFunc(srcmounts,fusepath,path);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
fd = ::open(paths[0].full.c_str(),flags);
fd = ::open(path.full.c_str(),flags);
if(fd == -1) if(fd == -1)
return -errno; return -errno;

40
src/link.cpp

@ -47,47 +47,35 @@ _link(const fs::SearchFunc searchFunc,
const string &to) const string &to)
{ {
int rv; int rv;
int error;
fs::PathVector paths;
fs::Path path;
rv = searchFunc(srcmounts,from,paths);
rv = searchFunc(srcmounts,from,path);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
rv = -1;
error = 0;
for(fs::PathVector::const_iterator
i = paths.begin(), ei = paths.end(); i != ei; ++i)
{
int lrv;
const string pathfrom = fs::make_path(i->base,from);
const string pathto = fs::make_path(i->base,to);
const string pathfrom = fs::make_path(path.base,from);
const string pathto = fs::make_path(path.base,to);
lrv = ::link(pathfrom.c_str(),pathto.c_str());
if(lrv == -1 && errno == ENOENT)
rv = ::link(pathfrom.c_str(),pathto.c_str());
if(rv == -1 && errno == ENOENT)
{ {
string todir; string todir;
fs::PathVector topaths;
fs::Path foundpath;
todir = fs::dirname(to); todir = fs::dirname(to);
fs::find::ffwp(srcmounts,todir,topaths);
if(topaths.size() > 0)
{
rv = fs::find::ffwp(srcmounts,todir,foundpath);
if(rv == -1)
return -errno;
{ {
const mergerfs::ugid::SetResetGuard ugid(0,0); const mergerfs::ugid::SetResetGuard ugid(0,0);
fs::clonepath(topaths[0].base,i->base,todir);
fs::clonepath(foundpath.base,path.base,todir);
} }
lrv = ::link(pathfrom.c_str(),pathto.c_str());
}
}
rv &= lrv;
if(rv == -1)
error = errno;
rv = ::link(pathfrom.c_str(),pathto.c_str());
} }
return ((rv == -1) ? -error : 0);
return ((rv == -1) ? -errno : 0);
} }
namespace mergerfs namespace mergerfs

6
src/listxattr.cpp

@ -75,13 +75,13 @@ _listxattr(const fs::SearchFunc searchFunc,
{ {
#ifndef WITHOUT_XATTR #ifndef WITHOUT_XATTR
int rv; int rv;
fs::PathVector paths;
fs::Path path;
rv = searchFunc(srcmounts,fusepath,paths);
rv = searchFunc(srcmounts,fusepath,path);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
rv = ::llistxattr(paths[0].full.c_str(),list,size);
rv = ::llistxattr(path.full.c_str(),list,size);
return ((rv == -1) ? -errno : rv); return ((rv == -1) ? -errno : rv);
#else #else

13
src/mkdir.cpp

@ -51,8 +51,8 @@ _mkdir(const fs::SearchFunc searchFunc,
int rv; int rv;
string path; string path;
string dirname; string dirname;
fs::PathVector createpath;
fs::PathVector existingpath;
fs::Path createpath;
fs::Path existingpath;
if(fs::path_exists(srcmounts,fusepath)) if(fs::path_exists(srcmounts,fusepath))
return -EEXIST; return -EEXIST;
@ -63,13 +63,16 @@ _mkdir(const fs::SearchFunc searchFunc,
return -errno; return -errno;
rv = createPathFunc(srcmounts,dirname,createpath); rv = createPathFunc(srcmounts,dirname,createpath);
if(createpath[0].base != existingpath[0].base)
if(rv == -1)
return -errno;
if(createpath.base != existingpath.base)
{ {
const mergerfs::ugid::SetResetGuard ugid(0,0); const mergerfs::ugid::SetResetGuard ugid(0,0);
fs::clonepath(existingpath[0].base,createpath[0].base,dirname);
fs::clonepath(existingpath.base,createpath.base,dirname);
} }
path = fs::make_path(createpath[0].base,fusepath);
path = fs::make_path(createpath.base,fusepath);
rv = ::mkdir(path.c_str(),mode); rv = ::mkdir(path.c_str(),mode);

15
src/mknod.cpp

@ -53,8 +53,8 @@ _mknod(const fs::SearchFunc searchFunc,
int rv; int rv;
string path; string path;
string dirname; string dirname;
fs::PathVector createpath;
fs::PathVector existingpath;
fs::Path createpath;
fs::Path existingpath;
if(fs::path_exists(srcmounts,fusepath)) if(fs::path_exists(srcmounts,fusepath))
return -EEXIST; return -EEXIST;
@ -64,14 +64,17 @@ _mknod(const fs::SearchFunc searchFunc,
if(rv == -1) if(rv == -1)
return -errno; return -errno;
createPathFunc(srcmounts,dirname,createpath);
if(existingpath[0].base != createpath[0].base)
rv = createPathFunc(srcmounts,dirname,createpath);
if(rv == -1)
return -errno;
if(existingpath.base != createpath.base)
{ {
const mergerfs::ugid::SetResetGuard ugid(0,0); const mergerfs::ugid::SetResetGuard ugid(0,0);
fs::clonepath(existingpath[0].base,createpath[0].base,dirname);
fs::clonepath(existingpath.base,createpath.base,dirname);
} }
path = fs::make_path(createpath[0].base,fusepath);
path = fs::make_path(createpath.base,fusepath);
rv = ::mknod(path.c_str(),mode,dev); rv = ::mknod(path.c_str(),mode,dev);

8
src/open.cpp

@ -51,17 +51,17 @@ _open(const fs::SearchFunc searchFunc,
{ {
int fd; int fd;
int rv; int rv;
fs::PathVector paths;
fs::Path path;
rv = searchFunc(srcmounts,fusepath,paths);
rv = searchFunc(srcmounts,fusepath,path);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
fd = ::open(paths[0].full.c_str(),flags);
fd = ::open(path.full.c_str(),flags);
if(fd == -1) if(fd == -1)
return -errno; return -errno;
fh = (uint64_t)new FileInfo(fd,flags,paths[0].full);
fh = (uint64_t)new FileInfo(fd,flags,path.full);
return 0; return 0;
} }

2
src/policy.cpp

@ -35,7 +35,6 @@ namespace mergerfs
const std::vector<Policy> Policy::_policies_ = const std::vector<Policy> Policy::_policies_ =
buildvector<Policy,true> buildvector<Policy,true>
(POLICY(invalid)) (POLICY(invalid))
(POLICY(all))
(POLICY(epmfs)) (POLICY(epmfs))
(POLICY(ff)) (POLICY(ff))
(POLICY(ffwp)) (POLICY(ffwp))
@ -46,7 +45,6 @@ namespace mergerfs
const Policy * const Policy::policies = &_policies_[1]; const Policy * const Policy::policies = &_policies_[1];
const Policy &Policy::invalid = Policy::policies[Policy::Enum::invalid]; const Policy &Policy::invalid = Policy::policies[Policy::Enum::invalid];
const Policy &Policy::all = Policy::policies[Policy::Enum::all];
const Policy &Policy::epmfs = Policy::policies[Policy::Enum::epmfs]; const Policy &Policy::epmfs = Policy::policies[Policy::Enum::epmfs];
const Policy &Policy::ff = Policy::policies[Policy::Enum::ff]; const Policy &Policy::ff = Policy::policies[Policy::Enum::ff];
const Policy &Policy::ffwp = Policy::policies[Policy::Enum::ffwp]; const Policy &Policy::ffwp = Policy::policies[Policy::Enum::ffwp];

4
src/policy.hpp

@ -41,8 +41,7 @@ namespace mergerfs
{ {
invalid = -1, invalid = -1,
BEGIN = 0, BEGIN = 0,
all = BEGIN,
epmfs,
epmfs = BEGIN,
ff, ff,
ffwp, ffwp,
mfs, mfs,
@ -101,7 +100,6 @@ namespace mergerfs
static const std::vector<Policy> _policies_; static const std::vector<Policy> _policies_;
static const Policy * const policies; static const Policy * const policies;
static const Policy &invalid; static const Policy &invalid;
static const Policy &all;
static const Policy &epmfs; static const Policy &epmfs;
static const Policy &ff; static const Policy &ff;
static const Policy &ffwp; static const Policy &ffwp;

6
src/readlink.cpp

@ -48,13 +48,13 @@ _readlink(const fs::SearchFunc searchFunc,
const size_t size) const size_t size)
{ {
int rv; int rv;
fs::PathVector paths;
fs::Path path;
rv = searchFunc(srcmounts,fusepath,paths);
rv = searchFunc(srcmounts,fusepath,path);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
rv = ::readlink(paths[0].full.c_str(),buf,size);
rv = ::readlink(path.full.c_str(),buf,size);
if(rv == -1) if(rv == -1)
return -errno; return -errno;

17
src/removexattr.cpp

@ -48,24 +48,15 @@ _removexattr(const fs::SearchFunc searchFunc,
{ {
#ifndef WITHOUT_XATTR #ifndef WITHOUT_XATTR
int rv; int rv;
int error;
fs::PathVector paths;
fs::Path path;
rv = searchFunc(srcmounts,fusepath,paths);
rv = searchFunc(srcmounts,fusepath,path);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
rv = -1;
error = 0;
for(fs::PathVector::const_iterator
i = paths.begin(), ei = paths.end(); i != ei; ++i)
{
rv &= ::lremovexattr(i->full.c_str(),attrname);
if(rv == -1)
error = errno;
}
rv = ::lremovexattr(path.full.c_str(),attrname);
return ((rv == -1) ? -error : 0);
return ((rv == -1) ? -errno : 0);
#else #else
return -ENOTSUP; return -ENOTSUP;
#endif #endif

6
src/rename.cpp

@ -48,15 +48,15 @@ _rename(const fs::SearchFunc searchFunc,
{ {
int rv; int rv;
string pathto; string pathto;
fs::PathVector pathfrom;
fs::Path pathfrom;
rv = searchFunc(srcmounts,from,pathfrom); rv = searchFunc(srcmounts,from,pathfrom);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
pathto = fs::make_path(pathfrom[0].base,to);
pathto = fs::make_path(pathfrom.base,to);
rv = ::rename(pathfrom[0].full.c_str(),pathto.c_str());
rv = ::rename(pathfrom.full.c_str(),pathto.c_str());
if(rv == -1 && errno == ENOENT) if(rv == -1 && errno == ENOENT)
return -EXDEV; return -EXDEV;

17
src/rmdir.cpp

@ -45,24 +45,15 @@ _rmdir(const fs::SearchFunc searchFunc,
const string &fusepath) const string &fusepath)
{ {
int rv; int rv;
int error;
fs::PathVector paths;
fs::Path path;
rv = searchFunc(srcmounts,fusepath,paths);
rv = searchFunc(srcmounts,fusepath,path);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
rv = -1;
error = 0;
for(fs::PathVector::const_iterator
i = paths.begin(), ei = paths.end(); i != ei; ++i)
{
rv &= ::rmdir(i->full.c_str());
if(rv == -1)
error = errno;
}
rv = ::rmdir(path.full.c_str());
return ((rv == -1) ? -error : 0);
return ((rv == -1) ? -errno : 0);
} }
namespace mergerfs namespace mergerfs

17
src/setxattr.cpp

@ -234,24 +234,15 @@ _setxattr(const fs::SearchFunc searchFunc,
{ {
#ifndef WITHOUT_XATTR #ifndef WITHOUT_XATTR
int rv; int rv;
int error;
fs::PathVector paths;
fs::Path path;
rv = searchFunc(srcmounts,fusepath,paths);
rv = searchFunc(srcmounts,fusepath,path);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
rv = -1;
error = 0;
for(fs::PathVector::const_iterator
i = paths.begin(), ei = paths.end(); i != ei; ++i)
{
rv &= ::lsetxattr(i->full.c_str(),attrname,attrval,attrvalsize,flags);
if(rv == -1)
error = errno;
}
rv = ::lsetxattr(path.full.c_str(),attrname,attrval,attrvalsize,flags);
return ((rv == -1) ? -error : 0);
return ((rv == -1) ? -errno : 0);
#else #else
return -ENOTSUP; return -ENOTSUP;
#endif #endif

12
src/symlink.cpp

@ -44,15 +44,15 @@ _symlink(const vector<string> &srcmounts,
const string &to) const string &to)
{ {
int rv; int rv;
fs::PathVector paths;
fs::Path path;
fs::find::ff(srcmounts,fs::dirname(to),paths);
if(paths.empty())
return -ENOENT;
rv = fs::find::ff(srcmounts,fs::dirname(to),path);
if(rv == -1)
return -errno;
paths[0].full = fs::make_path(paths[0].base,to);
path.full = fs::make_path(path.base,to);
rv = symlink(from.c_str(),paths[0].full.c_str());
rv = symlink(from.c_str(),path.full.c_str());
return ((rv == -1) ? -errno : 0); return ((rv == -1) ? -errno : 0);
} }

17
src/truncate.cpp

@ -47,24 +47,15 @@ _truncate(const fs::SearchFunc searchFunc,
const off_t size) const off_t size)
{ {
int rv; int rv;
int error;
fs::PathVector paths;
fs::Path path;
rv = searchFunc(srcmounts,fusepath,paths);
rv = searchFunc(srcmounts,fusepath,path);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
rv = -1;
error = 0;
for(fs::PathVector::const_iterator
i = paths.begin(), ei = paths.end(); i != ei; ++i)
{
rv &= ::truncate(i->full.c_str(),size);
if(rv == -1)
error = errno;
}
rv = ::truncate(path.full.c_str(),size);
return ((rv == -1) ? -error : 0);
return ((rv == -1) ? -errno : 0);
} }
namespace mergerfs namespace mergerfs

17
src/unlink.cpp

@ -45,24 +45,15 @@ _unlink(const fs::SearchFunc searchFunc,
const string &fusepath) const string &fusepath)
{ {
int rv; int rv;
int error;
fs::PathVector paths;
fs::Path path;
rv = searchFunc(srcmounts,fusepath,paths);
rv = searchFunc(srcmounts,fusepath,path);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
rv = -1;
error = 0;
for(fs::PathVector::const_iterator
i = paths.begin(), ei = paths.end(); i != ei; ++i)
{
rv &= ::unlink(i->full.c_str());
if(rv == -1)
error = errno;
}
rv = ::unlink(path.full.c_str());
return ((rv == -1) ? -error : 0);
return ((rv == -1) ? -errno : 0);
} }
namespace mergerfs namespace mergerfs

17
src/utimens.cpp

@ -47,24 +47,15 @@ _utimens(const fs::SearchFunc searchFunc,
const struct timespec ts[2]) const struct timespec ts[2])
{ {
int rv; int rv;
int error;
fs::PathVector paths;
fs::Path path;
rv = searchFunc(srcmounts,fusepath,paths);
rv = searchFunc(srcmounts,fusepath,path);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
rv = -1;
error = 0;
for(fs::PathVector::const_iterator
i = paths.begin(), ei = paths.end(); i != ei; ++i)
{
rv &= ::utimensat(0,i->full.c_str(),ts,AT_SYMLINK_NOFOLLOW);
if(rv == -1)
error = errno;
}
rv = ::utimensat(0,path.full.c_str(),ts,AT_SYMLINK_NOFOLLOW);
return ((rv == -1) ? -error : 0);
return ((rv == -1) ? -errno : 0);
} }
namespace mergerfs namespace mergerfs

Loading…
Cancel
Save