mirror of
https://github.com/trapexit/mergerfs.git
synced 2025-02-21 08:25:11 +08:00
Remove 'all' policy and simplify logic
This commit is contained in:
parent
1f61a662ad
commit
b411c63df1
@ -47,7 +47,7 @@ In /etc/fstab it'd look like the following:
|
||||
|
||||
# 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 ####
|
||||
| Class | FUSE calls |
|
||||
@ -60,13 +60,12 @@ Filesystem calls are broken up into 4 functional categories: search, action, cre
|
||||
#### Policy descriptions ####
|
||||
| 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. |
|
||||
| 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. |
|
||||
| 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 ####
|
||||
|
||||
|
@ -51,13 +51,13 @@ _access(const fs::SearchFunc searchFunc,
|
||||
const int mask)
|
||||
{
|
||||
int rv;
|
||||
fs::PathVector path;
|
||||
fs::Path path;
|
||||
|
||||
rv = searchFunc(srcmounts,fusepath,path);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
rv = ::eaccess(path[0].full.c_str(),mask);
|
||||
rv = ::eaccess(path.full.c_str(),mask);
|
||||
|
||||
return ((rv == -1) ? -errno : 0);
|
||||
}
|
||||
|
@ -45,24 +45,15 @@ _chmod(const fs::SearchFunc searchFunc,
|
||||
const mode_t mode)
|
||||
{
|
||||
int rv;
|
||||
int error;
|
||||
fs::PathVector paths;
|
||||
fs::Path path;
|
||||
|
||||
rv = searchFunc(srcmounts,fusepath,paths);
|
||||
rv = searchFunc(srcmounts,fusepath,path);
|
||||
if(rv == -1)
|
||||
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
|
||||
|
@ -47,24 +47,15 @@ _chown(const fs::SearchFunc searchFunc,
|
||||
const gid_t gid)
|
||||
{
|
||||
int rv;
|
||||
int error;
|
||||
fs::PathVector paths;
|
||||
fs::Path path;
|
||||
|
||||
rv = searchFunc(srcmounts,fusepath,paths);
|
||||
rv = searchFunc(srcmounts,fusepath,path);
|
||||
if(rv == -1)
|
||||
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
|
||||
|
@ -57,8 +57,8 @@ _create(const fs::SearchFunc searchFunc,
|
||||
int rv;
|
||||
string path;
|
||||
string dirname;
|
||||
fs::PathVector createpath;
|
||||
fs::PathVector existingpath;
|
||||
fs::Path createpath;
|
||||
fs::Path existingpath;
|
||||
|
||||
dirname = fs::dirname(fusepath);
|
||||
rv = searchFunc(srcmounts,dirname,existingpath);
|
||||
@ -69,13 +69,13 @@ _create(const fs::SearchFunc searchFunc,
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
if(createpath[0].base != existingpath[0].base)
|
||||
if(createpath.base != existingpath.base)
|
||||
{
|
||||
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);
|
||||
if(fd == -1)
|
||||
|
136
src/fs.cpp
136
src/fs.cpp
@ -500,7 +500,7 @@ namespace fs
|
||||
int
|
||||
invalid(const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
PathVector &paths)
|
||||
Path &rv)
|
||||
{
|
||||
return (errno = EINVAL,-1);
|
||||
}
|
||||
@ -508,7 +508,7 @@ namespace fs
|
||||
int
|
||||
ff(const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
PathVector &paths)
|
||||
Path &path)
|
||||
{
|
||||
errno = ENOENT;
|
||||
for(vector<string>::const_iterator
|
||||
@ -517,13 +517,18 @@ namespace fs
|
||||
++iter)
|
||||
{
|
||||
int rv;
|
||||
string path;
|
||||
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)
|
||||
return (paths.push_back(Path(*iter,path)),0);
|
||||
{
|
||||
path.base = *iter;
|
||||
path.full = fullpath;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
@ -532,7 +537,7 @@ namespace fs
|
||||
int
|
||||
ffwp(const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
PathVector &paths)
|
||||
Path &path)
|
||||
{
|
||||
Path fallback;
|
||||
|
||||
@ -543,24 +548,27 @@ namespace fs
|
||||
++iter)
|
||||
{
|
||||
int rv;
|
||||
string path;
|
||||
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)
|
||||
{
|
||||
return (paths.push_back(Path(*iter,path)),0);
|
||||
path.base = *iter;
|
||||
path.full = fullpath;
|
||||
return 0;
|
||||
}
|
||||
else if(errno == EACCES)
|
||||
{
|
||||
fallback.base = *iter;
|
||||
fallback.full = path;
|
||||
fallback.full = fullpath;
|
||||
}
|
||||
}
|
||||
|
||||
if(!fallback.base.empty())
|
||||
return (paths.push_back(fallback),0);
|
||||
return (path = fallback,0);
|
||||
|
||||
return -1;
|
||||
}
|
||||
@ -568,7 +576,7 @@ namespace fs
|
||||
int
|
||||
newest(const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
PathVector &paths)
|
||||
Path &path)
|
||||
{
|
||||
time_t newest;
|
||||
string npath;
|
||||
@ -581,70 +589,48 @@ namespace fs
|
||||
iter != eiter;
|
||||
++iter)
|
||||
{
|
||||
int rv;
|
||||
struct stat st;
|
||||
const string path = fs::make_path(*iter,fusepath);
|
||||
int rv;
|
||||
struct stat st;
|
||||
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)
|
||||
{
|
||||
newest = st.st_mtime;
|
||||
niter = iter;
|
||||
npath = path;
|
||||
npath = fullpath;
|
||||
}
|
||||
}
|
||||
|
||||
if(newest)
|
||||
return (paths.push_back(Path(*niter,npath)),0);
|
||||
{
|
||||
path.base = *niter;
|
||||
path.full = npath;
|
||||
return 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));
|
||||
}
|
||||
|
||||
return paths.empty() ? -1 : 0;
|
||||
}
|
||||
|
||||
int
|
||||
mfs(const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
PathVector &paths)
|
||||
Path &path)
|
||||
{
|
||||
fsblkcnt_t mfs;
|
||||
string mfspath;
|
||||
string fullmfspath;
|
||||
size_t mfsidx;
|
||||
|
||||
mfs = 0;
|
||||
errno = ENOENT;
|
||||
for(vector<string>::const_iterator
|
||||
iter = basepaths.begin(), eiter = basepaths.end();
|
||||
iter != eiter;
|
||||
++iter)
|
||||
mfs = 0;
|
||||
for(size_t i = 0, size = basepaths.size();
|
||||
i != size;
|
||||
i++)
|
||||
{
|
||||
int rv;
|
||||
struct statvfs fsstats;
|
||||
const string &mountpoint = *iter;
|
||||
struct statvfs fsstats;
|
||||
|
||||
rv = ::statvfs(mountpoint.c_str(),&fsstats);
|
||||
rv = ::statvfs(basepaths[i].c_str(),&fsstats);
|
||||
if(rv == 0)
|
||||
{
|
||||
fsblkcnt_t spaceavail;
|
||||
@ -652,18 +638,17 @@ namespace fs
|
||||
spaceavail = (fsstats.f_frsize * fsstats.f_bavail);
|
||||
if(spaceavail > mfs)
|
||||
{
|
||||
mfs = spaceavail;
|
||||
mfspath = mountpoint;
|
||||
mfs = spaceavail;
|
||||
mfsidx = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@ -671,11 +656,11 @@ namespace fs
|
||||
int
|
||||
epmfs(const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
PathVector &paths)
|
||||
Path &path)
|
||||
{
|
||||
fsblkcnt_t existingmfs = 0;
|
||||
fsblkcnt_t generalmfs = 0;
|
||||
string path;
|
||||
string fullpath;
|
||||
string generalmfspath;
|
||||
string existingmfspath;
|
||||
vector<string>::const_iterator iter = basepaths.begin();
|
||||
@ -703,8 +688,8 @@ namespace fs
|
||||
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(spaceavail > existingmfs)
|
||||
@ -722,7 +707,8 @@ namespace fs
|
||||
if(existingmfspath.empty())
|
||||
existingmfspath = generalmfspath;
|
||||
|
||||
paths.push_back(Path(existingmfspath,path));
|
||||
path.base = existingmfspath;
|
||||
path.full = fullpath;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -730,18 +716,12 @@ namespace fs
|
||||
int
|
||||
rand(const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
PathVector &paths)
|
||||
Path &path)
|
||||
{
|
||||
string randombasepath;
|
||||
string randomfullpath;
|
||||
|
||||
randombasepath = *random_element(basepaths.begin(),
|
||||
basepaths.end());
|
||||
|
||||
randomfullpath = fs::make_path(randombasepath,
|
||||
fusepath);
|
||||
|
||||
paths.push_back(Path(randombasepath,randomfullpath));
|
||||
path.base = *random_element(basepaths.begin(),
|
||||
basepaths.end());
|
||||
path.full = fs::make_path(path.base,
|
||||
fusepath);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
20
src/fs.hpp
20
src/fs.hpp
@ -48,8 +48,7 @@ namespace fs
|
||||
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 basename(const string &path);
|
||||
@ -114,28 +113,25 @@ namespace fs
|
||||
{
|
||||
int invalid(const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
PathVector &paths);
|
||||
Path &path);
|
||||
int ff(const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
PathVector &paths);
|
||||
Path &path);
|
||||
int ffwp(const vector<string> &paths,
|
||||
const string &fusepath,
|
||||
PathVector &rv);
|
||||
Path &path);
|
||||
int newest(const vector<string> &paths,
|
||||
const string &fusepath,
|
||||
PathVector &rv);
|
||||
int all(const vector<string> &paths,
|
||||
const string &fusepath,
|
||||
PathVector &rv);
|
||||
Path &path);
|
||||
int mfs(const vector<string> &paths,
|
||||
const string &fusepath,
|
||||
PathVector &rv);
|
||||
Path &path);
|
||||
int epmfs(const vector<string> &paths,
|
||||
const string &fusepath,
|
||||
PathVector &rv);
|
||||
Path &path);
|
||||
int rand(const vector<string> &paths,
|
||||
const string &fusepath,
|
||||
PathVector &rv);
|
||||
Path &path);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -71,13 +71,13 @@ _getattr(const fs::SearchFunc searchFunc,
|
||||
struct stat &buf)
|
||||
{
|
||||
int rv;
|
||||
fs::PathVector paths;
|
||||
fs::Path path;
|
||||
|
||||
rv = searchFunc(srcmounts,fusepath,paths);
|
||||
rv = searchFunc(srcmounts,fusepath,path);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
rv = ::lstat(paths[0].full.c_str(),&buf);
|
||||
rv = ::lstat(path.full.c_str(),&buf);
|
||||
|
||||
return ((rv == -1) ? -errno : 0);
|
||||
}
|
||||
|
@ -107,18 +107,18 @@ _getxattr(const fs::SearchFunc searchFunc,
|
||||
{
|
||||
#ifndef WITHOUT_XATTR
|
||||
int rv;
|
||||
fs::PathVector paths;
|
||||
fs::Path path;
|
||||
|
||||
rv = searchFunc(srcmounts,fusepath,paths);
|
||||
rv = searchFunc(srcmounts,fusepath,path);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
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"))
|
||||
rv = ::_getxattr_from_string(buf,count,paths[0].full);
|
||||
rv = ::_getxattr_from_string(buf,count,path.full);
|
||||
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);
|
||||
#else
|
||||
|
@ -93,13 +93,13 @@ _ioctl_dir_base(const fs::SearchFunc searchFunc,
|
||||
{
|
||||
int fd;
|
||||
int rv;
|
||||
fs::PathVector paths;
|
||||
fs::Path path;
|
||||
|
||||
rv = searchFunc(srcmounts,fusepath,paths);
|
||||
rv = searchFunc(srcmounts,fusepath,path);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
fd = ::open(paths[0].full.c_str(),flags);
|
||||
fd = ::open(path.full.c_str(),flags);
|
||||
if(fd == -1)
|
||||
return -errno;
|
||||
|
||||
|
52
src/link.cpp
52
src/link.cpp
@ -47,47 +47,35 @@ _link(const fs::SearchFunc searchFunc,
|
||||
const string &to)
|
||||
{
|
||||
int rv;
|
||||
int error;
|
||||
fs::PathVector paths;
|
||||
fs::Path path;
|
||||
|
||||
rv = searchFunc(srcmounts,from,paths);
|
||||
rv = searchFunc(srcmounts,from,path);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
rv = -1;
|
||||
error = 0;
|
||||
for(fs::PathVector::const_iterator
|
||||
i = paths.begin(), ei = paths.end(); i != ei; ++i)
|
||||
const string pathfrom = fs::make_path(path.base,from);
|
||||
const string pathto = fs::make_path(path.base,to);
|
||||
|
||||
rv = ::link(pathfrom.c_str(),pathto.c_str());
|
||||
if(rv == -1 && errno == ENOENT)
|
||||
{
|
||||
int lrv;
|
||||
const string pathfrom = fs::make_path(i->base,from);
|
||||
const string pathto = fs::make_path(i->base,to);
|
||||
string todir;
|
||||
fs::Path foundpath;
|
||||
|
||||
lrv = ::link(pathfrom.c_str(),pathto.c_str());
|
||||
if(lrv == -1 && errno == ENOENT)
|
||||
{
|
||||
string todir;
|
||||
fs::PathVector topaths;
|
||||
|
||||
todir = fs::dirname(to);
|
||||
fs::find::ffwp(srcmounts,todir,topaths);
|
||||
if(topaths.size() > 0)
|
||||
{
|
||||
{
|
||||
const mergerfs::ugid::SetResetGuard ugid(0,0);
|
||||
fs::clonepath(topaths[0].base,i->base,todir);
|
||||
}
|
||||
|
||||
lrv = ::link(pathfrom.c_str(),pathto.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
rv &= lrv;
|
||||
todir = fs::dirname(to);
|
||||
rv = fs::find::ffwp(srcmounts,todir,foundpath);
|
||||
if(rv == -1)
|
||||
error = errno;
|
||||
return -errno;
|
||||
|
||||
{
|
||||
const mergerfs::ugid::SetResetGuard ugid(0,0);
|
||||
fs::clonepath(foundpath.base,path.base,todir);
|
||||
}
|
||||
|
||||
rv = ::link(pathfrom.c_str(),pathto.c_str());
|
||||
}
|
||||
|
||||
return ((rv == -1) ? -error : 0);
|
||||
return ((rv == -1) ? -errno : 0);
|
||||
}
|
||||
|
||||
namespace mergerfs
|
||||
|
@ -75,13 +75,13 @@ _listxattr(const fs::SearchFunc searchFunc,
|
||||
{
|
||||
#ifndef WITHOUT_XATTR
|
||||
int rv;
|
||||
fs::PathVector paths;
|
||||
fs::Path path;
|
||||
|
||||
rv = searchFunc(srcmounts,fusepath,paths);
|
||||
rv = searchFunc(srcmounts,fusepath,path);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
rv = ::llistxattr(paths[0].full.c_str(),list,size);
|
||||
rv = ::llistxattr(path.full.c_str(),list,size);
|
||||
|
||||
return ((rv == -1) ? -errno : rv);
|
||||
#else
|
||||
|
@ -51,25 +51,28 @@ _mkdir(const fs::SearchFunc searchFunc,
|
||||
int rv;
|
||||
string path;
|
||||
string dirname;
|
||||
fs::PathVector createpath;
|
||||
fs::PathVector existingpath;
|
||||
fs::Path createpath;
|
||||
fs::Path existingpath;
|
||||
|
||||
if(fs::path_exists(srcmounts,fusepath))
|
||||
return -EEXIST;
|
||||
|
||||
dirname = fs::dirname(fusepath);
|
||||
dirname = fs::dirname(fusepath);
|
||||
rv = searchFunc(srcmounts,dirname,existingpath);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
|
@ -53,8 +53,8 @@ _mknod(const fs::SearchFunc searchFunc,
|
||||
int rv;
|
||||
string path;
|
||||
string dirname;
|
||||
fs::PathVector createpath;
|
||||
fs::PathVector existingpath;
|
||||
fs::Path createpath;
|
||||
fs::Path existingpath;
|
||||
|
||||
if(fs::path_exists(srcmounts,fusepath))
|
||||
return -EEXIST;
|
||||
@ -64,14 +64,17 @@ _mknod(const fs::SearchFunc searchFunc,
|
||||
if(rv == -1)
|
||||
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);
|
||||
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);
|
||||
|
||||
|
@ -51,17 +51,17 @@ _open(const fs::SearchFunc searchFunc,
|
||||
{
|
||||
int fd;
|
||||
int rv;
|
||||
fs::PathVector paths;
|
||||
fs::Path path;
|
||||
|
||||
rv = searchFunc(srcmounts,fusepath,paths);
|
||||
rv = searchFunc(srcmounts,fusepath,path);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
fd = ::open(paths[0].full.c_str(),flags);
|
||||
fd = ::open(path.full.c_str(),flags);
|
||||
if(fd == -1)
|
||||
return -errno;
|
||||
|
||||
fh = (uint64_t)new FileInfo(fd,flags,paths[0].full);
|
||||
fh = (uint64_t)new FileInfo(fd,flags,path.full);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -35,7 +35,6 @@ namespace mergerfs
|
||||
const std::vector<Policy> Policy::_policies_ =
|
||||
buildvector<Policy,true>
|
||||
(POLICY(invalid))
|
||||
(POLICY(all))
|
||||
(POLICY(epmfs))
|
||||
(POLICY(ff))
|
||||
(POLICY(ffwp))
|
||||
@ -46,7 +45,6 @@ namespace mergerfs
|
||||
const Policy * const Policy::policies = &_policies_[1];
|
||||
|
||||
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::ff = Policy::policies[Policy::Enum::ff];
|
||||
const Policy &Policy::ffwp = Policy::policies[Policy::Enum::ffwp];
|
||||
|
@ -41,8 +41,7 @@ namespace mergerfs
|
||||
{
|
||||
invalid = -1,
|
||||
BEGIN = 0,
|
||||
all = BEGIN,
|
||||
epmfs,
|
||||
epmfs = BEGIN,
|
||||
ff,
|
||||
ffwp,
|
||||
mfs,
|
||||
@ -101,7 +100,6 @@ namespace mergerfs
|
||||
static const std::vector<Policy> _policies_;
|
||||
static const Policy * const policies;
|
||||
static const Policy &invalid;
|
||||
static const Policy &all;
|
||||
static const Policy &epmfs;
|
||||
static const Policy &ff;
|
||||
static const Policy &ffwp;
|
||||
|
@ -48,13 +48,13 @@ _readlink(const fs::SearchFunc searchFunc,
|
||||
const size_t size)
|
||||
{
|
||||
int rv;
|
||||
fs::PathVector paths;
|
||||
fs::Path path;
|
||||
|
||||
rv = searchFunc(srcmounts,fusepath,paths);
|
||||
rv = searchFunc(srcmounts,fusepath,path);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
rv = ::readlink(paths[0].full.c_str(),buf,size);
|
||||
rv = ::readlink(path.full.c_str(),buf,size);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
|
@ -48,24 +48,15 @@ _removexattr(const fs::SearchFunc searchFunc,
|
||||
{
|
||||
#ifndef WITHOUT_XATTR
|
||||
int rv;
|
||||
int error;
|
||||
fs::PathVector paths;
|
||||
fs::Path path;
|
||||
|
||||
rv = searchFunc(srcmounts,fusepath,paths);
|
||||
rv = searchFunc(srcmounts,fusepath,path);
|
||||
if(rv == -1)
|
||||
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
|
||||
return -ENOTSUP;
|
||||
#endif
|
||||
|
@ -48,15 +48,15 @@ _rename(const fs::SearchFunc searchFunc,
|
||||
{
|
||||
int rv;
|
||||
string pathto;
|
||||
fs::PathVector pathfrom;
|
||||
fs::Path pathfrom;
|
||||
|
||||
rv = searchFunc(srcmounts,from,pathfrom);
|
||||
if(rv == -1)
|
||||
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)
|
||||
return -EXDEV;
|
||||
|
||||
|
@ -45,24 +45,15 @@ _rmdir(const fs::SearchFunc searchFunc,
|
||||
const string &fusepath)
|
||||
{
|
||||
int rv;
|
||||
int error;
|
||||
fs::PathVector paths;
|
||||
fs::Path path;
|
||||
|
||||
rv = searchFunc(srcmounts,fusepath,paths);
|
||||
rv = searchFunc(srcmounts,fusepath,path);
|
||||
if(rv == -1)
|
||||
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
|
||||
|
@ -234,24 +234,15 @@ _setxattr(const fs::SearchFunc searchFunc,
|
||||
{
|
||||
#ifndef WITHOUT_XATTR
|
||||
int rv;
|
||||
int error;
|
||||
fs::PathVector paths;
|
||||
fs::Path path;
|
||||
|
||||
rv = searchFunc(srcmounts,fusepath,paths);
|
||||
rv = searchFunc(srcmounts,fusepath,path);
|
||||
if(rv == -1)
|
||||
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
|
||||
return -ENOTSUP;
|
||||
#endif
|
||||
|
@ -44,15 +44,15 @@ _symlink(const vector<string> &srcmounts,
|
||||
const string &to)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
@ -47,24 +47,15 @@ _truncate(const fs::SearchFunc searchFunc,
|
||||
const off_t size)
|
||||
{
|
||||
int rv;
|
||||
int error;
|
||||
fs::PathVector paths;
|
||||
fs::Path path;
|
||||
|
||||
rv = searchFunc(srcmounts,fusepath,paths);
|
||||
rv = searchFunc(srcmounts,fusepath,path);
|
||||
if(rv == -1)
|
||||
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
|
||||
|
@ -45,24 +45,15 @@ _unlink(const fs::SearchFunc searchFunc,
|
||||
const string &fusepath)
|
||||
{
|
||||
int rv;
|
||||
int error;
|
||||
fs::PathVector paths;
|
||||
fs::Path path;
|
||||
|
||||
rv = searchFunc(srcmounts,fusepath,paths);
|
||||
rv = searchFunc(srcmounts,fusepath,path);
|
||||
if(rv == -1)
|
||||
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
|
||||
|
@ -47,24 +47,15 @@ _utimens(const fs::SearchFunc searchFunc,
|
||||
const struct timespec ts[2])
|
||||
{
|
||||
int rv;
|
||||
int error;
|
||||
fs::PathVector paths;
|
||||
fs::Path path;
|
||||
|
||||
rv = searchFunc(srcmounts,fusepath,paths);
|
||||
rv = searchFunc(srcmounts,fusepath,path);
|
||||
if(rv == -1)
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user