mirror of
https://github.com/trapexit/mergerfs.git
synced 2025-02-01 10:42:00 +08:00
Merge pull request #219 from trapexit/pathmake
use references to srcmounts rather than copies
This commit is contained in:
commit
c568a6d356
|
@ -35,19 +35,20 @@ int
|
|||
_access(Policy::Func::Search searchFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const string &fusepath,
|
||||
const char *fusepath,
|
||||
const int mask)
|
||||
{
|
||||
int rv;
|
||||
string path;
|
||||
string fullpath;
|
||||
vector<const string*> basepaths;
|
||||
|
||||
rv = searchFunc(srcmounts,fusepath,minfreespace,path);
|
||||
rv = searchFunc(srcmounts,fusepath,minfreespace,basepaths);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
fs::path::append(path,fusepath);
|
||||
fs::path::make(basepaths[0],fusepath,fullpath);
|
||||
|
||||
rv = ::eaccess(path.c_str(),mask);
|
||||
rv = ::eaccess(fullpath.c_str(),mask);
|
||||
|
||||
return ((rv == -1) ? -errno : 0);
|
||||
}
|
||||
|
|
|
@ -32,33 +32,56 @@ using mergerfs::Policy;
|
|||
|
||||
static
|
||||
int
|
||||
_chmod(Policy::Func::Action actionFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const string &fusepath,
|
||||
const mode_t mode)
|
||||
_chmod_loop_core(const string *basepath,
|
||||
const char *fusepath,
|
||||
const mode_t mode,
|
||||
const int error)
|
||||
{
|
||||
int rv;
|
||||
int error;
|
||||
vector<string> paths;
|
||||
string fullpath;
|
||||
|
||||
rv = actionFunc(srcmounts,fusepath,minfreespace,paths);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
fs::path::make(basepath,fusepath,fullpath);
|
||||
|
||||
rv = ::chmod(fullpath.c_str(),mode);
|
||||
|
||||
return calc_error(rv,error,errno);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_chmod_loop(const vector<const string*> &basepaths,
|
||||
const char *fusepath,
|
||||
const mode_t mode)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = -1;
|
||||
for(size_t i = 0, ei = paths.size(); i != ei; i++)
|
||||
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
|
||||
{
|
||||
fs::path::append(paths[i],fusepath);
|
||||
|
||||
rv = ::chmod(paths[i].c_str(),mode);
|
||||
|
||||
error = calc_error(rv,error,errno);
|
||||
error = _chmod_loop_core(basepaths[i],fusepath,mode,error);
|
||||
}
|
||||
|
||||
return -error;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_chmod(Policy::Func::Action actionFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const char *fusepath,
|
||||
const mode_t mode)
|
||||
{
|
||||
int rv;
|
||||
vector<const string*> basepaths;
|
||||
|
||||
rv = actionFunc(srcmounts,fusepath,minfreespace,basepaths);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
return _chmod_loop(basepaths,fusepath,mode);
|
||||
}
|
||||
|
||||
namespace mergerfs
|
||||
{
|
||||
namespace fuse
|
||||
|
|
|
@ -32,34 +32,59 @@ using std::vector;
|
|||
using mergerfs::Policy;
|
||||
using mergerfs::Config;
|
||||
|
||||
static
|
||||
int
|
||||
_chown_loop_core(const string *basepath,
|
||||
const char *fusepath,
|
||||
const uid_t uid,
|
||||
const gid_t gid,
|
||||
const int error)
|
||||
{
|
||||
int rv;
|
||||
string fullpath;
|
||||
|
||||
fs::path::make(basepath,fusepath,fullpath);
|
||||
|
||||
rv = ::lchown(fullpath.c_str(),uid,gid);
|
||||
|
||||
return calc_error(rv,error,errno);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_chown_loop(const vector<const string*> &basepaths,
|
||||
const char *fusepath,
|
||||
const uid_t uid,
|
||||
const gid_t gid)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = -1;
|
||||
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
|
||||
{
|
||||
error = _chown_loop_core(basepaths[i],fusepath,uid,gid,error);
|
||||
}
|
||||
|
||||
return -error;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_chown(Policy::Func::Action actionFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const string &fusepath,
|
||||
const char *fusepath,
|
||||
const uid_t uid,
|
||||
const gid_t gid)
|
||||
{
|
||||
int rv;
|
||||
int error;
|
||||
vector<string> paths;
|
||||
vector<const string*> basepaths;
|
||||
|
||||
rv = actionFunc(srcmounts,fusepath,minfreespace,paths);
|
||||
rv = actionFunc(srcmounts,fusepath,minfreespace,basepaths);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
error = -1;
|
||||
for(size_t i = 0, ei = paths.size(); i != ei; i++)
|
||||
{
|
||||
fs::path::append(paths[i],fusepath);
|
||||
|
||||
rv = ::lchown(paths[i].c_str(),uid,gid);
|
||||
|
||||
error = calc_error(rv,error,errno);
|
||||
}
|
||||
|
||||
return -error;
|
||||
return _chown_loop(basepaths,fusepath,uid,gid);
|
||||
}
|
||||
|
||||
namespace mergerfs
|
||||
|
|
|
@ -38,39 +38,26 @@ using namespace mergerfs;
|
|||
|
||||
static
|
||||
int
|
||||
_create(Policy::Func::Search searchFunc,
|
||||
Policy::Func::Create createFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const string &fusepath,
|
||||
const mode_t mode,
|
||||
const int flags,
|
||||
uint64_t &fh)
|
||||
_create_core(const string &existingpath,
|
||||
const string &createpath,
|
||||
const char *fusepath,
|
||||
const char *fusedirpath,
|
||||
const mode_t mode,
|
||||
const int flags,
|
||||
uint64_t &fh)
|
||||
{
|
||||
int fd;
|
||||
int rv;
|
||||
string dirname;
|
||||
vector<string> createpath;
|
||||
vector<string> existingpath;
|
||||
string fullpath;
|
||||
|
||||
dirname = fs::path::dirname(fusepath);
|
||||
rv = searchFunc(srcmounts,dirname,minfreespace,existingpath);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
rv = createFunc(srcmounts,dirname,minfreespace,createpath);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
if(createpath[0] != existingpath[0])
|
||||
if(createpath != existingpath)
|
||||
{
|
||||
const ugid::SetRootGuard ugidGuard;
|
||||
fs::clonepath(existingpath[0],createpath[0],dirname);
|
||||
fs::clonepath(existingpath,createpath,fusedirpath);
|
||||
}
|
||||
|
||||
fs::path::append(createpath[0],fusepath);
|
||||
fs::path::make(&createpath,fusepath,fullpath);
|
||||
|
||||
fd = ::open(createpath[0].c_str(),flags,mode);
|
||||
fd = ::open(fullpath.c_str(),flags,mode);
|
||||
if(fd == -1)
|
||||
return -errno;
|
||||
|
||||
|
@ -79,6 +66,41 @@ _create(Policy::Func::Search searchFunc,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_create(Policy::Func::Search searchFunc,
|
||||
Policy::Func::Create createFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const char *fusepath,
|
||||
const mode_t mode,
|
||||
const int flags,
|
||||
uint64_t &fh)
|
||||
{
|
||||
int rv;
|
||||
string fullpath;
|
||||
string fusedirpath;
|
||||
const char *fusedirpathcstr;
|
||||
vector<const string*> createpaths;
|
||||
vector<const string*> existingpaths;
|
||||
|
||||
fusedirpath = fusepath;
|
||||
fs::path::dirname(fusedirpath);
|
||||
fusedirpathcstr = fusedirpath.c_str();
|
||||
|
||||
rv = searchFunc(srcmounts,fusedirpathcstr,minfreespace,existingpaths);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
rv = createFunc(srcmounts,fusedirpathcstr,minfreespace,createpaths);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
return _create_core(*existingpaths[0],*createpaths[0],
|
||||
fusepath,fusedirpathcstr,
|
||||
mode,flags,fh);
|
||||
}
|
||||
|
||||
namespace mergerfs
|
||||
{
|
||||
namespace fuse
|
||||
|
|
|
@ -16,10 +16,6 @@
|
|||
|
||||
#if FALLOCATE
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include <fuse.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
|
|
@ -27,11 +27,11 @@ _flush(const int fd)
|
|||
{
|
||||
int rv;
|
||||
|
||||
rv = dup(fd);
|
||||
rv = ::dup(fd);
|
||||
if(rv == -1)
|
||||
errno = EIO;
|
||||
else
|
||||
rv = close(rv);
|
||||
rv = ::close(rv);
|
||||
|
||||
return ((rv == -1) ? -errno : 0);
|
||||
}
|
||||
|
|
20
src/fs.cpp
20
src/fs.cpp
|
@ -40,16 +40,16 @@ namespace fs
|
|||
{
|
||||
void
|
||||
findallfiles(const vector<string> &srcmounts,
|
||||
const string &fusepath,
|
||||
const char *fusepath,
|
||||
vector<string> &paths)
|
||||
{
|
||||
int rv;
|
||||
string fullpath;
|
||||
struct stat st;
|
||||
|
||||
for(size_t i = 0, ei = srcmounts.size(); i != ei; i++)
|
||||
{
|
||||
int rv;
|
||||
string fullpath;
|
||||
struct stat st;
|
||||
|
||||
fs::path::make(srcmounts[i],fusepath,fullpath);
|
||||
fs::path::make(&srcmounts[i],fusepath,fullpath);
|
||||
|
||||
rv = ::lstat(fullpath.c_str(),&st);
|
||||
if(rv == 0)
|
||||
|
@ -59,12 +59,12 @@ namespace fs
|
|||
|
||||
int
|
||||
findonfs(const vector<string> &srcmounts,
|
||||
const string &fusepath,
|
||||
const char *fusepath,
|
||||
const int fd,
|
||||
string &basepath)
|
||||
{
|
||||
int rv;
|
||||
string tmppath;
|
||||
string fullpath;
|
||||
unsigned long fsid;
|
||||
struct statvfs buf;
|
||||
|
||||
|
@ -75,9 +75,9 @@ namespace fs
|
|||
fsid = buf.f_fsid;
|
||||
for(int i = 0, ei = srcmounts.size(); i != ei; i++)
|
||||
{
|
||||
fs::path::make(srcmounts[i],fusepath,tmppath);
|
||||
fs::path::make(&srcmounts[i],fusepath,fullpath);
|
||||
|
||||
rv = ::statvfs(tmppath.c_str(),&buf);
|
||||
rv = ::statvfs(fullpath.c_str(),&buf);
|
||||
if(rv == -1)
|
||||
continue;
|
||||
|
||||
|
|
|
@ -27,11 +27,11 @@ namespace fs
|
|||
using std::vector;
|
||||
|
||||
void findallfiles(const vector<string> &srcmounts,
|
||||
const string &fusepath,
|
||||
const char *fusepath,
|
||||
vector<string> &paths);
|
||||
|
||||
int findonfs(const vector<string> &srcmounts,
|
||||
const string &fusepath,
|
||||
const char *fusepath,
|
||||
const int fd,
|
||||
string &basepath);
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ namespace fs
|
|||
int
|
||||
clonepath(const string &fromsrc,
|
||||
const string &tosrc,
|
||||
const string &relative)
|
||||
const char *relative)
|
||||
{
|
||||
int rv;
|
||||
struct stat st;
|
||||
|
@ -57,22 +57,23 @@ namespace fs
|
|||
string frompath;
|
||||
string dirname;
|
||||
|
||||
dirname = fs::path::dirname(relative);
|
||||
dirname = relative;
|
||||
fs::path::dirname(dirname);
|
||||
if(!dirname.empty())
|
||||
{
|
||||
rv = clonepath(fromsrc,tosrc,dirname);
|
||||
rv = clonepath(fromsrc,tosrc,dirname.c_str());
|
||||
if(rv == -1)
|
||||
return -1;
|
||||
}
|
||||
|
||||
fs::path::make(fromsrc,relative,frompath);
|
||||
fs::path::make(&fromsrc,relative,frompath);
|
||||
rv = ::stat(frompath.c_str(),&st);
|
||||
if(rv == -1)
|
||||
return -1;
|
||||
else if(!S_ISDIR(st.st_mode))
|
||||
return (errno = ENOTDIR,-1);
|
||||
|
||||
fs::path::make(tosrc,relative,topath);
|
||||
fs::path::make(&tosrc,relative,topath);
|
||||
rv = ::mkdir(topath.c_str(),st.st_mode);
|
||||
if(rv == -1)
|
||||
{
|
||||
|
|
|
@ -20,5 +20,5 @@ namespace fs
|
|||
{
|
||||
int clonepath(const std::string &from,
|
||||
const std::string &to,
|
||||
const std::string &relative);
|
||||
const char *relative);
|
||||
}
|
||||
|
|
|
@ -66,8 +66,9 @@ namespace fs
|
|||
if(rv == -1)
|
||||
return -1;
|
||||
|
||||
fusedir = fs::path::dirname(fusepath);
|
||||
rv = fs::clonepath(fdin_path,fdout_path,fusedir);
|
||||
fusedir = fusepath;
|
||||
fs::path::dirname(fusedir);
|
||||
rv = fs::clonepath(fdin_path,fdout_path,fusedir.c_str());
|
||||
if(rv == -1)
|
||||
return -1;
|
||||
|
||||
|
|
|
@ -29,15 +29,14 @@ namespace fs
|
|||
{
|
||||
namespace path
|
||||
{
|
||||
string
|
||||
dirname(const string &path)
|
||||
void
|
||||
dirname(string &path)
|
||||
{
|
||||
string parent = path;
|
||||
string::reverse_iterator i;
|
||||
string::reverse_iterator bi;
|
||||
|
||||
bi = parent.rend();
|
||||
i = parent.rbegin();
|
||||
bi = path.rend();
|
||||
i = path.rbegin();
|
||||
while(*i == '/' && i != bi)
|
||||
i++;
|
||||
|
||||
|
@ -47,9 +46,7 @@ namespace fs
|
|||
while(*i == '/' && i != bi)
|
||||
i++;
|
||||
|
||||
parent.erase(i.base(),parent.end());
|
||||
|
||||
return parent;
|
||||
path.erase(i.base(),path.end());
|
||||
}
|
||||
|
||||
string
|
||||
|
@ -57,54 +54,5 @@ namespace fs
|
|||
{
|
||||
return path.substr(path.find_last_of('/')+1);
|
||||
}
|
||||
|
||||
bool
|
||||
is_empty(const string &path)
|
||||
{
|
||||
DIR *dir;
|
||||
struct dirent *de;
|
||||
|
||||
dir = ::opendir(path.c_str());
|
||||
if(!dir)
|
||||
return false;
|
||||
|
||||
while((de = ::readdir(dir)))
|
||||
{
|
||||
const char *d_name = de->d_name;
|
||||
|
||||
if(d_name[0] == '.' &&
|
||||
((d_name[1] == '\0') ||
|
||||
(d_name[1] == '.' && d_name[2] == '\0')))
|
||||
continue;
|
||||
|
||||
::closedir(dir);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
::closedir(dir);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
exists(const vector<string> &paths,
|
||||
const string &fusepath)
|
||||
{
|
||||
for(size_t i = 0, ei = paths.size(); i != ei; i++)
|
||||
{
|
||||
int rv;
|
||||
string path;
|
||||
struct stat st;
|
||||
|
||||
fs::path::make(paths[i],fusepath,path);
|
||||
|
||||
rv = ::lstat(path.c_str(),&st);
|
||||
if(rv == 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,43 +25,28 @@ namespace fs
|
|||
namespace path
|
||||
{
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
string dirname(const string &path);
|
||||
void dirname(string &path);
|
||||
|
||||
string basename(const string &path);
|
||||
|
||||
bool is_empty(const string &path);
|
||||
|
||||
bool exists(vector<string>::const_iterator begin,
|
||||
vector<string>::const_iterator end,
|
||||
const string &fusepath);
|
||||
bool exists(const vector<string> &srcmounts,
|
||||
const string &fusepath);
|
||||
|
||||
inline
|
||||
string
|
||||
make(const string &base,
|
||||
const string &suffix)
|
||||
{
|
||||
return base + suffix;
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
make(const string &base,
|
||||
const string &suffix,
|
||||
string &output)
|
||||
{
|
||||
output = base + suffix;
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
append(string &base,
|
||||
const string &suffix)
|
||||
append(string &base,
|
||||
const char *suffix)
|
||||
{
|
||||
base += suffix;
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
make(const string *base,
|
||||
const char *suffix,
|
||||
string &output)
|
||||
{
|
||||
output = *base;
|
||||
output += suffix;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -63,19 +63,20 @@ int
|
|||
_getattr(Policy::Func::Search searchFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const string &fusepath,
|
||||
const char *fusepath,
|
||||
struct stat &buf)
|
||||
{
|
||||
int rv;
|
||||
vector<string> path;
|
||||
string fullpath;
|
||||
vector<const string*> basepaths;
|
||||
|
||||
rv = searchFunc(srcmounts,fusepath,minfreespace,path);
|
||||
rv = searchFunc(srcmounts,fusepath,minfreespace,basepaths);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
fs::path::append(path[0],fusepath);
|
||||
fs::path::make(basepaths[0],fusepath,fullpath);
|
||||
|
||||
rv = ::lstat(path[0].c_str(),&buf);
|
||||
rv = ::lstat(fullpath.c_str(),&buf);
|
||||
|
||||
return ((rv == -1) ? -errno : 0);
|
||||
}
|
||||
|
|
|
@ -43,14 +43,14 @@ using namespace mergerfs;
|
|||
static
|
||||
int
|
||||
_lgetxattr(const string &path,
|
||||
const string &name,
|
||||
const char *attrname,
|
||||
void *value,
|
||||
const size_t size)
|
||||
{
|
||||
#ifndef WITHOUT_XATTR
|
||||
int rv;
|
||||
|
||||
rv = ::lgetxattr(path.c_str(),name.c_str(),value,size);
|
||||
rv = ::lgetxattr(path.c_str(),attrname,value,size);
|
||||
|
||||
return ((rv == -1) ? -errno : rv);
|
||||
#else
|
||||
|
@ -161,7 +161,7 @@ _getxattr_pid(string &attrvalue)
|
|||
static
|
||||
int
|
||||
_getxattr_controlfile(const Config &config,
|
||||
const string &attrname,
|
||||
const char *attrname,
|
||||
char *buf,
|
||||
const size_t count)
|
||||
{
|
||||
|
@ -236,7 +236,7 @@ _getxattr_from_string(char *destbuf,
|
|||
static
|
||||
int
|
||||
_getxattr_user_mergerfs_allpaths(const vector<string> &srcmounts,
|
||||
const string &fusepath,
|
||||
const char *fusepath,
|
||||
char *buf,
|
||||
const size_t count)
|
||||
{
|
||||
|
@ -253,10 +253,10 @@ _getxattr_user_mergerfs_allpaths(const vector<string> &srcmounts,
|
|||
static
|
||||
int
|
||||
_getxattr_user_mergerfs(const string &basepath,
|
||||
const string &fusepath,
|
||||
const char *fusepath,
|
||||
const string &fullpath,
|
||||
const vector<string> &srcmounts,
|
||||
const string &attrname,
|
||||
const char *attrname,
|
||||
char *buf,
|
||||
const size_t count)
|
||||
{
|
||||
|
@ -281,23 +281,23 @@ int
|
|||
_getxattr(Policy::Func::Search searchFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const string &fusepath,
|
||||
const string &attrname,
|
||||
const char *fusepath,
|
||||
const char *attrname,
|
||||
char *buf,
|
||||
const size_t count)
|
||||
{
|
||||
int rv;
|
||||
string fullpath;
|
||||
vector<string> basepath;
|
||||
vector<const string*> basepaths;
|
||||
|
||||
rv = searchFunc(srcmounts,fusepath,minfreespace,basepath);
|
||||
rv = searchFunc(srcmounts,fusepath,minfreespace,basepaths);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
fs::path::make(basepath[0],fusepath,fullpath);
|
||||
fs::path::make(basepaths[0],fusepath,fullpath);
|
||||
|
||||
if(str::isprefix(attrname,"user.mergerfs."))
|
||||
rv = _getxattr_user_mergerfs(basepath[0],fusepath,fullpath,srcmounts,attrname,buf,count);
|
||||
rv = _getxattr_user_mergerfs(*basepaths[0],fusepath,fullpath,srcmounts,attrname,buf,count);
|
||||
else
|
||||
rv = _lgetxattr(fullpath,attrname,buf,count);
|
||||
|
||||
|
|
|
@ -61,21 +61,23 @@ int
|
|||
_ioctl_dir_base(Policy::Func::Search searchFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const string &fusepath,
|
||||
const char *fusepath,
|
||||
const int cmd,
|
||||
void *data)
|
||||
{
|
||||
int fd;
|
||||
int rv;
|
||||
vector<string> path;
|
||||
string fullpath;
|
||||
vector<const string*> basepaths;
|
||||
|
||||
rv = searchFunc(srcmounts,fusepath,minfreespace,path);
|
||||
rv = searchFunc(srcmounts,fusepath,minfreespace,basepaths);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
fs::path::append(path[0],fusepath);
|
||||
fs::path::make(basepaths[0],fusepath,fullpath);
|
||||
|
||||
fd = ::open(path[0].c_str(),O_RDWR|O_NOATIME|O_DIRECTORY);
|
||||
const int flags = O_RDWR | O_NOATIME | O_DIRECTORY;
|
||||
fd = ::open(fullpath.c_str(),flags);
|
||||
if(fd == -1)
|
||||
return -errno;
|
||||
|
||||
|
@ -88,9 +90,9 @@ _ioctl_dir_base(Policy::Func::Search searchFunc,
|
|||
|
||||
static
|
||||
int
|
||||
_ioctl_dir(const string &fusepath,
|
||||
const int cmd,
|
||||
void *data)
|
||||
_ioctl_dir(const char *fusepath,
|
||||
const int cmd,
|
||||
void *data)
|
||||
{
|
||||
const fuse_context *fc = fuse_get_context();
|
||||
const Config &config = Config::get(fc);
|
||||
|
|
163
src/link.cpp
163
src/link.cpp
|
@ -36,12 +36,12 @@ using namespace mergerfs;
|
|||
|
||||
static
|
||||
int
|
||||
_link_create_path_one(const string &oldbasepath,
|
||||
const string &newbasepath,
|
||||
const string &oldfusepath,
|
||||
const string &newfusepath,
|
||||
const string &newfusedirpath,
|
||||
const int error)
|
||||
_link_create_path_core(const string &oldbasepath,
|
||||
const string &newbasepath,
|
||||
const char *oldfusepath,
|
||||
const char *newfusepath,
|
||||
const string &newfusedirpath,
|
||||
const int error)
|
||||
{
|
||||
int rv;
|
||||
string oldfullpath;
|
||||
|
@ -50,53 +50,66 @@ _link_create_path_one(const string &oldbasepath,
|
|||
if(oldbasepath != newbasepath)
|
||||
{
|
||||
const ugid::SetRootGuard ugidGuard;
|
||||
fs::clonepath(newbasepath,oldbasepath,newfusedirpath);
|
||||
fs::clonepath(newbasepath,oldbasepath,newfusedirpath.c_str());
|
||||
}
|
||||
|
||||
fs::path::make(oldbasepath,oldfusepath,oldfullpath);
|
||||
fs::path::make(oldbasepath,newfusepath,newfullpath);
|
||||
fs::path::make(&oldbasepath,oldfusepath,oldfullpath);
|
||||
fs::path::make(&oldbasepath,newfusepath,newfullpath);
|
||||
|
||||
rv = ::link(oldfullpath.c_str(),newfullpath.c_str());
|
||||
|
||||
return calc_error(rv,error,errno);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_link_create_path_loop(const vector<const string*> &oldbasepaths,
|
||||
const string &newbasepath,
|
||||
const char *oldfusepath,
|
||||
const char *newfusepath,
|
||||
const string &newfusedirpath)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = -1;
|
||||
for(size_t i = 0, ei = oldbasepaths.size(); i != ei; i++)
|
||||
{
|
||||
error = _link_create_path_core(*oldbasepaths[i],newbasepath,
|
||||
oldfusepath,newfusepath,
|
||||
newfusedirpath,
|
||||
error);
|
||||
}
|
||||
|
||||
return -error;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_link_create_path(Policy::Func::Search searchFunc,
|
||||
Policy::Func::Action actionFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const string &oldfusepath,
|
||||
const string &newfusepath)
|
||||
const char *oldfusepath,
|
||||
const char *newfusepath)
|
||||
{
|
||||
int rv;
|
||||
int error;
|
||||
string newbasepath;
|
||||
vector<string> toremove;
|
||||
vector<string> oldbasepaths;
|
||||
string newfusedirpath;
|
||||
vector<const string*> oldbasepaths;
|
||||
vector<const string*> newbasepaths;
|
||||
|
||||
rv = actionFunc(srcmounts,oldfusepath,minfreespace,oldbasepaths);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
const string newfusedirpath = fs::path::dirname(newfusepath);
|
||||
rv = searchFunc(srcmounts,newfusedirpath,minfreespace,newbasepath);
|
||||
newfusedirpath = newfusepath;
|
||||
fs::path::dirname(newfusedirpath);
|
||||
rv = searchFunc(srcmounts,newfusedirpath.c_str(),minfreespace,newbasepaths);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
error = -1;
|
||||
for(size_t i = 0, ei = oldbasepaths.size(); i != ei; i++)
|
||||
{
|
||||
const string &oldbasepath = oldbasepaths[i];
|
||||
|
||||
error = _link_create_path_one(oldbasepath,newbasepath,
|
||||
oldfusepath,newfusepath,
|
||||
newfusedirpath,
|
||||
error);
|
||||
}
|
||||
|
||||
return -error;
|
||||
return _link_create_path_loop(oldbasepaths,*newbasepaths[0],
|
||||
oldfusepath,newfusepath,
|
||||
newfusedirpath);
|
||||
}
|
||||
|
||||
static
|
||||
|
@ -106,25 +119,28 @@ _clonepath_if_would_create(Policy::Func::Search searchFunc,
|
|||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const string &oldbasepath,
|
||||
const string &oldfusepath,
|
||||
const string &newfusepath)
|
||||
const char *oldfusepath,
|
||||
const char *newfusepath)
|
||||
{
|
||||
int rv;
|
||||
string newbasepath;
|
||||
string newfusedirpath;
|
||||
const char *newfusedirpathcstr;
|
||||
vector<const string*> newbasepath;
|
||||
|
||||
newfusedirpath = fs::path::dirname(newfusepath);
|
||||
newfusedirpath = newfusepath;
|
||||
fs::path::dirname(newfusedirpath);
|
||||
newfusedirpathcstr = newfusedirpath.c_str();
|
||||
|
||||
rv = createFunc(srcmounts,newfusedirpath,minfreespace,newbasepath);
|
||||
rv = createFunc(srcmounts,newfusedirpathcstr,minfreespace,newbasepath);
|
||||
if(rv != -1)
|
||||
{
|
||||
if(oldbasepath == newbasepath)
|
||||
if(oldbasepath == *newbasepath[0])
|
||||
{
|
||||
rv = searchFunc(srcmounts,newfusedirpath,minfreespace,newbasepath);
|
||||
rv = searchFunc(srcmounts,newfusedirpathcstr,minfreespace,newbasepath);
|
||||
if(rv != -1)
|
||||
{
|
||||
const ugid::SetRootGuard ugidGuard;
|
||||
fs::clonepath(newbasepath,oldbasepath,newfusedirpath);
|
||||
fs::clonepath(*newbasepath[0],oldbasepath,newfusedirpathcstr);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -139,28 +155,29 @@ _clonepath_if_would_create(Policy::Func::Search searchFunc,
|
|||
|
||||
static
|
||||
int
|
||||
_link_preserve_path_one(Policy::Func::Search searchFunc,
|
||||
Policy::Func::Create createFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const string &oldbasepath,
|
||||
const string &oldfusepath,
|
||||
const string &newfusepath,
|
||||
const int error)
|
||||
_link_preserve_path_core(Policy::Func::Search searchFunc,
|
||||
Policy::Func::Create createFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const string &oldbasepath,
|
||||
const char *oldfusepath,
|
||||
const char *newfusepath,
|
||||
const int error)
|
||||
{
|
||||
int rv;
|
||||
string oldfullpath;
|
||||
string newfullpath;
|
||||
|
||||
fs::path::make(oldbasepath,oldfusepath,oldfullpath);
|
||||
fs::path::make(oldbasepath,newfusepath,newfullpath);
|
||||
fs::path::make(&oldbasepath,oldfusepath,oldfullpath);
|
||||
fs::path::make(&oldbasepath,newfusepath,newfullpath);
|
||||
|
||||
rv = ::link(oldfullpath.c_str(),newfullpath.c_str());
|
||||
if((rv == -1) && (errno == ENOENT))
|
||||
{
|
||||
rv = _clonepath_if_would_create(searchFunc,createFunc,
|
||||
srcmounts,minfreespace,
|
||||
oldbasepath,oldfusepath,newfusepath);
|
||||
oldbasepath,
|
||||
oldfusepath,newfusepath);
|
||||
if(rv != -1)
|
||||
rv = ::link(oldfullpath.c_str(),newfullpath.c_str());
|
||||
}
|
||||
|
@ -168,6 +185,31 @@ _link_preserve_path_one(Policy::Func::Search searchFunc,
|
|||
return calc_error(rv,error,errno);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_link_preserve_path_loop(Policy::Func::Search searchFunc,
|
||||
Policy::Func::Create createFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const char *oldfusepath,
|
||||
const char *newfusepath,
|
||||
const vector<const string*> &oldbasepaths)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = -1;
|
||||
for(size_t i = 0, ei = oldbasepaths.size(); i != ei; i++)
|
||||
{
|
||||
error = _link_preserve_path_core(searchFunc,createFunc,
|
||||
srcmounts,minfreespace,
|
||||
*oldbasepaths[i],
|
||||
oldfusepath,newfusepath,
|
||||
error);
|
||||
}
|
||||
|
||||
return -error;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_link_preserve_path(Policy::Func::Search searchFunc,
|
||||
|
@ -175,31 +217,20 @@ _link_preserve_path(Policy::Func::Search searchFunc,
|
|||
Policy::Func::Create createFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const string &oldfusepath,
|
||||
const string &newfusepath)
|
||||
const char *oldfusepath,
|
||||
const char *newfusepath)
|
||||
{
|
||||
int rv;
|
||||
int error;
|
||||
vector<string> toremove;
|
||||
vector<string> oldbasepaths;
|
||||
vector<const string*> oldbasepaths;
|
||||
|
||||
rv = actionFunc(srcmounts,oldfusepath,minfreespace,oldbasepaths);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
error = -1;
|
||||
for(size_t i = 0, ei = oldbasepaths.size(); i != ei; i++)
|
||||
{
|
||||
const string &oldbasepath = oldbasepaths[i];
|
||||
|
||||
error = _link_preserve_path_one(searchFunc,createFunc,
|
||||
srcmounts,minfreespace,
|
||||
oldbasepath,
|
||||
oldfusepath,newfusepath,
|
||||
error);
|
||||
}
|
||||
|
||||
return -error;
|
||||
return _link_preserve_path_loop(searchFunc,createFunc,
|
||||
srcmounts,minfreespace,
|
||||
oldfusepath,newfusepath,
|
||||
oldbasepaths);
|
||||
}
|
||||
|
||||
namespace mergerfs
|
||||
|
|
|
@ -69,32 +69,31 @@ _listxattr_controlfile(char *list,
|
|||
return xattrs.size();
|
||||
}
|
||||
|
||||
#ifndef WITHOUT_XATTR
|
||||
static
|
||||
int
|
||||
_listxattr(Policy::Func::Search searchFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const string &fusepath,
|
||||
const char *fusepath,
|
||||
char *list,
|
||||
const size_t size)
|
||||
{
|
||||
#ifndef WITHOUT_XATTR
|
||||
int rv;
|
||||
vector<string> path;
|
||||
string fullpath;
|
||||
vector<const string*> basepaths;
|
||||
|
||||
rv = searchFunc(srcmounts,fusepath,minfreespace,path);
|
||||
rv = searchFunc(srcmounts,fusepath,minfreespace,basepaths);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
fs::path::append(path[0],fusepath);
|
||||
fs::path::make(basepaths[0],fusepath,fullpath);
|
||||
|
||||
rv = ::llistxattr(path[0].c_str(),list,size);
|
||||
rv = ::llistxattr(fullpath.c_str(),list,size);
|
||||
|
||||
return ((rv == -1) ? -errno : rv);
|
||||
#else
|
||||
return -ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace mergerfs
|
||||
{
|
||||
|
@ -111,6 +110,7 @@ namespace mergerfs
|
|||
if(fusepath == config.controlfile)
|
||||
return _listxattr_controlfile(list,size);
|
||||
|
||||
#ifndef WITHOUT_XATTR
|
||||
const ugid::Set ugid(fc->uid,fc->gid);
|
||||
const rwlock::ReadGuard readlock(&config.srcmountslock);
|
||||
|
||||
|
@ -120,6 +120,9 @@ namespace mergerfs
|
|||
fusepath,
|
||||
list,
|
||||
size);
|
||||
#else
|
||||
return -ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,49 +37,80 @@ using namespace mergerfs;
|
|||
|
||||
static
|
||||
int
|
||||
_mkdir(Policy::Func::Search searchFunc,
|
||||
Policy::Func::Create createFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const string &fusepath,
|
||||
const mode_t mode)
|
||||
_mkdir_loop_core(const string &existingpath,
|
||||
const string &createpath,
|
||||
const char *fusepath,
|
||||
const char *fusedirpath,
|
||||
const mode_t mode,
|
||||
const int error)
|
||||
{
|
||||
int rv;
|
||||
string fullpath;
|
||||
|
||||
if(createpath != existingpath)
|
||||
{
|
||||
const ugid::SetRootGuard ugidGuard;
|
||||
fs::clonepath(existingpath,createpath,fusedirpath);
|
||||
}
|
||||
|
||||
fs::path::make(&createpath,fusepath,fullpath);
|
||||
|
||||
rv = ::mkdir(fullpath.c_str(),mode);
|
||||
|
||||
return calc_error(rv,error,errno);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_mkdir_loop(const string &existingpath,
|
||||
const vector<const string*> &createpaths,
|
||||
const char *fusepath,
|
||||
const char *fusedirpath,
|
||||
const mode_t mode)
|
||||
{
|
||||
int error;
|
||||
string dirname;
|
||||
string existingpath;
|
||||
vector<string> createpaths;
|
||||
|
||||
dirname = fs::path::dirname(fusepath);
|
||||
rv = searchFunc(srcmounts,dirname,minfreespace,existingpath);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
rv = createFunc(srcmounts,dirname,minfreespace,createpaths);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
error = -1;
|
||||
for(size_t i = 0, ei = createpaths.size(); i != ei; i++)
|
||||
{
|
||||
string &createpath = createpaths[i];
|
||||
|
||||
if(createpath != existingpath)
|
||||
{
|
||||
const ugid::SetRootGuard ugidGuard;
|
||||
fs::clonepath(existingpath,createpath,dirname);
|
||||
}
|
||||
|
||||
fs::path::append(createpath,fusepath);
|
||||
|
||||
rv = ::mkdir(createpath.c_str(),mode);
|
||||
|
||||
error = calc_error(rv,error,errno);
|
||||
error = _mkdir_loop_core(existingpath,*createpaths[i],
|
||||
fusepath,fusedirpath,mode,error);
|
||||
}
|
||||
|
||||
return -error;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_mkdir(Policy::Func::Search searchFunc,
|
||||
Policy::Func::Create createFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const char *fusepath,
|
||||
const mode_t mode)
|
||||
{
|
||||
int rv;
|
||||
string fusedirpath;
|
||||
const char *fusedirpathcstr;
|
||||
vector<const string*> createpaths;
|
||||
vector<const string*> existingpaths;
|
||||
|
||||
fusedirpath = fusepath;
|
||||
fs::path::dirname(fusedirpath);
|
||||
fusedirpathcstr = fusedirpath.c_str();
|
||||
|
||||
rv = searchFunc(srcmounts,fusedirpathcstr,minfreespace,existingpaths);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
rv = createFunc(srcmounts,fusedirpathcstr,minfreespace,createpaths);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
return _mkdir_loop(*existingpaths[0],createpaths,
|
||||
fusepath,fusedirpathcstr,mode);
|
||||
}
|
||||
|
||||
namespace mergerfs
|
||||
{
|
||||
namespace fuse
|
||||
|
|
|
@ -38,50 +38,85 @@ using namespace mergerfs;
|
|||
|
||||
static
|
||||
int
|
||||
_mknod(Policy::Func::Search searchFunc,
|
||||
Policy::Func::Create createFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const string &fusepath,
|
||||
const mode_t mode,
|
||||
const dev_t dev)
|
||||
_mknod_loop_core(const string &existingpath,
|
||||
const string &createpath,
|
||||
const char *fusepath,
|
||||
const char *fusedirpath,
|
||||
const mode_t mode,
|
||||
const dev_t dev,
|
||||
const int error)
|
||||
{
|
||||
int rv;
|
||||
string fullpath;
|
||||
|
||||
if(createpath != existingpath)
|
||||
{
|
||||
const ugid::SetRootGuard ugidGuard;
|
||||
fs::clonepath(existingpath,createpath,fusedirpath);
|
||||
}
|
||||
|
||||
fs::path::make(&createpath,fusepath,fullpath);
|
||||
|
||||
rv = ::mknod(fullpath.c_str(),mode,dev);
|
||||
|
||||
return calc_error(rv,error,errno);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_mknod_loop(const string &existingpath,
|
||||
const vector<const string*> &createpaths,
|
||||
const char *fusepath,
|
||||
const char *fusedirpath,
|
||||
const mode_t mode,
|
||||
const dev_t dev)
|
||||
{
|
||||
int error;
|
||||
string dirname;
|
||||
string existingpath;
|
||||
vector<string> createpaths;
|
||||
|
||||
dirname = fs::path::dirname(fusepath);
|
||||
rv = searchFunc(srcmounts,dirname,minfreespace,existingpath);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
rv = createFunc(srcmounts,dirname,minfreespace,createpaths);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
error = -1;
|
||||
for(size_t i = 0, ei = createpaths.size(); i != ei; i++)
|
||||
{
|
||||
string &createpath = createpaths[i];
|
||||
|
||||
if(createpath != existingpath)
|
||||
{
|
||||
const ugid::SetRootGuard ugidGuard;
|
||||
fs::clonepath(existingpath,createpath,dirname);
|
||||
}
|
||||
|
||||
fs::path::append(createpath,fusepath);
|
||||
|
||||
rv = ::mknod(createpath.c_str(),mode,dev);
|
||||
|
||||
error = calc_error(rv,error,errno);
|
||||
error = _mknod_loop_core(existingpath,*createpaths[i],
|
||||
fusepath,fusedirpath,
|
||||
mode,dev,error);
|
||||
}
|
||||
|
||||
return -error;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_mknod(Policy::Func::Search searchFunc,
|
||||
Policy::Func::Create createFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const char *fusepath,
|
||||
const mode_t mode,
|
||||
const dev_t dev)
|
||||
{
|
||||
int rv;
|
||||
string fusedirpath;
|
||||
const char *fusedirpathcstr;
|
||||
vector<const string*> createpaths;
|
||||
vector<const string*> existingpaths;
|
||||
|
||||
fusedirpath = fusepath;
|
||||
fs::path::dirname(fusedirpath);
|
||||
fusedirpathcstr = fusedirpath.c_str();
|
||||
|
||||
rv = searchFunc(srcmounts,fusedirpathcstr,minfreespace,existingpaths);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
rv = createFunc(srcmounts,fusedirpathcstr,minfreespace,createpaths);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
return _mknod_loop(*existingpaths[0],createpaths,
|
||||
fusepath,fusedirpathcstr,
|
||||
mode,dev);
|
||||
}
|
||||
|
||||
namespace mergerfs
|
||||
{
|
||||
namespace fuse
|
||||
|
|
40
src/open.cpp
40
src/open.cpp
|
@ -35,24 +35,17 @@ using mergerfs::Policy;
|
|||
|
||||
static
|
||||
int
|
||||
_open(Policy::Func::Search searchFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const string &fusepath,
|
||||
const int flags,
|
||||
uint64_t &fh)
|
||||
_open_core(const string *basepath,
|
||||
const char *fusepath,
|
||||
const int flags,
|
||||
uint64_t &fh)
|
||||
{
|
||||
int fd;
|
||||
int rv;
|
||||
vector<string> path;
|
||||
string fullpath;
|
||||
|
||||
rv = searchFunc(srcmounts,fusepath,minfreespace,path);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
fs::path::make(basepath,fusepath,fullpath);
|
||||
|
||||
fs::path::append(path[0],fusepath);
|
||||
|
||||
fd = ::open(path[0].c_str(),flags);
|
||||
fd = ::open(fullpath.c_str(),flags);
|
||||
if(fd == -1)
|
||||
return -errno;
|
||||
|
||||
|
@ -61,6 +54,25 @@ _open(Policy::Func::Search searchFunc,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_open(Policy::Func::Search searchFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const char *fusepath,
|
||||
const int flags,
|
||||
uint64_t &fh)
|
||||
{
|
||||
int rv;
|
||||
vector<const string*> basepaths;
|
||||
|
||||
rv = searchFunc(srcmounts,fusepath,minfreespace,basepaths);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
return _open_core(basepaths[0],fusepath,flags,fh);
|
||||
}
|
||||
|
||||
namespace mergerfs
|
||||
{
|
||||
namespace fuse
|
||||
|
|
|
@ -61,12 +61,13 @@ namespace mergerfs
|
|||
typedef std::string string;
|
||||
typedef std::size_t size_t;
|
||||
typedef std::vector<string> strvec;
|
||||
typedef std::vector<const string*> cstrptrvec;
|
||||
typedef const string cstring;
|
||||
typedef const size_t csize_t;
|
||||
typedef const strvec cstrvec;
|
||||
typedef const Category::Enum::Type CType;
|
||||
|
||||
typedef int (*Ptr)(CType,cstrvec&,cstring&,csize_t,strvec&);
|
||||
typedef int (*Ptr)(CType,cstrvec &,const char *,csize_t,cstrptrvec &);
|
||||
|
||||
template <CType T>
|
||||
class Base
|
||||
|
@ -77,24 +78,11 @@ namespace mergerfs
|
|||
{}
|
||||
|
||||
int
|
||||
operator()(cstrvec& b,cstring& c,csize_t d,strvec& e)
|
||||
operator()(cstrvec &b,const char *c,csize_t d,cstrptrvec &e)
|
||||
{
|
||||
return func(T,b,c,d,e);
|
||||
}
|
||||
|
||||
int
|
||||
operator()(cstrvec& b,cstring& c,csize_t d,string& e)
|
||||
{
|
||||
int rv;
|
||||
strvec vec;
|
||||
|
||||
rv = func(T,b,c,d,vec);
|
||||
if(!vec.empty())
|
||||
e = vec[0];
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
private:
|
||||
const Ptr func;
|
||||
};
|
||||
|
@ -103,21 +91,21 @@ namespace mergerfs
|
|||
typedef Base<Category::Enum::create> Create;
|
||||
typedef Base<Category::Enum::search> Search;
|
||||
|
||||
static int all(CType,cstrvec&,cstring&,csize_t,strvec&);
|
||||
static int einval(CType,cstrvec&,cstring&,csize_t,strvec&);
|
||||
static int enosys(CType,cstrvec&,cstring&,csize_t,strvec&);
|
||||
static int enotsup(CType,cstrvec&,cstring&,csize_t,strvec&);
|
||||
static int epmfs(CType,cstrvec&,cstring&,csize_t,strvec&);
|
||||
static int erofs(CType,cstrvec&,cstring&,csize_t,strvec&);
|
||||
static int exdev(CType,cstrvec&,cstring&,csize_t,strvec&);
|
||||
static int ff(CType,cstrvec&,cstring&,csize_t,strvec&);
|
||||
static int ffwp(CType,cstrvec&,cstring&,csize_t,strvec&);
|
||||
static int fwfs(CType,cstrvec&,cstring&,csize_t,strvec&);
|
||||
static int invalid(CType,cstrvec&,cstring&,csize_t,strvec&);
|
||||
static int lfs(CType,cstrvec&,cstring&,csize_t,strvec&);
|
||||
static int mfs(CType,cstrvec&,cstring&,csize_t,strvec&);
|
||||
static int newest(CType,cstrvec&,cstring&,csize_t,strvec&);
|
||||
static int rand(CType,cstrvec&,cstring&,csize_t,strvec&);
|
||||
static int all(CType,cstrvec&,const char*,csize_t,cstrptrvec&);
|
||||
static int einval(CType,cstrvec&,const char*,csize_t,cstrptrvec&);
|
||||
static int enosys(CType,cstrvec&,const char *,csize_t,cstrptrvec&);
|
||||
static int enotsup(CType,cstrvec&,const char *,csize_t,cstrptrvec&);
|
||||
static int epmfs(CType,cstrvec&,const char *,csize_t,cstrptrvec&);
|
||||
static int erofs(CType,cstrvec&,const char *,csize_t,cstrptrvec&);
|
||||
static int exdev(CType,cstrvec&,const char *,csize_t,cstrptrvec&);
|
||||
static int ff(CType,cstrvec&,const char *,csize_t,cstrptrvec&);
|
||||
static int ffwp(CType,cstrvec&,const char *,csize_t,cstrptrvec&);
|
||||
static int fwfs(CType,cstrvec&,const char *,csize_t,cstrptrvec&);
|
||||
static int invalid(CType,cstrvec&,const char *,csize_t,cstrptrvec&);
|
||||
static int lfs(CType,cstrvec&,const char *,csize_t,cstrptrvec&);
|
||||
static int mfs(CType,cstrvec&,const char *,csize_t,cstrptrvec&);
|
||||
static int newest(CType,cstrvec&,const char *,csize_t,cstrptrvec&);
|
||||
static int rand(CType,cstrvec&,const char *,csize_t,cstrptrvec&);
|
||||
};
|
||||
|
||||
private:
|
||||
|
|
|
@ -31,9 +31,9 @@ using std::size_t;
|
|||
|
||||
static
|
||||
int
|
||||
_all(const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
vector<string> &paths)
|
||||
_all(const vector<string> &basepaths,
|
||||
const char *fusepath,
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
int rv;
|
||||
struct stat st;
|
||||
|
@ -41,7 +41,7 @@ _all(const vector<string> &basepaths,
|
|||
|
||||
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
|
||||
{
|
||||
const string &basepath = basepaths[i];
|
||||
const string *basepath = &basepaths[i];
|
||||
|
||||
fs::path::make(basepath,fusepath,fullpath);
|
||||
|
||||
|
@ -58,13 +58,14 @@ _all(const vector<string> &basepaths,
|
|||
|
||||
static
|
||||
int
|
||||
_all_create(const vector<string> &basepaths,
|
||||
vector<string> &paths)
|
||||
_all_create(const vector<string> &basepaths,
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
if(basepaths.empty())
|
||||
return (errno=ENOENT,-1);
|
||||
|
||||
paths = basepaths;
|
||||
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
|
||||
paths.push_back(&basepaths[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -74,9 +75,9 @@ namespace mergerfs
|
|||
int
|
||||
Policy::Func::all(const Category::Enum::Type type,
|
||||
const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
const char *fusepath,
|
||||
const size_t minfreespace,
|
||||
vector<string> &paths)
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
if(type == Category::Enum::create)
|
||||
return _all_create(basepaths,paths);
|
||||
|
|
|
@ -29,9 +29,9 @@ namespace mergerfs
|
|||
int
|
||||
Policy::Func::einval(const Category::Enum::Type type,
|
||||
const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
const char *fusepath,
|
||||
const size_t minfreespace,
|
||||
vector<string> &paths)
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
return (errno=EINVAL,-1);
|
||||
}
|
||||
|
|
|
@ -29,9 +29,9 @@ namespace mergerfs
|
|||
int
|
||||
Policy::Func::enosys(const Category::Enum::Type type,
|
||||
const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
const char *fusepath,
|
||||
const size_t minfreespace,
|
||||
vector<string> &paths)
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
return (errno=ENOSYS,-1);
|
||||
}
|
||||
|
|
|
@ -29,9 +29,9 @@ namespace mergerfs
|
|||
int
|
||||
Policy::Func::enotsup(const Category::Enum::Type type,
|
||||
const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
const char *fusepath,
|
||||
const size_t minfreespace,
|
||||
vector<string> &paths)
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
return (errno=ENOTSUP,-1);
|
||||
}
|
||||
|
|
|
@ -34,13 +34,12 @@ using mergerfs::Category;
|
|||
typedef struct statvfs statvfs_t;
|
||||
|
||||
static
|
||||
inline
|
||||
void
|
||||
_calc_mfs(const statvfs_t &fsstats,
|
||||
const string &basepath,
|
||||
const size_t minfreespace,
|
||||
fsblkcnt_t &mfs,
|
||||
string &mfsbasepath)
|
||||
_calc_mfs(const statvfs_t &fsstats,
|
||||
const string *basepath,
|
||||
const size_t minfreespace,
|
||||
fsblkcnt_t &mfs,
|
||||
const string *&mfsbasepath)
|
||||
{
|
||||
fsblkcnt_t spaceavail;
|
||||
|
||||
|
@ -54,22 +53,22 @@ _calc_mfs(const statvfs_t &fsstats,
|
|||
|
||||
static
|
||||
int
|
||||
_epmfs_create(const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
const size_t minfreespace,
|
||||
vector<string> &paths)
|
||||
|
||||
_epmfs_create(const vector<string> &basepaths,
|
||||
const char *fusepath,
|
||||
const size_t minfreespace,
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
int rv;
|
||||
int rv;
|
||||
string fullpath;
|
||||
statvfs_t fsstats;
|
||||
fsblkcnt_t epmfs;
|
||||
string epmfsbasepath;
|
||||
string fullpath;
|
||||
statvfs_t fsstats;
|
||||
const string *epmfsbasepath;
|
||||
|
||||
epmfs = 0;
|
||||
epmfsbasepath = NULL;
|
||||
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
|
||||
{
|
||||
const string &basepath = basepaths[i];
|
||||
const string *basepath = &basepaths[i];
|
||||
|
||||
fs::path::make(basepath,fusepath,fullpath);
|
||||
|
||||
|
@ -78,7 +77,7 @@ _epmfs_create(const vector<string> &basepaths,
|
|||
_calc_mfs(fsstats,basepath,minfreespace,epmfs,epmfsbasepath);
|
||||
}
|
||||
|
||||
if(epmfsbasepath.empty())
|
||||
if(epmfsbasepath == NULL)
|
||||
return Policy::Func::mfs(Category::Enum::create,basepaths,fusepath,minfreespace,paths);
|
||||
|
||||
paths.push_back(epmfsbasepath);
|
||||
|
@ -88,21 +87,22 @@ _epmfs_create(const vector<string> &basepaths,
|
|||
|
||||
static
|
||||
int
|
||||
_epmfs(const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
vector<string> &paths)
|
||||
_epmfs(const vector<string> &basepaths,
|
||||
const char *fusepath,
|
||||
vector<const string*> &paths)
|
||||
|
||||
{
|
||||
int rv;
|
||||
int rv;
|
||||
string fullpath;
|
||||
statvfs_t fsstats;
|
||||
fsblkcnt_t epmfs;
|
||||
string epmfsbasepath;
|
||||
string fullpath;
|
||||
statvfs_t fsstats;
|
||||
const string *epmfsbasepath;
|
||||
|
||||
epmfs = 0;
|
||||
epmfsbasepath = NULL;
|
||||
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
|
||||
{
|
||||
const string &basepath = basepaths[i];
|
||||
const string *basepath = &basepaths[i];
|
||||
|
||||
fs::path::make(basepath,fusepath,fullpath);
|
||||
|
||||
|
@ -111,7 +111,7 @@ _epmfs(const vector<string> &basepaths,
|
|||
_calc_mfs(fsstats,basepath,0,epmfs,epmfsbasepath);
|
||||
}
|
||||
|
||||
if(epmfsbasepath.empty())
|
||||
if(epmfsbasepath == NULL)
|
||||
return (errno=ENOENT,-1);
|
||||
|
||||
paths.push_back(epmfsbasepath);
|
||||
|
@ -124,9 +124,9 @@ namespace mergerfs
|
|||
int
|
||||
Policy::Func::epmfs(const Category::Enum::Type type,
|
||||
const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
const char *fusepath,
|
||||
const size_t minfreespace,
|
||||
vector<string> &paths)
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
if(type == Category::Enum::create)
|
||||
return _epmfs_create(basepaths,fusepath,minfreespace,paths);
|
||||
|
|
|
@ -29,9 +29,9 @@ namespace mergerfs
|
|||
int
|
||||
Policy::Func::erofs(const Category::Enum::Type type,
|
||||
const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
const char *fusepath,
|
||||
const size_t minfreespace,
|
||||
vector<string> &paths)
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
return (errno=EROFS,-1);
|
||||
}
|
||||
|
|
|
@ -29,9 +29,9 @@ namespace mergerfs
|
|||
int
|
||||
Policy::Func::exdev(const Category::Enum::Type type,
|
||||
const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
const char *fusepath,
|
||||
const size_t minfreespace,
|
||||
vector<string> &paths)
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
return (errno=EXDEV,-1);
|
||||
}
|
||||
|
|
|
@ -31,18 +31,19 @@ using std::size_t;
|
|||
|
||||
static
|
||||
int
|
||||
_ff(const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
vector<string> &paths)
|
||||
_ff(const vector<string> &basepaths,
|
||||
const char *fusepath,
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
int rv;
|
||||
string fullpath;
|
||||
struct stat st;
|
||||
|
||||
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
|
||||
{
|
||||
int rv;
|
||||
struct stat st;
|
||||
string fullpath;
|
||||
const string &basepath = basepaths[i];
|
||||
const string *basepath = &basepaths[i];
|
||||
|
||||
fullpath = fs::path::make(basepath,fusepath);
|
||||
fs::path::make(basepath,fusepath,fullpath);
|
||||
|
||||
rv = ::lstat(fullpath.c_str(),&st);
|
||||
if(rv == -1)
|
||||
|
@ -58,14 +59,14 @@ _ff(const vector<string> &basepaths,
|
|||
|
||||
static
|
||||
int
|
||||
_ff_create(const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
vector<string> &paths)
|
||||
_ff_create(const vector<string> &basepaths,
|
||||
const char *fusepath,
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
if(basepaths.empty())
|
||||
return (errno=ENOENT,-1);
|
||||
|
||||
paths.push_back(basepaths[0]);
|
||||
paths.push_back(&basepaths[0]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -75,9 +76,9 @@ namespace mergerfs
|
|||
int
|
||||
Policy::Func::ff(const Category::Enum::Type type,
|
||||
const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
const char *fusepath,
|
||||
const size_t minfreespace,
|
||||
vector<string> &paths)
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
if(type == Category::Enum::create)
|
||||
return _ff_create(basepaths,fusepath,paths);
|
||||
|
|
|
@ -31,18 +31,19 @@ using std::size_t;
|
|||
|
||||
static
|
||||
int
|
||||
_ffwp(const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
vector<string> &paths)
|
||||
_ffwp(const vector<string> &basepaths,
|
||||
const char *fusepath,
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
string fallback;
|
||||
int rv;
|
||||
struct stat st;
|
||||
string fullpath;
|
||||
const string *fallback;
|
||||
|
||||
fallback = NULL;
|
||||
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
|
||||
{
|
||||
int rv;
|
||||
struct stat st;
|
||||
string fullpath;
|
||||
const string &basepath = basepaths[i];
|
||||
const string *basepath = &basepaths[i];
|
||||
|
||||
fs::path::make(basepath,fusepath,fullpath);
|
||||
|
||||
|
@ -58,7 +59,7 @@ _ffwp(const vector<string> &basepaths,
|
|||
}
|
||||
}
|
||||
|
||||
if(fallback.empty())
|
||||
if(fallback == NULL)
|
||||
return (errno=ENOENT,-1);
|
||||
|
||||
paths.push_back(fallback);
|
||||
|
@ -71,9 +72,9 @@ namespace mergerfs
|
|||
int
|
||||
Policy::Func::ffwp(const Category::Enum::Type type,
|
||||
const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
const char *fusepath,
|
||||
const size_t minfreespace,
|
||||
vector<string> &paths)
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
return _ffwp(basepaths,fusepath,paths);
|
||||
}
|
||||
|
|
|
@ -33,15 +33,16 @@ static
|
|||
int
|
||||
_fwfs_create(const Category::Enum::Type type,
|
||||
const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
const char *fusepath,
|
||||
const size_t minfreespace,
|
||||
vector<string> &paths)
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
int rv;
|
||||
struct statvfs fsstats;
|
||||
|
||||
for(size_t i = 0, size = basepaths.size(); i != size; i++)
|
||||
{
|
||||
int rv;
|
||||
struct statvfs fsstats;
|
||||
const string &basepath = basepaths[i];
|
||||
const string &basepath = basepaths[i];
|
||||
|
||||
rv = ::statvfs(basepath.c_str(),&fsstats);
|
||||
if(rv == 0)
|
||||
|
@ -52,7 +53,7 @@ _fwfs_create(const Category::Enum::Type type,
|
|||
if(spaceavail < minfreespace)
|
||||
continue;
|
||||
|
||||
paths.push_back(basepath);
|
||||
paths.push_back(&basepath);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -65,16 +66,17 @@ static
|
|||
int
|
||||
_fwfs(const Category::Enum::Type type,
|
||||
const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
const char *fusepath,
|
||||
const size_t minfreespace,
|
||||
vector<string> &paths)
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
int rv;
|
||||
string fullpath;
|
||||
struct statvfs fsstats;
|
||||
|
||||
for(size_t i = 0, size = basepaths.size(); i != size; i++)
|
||||
{
|
||||
int rv;
|
||||
string fullpath;
|
||||
struct statvfs fsstats;
|
||||
const string &basepath = basepaths[i];
|
||||
const string *basepath = &basepaths[i];
|
||||
|
||||
fs::path::make(basepath,fusepath,fullpath);
|
||||
|
||||
|
@ -101,9 +103,9 @@ namespace mergerfs
|
|||
int
|
||||
Policy::Func::fwfs(const Category::Enum::Type type,
|
||||
const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
const char *fusepath,
|
||||
const size_t minfreespace,
|
||||
vector<string> &paths)
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
if(type == Category::Enum::create)
|
||||
return _fwfs_create(type,basepaths,fusepath,minfreespace,paths);
|
||||
|
|
|
@ -30,9 +30,9 @@ namespace mergerfs
|
|||
int
|
||||
Policy::Func::invalid(const Category::Enum::Type type,
|
||||
const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
const char *fusepath,
|
||||
const size_t minfreespace,
|
||||
vector<string> &rv)
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
return (errno=EINVAL,-1);
|
||||
}
|
||||
|
|
|
@ -36,18 +36,19 @@ static
|
|||
int
|
||||
_lfs_create(const Category::Enum::Type type,
|
||||
const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
const char *fusepath,
|
||||
const size_t minfreespace,
|
||||
vector<string> &paths)
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
int rv;
|
||||
fsblkcnt_t lfs;
|
||||
string lfsstr;
|
||||
const string *lfsstr;
|
||||
struct statvfs fsstats;
|
||||
|
||||
lfs = -1;
|
||||
lfs = -1;
|
||||
lfsstr = NULL;
|
||||
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
|
||||
{
|
||||
int rv;
|
||||
struct statvfs fsstats;
|
||||
const string &basepath = basepaths[i];
|
||||
|
||||
rv = ::statvfs(basepath.c_str(),&fsstats);
|
||||
|
@ -60,12 +61,12 @@ _lfs_create(const Category::Enum::Type type,
|
|||
(spaceavail < lfs))
|
||||
{
|
||||
lfs = spaceavail;
|
||||
lfsstr = basepath;
|
||||
lfsstr = &basepath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(lfsstr.empty())
|
||||
if(lfsstr == NULL)
|
||||
return Policy::Func::mfs(type,basepaths,fusepath,minfreespace,paths);
|
||||
|
||||
paths.push_back(lfsstr);
|
||||
|
@ -77,20 +78,21 @@ static
|
|||
int
|
||||
_lfs(const Category::Enum::Type type,
|
||||
const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
const char *fusepath,
|
||||
const size_t minfreespace,
|
||||
vector<string> &paths)
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
int rv;
|
||||
string fullpath;
|
||||
struct statvfs fsstats;
|
||||
fsblkcnt_t lfs;
|
||||
string lfsstr;
|
||||
const string *lfsstr;
|
||||
|
||||
lfs = -1;
|
||||
lfs = -1;
|
||||
lfsstr = NULL;
|
||||
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
|
||||
{
|
||||
int rv;
|
||||
string fullpath;
|
||||
struct statvfs fsstats;
|
||||
const string &basepath = basepaths[i];
|
||||
const string *basepath = &basepaths[i];
|
||||
|
||||
fs::path::make(basepath,fusepath,fullpath);
|
||||
|
||||
|
@ -109,7 +111,7 @@ _lfs(const Category::Enum::Type type,
|
|||
}
|
||||
}
|
||||
|
||||
if(lfsstr.empty())
|
||||
if(lfsstr == NULL)
|
||||
return Policy::Func::mfs(type,basepaths,fusepath,minfreespace,paths);
|
||||
|
||||
paths.push_back(lfsstr);
|
||||
|
@ -122,9 +124,9 @@ namespace mergerfs
|
|||
int
|
||||
Policy::Func::lfs(const Category::Enum::Type type,
|
||||
const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
const char *fusepath,
|
||||
const size_t minfreespace,
|
||||
vector<string> &paths)
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
if(type == Category::Enum::create)
|
||||
return _lfs_create(type,basepaths,fusepath,minfreespace,paths);
|
||||
|
|
|
@ -29,18 +29,19 @@ using std::size_t;
|
|||
|
||||
static
|
||||
int
|
||||
_mfs_create(const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
vector<string> &paths)
|
||||
_mfs_create(const vector<string> &basepaths,
|
||||
const char *fusepath,
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
int rv;
|
||||
struct statvfs fsstats;
|
||||
fsblkcnt_t mfs;
|
||||
string mfsstr;
|
||||
const string *mfsstr;
|
||||
|
||||
mfs = 0;
|
||||
mfsstr = NULL;
|
||||
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
|
||||
{
|
||||
int rv;
|
||||
struct statvfs fsstats;
|
||||
const string &basepath = basepaths[i];
|
||||
|
||||
rv = ::statvfs(basepath.c_str(),&fsstats);
|
||||
|
@ -52,12 +53,12 @@ _mfs_create(const vector<string> &basepaths,
|
|||
if(spaceavail > mfs)
|
||||
{
|
||||
mfs = spaceavail;
|
||||
mfsstr = basepath;
|
||||
mfsstr = &basepath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(mfsstr.empty())
|
||||
if(mfsstr == NULL)
|
||||
return (errno=ENOENT,-1);
|
||||
|
||||
paths.push_back(mfsstr);
|
||||
|
@ -67,20 +68,21 @@ _mfs_create(const vector<string> &basepaths,
|
|||
|
||||
static
|
||||
int
|
||||
_mfs(const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
vector<string> &paths)
|
||||
_mfs(const vector<string> &basepaths,
|
||||
const char *fusepath,
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
int rv;
|
||||
string fullpath;
|
||||
struct statvfs fsstats;
|
||||
fsblkcnt_t mfs;
|
||||
string mfsstr;
|
||||
const string *mfsstr;
|
||||
|
||||
mfs = 0;
|
||||
mfsstr = NULL;
|
||||
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
|
||||
{
|
||||
int rv;
|
||||
string fullpath;
|
||||
struct statvfs fsstats;
|
||||
const string &basepath = basepaths[i];
|
||||
const string *basepath = &basepaths[i];
|
||||
|
||||
fs::path::make(basepath,fusepath,fullpath);
|
||||
|
||||
|
@ -98,7 +100,7 @@ _mfs(const vector<string> &basepaths,
|
|||
}
|
||||
}
|
||||
|
||||
if(mfsstr.empty())
|
||||
if(mfsstr == NULL)
|
||||
return (errno=ENOENT,-1);
|
||||
|
||||
paths.push_back(mfsstr);
|
||||
|
@ -111,9 +113,9 @@ namespace mergerfs
|
|||
int
|
||||
Policy::Func::mfs(const Category::Enum::Type type,
|
||||
const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
const char *fusepath,
|
||||
const size_t minfreespace,
|
||||
vector<string> &paths)
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
if(type == Category::Enum::create)
|
||||
return _mfs_create(basepaths,fusepath,paths);
|
||||
|
|
|
@ -32,19 +32,21 @@ using std::size_t;
|
|||
|
||||
static
|
||||
int
|
||||
_newest(const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
vector<string> &paths)
|
||||
_newest(const vector<string> &basepaths,
|
||||
const char *fusepath,
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
time_t newest = std::numeric_limits<time_t>::min();
|
||||
string neweststr;
|
||||
int rv;
|
||||
struct stat st;
|
||||
string fullpath;
|
||||
time_t newest;
|
||||
const string *neweststr;
|
||||
|
||||
newest = std::numeric_limits<time_t>::min();
|
||||
neweststr = NULL;
|
||||
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
|
||||
{
|
||||
int rv;
|
||||
struct stat st;
|
||||
string fullpath;
|
||||
const string &basepath = basepaths[i];
|
||||
const string *basepath = &basepaths[i];
|
||||
|
||||
fs::path::make(basepath,fusepath,fullpath);
|
||||
|
||||
|
@ -56,7 +58,7 @@ _newest(const vector<string> &basepaths,
|
|||
}
|
||||
}
|
||||
|
||||
if(neweststr.empty())
|
||||
if(neweststr == NULL)
|
||||
return (errno=ENOENT,-1);
|
||||
|
||||
paths.push_back(neweststr);
|
||||
|
@ -69,9 +71,9 @@ namespace mergerfs
|
|||
int
|
||||
Policy::Func::newest(const Category::Enum::Type type,
|
||||
const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
const char *fusepath,
|
||||
const size_t minfreespace,
|
||||
vector<string> &paths)
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
return _newest(basepaths,fusepath,paths);
|
||||
}
|
||||
|
|
|
@ -31,9 +31,9 @@ namespace mergerfs
|
|||
int
|
||||
Policy::Func::rand(const Category::Enum::Type type,
|
||||
const vector<string> &basepaths,
|
||||
const string &fusepath,
|
||||
const char *fusepath,
|
||||
const size_t minfreespace,
|
||||
vector<string> &paths)
|
||||
vector<const string*> &paths)
|
||||
{
|
||||
int rv;
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ using std::pair;
|
|||
static
|
||||
int
|
||||
_readdir(const vector<string> &srcmounts,
|
||||
const string &dirname,
|
||||
const char *dirname,
|
||||
void *buf,
|
||||
const fuse_fill_dir_t filler)
|
||||
{
|
||||
|
@ -53,7 +53,8 @@ _readdir(const vector<string> &srcmounts,
|
|||
DIR *dh;
|
||||
string basepath;
|
||||
|
||||
fs::path::make(srcmounts[i],dirname,basepath);
|
||||
fs::path::make(&srcmounts[i],dirname,basepath);
|
||||
|
||||
dh = ::opendir(basepath.c_str());
|
||||
if(!dh)
|
||||
continue;
|
||||
|
|
|
@ -33,23 +33,17 @@ using mergerfs::Policy;
|
|||
|
||||
static
|
||||
int
|
||||
_readlink(Policy::Func::Search searchFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const string &fusepath,
|
||||
char *buf,
|
||||
const size_t size)
|
||||
_readlink_core(const string *basepath,
|
||||
const char *fusepath,
|
||||
char *buf,
|
||||
const size_t size)
|
||||
{
|
||||
int rv;
|
||||
vector<string> path;
|
||||
string fullpath;
|
||||
|
||||
rv = searchFunc(srcmounts,fusepath,minfreespace,path);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
fs::path::make(basepath,fusepath,fullpath);
|
||||
|
||||
fs::path::append(path[0],fusepath);
|
||||
|
||||
rv = ::readlink(path[0].c_str(),buf,size);
|
||||
rv = ::readlink(fullpath.c_str(),buf,size);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
|
@ -58,6 +52,25 @@ _readlink(Policy::Func::Search searchFunc,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_readlink(Policy::Func::Search searchFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const char *fusepath,
|
||||
char *buf,
|
||||
const size_t size)
|
||||
{
|
||||
int rv;
|
||||
vector<const string*> basepaths;
|
||||
|
||||
rv = searchFunc(srcmounts,fusepath,minfreespace,basepaths);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
return _readlink_core(basepaths[0],fusepath,buf,size);
|
||||
}
|
||||
|
||||
namespace mergerfs
|
||||
{
|
||||
namespace fuse
|
||||
|
|
|
@ -33,38 +33,60 @@ using std::string;
|
|||
using std::vector;
|
||||
using mergerfs::Policy;
|
||||
|
||||
#ifndef WITHOUT_XATTR
|
||||
static
|
||||
int
|
||||
_removexattr_loop_core(const string *basepath,
|
||||
const char *fusepath,
|
||||
const char *attrname,
|
||||
const int error)
|
||||
{
|
||||
int rv;
|
||||
string fullpath;
|
||||
|
||||
fs::path::make(basepath,fusepath,fullpath);
|
||||
|
||||
rv = ::lremovexattr(fullpath.c_str(),attrname);
|
||||
|
||||
return calc_error(rv,error,errno);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_removexattr_loop(const vector<const string*> &basepaths,
|
||||
const char *fusepath,
|
||||
const char *attrname)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = -1;
|
||||
|
||||
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
|
||||
{
|
||||
error = _removexattr_loop_core(basepaths[i],fusepath,attrname,error);
|
||||
}
|
||||
|
||||
return -error;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_removexattr(Policy::Func::Action actionFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const string &fusepath,
|
||||
const char *fusepath,
|
||||
const char *attrname)
|
||||
{
|
||||
#ifndef WITHOUT_XATTR
|
||||
int rv;
|
||||
int error;
|
||||
vector<string> paths;
|
||||
vector<const string*> basepaths;
|
||||
|
||||
rv = actionFunc(srcmounts,fusepath,minfreespace,paths);
|
||||
rv = actionFunc(srcmounts,fusepath,minfreespace,basepaths);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
error = -1;
|
||||
for(size_t i = 0, ei = paths.size(); i != ei; i++)
|
||||
{
|
||||
fs::path::append(paths[i],fusepath);
|
||||
|
||||
rv = ::lremovexattr(paths[i].c_str(),attrname);
|
||||
|
||||
error = calc_error(rv,error,errno);
|
||||
}
|
||||
|
||||
return -error;
|
||||
#else
|
||||
return -ENOTSUP;
|
||||
#endif
|
||||
return _removexattr_loop(basepaths,fusepath,attrname);
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace mergerfs
|
||||
{
|
||||
|
@ -74,6 +96,7 @@ namespace mergerfs
|
|||
removexattr(const char *fusepath,
|
||||
const char *attrname)
|
||||
{
|
||||
#ifndef WITHOUT_XATTR
|
||||
const fuse_context *fc = fuse_get_context();
|
||||
const Config &config = Config::get(fc);
|
||||
|
||||
|
@ -88,6 +111,9 @@ namespace mergerfs
|
|||
config.minfreespace,
|
||||
fusepath,
|
||||
attrname);
|
||||
#else
|
||||
return -ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
114
src/rename.cpp
114
src/rename.cpp
|
@ -38,10 +38,16 @@ using namespace mergerfs;
|
|||
|
||||
static
|
||||
bool
|
||||
member(const vector<string> &haystack,
|
||||
const string &needle)
|
||||
member(const vector<const string*> &haystack,
|
||||
const string &needle)
|
||||
{
|
||||
return (std::find(haystack.begin(),haystack.end(),needle) != haystack.end());
|
||||
for(size_t i = 0, ei = haystack.size(); i != ei; i++)
|
||||
{
|
||||
if(*haystack[i] == needle)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static
|
||||
|
@ -54,21 +60,21 @@ _remove(const vector<string> &toremove)
|
|||
|
||||
static
|
||||
void
|
||||
_rename_create_path_one(const vector<string> &oldbasepaths,
|
||||
const string &oldbasepath,
|
||||
const string &newbasepath,
|
||||
const string &oldfusepath,
|
||||
const string &newfusepath,
|
||||
const string &newfusedirpath,
|
||||
int &error,
|
||||
vector<string> &tounlink)
|
||||
_rename_create_path_core(const vector<const string*> &oldbasepaths,
|
||||
const string &oldbasepath,
|
||||
const string &newbasepath,
|
||||
const char *oldfusepath,
|
||||
const char *newfusepath,
|
||||
const string &newfusedirpath,
|
||||
int &error,
|
||||
vector<string> &tounlink)
|
||||
{
|
||||
int rv;
|
||||
bool ismember;
|
||||
string oldfullpath;
|
||||
string newfullpath;
|
||||
|
||||
fs::path::make(oldbasepath,newfusepath,newfullpath);
|
||||
fs::path::make(&oldbasepath,newfusepath,newfullpath);
|
||||
|
||||
ismember = member(oldbasepaths,oldbasepath);
|
||||
if(ismember)
|
||||
|
@ -76,10 +82,10 @@ _rename_create_path_one(const vector<string> &oldbasepaths,
|
|||
if(oldbasepath != newbasepath)
|
||||
{
|
||||
const ugid::SetRootGuard ugidGuard;
|
||||
fs::clonepath(newbasepath,oldbasepath,newfusedirpath);
|
||||
fs::clonepath(newbasepath,oldbasepath,newfusedirpath.c_str());
|
||||
}
|
||||
|
||||
fs::path::make(oldbasepath,oldfusepath,oldfullpath);
|
||||
fs::path::make(&oldbasepath,oldfusepath,oldfullpath);
|
||||
|
||||
rv = ::rename(oldfullpath.c_str(),newfullpath.c_str());
|
||||
error = calc_error(rv,error,errno);
|
||||
|
@ -98,21 +104,22 @@ _rename_create_path(Policy::Func::Search searchFunc,
|
|||
Policy::Func::Action actionFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const string &oldfusepath,
|
||||
const string &newfusepath)
|
||||
const char *oldfusepath,
|
||||
const char *newfusepath)
|
||||
{
|
||||
int rv;
|
||||
int error;
|
||||
string newbasepath;
|
||||
vector<string> toremove;
|
||||
vector<string> oldbasepaths;
|
||||
vector<const string*> newbasepath;
|
||||
vector<const string*> oldbasepaths;
|
||||
|
||||
rv = actionFunc(srcmounts,oldfusepath,minfreespace,oldbasepaths);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
const string newfusedirpath = fs::path::dirname(newfusepath);
|
||||
rv = searchFunc(srcmounts,newfusedirpath,minfreespace,newbasepath);
|
||||
string newfusedirpath = newfusepath;
|
||||
fs::path::dirname(newfusedirpath);
|
||||
rv = searchFunc(srcmounts,newfusedirpath.c_str(),minfreespace,newbasepath);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
|
@ -121,10 +128,11 @@ _rename_create_path(Policy::Func::Search searchFunc,
|
|||
{
|
||||
const string &oldbasepath = srcmounts[i];
|
||||
|
||||
_rename_create_path_one(oldbasepaths,oldbasepath,newbasepath,
|
||||
oldfusepath,newfusepath,
|
||||
newfusedirpath,
|
||||
error,toremove);
|
||||
_rename_create_path_core(oldbasepaths,
|
||||
oldbasepath,*newbasepath[0],
|
||||
oldfusepath,newfusepath,
|
||||
newfusedirpath,
|
||||
error,toremove);
|
||||
}
|
||||
|
||||
if(error == 0)
|
||||
|
@ -140,25 +148,25 @@ _clonepath_if_would_create(Policy::Func::Search searchFunc,
|
|||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const string &oldbasepath,
|
||||
const string &oldfusepath,
|
||||
const string &newfusepath)
|
||||
const char *oldfusepath,
|
||||
const char *newfusepath)
|
||||
{
|
||||
int rv;
|
||||
string newbasepath;
|
||||
string newfusedirpath;
|
||||
vector<const string*> newbasepath;
|
||||
|
||||
newfusedirpath = fs::path::dirname(newfusepath);
|
||||
|
||||
rv = createFunc(srcmounts,newfusedirpath,minfreespace,newbasepath);
|
||||
newfusedirpath = newfusepath;
|
||||
fs::path::dirname(newfusedirpath);
|
||||
rv = createFunc(srcmounts,newfusedirpath.c_str(),minfreespace,newbasepath);
|
||||
if(rv != -1)
|
||||
{
|
||||
if(oldbasepath == newbasepath)
|
||||
if(oldbasepath == *newbasepath[0])
|
||||
{
|
||||
rv = searchFunc(srcmounts,newfusedirpath,minfreespace,newbasepath);
|
||||
rv = searchFunc(srcmounts,newfusedirpath.c_str(),minfreespace,newbasepath);
|
||||
if(rv != -1)
|
||||
{
|
||||
const ugid::SetRootGuard ugidGuard;
|
||||
fs::clonepath(newbasepath,oldbasepath,newfusedirpath);
|
||||
fs::clonepath(*newbasepath[0],oldbasepath,newfusedirpath.c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -173,29 +181,29 @@ _clonepath_if_would_create(Policy::Func::Search searchFunc,
|
|||
|
||||
static
|
||||
void
|
||||
_rename_preserve_path_one(Policy::Func::Search searchFunc,
|
||||
Policy::Func::Create createFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const vector<string> &oldbasepaths,
|
||||
const string &oldbasepath,
|
||||
const string &oldfusepath,
|
||||
const string &newfusepath,
|
||||
int &error,
|
||||
vector<string> &toremove)
|
||||
_rename_preserve_path_core(Policy::Func::Search searchFunc,
|
||||
Policy::Func::Create createFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const vector<const string*> &oldbasepaths,
|
||||
const string &oldbasepath,
|
||||
const char *oldfusepath,
|
||||
const char *newfusepath,
|
||||
int &error,
|
||||
vector<string> &toremove)
|
||||
{
|
||||
int rv;
|
||||
bool ismember;
|
||||
string newfullpath;
|
||||
|
||||
fs::path::make(oldbasepath,newfusepath,newfullpath);
|
||||
fs::path::make(&oldbasepath,newfusepath,newfullpath);
|
||||
|
||||
ismember = member(oldbasepaths,oldbasepath);
|
||||
if(ismember)
|
||||
{
|
||||
string oldfullpath;
|
||||
|
||||
fs::path::make(oldbasepath,oldfusepath,oldfullpath);
|
||||
fs::path::make(&oldbasepath,oldfusepath,oldfullpath);
|
||||
|
||||
rv = ::rename(oldfullpath.c_str(),newfullpath.c_str());
|
||||
if((rv == -1) && (errno == ENOENT))
|
||||
|
@ -224,13 +232,13 @@ _rename_preserve_path(Policy::Func::Search searchFunc,
|
|||
Policy::Func::Create createFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const string &oldfusepath,
|
||||
const string &newfusepath)
|
||||
const char *oldfusepath,
|
||||
const char *newfusepath)
|
||||
{
|
||||
int rv;
|
||||
int error;
|
||||
vector<string> toremove;
|
||||
vector<string> oldbasepaths;
|
||||
vector<const string*> oldbasepaths;
|
||||
|
||||
rv = actionFunc(srcmounts,oldfusepath,minfreespace,oldbasepaths);
|
||||
if(rv == -1)
|
||||
|
@ -241,11 +249,11 @@ _rename_preserve_path(Policy::Func::Search searchFunc,
|
|||
{
|
||||
const string &oldbasepath = srcmounts[i];
|
||||
|
||||
_rename_preserve_path_one(searchFunc,createFunc,
|
||||
srcmounts,minfreespace,
|
||||
oldbasepaths,oldbasepath,
|
||||
oldfusepath,newfusepath,
|
||||
error,toremove);
|
||||
_rename_preserve_path_core(searchFunc,createFunc,
|
||||
srcmounts,minfreespace,
|
||||
oldbasepaths,oldbasepath,
|
||||
oldfusepath,newfusepath,
|
||||
error,toremove);
|
||||
}
|
||||
|
||||
if(error == 0)
|
||||
|
|
|
@ -33,32 +33,54 @@ using mergerfs::Policy;
|
|||
|
||||
static
|
||||
int
|
||||
_rmdir(Policy::Func::Action actionFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const string &fusepath)
|
||||
_rmdir_loop_core(const string *basepath,
|
||||
const char *fusepath,
|
||||
const int error)
|
||||
{
|
||||
int rv;
|
||||
int error;
|
||||
vector<string> paths;
|
||||
string fullpath;
|
||||
|
||||
rv = actionFunc(srcmounts,fusepath,minfreespace,paths);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
fs::path::make(basepath,fusepath,fullpath);
|
||||
|
||||
rv = ::rmdir(fullpath.c_str());
|
||||
|
||||
return calc_error(rv,error,errno);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int
|
||||
_rmdir_loop(const vector<const string*> &basepaths,
|
||||
const char *fusepath)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = -1;
|
||||
for(size_t i = 0, ei = paths.size(); i != ei; i++)
|
||||
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
|
||||
{
|
||||
fs::path::append(paths[i],fusepath);
|
||||
|
||||
rv = ::rmdir(paths[i].c_str());
|
||||
|
||||
error = calc_error(rv,error,errno);
|
||||
error = _rmdir_loop_core(basepaths[i],fusepath,error);
|
||||
}
|
||||
|
||||
return -error;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_rmdir(Policy::Func::Action actionFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const char *fusepath)
|
||||
{
|
||||
int rv;
|
||||
vector<const string*> basepaths;
|
||||
|
||||
rv = actionFunc(srcmounts,fusepath,minfreespace,basepaths);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
return _rmdir_loop(basepaths,fusepath);
|
||||
}
|
||||
|
||||
namespace mergerfs
|
||||
{
|
||||
namespace fuse
|
||||
|
|
|
@ -287,41 +287,73 @@ _setxattr_controlfile(Config &config,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
#ifndef WITHOUT_XATTR
|
||||
|
||||
static
|
||||
int
|
||||
_setxattr_loop_core(const string *basepath,
|
||||
const char *fusepath,
|
||||
const char *attrname,
|
||||
const char *attrval,
|
||||
const size_t attrvalsize,
|
||||
const int flags,
|
||||
const int error)
|
||||
{
|
||||
int rv;
|
||||
string fullpath;
|
||||
|
||||
fs::path::make(basepath,fusepath,fullpath);
|
||||
|
||||
rv = ::lsetxattr(fullpath.c_str(),attrname,attrval,attrvalsize,flags);
|
||||
|
||||
return calc_error(rv,error,errno);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_setxattr_loop(const vector<const string*> &basepaths,
|
||||
const char *fusepath,
|
||||
const char *attrname,
|
||||
const char *attrval,
|
||||
const size_t attrvalsize,
|
||||
const int flags)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = -1;
|
||||
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
|
||||
{
|
||||
error = _setxattr_loop_core(basepaths[i],fusepath,
|
||||
attrname,attrval,attrvalsize,flags,
|
||||
error);
|
||||
}
|
||||
|
||||
return -error;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_setxattr(Policy::Func::Action actionFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const string &fusepath,
|
||||
const char *fusepath,
|
||||
const char *attrname,
|
||||
const char *attrval,
|
||||
const size_t attrvalsize,
|
||||
const int flags)
|
||||
{
|
||||
#ifndef WITHOUT_XATTR
|
||||
int rv;
|
||||
int error;
|
||||
vector<string> paths;
|
||||
vector<const string*> basepaths;
|
||||
|
||||
rv = actionFunc(srcmounts,fusepath,minfreespace,paths);
|
||||
rv = actionFunc(srcmounts,fusepath,minfreespace,basepaths);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
error = -1;
|
||||
for(size_t i = 0, ei = paths.size(); i != ei; i++)
|
||||
{
|
||||
fs::path::append(paths[i],fusepath);
|
||||
|
||||
rv = ::lsetxattr(paths[i].c_str(),attrname,attrval,attrvalsize,flags);
|
||||
|
||||
error = calc_error(rv,error,errno);
|
||||
}
|
||||
|
||||
return -error;
|
||||
#else
|
||||
return -ENOTSUP;
|
||||
#endif
|
||||
return _setxattr_loop(basepaths,fusepath,attrname,attrval,attrvalsize,flags);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
namespace mergerfs
|
||||
{
|
||||
namespace fuse
|
||||
|
@ -342,6 +374,7 @@ namespace mergerfs
|
|||
string(attrval,attrvalsize),
|
||||
flags);
|
||||
|
||||
#ifndef WITHOUT_XATTR
|
||||
const ugid::Set ugid(fc->uid,fc->gid);
|
||||
const rwlock::ReadGuard readlock(&config.srcmountslock);
|
||||
|
||||
|
@ -353,6 +386,9 @@ namespace mergerfs
|
|||
attrval,
|
||||
attrvalsize,
|
||||
flags);
|
||||
#else
|
||||
return -ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
10
src/str.cpp
10
src/str.cpp
|
@ -28,7 +28,7 @@ namespace str
|
|||
{
|
||||
void
|
||||
split(vector<string> &result,
|
||||
const string &str,
|
||||
const char *str,
|
||||
const char delimiter)
|
||||
{
|
||||
string part;
|
||||
|
@ -38,6 +38,14 @@ namespace str
|
|||
result.push_back(part);
|
||||
}
|
||||
|
||||
void
|
||||
split(vector<string> &result,
|
||||
const string &str,
|
||||
const char delimiter)
|
||||
{
|
||||
return split(result,str.c_str(),delimiter);
|
||||
}
|
||||
|
||||
string
|
||||
join(const vector<string> &vec,
|
||||
const size_t substridx,
|
||||
|
|
|
@ -20,6 +20,10 @@
|
|||
namespace str
|
||||
{
|
||||
void
|
||||
split(std::vector<std::string> &result,
|
||||
const char *str,
|
||||
const char delimiter);
|
||||
void
|
||||
split(std::vector<std::string> &result,
|
||||
const std::string &str,
|
||||
const char delimiter);
|
||||
|
|
|
@ -33,49 +33,81 @@ using std::vector;
|
|||
using mergerfs::Policy;
|
||||
using namespace mergerfs;
|
||||
|
||||
static
|
||||
int
|
||||
_symlink_loop_core(const string &existingpath,
|
||||
const string &newbasepath,
|
||||
const char *oldpath,
|
||||
const char *newpath,
|
||||
const char *newdirpath,
|
||||
const int error)
|
||||
{
|
||||
int rv;
|
||||
string fullnewpath;
|
||||
|
||||
if(newbasepath != existingpath)
|
||||
{
|
||||
const ugid::SetRootGuard ugidGuard;
|
||||
fs::clonepath(existingpath,newbasepath,newdirpath);
|
||||
}
|
||||
|
||||
fs::path::make(&newbasepath,newpath,fullnewpath);
|
||||
|
||||
rv = ::symlink(oldpath,fullnewpath.c_str());
|
||||
|
||||
return calc_error(rv,error,errno);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_symlink_loop(const string &existingpath,
|
||||
const vector<const string*> newbasepaths,
|
||||
const char *oldpath,
|
||||
const char *newpath,
|
||||
const char *newdirpath)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = -1;
|
||||
for(size_t i = 0, ei = newbasepaths.size(); i != ei; i++)
|
||||
{
|
||||
error = _symlink_loop_core(existingpath,*newbasepaths[i],
|
||||
oldpath,newpath,newdirpath,
|
||||
error);
|
||||
}
|
||||
|
||||
return -error;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_symlink(Policy::Func::Search searchFunc,
|
||||
Policy::Func::Create createFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const string &oldpath,
|
||||
const string &newpath)
|
||||
const char *oldpath,
|
||||
const char *newpath)
|
||||
{
|
||||
int rv;
|
||||
int error;
|
||||
string dirname;
|
||||
string existingpath;
|
||||
vector<string> newpathdirs;
|
||||
string newdirpath;
|
||||
const char *newdirpathcstr;
|
||||
vector<const string*> newbasepaths;
|
||||
vector<const string*> existingpaths;
|
||||
|
||||
dirname = fs::path::dirname(newpath);
|
||||
rv = searchFunc(srcmounts,dirname,minfreespace,existingpath);
|
||||
newdirpath = newpath;
|
||||
fs::path::dirname(newdirpath);
|
||||
newdirpathcstr = newdirpath.c_str();
|
||||
|
||||
rv = searchFunc(srcmounts,newdirpathcstr,minfreespace,existingpaths);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
rv = createFunc(srcmounts,dirname,minfreespace,newpathdirs);
|
||||
rv = createFunc(srcmounts,newdirpathcstr,minfreespace,newbasepaths);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
error = -1;
|
||||
for(size_t i = 0, ei = newpathdirs.size(); i != ei; i++)
|
||||
{
|
||||
string &newpathdir = newpathdirs[i];
|
||||
|
||||
if(newpathdir != existingpath)
|
||||
{
|
||||
const ugid::SetRootGuard ugidGuard;
|
||||
fs::clonepath(existingpath,newpathdir,dirname);
|
||||
}
|
||||
|
||||
fs::path::append(newpathdir,newpath);
|
||||
|
||||
rv = symlink(oldpath.c_str(),newpathdir.c_str());
|
||||
|
||||
error = calc_error(rv,error,errno);
|
||||
}
|
||||
|
||||
return -error;
|
||||
return _symlink_loop(*existingpaths[0],newbasepaths,
|
||||
oldpath,newpath,newdirpathcstr);
|
||||
}
|
||||
|
||||
namespace mergerfs
|
||||
|
|
|
@ -35,33 +35,56 @@ using mergerfs::Policy;
|
|||
|
||||
static
|
||||
int
|
||||
_truncate(Policy::Func::Action actionFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const string &fusepath,
|
||||
const off_t size)
|
||||
_truncate_loop_core(const string *basepath,
|
||||
const char *fusepath,
|
||||
const off_t size,
|
||||
const int error)
|
||||
{
|
||||
int rv;
|
||||
int error;
|
||||
vector<string> paths;
|
||||
string fullpath;
|
||||
|
||||
rv = actionFunc(srcmounts,fusepath,minfreespace,paths);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
fs::path::make(basepath,fusepath,fullpath);
|
||||
|
||||
rv = ::truncate(fullpath.c_str(),size);
|
||||
|
||||
return calc_error(rv,error,errno);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_truncate_loop(const vector<const string*> &basepaths,
|
||||
const char *fusepath,
|
||||
const off_t size)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = -1;
|
||||
for(size_t i = 0, ei = paths.size(); i != ei; i++)
|
||||
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
|
||||
{
|
||||
fs::path::append(paths[i],fusepath);
|
||||
|
||||
rv = ::truncate(paths[i].c_str(),size);
|
||||
|
||||
error = calc_error(rv,error,errno);
|
||||
error = _truncate_loop_core(basepaths[0],fusepath,size,error);
|
||||
}
|
||||
|
||||
return -error;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_truncate(Policy::Func::Action actionFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const char *fusepath,
|
||||
const off_t size)
|
||||
{
|
||||
int rv;
|
||||
vector<const string*> basepaths;
|
||||
|
||||
rv = actionFunc(srcmounts,fusepath,minfreespace,basepaths);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
return _truncate_loop(basepaths,fusepath,size);
|
||||
}
|
||||
|
||||
namespace mergerfs
|
||||
{
|
||||
namespace fuse
|
||||
|
|
|
@ -34,32 +34,53 @@ using mergerfs::Policy;
|
|||
|
||||
static
|
||||
int
|
||||
_unlink(Policy::Func::Action actionFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const string &fusepath)
|
||||
_unlink_loop_core(const string *basepath,
|
||||
const char *fusepath,
|
||||
const int error)
|
||||
{
|
||||
int rv;
|
||||
int error;
|
||||
vector<string> paths;
|
||||
string fullpath;
|
||||
|
||||
rv = actionFunc(srcmounts,fusepath,minfreespace,paths);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
fs::path::make(basepath,fusepath,fullpath);
|
||||
|
||||
rv = ::unlink(fullpath.c_str());
|
||||
|
||||
return calc_error(rv,error,errno);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_unlink_loop(const vector<const string*> &basepaths,
|
||||
const char *fusepath)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = -1;
|
||||
for(size_t i = 0, ei = paths.size(); i != ei; i++)
|
||||
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
|
||||
{
|
||||
fs::path::append(paths[i],fusepath);
|
||||
|
||||
rv = ::unlink(paths[i].c_str());
|
||||
|
||||
error = calc_error(rv,error,errno);
|
||||
error = _unlink_loop_core(basepaths[i],fusepath,error);
|
||||
}
|
||||
|
||||
return -error;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_unlink(Policy::Func::Action actionFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const char *fusepath)
|
||||
{
|
||||
int rv;
|
||||
vector<const string*> basepaths;
|
||||
|
||||
rv = actionFunc(srcmounts,fusepath,minfreespace,basepaths);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
return _unlink_loop(basepaths,fusepath);
|
||||
}
|
||||
|
||||
namespace mergerfs
|
||||
{
|
||||
namespace fuse
|
||||
|
|
|
@ -35,33 +35,56 @@ using mergerfs::Policy;
|
|||
|
||||
static
|
||||
int
|
||||
_utimens(Policy::Func::Action actionFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const string &fusepath,
|
||||
const timespec ts[2])
|
||||
_utimens_loop_core(const string *basepath,
|
||||
const char *fusepath,
|
||||
const timespec ts[2],
|
||||
const int error)
|
||||
{
|
||||
int rv;
|
||||
int error;
|
||||
vector<string> paths;
|
||||
string fullpath;
|
||||
|
||||
rv = actionFunc(srcmounts,fusepath,minfreespace,paths);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
fs::path::make(basepath,fusepath,fullpath);
|
||||
|
||||
rv = ::utimensat(0,fullpath.c_str(),ts,AT_SYMLINK_NOFOLLOW);
|
||||
|
||||
return calc_error(rv,error,errno);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_utimens_loop(const vector<const string*> &basepaths,
|
||||
const char *fusepath,
|
||||
const timespec ts[2])
|
||||
{
|
||||
int error;
|
||||
|
||||
error = -1;
|
||||
for(size_t i = 0, ei = paths.size(); i != ei; i++)
|
||||
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
|
||||
{
|
||||
fs::path::append(paths[i],fusepath);
|
||||
|
||||
rv = ::utimensat(0,paths[i].c_str(),ts,AT_SYMLINK_NOFOLLOW);
|
||||
|
||||
error = calc_error(rv,error,errno);
|
||||
error = _utimens_loop_core(basepaths[i],fusepath,ts,error);
|
||||
}
|
||||
|
||||
return -error;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_utimens(Policy::Func::Action actionFunc,
|
||||
const vector<string> &srcmounts,
|
||||
const size_t minfreespace,
|
||||
const char *fusepath,
|
||||
const timespec ts[2])
|
||||
{
|
||||
int rv;
|
||||
vector<const string*> basepaths;
|
||||
|
||||
rv = actionFunc(srcmounts,fusepath,minfreespace,basepaths);
|
||||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
return _utimens_loop(basepaths,fusepath,ts);
|
||||
}
|
||||
|
||||
namespace mergerfs
|
||||
{
|
||||
namespace fuse
|
||||
|
|
Loading…
Reference in New Issue
Block a user