Browse Source

branches: add per branch minfreespace w/ original value as default

example: /mnt/disk0=RW,1G:/mnt/disk1=RW,2G
pull/821/head
Antonio SJ Musumeci 4 years ago
parent
commit
fc3453932a
  1. 518
      src/branch.cpp
  2. 31
      src/branch.hpp
  3. 2
      src/config.cpp
  4. 8
      src/from_string.cpp
  5. 20
      src/fs_findonfs.cpp
  6. 9
      src/fs_movefile.cpp
  7. 2
      src/fs_movefile.hpp
  8. 4
      src/fuse_access.cpp
  9. 4
      src/fuse_chmod.cpp
  10. 4
      src/fuse_chown.cpp
  11. 6
      src/fuse_create.cpp
  12. 4
      src/fuse_getattr.cpp
  13. 4
      src/fuse_getxattr.cpp
  14. 12
      src/fuse_ioctl.cpp
  15. 23
      src/fuse_link.cpp
  16. 4
      src/fuse_listxattr.cpp
  17. 6
      src/fuse_mkdir.cpp
  18. 6
      src/fuse_mknod.cpp
  19. 4
      src/fuse_open.cpp
  20. 9
      src/fuse_readdir.cpp
  21. 18
      src/fuse_readdir_linux.cpp
  22. 1
      src/fuse_readdir_plus.cpp
  23. 23
      src/fuse_readdir_plus_linux.cpp
  24. 28
      src/fuse_readdir_plus_posix.cpp
  25. 24
      src/fuse_readdir_posix.cpp
  26. 4
      src/fuse_readlink.cpp
  27. 4
      src/fuse_removexattr.cpp
  28. 25
      src/fuse_rename.cpp
  29. 4
      src/fuse_rmdir.cpp
  30. 4
      src/fuse_setxattr.cpp
  31. 11
      src/fuse_statfs.cpp
  32. 6
      src/fuse_symlink.cpp
  33. 4
      src/fuse_truncate.cpp
  34. 4
      src/fuse_unlink.cpp
  35. 4
      src/fuse_utimens.cpp
  36. 1
      src/fuse_write.cpp
  37. 1
      src/fuse_write_buf.cpp
  38. 1715
      src/nonstd/optional.hpp
  39. 34
      src/num.cpp
  40. 5
      src/num.hpp
  41. 2
      src/option_parser.cpp
  42. 58
      src/policy.hpp
  43. 24
      src/policy_all.cpp
  44. 5
      src/policy_cache.cpp
  45. 1
      src/policy_cache.hpp
  46. 59
      src/policy_epall.cpp
  47. 59
      src/policy_epff.cpp
  48. 93
      src/policy_eplfs.cpp
  49. 89
      src/policy_eplus.cpp
  50. 89
      src/policy_epmfs.cpp
  51. 81
      src/policy_eppfrd.cpp
  52. 3
      src/policy_eprand.cpp
  53. 1
      src/policy_erofs.cpp
  54. 24
      src/policy_ff.cpp
  55. 1
      src/policy_invalid.cpp
  56. 34
      src/policy_lfs.cpp
  57. 36
      src/policy_lus.cpp
  58. 34
      src/policy_mfs.cpp
  59. 39
      src/policy_msplfs.cpp
  60. 39
      src/policy_msplus.cpp
  61. 39
      src/policy_mspmfs.cpp
  62. 38
      src/policy_msppfrd.cpp
  63. 89
      src/policy_newest.cpp
  64. 32
      src/policy_pfrd.cpp
  65. 3
      src/policy_rand.cpp
  66. 16
      src/rwlock.hpp
  67. 19
      src/str.cpp
  68. 5
      src/str.hpp

518
src/branch.cpp

@ -18,8 +18,11 @@
#include "branch.hpp" #include "branch.hpp"
#include "ef.hpp" #include "ef.hpp"
#include "from_string.hpp"
#include "fs_glob.hpp" #include "fs_glob.hpp"
#include "fs_realpathize.hpp" #include "fs_realpathize.hpp"
#include "nonstd/optional.hpp"
#include "num.hpp"
#include "str.hpp" #include "str.hpp"
#include <string> #include <string>
@ -29,239 +32,381 @@
using std::string; using std::string;
using std::vector; using std::vector;
using nonstd::optional;
bool
Branch::ro(void) const
{
return (mode == Branch::RO);
}
bool
Branch::nc(void) const
Branch::Branch(const uint64_t &default_minfreespace_)
: _default_minfreespace(&default_minfreespace_)
{ {
return (mode == Branch::NC);
} }
bool
Branch::ro_or_nc(void) const
{
return ((mode == Branch::RO) ||
(mode == Branch::NC));
}
static
void
split(const std::string &s_,
std::string *instr_,
std::string *values_)
int
Branch::from_string(const std::string &str_)
{ {
uint64_t offset;
offset = s_.find_first_of('/');
*instr_ = s_.substr(0,offset);
if(offset != std::string::npos)
*values_ = s_.substr(offset);
return -EINVAL;
} }
Branches::Branches()
std::string
Branch::to_string(void) const
{ {
pthread_rwlock_init(&lock,NULL);
}
std::string rv;
static
void
parse(const string &str_,
Branches &branches_)
{
string str;
Branch branch;
vector<string> globbed;
str = str_;
branch.mode = Branch::INVALID;
if(str::endswith(str,"=RO"))
branch.mode = Branch::RO;
ef(str::endswith(str,"=RW"))
branch.mode = Branch::RW;
ef(str::endswith(str,"=NC"))
branch.mode = Branch::NC;
if(branch.mode != Branch::INVALID)
str.resize(str.size() - 3);
else
branch.mode = Branch::RW;
fs::glob(str,&globbed);
fs::realpathize(&globbed);
for(size_t i = 0; i < globbed.size(); i++)
rv = path;
rv += '=';
switch(mode)
{ {
branch.path = globbed[i];
branches_.push_back(branch);
default:
case Branch::Mode::RW:
rv += "RW";
break;
case Branch::Mode::RO:
rv += "RO";
break;
case Branch::Mode::NC:
rv += "NC";
break;
} }
}
static
void
set(Branches &branches_,
const std::string &str_)
{
vector<string> paths;
branches_.clear();
str::split(str_,':',&paths);
for(size_t i = 0; i < paths.size(); i++)
if(_minfreespace.has_value())
{ {
Branches tmp;
parse(paths[i],tmp);
branches_.insert(branches_.end(),
tmp.begin(),
tmp.end());
rv += ',';
rv += num::humanize(_minfreespace.value());
} }
return rv;
} }
static
void void
add_begin(Branches &branches_,
const std::string &str_)
Branch::set_minfreespace(const uint64_t minfreespace_)
{ {
vector<string> paths;
str::split(str_,':',&paths);
for(size_t i = 0; i < paths.size(); i++)
{
Branches tmp;
parse(paths[i],tmp);
branches_.insert(branches_.begin(),
tmp.begin(),
tmp.end());
}
_minfreespace = minfreespace_;
} }
static
void
add_end(Branches &branches_,
const std::string &str_)
uint64_t
Branch::minfreespace(void) const
{ {
vector<string> paths;
str::split(str_,':',&paths);
for(size_t i = 0; i < paths.size(); i++)
{
Branches tmp;
parse(paths[i],tmp);
branches_.insert(branches_.end(),
tmp.begin(),
tmp.end());
}
if(_minfreespace.has_value())
return _minfreespace.value();
return *_default_minfreespace;
} }
static
void
erase_begin(Branches &branches_)
bool
Branch::ro(void) const
{ {
branches_.erase(branches_.begin());
return (mode == Branch::Mode::RO);
} }
static
void
erase_end(Branches &branches_)
bool
Branch::nc(void) const
{ {
branches_.pop_back();
return (mode == Branch::Mode::NC);
} }
static
void
erase_fnmatch(Branches &branches_,
const std::string &str_)
bool
Branch::ro_or_nc(void) const
{ {
vector<string> patterns;
str::split(str_,':',&patterns);
return ((mode == Branch::Mode::RO) ||
(mode == Branch::Mode::NC));
}
for(Branches::iterator i = branches_.begin();
i != branches_.end();)
{
int match = FNM_NOMATCH;
namespace l
{
static
void
split(const std::string &s_,
std::string *instr_,
std::string *values_)
{
uint64_t offset;
offset = s_.find_first_of('/');
*instr_ = s_.substr(0,offset);
if(offset != std::string::npos)
*values_ = s_.substr(offset);
}
}
for(vector<string>::const_iterator pi = patterns.begin();
pi != patterns.end() && match != 0;
++pi)
{
match = ::fnmatch(pi->c_str(),i->path.c_str(),0);
}
Branches::Branches(const uint64_t &default_minfreespace_)
: default_minfreespace(default_minfreespace_)
{
pthread_rwlock_init(&lock,NULL);
}
i = ((match == 0) ? branches_.erase(i) : (i+1));
}
namespace l
{
static
int
parse_mode(const string &str_,
Branch::Mode *mode_)
{
if(str_ == "RW")
*mode_ = Branch::Mode::RW;
ef(str_ == "RO")
*mode_ = Branch::Mode::RO;
ef(str_ == "NC")
*mode_ = Branch::Mode::NC;
else
return -EINVAL;
return 0;
}
static
int
parse_minfreespace(const string &str_,
optional<uint64_t> *minfreespace_)
{
int rv;
uint64_t uint64;
rv = str::from(str_,&uint64);
if(rv < 0)
return rv;
*minfreespace_ = uint64;
return 0;
}
static
int
parse_branch(const string &str_,
string *glob_,
Branch::Mode *mode_,
optional<uint64_t> *minfreespace_)
{
int rv;
string options;
vector<string> v;
str::rsplit1(str_,'=',&v);
switch(v.size())
{
case 1:
*glob_ = v[0];
*mode_ = Branch::Mode::RW;
break;
case 2:
*glob_ = v[0];
options = v[1];
v.clear();
str::split(options,',',&v);
switch(v.size())
{
case 2:
rv = l::parse_minfreespace(v[1],minfreespace_);
if(rv < 0)
return rv;
case 1:
rv = l::parse_mode(v[0],mode_);
if(rv < 0)
return rv;
break;
case 0:
return -EINVAL;
}
break;
default:
return -EINVAL;
}
return 0;
}
static
int
parse(const string &str_,
const uint64_t &default_minfreespace_,
BranchVec *branches_)
{
int rv;
string glob;
vector<string> globbed;
optional<uint64_t> minfreespace;
Branch branch(default_minfreespace_);
rv = l::parse_branch(str_,&glob,&branch.mode,&minfreespace);
if(rv < 0)
return rv;
if(minfreespace.has_value())
branch.set_minfreespace(minfreespace.value());
fs::glob(glob,&globbed);
fs::realpathize(&globbed);
for(size_t i = 0; i < globbed.size(); i++)
{
branch.path = globbed[i];
branches_->push_back(branch);
}
return 0;
}
static
int
set(const std::string &str_,
Branches *branches_)
{
int rv;
vector<string> paths;
BranchVec tmp_branchvec;
str::split(str_,':',&paths);
for(size_t i = 0; i < paths.size(); i++)
{
rv = l::parse(paths[i],branches_->default_minfreespace,&tmp_branchvec);
if(rv < 0)
return rv;
}
branches_->vec.clear();
branches_->vec.insert(branches_->vec.end(),
tmp_branchvec.begin(),
tmp_branchvec.end());
return 0;
}
static
int
add_begin(const std::string &str_,
Branches *branches_)
{
int rv;
vector<string> paths;
BranchVec tmp_branchvec;
str::split(str_,':',&paths);
for(size_t i = 0; i < paths.size(); i++)
{
rv = l::parse(paths[i],branches_->default_minfreespace,&tmp_branchvec);
if(rv < 0)
return rv;
}
branches_->vec.insert(branches_->vec.begin(),
tmp_branchvec.begin(),
tmp_branchvec.end());
return 0;
}
static
int
add_end(const std::string &str_,
Branches *branches_)
{
int rv;
vector<string> paths;
BranchVec tmp_branchvec;
str::split(str_,':',&paths);
for(size_t i = 0; i < paths.size(); i++)
{
rv = l::parse(paths[i],branches_->default_minfreespace,&tmp_branchvec);
if(rv < 0)
return rv;
}
branches_->vec.insert(branches_->vec.end(),
tmp_branchvec.begin(),
tmp_branchvec.end());
return 0;
}
static
int
erase_begin(BranchVec *branches_)
{
branches_->erase(branches_->begin());
return 0;
}
static
int
erase_end(BranchVec *branches_)
{
branches_->pop_back();
return 0;
}
static
int
erase_fnmatch(const std::string &str_,
Branches *branches_)
{
vector<string> patterns;
str::split(str_,':',&patterns);
for(BranchVec::iterator i = branches_->vec.begin();
i != branches_->vec.end();)
{
int match = FNM_NOMATCH;
for(vector<string>::const_iterator pi = patterns.begin();
pi != patterns.end() && match != 0;
++pi)
{
match = ::fnmatch(pi->c_str(),i->path.c_str(),0);
}
i = ((match == 0) ? branches_->vec.erase(i) : (i+1));
}
return 0;
}
} }
int int
Branches::from_string(const std::string &s_) Branches::from_string(const std::string &s_)
{ {
rwlock::WriteGuard guard(&lock);
rwlock::WriteGuard guard(lock);
std::string instr; std::string instr;
std::string values; std::string values;
::split(s_,&instr,&values);
l::split(s_,&instr,&values);
if(instr == "+") if(instr == "+")
::add_end(*this,values);
ef(instr == "+<")
::add_begin(*this,values);
ef(instr == "+>")
::add_end(*this,values);
ef(instr == "-")
::erase_fnmatch(*this,values);
ef(instr == "-<")
::erase_begin(*this);
ef(instr == "->")
::erase_end(*this);
ef(instr == "=")
::set(*this,values);
ef(instr.empty())
::set(*this,values);
else
return -EINVAL;
return 0;
return l::add_end(values,this);
if(instr == "+<")
return l::add_begin(values,this);
if(instr == "+>")
return l::add_end(values,this);
if(instr == "-")
return l::erase_fnmatch(values,this);
if(instr == "-<")
return l::erase_begin(&vec);
if(instr == "->")
return l::erase_end(&vec);
if(instr == "=")
return l::set(values,this);
if(instr.empty())
return l::set(values,this);
return -EINVAL;
} }
string string
Branches::to_string(void) const Branches::to_string(void) const
{ {
rwlock::ReadGuard guard(&lock);
rwlock::ReadGuard guard(lock);
string tmp; string tmp;
for(size_t i = 0; i < size(); i++)
for(size_t i = 0; i < vec.size(); i++)
{ {
const Branch &branch = (*this)[i];
tmp += branch.path;
tmp += '=';
switch(branch.mode)
{
default:
case Branch::RW:
tmp += "RW";
break;
case Branch::RO:
tmp += "RO";
break;
case Branch::NC:
tmp += "NC";
break;
}
const Branch &branch = vec[i];
tmp += branch.to_string();
tmp += ':'; tmp += ':';
} }
@ -274,11 +419,11 @@ Branches::to_string(void) const
void void
Branches::to_paths(vector<string> &vec_) const Branches::to_paths(vector<string> &vec_) const
{ {
rwlock::ReadGuard guard(&lock);
rwlock::ReadGuard guard(lock);
for(size_t i = 0; i < size(); i++)
for(size_t i = 0; i < vec.size(); i++)
{ {
const Branch &branch = (*this)[i];
const Branch &branch = vec[i];
vec_.push_back(branch.path); vec_.push_back(branch.path);
} }
@ -299,12 +444,13 @@ SrcMounts::from_string(const std::string &s_)
std::string std::string
SrcMounts::to_string(void) const SrcMounts::to_string(void) const
{ {
rwlock::ReadGuard guard(&_branches.lock);
rwlock::ReadGuard guard(_branches.lock);
std::string rv; std::string rv;
for(uint64_t i = 0; i < _branches.size(); i++)
for(uint64_t i = 0; i < _branches.vec.size(); i++)
{ {
rv += _branches[i].path;
rv += _branches.vec[i].path;
rv += ':'; rv += ':';
} }

31
src/branch.hpp

@ -20,16 +20,25 @@
#include "rwlock.hpp" #include "rwlock.hpp"
#include "tofrom_string.hpp" #include "tofrom_string.hpp"
#include "nonstd/optional.hpp"
#include <string> #include <string>
#include <vector> #include <vector>
#include <stdint.h>
#include <pthread.h> #include <pthread.h>
class Branch
class Branch : public ToFromString
{ {
public: public:
enum Mode
Branch(const uint64_t &default_minfreespace);
public:
int from_string(const std::string &str);
std::string to_string(void) const;
public:
enum class Mode
{ {
INVALID, INVALID,
RO, RO,
@ -37,18 +46,30 @@ public:
NC NC
}; };
public:
Mode mode; Mode mode;
std::string path; std::string path;
uint64_t minfreespace() const;
public:
void set_minfreespace(const uint64_t minfreespace);
public:
bool ro(void) const; bool ro(void) const;
bool nc(void) const; bool nc(void) const;
bool ro_or_nc(void) const; bool ro_or_nc(void) const;
private:
nonstd::optional<uint64_t> _minfreespace;
const uint64_t *_default_minfreespace;
}; };
class Branches : public std::vector<Branch>, public ToFromString
typedef std::vector<Branch> BranchVec;
class Branches : public ToFromString
{ {
public: public:
Branches();
Branches(const uint64_t &default_minfreespace_);
public: public:
int from_string(const std::string &str); int from_string(const std::string &str);
@ -59,6 +80,8 @@ public:
public: public:
mutable pthread_rwlock_t lock; mutable pthread_rwlock_t lock;
BranchVec vec;
const uint64_t &default_minfreespace;
}; };
class SrcMounts : public ToFromString class SrcMounts : public ToFromString

2
src/config.cpp

@ -67,7 +67,7 @@ Config::Config()
async_read(true), async_read(true),
auto_cache(false), auto_cache(false),
branches(),
branches(minfreespace),
cache_attr(1), cache_attr(1),
cache_entry(1), cache_entry(1),
cache_files(CacheFiles::ENUM::LIBFUSE), cache_files(CacheFiles::ENUM::LIBFUSE),

8
src/from_string.cpp

@ -67,22 +67,22 @@ namespace str
{ {
case 'k': case 'k':
case 'K': case 'K':
tmp *= 1024;
tmp *= 1024ULL;
break; break;
case 'm': case 'm':
case 'M': case 'M':
tmp *= (1024 * 1024);
tmp *= (1024ULL * 1024ULL);
break; break;
case 'g': case 'g':
case 'G': case 'G':
tmp *= (1024 * 1024 * 1024);
tmp *= (1024ULL * 1024ULL * 1024ULL);
break; break;
case 't': case 't':
case 'T': case 'T':
tmp *= (1024ULL * 1024 * 1024 * 1024);
tmp *= (1024ULL * 1024ULL * 1024ULL * 1024ULL);
break; break;
case '\0': case '\0':

20
src/fs_findonfs.cpp

@ -24,10 +24,11 @@
#include <string> #include <string>
namespace fs
namespace l
{ {
static
int int
findonfs(const Branches &branches_,
findonfs(const BranchVec &branches_,
const std::string &fusepath_, const std::string &fusepath_,
const int fd_, const int fd_,
std::string *basepath_) std::string *basepath_)
@ -37,7 +38,6 @@ namespace fs
struct stat st; struct stat st;
std::string fullpath; std::string fullpath;
const Branch *branch; const Branch *branch;
const rwlock::ReadGuard guard(&branches_.lock);
rv = fs::fstat(fd_,&st); rv = fs::fstat(fd_,&st);
if(rv == -1) if(rv == -1)
@ -65,3 +65,17 @@ namespace fs
return (errno=ENOENT,-1); return (errno=ENOENT,-1);
} }
} }
namespace fs
{
int
findonfs(const Branches &branches_,
const std::string &fusepath_,
const int fd_,
std::string *basepath_)
{
rwlock::ReadGuard guard(branches_.lock);
return l::findonfs(branches_.vec,fusepath_,fd_,basepath_);
}
}

9
src/fs_movefile.cpp

@ -49,7 +49,6 @@ namespace l
int int
movefile(Policy::Func::Create createFunc_, movefile(Policy::Func::Create createFunc_,
const Branches &branches_, const Branches &branches_,
const uint64_t minfreepsace_,
const string &fusepath_, const string &fusepath_,
int *origfd_) int *origfd_)
{ {
@ -73,7 +72,7 @@ namespace l
if(rv == -1) if(rv == -1)
return -1; return -1;
rv = createFunc_(branches_,fusepath_,minfreepsace_,&fdout_path);
rv = createFunc_(branches_,fusepath_,&fdout_path);
if(rv == -1) if(rv == -1)
return -1; return -1;
@ -135,22 +134,20 @@ namespace fs
int int
movefile(const Policy *policy_, movefile(const Policy *policy_,
const Branches &basepaths_, const Branches &basepaths_,
const uint64_t minfreepsace_,
const string &fusepath_, const string &fusepath_,
int *origfd_) int *origfd_)
{ {
return l::movefile(policy_,basepaths_,minfreepsace_,fusepath_,origfd_);
return l::movefile(policy_,basepaths_,fusepath_,origfd_);
} }
int int
movefile_as_root(const Policy *policy_, movefile_as_root(const Policy *policy_,
const Branches &basepaths_, const Branches &basepaths_,
const uint64_t minfreepsace_,
const string &fusepath_, const string &fusepath_,
int *origfd_) int *origfd_)
{ {
const ugid::Set ugid(0,0); const ugid::Set ugid(0,0);
return fs::movefile(policy_,basepaths_,minfreepsace_,fusepath_,origfd_);
return fs::movefile(policy_,basepaths_,fusepath_,origfd_);
} }
} }

2
src/fs_movefile.hpp

@ -26,14 +26,12 @@ namespace fs
int int
movefile(const Policy *policy, movefile(const Policy *policy,
const Branches &branches, const Branches &branches,
const uint64_t minfreepsace,
const std::string &fusepath, const std::string &fusepath,
int *origfd); int *origfd);
int int
movefile_as_root(const Policy *policy, movefile_as_root(const Policy *policy,
const Branches &branches, const Branches &branches,
const uint64_t minfreepsace,
const std::string &fusepath, const std::string &fusepath,
int *origfd); int *origfd);
} }

4
src/fuse_access.cpp

@ -32,7 +32,6 @@ namespace l
int int
access(Policy::Func::Search searchFunc, access(Policy::Func::Search searchFunc,
const Branches &branches_, const Branches &branches_,
const uint64_t minfreespace,
const char *fusepath, const char *fusepath,
const int mask) const int mask)
{ {
@ -40,7 +39,7 @@ namespace l
string fullpath; string fullpath;
vector<string> basepaths; vector<string> basepaths;
rv = searchFunc(branches_,fusepath,minfreespace,&basepaths);
rv = searchFunc(branches_,fusepath,&basepaths);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
@ -64,7 +63,6 @@ namespace FUSE
return l::access(config.func.access.policy, return l::access(config.func.access.policy,
config.branches, config.branches,
config.minfreespace,
fusepath, fusepath,
mask); mask);
} }

4
src/fuse_chmod.cpp

@ -71,14 +71,13 @@ namespace l
int int
chmod(Policy::Func::Action actionFunc_, chmod(Policy::Func::Action actionFunc_,
const Branches &branches_, const Branches &branches_,
const uint64_t minfreespace_,
const char *fusepath_, const char *fusepath_,
const mode_t mode_) const mode_t mode_)
{ {
int rv; int rv;
vector<string> basepaths; vector<string> basepaths;
rv = actionFunc_(branches_,fusepath_,minfreespace_,&basepaths);
rv = actionFunc_(branches_,fusepath_,&basepaths);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
@ -98,7 +97,6 @@ namespace FUSE
return l::chmod(config.func.chmod.policy, return l::chmod(config.func.chmod.policy,
config.branches, config.branches,
config.minfreespace,
fusepath_, fusepath_,
mode_); mode_);
} }

4
src/fuse_chown.cpp

@ -71,7 +71,6 @@ namespace l
int int
chown(Policy::Func::Action actionFunc_, chown(Policy::Func::Action actionFunc_,
const Branches &branches_, const Branches &branches_,
const uint64_t minfreespace_,
const char *fusepath_, const char *fusepath_,
const uid_t uid_, const uid_t uid_,
const gid_t gid_) const gid_t gid_)
@ -79,7 +78,7 @@ namespace l
int rv; int rv;
vector<string> basepaths; vector<string> basepaths;
rv = actionFunc_(branches_,fusepath_,minfreespace_,&basepaths);
rv = actionFunc_(branches_,fusepath_,&basepaths);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
@ -100,7 +99,6 @@ namespace FUSE
return l::chown(config.func.chown.policy, return l::chown(config.func.chown.policy,
config.branches, config.branches,
config.minfreespace,
fusepath_, fusepath_,
uid_, uid_,
gid_); gid_);

6
src/fuse_create.cpp

@ -128,7 +128,6 @@ namespace l
create(Policy::Func::Search searchFunc_, create(Policy::Func::Search searchFunc_,
Policy::Func::Create createFunc_, Policy::Func::Create createFunc_,
const Branches &branches_, const Branches &branches_,
const uint64_t minfreespace_,
const char *fusepath_, const char *fusepath_,
const mode_t mode_, const mode_t mode_,
const mode_t umask_, const mode_t umask_,
@ -143,11 +142,11 @@ namespace l
fusedirpath = fs::path::dirname(fusepath_); fusedirpath = fs::path::dirname(fusepath_);
rv = searchFunc_(branches_,fusedirpath,minfreespace_,&existingpaths);
rv = searchFunc_(branches_,fusedirpath,&existingpaths);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
rv = createFunc_(branches_,fusedirpath,minfreespace_,&createpaths);
rv = createFunc_(branches_,fusedirpath,&createpaths);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
@ -183,7 +182,6 @@ namespace FUSE
return l::create(config.func.getattr.policy, return l::create(config.func.getattr.policy,
config.func.create.policy, config.func.create.policy,
config.branches, config.branches,
config.minfreespace,
fusepath_, fusepath_,
mode_, mode_,
fc->umask, fc->umask,

4
src/fuse_getattr.cpp

@ -61,7 +61,6 @@ namespace l
int int
getattr(Policy::Func::Search searchFunc_, getattr(Policy::Func::Search searchFunc_,
const Branches &branches_, const Branches &branches_,
const uint64_t minfreespace_,
const char *fusepath_, const char *fusepath_,
struct stat *st_, struct stat *st_,
const bool symlinkify_, const bool symlinkify_,
@ -71,7 +70,7 @@ namespace l
string fullpath; string fullpath;
vector<string> basepaths; vector<string> basepaths;
rv = searchFunc_(branches_,fusepath_,minfreespace_,&basepaths);
rv = searchFunc_(branches_,fusepath_,&basepaths);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
@ -108,7 +107,6 @@ namespace FUSE
rv = l::getattr(config.func.getattr.policy, rv = l::getattr(config.func.getattr.policy,
config.branches, config.branches,
config.minfreespace,
fusepath_, fusepath_,
st_, st_,
config.symlinkify, config.symlinkify,

4
src/fuse_getxattr.cpp

@ -165,7 +165,6 @@ namespace l
int int
getxattr(Policy::Func::Search searchFunc_, getxattr(Policy::Func::Search searchFunc_,
const Branches &branches_, const Branches &branches_,
const size_t minfreespace_,
const char *fusepath_, const char *fusepath_,
const char *attrname_, const char *attrname_,
char *buf_, char *buf_,
@ -175,7 +174,7 @@ namespace l
string fullpath; string fullpath;
vector<string> basepaths; vector<string> basepaths;
rv = searchFunc_(branches_,fusepath_,minfreespace_,&basepaths);
rv = searchFunc_(branches_,fusepath_,&basepaths);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
@ -222,7 +221,6 @@ namespace FUSE
return l::getxattr(config.func.getxattr.policy, return l::getxattr(config.func.getxattr.policy,
config.branches, config.branches,
config.minfreespace,
fusepath_, fusepath_,
attrname_, attrname_,
buf_, buf_,

12
src/fuse_ioctl.cpp

@ -136,7 +136,6 @@ namespace l
int int
ioctl_dir_base(Policy::Func::Search searchFunc_, ioctl_dir_base(Policy::Func::Search searchFunc_,
const Branches &branches_, const Branches &branches_,
const uint64_t minfreespace_,
const char *fusepath_, const char *fusepath_,
const uint32_t cmd_, const uint32_t cmd_,
void *data_, void *data_,
@ -147,7 +146,7 @@ namespace l
string fullpath; string fullpath;
vector<string> basepaths; vector<string> basepaths;
rv = searchFunc_(branches_,fusepath_,minfreespace_,&basepaths);
rv = searchFunc_(branches_,fusepath_,&basepaths);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
@ -178,7 +177,6 @@ namespace l
return l::ioctl_dir_base(config.func.open.policy, return l::ioctl_dir_base(config.func.open.policy,
config.branches, config.branches,
config.minfreespace,
di->fusepath.c_str(), di->fusepath.c_str(),
cmd_, cmd_,
data_, data_,
@ -257,14 +255,13 @@ namespace l
int int
file_basepath(Policy::Func::Search searchFunc_, file_basepath(Policy::Func::Search searchFunc_,
const Branches &branches_, const Branches &branches_,
const uint64_t minfreespace_,
const char *fusepath_, const char *fusepath_,
void *data_) void *data_)
{ {
int rv; int rv;
vector<string> basepaths; vector<string> basepaths;
rv = searchFunc_(branches_,fusepath_,minfreespace_,&basepaths);
rv = searchFunc_(branches_,fusepath_,&basepaths);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
@ -281,7 +278,6 @@ namespace l
return l::file_basepath(config.func.open.policy, return l::file_basepath(config.func.open.policy,
config.branches, config.branches,
config.minfreespace,
fusepath.c_str(), fusepath.c_str(),
data_); data_);
} }
@ -300,7 +296,6 @@ namespace l
int int
file_fullpath(Policy::Func::Search searchFunc_, file_fullpath(Policy::Func::Search searchFunc_,
const Branches &branches_, const Branches &branches_,
const uint64_t minfreespace_,
const string &fusepath_, const string &fusepath_,
void *data_) void *data_)
{ {
@ -308,7 +303,7 @@ namespace l
string fullpath; string fullpath;
vector<string> basepaths; vector<string> basepaths;
rv = searchFunc_(branches_,fusepath_,minfreespace_,&basepaths);
rv = searchFunc_(branches_,fusepath_,&basepaths);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
@ -327,7 +322,6 @@ namespace l
return l::file_fullpath(config.func.open.policy, return l::file_fullpath(config.func.open.policy,
config.branches, config.branches,
config.minfreespace,
fusepath, fusepath,
data_); data_);
} }

23
src/fuse_link.cpp

@ -83,7 +83,6 @@ namespace l
link_create_path(Policy::Func::Search searchFunc_, link_create_path(Policy::Func::Search searchFunc_,
Policy::Func::Action actionFunc_, Policy::Func::Action actionFunc_,
const Branches &branches_, const Branches &branches_,
const uint64_t minfreespace_,
const char *oldfusepath_, const char *oldfusepath_,
const char *newfusepath_) const char *newfusepath_)
{ {
@ -92,13 +91,13 @@ namespace l
vector<string> oldbasepaths; vector<string> oldbasepaths;
vector<string> newbasepaths; vector<string> newbasepaths;
rv = actionFunc_(branches_,oldfusepath_,minfreespace_,&oldbasepaths);
rv = actionFunc_(branches_,oldfusepath_,&oldbasepaths);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
newfusedirpath = fs::path::dirname(newfusepath_); newfusedirpath = fs::path::dirname(newfusepath_);
rv = searchFunc_(branches_,newfusedirpath,minfreespace_,&newbasepaths);
rv = searchFunc_(branches_,newfusedirpath,&newbasepaths);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
@ -112,7 +111,6 @@ namespace l
clonepath_if_would_create(Policy::Func::Search searchFunc_, clonepath_if_would_create(Policy::Func::Search searchFunc_,
Policy::Func::Create createFunc_, Policy::Func::Create createFunc_,
const Branches &branches_, const Branches &branches_,
const uint64_t minfreespace_,
const string &oldbasepath_, const string &oldbasepath_,
const char *oldfusepath_, const char *oldfusepath_,
const char *newfusepath_) const char *newfusepath_)
@ -123,14 +121,14 @@ namespace l
newfusedirpath = fs::path::dirname(newfusepath_); newfusedirpath = fs::path::dirname(newfusepath_);
rv = createFunc_(branches_,newfusedirpath,minfreespace_,&newbasepath);
rv = createFunc_(branches_,newfusedirpath,&newbasepath);
if(rv == -1) if(rv == -1)
return -1; return -1;
if(oldbasepath_ != newbasepath[0]) if(oldbasepath_ != newbasepath[0])
return (errno=EXDEV,-1); return (errno=EXDEV,-1);
rv = searchFunc_(branches_,newfusedirpath,minfreespace_,&newbasepath);
rv = searchFunc_(branches_,newfusedirpath,&newbasepath);
if(rv == -1) if(rv == -1)
return -1; return -1;
@ -142,7 +140,6 @@ namespace l
link_preserve_path_core(Policy::Func::Search searchFunc_, link_preserve_path_core(Policy::Func::Search searchFunc_,
Policy::Func::Create createFunc_, Policy::Func::Create createFunc_,
const Branches &branches_, const Branches &branches_,
const uint64_t minfreespace_,
const string &oldbasepath_, const string &oldbasepath_,
const char *oldfusepath_, const char *oldfusepath_,
const char *newfusepath_, const char *newfusepath_,
@ -159,7 +156,7 @@ namespace l
if((rv == -1) && (errno == ENOENT)) if((rv == -1) && (errno == ENOENT))
{ {
rv = l::clonepath_if_would_create(searchFunc_,createFunc_, rv = l::clonepath_if_would_create(searchFunc_,createFunc_,
branches_,minfreespace_,
branches_,
oldbasepath_, oldbasepath_,
oldfusepath_,newfusepath_); oldfusepath_,newfusepath_);
if(rv != -1) if(rv != -1)
@ -174,7 +171,6 @@ namespace l
link_preserve_path_loop(Policy::Func::Search searchFunc_, link_preserve_path_loop(Policy::Func::Search searchFunc_,
Policy::Func::Create createFunc_, Policy::Func::Create createFunc_,
const Branches &branches_, const Branches &branches_,
const uint64_t minfreespace_,
const char *oldfusepath_, const char *oldfusepath_,
const char *newfusepath_, const char *newfusepath_,
const vector<string> &oldbasepaths_) const vector<string> &oldbasepaths_)
@ -185,7 +181,7 @@ namespace l
for(size_t i = 0, ei = oldbasepaths_.size(); i != ei; i++) for(size_t i = 0, ei = oldbasepaths_.size(); i != ei; i++)
{ {
error = l::link_preserve_path_core(searchFunc_,createFunc_, error = l::link_preserve_path_core(searchFunc_,createFunc_,
branches_,minfreespace_,
branches_,
oldbasepaths_[i], oldbasepaths_[i],
oldfusepath_,newfusepath_, oldfusepath_,newfusepath_,
error); error);
@ -200,19 +196,18 @@ namespace l
Policy::Func::Action actionFunc_, Policy::Func::Action actionFunc_,
Policy::Func::Create createFunc_, Policy::Func::Create createFunc_,
const Branches &branches_, const Branches &branches_,
const uint64_t minfreespace_,
const char *oldfusepath_, const char *oldfusepath_,
const char *newfusepath_) const char *newfusepath_)
{ {
int rv; int rv;
vector<string> oldbasepaths; vector<string> oldbasepaths;
rv = actionFunc_(branches_,oldfusepath_,minfreespace_,&oldbasepaths);
rv = actionFunc_(branches_,oldfusepath_,&oldbasepaths);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
return l::link_preserve_path_loop(searchFunc_,createFunc_, return l::link_preserve_path_loop(searchFunc_,createFunc_,
branches_,minfreespace_,
branches_,
oldfusepath_,newfusepath_, oldfusepath_,newfusepath_,
oldbasepaths); oldbasepaths);
} }
@ -233,14 +228,12 @@ namespace FUSE
config.func.link.policy, config.func.link.policy,
config.func.create.policy, config.func.create.policy,
config.branches, config.branches,
config.minfreespace,
from_, from_,
to_); to_);
return l::link_create_path(config.func.link.policy, return l::link_create_path(config.func.link.policy,
config.func.create.policy, config.func.create.policy,
config.branches, config.branches,
config.minfreespace,
from_, from_,
to_); to_);
} }

4
src/fuse_listxattr.cpp

@ -59,7 +59,6 @@ namespace l
int int
listxattr(Policy::Func::Search searchFunc_, listxattr(Policy::Func::Search searchFunc_,
const Branches &branches_, const Branches &branches_,
const uint64_t minfreespace_,
const char *fusepath_, const char *fusepath_,
char *list_, char *list_,
const size_t size_) const size_t size_)
@ -68,7 +67,7 @@ namespace l
string fullpath; string fullpath;
vector<string> basepaths; vector<string> basepaths;
rv = searchFunc_(branches_,fusepath_,minfreespace_,&basepaths);
rv = searchFunc_(branches_,fusepath_,&basepaths);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
@ -107,7 +106,6 @@ namespace FUSE
return l::listxattr(config.func.listxattr.policy, return l::listxattr(config.func.listxattr.policy,
config.branches, config.branches,
config.minfreespace,
fusepath_, fusepath_,
list_, list_,
size_); size_);

6
src/fuse_mkdir.cpp

@ -97,7 +97,6 @@ namespace l
mkdir(Policy::Func::Search searchFunc_, mkdir(Policy::Func::Search searchFunc_,
Policy::Func::Create createFunc_, Policy::Func::Create createFunc_,
const Branches &branches_, const Branches &branches_,
const uint64_t minfreespace_,
const char *fusepath_, const char *fusepath_,
const mode_t mode_, const mode_t mode_,
const mode_t umask_) const mode_t umask_)
@ -109,11 +108,11 @@ namespace l
fusedirpath = fs::path::dirname(fusepath_); fusedirpath = fs::path::dirname(fusepath_);
rv = searchFunc_(branches_,fusedirpath,minfreespace_,&existingpaths);
rv = searchFunc_(branches_,fusedirpath,&existingpaths);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
rv = createFunc_(branches_,fusedirpath,minfreespace_,&createpaths);
rv = createFunc_(branches_,fusedirpath,&createpaths);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
@ -139,7 +138,6 @@ namespace FUSE
return l::mkdir(config.func.getattr.policy, return l::mkdir(config.func.getattr.policy,
config.func.mkdir.policy, config.func.mkdir.policy,
config.branches, config.branches,
config.minfreespace,
fusepath_, fusepath_,
mode_, mode_,
fc->umask); fc->umask);

6
src/fuse_mknod.cpp

@ -99,7 +99,6 @@ namespace l
mknod(Policy::Func::Search searchFunc_, mknod(Policy::Func::Search searchFunc_,
Policy::Func::Create createFunc_, Policy::Func::Create createFunc_,
const Branches &branches_, const Branches &branches_,
const uint64_t minfreespace_,
const char *fusepath_, const char *fusepath_,
const mode_t mode_, const mode_t mode_,
const mode_t umask_, const mode_t umask_,
@ -112,11 +111,11 @@ namespace l
fusedirpath = fs::path::dirname(fusepath_); fusedirpath = fs::path::dirname(fusepath_);
rv = searchFunc_(branches_,fusedirpath,minfreespace_,&existingpaths);
rv = searchFunc_(branches_,fusedirpath,&existingpaths);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
rv = createFunc_(branches_,fusedirpath,minfreespace_,&createpaths);
rv = createFunc_(branches_,fusedirpath,&createpaths);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
@ -140,7 +139,6 @@ namespace FUSE
return l::mknod(config.func.getattr.policy, return l::mknod(config.func.getattr.policy,
config.func.mknod.policy, config.func.mknod.policy,
config.branches, config.branches,
config.minfreespace,
fusepath_, fusepath_,
mode_, mode_,
fc->umask, fc->umask,

4
src/fuse_open.cpp

@ -183,7 +183,6 @@ namespace l
open(Policy::Func::Search searchFunc_, open(Policy::Func::Search searchFunc_,
PolicyCache &cache, PolicyCache &cache,
const Branches &branches_, const Branches &branches_,
const uint64_t minfreespace_,
const char *fusepath_, const char *fusepath_,
const int flags_, const int flags_,
const bool link_cow_, const bool link_cow_,
@ -193,7 +192,7 @@ namespace l
int rv; int rv;
string basepath; string basepath;
rv = cache(searchFunc_,branches_,fusepath_,minfreespace_,&basepath);
rv = cache(searchFunc_,branches_,fusepath_,&basepath);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
@ -219,7 +218,6 @@ namespace FUSE
return l::open(config.func.open.policy, return l::open(config.func.open.policy,
config.open_cache, config.open_cache,
config.branches, config.branches,
config.minfreespace,
fusepath_, fusepath_,
ffi_->flags, ffi_->flags,
config.link_cow, config.link_cow,

9
src/fuse_readdir.cpp

@ -32,11 +32,10 @@ namespace FUSE
readdir(fuse_file_info *ffi_, readdir(fuse_file_info *ffi_,
fuse_dirents_t *buf_) fuse_dirents_t *buf_)
{ {
DirInfo *di = reinterpret_cast<DirInfo*>(ffi_->fh);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::ro();
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard guard(&config.branches.lock);
DirInfo *di = reinterpret_cast<DirInfo*>(ffi_->fh);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::ro();
const ugid::Set ugid(fc->uid,fc->gid);
switch(config.readdir) switch(config.readdir)
{ {

18
src/fuse_readdir_linux.cpp

@ -26,6 +26,7 @@
#include "hashset.hpp" #include "hashset.hpp"
#include "linux_dirent64.h" #include "linux_dirent64.h"
#include "mempools.hpp" #include "mempools.hpp"
#include "rwlock.hpp"
#include <fuse.h> #include <fuse.h>
#include <fuse_dirents.h> #include <fuse_dirents.h>
@ -52,9 +53,9 @@ namespace l
static static
int int
readdir(const Branches &branches_,
const char *dirname_,
fuse_dirents_t *buf_)
readdir(const BranchVec &branches_,
const char *dirname_,
fuse_dirents_t *buf_)
{ {
int rv; int rv;
dev_t dev; dev_t dev;
@ -121,6 +122,17 @@ namespace l
return 0; return 0;
} }
static
int
readdir(const Branches &branches_,
const char *dirname_,
fuse_dirents_t *buf_)
{
rwlock::ReadGuard guard(branches_.lock);
return l::readdir(branches_.vec,dirname_,buf_);
}
} }
namespace FUSE namespace FUSE

1
src/fuse_readdir_plus.cpp

@ -36,7 +36,6 @@ namespace FUSE
const fuse_context *fc = fuse_get_context(); const fuse_context *fc = fuse_get_context();
const Config &config = Config::ro(); const Config &config = Config::ro();
const ugid::Set ugid(fc->uid,fc->gid); const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard guard(&config.branches.lock);
switch(config.readdir) switch(config.readdir)
{ {

23
src/fuse_readdir_plus_linux.cpp

@ -53,11 +53,11 @@ namespace l
static static
int int
readdir_plus(const Branches &branches_,
const char *dirname_,
const uint64_t entry_timeout_,
const uint64_t attr_timeout_,
fuse_dirents_t *buf_)
readdir_plus(const BranchVec &branches_,
const char *dirname_,
const uint64_t entry_timeout_,
const uint64_t attr_timeout_,
fuse_dirents_t *buf_)
{ {
int rv; int rv;
dev_t dev; dev_t dev;
@ -136,6 +136,19 @@ namespace l
return 0; return 0;
} }
static
int
readdir_plus(const Branches &branches_,
const char *dirname_,
const uint64_t entry_timeout_,
const uint64_t attr_timeout_,
fuse_dirents_t *buf_)
{
rwlock::ReadGuard guard(branches_.lock);
return l::readdir_plus(branches_.vec,dirname_,entry_timeout_,attr_timeout_,buf_);
}
} }
namespace FUSE namespace FUSE

28
src/fuse_readdir_plus_posix.cpp

@ -28,6 +28,7 @@
#include "fs_readdir.hpp" #include "fs_readdir.hpp"
#include "fs_stat.hpp" #include "fs_stat.hpp"
#include "hashset.hpp" #include "hashset.hpp"
#include "rwlock.hpp"
#include <fuse.h> #include <fuse.h>
#include <fuse_dirents.h> #include <fuse_dirents.h>
@ -57,11 +58,11 @@ namespace l
static static
int int
readdir_plus(const Branches &branches_,
const char *dirname_,
const uint64_t entry_timeout_,
const uint64_t attr_timeout_,
fuse_dirents_t *buf_)
readdir_plus(const BranchVec &branches_,
const char *dirname_,
const uint64_t entry_timeout_,
const uint64_t attr_timeout_,
fuse_dirents_t *buf_)
{ {
dev_t dev; dev_t dev;
HashSet names; HashSet names;
@ -126,6 +127,23 @@ namespace l
return 0; return 0;
} }
static
int
readdir_plus(const Branches &branches_,
const char *dirname_,
const uint64_t entry_timeout_,
const uint64_t attr_timeout_,
fuse_dirents_t *buf_)
{
rwlock::ReadGuard guard(branches_.lock);
return l::readdir_plus(branches_.vec,
dirname_,
entry_timeout_,
attr_timeout_,
buf_);
}
} }
namespace FUSE namespace FUSE

24
src/fuse_readdir_posix.cpp

@ -19,14 +19,15 @@
#include "branch.hpp" #include "branch.hpp"
#include "errno.hpp" #include "errno.hpp"
#include "fs_closedir.hpp" #include "fs_closedir.hpp"
#include "fs_devid.hpp"
#include "fs_dirfd.hpp" #include "fs_dirfd.hpp"
#include "fs_inode.hpp"
#include "fs_opendir.hpp" #include "fs_opendir.hpp"
#include "fs_path.hpp"
#include "fs_readdir.hpp" #include "fs_readdir.hpp"
#include "fs_stat.hpp" #include "fs_stat.hpp"
#include "fs_devid.hpp"
#include "fs_inode.hpp"
#include "fs_path.hpp"
#include "hashset.hpp" #include "hashset.hpp"
#include "rwlock.hpp"
#include <fuse.h> #include <fuse.h>
#include <fuse_dirents.h> #include <fuse_dirents.h>
@ -56,9 +57,9 @@ namespace l
static static
int int
readdir(const Branches &branches_,
const char *dirname_,
fuse_dirents_t *buf_)
readdir(const BranchVec &branches_,
const char *dirname_,
fuse_dirents_t *buf_)
{ {
dev_t dev; dev_t dev;
HashSet names; HashSet names;
@ -109,6 +110,17 @@ namespace l
return 0; return 0;
} }
static
int
readdir(const Branches &branches_,
const char *dirname_,
fuse_dirents_t *buf_)
{
rwlock::ReadGuard guard(branches_.lock);
return l::readdir(branches_.vec,dirname_,buf_);
}
} }
namespace FUSE namespace FUSE

4
src/fuse_readlink.cpp

@ -94,7 +94,6 @@ namespace l
int int
readlink(Policy::Func::Search searchFunc_, readlink(Policy::Func::Search searchFunc_,
const Branches &branches_, const Branches &branches_,
const uint64_t minfreespace_,
const char *fusepath_, const char *fusepath_,
char *buf_, char *buf_,
const size_t size_, const size_t size_,
@ -104,7 +103,7 @@ namespace l
int rv; int rv;
vector<string> basepaths; vector<string> basepaths;
rv = searchFunc_(branches_,fusepath_,minfreespace_,&basepaths);
rv = searchFunc_(branches_,fusepath_,&basepaths);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
@ -126,7 +125,6 @@ namespace FUSE
return l::readlink(config.func.readlink.policy, return l::readlink(config.func.readlink.policy,
config.branches, config.branches,
config.minfreespace,
fusepath_, fusepath_,
buf_, buf_,
size_, size_,

4
src/fuse_removexattr.cpp

@ -70,14 +70,13 @@ namespace l
int int
removexattr(Policy::Func::Action actionFunc_, removexattr(Policy::Func::Action actionFunc_,
const Branches &branches_, const Branches &branches_,
const uint64_t minfreespace_,
const char *fusepath_, const char *fusepath_,
const char *attrname_) const char *attrname_)
{ {
int rv; int rv;
vector<string> basepaths; vector<string> basepaths;
rv = actionFunc_(branches_,fusepath_,minfreespace_,&basepaths);
rv = actionFunc_(branches_,fusepath_,&basepaths);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
@ -103,7 +102,6 @@ namespace FUSE
return l::removexattr(config.func.removexattr.policy, return l::removexattr(config.func.removexattr.policy,
config.branches, config.branches,
config.minfreespace,
fusepath_, fusepath_,
attrname_); attrname_);
} }

25
src/fuse_rename.cpp

@ -99,7 +99,6 @@ int
_rename_create_path(Policy::Func::Search searchFunc, _rename_create_path(Policy::Func::Search searchFunc,
Policy::Func::Action actionFunc, Policy::Func::Action actionFunc,
const Branches &branches_, const Branches &branches_,
const uint64_t minfreespace,
const char *oldfusepath, const char *oldfusepath,
const char *newfusepath) const char *newfusepath)
{ {
@ -111,13 +110,13 @@ _rename_create_path(Policy::Func::Search searchFunc,
vector<string> oldbasepaths; vector<string> oldbasepaths;
vector<string> branches; vector<string> branches;
rv = actionFunc(branches_,oldfusepath,minfreespace,&oldbasepaths);
rv = actionFunc(branches_,oldfusepath,&oldbasepaths);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
newfusedirpath = fs::path::dirname(newfusepath); newfusedirpath = fs::path::dirname(newfusepath);
rv = searchFunc(branches_,newfusedirpath,minfreespace,&newbasepath);
rv = searchFunc(branches_,newfusedirpath,&newbasepath);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
@ -146,14 +145,13 @@ static
int int
_clonepath(Policy::Func::Search searchFunc, _clonepath(Policy::Func::Search searchFunc,
const Branches &branches_, const Branches &branches_,
const uint64_t minfreespace,
const string &dstbasepath, const string &dstbasepath,
const string &fusedirpath) const string &fusedirpath)
{ {
int rv; int rv;
vector<string> srcbasepath; vector<string> srcbasepath;
rv = searchFunc(branches_,fusedirpath,minfreespace,&srcbasepath);
rv = searchFunc(branches_,fusedirpath,&srcbasepath);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
@ -167,7 +165,6 @@ int
_clonepath_if_would_create(Policy::Func::Search searchFunc, _clonepath_if_would_create(Policy::Func::Search searchFunc,
Policy::Func::Create createFunc, Policy::Func::Create createFunc,
const Branches &branches_, const Branches &branches_,
const uint64_t minfreespace,
const string &oldbasepath, const string &oldbasepath,
const char *oldfusepath, const char *oldfusepath,
const char *newfusepath) const char *newfusepath)
@ -178,12 +175,12 @@ _clonepath_if_would_create(Policy::Func::Search searchFunc,
newfusedirpath = fs::path::dirname(newfusepath); newfusedirpath = fs::path::dirname(newfusepath);
rv = createFunc(branches_,newfusedirpath,minfreespace,&newbasepath);
rv = createFunc(branches_,newfusedirpath,&newbasepath);
if(rv == -1) if(rv == -1)
return rv; return rv;
if(oldbasepath == newbasepath[0]) if(oldbasepath == newbasepath[0])
return _clonepath(searchFunc,branches_,minfreespace,oldbasepath,newfusedirpath);
return _clonepath(searchFunc,branches_,oldbasepath,newfusedirpath);
return (errno=EXDEV,-1); return (errno=EXDEV,-1);
} }
@ -193,7 +190,6 @@ void
_rename_preserve_path_core(Policy::Func::Search searchFunc, _rename_preserve_path_core(Policy::Func::Search searchFunc,
Policy::Func::Create createFunc, Policy::Func::Create createFunc,
const Branches &branches_, const Branches &branches_,
const uint64_t minfreespace,
const vector<string> &oldbasepaths, const vector<string> &oldbasepaths,
const string &oldbasepath, const string &oldbasepath,
const char *oldfusepath, const char *oldfusepath,
@ -218,8 +214,8 @@ _rename_preserve_path_core(Policy::Func::Search searchFunc,
if((rv == -1) && (errno == ENOENT)) if((rv == -1) && (errno == ENOENT))
{ {
rv = _clonepath_if_would_create(searchFunc,createFunc, rv = _clonepath_if_would_create(searchFunc,createFunc,
branches_,minfreespace,
oldbasepath,oldfusepath,newfusepath);
branches_,oldbasepath,
oldfusepath,newfusepath);
if(rv == 0) if(rv == 0)
rv = fs::rename(oldfullpath,newfullpath); rv = fs::rename(oldfullpath,newfullpath);
} }
@ -240,7 +236,6 @@ _rename_preserve_path(Policy::Func::Search searchFunc,
Policy::Func::Action actionFunc, Policy::Func::Action actionFunc,
Policy::Func::Create createFunc, Policy::Func::Create createFunc,
const Branches &branches_, const Branches &branches_,
const uint64_t minfreespace,
const char *oldfusepath, const char *oldfusepath,
const char *newfusepath) const char *newfusepath)
{ {
@ -250,7 +245,7 @@ _rename_preserve_path(Policy::Func::Search searchFunc,
vector<string> oldbasepaths; vector<string> oldbasepaths;
vector<string> branches; vector<string> branches;
rv = actionFunc(branches_,oldfusepath,minfreespace,&oldbasepaths);
rv = actionFunc(branches_,oldfusepath,&oldbasepaths);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
@ -262,7 +257,7 @@ _rename_preserve_path(Policy::Func::Search searchFunc,
const string &oldbasepath = branches[i]; const string &oldbasepath = branches[i];
_rename_preserve_path_core(searchFunc,createFunc, _rename_preserve_path_core(searchFunc,createFunc,
branches_,minfreespace,
branches_,
oldbasepaths,oldbasepath, oldbasepaths,oldbasepath,
oldfusepath,newfusepath, oldfusepath,newfusepath,
error,toremove); error,toremove);
@ -291,14 +286,12 @@ namespace FUSE
config.func.rename.policy, config.func.rename.policy,
config.func.create.policy, config.func.create.policy,
config.branches, config.branches,
config.minfreespace,
oldpath, oldpath,
newpath); newpath);
return _rename_create_path(config.func.getattr.policy, return _rename_create_path(config.func.getattr.policy,
config.func.rename.policy, config.func.rename.policy,
config.branches, config.branches,
config.minfreespace,
oldpath, oldpath,
newpath); newpath);
} }

4
src/fuse_rmdir.cpp

@ -69,13 +69,12 @@ namespace l
int int
rmdir(Policy::Func::Action actionFunc_, rmdir(Policy::Func::Action actionFunc_,
const Branches &branches_, const Branches &branches_,
const uint64_t minfreespace_,
const char *fusepath_) const char *fusepath_)
{ {
int rv; int rv;
vector<string> basepaths; vector<string> basepaths;
rv = actionFunc_(branches_,fusepath_,minfreespace_,&basepaths);
rv = actionFunc_(branches_,fusepath_,&basepaths);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
@ -94,7 +93,6 @@ namespace FUSE
return l::rmdir(config.func.rmdir.policy, return l::rmdir(config.func.rmdir.policy,
config.branches, config.branches,
config.minfreespace,
fusepath_); fusepath_);
} }
} }

4
src/fuse_setxattr.cpp

@ -124,7 +124,6 @@ namespace l
int int
setxattr(Policy::Func::Action actionFunc, setxattr(Policy::Func::Action actionFunc,
const Branches &branches_, const Branches &branches_,
const uint64_t minfreespace,
const char *fusepath, const char *fusepath,
const char *attrname, const char *attrname,
const char *attrval, const char *attrval,
@ -134,7 +133,7 @@ namespace l
int rv; int rv;
vector<string> basepaths; vector<string> basepaths;
rv = actionFunc(branches_,fusepath,minfreespace,&basepaths);
rv = actionFunc(branches_,fusepath,&basepaths);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
@ -171,7 +170,6 @@ namespace FUSE
return l::setxattr(config.func.setxattr.policy, return l::setxattr(config.func.setxattr.policy,
config.branches, config.branches,
config.minfreespace,
fusepath, fusepath,
attrname, attrname,
attrval, attrval,

11
src/fuse_statfs.cpp

@ -19,6 +19,7 @@
#include "fs_lstat.hpp" #include "fs_lstat.hpp"
#include "fs_path.hpp" #include "fs_path.hpp"
#include "fs_statvfs.hpp" #include "fs_statvfs.hpp"
#include "rwlock.hpp"
#include "statvfs_util.hpp" #include "statvfs_util.hpp"
#include "ugid.hpp" #include "ugid.hpp"
@ -84,6 +85,8 @@ namespace l
const StatFSIgnore ignore_, const StatFSIgnore ignore_,
struct statvfs *fsstat_) struct statvfs *fsstat_)
{ {
rwlock::ReadGuard guard(branches_.lock);
int rv; int rv;
string fullpath; string fullpath;
struct stat st; struct stat st;
@ -96,11 +99,11 @@ namespace l
min_bsize = std::numeric_limits<unsigned long>::max(); min_bsize = std::numeric_limits<unsigned long>::max();
min_frsize = std::numeric_limits<unsigned long>::max(); min_frsize = std::numeric_limits<unsigned long>::max();
min_namemax = std::numeric_limits<unsigned long>::max(); min_namemax = std::numeric_limits<unsigned long>::max();
for(size_t i = 0, ei = branches_.size(); i < ei; i++)
for(size_t i = 0, ei = branches_.vec.size(); i < ei; i++)
{ {
fullpath = ((mode_ == StatFS::ENUM::FULL) ? fullpath = ((mode_ == StatFS::ENUM::FULL) ?
fs::path::make(branches_[i].path,fusepath_) :
branches_[i].path);
fs::path::make(branches_.vec[i].path,fusepath_) :
branches_.vec[i].path);
rv = fs::lstat(fullpath,&st); rv = fs::lstat(fullpath,&st);
if(rv == -1) if(rv == -1)
@ -117,7 +120,7 @@ namespace l
if(stvfs.f_namemax && (min_namemax > stvfs.f_namemax)) if(stvfs.f_namemax && (min_namemax > stvfs.f_namemax))
min_namemax = stvfs.f_namemax; min_namemax = stvfs.f_namemax;
if(l::should_ignore(ignore_,&branches_[i],StatVFS::readonly(stvfs)))
if(l::should_ignore(ignore_,&branches_.vec[i],StatVFS::readonly(stvfs)))
{ {
stvfs.f_bavail = 0; stvfs.f_bavail = 0;
stvfs.f_favail = 0; stvfs.f_favail = 0;

6
src/fuse_symlink.cpp

@ -83,7 +83,6 @@ namespace l
symlink(Policy::Func::Search searchFunc_, symlink(Policy::Func::Search searchFunc_,
Policy::Func::Create createFunc_, Policy::Func::Create createFunc_,
const Branches &branches_, const Branches &branches_,
const uint64_t minfreespace_,
const char *oldpath_, const char *oldpath_,
const char *newpath_) const char *newpath_)
{ {
@ -94,11 +93,11 @@ namespace l
newdirpath = fs::path::dirname(newpath_); newdirpath = fs::path::dirname(newpath_);
rv = searchFunc_(branches_,newdirpath,minfreespace_,&existingpaths);
rv = searchFunc_(branches_,newdirpath,&existingpaths);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
rv = createFunc_(branches_,newdirpath,minfreespace_,&newbasepaths);
rv = createFunc_(branches_,newdirpath,&newbasepaths);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
@ -120,7 +119,6 @@ namespace FUSE
return l::symlink(config.func.getattr.policy, return l::symlink(config.func.getattr.policy,
config.func.symlink.policy, config.func.symlink.policy,
config.branches, config.branches,
config.minfreespace,
oldpath_, oldpath_,
newpath_); newpath_);
} }

4
src/fuse_truncate.cpp

@ -72,14 +72,13 @@ namespace l
int int
truncate(Policy::Func::Action actionFunc_, truncate(Policy::Func::Action actionFunc_,
const Branches &branches_, const Branches &branches_,
const uint64_t minfreespace_,
const char *fusepath_, const char *fusepath_,
const off_t size_) const off_t size_)
{ {
int rv; int rv;
vector<string> basepaths; vector<string> basepaths;
rv = actionFunc_(branches_,fusepath_,minfreespace_,&basepaths);
rv = actionFunc_(branches_,fusepath_,&basepaths);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
@ -99,7 +98,6 @@ namespace FUSE
return l::truncate(config.func.truncate.policy, return l::truncate(config.func.truncate.policy,
config.branches, config.branches,
config.minfreespace,
fusepath_, fusepath_,
size_); size_);
} }

4
src/fuse_unlink.cpp

@ -69,13 +69,12 @@ namespace l
int int
unlink(Policy::Func::Action actionFunc_, unlink(Policy::Func::Action actionFunc_,
const Branches &branches_, const Branches &branches_,
const uint64_t minfreespace_,
const char *fusepath_) const char *fusepath_)
{ {
int rv; int rv;
vector<string> basepaths; vector<string> basepaths;
rv = actionFunc_(branches_,fusepath_,minfreespace_,&basepaths);
rv = actionFunc_(branches_,fusepath_,&basepaths);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
@ -96,7 +95,6 @@ namespace FUSE
return l::unlink(config.func.unlink.policy, return l::unlink(config.func.unlink.policy,
config.branches, config.branches,
config.minfreespace,
fusepath_); fusepath_);
} }
} }

4
src/fuse_utimens.cpp

@ -71,14 +71,13 @@ namespace l
int int
utimens(Policy::Func::Action actionFunc_, utimens(Policy::Func::Action actionFunc_,
const Branches &branches_, const Branches &branches_,
const uint64_t minfreespace_,
const char *fusepath_, const char *fusepath_,
const timespec ts_[2]) const timespec ts_[2])
{ {
int rv; int rv;
vector<string> basepaths; vector<string> basepaths;
rv = actionFunc_(branches_,fusepath_,minfreespace_,&basepaths);
rv = actionFunc_(branches_,fusepath_,&basepaths);
if(rv == -1) if(rv == -1)
return -errno; return -errno;
@ -98,7 +97,6 @@ namespace FUSE
return l::utimens(config.func.utimens.policy, return l::utimens(config.func.utimens.policy,
config.branches, config.branches,
config.minfreespace,
fusepath_, fusepath_,
ts_); ts_);
} }

1
src/fuse_write.cpp

@ -92,7 +92,6 @@ namespace l
rv = fs::movefile_as_root(config.moveonenospc.policy, rv = fs::movefile_as_root(config.moveonenospc.policy,
config.branches, config.branches,
config.minfreespace,
fi_->fusepath, fi_->fusepath,
&fi_->fd); &fi_->fd);
if(rv == -1) if(rv == -1)

1
src/fuse_write_buf.cpp

@ -74,7 +74,6 @@ namespace l
rv = fs::movefile_as_root(config.moveonenospc.policy, rv = fs::movefile_as_root(config.moveonenospc.policy,
config.branches, config.branches,
config.minfreespace,
fi_->fusepath, fi_->fusepath,
&fi_->fd); &fi_->fd);
if(rv == -1) if(rv == -1)

1715
src/nonstd/optional.hpp
File diff suppressed because it is too large
View File

34
src/num.cpp

@ -14,11 +14,19 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "ef.hpp"
#include <string>
#include <stdint.h> #include <stdint.h>
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <time.h> #include <time.h>
#include <string>
#define KB (1024UL)
#define MB (KB * 1024UL)
#define GB (MB * 1024UL)
#define TB (GB * 1024UL)
namespace num namespace num
{ {
@ -98,3 +106,27 @@ namespace num
return 0; return 0;
} }
} }
namespace num
{
std::string
humanize(const uint64_t bytes_)
{
char buf[64];
if(bytes_ < KB)
sprintf(buf,"%lu",bytes_);
ef(((bytes_ / TB) * TB) == bytes_)
sprintf(buf,"%luT",bytes_ / TB);
ef(((bytes_ / GB) * GB) == bytes_)
sprintf(buf,"%luG",bytes_ / GB);
ef(((bytes_ / MB) * MB) == bytes_)
sprintf(buf,"%luM",bytes_ / MB);
ef(((bytes_ / KB) * KB) == bytes_)
sprintf(buf,"%luK",bytes_ / KB);
else
sprintf(buf,"%lu",bytes_);
return std::string(buf);
}
}

5
src/num.hpp

@ -26,3 +26,8 @@ namespace num
int to_double(const std::string &str, double *value); int to_double(const std::string &str, double *value);
int to_time_t(const std::string &str, time_t *value); int to_time_t(const std::string &str, time_t *value);
} }
namespace num
{
std::string humanize(const uint64_t bytes);
}

2
src/option_parser.cpp

@ -419,7 +419,7 @@ option_processor(void *data_,
return process_opt(data,arg_); return process_opt(data,arg_);
case FUSE_OPT_KEY_NONOPT: case FUSE_OPT_KEY_NONOPT:
if(data->config->branches.empty())
if(data->config->branches.vec.empty())
return process_branches(data,arg_); return process_branches(data,arg_);
else else
return process_mount(data,arg_); return process_mount(data,arg_);

58
src/policy.hpp

@ -66,7 +66,7 @@ public:
typedef const uint64_t cuint64_t; typedef const uint64_t cuint64_t;
typedef const strvec cstrvec; typedef const strvec cstrvec;
typedef int (*Ptr)(Category,const Branches &,const char *,cuint64_t,strvec *);
typedef int (*Ptr)(Category,const Branches&,const char*,strvec *);
template <Category T> template <Category T>
class Base class Base
@ -81,26 +81,26 @@ public:
{} {}
int int
operator()(const Branches &b,const char *c,cuint64_t d,strvec *e)
operator()(const Branches &a,const char *b,strvec *c)
{ {
return func(T,b,c,d,e);
return func(T,a,b,c);
} }
int int
operator()(const Branches &b,const string &c,cuint64_t d,strvec *e)
operator()(const Branches &a,const string &b,strvec *c)
{ {
return func(T,b,c.c_str(),d,e);
return func(T,a,b.c_str(),c);
} }
int int
operator()(const Branches &b,const char *c,cuint64_t d,string *e)
operator()(const Branches &a,const char *b,string *c)
{ {
int rv; int rv;
strvec v; strvec v;
rv = func(T,b,c,d,&v);
rv = func(T,a,b,&v);
if(!v.empty()) if(!v.empty())
*e = v[0];
*c = v[0];
return rv; return rv;
} }
@ -113,27 +113,27 @@ public:
typedef Base<Category::CREATE> Create; typedef Base<Category::CREATE> Create;
typedef Base<Category::SEARCH> Search; typedef Base<Category::SEARCH> Search;
static int invalid(Category,const Branches&,const char *,cuint64_t,strvec*);
static int all(Category,const Branches&,const char*,cuint64_t,strvec*);
static int epall(Category,const Branches&,const char*,cuint64_t,strvec*);
static int epff(Category,const Branches&,const char *,cuint64_t,strvec*);
static int eplfs(Category,const Branches&,const char *,cuint64_t,strvec*);
static int eplus(Category,const Branches&,const char *,cuint64_t,strvec*);
static int epmfs(Category,const Branches&,const char *,cuint64_t,strvec*);
static int eppfrd(Category,const Branches&,const char *,cuint64_t,strvec*);
static int eprand(Category,const Branches&,const char *,cuint64_t,strvec*);
static int erofs(Category,const Branches&,const char *,cuint64_t,strvec*);
static int ff(Category,const Branches&,const char *,cuint64_t,strvec*);
static int lfs(Category,const Branches&,const char *,cuint64_t,strvec*);
static int lus(Category,const Branches&,const char *,cuint64_t,strvec*);
static int mfs(Category,const Branches&,const char *,cuint64_t,strvec*);
static int msplfs(Category,const Branches&,const char *,cuint64_t,strvec*);
static int msplus(Category,const Branches&,const char *,cuint64_t,strvec*);
static int mspmfs(Category,const Branches&,const char *,cuint64_t,strvec*);
static int msppfrd(Category,const Branches&,const char *,cuint64_t,strvec*);
static int newest(Category,const Branches&,const char *,cuint64_t,strvec*);
static int pfrd(Category,const Branches&,const char *,cuint64_t,strvec*);
static int rand(Category,const Branches&,const char *,cuint64_t,strvec*);
static int invalid(Category,const Branches&,const char *,strvec*);
static int all(Category,const Branches&,const char*,strvec*);
static int epall(Category,const Branches&,const char*,strvec*);
static int epff(Category,const Branches&,const char *,strvec*);
static int eplfs(Category,const Branches&,const char *,strvec*);
static int eplus(Category,const Branches&,const char *,strvec*);
static int epmfs(Category,const Branches&,const char *,strvec*);
static int eppfrd(Category,const Branches&,const char *,strvec*);
static int eprand(Category,const Branches&,const char *,strvec*);
static int erofs(Category,const Branches&,const char *,strvec*);
static int ff(Category,const Branches&,const char *,strvec*);
static int lfs(Category,const Branches&,const char *,strvec*);
static int lus(Category,const Branches&,const char *,strvec*);
static int mfs(Category,const Branches&,const char *,strvec*);
static int msplfs(Category,const Branches&,const char *,strvec*);
static int msplus(Category,const Branches&,const char *,strvec*);
static int mspmfs(Category,const Branches&,const char *,strvec*);
static int msppfrd(Category,const Branches&,const char *,strvec*);
static int newest(Category,const Branches&,const char *,strvec*);
static int pfrd(Category,const Branches&,const char *,strvec*);
static int rand(Category,const Branches&,const char *,strvec*);
}; };
private: private:

24
src/policy_all.cpp

@ -32,12 +32,9 @@ namespace all
{ {
static static
int int
create(const Branches &branches_,
const uint64_t minfreespace_,
vector<string> *paths_)
create(const BranchVec &branches_,
vector<string> *paths_)
{ {
rwlock::ReadGuard guard(&branches_.lock);
int rv; int rv;
int error; int error;
fs::info_t info; fs::info_t info;
@ -55,7 +52,7 @@ namespace all
error_and_continue(error,ENOENT); error_and_continue(error,ENOENT);
if(info.readonly) if(info.readonly)
error_and_continue(error,EROFS); error_and_continue(error,EROFS);
if(info.spaceavail < minfreespace_)
if(info.spaceavail < branch->minfreespace())
error_and_continue(error,ENOSPC); error_and_continue(error,ENOSPC);
paths_->push_back(branch->path); paths_->push_back(branch->path);
@ -66,17 +63,26 @@ namespace all
return 0; return 0;
} }
static
int
create(const Branches &branches_,
vector<string> *paths_)
{
rwlock::ReadGuard guard(branches_.lock);
return all::create(branches_.vec,paths_);
}
} }
int int
Policy::Func::all(const Category type_, Policy::Func::all(const Category type_,
const Branches &branches_, const Branches &branches_,
const char *fusepath_, const char *fusepath_,
const uint64_t minfreespace_,
vector<string> *paths_) vector<string> *paths_)
{ {
if(type_ == Category::CREATE) if(type_ == Category::CREATE)
return all::create(branches_,minfreespace_,paths_);
return all::create(branches_,paths_);
return Policy::Func::epall(type_,branches_,fusepath_,minfreespace_,paths_);
return Policy::Func::epall(type_,branches_,fusepath_,paths_);
} }

5
src/policy_cache.cpp

@ -94,7 +94,6 @@ int
PolicyCache::operator()(Policy::Func::Search &func_, PolicyCache::operator()(Policy::Func::Search &func_,
const Branches &branches_, const Branches &branches_,
const char *fusepath_, const char *fusepath_,
const uint64_t minfreespace_,
std::string *branch_) std::string *branch_)
{ {
int rv; int rv;
@ -103,7 +102,7 @@ PolicyCache::operator()(Policy::Func::Search &func_,
string branch; string branch;
if(timeout == 0) if(timeout == 0)
return func_(branches_,fusepath_,minfreespace_,branch_);
return func_(branches_,fusepath_,branch_);
now = l::get_time(); now = l::get_time();
@ -113,7 +112,7 @@ PolicyCache::operator()(Policy::Func::Search &func_,
if((now - v->time) >= timeout) if((now - v->time) >= timeout)
{ {
pthread_mutex_unlock(&_lock); pthread_mutex_unlock(&_lock);
rv = func_(branches_,fusepath_,minfreespace_,&branch);
rv = func_(branches_,fusepath_,&branch);
if(rv == -1) if(rv == -1)
return -1; return -1;

1
src/policy_cache.hpp

@ -49,7 +49,6 @@ public:
int operator()(Policy::Func::Search &func, int operator()(Policy::Func::Search &func,
const Branches &branches, const Branches &branches,
const char *fusepath, const char *fusepath,
const uint64_t minfreespace,
std::string *branch); std::string *branch);
public: public:

59
src/policy_epall.cpp

@ -33,13 +33,10 @@ namespace epall
{ {
static static
int int
create(const Branches &branches_,
const char *fusepath_,
const uint64_t minfreespace_,
vector<string> *paths_)
create(const BranchVec &branches_,
const char *fusepath_,
vector<string> *paths_)
{ {
rwlock::ReadGuard guard(&branches_.lock);
int rv; int rv;
int error; int error;
fs::info_t info; fs::info_t info;
@ -50,16 +47,16 @@ namespace epall
{ {
branch = &branches_[i]; branch = &branches_[i];
if(!fs::exists(branch->path,fusepath_))
error_and_continue(error,ENOENT);
if(branch->ro_or_nc()) if(branch->ro_or_nc())
error_and_continue(error,EROFS); error_and_continue(error,EROFS);
if(!fs::exists(branch->path,fusepath_))
error_and_continue(error,ENOENT);
rv = fs::info(branch->path,&info); rv = fs::info(branch->path,&info);
if(rv == -1) if(rv == -1)
error_and_continue(error,ENOENT); error_and_continue(error,ENOENT);
if(info.readonly) if(info.readonly)
error_and_continue(error,EROFS); error_and_continue(error,EROFS);
if(info.spaceavail < minfreespace_)
if(info.spaceavail < branch->minfreespace())
error_and_continue(error,ENOSPC); error_and_continue(error,ENOSPC);
paths_->push_back(branch->path); paths_->push_back(branch->path);
@ -73,12 +70,21 @@ namespace epall
static static
int int
action(const Branches &branches_,
create(const Branches &branches_,
const char *fusepath_, const char *fusepath_,
vector<string> *paths_) vector<string> *paths_)
{ {
rwlock::ReadGuard guard(&branches_.lock);
rwlock::ReadGuard guard(branches_.lock);
return epall::create(branches_.vec,fusepath_,paths_);
}
static
int
action(const BranchVec &branches_,
const char *fusepath_,
vector<string> *paths_)
{
int rv; int rv;
int error; int error;
bool readonly; bool readonly;
@ -89,10 +95,10 @@ namespace epall
{ {
branch = &branches_[i]; branch = &branches_[i];
if(!fs::exists(branch->path,fusepath_))
error_and_continue(error,ENOENT);
if(branch->ro()) if(branch->ro())
error_and_continue(error,EROFS); error_and_continue(error,EROFS);
if(!fs::exists(branch->path,fusepath_))
error_and_continue(error,ENOENT);
rv = fs::statvfs_cache_readonly(branch->path,&readonly); rv = fs::statvfs_cache_readonly(branch->path,&readonly);
if(rv == -1) if(rv == -1)
error_and_continue(error,ENOENT); error_and_continue(error,ENOENT);
@ -110,12 +116,21 @@ namespace epall
static static
int int
search(const Branches &branches_,
action(const Branches &branches_,
const char *fusepath_, const char *fusepath_,
vector<string> *paths_) vector<string> *paths_)
{ {
rwlock::ReadGuard guard(&branches_.lock);
rwlock::ReadGuard guard(branches_.lock);
return epall::action(branches_.vec,fusepath_,paths_);
}
static
int
search(const BranchVec &branches_,
const char *fusepath_,
vector<string> *paths_)
{
const Branch *branch; const Branch *branch;
for(size_t i = 0, ei = branches_.size(); i != ei; i++) for(size_t i = 0, ei = branches_.size(); i != ei; i++)
@ -133,19 +148,29 @@ namespace epall
return 0; return 0;
} }
static
int
search(const Branches &branches_,
const char *fusepath_,
vector<string> *paths_)
{
rwlock::ReadGuard guard(branches_.lock);
return epall::search(branches_.vec,fusepath_,paths_);
}
} }
int int
Policy::Func::epall(const Category type_, Policy::Func::epall(const Category type_,
const Branches &branches_, const Branches &branches_,
const char *fusepath_, const char *fusepath_,
const uint64_t minfreespace_,
vector<string> *paths_) vector<string> *paths_)
{ {
switch(type_) switch(type_)
{ {
case Category::CREATE: case Category::CREATE:
return epall::create(branches_,fusepath_,minfreespace_,paths_);
return epall::create(branches_,fusepath_,paths_);
case Category::ACTION: case Category::ACTION:
return epall::action(branches_,fusepath_,paths_); return epall::action(branches_,fusepath_,paths_);
case Category::SEARCH: case Category::SEARCH:

59
src/policy_epff.cpp

@ -33,13 +33,10 @@ namespace epff
{ {
static static
int int
create(const Branches &branches_,
const char *fusepath_,
const uint64_t minfreespace_,
vector<string> *paths_)
create(const BranchVec &branches_,
const char *fusepath_,
vector<string> *paths_)
{ {
rwlock::ReadGuard guard(&branches_.lock);
int rv; int rv;
int error; int error;
fs::info_t info; fs::info_t info;
@ -50,16 +47,16 @@ namespace epff
{ {
branch = &branches_[i]; branch = &branches_[i];
if(!fs::exists(branch->path,fusepath_))
error_and_continue(error,ENOENT);
if(branch->ro_or_nc()) if(branch->ro_or_nc())
error_and_continue(error,EROFS); error_and_continue(error,EROFS);
if(!fs::exists(branch->path,fusepath_))
error_and_continue(error,ENOENT);
rv = fs::info(branch->path,&info); rv = fs::info(branch->path,&info);
if(rv == -1) if(rv == -1)
error_and_continue(error,ENOENT); error_and_continue(error,ENOENT);
if(info.readonly) if(info.readonly)
error_and_continue(error,EROFS); error_and_continue(error,EROFS);
if(info.spaceavail < minfreespace_)
if(info.spaceavail < branch->minfreespace())
error_and_continue(error,ENOSPC); error_and_continue(error,ENOSPC);
paths_->push_back(branch->path); paths_->push_back(branch->path);
@ -72,12 +69,21 @@ namespace epff
static static
int int
action(const Branches &branches_,
create(const Branches &branches_,
const char *fusepath_, const char *fusepath_,
vector<string> *paths_) vector<string> *paths_)
{ {
rwlock::ReadGuard guard(&branches_.lock);
rwlock::ReadGuard guard(branches_.lock);
return epff::create(branches_.vec,fusepath_,paths_);
}
static
int
action(const BranchVec &branches_,
const char *fusepath_,
vector<string> *paths_)
{
int rv; int rv;
int error; int error;
bool readonly; bool readonly;
@ -88,10 +94,10 @@ namespace epff
{ {
branch = &branches_[i]; branch = &branches_[i];
if(!fs::exists(branch->path,fusepath_))
error_and_continue(error,ENOENT);
if(branch->ro()) if(branch->ro())
error_and_continue(error,EROFS); error_and_continue(error,EROFS);
if(!fs::exists(branch->path,fusepath_))
error_and_continue(error,ENOENT);
rv = fs::statvfs_cache_readonly(branch->path,&readonly); rv = fs::statvfs_cache_readonly(branch->path,&readonly);
if(rv == -1) if(rv == -1)
error_and_continue(error,ENOENT); error_and_continue(error,ENOENT);
@ -108,12 +114,21 @@ namespace epff
static static
int int
search(const Branches &branches_,
action(const Branches &branches_,
const char *fusepath_, const char *fusepath_,
vector<string> *paths_) vector<string> *paths_)
{ {
rwlock::ReadGuard guard(&branches_.lock);
rwlock::ReadGuard guard(branches_.lock);
return epff::action(branches_.vec,fusepath_,paths_);
}
static
int
search(const BranchVec &branches_,
const char *fusepath_,
vector<string> *paths_)
{
const Branch *branch; const Branch *branch;
for(size_t i = 0, ei = branches_.size(); i != ei; i++) for(size_t i = 0, ei = branches_.size(); i != ei; i++)
@ -130,19 +145,29 @@ namespace epff
return (errno=ENOENT,-1); return (errno=ENOENT,-1);
} }
static
int
search(const Branches &branches_,
const char *fusepath_,
vector<string> *paths_)
{
rwlock::ReadGuard guard(branches_.lock);
return epff::search(branches_.vec,fusepath_,paths_);
}
} }
int int
Policy::Func::epff(const Category type_, Policy::Func::epff(const Category type_,
const Branches &branches_, const Branches &branches_,
const char *fusepath_, const char *fusepath_,
const uint64_t minfreespace_,
vector<string> *paths_) vector<string> *paths_)
{ {
switch(type_) switch(type_)
{ {
case Category::CREATE: case Category::CREATE:
return epff::create(branches_,fusepath_,minfreespace_,paths_);
return epff::create(branches_,fusepath_,paths_);
case Category::ACTION: case Category::ACTION:
return epff::action(branches_,fusepath_,paths_); return epff::action(branches_,fusepath_,paths_);
case Category::SEARCH: case Category::SEARCH:

93
src/policy_eplfs.cpp

@ -34,79 +34,85 @@ namespace eplfs
{ {
static static
int int
create(const Branches &branches_,
const char *fusepath_,
const uint64_t minfreespace_,
vector<string> *paths_)
create(const BranchVec &branches_,
const char *fusepath_,
vector<string> *paths_)
{ {
rwlock::ReadGuard guard(&branches_.lock);
int rv; int rv;
int error; int error;
uint64_t eplfs; uint64_t eplfs;
fs::info_t info; fs::info_t info;
const Branch *branch; const Branch *branch;
const string *eplfsbasepath;
const string *basepath;
error = ENOENT; error = ENOENT;
eplfs = std::numeric_limits<uint64_t>::max(); eplfs = std::numeric_limits<uint64_t>::max();
eplfsbasepath = NULL;
basepath = NULL;
for(size_t i = 0, ei = branches_.size(); i != ei; i++) for(size_t i = 0, ei = branches_.size(); i != ei; i++)
{ {
branch = &branches_[i]; branch = &branches_[i];
if(!fs::exists(branch->path,fusepath_))
error_and_continue(error,ENOENT);
if(branch->ro_or_nc()) if(branch->ro_or_nc())
error_and_continue(error,EROFS); error_and_continue(error,EROFS);
if(!fs::exists(branch->path,fusepath_))
error_and_continue(error,ENOENT);
rv = fs::info(branch->path,&info); rv = fs::info(branch->path,&info);
if(rv == -1) if(rv == -1)
error_and_continue(error,ENOENT); error_and_continue(error,ENOENT);
if(info.readonly) if(info.readonly)
error_and_continue(error,EROFS); error_and_continue(error,EROFS);
if(info.spaceavail < minfreespace_)
if(info.spaceavail < branch->minfreespace())
error_and_continue(error,ENOSPC); error_and_continue(error,ENOSPC);
if(info.spaceavail > eplfs) if(info.spaceavail > eplfs)
continue; continue;
eplfs = info.spaceavail; eplfs = info.spaceavail;
eplfsbasepath = &branch->path;
basepath = &branch->path;
} }
if(eplfsbasepath == NULL)
if(basepath == NULL)
return (errno=error,-1); return (errno=error,-1);
paths_->push_back(*eplfsbasepath);
paths_->push_back(*basepath);
return 0; return 0;
} }
static static
int int
action(const Branches &branches_,
create(const Branches &branches_,
const char *fusepath_, const char *fusepath_,
vector<string> *paths_) vector<string> *paths_)
{ {
rwlock::ReadGuard guard(&branches_.lock);
rwlock::ReadGuard guard(branches_.lock);
return eplfs::create(branches_.vec,fusepath_,paths_);
}
static
int
action(const BranchVec &branches_,
const char *fusepath_,
vector<string> *paths_)
{
int rv; int rv;
int error; int error;
uint64_t eplfs; uint64_t eplfs;
fs::info_t info; fs::info_t info;
const Branch *branch; const Branch *branch;
const string *eplfsbasepath;
const string *basepath;
error = ENOENT; error = ENOENT;
eplfs = std::numeric_limits<uint64_t>::max(); eplfs = std::numeric_limits<uint64_t>::max();
eplfsbasepath = NULL;
basepath = NULL;
for(size_t i = 0, ei = branches_.size(); i != ei; i++) for(size_t i = 0, ei = branches_.size(); i != ei; i++)
{ {
branch = &branches_[i]; branch = &branches_[i];
if(!fs::exists(branch->path,fusepath_))
error_and_continue(error,ENOENT);
if(branch->ro()) if(branch->ro())
error_and_continue(error,EROFS); error_and_continue(error,EROFS);
if(!fs::exists(branch->path,fusepath_))
error_and_continue(error,ENOENT);
rv = fs::info(branch->path,&info); rv = fs::info(branch->path,&info);
if(rv == -1) if(rv == -1)
error_and_continue(error,ENOENT); error_and_continue(error,ENOENT);
@ -116,33 +122,42 @@ namespace eplfs
continue; continue;
eplfs = info.spaceavail; eplfs = info.spaceavail;
eplfsbasepath = &branch->path;
basepath = &branch->path;
} }
if(eplfsbasepath == NULL)
if(basepath == NULL)
return (errno=error,-1); return (errno=error,-1);
paths_->push_back(*eplfsbasepath);
paths_->push_back(*basepath);
return 0; return 0;
} }
static static
int int
search(const Branches &branches_,
const char *fusepath_,
vector<string> *paths_)
action(const Branches &branches_,
const char *fusepath_,
vector<string> *paths_)
{ {
rwlock::ReadGuard guard(&branches_.lock);
rwlock::ReadGuard guard(branches_.lock);
return eplfs::action(branches_.vec,fusepath_,paths_);
}
static
int
search(const BranchVec &branches_,
const char *fusepath_,
vector<string> *paths_)
{
int rv; int rv;
uint64_t eplfs; uint64_t eplfs;
uint64_t spaceavail; uint64_t spaceavail;
const Branch *branch; const Branch *branch;
const string *eplfsbasepath;
const string *basepath;
eplfs = std::numeric_limits<uint64_t>::max(); eplfs = std::numeric_limits<uint64_t>::max();
eplfsbasepath = NULL;
basepath = NULL;
for(size_t i = 0, ei = branches_.size(); i != ei; i++) for(size_t i = 0, ei = branches_.size(); i != ei; i++)
{ {
branch = &branches_[i]; branch = &branches_[i];
@ -156,29 +171,39 @@ namespace eplfs
continue; continue;
eplfs = spaceavail; eplfs = spaceavail;
eplfsbasepath = &branch->path;
basepath = &branch->path;
} }
if(eplfsbasepath == NULL)
if(basepath == NULL)
return (errno=ENOENT,-1); return (errno=ENOENT,-1);
paths_->push_back(*eplfsbasepath);
paths_->push_back(*basepath);
return 0; return 0;
} }
static
int
search(const Branches &branches_,
const char *fusepath_,
vector<string> *paths_)
{
rwlock::ReadGuard guard(branches_.lock);
return eplfs::search(branches_.vec,fusepath_,paths_);
}
} }
int int
Policy::Func::eplfs(const Category type_, Policy::Func::eplfs(const Category type_,
const Branches &branches_, const Branches &branches_,
const char *fusepath_, const char *fusepath_,
const uint64_t minfreespace_,
vector<string> *paths_) vector<string> *paths_)
{ {
switch(type_) switch(type_)
{ {
case Category::CREATE: case Category::CREATE:
return eplfs::create(branches_,fusepath_,minfreespace_,paths_);
return eplfs::create(branches_,fusepath_,paths_);
case Category::ACTION: case Category::ACTION:
return eplfs::action(branches_,fusepath_,paths_); return eplfs::action(branches_,fusepath_,paths_);
case Category::SEARCH: case Category::SEARCH:

89
src/policy_eplus.cpp

@ -34,79 +34,85 @@ namespace eplus
{ {
static static
int int
create(const Branches &branches_,
const char *fusepath_,
const uint64_t minfreespace_,
vector<string> *paths_)
create(const BranchVec &branches_,
const char *fusepath_,
vector<string> *paths_)
{ {
rwlock::ReadGuard guard(&branches_.lock);
int rv; int rv;
int error; int error;
uint64_t eplus; uint64_t eplus;
fs::info_t info; fs::info_t info;
const Branch *branch; const Branch *branch;
const string *eplusbasepath;
const string *basepath;
error = ENOENT; error = ENOENT;
eplus = std::numeric_limits<uint64_t>::max(); eplus = std::numeric_limits<uint64_t>::max();
eplusbasepath = NULL;
basepath = NULL;
for(size_t i = 0, ei = branches_.size(); i != ei; i++) for(size_t i = 0, ei = branches_.size(); i != ei; i++)
{ {
branch = &branches_[i]; branch = &branches_[i];
if(!fs::exists(branch->path,fusepath_))
error_and_continue(error,ENOENT);
if(branch->ro_or_nc()) if(branch->ro_or_nc())
error_and_continue(error,EROFS); error_and_continue(error,EROFS);
if(!fs::exists(branch->path,fusepath_))
error_and_continue(error,ENOENT);
rv = fs::info(branch->path,&info); rv = fs::info(branch->path,&info);
if(rv == -1) if(rv == -1)
error_and_continue(error,ENOENT); error_and_continue(error,ENOENT);
if(info.readonly) if(info.readonly)
error_and_continue(error,EROFS); error_and_continue(error,EROFS);
if(info.spaceavail < minfreespace_)
if(info.spaceavail < branch->minfreespace())
error_and_continue(error,ENOSPC); error_and_continue(error,ENOSPC);
if(info.spaceused >= eplus) if(info.spaceused >= eplus)
continue; continue;
eplus = info.spaceused; eplus = info.spaceused;
eplusbasepath = &branch->path;
basepath = &branch->path;
} }
if(eplusbasepath == NULL)
if(basepath == NULL)
return (errno=error,-1); return (errno=error,-1);
paths_->push_back(*eplusbasepath);
paths_->push_back(*basepath);
return 0; return 0;
} }
static static
int int
action(const Branches &branches_,
create(const Branches &branches_,
const char *fusepath_, const char *fusepath_,
vector<string> *paths_) vector<string> *paths_)
{ {
rwlock::ReadGuard guard(&branches_.lock);
rwlock::ReadGuard guard(branches_.lock);
return eplus::create(branches_.vec,fusepath_,paths_);
}
static
int
action(const BranchVec &branches_,
const char *fusepath_,
vector<string> *paths_)
{
int rv; int rv;
int error; int error;
uint64_t eplus; uint64_t eplus;
fs::info_t info; fs::info_t info;
const Branch *branch; const Branch *branch;
const string *eplusbasepath;
const string *basepath;
error = ENOENT; error = ENOENT;
eplus = std::numeric_limits<uint64_t>::max(); eplus = std::numeric_limits<uint64_t>::max();
eplusbasepath = NULL;
basepath = NULL;
for(size_t i = 0, ei = branches_.size(); i != ei; i++) for(size_t i = 0, ei = branches_.size(); i != ei; i++)
{ {
branch = &branches_[i]; branch = &branches_[i];
if(!fs::exists(branch->path,fusepath_))
error_and_continue(error,ENOENT);
if(branch->ro()) if(branch->ro())
error_and_continue(error,EROFS); error_and_continue(error,EROFS);
if(!fs::exists(branch->path,fusepath_))
error_and_continue(error,ENOENT);
rv = fs::info(branch->path,&info); rv = fs::info(branch->path,&info);
if(rv == -1) if(rv == -1)
error_and_continue(error,ENOENT); error_and_continue(error,ENOENT);
@ -116,33 +122,42 @@ namespace eplus
continue; continue;
eplus = info.spaceused; eplus = info.spaceused;
eplusbasepath = &branch->path;
basepath = &branch->path;
} }
if(eplusbasepath == NULL)
if(basepath == NULL)
return (errno=error,-1); return (errno=error,-1);
paths_->push_back(*eplusbasepath);
paths_->push_back(*basepath);
return 0; return 0;
} }
static static
int int
search(const Branches &branches_,
action(const Branches &branches_,
const char *fusepath_, const char *fusepath_,
vector<string> *paths_) vector<string> *paths_)
{ {
rwlock::ReadGuard guard(&branches_.lock);
rwlock::ReadGuard guard(branches_.lock);
return eplus::action(branches_.vec,fusepath_,paths_);
}
static
int
search(const BranchVec &branches_,
const char *fusepath_,
vector<string> *paths_)
{
int rv; int rv;
uint64_t eplus; uint64_t eplus;
uint64_t spaceused; uint64_t spaceused;
const Branch *branch; const Branch *branch;
const string *eplusbasepath;
const string *basepath;
eplus = 0; eplus = 0;
eplusbasepath = NULL;
basepath = NULL;
for(size_t i = 0, ei = branches_.size(); i != ei; i++) for(size_t i = 0, ei = branches_.size(); i != ei; i++)
{ {
branch = &branches_[i]; branch = &branches_[i];
@ -156,29 +171,39 @@ namespace eplus
continue; continue;
eplus = spaceused; eplus = spaceused;
eplusbasepath = &branch->path;
basepath = &branch->path;
} }
if(eplusbasepath == NULL)
if(basepath == NULL)
return (errno=ENOENT,-1); return (errno=ENOENT,-1);
paths_->push_back(*eplusbasepath);
paths_->push_back(*basepath);
return 0; return 0;
} }
static
int
search(const Branches &branches_,
const char *fusepath_,
vector<string> *paths_)
{
rwlock::ReadGuard guard(branches_.lock);
return eplus::search(branches_.vec,fusepath_,paths_);
}
} }
int int
Policy::Func::eplus(const Category type_, Policy::Func::eplus(const Category type_,
const Branches &branches_, const Branches &branches_,
const char *fusepath_, const char *fusepath_,
const uint64_t minfreespace_,
vector<string> *paths_) vector<string> *paths_)
{ {
switch(type_) switch(type_)
{ {
case Category::CREATE: case Category::CREATE:
return eplus::create(branches_,fusepath_,minfreespace_,paths_);
return eplus::create(branches_,fusepath_,paths_);
case Category::ACTION: case Category::ACTION:
return eplus::action(branches_,fusepath_,paths_); return eplus::action(branches_,fusepath_,paths_);
case Category::SEARCH: case Category::SEARCH:

89
src/policy_epmfs.cpp

@ -34,79 +34,85 @@ namespace epmfs
{ {
static static
int int
create(const Branches &branches_,
const char *fusepath_,
const uint64_t minfreespace_,
vector<string> *paths_)
create(const BranchVec &branches_,
const char *fusepath_,
vector<string> *paths_)
{ {
rwlock::ReadGuard guard(&branches_.lock);
int rv; int rv;
int error; int error;
uint64_t epmfs; uint64_t epmfs;
fs::info_t info; fs::info_t info;
const Branch *branch; const Branch *branch;
const string *epmfsbasepath;
const string *basepath;
error = ENOENT; error = ENOENT;
epmfs = std::numeric_limits<uint64_t>::min(); epmfs = std::numeric_limits<uint64_t>::min();
epmfsbasepath = NULL;
basepath = NULL;
for(size_t i = 0, ei = branches_.size(); i != ei; i++) for(size_t i = 0, ei = branches_.size(); i != ei; i++)
{ {
branch = &branches_[i]; branch = &branches_[i];
if(!fs::exists(branch->path,fusepath_))
error_and_continue(error,ENOENT);
if(branch->ro_or_nc()) if(branch->ro_or_nc())
error_and_continue(error,EROFS); error_and_continue(error,EROFS);
if(!fs::exists(branch->path,fusepath_))
error_and_continue(error,ENOENT);
rv = fs::info(branch->path,&info); rv = fs::info(branch->path,&info);
if(rv == -1) if(rv == -1)
error_and_continue(error,ENOENT); error_and_continue(error,ENOENT);
if(info.readonly) if(info.readonly)
error_and_continue(error,EROFS); error_and_continue(error,EROFS);
if(info.spaceavail < minfreespace_)
if(info.spaceavail < branch->minfreespace())
error_and_continue(error,ENOSPC); error_and_continue(error,ENOSPC);
if(info.spaceavail < epmfs) if(info.spaceavail < epmfs)
continue; continue;
epmfs = info.spaceavail; epmfs = info.spaceavail;
epmfsbasepath = &branch->path;
basepath = &branch->path;
} }
if(epmfsbasepath == NULL)
if(basepath == NULL)
return (errno=error,-1); return (errno=error,-1);
paths_->push_back(*epmfsbasepath);
paths_->push_back(*basepath);
return 0; return 0;
} }
static static
int int
action(const Branches &branches_,
create(const Branches &branches_,
const char *fusepath_, const char *fusepath_,
vector<string> *paths_) vector<string> *paths_)
{ {
rwlock::ReadGuard guard(&branches_.lock);
rwlock::ReadGuard guard(branches_.lock);
return epmfs::create(branches_.vec,fusepath_,paths_);
}
static
int
action(const BranchVec &branches_,
const char *fusepath_,
vector<string> *paths_)
{
int rv; int rv;
int error; int error;
uint64_t epmfs; uint64_t epmfs;
fs::info_t info; fs::info_t info;
const Branch *branch; const Branch *branch;
const string *epmfsbasepath;
const string *basepath;
error = ENOENT; error = ENOENT;
epmfs = std::numeric_limits<uint64_t>::min(); epmfs = std::numeric_limits<uint64_t>::min();
epmfsbasepath = NULL;
basepath = NULL;
for(size_t i = 0, ei = branches_.size(); i != ei; i++) for(size_t i = 0, ei = branches_.size(); i != ei; i++)
{ {
branch = &branches_[i]; branch = &branches_[i];
if(!fs::exists(branch->path,fusepath_))
error_and_continue(error,ENOENT);
if(branch->ro()) if(branch->ro())
error_and_continue(error,EROFS); error_and_continue(error,EROFS);
if(!fs::exists(branch->path,fusepath_))
error_and_continue(error,ENOENT);
rv = fs::info(branch->path,&info); rv = fs::info(branch->path,&info);
if(rv == -1) if(rv == -1)
error_and_continue(error,ENOENT); error_and_continue(error,ENOENT);
@ -116,33 +122,42 @@ namespace epmfs
continue; continue;
epmfs = info.spaceavail; epmfs = info.spaceavail;
epmfsbasepath = &branch->path;
basepath = &branch->path;
} }
if(epmfsbasepath == NULL)
if(basepath == NULL)
return (errno=error,-1); return (errno=error,-1);
paths_->push_back(*epmfsbasepath);
paths_->push_back(*basepath);
return 0; return 0;
} }
static static
int int
search(const Branches &branches_,
action(const Branches &branches_,
const char *fusepath_, const char *fusepath_,
vector<string> *paths_) vector<string> *paths_)
{ {
rwlock::ReadGuard guard(&branches_.lock);
rwlock::ReadGuard guard(branches_.lock);
return epmfs::action(branches_.vec,fusepath_,paths_);
}
static
int
search(const BranchVec &branches_,
const char *fusepath_,
vector<string> *paths_)
{
int rv; int rv;
uint64_t epmfs; uint64_t epmfs;
uint64_t spaceavail; uint64_t spaceavail;
const Branch *branch; const Branch *branch;
const string *epmfsbasepath;
const string *basepath;
epmfs = 0; epmfs = 0;
epmfsbasepath = NULL;
basepath = NULL;
for(size_t i = 0, ei = branches_.size(); i != ei; i++) for(size_t i = 0, ei = branches_.size(); i != ei; i++)
{ {
branch = &branches_[i]; branch = &branches_[i];
@ -156,29 +171,39 @@ namespace epmfs
continue; continue;
epmfs = spaceavail; epmfs = spaceavail;
epmfsbasepath = &branch->path;
basepath = &branch->path;
} }
if(epmfsbasepath == NULL)
if(basepath == NULL)
return (errno=ENOENT,-1); return (errno=ENOENT,-1);
paths_->push_back(*epmfsbasepath);
paths_->push_back(*basepath);
return 0; return 0;
} }
static
int
search(const Branches &branches_,
const char *fusepath_,
vector<string> *paths_)
{
rwlock::ReadGuard guard(branches_.lock);
return epmfs::search(branches_.vec,fusepath_,paths_);
}
} }
int int
Policy::Func::epmfs(const Category type_, Policy::Func::epmfs(const Category type_,
const Branches &branches_, const Branches &branches_,
const char *fusepath_, const char *fusepath_,
const uint64_t minfreespace_,
vector<string> *paths_) vector<string> *paths_)
{ {
switch(type_) switch(type_)
{ {
case Category::CREATE: case Category::CREATE:
return epmfs::create(branches_,fusepath_,minfreespace_,paths_);
return epmfs::create(branches_,fusepath_,paths_);
case Category::ACTION: case Category::ACTION:
return epmfs::action(branches_,fusepath_,paths_); return epmfs::action(branches_,fusepath_,paths_);
case Category::SEARCH: case Category::SEARCH:

81
src/policy_eppfrd.cpp

@ -42,18 +42,16 @@ namespace eppfrd
{ {
static static
int int
get_branchinfo_create(const Branches &branches_,
const char *fusepath_,
const uint64_t minfreespace_,
BranchInfoVec *branchinfo_,
uint64_t *sum_)
get_branchinfo_create(const BranchVec &branches_,
const char *fusepath_,
BranchInfoVec *branchinfo_,
uint64_t *sum_)
{ {
int rv; int rv;
int error; int error;
BranchInfo bi; BranchInfo bi;
fs::info_t info; fs::info_t info;
const Branch *branch; const Branch *branch;
rwlock::ReadGuard guard(&branches_.lock);
*sum_ = 0; *sum_ = 0;
error = ENOENT; error = ENOENT;
@ -70,7 +68,7 @@ namespace eppfrd
error_and_continue(error,ENOENT); error_and_continue(error,ENOENT);
if(info.readonly) if(info.readonly)
error_and_continue(error,EROFS); error_and_continue(error,EROFS);
if(info.spaceavail < minfreespace_)
if(info.spaceavail < branch->minfreespace())
error_and_continue(error,ENOSPC); error_and_continue(error,ENOSPC);
*sum_ += info.spaceavail; *sum_ += info.spaceavail;
@ -85,18 +83,30 @@ namespace eppfrd
static static
int int
get_branchinfo_action(const Branches &branches_,
get_branchinfo_create(const Branches &branches_,
const char *fusepath_, const char *fusepath_,
const uint64_t minfreespace_,
BranchInfoVec *branchinfo_, BranchInfoVec *branchinfo_,
uint64_t *sum_) uint64_t *sum_)
{
rwlock::ReadGuard guard(branches_.lock);
branchinfo_->reserve(branches_.vec.size());
return eppfrd::get_branchinfo_create(branches_.vec,fusepath_,branchinfo_,sum_);
}
static
int
get_branchinfo_action(const BranchVec &branches_,
const char *fusepath_,
BranchInfoVec *branchinfo_,
uint64_t *sum_)
{ {
int rv; int rv;
int error; int error;
BranchInfo bi; BranchInfo bi;
fs::info_t info; fs::info_t info;
const Branch *branch; const Branch *branch;
rwlock::ReadGuard guard(&branches_.lock);
*sum_ = 0; *sum_ = 0;
error = ENOENT; error = ENOENT;
@ -126,17 +136,29 @@ namespace eppfrd
static static
int int
get_branchinfo_search(const Branches &branches_,
get_branchinfo_action(const Branches &branches_,
const char *fusepath_, const char *fusepath_,
const uint64_t minfreespace_,
BranchInfoVec *branchinfo_, BranchInfoVec *branchinfo_,
uint64_t *sum_) uint64_t *sum_)
{
rwlock::ReadGuard guard(branches_.lock);
branchinfo_->reserve(branches_.vec.size());
return eppfrd::get_branchinfo_action(branches_.vec,fusepath_,branchinfo_,sum_);
}
static
int
get_branchinfo_search(const BranchVec &branches_,
const char *fusepath_,
BranchInfoVec *branchinfo_,
uint64_t *sum_)
{ {
int rv; int rv;
BranchInfo bi; BranchInfo bi;
uint64_t spaceavail; uint64_t spaceavail;
const Branch *branch; const Branch *branch;
rwlock::ReadGuard guard(&branches_.lock);
*sum_ = 0; *sum_ = 0;
for(size_t i = 0, ei = branches_.size(); i < ei; i++) for(size_t i = 0, ei = branches_.size(); i < ei; i++)
@ -159,6 +181,20 @@ namespace eppfrd
return ENOENT; return ENOENT;
} }
static
int
get_branchinfo_search(const Branches &branches_,
const char *fusepath_,
BranchInfoVec *branchinfo_,
uint64_t *sum_)
{
rwlock::ReadGuard guard(branches_.lock);
branchinfo_->reserve(branches_.vec.size());
return eppfrd::get_branchinfo_search(branches_.vec,fusepath_,branchinfo_,sum_);
}
static static
const const
string* string*
@ -187,7 +223,6 @@ namespace eppfrd
int int
create(const Branches &branches_, create(const Branches &branches_,
const char *fusepath_, const char *fusepath_,
const uint64_t minfreespace_,
vector<string> *paths_) vector<string> *paths_)
{ {
int error; int error;
@ -195,8 +230,7 @@ namespace eppfrd
const string *basepath; const string *basepath;
BranchInfoVec branchinfo; BranchInfoVec branchinfo;
branchinfo.reserve(branches_.size());
error = eppfrd::get_branchinfo_create(branches_,fusepath_,minfreespace_,&branchinfo,&sum);
error = eppfrd::get_branchinfo_create(branches_,fusepath_,&branchinfo,&sum);
basepath = eppfrd::get_branch(branchinfo,sum); basepath = eppfrd::get_branch(branchinfo,sum);
if(basepath == NULL) if(basepath == NULL)
return (errno=error,-1); return (errno=error,-1);
@ -210,7 +244,6 @@ namespace eppfrd
int int
action(const Branches &branches_, action(const Branches &branches_,
const char *fusepath_, const char *fusepath_,
const uint64_t minfreespace_,
vector<string> *paths_) vector<string> *paths_)
{ {
int error; int error;
@ -218,8 +251,7 @@ namespace eppfrd
const string *basepath; const string *basepath;
BranchInfoVec branchinfo; BranchInfoVec branchinfo;
branchinfo.reserve(branches_.size());
error = eppfrd::get_branchinfo_action(branches_,fusepath_,minfreespace_,&branchinfo,&sum);
error = eppfrd::get_branchinfo_action(branches_,fusepath_,&branchinfo,&sum);
basepath = eppfrd::get_branch(branchinfo,sum); basepath = eppfrd::get_branch(branchinfo,sum);
if(basepath == NULL) if(basepath == NULL)
return (errno=error,-1); return (errno=error,-1);
@ -233,7 +265,6 @@ namespace eppfrd
int int
search(const Branches &branches_, search(const Branches &branches_,
const char *fusepath_, const char *fusepath_,
const uint64_t minfreespace_,
vector<string> *paths_) vector<string> *paths_)
{ {
int error; int error;
@ -241,8 +272,7 @@ namespace eppfrd
const string *basepath; const string *basepath;
BranchInfoVec branchinfo; BranchInfoVec branchinfo;
branchinfo.reserve(branches_.size());
error = eppfrd::get_branchinfo_search(branches_,fusepath_,minfreespace_,&branchinfo,&sum);
error = eppfrd::get_branchinfo_search(branches_,fusepath_,&branchinfo,&sum);
basepath = eppfrd::get_branch(branchinfo,sum); basepath = eppfrd::get_branch(branchinfo,sum);
if(basepath == NULL) if(basepath == NULL)
return (errno=error,-1); return (errno=error,-1);
@ -257,17 +287,16 @@ int
Policy::Func::eppfrd(const Category type_, Policy::Func::eppfrd(const Category type_,
const Branches &branches_, const Branches &branches_,
const char *fusepath_, const char *fusepath_,
const uint64_t minfreespace_,
vector<string> *paths_) vector<string> *paths_)
{ {
switch(type_) switch(type_)
{ {
case Category::CREATE: case Category::CREATE:
return eppfrd::create(branches_,fusepath_,minfreespace_,paths_);
return eppfrd::create(branches_,fusepath_,paths_);
case Category::ACTION: case Category::ACTION:
return eppfrd::action(branches_,fusepath_,minfreespace_,paths_);
return eppfrd::action(branches_,fusepath_,paths_);
default: default:
case Category::SEARCH: case Category::SEARCH:
return eppfrd::search(branches_,fusepath_,minfreespace_,paths_);
return eppfrd::search(branches_,fusepath_,paths_);
} }
} }

3
src/policy_eprand.cpp

@ -28,12 +28,11 @@ int
Policy::Func::eprand(const Category type_, Policy::Func::eprand(const Category type_,
const Branches &branches_, const Branches &branches_,
const char *fusepath_, const char *fusepath_,
const uint64_t minfreespace_,
vector<string> *paths_) vector<string> *paths_)
{ {
int rv; int rv;
rv = Policy::Func::epall(type_,branches_,fusepath_,minfreespace_,paths_);
rv = Policy::Func::epall(type_,branches_,fusepath_,paths_);
if(rv == 0) if(rv == 0)
{ {
std::random_shuffle(paths_->begin(),paths_->end()); std::random_shuffle(paths_->begin(),paths_->end());

1
src/policy_erofs.cpp

@ -27,7 +27,6 @@ int
Policy::Func::erofs(const Category type_, Policy::Func::erofs(const Category type_,
const Branches &branches_, const Branches &branches_,
const char *fusepath_, const char *fusepath_,
const uint64_t minfreespace_,
vector<string> *paths) vector<string> *paths)
{ {
return (errno=EROFS,-1); return (errno=EROFS,-1);

24
src/policy_ff.cpp

@ -32,12 +32,9 @@ namespace ff
{ {
static static
int int
create(const Branches &branches_,
const uint64_t minfreespace_,
vector<string> *paths_)
create(const BranchVec &branches_,
vector<string> *paths_)
{ {
rwlock::ReadGuard guard(&branches_.lock);
int rv; int rv;
int error; int error;
fs::info_t info; fs::info_t info;
@ -55,7 +52,7 @@ namespace ff
error_and_continue(error,ENOENT); error_and_continue(error,ENOENT);
if(info.readonly) if(info.readonly)
error_and_continue(error,EROFS); error_and_continue(error,EROFS);
if(info.spaceavail < minfreespace_)
if(info.spaceavail < branch->minfreespace())
error_and_continue(error,ENOSPC); error_and_continue(error,ENOSPC);
paths_->push_back(branch->path); paths_->push_back(branch->path);
@ -65,17 +62,26 @@ namespace ff
return (errno=error,-1); return (errno=error,-1);
} }
static
int
create(const Branches &branches_,
vector<string> *paths_)
{
rwlock::ReadGuard guard(branches_.lock);
return ff::create(branches_.vec,paths_);
}
} }
int int
Policy::Func::ff(const Category type_, Policy::Func::ff(const Category type_,
const Branches &branches_, const Branches &branches_,
const char *fusepath_, const char *fusepath_,
const uint64_t minfreespace_,
vector<string> *paths_) vector<string> *paths_)
{ {
if(type_ == Category::CREATE) if(type_ == Category::CREATE)
return ff::create(branches_,minfreespace_,paths_);
return ff::create(branches_,paths_);
return Policy::Func::epff(type_,branches_,fusepath_,minfreespace_,paths_);
return Policy::Func::epff(type_,branches_,fusepath_,paths_);
} }

1
src/policy_invalid.cpp

@ -27,7 +27,6 @@ int
Policy::Func::invalid(const Category type_, Policy::Func::invalid(const Category type_,
const Branches &branches_, const Branches &branches_,
const char *fusepath_, const char *fusepath_,
const uint64_t minfreespace_,
vector<string> *paths_) vector<string> *paths_)
{ {
return (errno=EINVAL,-1); return (errno=EINVAL,-1);

34
src/policy_lfs.cpp

@ -33,22 +33,19 @@ namespace lfs
{ {
static static
int int
create(const Branches &branches_,
const uint64_t minfreespace_,
vector<string> *paths_)
create(const BranchVec &branches_,
vector<string> *paths_)
{ {
rwlock::ReadGuard guard(&branches_.lock);
int rv; int rv;
int error; int error;
uint64_t lfs; uint64_t lfs;
fs::info_t info; fs::info_t info;
const Branch *branch; const Branch *branch;
const string *lfsbasepath;
const string *basepath;
error = ENOENT; error = ENOENT;
lfs = std::numeric_limits<uint64_t>::max(); lfs = std::numeric_limits<uint64_t>::max();
lfsbasepath = NULL;
basepath = NULL;
for(size_t i = 0, ei = branches_.size(); i != ei; i++) for(size_t i = 0, ei = branches_.size(); i != ei; i++)
{ {
branch = &branches_[i]; branch = &branches_[i];
@ -60,33 +57,42 @@ namespace lfs
error_and_continue(error,ENOENT); error_and_continue(error,ENOENT);
if(info.readonly) if(info.readonly)
error_and_continue(error,EROFS); error_and_continue(error,EROFS);
if(info.spaceavail < minfreespace_)
if(info.spaceavail < branch->minfreespace())
error_and_continue(error,ENOSPC); error_and_continue(error,ENOSPC);
if(info.spaceavail > lfs) if(info.spaceavail > lfs)
continue; continue;
lfs = info.spaceavail; lfs = info.spaceavail;
lfsbasepath = &branch->path;
basepath = &branch->path;
} }
if(lfsbasepath == NULL)
if(basepath == NULL)
return (errno=error,-1); return (errno=error,-1);
paths_->push_back(*lfsbasepath);
paths_->push_back(*basepath);
return 0; return 0;
} }
static
int
create(const Branches &branches_,
vector<string> *paths_)
{
rwlock::ReadGuard guard(branches_.lock);
return lfs::create(branches_.vec,paths_);
}
} }
int int
Policy::Func::lfs(const Category type_, Policy::Func::lfs(const Category type_,
const Branches &branches_, const Branches &branches_,
const char *fusepath_, const char *fusepath_,
const uint64_t minfreespace_,
vector<string> *paths_) vector<string> *paths_)
{ {
if(type_ == Category::CREATE) if(type_ == Category::CREATE)
return lfs::create(branches_,minfreespace_,paths_);
return lfs::create(branches_,paths_);
return Policy::Func::eplfs(type_,branches_,fusepath_,minfreespace_,paths_);
return Policy::Func::eplfs(type_,branches_,fusepath_,paths_);
} }

36
src/policy_lus.cpp

@ -33,22 +33,19 @@ namespace lus
{ {
static static
int int
create(const Branches &branches_,
const uint64_t minfreespace_,
vector<string> *paths_)
create(const BranchVec &branches_,
vector<string> *paths_)
{ {
rwlock::ReadGuard guard(&branches_.lock);
int rv; int rv;
int error; int error;
uint64_t lus; uint64_t lus;
fs::info_t info; fs::info_t info;
const Branch *branch; const Branch *branch;
const string *lusbasepath;
const string *basepath;
error = ENOENT; error = ENOENT;
lus = std::numeric_limits<uint64_t>::max(); lus = std::numeric_limits<uint64_t>::max();
lusbasepath = NULL;
basepath = NULL;
for(size_t i = 0, ei = branches_.size(); i != ei; i++) for(size_t i = 0, ei = branches_.size(); i != ei; i++)
{ {
branch = &branches_[i]; branch = &branches_[i];
@ -60,33 +57,42 @@ namespace lus
error_and_continue(error,ENOENT); error_and_continue(error,ENOENT);
if(info.readonly) if(info.readonly)
error_and_continue(error,EROFS); error_and_continue(error,EROFS);
if(info.spaceavail < minfreespace_)
if(info.spaceavail < branch->minfreespace())
error_and_continue(error,ENOSPC); error_and_continue(error,ENOSPC);
if(info.spaceused >= lus) if(info.spaceused >= lus)
continue; continue;
lus = info.spaceused;
lusbasepath = &branch->path;
lus = info.spaceused;
basepath = &branch->path;
} }
if(lusbasepath == NULL)
if(basepath == NULL)
return (errno=error,-1); return (errno=error,-1);
paths_->push_back(*lusbasepath);
paths_->push_back(*basepath);
return 0; return 0;
} }
static
int
create(const Branches &branches_,
vector<string> *paths_)
{
rwlock::ReadGuard guard(branches_.lock);
return lus::create(branches_.vec,paths_);
}
} }
int int
Policy::Func::lus(const Category type_, Policy::Func::lus(const Category type_,
const Branches &branches_, const Branches &branches_,
const char *fusepath_, const char *fusepath_,
const uint64_t minfreespace_,
vector<string> *paths_) vector<string> *paths_)
{ {
if(type_ == Category::CREATE) if(type_ == Category::CREATE)
return lus::create(branches_,minfreespace_,paths_);
return lus::create(branches_,paths_);
return Policy::Func::eplus(type_,branches_,fusepath_,minfreespace_,paths_);
return Policy::Func::eplus(type_,branches_,fusepath_,paths_);
} }

34
src/policy_mfs.cpp

@ -32,22 +32,19 @@ namespace mfs
{ {
static static
int int
create(const Branches &branches_,
const uint64_t minfreespace_,
vector<string> *paths_)
create(const BranchVec &branches_,
vector<string> *paths_)
{ {
rwlock::ReadGuard guard(&branches_.lock);
int rv; int rv;
int error; int error;
uint64_t mfs; uint64_t mfs;
fs::info_t info; fs::info_t info;
const Branch *branch; const Branch *branch;
const string *mfsbasepath;
const string *basepath;
error = ENOENT; error = ENOENT;
mfs = 0; mfs = 0;
mfsbasepath = NULL;
basepath = NULL;
for(size_t i = 0, ei = branches_.size(); i != ei; i++) for(size_t i = 0, ei = branches_.size(); i != ei; i++)
{ {
branch = &branches_[i]; branch = &branches_[i];
@ -59,33 +56,42 @@ namespace mfs
error_and_continue(error,ENOENT); error_and_continue(error,ENOENT);
if(info.readonly) if(info.readonly)
error_and_continue(error,EROFS); error_and_continue(error,EROFS);
if(info.spaceavail < minfreespace_)
if(info.spaceavail < branch->minfreespace())
error_and_continue(error,ENOSPC); error_and_continue(error,ENOSPC);
if(info.spaceavail < mfs) if(info.spaceavail < mfs)
continue; continue;
mfs = info.spaceavail; mfs = info.spaceavail;
mfsbasepath = &branch->path;
basepath = &branch->path;
} }
if(mfsbasepath == NULL)
if(basepath == NULL)
return (errno=error,-1); return (errno=error,-1);
paths_->push_back(*mfsbasepath);
paths_->push_back(*basepath);
return 0; return 0;
} }
static
int
create(const Branches &branches_,
vector<string> *paths_)
{
rwlock::ReadGuard guard(branches_.lock);
return mfs::create(branches_.vec,paths_);
}
} }
int int
Policy::Func::mfs(const Category type_, Policy::Func::mfs(const Category type_,
const Branches &branches_, const Branches &branches_,
const char *fusepath_, const char *fusepath_,
const uint64_t minfreespace_,
vector<string> *paths_) vector<string> *paths_)
{ {
if(type_ == Category::CREATE) if(type_ == Category::CREATE)
return mfs::create(branches_,minfreespace_,paths_);
return mfs::create(branches_,paths_);
return Policy::Func::epmfs(type_,branches_,fusepath_,minfreespace_,paths_);
return Policy::Func::epmfs(type_,branches_,fusepath_,paths_);
} }

39
src/policy_msplfs.cpp

@ -36,10 +36,9 @@ namespace msplfs
static static
const const
string* string*
create_1(const Branches &branches_,
const string &fusepath_,
const uint64_t minfreespace_,
int *err_)
create_1(const BranchVec &branches_,
const string &fusepath_,
int *err_)
{ {
int rv; int rv;
uint64_t lfs; uint64_t lfs;
@ -54,16 +53,16 @@ namespace msplfs
{ {
branch = &branches_[i]; branch = &branches_[i];
if(!fs::exists(branch->path,fusepath))
error_and_continue(*err_,ENOENT);
if(branch->ro_or_nc()) if(branch->ro_or_nc())
error_and_continue(*err_,EROFS); error_and_continue(*err_,EROFS);
if(!fs::exists(branch->path,fusepath))
error_and_continue(*err_,ENOENT);
rv = fs::info(branch->path,&info); rv = fs::info(branch->path,&info);
if(rv == -1) if(rv == -1)
error_and_continue(*err_,ENOENT); error_and_continue(*err_,ENOENT);
if(info.readonly) if(info.readonly)
error_and_continue(*err_,EROFS); error_and_continue(*err_,EROFS);
if(info.spaceavail < minfreespace_)
if(info.spaceavail < branch->minfreespace())
error_and_continue(*err_,ENOSPC); error_and_continue(*err_,ENOSPC);
if(info.spaceavail > lfs) if(info.spaceavail > lfs)
continue; continue;
@ -77,21 +76,19 @@ namespace msplfs
static static
int int
create(const Branches &branches_,
const char *fusepath_,
const uint64_t minfreespace_,
vector<string> *paths_)
create(const BranchVec &branches_,
const char *fusepath_,
vector<string> *paths_)
{ {
int error; int error;
string fusepath; string fusepath;
const string *basepath; const string *basepath;
rwlock::ReadGuard guard(&branches_.lock);
error = ENOENT; error = ENOENT;
fusepath = fusepath_; fusepath = fusepath_;
do do
{ {
basepath = create_1(branches_,fusepath,minfreespace_,&error);
basepath = msplfs::create_1(branches_,fusepath,&error);
if(basepath) if(basepath)
break; break;
@ -106,17 +103,27 @@ namespace msplfs
return 0; return 0;
} }
static
int
create(const Branches &branches_,
const char *fusepath_,
vector<string> *paths_)
{
rwlock::ReadGuard guard(branches_.lock);
return msplfs::create(branches_.vec,fusepath_,paths_);
}
} }
int int
Policy::Func::msplfs(const Category type_, Policy::Func::msplfs(const Category type_,
const Branches &branches_, const Branches &branches_,
const char *fusepath_, const char *fusepath_,
const uint64_t minfreespace_,
vector<string> *paths_) vector<string> *paths_)
{ {
if(type_ == Category::CREATE) if(type_ == Category::CREATE)
return msplfs::create(branches_,fusepath_,minfreespace_,paths_);
return msplfs::create(branches_,fusepath_,paths_);
return Policy::Func::eplfs(type_,branches_,fusepath_,minfreespace_,paths_);
return Policy::Func::eplfs(type_,branches_,fusepath_,paths_);
} }

39
src/policy_msplus.cpp

@ -36,10 +36,9 @@ namespace msplus
static static
const const
string* string*
create_1(const Branches &branches_,
const string &fusepath_,
const uint64_t minfreespace_,
int *err_)
create_1(const BranchVec &branches_,
const string &fusepath_,
int *err_)
{ {
int rv; int rv;
uint64_t lus; uint64_t lus;
@ -54,16 +53,16 @@ namespace msplus
{ {
branch = &branches_[i]; branch = &branches_[i];
if(!fs::exists(branch->path,fusepath))
error_and_continue(*err_,ENOENT);
if(branch->ro_or_nc()) if(branch->ro_or_nc())
error_and_continue(*err_,EROFS); error_and_continue(*err_,EROFS);
if(!fs::exists(branch->path,fusepath))
error_and_continue(*err_,ENOENT);
rv = fs::info(branch->path,&info); rv = fs::info(branch->path,&info);
if(rv == -1) if(rv == -1)
error_and_continue(*err_,ENOENT); error_and_continue(*err_,ENOENT);
if(info.readonly) if(info.readonly)
error_and_continue(*err_,EROFS); error_and_continue(*err_,EROFS);
if(info.spaceavail < minfreespace_)
if(info.spaceavail < branch->minfreespace())
error_and_continue(*err_,ENOSPC); error_and_continue(*err_,ENOSPC);
if(info.spaceused >= lus) if(info.spaceused >= lus)
continue; continue;
@ -77,21 +76,19 @@ namespace msplus
static static
int int
create(const Branches &branches_,
const char *fusepath_,
const uint64_t minfreespace_,
vector<string> *paths_)
create(const BranchVec &branches_,
const char *fusepath_,
vector<string> *paths_)
{ {
int error; int error;
string fusepath; string fusepath;
const string *basepath; const string *basepath;
rwlock::ReadGuard guard(&branches_.lock);
error = ENOENT; error = ENOENT;
fusepath = fusepath_; fusepath = fusepath_;
do do
{ {
basepath = create_1(branches_,fusepath,minfreespace_,&error);
basepath = msplus::create_1(branches_,fusepath,&error);
if(basepath) if(basepath)
break; break;
@ -106,17 +103,27 @@ namespace msplus
return 0; return 0;
} }
static
int
create(const Branches &branches_,
const char *fusepath_,
vector<string> *paths_)
{
rwlock::ReadGuard guard(branches_.lock);
return msplus::create(branches_.vec,fusepath_,paths_);
}
} }
int int
Policy::Func::msplus(const Category type_, Policy::Func::msplus(const Category type_,
const Branches &branches_, const Branches &branches_,
const char *fusepath_, const char *fusepath_,
const uint64_t minfreespace_,
vector<string> *paths_) vector<string> *paths_)
{ {
if(type_ == Category::CREATE) if(type_ == Category::CREATE)
return msplus::create(branches_,fusepath_,minfreespace_,paths_);
return msplus::create(branches_,fusepath_,paths_);
return Policy::Func::eplus(type_,branches_,fusepath_,minfreespace_,paths_);
return Policy::Func::eplus(type_,branches_,fusepath_,paths_);
} }

39
src/policy_mspmfs.cpp

@ -36,10 +36,9 @@ namespace mspmfs
static static
const const
string* string*
create_1(const Branches &branches_,
const string &fusepath_,
const uint64_t minfreespace_,
int *err_)
create_1(const BranchVec &branches_,
const string &fusepath_,
int *err_)
{ {
int rv; int rv;
uint64_t mfs; uint64_t mfs;
@ -54,16 +53,16 @@ namespace mspmfs
{ {
branch = &branches_[i]; branch = &branches_[i];
if(!fs::exists(branch->path,fusepath))
error_and_continue(*err_,ENOENT);
if(branch->ro_or_nc()) if(branch->ro_or_nc())
error_and_continue(*err_,EROFS); error_and_continue(*err_,EROFS);
if(!fs::exists(branch->path,fusepath))
error_and_continue(*err_,ENOENT);
rv = fs::info(branch->path,&info); rv = fs::info(branch->path,&info);
if(rv == -1) if(rv == -1)
error_and_continue(*err_,ENOENT); error_and_continue(*err_,ENOENT);
if(info.readonly) if(info.readonly)
error_and_continue(*err_,EROFS); error_and_continue(*err_,EROFS);
if(info.spaceavail < minfreespace_)
if(info.spaceavail < branch->minfreespace())
error_and_continue(*err_,ENOSPC); error_and_continue(*err_,ENOSPC);
if(info.spaceavail < mfs) if(info.spaceavail < mfs)
continue; continue;
@ -77,21 +76,19 @@ namespace mspmfs
static static
int int
create(const Branches &branches_,
const char *fusepath_,
const uint64_t minfreespace_,
vector<string> *paths_)
create(const BranchVec &branches_,
const char *fusepath_,
vector<string> *paths_)
{ {
int error; int error;
string fusepath; string fusepath;
const string *basepath; const string *basepath;
rwlock::ReadGuard guard(&branches_.lock);
error = ENOENT; error = ENOENT;
fusepath = fusepath_; fusepath = fusepath_;
do do
{ {
basepath = create_1(branches_,fusepath,minfreespace_,&error);
basepath = mspmfs::create_1(branches_,fusepath,&error);
if(basepath) if(basepath)
break; break;
@ -106,17 +103,27 @@ namespace mspmfs
return 0; return 0;
} }
static
int
create(const Branches &branches_,
const char *fusepath_,
vector<string> *paths_)
{
rwlock::ReadGuard guard(branches_.lock);
return mspmfs::create(branches_.vec,fusepath_,paths_);
}
} }
int int
Policy::Func::mspmfs(const Category type_, Policy::Func::mspmfs(const Category type_,
const Branches &branches_, const Branches &branches_,
const char *fusepath_, const char *fusepath_,
const uint64_t minfreespace_,
vector<string> *paths_) vector<string> *paths_)
{ {
if(type_ == Category::CREATE) if(type_ == Category::CREATE)
return mspmfs::create(branches_,fusepath_,minfreespace_,paths_);
return mspmfs::create(branches_,fusepath_,paths_);
return Policy::Func::epmfs(type_,branches_,fusepath_,minfreespace_,paths_);
return Policy::Func::epmfs(type_,branches_,fusepath_,paths_);
} }

38
src/policy_msppfrd.cpp

@ -44,18 +44,16 @@ namespace msppfrd
{ {
static static
int int
create_1(const Branches &branches_,
const string &fusepath_,
const uint64_t minfreespace_,
BranchInfoVec *branchinfo_,
uint64_t *sum_)
create_1(const BranchVec &branches_,
const string &fusepath_,
BranchInfoVec *branchinfo_,
uint64_t *sum_)
{ {
int rv; int rv;
int error; int error;
BranchInfo bi; BranchInfo bi;
fs::info_t info; fs::info_t info;
const Branch *branch; const Branch *branch;
rwlock::ReadGuard guard(&branches_.lock);
*sum_ = 0; *sum_ = 0;
error = ENOENT; error = ENOENT;
@ -72,7 +70,7 @@ namespace msppfrd
error_and_continue(error,ENOENT); error_and_continue(error,ENOENT);
if(info.readonly) if(info.readonly)
error_and_continue(error,EROFS); error_and_continue(error,EROFS);
if(info.spaceavail < minfreespace_)
if(info.spaceavail < branch->minfreespace())
error_and_continue(error,ENOSPC); error_and_continue(error,ENOSPC);
*sum_ += info.spaceavail; *sum_ += info.spaceavail;
@ -85,11 +83,24 @@ namespace msppfrd
return error; return error;
} }
static
int
create_1(const Branches &branches_,
const string &fusepath_,
BranchInfoVec *branchinfo_,
uint64_t *sum_)
{
rwlock::ReadGuard guard(branches_.lock);
branchinfo_->reserve(branches_.vec.size());
return msppfrd::create_1(branches_.vec,fusepath_,branchinfo_,sum_);
}
static static
int int
get_branchinfo(const Branches &branches_, get_branchinfo(const Branches &branches_,
const char *fusepath_, const char *fusepath_,
const uint64_t minfreespace_,
BranchInfoVec *branchinfo_, BranchInfoVec *branchinfo_,
uint64_t *sum_) uint64_t *sum_)
{ {
@ -99,7 +110,7 @@ namespace msppfrd
fusepath = fusepath_; fusepath = fusepath_;
do do
{ {
error = msppfrd::create_1(branches_,fusepath,minfreespace_,branchinfo_,sum_);
error = msppfrd::create_1(branches_,fusepath,branchinfo_,sum_);
if(branchinfo_->size()) if(branchinfo_->size())
return error; return error;
@ -138,7 +149,6 @@ namespace msppfrd
int int
create(const Branches &branches_, create(const Branches &branches_,
const char *fusepath_, const char *fusepath_,
const uint64_t minfreespace_,
vector<string> *paths_) vector<string> *paths_)
{ {
int error; int error;
@ -146,8 +156,7 @@ namespace msppfrd
const string *basepath; const string *basepath;
BranchInfoVec branchinfo; BranchInfoVec branchinfo;
branchinfo.reserve(branches_.size());
error = msppfrd::get_branchinfo(branches_,fusepath_,minfreespace_,&branchinfo,&sum);
error = msppfrd::get_branchinfo(branches_,fusepath_,&branchinfo,&sum);
basepath = msppfrd::get_branch(branchinfo,sum); basepath = msppfrd::get_branch(branchinfo,sum);
if(basepath == NULL) if(basepath == NULL)
return (errno=error,-1); return (errno=error,-1);
@ -162,11 +171,10 @@ int
Policy::Func::msppfrd(const Category type_, Policy::Func::msppfrd(const Category type_,
const Branches &branches_, const Branches &branches_,
const char *fusepath_, const char *fusepath_,
const uint64_t minfreespace_,
vector<string> *paths_) vector<string> *paths_)
{ {
if(type_ == Category::CREATE) if(type_ == Category::CREATE)
return msppfrd::create(branches_,fusepath_,minfreespace_,paths_);
return msppfrd::create(branches_,fusepath_,paths_);
return Policy::Func::eppfrd(type_,branches_,fusepath_,minfreespace_,paths_);
return Policy::Func::eppfrd(type_,branches_,fusepath_,paths_);
} }

89
src/policy_newest.cpp

@ -36,32 +36,29 @@ namespace newest
{ {
static static
int int
create(const Branches &branches_,
const char *fusepath_,
const uint64_t minfreespace_,
vector<string> *paths_)
create(const BranchVec &branches_,
const char *fusepath_,
vector<string> *paths_)
{ {
rwlock::ReadGuard guard(&branches_.lock);
int rv; int rv;
int error; int error;
time_t newest; time_t newest;
struct stat st; struct stat st;
fs::info_t info; fs::info_t info;
const Branch *branch; const Branch *branch;
const string *newestbasepath;
const string *basepath;
error = ENOENT; error = ENOENT;
newest = std::numeric_limits<time_t>::min(); newest = std::numeric_limits<time_t>::min();
newestbasepath = NULL;
basepath = NULL;
for(size_t i = 0, ei = branches_.size(); i != ei; i++) for(size_t i = 0, ei = branches_.size(); i != ei; i++)
{ {
branch = &branches_[i]; branch = &branches_[i];
if(!fs::exists(branch->path,fusepath_,&st))
error_and_continue(error,ENOENT);
if(branch->ro_or_nc()) if(branch->ro_or_nc())
error_and_continue(error,EROFS); error_and_continue(error,EROFS);
if(!fs::exists(branch->path,fusepath_,&st))
error_and_continue(error,ENOENT);
if(st.st_mtime < newest) if(st.st_mtime < newest)
continue; continue;
rv = fs::info(branch->path,&info); rv = fs::info(branch->path,&info);
@ -69,48 +66,57 @@ namespace newest
error_and_continue(error,ENOENT); error_and_continue(error,ENOENT);
if(info.readonly) if(info.readonly)
error_and_continue(error,EROFS); error_and_continue(error,EROFS);
if(info.spaceavail < minfreespace_)
if(info.spaceavail < branch->minfreespace())
error_and_continue(error,ENOSPC); error_and_continue(error,ENOSPC);
newest = st.st_mtime; newest = st.st_mtime;
newestbasepath = &branch->path;
basepath = &branch->path;
} }
if(newestbasepath == NULL)
if(basepath == NULL)
return (errno=error,-1); return (errno=error,-1);
paths_->push_back(*newestbasepath);
paths_->push_back(*basepath);
return 0; return 0;
} }
static static
int int
action(const Branches &branches_,
create(const Branches &branches_,
const char *fusepath_, const char *fusepath_,
vector<string> *paths_) vector<string> *paths_)
{ {
rwlock::ReadGuard guard(&branches_.lock);
rwlock::ReadGuard guard(branches_.lock);
return newest::create(branches_.vec,fusepath_,paths_);
}
static
int
action(const BranchVec &branches_,
const char *fusepath_,
vector<string> *paths_)
{
int rv; int rv;
int error; int error;
bool readonly; bool readonly;
time_t newest; time_t newest;
struct stat st; struct stat st;
const Branch *branch; const Branch *branch;
const string *newestbasepath;
const string *basepath;
error = ENOENT; error = ENOENT;
newest = std::numeric_limits<time_t>::min(); newest = std::numeric_limits<time_t>::min();
newestbasepath = NULL;
basepath = NULL;
for(size_t i = 0, ei = branches_.size(); i != ei; i++) for(size_t i = 0, ei = branches_.size(); i != ei; i++)
{ {
branch = &branches_[i]; branch = &branches_[i];
if(!fs::exists(branch->path,fusepath_,&st))
error_and_continue(error,ENOENT);
if(branch->ro()) if(branch->ro())
error_and_continue(error,EROFS); error_and_continue(error,EROFS);
if(!fs::exists(branch->path,fusepath_,&st))
error_and_continue(error,ENOENT);
if(st.st_mtime < newest) if(st.st_mtime < newest)
continue; continue;
rv = fs::statvfs_cache_readonly(branch->path,&readonly); rv = fs::statvfs_cache_readonly(branch->path,&readonly);
@ -120,32 +126,41 @@ namespace newest
error_and_continue(error,EROFS); error_and_continue(error,EROFS);
newest = st.st_mtime; newest = st.st_mtime;
newestbasepath = &branch->path;
basepath = &branch->path;
} }
if(newestbasepath == NULL)
if(basepath == NULL)
return (errno=error,-1); return (errno=error,-1);
paths_->push_back(*newestbasepath);
paths_->push_back(*basepath);
return 0; return 0;
} }
static static
int int
search(const Branches &branches_,
action(const Branches &branches_,
const char *fusepath_, const char *fusepath_,
vector<string> *paths_) vector<string> *paths_)
{ {
rwlock::ReadGuard guard(&branches_.lock);
rwlock::ReadGuard guard(branches_.lock);
return newest::action(branches_.vec,fusepath_,paths_);
}
static
int
search(const BranchVec &branches_,
const char *fusepath_,
vector<string> *paths_)
{
time_t newest; time_t newest;
struct stat st; struct stat st;
const Branch *branch; const Branch *branch;
const string *newestbasepath;
const string *basepath;
newest = std::numeric_limits<time_t>::min(); newest = std::numeric_limits<time_t>::min();
newestbasepath = NULL;
basepath = NULL;
for(size_t i = 0, ei = branches_.size(); i != ei; i++) for(size_t i = 0, ei = branches_.size(); i != ei; i++)
{ {
branch = &branches_[i]; branch = &branches_[i];
@ -156,29 +171,39 @@ namespace newest
continue; continue;
newest = st.st_mtime; newest = st.st_mtime;
newestbasepath = &branch->path;
basepath = &branch->path;
} }
if(newestbasepath == NULL)
if(basepath == NULL)
return (errno=ENOENT,-1); return (errno=ENOENT,-1);
paths_->push_back(*newestbasepath);
paths_->push_back(*basepath);
return 0; return 0;
} }
static
int
search(const Branches &branches_,
const char *fusepath_,
vector<string> *paths_)
{
rwlock::ReadGuard guard(branches_.lock);
return newest::search(branches_.vec,fusepath_,paths_);
}
} }
int int
Policy::Func::newest(const Category type_, Policy::Func::newest(const Category type_,
const Branches &branches_, const Branches &branches_,
const char *fusepath_, const char *fusepath_,
const uint64_t minfreespace_,
vector<string> *paths_) vector<string> *paths_)
{ {
switch(type_) switch(type_)
{ {
case Category::CREATE: case Category::CREATE:
return newest::create(branches_,fusepath_,minfreespace_,paths_);
return newest::create(branches_,fusepath_,paths_);
case Category::ACTION: case Category::ACTION:
return newest::action(branches_,fusepath_,paths_); return newest::action(branches_,fusepath_,paths_);
case Category::SEARCH: case Category::SEARCH:

32
src/policy_pfrd.cpp

@ -40,17 +40,15 @@ namespace pfrd
{ {
static static
int int
get_branchinfo(const Branches &branches_,
const uint64_t minfreespace_,
BranchInfoVec *branchinfo_,
uint64_t *sum_)
get_branchinfo(const BranchVec &branches_,
BranchInfoVec *branchinfo_,
uint64_t *sum_)
{ {
int rv; int rv;
int error; int error;
BranchInfo bi; BranchInfo bi;
fs::info_t info; fs::info_t info;
const Branch *branch; const Branch *branch;
rwlock::ReadGuard guard(&branches_.lock);
*sum_ = 0; *sum_ = 0;
error = ENOENT; error = ENOENT;
@ -65,7 +63,7 @@ namespace pfrd
error_and_continue(error,ENOENT); error_and_continue(error,ENOENT);
if(info.readonly) if(info.readonly)
error_and_continue(error,EROFS); error_and_continue(error,EROFS);
if(info.spaceavail < minfreespace_)
if(info.spaceavail < branch->minfreespace())
error_and_continue(error,ENOSPC); error_and_continue(error,ENOSPC);
*sum_ += info.spaceavail; *sum_ += info.spaceavail;
@ -78,6 +76,19 @@ namespace pfrd
return error; return error;
} }
static
int
get_branchinfo(const Branches &branches_,
BranchInfoVec *branchinfo_,
uint64_t *sum_)
{
rwlock::ReadGuard guard(branches_.lock);
branchinfo_->reserve(branches_.vec.size());
return pfrd::get_branchinfo(branches_.vec,branchinfo_,sum_);
}
static static
const const
string* string*
@ -106,7 +117,6 @@ namespace pfrd
int int
create(const Branches &branches_, create(const Branches &branches_,
const char *fusepath_, const char *fusepath_,
const uint64_t minfreespace_,
vector<string> *paths_) vector<string> *paths_)
{ {
int error; int error;
@ -114,8 +124,7 @@ namespace pfrd
const string *basepath; const string *basepath;
BranchInfoVec branchinfo; BranchInfoVec branchinfo;
branchinfo.reserve(branches_.size());
error = pfrd::get_branchinfo(branches_,minfreespace_,&branchinfo,&sum);
error = pfrd::get_branchinfo(branches_,&branchinfo,&sum);
basepath = pfrd::get_branch(branchinfo,sum); basepath = pfrd::get_branch(branchinfo,sum);
if(basepath == NULL) if(basepath == NULL)
return (errno=error,-1); return (errno=error,-1);
@ -130,11 +139,10 @@ int
Policy::Func::pfrd(const Category type_, Policy::Func::pfrd(const Category type_,
const Branches &branches_, const Branches &branches_,
const char *fusepath_, const char *fusepath_,
const uint64_t minfreespace_,
vector<string> *paths_) vector<string> *paths_)
{ {
if(type_ == Category::CREATE) if(type_ == Category::CREATE)
return pfrd::create(branches_,fusepath_,minfreespace_,paths_);
return pfrd::create(branches_,fusepath_,paths_);
return Policy::Func::eppfrd(type_,branches_,fusepath_,minfreespace_,paths_);
return Policy::Func::eppfrd(type_,branches_,fusepath_,paths_);
} }

3
src/policy_rand.cpp

@ -28,12 +28,11 @@ int
Policy::Func::rand(const Category type_, Policy::Func::rand(const Category type_,
const Branches &branches_, const Branches &branches_,
const char *fusepath_, const char *fusepath_,
const uint64_t minfreespace_,
vector<string> *paths_) vector<string> *paths_)
{ {
int rv; int rv;
rv = Policy::Func::all(type_,branches_,fusepath_,minfreespace_,paths_);
rv = Policy::Func::all(type_,branches_,fusepath_,paths_);
if(rv == 0) if(rv == 0)
{ {
std::random_shuffle(paths_->begin(),paths_->end()); std::random_shuffle(paths_->begin(),paths_->end());

16
src/rwlock.hpp

@ -23,42 +23,42 @@ namespace rwlock
class ReadGuard class ReadGuard
{ {
public: public:
ReadGuard(pthread_rwlock_t *lock_)
ReadGuard(pthread_rwlock_t &lock_)
: _lock(lock_) : _lock(lock_)
{ {
pthread_rwlock_rdlock(_lock);
pthread_rwlock_rdlock(&_lock);
} }
~ReadGuard() ~ReadGuard()
{ {
pthread_rwlock_unlock(_lock);
pthread_rwlock_unlock(&_lock);
} }
private: private:
ReadGuard(); ReadGuard();
private: private:
pthread_rwlock_t *_lock;
pthread_rwlock_t &_lock;
}; };
class WriteGuard class WriteGuard
{ {
public: public:
WriteGuard(pthread_rwlock_t *lock_)
WriteGuard(pthread_rwlock_t &lock_)
: _lock(lock_) : _lock(lock_)
{ {
pthread_rwlock_wrlock(_lock);
pthread_rwlock_wrlock(&_lock);
} }
~WriteGuard() ~WriteGuard()
{ {
pthread_rwlock_unlock(_lock);
pthread_rwlock_unlock(&_lock);
} }
private: private:
WriteGuard(); WriteGuard();
private: private:
pthread_rwlock_t *_lock;
pthread_rwlock_t &_lock;
}; };
} }

19
src/str.cpp

@ -46,6 +46,25 @@ namespace str
return str::split(str_.c_str(),delimiter_,result_); return str::split(str_.c_str(),delimiter_,result_);
} }
void
rsplit1(const string &str_,
const char delimiter_,
vector<string> *result_)
{
std::size_t off;
off = str_.rfind('=');
if(off == std::string::npos)
{
result_->push_back(str_);
}
else
{
result_->push_back(str_.substr(0,off));
result_->push_back(str_.substr(off+1));
}
}
void void
splitkv(const string &str_, splitkv(const string &str_,
const char delimiter_, const char delimiter_,

5
src/str.hpp

@ -30,6 +30,11 @@ namespace str
const char delimiter, const char delimiter,
std::vector<std::string> *result); std::vector<std::string> *result);
void
rsplit1(const std::string &str,
const char delimiter,
std::vector<std::string> *result);
void void
splitkv(const std::string &str, splitkv(const std::string &str,
const char delimiter, const char delimiter,

Loading…
Cancel
Save