Browse Source

checkpoint

toml
Antonio SJ Musumeci 3 years ago
parent
commit
9019df57d0
  1. 2
      config.toml
  2. 95
      src/branch.cpp
  3. 73
      src/branch.hpp
  4. 28
      src/branch_group.cpp
  5. 4
      src/branch_group.hpp
  6. 407
      src/branches.cpp
  7. 77
      src/branches.hpp
  8. 9
      src/fs_clonepath_branches.hpp
  9. 2
      src/fuse_access_policy_ff.hpp
  10. 2
      src/fuse_chmod_policy_all.hpp
  11. 2
      src/fuse_chown_policy_all.hpp
  12. 2
      src/fuse_create_policy_epff.hpp
  13. 2
      src/fuse_getattr_policy_aggregate.hpp
  14. 2
      src/fuse_getattr_policy_check_ff.hpp
  15. 2
      src/fuse_getattr_policy_ff.hpp
  16. 2
      src/fuse_getattr_policy_newest.hpp
  17. 2
      src/fuse_getxattr_policy_ff.hpp
  18. 2
      src/fuse_ioctl_policy_all.hpp
  19. 2
      src/fuse_listxattr_policy_ff.hpp
  20. 2
      src/fuse_mkdir_policy_epff.hpp
  21. 2
      src/fuse_mkdir_policy_ff.hpp
  22. 2
      src/fuse_mknod_policy_epff.hpp
  23. 2
      src/fuse_mknod_policy_ff.hpp
  24. 2
      src/fuse_open_policy_ff.hpp
  25. 2
      src/fuse_readdir_policy_posix.hpp
  26. 2
      src/fuse_readlink_policy_ff.hpp
  27. 2
      src/fuse_symlink_policy_ff.hpp
  28. 2
      src/fuse_truncate_policy_all.hpp
  29. 2
      src/fuse_utimens_policy_all.hpp
  30. 194
      src/policy.hpp
  31. 86
      src/policy_all.cpp
  32. 61
      src/policy_all.hpp
  33. 131
      src/policy_cache.cpp
  34. 62
      src/policy_cache.hpp
  35. 143
      src/policy_epall.cpp
  36. 64
      src/policy_epall.hpp
  37. 142
      src/policy_epff.cpp
  38. 61
      src/policy_epff.hpp
  39. 178
      src/policy_eplfs.cpp
  40. 61
      src/policy_eplfs.hpp
  41. 176
      src/policy_eplus.cpp
  42. 61
      src/policy_eplus.hpp
  43. 177
      src/policy_epmfs.cpp
  44. 64
      src/policy_epmfs.hpp
  45. 262
      src/policy_eppfrd.cpp
  46. 61
      src/policy_eppfrd.hpp
  47. 73
      src/policy_eprand.cpp
  48. 61
      src/policy_eprand.hpp
  49. 48
      src/policy_erofs.cpp
  50. 61
      src/policy_erofs.hpp
  51. 51
      src/policy_error.hpp
  52. 85
      src/policy_ff.cpp
  53. 61
      src/policy_ff.hpp
  54. 98
      src/policy_lfs.cpp
  55. 61
      src/policy_lfs.hpp
  56. 99
      src/policy_lus.cpp
  57. 61
      src/policy_lus.hpp
  58. 94
      src/policy_mfs.cpp
  59. 61
      src/policy_mfs.hpp
  60. 126
      src/policy_msplfs.cpp
  61. 61
      src/policy_msplfs.hpp
  62. 124
      src/policy_msplus.cpp
  63. 61
      src/policy_msplus.hpp
  64. 127
      src/policy_mspmfs.cpp
  65. 61
      src/policy_mspmfs.hpp
  66. 179
      src/policy_msppfrd.cpp
  67. 61
      src/policy_msppfrd.hpp
  68. 176
      src/policy_newest.cpp
  69. 61
      src/policy_newest.hpp
  70. 149
      src/policy_pfrd.cpp
  71. 61
      src/policy_pfrd.hpp
  72. 73
      src/policy_rand.cpp
  73. 61
      src/policy_rand.hpp
  74. 51
      src/policy_rv.hpp
  75. 2
      src/state.hpp

2
config.toml

@ -82,7 +82,7 @@ min-free-space = 123
[[branches.group]]
[[branches.group.branch]]
active = false
active = true
path = '/tmp/mergerfs/a'
path-type = 'literal'
mode = 'RW'

95
src/branch.cpp

@ -17,101 +17,24 @@
*/
#include "branch.hpp"
#include "ef.hpp"
#include "errno.hpp"
#include "num.hpp"
Branch::Branch(const uint64_t &default_minfreespace_)
: _default_minfreespace(&default_minfreespace_)
{
}
int
Branch::from_string(const std::string &str_)
{
return -EINVAL;
}
std::string
Branch::to_string(void) const
{
std::string rv;
rv = path;
rv += '=';
switch(mode)
{
default:
case Branch::Mode::RW:
rv += "RW";
break;
case Branch::Mode::RO:
rv += "RO";
break;
case Branch::Mode::NC:
rv += "NC";
break;
}
if(_minfreespace.has_value())
{
rv += ',';
rv += num::humanize(_minfreespace.value());
}
return rv;
}
void
Branch::set_minfreespace(const uint64_t minfreespace_)
{
_minfreespace = minfreespace_;
}
uint64_t
Branch::minfreespace(void) const
{
if(_minfreespace.has_value())
return _minfreespace.value();
return *_default_minfreespace;
}
bool
Branch::ro(void) const
{
return (mode == Branch::Mode::RO);
}
bool
Branch::nc(void) const
{
return (mode == Branch::Mode::NC);
}
bool
Branch::ro_or_nc(void) const
{
return ((mode == Branch::Mode::RO) ||
(mode == Branch::Mode::NC));
}
Branch2::Mode
Branch2::str2mode(const std::string &str_)
Branch::Mode
Branch::str2mode(const std::string &str_)
{
if(str_ == "RW")
return Branch2::Mode::RW;
return Branch::Mode::RW;
if(str_ == "RO")
return Branch2::Mode::RO;
return Branch::Mode::RO;
if(str_ == "NC")
return Branch2::Mode::NC;
return Branch::Mode::NC;
return Branch2::Mode::RW;
return Branch::Mode::RW;
}
Branch2::Branch2(const toml::value &toml_,
const Branch2::Mode default_mode_,
const uint64_t default_minfreespace_)
Branch::Branch(const toml::value &toml_,
const Branch::Mode default_mode_,
const uint64_t default_minfreespace_)
{
mode = toml::find_or(toml_,"mode",default_mode_);
minfreespace = toml::find_or(toml_,"min-free-space",default_minfreespace_);

73
src/branch.hpp

@ -18,59 +18,16 @@
#pragma once
#include "from_toml.hpp"
#include "fs_path.hpp"
#include "ghc/filesystem.hpp"
#include "nonstd/optional.hpp"
#include "strvec.hpp"
#include "tofrom_string.hpp"
#include "toml.hpp"
#include <cstdint>
#include <string>
#include <vector>
class Branch final : public ToFromString
{
public:
typedef std::vector<Branch> Vector;
public:
Branch(const uint64_t &default_minfreespace_);
public:
enum class Mode
{
INVALID,
RO,
RW,
NC
};
public:
bool ro(void) const;
bool nc(void) const;
bool ro_or_nc(void) const;
public:
int from_string(const std::string &str) final;
std::string to_string(void) const final;
public:
uint64_t minfreespace() const;
void set_minfreespace(const uint64_t);
public:
Mode mode;
std::string path;
private:
nonstd::optional<uint64_t> _minfreespace;
const uint64_t *_default_minfreespace;
};
class Branch2
class Branch
{
public:
enum class Mode
@ -84,9 +41,9 @@ public:
static Mode str2mode(const std::string &);
public:
Branch2(const toml::value &toml,
const Branch2::Mode default_mode,
const uint64_t default_minfreespace);
Branch(const toml::value &toml,
const Branch::Mode default_mode,
const uint64_t default_minfreespace);
public:
bool ro(void) const;
@ -94,30 +51,30 @@ public:
bool ro_or_nc(void) const;
public:
ghc::filesystem::path path;
Mode mode;
uint64_t minfreespace;
gfs::path path;
Mode mode;
uint64_t minfreespace;
};
namespace toml
{
template<>
struct from<Branch2::Mode>
struct from<Branch::Mode>
{
static
Branch2::Mode
Branch::Mode
from_toml(const toml::value &v_)
{
std::string str = v_.as_string();
if(str == "RW")
return Branch2::Mode::RW;
return Branch::Mode::RW;
if(str == "RO")
return Branch2::Mode::RO;
return Branch::Mode::RO;
if(str == "NC")
return Branch2::Mode::NC;
return Branch::Mode::NC;
return Branch2::Mode::RW;
return Branch::Mode::RW;
}
};
}

28
src/branch_group.cpp

@ -19,32 +19,30 @@
#include "branch_group.hpp"
#include "fs_glob.hpp"
#include "fs_path.hpp"
#include <iostream>
#include <stdexcept>
namespace gfs = ghc::filesystem;
namespace l
{
static
void
add_literal(const toml::value &branch_,
const Branch2::Mode default_mode_,
const uint64_t default_minfreespace_,
BranchGroup *branch_group_)
add_literal(const toml::value &branch_,
const Branch::Mode default_mode_,
const uint64_t default_minfreespace_,
BranchGroup *branch_group_)
{
branch_group_->emplace_back(branch_,default_mode_,default_minfreespace_);
}
static
void
add_glob(const toml::value &branch_,
const Branch2::Mode default_mode_,
const uint64_t default_minfreespace_,
BranchGroup *branch_group_)
add_glob(const toml::value &branch_,
const Branch::Mode default_mode_,
const uint64_t default_minfreespace_,
BranchGroup *branch_group_)
{
std::string pattern;
std::vector<gfs::path> paths;
@ -66,11 +64,11 @@ namespace l
}
BranchGroup::BranchGroup(const toml::value &toml_,
const Branch2::Mode default_mode_,
const uint64_t default_minfreespace_)
BranchGroup::BranchGroup(const toml::value &toml_,
const Branch::Mode default_mode_,
const uint64_t default_minfreespace_)
{
Branch2::Mode default_mode;
Branch::Mode default_mode;
uint64_t default_minfreespace;
default_mode = toml::find_or(toml_,"mode",default_mode_);

4
src/branch_group.hpp

@ -22,10 +22,10 @@
#include <vector>
class BranchGroup : public std::vector<Branch2>
class BranchGroup : public std::vector<Branch>
{
public:
BranchGroup(const toml::value &,
const Branch2::Mode,
const Branch::Mode,
const uint64_t);
};

407
src/branches.cpp

@ -19,422 +19,19 @@
#include "branches.hpp"
#include "ef.hpp"
#include "errno.hpp"
#include "from_string.hpp"
#include "fs_glob.hpp"
#include "fs_realpathize.hpp"
#include "nonstd/optional.hpp"
#include "num.hpp"
#include "str.hpp"
#include <string>
#include <fnmatch.h>
#include <iostream>
using std::string;
using std::vector;
using nonstd::optional;
Branches::Impl::Impl(const uint64_t &default_minfreespace_)
: _default_minfreespace(default_minfreespace_)
{
}
Branches::Impl&
Branches::Impl::operator=(Branches::Impl &rval_)
{
auto this_base = dynamic_cast<Branch::Vector*>(this);
auto rval_base = dynamic_cast<Branch::Vector*>(&rval_);
*this_base = *rval_base;
return *this;
}
Branches::Impl&
Branches::Impl::operator=(Branches::Impl &&rval_)
{
auto this_base = dynamic_cast<Branch::Vector*>(this);
auto rval_base = dynamic_cast<Branch::Vector*>(&rval_);
*this_base = std::move(*rval_base);
return *this;
}
const
uint64_t&
Branches::Impl::minfreespace(void) const
{
return _default_minfreespace;
}
namespace l
{
static
void
split(const std::string &s_,
std::string *instr_,
std::string *values_)
{
uint64_t offset;
offset = s_.find_first_not_of("+<>-=");
if(offset > 1)
offset = 2;
*instr_ = s_.substr(0,offset);
if(offset != std::string::npos)
*values_ = s_.substr(offset);
}
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_,
Branches::Impl *branches_)
{
int rv;
string glob;
StrVec paths;
optional<uint64_t> minfreespace;
Branch branch(branches_->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,&paths);
fs::realpathize(&paths);
for(auto &path : paths)
{
branch.path = path;
branches_->push_back(branch);
}
return 0;
}
static
int
set(const std::string &str_,
Branches::Impl *branches_)
{
int rv;
StrVec paths;
Branches::Impl tmp_branches(branches_->minfreespace());
str::split(str_,':',&paths);
for(auto &path : paths)
{
rv = l::parse(path,&tmp_branches);
if(rv < 0)
return rv;
}
*branches_ = std::move(tmp_branches);
return 0;
}
static
int
add_begin(const std::string &str_,
Branches::Impl *branches_)
{
int rv;
vector<string> paths;
Branches::Impl tmp_branches(branches_->minfreespace());
str::split(str_,':',&paths);
for(auto &path : paths)
{
rv = l::parse(path,&tmp_branches);
if(rv < 0)
return rv;
}
branches_->insert(branches_->begin(),
tmp_branches.begin(),
tmp_branches.end());
return 0;
}
static
int
add_end(const std::string &str_,
Branches::Impl *branches_)
{
int rv;
StrVec paths;
Branches::Impl tmp_branches(branches_->minfreespace());
str::split(str_,':',&paths);
for(auto &path : paths)
{
rv = l::parse(path,&tmp_branches);
if(rv < 0)
return rv;
}
branches_->insert(branches_->end(),
tmp_branches.begin(),
tmp_branches.end());
return 0;
}
static
int
erase_begin(Branches::Impl *branches_)
{
branches_->erase(branches_->begin());
return 0;
}
static
int
erase_end(Branches::Impl *branches_)
{
branches_->pop_back();
return 0;
}
static
int
erase_fnmatch(const std::string &str_,
Branches::Impl *branches_)
{
StrVec patterns;
str::split(str_,':',&patterns);
for(auto i = branches_->begin(); i != branches_->end();)
{
int match = FNM_NOMATCH;
for(auto pi = patterns.cbegin(); pi != patterns.cend() && match != 0; ++pi)
{
match = ::fnmatch(pi->c_str(),i->path.c_str(),0);
}
i = ((match == 0) ? branches_->erase(i) : (i+1));
}
return 0;
}
}
int
Branches::Impl::from_string(const std::string &s_)
{
std::string instr;
std::string values;
l::split(s_,&instr,&values);
if(instr == "+")
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(this);
if(instr == "->")
return l::erase_end(this);
if(instr == "=")
return l::set(values,this);
if(instr.empty())
return l::set(values,this);
return -EINVAL;
}
std::string
Branches::Impl::to_string(void) const
{
string tmp;
if(empty())
return tmp;
for(auto &branch : *this)
{
tmp += branch.to_string();
tmp += ':';
}
tmp.pop_back();
return tmp;
}
void
Branches::Impl::to_paths(StrVec &paths_) const
{
for(auto &branch : *this)
{
paths_.push_back(branch.path);
}
}
int
Branches::from_string(const std::string &str_)
{
int rv;
Branches::Ptr impl;
Branches::Ptr new_impl;
{
std::lock_guard<std::mutex> lock_guard(_mutex);
impl = _impl;
}
new_impl = std::make_shared<Branches::Impl>(impl->minfreespace());
*new_impl = *impl;
rv = new_impl->from_string(str_);
if(rv < 0)
return rv;
{
std::lock_guard<std::mutex> lock_guard(_mutex);
_impl = new_impl;
}
return 0;
}
string
Branches::to_string(void) const
{
std::lock_guard<std::mutex> lock_guard(_mutex);
return _impl->to_string();
}
SrcMounts::SrcMounts(Branches &b_)
: _branches(b_)
{
}
int
SrcMounts::from_string(const std::string &s_)
{
return _branches.from_string(s_);
}
std::string
SrcMounts::to_string(void) const
{
std::string rv;
Branches::CPtr branches = _branches;
if(branches->empty())
return rv;
for(const auto &branch : *branches)
{
rv += branch.path;
rv += ':';
}
rv.pop_back();
return rv;
}
Branches2::Branches2(const toml::value &toml_)
Branches::Branches(const toml::value &toml_)
{
toml::value branches;
Branch2::Mode default_mode;
Branch::Mode default_mode;
uint64_t default_minfreespace;
default_mode = toml::find_or(toml_,"branches","mode",Branch2::Mode::RW);

77
src/branches.hpp

@ -18,87 +18,14 @@
#pragma once
#include "from_toml.hpp"
#include "branch.hpp"
#include "branch_group.hpp"
#include "nonstd/optional.hpp"
#include "strvec.hpp"
#include "tofrom_string.hpp"
#include <cstdint>
#include <memory>
#include <mutex>
#include <string>
#include <vector>
class Branches2 : public std::vector<BranchGroup>
class Branches : public std::vector<BranchGroup>
{
public:
Branches2(const toml::value &);
};
class Branches final : public ToFromString
{
public:
class Impl final : public ToFromString, public Branch::Vector
{
public:
typedef std::shared_ptr<Impl> Ptr;
typedef std::shared_ptr<const Impl> CPtr;
public:
Impl(const uint64_t &default_minfreespace_);
public:
int from_string(const std::string &str) final;
std::string to_string(void) const final;
public:
const uint64_t& minfreespace(void) const;
void to_paths(StrVec &strvec) const;
public:
Impl& operator=(Impl &impl_);
Impl& operator=(Impl &&impl_);
private:
const uint64_t &_default_minfreespace;
};
public:
typedef Branches::Impl::Ptr Ptr;
typedef Branches::Impl::CPtr CPtr;
public:
Branches(const uint64_t &default_minfreespace_)
: _impl(std::make_shared<Impl>(default_minfreespace_))
{}
public:
int from_string(const std::string &str) final;
std::string to_string(void) const final;
public:
operator CPtr() const { std::lock_guard<std::mutex> lg(_mutex); return _impl; }
CPtr operator->() const { std::lock_guard<std::mutex> lg(_mutex); return _impl; }
private:
mutable std::mutex _mutex;
Ptr _impl;
};
class SrcMounts : public ToFromString
{
public:
SrcMounts(Branches &b_);
public:
int from_string(const std::string &str) final;
std::string to_string(void) const final;
private:
Branches &_branches;
Branches(const toml::value &);
};

9
src/fs_clonepath_branches.hpp

@ -19,12 +19,13 @@
#pragma once
#include "branches.hpp"
#include "ghc/filesystem.hpp"
#include "fs_path.hpp"
namespace fs
{
int
clonepath_as_root(const Branches2 &branches_,
const ghc::filesystem::path &to_,
const ghc::filesystem::path &relative_);
clonepath_as_root(const Branches &branches_,
const gfs::path &to_,
const gfs::path &relative_);
}

2
src/fuse_access_policy_ff.hpp

@ -35,6 +35,6 @@ namespace FUSE::ACCESS::POLICY
const int mode) final;
private:
Branches2 _branches;
Branches _branches;
};
}

2
src/fuse_chmod_policy_all.hpp

@ -35,6 +35,6 @@ namespace FUSE::CHMOD::POLICY
const mode_t mode) final;
private:
Branches2 _branches;
Branches _branches;
};
}

2
src/fuse_chown_policy_all.hpp

@ -36,6 +36,6 @@ namespace FUSE::CHOWN::POLICY
const gid_t gid) final;
private:
Branches2 _branches;
Branches _branches;
};
}

2
src/fuse_create_policy_epff.hpp

@ -39,6 +39,6 @@ namespace FUSE::CREATE::POLICY
fuse_file_info_t *ffi) final;
private:
Branches2 _branches;
Branches _branches;
};
}

2
src/fuse_getattr_policy_aggregate.hpp

@ -40,6 +40,6 @@ namespace FUSE::GETATTR::POLICY
private:
Stat::Func _statfunc;
Branches2 _branches;
Branches _branches;
};
}

2
src/fuse_getattr_policy_check_ff.hpp

@ -40,6 +40,6 @@ namespace FUSE::GETATTR::POLICY
private:
Stat::Func _statfunc;
Branches2 _branches;
Branches _branches;
};
}

2
src/fuse_getattr_policy_ff.hpp

@ -40,6 +40,6 @@ namespace FUSE::GETATTR::POLICY
private:
Stat::Func _statfunc;
Branches2 _branches;
Branches _branches;
};
}

2
src/fuse_getattr_policy_newest.hpp

@ -40,6 +40,6 @@ namespace FUSE::GETATTR::POLICY
private:
Stat::Func _statfunc;
Branches2 _branches;
Branches _branches;
};
}

2
src/fuse_getxattr_policy_ff.hpp

@ -40,6 +40,6 @@ namespace FUSE::GETXATTR::POLICY
size_t count) final;
private:
Branches2 _branches;
Branches _branches;
};
}

2
src/fuse_ioctl_policy_all.hpp

@ -38,6 +38,6 @@ namespace FUSE::IOCTL::POLICY
uint32_t *out_bufsz) final;
private:
Branches2 _branches;
Branches _branches;
};
}

2
src/fuse_listxattr_policy_ff.hpp

@ -38,6 +38,6 @@ namespace FUSE::LISTXATTR::POLICY
const size_t size) final;
private:
Branches2 _branches;
Branches _branches;
};
}

2
src/fuse_mkdir_policy_epff.hpp

@ -36,6 +36,6 @@ namespace FUSE::MKDIR::POLICY
const mode_t umask) final;
private:
Branches2 _branches;
Branches _branches;
};
}

2
src/fuse_mkdir_policy_ff.hpp

@ -36,6 +36,6 @@ namespace FUSE::MKDIR::POLICY
const mode_t umask) final;
private:
Branches2 _branches;
Branches _branches;
};
}

2
src/fuse_mknod_policy_epff.hpp

@ -37,6 +37,6 @@ namespace FUSE::MKNOD::POLICY
const dev_t dev) final;
private:
Branches2 _branches;
Branches _branches;
};
}

2
src/fuse_mknod_policy_ff.hpp

@ -37,6 +37,6 @@ namespace FUSE::MKNOD::POLICY
const dev_t dev) final;
private:
Branches2 _branches;
Branches _branches;
};
}

2
src/fuse_open_policy_ff.hpp

@ -37,6 +37,6 @@ namespace FUSE::OPEN::POLICY
fuse_file_info_t *ffi) final;
private:
Branches2 _branches;
Branches _branches;
};
}

2
src/fuse_readdir_policy_posix.hpp

@ -37,6 +37,6 @@ namespace FUSE::READDIR::POLICY
fuse_dirents_t *buf) final;
private:
Branches2 _branches;
Branches _branches;
};
}

2
src/fuse_readlink_policy_ff.hpp

@ -38,6 +38,6 @@ namespace FUSE::READLINK::POLICY
const size_t bufsiz) final;
private:
Branches2 _branches;
Branches _branches;
};
}

2
src/fuse_symlink_policy_ff.hpp

@ -37,6 +37,6 @@ namespace FUSE::SYMLINK::POLICY
fuse_timeouts_t *timeouts) final;
private:
Branches2 _branches;
Branches _branches;
};
}

2
src/fuse_truncate_policy_all.hpp

@ -35,6 +35,6 @@ namespace FUSE::TRUNCATE::POLICY
const off_t length) final;
private:
Branches2 _branches;
Branches _branches;
};
}

2
src/fuse_utimens_policy_all.hpp

@ -35,6 +35,6 @@ namespace FUSE::UTIMENS::POLICY
const timespec ts[2]) final;
private:
Branches2 _branches;
Branches _branches;
};
}

194
src/policy.hpp

@ -1,194 +0,0 @@
/*
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "branches.hpp"
#include "strvec.hpp"
#include <string>
namespace Policy
{
class ActionImpl
{
public:
ActionImpl(const std::string &name_)
: name(name_)
{
}
public:
std::string name;
virtual int operator()(const Branches::CPtr&,const char*,StrVec*) const = 0;
};
class Action
{
public:
Action(ActionImpl *impl_)
: impl(impl_)
{}
Action&
operator=(ActionImpl *impl_)
{
impl = impl_;
return *this;
}
const
std::string&
name(void) const
{
return impl->name;
}
int
operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return (*impl)(branches_,fusepath_,paths_);
}
int
operator()(const Branches::CPtr &branches_,
const std::string &fusepath_,
StrVec *paths_) const
{
return (*impl)(branches_,fusepath_.c_str(),paths_);
}
private:
ActionImpl *impl;
};
class CreateImpl
{
public:
CreateImpl(const std::string &name_)
: name(name_)
{
}
public:
std::string name;
virtual int operator()(const Branches::CPtr&,const char*,StrVec*) const = 0;
virtual bool path_preserving(void) const = 0;
};
class Create
{
public:
Create(CreateImpl *impl_)
: impl(impl_)
{}
Create&
operator=(CreateImpl *impl_)
{
impl = impl_;
return *this;
}
const
std::string&
name(void) const
{
return impl->name;
}
bool
path_preserving(void) const
{
return impl->path_preserving();
}
int
operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return (*impl)(branches_,fusepath_,paths_);
}
int
operator()(const Branches::CPtr &branches_,
const std::string &fusepath_,
StrVec *paths_) const
{
return (*impl)(branches_,fusepath_.c_str(),paths_);
}
private:
CreateImpl *impl;
};
class SearchImpl
{
public:
SearchImpl(const std::string &name_)
: name(name_)
{
}
public:
std::string name;
virtual int operator()(const Branches::CPtr&,const char*,StrVec*) const = 0;
};
class Search
{
public:
Search(SearchImpl *impl_)
: impl(impl_)
{}
Search&
operator=(SearchImpl *impl_)
{
impl = impl_;
return *this;
}
const
std::string&
name(void) const
{
return impl->name;
}
int
operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return (*impl)(branches_,fusepath_,paths_);
}
int
operator()(const Branches::CPtr &branches_,
const std::string &fusepath_,
StrVec *paths_) const
{
return (*impl)(branches_,fusepath_.c_str(),paths_);
}
private:
SearchImpl *impl;
};
}

86
src/policy_all.cpp

@ -1,86 +0,0 @@
/*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "errno.hpp"
#include "fs_exists.hpp"
#include "fs_info.hpp"
#include "fs_path.hpp"
#include "policy.hpp"
#include "policies.hpp"
#include "policy_error.hpp"
#include "strvec.hpp"
#include <string>
using std::string;
namespace all
{
static
int
create(const Branches::CPtr &branches_,
StrVec *paths_)
{
int rv;
int error;
fs::info_t info;
error = ENOENT;
for(auto &branch : *branches_)
{
if(branch.ro_or_nc())
error_and_continue(error,EROFS);
rv = fs::info(branch.path,&info);
if(rv == -1)
error_and_continue(error,ENOENT);
if(info.readonly)
error_and_continue(error,EROFS);
if(info.spaceavail < branch.minfreespace())
error_and_continue(error,ENOSPC);
paths_->push_back(branch.path);
}
if(paths_->empty())
return (errno=error,-1);
return 0;
}
}
int
Policy::All::Action::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return Policies::Action::epall(branches_,fusepath_,paths_);
}
int
Policy::All::Create::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return ::all::create(branches_,paths_);
}
int
Policy::All::Search::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return Policies::Search::epall(branches_,fusepath_,paths_);
}

61
src/policy_all.hpp

@ -1,61 +0,0 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "policy.hpp"
namespace Policy
{
namespace All
{
class Action final : public Policy::ActionImpl
{
public:
Action()
: Policy::ActionImpl("all")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
class Create final : public Policy::CreateImpl
{
public:
Create()
: Policy::CreateImpl("all")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
bool path_preserving(void) const final { return false; }
};
class Search final : public Policy::SearchImpl
{
public:
Search()
: Policy::SearchImpl("all")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
}
}

131
src/policy_cache.cpp

@ -1,131 +0,0 @@
#include "policy_cache.hpp"
#include <cstdlib>
#include <map>
#include <string>
#include <time.h>
using std::map;
using std::string;
static const uint64_t DEFAULT_TIMEOUT = 0;
namespace l
{
static
uint64_t
get_time(void)
{
uint64_t rv;
rv = ::time(NULL);
return rv;
}
}
PolicyCache::Value::Value()
: time(0),
paths()
{
}
PolicyCache::PolicyCache(void)
: timeout(DEFAULT_TIMEOUT)
{
pthread_mutex_init(&_lock,NULL);
}
void
PolicyCache::erase(const char *fusepath_)
{
if(timeout == 0)
return;
pthread_mutex_lock(&_lock);
_cache.erase(fusepath_);
pthread_mutex_unlock(&_lock);
}
void
PolicyCache::cleanup(const int prob_)
{
uint64_t now;
map<string,Value>::iterator i;
if(timeout == 0)
return;
if(rand() % prob_)
return;
now = l::get_time();
pthread_mutex_lock(&_lock);
i = _cache.begin();
while(i != _cache.end())
{
if((now - i->second.time) >= timeout)
_cache.erase(i++);
else
++i;
}
pthread_mutex_unlock(&_lock);
}
void
PolicyCache::clear(void)
{
pthread_mutex_lock(&_lock);
_cache.clear();
pthread_mutex_unlock(&_lock);
}
int
PolicyCache::operator()(const Policy::Search &policy_,
const Branches &branches_,
const char *fusepath_,
StrVec *paths_)
{
int rv;
Value *v;
uint64_t now;
if(timeout == 0)
return policy_(branches_,fusepath_,paths_);
now = l::get_time();
pthread_mutex_lock(&_lock);
v = &_cache[fusepath_];
if((now - v->time) >= timeout)
{
pthread_mutex_unlock(&_lock);
rv = policy_(branches_,fusepath_,paths_);
if(rv == -1)
return -1;
pthread_mutex_lock(&_lock);
v->time = now;
v->paths = *paths_;
}
else
{
*paths_ = v->paths;
}
pthread_mutex_unlock(&_lock);
return 0;
}

62
src/policy_cache.hpp

@ -1,62 +0,0 @@
/*
ISC License
Copyright (c) 2019, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "policy.hpp"
#include "strvec.hpp"
#include <cstdint>
#include <string>
#include <map>
#include <pthread.h>
class PolicyCache
{
public:
struct Value
{
Value();
uint64_t time;
StrVec paths;
};
public:
PolicyCache(void);
public:
void erase(const char *fusepath);
void cleanup(const int prob = 1);
void clear(void);
public:
int operator()(const Policy::Search &policy,
const Branches &branches,
const char *fusepath,
StrVec *paths);
public:
uint64_t timeout;
private:
pthread_mutex_t _lock;
std::map<std::string,Value> _cache;
};

143
src/policy_epall.cpp

@ -1,143 +0,0 @@
/*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "errno.hpp"
#include "fs_exists.hpp"
#include "fs_info.hpp"
#include "fs_path.hpp"
#include "fs_statvfs_cache.hpp"
#include "policy.hpp"
#include "policy_epall.hpp"
#include "policy_error.hpp"
#include "strvec.hpp"
#include <string>
using std::string;
namespace epall
{
static
int
create(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_)
{
int rv;
int error;
fs::info_t info;
error = ENOENT;
for(auto &branch : *branches_)
{
if(branch.ro_or_nc())
error_and_continue(error,EROFS);
if(!fs::exists(branch.path,fusepath_))
error_and_continue(error,ENOENT);
rv = fs::info(branch.path,&info);
if(rv == -1)
error_and_continue(error,ENOENT);
if(info.readonly)
error_and_continue(error,EROFS);
if(info.spaceavail < branch.minfreespace())
error_and_continue(error,ENOSPC);
paths_->push_back(branch.path);
}
if(paths_->empty())
return (errno=error,-1);
return 0;
}
static
int
action(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_)
{
int rv;
int error;
bool readonly;
error = ENOENT;
for(auto &branch : *branches_)
{
if(branch.ro())
error_and_continue(error,EROFS);
if(!fs::exists(branch.path,fusepath_))
error_and_continue(error,ENOENT);
rv = fs::statvfs_cache_readonly(branch.path,&readonly);
if(rv == -1)
error_and_continue(error,ENOENT);
if(readonly)
error_and_continue(error,EROFS);
paths_->push_back(branch.path);
}
if(paths_->empty())
return (errno=error,-1);
return 0;
}
static
int
search(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_)
{
for(auto &branch : *branches_)
{
if(!fs::exists(branch.path,fusepath_))
continue;
paths_->push_back(branch.path);
}
if(paths_->empty())
return (errno=ENOENT,-1);
return 0;
}
}
int
Policy::EPAll::Action::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return ::epall::action(branches_,fusepath_,paths_);
}
int
Policy::EPAll::Create::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return ::epall::create(branches_,fusepath_,paths_);
}
int
Policy::EPAll::Search::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return ::epall::search(branches_,fusepath_,paths_);
}

64
src/policy_epall.hpp

@ -1,64 +0,0 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "policy.hpp"
namespace Policy
{
namespace EPAll
{
class Action final : public Policy::ActionImpl
{
public:
Action()
: Policy::ActionImpl("epall")
{
}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
class Create final : public Policy::CreateImpl
{
public:
Create()
: Policy::CreateImpl("epall")
{
}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
bool path_preserving(void) const final { return true; }
};
class Search final : public Policy::SearchImpl
{
public:
Search()
: Policy::SearchImpl("epall")
{
}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
}
}

142
src/policy_epff.cpp

@ -1,142 +0,0 @@
/*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "branches.hpp"
#include "errno.hpp"
#include "fs_exists.hpp"
#include "fs_info.hpp"
#include "fs_path.hpp"
#include "fs_statvfs_cache.hpp"
#include "policy.hpp"
#include "policy_epff.hpp"
#include "policy_error.hpp"
#include "rwlock.hpp"
#include <string>
#include <vector>
using std::string;
using std::vector;
namespace epff
{
static
int
create(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_)
{
int rv;
int error;
fs::info_t info;
error = ENOENT;
for(auto &branch : *branches_)
{
if(branch.ro_or_nc())
error_and_continue(error,EROFS);
if(!fs::exists(branch.path,fusepath_))
error_and_continue(error,ENOENT);
rv = fs::info(branch.path,&info);
if(rv == -1)
error_and_continue(error,ENOENT);
if(info.readonly)
error_and_continue(error,EROFS);
if(info.spaceavail < branch.minfreespace())
error_and_continue(error,ENOSPC);
paths_->push_back(branch.path);
return 0;
}
return (errno=error,-1);
}
static
int
action(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_)
{
int rv;
int error;
bool readonly;
error = ENOENT;
for(auto &branch : *branches_)
{
if(branch.ro())
error_and_continue(error,EROFS);
if(!fs::exists(branch.path,fusepath_))
error_and_continue(error,ENOENT);
rv = fs::statvfs_cache_readonly(branch.path,&readonly);
if(rv == -1)
error_and_continue(error,ENOENT);
if(readonly)
error_and_continue(error,EROFS);
paths_->push_back(branch.path);
return 0;
}
return (errno=error,-1);
}
static
int
search(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_)
{
for(auto &branch : *branches_)
{
if(!fs::exists(branch.path,fusepath_))
continue;
paths_->push_back(branch.path);
return 0;
}
return (errno=ENOENT,-1);
}
}
int
Policy::EPFF::Action::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return ::epff::action(branches_,fusepath_,paths_);
}
int
Policy::EPFF::Create::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return ::epff::create(branches_,fusepath_,paths_);
}
int
Policy::EPFF::Search::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return ::epff::search(branches_,fusepath_,paths_);
}

61
src/policy_epff.hpp

@ -1,61 +0,0 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "policy.hpp"
namespace Policy
{
namespace EPFF
{
class Action final : public Policy::ActionImpl
{
public:
Action()
: Policy::ActionImpl("epff")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
class Create final : public Policy::CreateImpl
{
public:
Create()
: Policy::CreateImpl("epff")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
bool path_preserving(void) const final { return true; }
};
class Search final : public Policy::SearchImpl
{
public:
Search()
: Policy::SearchImpl("epff")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
}
}

178
src/policy_eplfs.cpp

@ -1,178 +0,0 @@
/*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "errno.hpp"
#include "fs_exists.hpp"
#include "fs_info.hpp"
#include "fs_path.hpp"
#include "fs_statvfs_cache.hpp"
#include "policies.hpp"
#include "policy.hpp"
#include "policy_eplfs.hpp"
#include "policy_error.hpp"
#include <limits>
#include <string>
#include <vector>
using std::string;
using std::vector;
namespace eplfs
{
static
int
create(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_)
{
int rv;
int error;
uint64_t eplfs;
fs::info_t info;
const string *basepath;
error = ENOENT;
eplfs = std::numeric_limits<uint64_t>::max();
basepath = NULL;
for(const auto &branch : *branches_)
{
if(branch.ro_or_nc())
error_and_continue(error,EROFS);
if(!fs::exists(branch.path,fusepath_))
error_and_continue(error,ENOENT);
rv = fs::info(branch.path,&info);
if(rv == -1)
error_and_continue(error,ENOENT);
if(info.readonly)
error_and_continue(error,EROFS);
if(info.spaceavail < branch.minfreespace())
error_and_continue(error,ENOSPC);
if(info.spaceavail > eplfs)
continue;
eplfs = info.spaceavail;
basepath = &branch.path;
}
if(basepath == NULL)
return (errno=error,-1);
paths_->push_back(*basepath);
return 0;
}
static
int
action(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_)
{
int rv;
int error;
uint64_t eplfs;
fs::info_t info;
const string *basepath;
error = ENOENT;
eplfs = std::numeric_limits<uint64_t>::max();
basepath = NULL;
for(const auto &branch : *branches_)
{
if(branch.ro())
error_and_continue(error,EROFS);
if(!fs::exists(branch.path,fusepath_))
error_and_continue(error,ENOENT);
rv = fs::info(branch.path,&info);
if(rv == -1)
error_and_continue(error,ENOENT);
if(info.readonly)
error_and_continue(error,EROFS);
if(info.spaceavail > eplfs)
continue;
eplfs = info.spaceavail;
basepath = &branch.path;
}
if(basepath == NULL)
return (errno=error,-1);
paths_->push_back(*basepath);
return 0;
}
static
int
search(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_)
{
int rv;
uint64_t eplfs;
uint64_t spaceavail;
const string *basepath;
eplfs = std::numeric_limits<uint64_t>::max();
basepath = NULL;
for(const auto &branch : *branches_)
{
if(!fs::exists(branch.path,fusepath_))
continue;
rv = fs::statvfs_cache_spaceavail(branch.path,&spaceavail);
if(rv == -1)
continue;
if(spaceavail > eplfs)
continue;
eplfs = spaceavail;
basepath = &branch.path;
}
if(basepath == NULL)
return (errno=ENOENT,-1);
paths_->push_back(*basepath);
return 0;
}
}
int
Policy::EPLFS::Action::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return ::eplfs::action(branches_,fusepath_,paths_);
}
int
Policy::EPLFS::Create::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return ::eplfs::create(branches_,fusepath_,paths_);
}
int
Policy::EPLFS::Search::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return ::eplfs::search(branches_,fusepath_,paths_);
}

61
src/policy_eplfs.hpp

@ -1,61 +0,0 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "policy.hpp"
namespace Policy
{
namespace EPLFS
{
class Action final : public Policy::ActionImpl
{
public:
Action()
: Policy::ActionImpl("eplfs")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
class Create final : public Policy::CreateImpl
{
public:
Create()
: Policy::CreateImpl("eplfs")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
bool path_preserving(void) const final { return true; }
};
class Search final : public Policy::SearchImpl
{
public:
Search()
: Policy::SearchImpl("eplfs")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
}
}

176
src/policy_eplus.cpp

@ -1,176 +0,0 @@
/*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "errno.hpp"
#include "fs_exists.hpp"
#include "fs_info.hpp"
#include "fs_path.hpp"
#include "fs_statvfs_cache.hpp"
#include "policy.hpp"
#include "policy_eplus.hpp"
#include "policy_error.hpp"
#include "rwlock.hpp"
#include <limits>
#include <string>
using std::string;
namespace eplus
{
static
int
create(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_)
{
int rv;
int error;
uint64_t eplus;
fs::info_t info;
const string *basepath;
error = ENOENT;
eplus = std::numeric_limits<uint64_t>::max();
basepath = NULL;
for(auto &branch : *branches_)
{
if(branch.ro_or_nc())
error_and_continue(error,EROFS);
if(!fs::exists(branch.path,fusepath_))
error_and_continue(error,ENOENT);
rv = fs::info(branch.path,&info);
if(rv == -1)
error_and_continue(error,ENOENT);
if(info.readonly)
error_and_continue(error,EROFS);
if(info.spaceavail < branch.minfreespace())
error_and_continue(error,ENOSPC);
if(info.spaceused >= eplus)
continue;
eplus = info.spaceused;
basepath = &branch.path;
}
if(basepath == NULL)
return (errno=error,-1);
paths_->push_back(*basepath);
return 0;
}
static
int
action(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_)
{
int rv;
int error;
uint64_t eplus;
fs::info_t info;
const string *basepath;
error = ENOENT;
eplus = std::numeric_limits<uint64_t>::max();
basepath = NULL;
for(auto &branch : *branches_)
{
if(branch.ro())
error_and_continue(error,EROFS);
if(!fs::exists(branch.path,fusepath_))
error_and_continue(error,ENOENT);
rv = fs::info(branch.path,&info);
if(rv == -1)
error_and_continue(error,ENOENT);
if(info.readonly)
error_and_continue(error,EROFS);
if(info.spaceused >= eplus)
continue;
eplus = info.spaceused;
basepath = &branch.path;
}
if(basepath == NULL)
return (errno=error,-1);
paths_->push_back(*basepath);
return 0;
}
static
int
search(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_)
{
int rv;
uint64_t eplus;
uint64_t spaceused;
const string *basepath;
eplus = 0;
basepath = NULL;
for(auto &branch : *branches_)
{
if(!fs::exists(branch.path,fusepath_))
continue;
rv = fs::statvfs_cache_spaceused(branch.path,&spaceused);
if(rv == -1)
continue;
if(spaceused >= eplus)
continue;
eplus = spaceused;
basepath = &branch.path;
}
if(basepath == NULL)
return (errno=ENOENT,-1);
paths_->push_back(*basepath);
return 0;
}
}
int
Policy::EPLUS::Action::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return ::eplus::action(branches_,fusepath_,paths_);
}
int
Policy::EPLUS::Create::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return ::eplus::create(branches_,fusepath_,paths_);
}
int
Policy::EPLUS::Search::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return ::eplus::search(branches_,fusepath_,paths_);
}

61
src/policy_eplus.hpp

@ -1,61 +0,0 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "policy.hpp"
namespace Policy
{
namespace EPLUS
{
class Action final : public Policy::ActionImpl
{
public:
Action()
: Policy::ActionImpl("eplus")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
class Create final : public Policy::CreateImpl
{
public:
Create()
: Policy::CreateImpl("eplus")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
bool path_preserving(void) const final { return true; }
};
class Search final : public Policy::SearchImpl
{
public:
Search()
: Policy::SearchImpl("eplus")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
}
}

177
src/policy_epmfs.cpp

@ -1,177 +0,0 @@
/*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "errno.hpp"
#include "fs_exists.hpp"
#include "fs_info.hpp"
#include "fs_path.hpp"
#include "fs_statvfs_cache.hpp"
#include "policy.hpp"
#include "policy_epmfs.hpp"
#include "policy_error.hpp"
#include <limits>
#include <string>
using std::string;
namespace epmfs
{
static
int
create(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_)
{
int rv;
int error;
uint64_t epmfs;
fs::info_t info;
const string *basepath;
error = ENOENT;
epmfs = std::numeric_limits<uint64_t>::min();
basepath = NULL;
for(const auto &branch : *branches_)
{
if(branch.ro_or_nc())
error_and_continue(error,EROFS);
if(!fs::exists(branch.path,fusepath_))
error_and_continue(error,ENOENT);
rv = fs::info(branch.path,&info);
if(rv == -1)
error_and_continue(error,ENOENT);
if(info.readonly)
error_and_continue(error,EROFS);
if(info.spaceavail < branch.minfreespace())
error_and_continue(error,ENOSPC);
if(info.spaceavail < epmfs)
continue;
epmfs = info.spaceavail;
basepath = &branch.path;
}
if(basepath == NULL)
return (errno=error,-1);
paths_->push_back(*basepath);
return 0;
}
static
int
action(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_)
{
int rv;
int error;
uint64_t epmfs;
fs::info_t info;
const string *basepath;
error = ENOENT;
epmfs = std::numeric_limits<uint64_t>::min();
basepath = NULL;
for(const auto &branch : *branches_)
{
if(branch.ro())
error_and_continue(error,EROFS);
if(!fs::exists(branch.path,fusepath_))
error_and_continue(error,ENOENT);
rv = fs::info(branch.path,&info);
if(rv == -1)
error_and_continue(error,ENOENT);
if(info.readonly)
error_and_continue(error,EROFS);
if(info.spaceavail < epmfs)
continue;
epmfs = info.spaceavail;
basepath = &branch.path;
}
if(basepath == NULL)
return (errno=error,-1);
paths_->push_back(*basepath);
return 0;
}
static
int
search(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_)
{
int rv;
uint64_t epmfs;
uint64_t spaceavail;
const string *basepath;
epmfs = 0;
basepath = NULL;
for(const auto &branch : *branches_)
{
if(!fs::exists(branch.path,fusepath_))
continue;
rv = fs::statvfs_cache_spaceavail(branch.path,&spaceavail);
if(rv == -1)
continue;
if(spaceavail < epmfs)
continue;
epmfs = spaceavail;
basepath = &branch.path;
}
if(basepath == NULL)
return (errno=ENOENT,-1);
paths_->push_back(*basepath);
return 0;
}
}
int
Policy::EPMFS::Action::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return ::epmfs::action(branches_,fusepath_,paths_);
}
int
Policy::EPMFS::Create::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return ::epmfs::create(branches_,fusepath_,paths_);
}
int
Policy::EPMFS::Search::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return ::epmfs::search(branches_,fusepath_,paths_);
}

64
src/policy_epmfs.hpp

@ -1,64 +0,0 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "policy.hpp"
namespace Policy
{
namespace EPMFS
{
class Action final : public Policy::ActionImpl
{
public:
Action()
: Policy::ActionImpl("epmfs")
{
}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
class Create final : public Policy::CreateImpl
{
public:
Create()
: Policy::CreateImpl("epmfs")
{
}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
bool path_preserving(void) const final { return true; }
};
class Search final : public Policy::SearchImpl
{
public:
Search()
: Policy::SearchImpl("epmfs")
{
}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
}
}

262
src/policy_eppfrd.cpp

@ -1,262 +0,0 @@
/*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "errno.hpp"
#include "fs_exists.hpp"
#include "fs_info.hpp"
#include "fs_path.hpp"
#include "fs_statvfs_cache.hpp"
#include "policy.hpp"
#include "policy_eppfrd.hpp"
#include "policy_error.hpp"
#include "rnd.hpp"
#include "rwlock.hpp"
#include "strvec.hpp"
#include <string>
#include <vector>
using std::string;
using std::vector;
struct BranchInfo
{
uint64_t spaceavail;
const string *basepath;
};
typedef vector<BranchInfo> BranchInfoVec;
namespace eppfrd
{
static
int
get_branchinfo_create(const Branches::CPtr &branches_,
const char *fusepath_,
BranchInfoVec *branchinfo_,
uint64_t *sum_)
{
int rv;
int error;
BranchInfo bi;
fs::info_t info;
*sum_ = 0;
error = ENOENT;
for(auto &branch : *branches_)
{
if(branch.ro_or_nc())
error_and_continue(error,EROFS);
if(!fs::exists(branch.path,fusepath_))
error_and_continue(error,ENOENT);
rv = fs::info(branch.path,&info);
if(rv == -1)
error_and_continue(error,ENOENT);
if(info.readonly)
error_and_continue(error,EROFS);
if(info.spaceavail < branch.minfreespace())
error_and_continue(error,ENOSPC);
*sum_ += info.spaceavail;
bi.spaceavail = info.spaceavail;
bi.basepath = &branch.path;
branchinfo_->push_back(bi);
}
return error;
}
static
int
get_branchinfo_action(const Branches::CPtr &branches_,
const char *fusepath_,
BranchInfoVec *branchinfo_,
uint64_t *sum_)
{
int rv;
int error;
BranchInfo bi;
fs::info_t info;
*sum_ = 0;
error = ENOENT;
for(auto &branch : *branches_)
{
if(branch.ro())
error_and_continue(error,EROFS);
if(!fs::exists(branch.path,fusepath_))
error_and_continue(error,ENOENT);
rv = fs::info(branch.path,&info);
if(rv == -1)
error_and_continue(error,ENOENT);
if(info.readonly)
error_and_continue(error,EROFS);
*sum_ += info.spaceavail;
bi.spaceavail = info.spaceavail;
bi.basepath = &branch.path;
branchinfo_->push_back(bi);
}
return error;
}
static
int
get_branchinfo_search(const Branches::CPtr &branches_,
const char *fusepath_,
BranchInfoVec *branchinfo_,
uint64_t *sum_)
{
int rv;
BranchInfo bi;
uint64_t spaceavail;
*sum_ = 0;
for(auto &branch : *branches_)
{
if(!fs::exists(branch.path,fusepath_))
continue;
rv = fs::statvfs_cache_spaceavail(branch.path,&spaceavail);
if(rv == -1)
continue;
*sum_ += spaceavail;
bi.spaceavail = spaceavail;
bi.basepath = &branch.path;
branchinfo_->push_back(bi);
}
return ENOENT;
}
static
const
string*
get_branch(const BranchInfoVec &branchinfo_,
const uint64_t sum_)
{
uint64_t idx;
uint64_t threshold;
if(sum_ == 0)
return NULL;
idx = 0;
threshold = RND::rand64(sum_);
for(size_t i = 0; i < branchinfo_.size(); i++)
{
idx += branchinfo_[i].spaceavail;
if(idx < threshold)
continue;
return branchinfo_[i].basepath;
}
return NULL;
}
static
int
create(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_)
{
int error;
uint64_t sum;
const string *basepath;
BranchInfoVec branchinfo;
error = eppfrd::get_branchinfo_create(branches_,fusepath_,&branchinfo,&sum);
basepath = eppfrd::get_branch(branchinfo,sum);
if(basepath == NULL)
return (errno=error,-1);
paths_->push_back(*basepath);
return 0;
}
static
int
action(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_)
{
int error;
uint64_t sum;
const string *basepath;
BranchInfoVec branchinfo;
error = eppfrd::get_branchinfo_action(branches_,fusepath_,&branchinfo,&sum);
basepath = eppfrd::get_branch(branchinfo,sum);
if(basepath == NULL)
return (errno=error,-1);
paths_->push_back(*basepath);
return 0;
}
static
int
search(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_)
{
int error;
uint64_t sum;
const string *basepath;
BranchInfoVec branchinfo;
error = eppfrd::get_branchinfo_search(branches_,fusepath_,&branchinfo,&sum);
basepath = eppfrd::get_branch(branchinfo,sum);
if(basepath == NULL)
return (errno=error,-1);
paths_->push_back(*basepath);
return 0;
}
}
int
Policy::EPPFRD::Action::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return ::eppfrd::action(branches_,fusepath_,paths_);
}
int
Policy::EPPFRD::Create::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return ::eppfrd::create(branches_,fusepath_,paths_);
}
int
Policy::EPPFRD::Search::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return ::eppfrd::search(branches_,fusepath_,paths_);
}

61
src/policy_eppfrd.hpp

@ -1,61 +0,0 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "policy.hpp"
namespace Policy
{
namespace EPPFRD
{
class Action final : public Policy::ActionImpl
{
public:
Action()
: Policy::ActionImpl("eppfrd")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
class Create final : public Policy::CreateImpl
{
public:
Create()
: Policy::CreateImpl("eppfrd")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
bool path_preserving(void) const final { return true; }
};
class Search final : public Policy::SearchImpl
{
public:
Search()
: Policy::SearchImpl("eppfrd")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
}
}

73
src/policy_eprand.cpp

@ -1,73 +0,0 @@
/*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "errno.hpp"
#include "policies.hpp"
#include "policy.hpp"
#include "policy_eprand.hpp"
#include <algorithm>
int
Policy::EPRand::Action::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
int rv;
rv = Policies::Action::epall(branches_,fusepath_,paths_);
if(rv == 0)
{
std::random_shuffle(paths_->begin(),paths_->end());
paths_->resize(1);
}
return rv;
}
int
Policy::EPRand::Create::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
int rv;
rv = Policies::Create::epall(branches_,fusepath_,paths_);
if(rv == 0)
{
std::random_shuffle(paths_->begin(),paths_->end());
paths_->resize(1);
}
return rv;
}
int
Policy::EPRand::Search::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
int rv;
rv = Policies::Search::epall(branches_,fusepath_,paths_);
if(rv == 0)
{
std::random_shuffle(paths_->begin(),paths_->end());
paths_->resize(1);
}
return rv;
}

61
src/policy_eprand.hpp

@ -1,61 +0,0 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "policy.hpp"
namespace Policy
{
namespace EPRand
{
class Action final : public Policy::ActionImpl
{
public:
Action()
: Policy::ActionImpl("eprand")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
class Create final : public Policy::CreateImpl
{
public:
Create()
: Policy::CreateImpl("eprand")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
bool path_preserving(void) const final { return true; }
};
class Search final : public Policy::SearchImpl
{
public:
Search()
: Policy::SearchImpl("eprand")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
}
}

48
src/policy_erofs.cpp

@ -1,48 +0,0 @@
/*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "errno.hpp"
#include "policy.hpp"
#include "policy_erofs.hpp"
#include <string>
using std::string;
int
Policy::ERoFS::Action::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return (errno=EROFS,-1);
}
int
Policy::ERoFS::Create::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return (errno=EROFS,-1);
}
int
Policy::ERoFS::Search::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return (errno=EROFS,-1);
}

61
src/policy_erofs.hpp

@ -1,61 +0,0 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "policy.hpp"
namespace Policy
{
namespace ERoFS
{
class Action final : public Policy::ActionImpl
{
public:
Action()
: Policy::ActionImpl("erofs")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
class Create final : public Policy::CreateImpl
{
public:
Create()
: Policy::CreateImpl("erofs")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
bool path_preserving(void) const final { return false; }
};
class Search final : public Policy::SearchImpl
{
public:
Search()
: Policy::SearchImpl("erofs")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
}
}

51
src/policy_error.hpp

@ -1,51 +0,0 @@
/*
ISC License
Copyright (c) 2018, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#define error_and_continue(CUR,ERR) \
{ \
policy::calc_error(CUR,ERR); \
continue; \
}
namespace policy
{
static
inline
void
calc_error(int &cur_,
int err_)
{
switch(cur_)
{
default:
case ENOENT:
cur_ = err_;
break;
case ENOSPC:
if(err_ != ENOENT)
cur_ = err_;
break;
case EROFS:
if((err_ != ENOENT) && (err_ != ENOSPC))
cur_ = err_;
break;
}
}
}

85
src/policy_ff.cpp

@ -1,85 +0,0 @@
/*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "errno.hpp"
#include "fs_exists.hpp"
#include "fs_info.hpp"
#include "fs_path.hpp"
#include "policies.hpp"
#include "policy.hpp"
#include "policy_error.hpp"
#include "policy_ff.hpp"
#include <string>
using std::string;
namespace ff
{
static
int
create(const Branches::CPtr &branches_,
StrVec *paths_)
{
int rv;
int error;
fs::info_t info;
error = ENOENT;
for(auto &branch : *branches_)
{
if(branch.ro_or_nc())
error_and_continue(error,EROFS);
rv = fs::info(branch.path,&info);
if(rv == -1)
error_and_continue(error,ENOENT);
if(info.readonly)
error_and_continue(error,EROFS);
if(info.spaceavail < branch.minfreespace())
error_and_continue(error,ENOSPC);
paths_->push_back(branch.path);
return 0;
}
return (errno=error,-1);
}
}
int
Policy::FF::Action::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return Policies::Action::epff(branches_,fusepath_,paths_);
}
int
Policy::FF::Create::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return ::ff::create(branches_,paths_);
}
int
Policy::FF::Search::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return Policies::Search::epff(branches_,fusepath_,paths_);
}

61
src/policy_ff.hpp

@ -1,61 +0,0 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "policy.hpp"
namespace Policy
{
namespace FF
{
class Action final : public Policy::ActionImpl
{
public:
Action()
: Policy::ActionImpl("ff")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
class Create final : public Policy::CreateImpl
{
public:
Create()
: Policy::CreateImpl("ff")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
bool path_preserving(void) const final { return false; }
};
class Search final : public Policy::SearchImpl
{
public:
Search()
: Policy::SearchImpl("ff")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
}
}

98
src/policy_lfs.cpp

@ -1,98 +0,0 @@
/*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "errno.hpp"
#include "fs_exists.hpp"
#include "fs_info.hpp"
#include "fs_path.hpp"
#include "policies.hpp"
#include "policy.hpp"
#include "policy_error.hpp"
#include "policy_lfs.hpp"
#include "strvec.hpp"
#include <limits>
#include <string>
using std::string;
namespace lfs
{
static
int
create(const Branches::CPtr &branches_,
StrVec *paths_)
{
int rv;
int error;
uint64_t lfs;
fs::info_t info;
const Branch *branch;
const string *basepath;
error = ENOENT;
lfs = std::numeric_limits<uint64_t>::max();
basepath = NULL;
for(const auto &branch : *branches_)
{
if(branch.ro_or_nc())
error_and_continue(error,EROFS);
rv = fs::info(branch.path,&info);
if(rv == -1)
error_and_continue(error,ENOENT);
if(info.readonly)
error_and_continue(error,EROFS);
if(info.spaceavail < branch.minfreespace())
error_and_continue(error,ENOSPC);
if(info.spaceavail > lfs)
continue;
lfs = info.spaceavail;
basepath = &branch.path;
}
if(basepath == NULL)
return (errno=error,-1);
paths_->push_back(*basepath);
return 0;
}
}
int
Policy::LFS::Action::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return Policies::Action::eplfs(branches_,fusepath_,paths_);
}
int
Policy::LFS::Create::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return ::lfs::create(branches_,paths_);
}
int
Policy::LFS::Search::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return Policies::Search::eplfs(branches_,fusepath_,paths_);
}

61
src/policy_lfs.hpp

@ -1,61 +0,0 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "policy.hpp"
namespace Policy
{
namespace LFS
{
class Action final : public Policy::ActionImpl
{
public:
Action()
: Policy::ActionImpl("lfs")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
class Create final : public Policy::CreateImpl
{
public:
Create()
: Policy::CreateImpl("lfs")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
bool path_preserving() const final { return false; }
};
class Search final : public Policy::SearchImpl
{
public:
Search()
: Policy::SearchImpl("lfs")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
}
}

99
src/policy_lus.cpp

@ -1,99 +0,0 @@
/*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "errno.hpp"
#include "fs_exists.hpp"
#include "fs_info.hpp"
#include "fs_path.hpp"
#include "policies.hpp"
#include "policy.hpp"
#include "policy_error.hpp"
#include "policy_lus.hpp"
#include "strvec.hpp"
#include <limits>
#include <string>
#include <vector>
using std::string;
using std::vector;
namespace lus
{
static
int
create(const Branches::CPtr &branches_,
StrVec *paths_)
{
int rv;
int error;
uint64_t lus;
fs::info_t info;
const string *basepath;
error = ENOENT;
lus = std::numeric_limits<uint64_t>::max();
basepath = NULL;
for(auto &branch : *branches_)
{
if(branch.ro_or_nc())
error_and_continue(error,EROFS);
rv = fs::info(branch.path,&info);
if(rv == -1)
error_and_continue(error,ENOENT);
if(info.readonly)
error_and_continue(error,EROFS);
if(info.spaceavail < branch.minfreespace())
error_and_continue(error,ENOSPC);
if(info.spaceused >= lus)
continue;
lus = info.spaceused;
basepath = &branch.path;
}
if(basepath == NULL)
return (errno=error,-1);
paths_->push_back(*basepath);
return 0;
}
}
int
Policy::LUS::Action::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return Policies::Action::eplus(branches_,fusepath_,paths_);
}
int
Policy::LUS::Create::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return ::lus::create(branches_,paths_);
}
int
Policy::LUS::Search::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return Policies::Search::eplus(branches_,fusepath_,paths_);
}

61
src/policy_lus.hpp

@ -1,61 +0,0 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "policy.hpp"
namespace Policy
{
namespace LUS
{
class Action final : public Policy::ActionImpl
{
public:
Action()
: Policy::ActionImpl("lus")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
class Create final : public Policy::CreateImpl
{
public:
Create()
: Policy::CreateImpl("lus")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
bool path_preserving() const final { return false; }
};
class Search final : public Policy::SearchImpl
{
public:
Search()
: Policy::SearchImpl("lus")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
}
}

94
src/policy_mfs.cpp

@ -1,94 +0,0 @@
/*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "errno.hpp"
#include "fs_exists.hpp"
#include "fs_info.hpp"
#include "fs_path.hpp"
#include "policies.hpp"
#include "policy.hpp"
#include "policy_error.hpp"
#include <string>
using std::string;
namespace mfs
{
static
int
create(const Branches::CPtr &branches_,
StrVec *paths_)
{
int rv;
int error;
uint64_t mfs;
fs::info_t info;
const string *basepath;
error = ENOENT;
mfs = 0;
basepath = NULL;
for(const auto &branch : *branches_)
{
if(branch.ro_or_nc())
error_and_continue(error,EROFS);
rv = fs::info(branch.path,&info);
if(rv == -1)
error_and_continue(error,ENOENT);
if(info.readonly)
error_and_continue(error,EROFS);
if(info.spaceavail < branch.minfreespace())
error_and_continue(error,ENOSPC);
if(info.spaceavail < mfs)
continue;
mfs = info.spaceavail;
basepath = &branch.path;
}
if(basepath == NULL)
return (errno=error,-1);
paths_->push_back(*basepath);
return 0;
}
}
int
Policy::MFS::Action::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return Policies::Action::epmfs(branches_,fusepath_,paths_);
}
int
Policy::MFS::Create::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return ::mfs::create(branches_,paths_);
}
int
Policy::MFS::Search::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return Policies::Search::epmfs(branches_,fusepath_,paths_);
}

61
src/policy_mfs.hpp

@ -1,61 +0,0 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "policy.hpp"
namespace Policy
{
namespace MFS
{
class Action final : public Policy::ActionImpl
{
public:
Action()
: Policy::ActionImpl("mfs")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
class Create final : public Policy::CreateImpl
{
public:
Create()
: Policy::CreateImpl("mfs")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
bool path_preserving() const final { return false; }
};
class Search final : public Policy::SearchImpl
{
public:
Search()
: Policy::SearchImpl("mfs")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
}
}

126
src/policy_msplfs.cpp

@ -1,126 +0,0 @@
/*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "errno.hpp"
#include "fs_exists.hpp"
#include "fs_info.hpp"
#include "fs_path.hpp"
#include "fs_statvfs_cache.hpp"
#include "policies.hpp"
#include "policy.hpp"
#include "policy_error.hpp"
#include "policy_msplfs.hpp"
#include "strvec.hpp"
#include <limits>
#include <string>
using std::string;
namespace msplfs
{
static
const
string*
create_1(const Branches::CPtr &branches_,
const string &fusepath_,
int *err_)
{
int rv;
uint64_t lfs;
fs::info_t info;
const string *basepath;
basepath = NULL;
lfs = std::numeric_limits<uint64_t>::max();
for(const auto &branch : *branches_)
{
if(branch.ro_or_nc())
error_and_continue(*err_,EROFS);
if(!fs::exists(branch.path,fusepath_))
error_and_continue(*err_,ENOENT);
rv = fs::info(branch.path,&info);
if(rv == -1)
error_and_continue(*err_,ENOENT);
if(info.readonly)
error_and_continue(*err_,EROFS);
if(info.spaceavail < branch.minfreespace())
error_and_continue(*err_,ENOSPC);
if(info.spaceavail > lfs)
continue;
lfs = info.spaceavail;
basepath = &branch.path;
}
return basepath;
}
static
int
create(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_)
{
int error;
string fusepath;
const string *basepath;
error = ENOENT;
fusepath = fusepath_;
for(;;)
{
basepath = msplfs::create_1(branches_,fusepath,&error);
if(basepath)
break;
if(fusepath == "/")
break;
fusepath = fs::path::dirname(fusepath);
}
if(basepath == NULL)
return (errno=error,-1);
paths_->push_back(*basepath);
return 0;
}
}
int
Policy::MSPLFS::Action::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return Policies::Action::eplfs(branches_,fusepath_,paths_);
}
int
Policy::MSPLFS::Create::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return ::msplfs::create(branches_,fusepath_,paths_);
}
int
Policy::MSPLFS::Search::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return Policies::Search::eplfs(branches_,fusepath_,paths_);
}

61
src/policy_msplfs.hpp

@ -1,61 +0,0 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "policy.hpp"
namespace Policy
{
namespace MSPLFS
{
class Action final : public Policy::ActionImpl
{
public:
Action()
: Policy::ActionImpl("msplfs")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
class Create final : public Policy::CreateImpl
{
public:
Create()
: Policy::CreateImpl("msplfs")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
bool path_preserving() const final { return true; }
};
class Search final : public Policy::SearchImpl
{
public:
Search()
: Policy::SearchImpl("msplfs")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
}
}

124
src/policy_msplus.cpp

@ -1,124 +0,0 @@
/*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "errno.hpp"
#include "fs_exists.hpp"
#include "fs_info.hpp"
#include "fs_path.hpp"
#include "fs_statvfs_cache.hpp"
#include "policies.hpp"
#include "policy.hpp"
#include "policy_error.hpp"
#include "policy_msplus.hpp"
#include <limits>
#include <string>
using std::string;
namespace msplus
{
static
const
string*
create_1(const Branches::CPtr &branches_,
const string &fusepath_,
int *err_)
{
int rv;
uint64_t lus;
fs::info_t info;
const string *basepath;
basepath = NULL;
lus = std::numeric_limits<uint64_t>::max();
for(auto &branch : *branches_)
{
if(branch.ro_or_nc())
error_and_continue(*err_,EROFS);
if(!fs::exists(branch.path,fusepath_))
error_and_continue(*err_,ENOENT);
rv = fs::info(branch.path,&info);
if(rv == -1)
error_and_continue(*err_,ENOENT);
if(info.readonly)
error_and_continue(*err_,EROFS);
if(info.spaceavail < branch.minfreespace())
error_and_continue(*err_,ENOSPC);
if(info.spaceused >= lus)
continue;
lus = info.spaceused;;
basepath = &branch.path;
}
return basepath;
}
static
int
create(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_)
{
int error;
string fusepath;
const string *basepath;
error = ENOENT;
fusepath = fusepath_;
for(;;)
{
basepath = msplus::create_1(branches_,fusepath,&error);
if(basepath)
break;
if(fusepath == "/")
break;
fusepath = fs::path::dirname(fusepath);
}
if(basepath == NULL)
return (errno=error,-1);
paths_->push_back(*basepath);
return 0;
}
}
int
Policy::MSPLUS::Action::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return Policies::Action::eplus(branches_,fusepath_,paths_);
}
int
Policy::MSPLUS::Create::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return ::msplus::create(branches_,fusepath_,paths_);
}
int
Policy::MSPLUS::Search::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return Policies::Search::eplus(branches_,fusepath_,paths_);
}

61
src/policy_msplus.hpp

@ -1,61 +0,0 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "policy.hpp"
namespace Policy
{
namespace MSPLUS
{
class Action final : public Policy::ActionImpl
{
public:
Action()
: Policy::ActionImpl("msplus")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
class Create final : public Policy::CreateImpl
{
public:
Create()
: Policy::CreateImpl("msplus")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
bool path_preserving() const final { return true; }
};
class Search final : public Policy::SearchImpl
{
public:
Search()
: Policy::SearchImpl("msplus")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
}
}

127
src/policy_mspmfs.cpp

@ -1,127 +0,0 @@
/*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "errno.hpp"
#include "fs_exists.hpp"
#include "fs_info.hpp"
#include "fs_path.hpp"
#include "fs_statvfs_cache.hpp"
#include "policies.hpp"
#include "policy.hpp"
#include "policy_error.hpp"
#include "policy_mspmfs.hpp"
#include <limits>
#include <string>
#include <vector>
using std::string;
using std::vector;
namespace mspmfs
{
static
const
string*
create_1(const Branches::CPtr &branches_,
const string &fusepath_,
int *err_)
{
int rv;
uint64_t mfs;
fs::info_t info;
const string *basepath;
basepath = NULL;
mfs = std::numeric_limits<uint64_t>::min();
for(const auto &branch : *branches_)
{
if(branch.ro_or_nc())
error_and_continue(*err_,EROFS);
if(!fs::exists(branch.path,fusepath_))
error_and_continue(*err_,ENOENT);
rv = fs::info(branch.path,&info);
if(rv == -1)
error_and_continue(*err_,ENOENT);
if(info.readonly)
error_and_continue(*err_,EROFS);
if(info.spaceavail < branch.minfreespace())
error_and_continue(*err_,ENOSPC);
if(info.spaceavail < mfs)
continue;
mfs = info.spaceavail;
basepath = &branch.path;
}
return basepath;
}
static
int
create(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_)
{
int error;
string fusepath;
const string *basepath;
error = ENOENT;
fusepath = fusepath_;
for(;;)
{
basepath = mspmfs::create_1(branches_,fusepath,&error);
if(basepath)
break;
if(fusepath == "/")
break;
fusepath = fs::path::dirname(fusepath);
}
if(basepath == NULL)
return (errno=error,-1);
paths_->push_back(*basepath);
return 0;
}
}
int
Policy::MSPMFS::Action::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return Policies::Action::epmfs(branches_,fusepath_,paths_);
}
int
Policy::MSPMFS::Create::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return ::mspmfs::create(branches_,fusepath_,paths_);
}
int
Policy::MSPMFS::Search::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return Policies::Search::epmfs(branches_,fusepath_,paths_);
}

61
src/policy_mspmfs.hpp

@ -1,61 +0,0 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "policy.hpp"
namespace Policy
{
namespace MSPMFS
{
class Action final : public Policy::ActionImpl
{
public:
Action()
: Policy::ActionImpl("mspmfs")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
class Create final : public Policy::CreateImpl
{
public:
Create()
: Policy::CreateImpl("mspmfs")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
bool path_preserving() const final { return true; }
};
class Search final : public Policy::SearchImpl
{
public:
Search()
: Policy::SearchImpl("mspmfs")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
}
}

179
src/policy_msppfrd.cpp

@ -1,179 +0,0 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "errno.hpp"
#include "fs_exists.hpp"
#include "fs_info.hpp"
#include "fs_path.hpp"
#include "fs_statvfs_cache.hpp"
#include "policy.hpp"
#include "policy_msppfrd.hpp"
#include "policies.hpp"
#include "policy_error.hpp"
#include "rnd.hpp"
#include <string>
#include <vector>
using std::string;
using std::vector;
struct BranchInfo
{
uint64_t spaceavail;
const string *basepath;
};
typedef vector<BranchInfo> BranchInfoVec;
namespace msppfrd
{
static
int
create_1(const Branches::CPtr &branches_,
const string &fusepath_,
BranchInfoVec *branchinfo_,
uint64_t *sum_)
{
int rv;
int error;
BranchInfo bi;
fs::info_t info;
*sum_ = 0;
error = ENOENT;
for(auto &branch : *branches_)
{
if(branch.ro_or_nc())
error_and_continue(error,EROFS);
if(!fs::exists(branch.path,fusepath_))
error_and_continue(error,ENOENT);
rv = fs::info(branch.path,&info);
if(rv == -1)
error_and_continue(error,ENOENT);
if(info.readonly)
error_and_continue(error,EROFS);
if(info.spaceavail < branch.minfreespace())
error_and_continue(error,ENOSPC);
*sum_ += info.spaceavail;
bi.spaceavail = info.spaceavail;
bi.basepath = &branch.path;
branchinfo_->push_back(bi);
}
return error;
}
static
int
get_branchinfo(const Branches::CPtr &branches_,
const char *fusepath_,
BranchInfoVec *branchinfo_,
uint64_t *sum_)
{
int error;
string fusepath;
fusepath = fusepath_;
for(;;)
{
error = msppfrd::create_1(branches_,fusepath,branchinfo_,sum_);
if(branchinfo_->size())
break;
if(fusepath == "/")
break;
fusepath = fs::path::dirname(fusepath);
}
return error;
}
static
const
string*
get_branch(const BranchInfoVec &branchinfo_,
const uint64_t sum_)
{
uint64_t idx;
uint64_t threshold;
if(sum_ == 0)
return NULL;
idx = 0;
threshold = RND::rand64(sum_);
for(size_t i = 0; i < branchinfo_.size(); i++)
{
idx += branchinfo_[i].spaceavail;
if(idx < threshold)
continue;
return branchinfo_[i].basepath;
}
return NULL;
}
static
int
create(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_)
{
int error;
uint64_t sum;
const string *basepath;
BranchInfoVec branchinfo;
error = msppfrd::get_branchinfo(branches_,fusepath_,&branchinfo,&sum);
basepath = msppfrd::get_branch(branchinfo,sum);
if(basepath == NULL)
return (errno=error,-1);
paths_->push_back(*basepath);
return 0;
}
}
int
Policy::MSPPFRD::Action::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return Policies::Action::eppfrd(branches_,fusepath_,paths_);
}
int
Policy::MSPPFRD::Create::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return ::msppfrd::create(branches_,fusepath_,paths_);
}
int
Policy::MSPPFRD::Search::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return Policies::Search::eppfrd(branches_,fusepath_,paths_);
}

61
src/policy_msppfrd.hpp

@ -1,61 +0,0 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "policy.hpp"
namespace Policy
{
namespace MSPPFRD
{
class Action final : public Policy::ActionImpl
{
public:
Action()
: Policy::ActionImpl("msppfrd")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
class Create final : public Policy::CreateImpl
{
public:
Create()
: Policy::CreateImpl("msppfrd")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
bool path_preserving() const final { return true; };
};
class Search final : public Policy::SearchImpl
{
public:
Search()
: Policy::SearchImpl("msppfrd")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
}
}

176
src/policy_newest.cpp

@ -1,176 +0,0 @@
/*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "errno.hpp"
#include "fs_exists.hpp"
#include "fs_info.hpp"
#include "fs_path.hpp"
#include "fs_statvfs_cache.hpp"
#include "policy.hpp"
#include "policy_error.hpp"
#include "policy_newest.hpp"
#include "rwlock.hpp"
#include <string>
#include <limits>
#include <sys/stat.h>
using std::string;
namespace newest
{
static
int
create(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_)
{
int rv;
int error;
time_t newest;
struct stat st;
fs::info_t info;
const string *basepath;
error = ENOENT;
newest = std::numeric_limits<time_t>::min();
basepath = NULL;
for(auto &branch : *branches_)
{
if(branch.ro_or_nc())
error_and_continue(error,EROFS);
if(!fs::exists(branch.path,fusepath_,&st))
error_and_continue(error,ENOENT);
if(st.st_mtime < newest)
continue;
rv = fs::info(branch.path,&info);
if(rv == -1)
error_and_continue(error,ENOENT);
if(info.readonly)
error_and_continue(error,EROFS);
if(info.spaceavail < branch.minfreespace())
error_and_continue(error,ENOSPC);
newest = st.st_mtime;
basepath = &branch.path;
}
if(basepath == NULL)
return (errno=error,-1);
paths_->push_back(*basepath);
return 0;
}
static
int
action(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_)
{
int rv;
int error;
bool readonly;
time_t newest;
struct stat st;
const string *basepath;
error = ENOENT;
newest = std::numeric_limits<time_t>::min();
basepath = NULL;
for(auto &branch : *branches_)
{
if(branch.ro())
error_and_continue(error,EROFS);
if(!fs::exists(branch.path,fusepath_,&st))
error_and_continue(error,ENOENT);
if(st.st_mtime < newest)
continue;
rv = fs::statvfs_cache_readonly(branch.path,&readonly);
if(rv == -1)
error_and_continue(error,ENOENT);
if(readonly)
error_and_continue(error,EROFS);
newest = st.st_mtime;
basepath = &branch.path;
}
if(basepath == NULL)
return (errno=error,-1);
paths_->push_back(*basepath);
return 0;
}
static
int
search(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_)
{
time_t newest;
struct stat st;
const string *basepath;
newest = std::numeric_limits<time_t>::min();
basepath = NULL;
for(auto &branch : *branches_)
{
if(!fs::exists(branch.path,fusepath_,&st))
continue;
if(st.st_mtime < newest)
continue;
newest = st.st_mtime;
basepath = &branch.path;
}
if(basepath == NULL)
return (errno=ENOENT,-1);
paths_->push_back(*basepath);
return 0;
}
}
int
Policy::Newest::Action::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return ::newest::action(branches_,fusepath_,paths_);
}
int
Policy::Newest::Create::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return ::newest::create(branches_,fusepath_,paths_);
}
int
Policy::Newest::Search::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return ::newest::search(branches_,fusepath_,paths_);
}

61
src/policy_newest.hpp

@ -1,61 +0,0 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "policy.hpp"
namespace Policy
{
namespace Newest
{
class Action final : public Policy::ActionImpl
{
public:
Action()
: Policy::ActionImpl("newest")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
class Create final : public Policy::CreateImpl
{
public:
Create()
: Policy::CreateImpl("newest")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
bool path_preserving() const final { return false; }
};
class Search final : public Policy::SearchImpl
{
public:
Search()
: Policy::SearchImpl("newest")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
}
}

149
src/policy_pfrd.cpp

@ -1,149 +0,0 @@
/*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "errno.hpp"
#include "fs_info.hpp"
#include "fs_path.hpp"
#include "policies.hpp"
#include "policy.hpp"
#include "policy_error.hpp"
#include "policy_pfrd.hpp"
#include "rnd.hpp"
#include "strvec.hpp"
#include <string>
#include <vector>
using std::string;
using std::vector;
struct BranchInfo
{
uint64_t spaceavail;
const string *basepath;
};
typedef vector<BranchInfo> BranchInfoVec;
namespace pfrd
{
static
int
get_branchinfo(const Branches::CPtr &branches_,
BranchInfoVec *branchinfo_,
uint64_t *sum_)
{
int rv;
int error;
BranchInfo bi;
fs::info_t info;
*sum_ = 0;
error = ENOENT;
for(auto &branch : *branches_)
{
if(branch.ro_or_nc())
error_and_continue(error,EROFS);
rv = fs::info(branch.path,&info);
if(rv == -1)
error_and_continue(error,ENOENT);
if(info.readonly)
error_and_continue(error,EROFS);
if(info.spaceavail < branch.minfreespace())
error_and_continue(error,ENOSPC);
*sum_ += info.spaceavail;
bi.spaceavail = info.spaceavail;
bi.basepath = &branch.path;
branchinfo_->push_back(bi);
}
return error;
}
static
const
string*
get_branch(const BranchInfoVec &branchinfo_,
const uint64_t sum_)
{
uint64_t idx;
uint64_t threshold;
if(sum_ == 0)
return NULL;
idx = 0;
threshold = RND::rand64(sum_);
for(size_t i = 0; i < branchinfo_.size(); i++)
{
idx += branchinfo_[i].spaceavail;
if(idx < threshold)
continue;
return branchinfo_[i].basepath;
}
return NULL;
}
static
int
create(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_)
{
int error;
uint64_t sum;
const string *basepath;
BranchInfoVec branchinfo;
error = pfrd::get_branchinfo(branches_,&branchinfo,&sum);
basepath = pfrd::get_branch(branchinfo,sum);
if(basepath == NULL)
return (errno=error,-1);
paths_->push_back(*basepath);
return 0;
}
}
int
Policy::PFRD::Action::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return Policies::Action::eppfrd(branches_,fusepath_,paths_);
}
int
Policy::PFRD::Create::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return ::pfrd::create(branches_,fusepath_,paths_);
}
int
Policy::PFRD::Search::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
return Policies::Search::eppfrd(branches_,fusepath_,paths_);
}

61
src/policy_pfrd.hpp

@ -1,61 +0,0 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "policy.hpp"
namespace Policy
{
namespace PFRD
{
class Action final : public Policy::ActionImpl
{
public:
Action()
: Policy::ActionImpl("pfrd")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
class Create final : public Policy::CreateImpl
{
public:
Create()
: Policy::CreateImpl("pfrd")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
bool path_preserving() const final { return false; }
};
class Search final : public Policy::SearchImpl
{
public:
Search()
: Policy::SearchImpl("pfrd")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
}
}

73
src/policy_rand.cpp

@ -1,73 +0,0 @@
/*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "errno.hpp"
#include "policy.hpp"
#include "policy_rand.hpp"
#include "policies.hpp"
#include <algorithm>
int
Policy::Rand::Action::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
int rv;
rv = Policies::Action::all(branches_,fusepath_,paths_);
if(rv == 0)
{
std::random_shuffle(paths_->begin(),paths_->end());
paths_->resize(1);
}
return rv;
}
int
Policy::Rand::Create::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
int rv;
rv = Policies::Create::all(branches_,fusepath_,paths_);
if(rv == 0)
{
std::random_shuffle(paths_->begin(),paths_->end());
paths_->resize(1);
}
return rv;
}
int
Policy::Rand::Search::operator()(const Branches::CPtr &branches_,
const char *fusepath_,
StrVec *paths_) const
{
int rv;
rv = Policies::Search::all(branches_,fusepath_,paths_);
if(rv == 0)
{
std::random_shuffle(paths_->begin(),paths_->end());
paths_->resize(1);
}
return rv;
}

61
src/policy_rand.hpp

@ -1,61 +0,0 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "policy.hpp"
namespace Policy
{
namespace Rand
{
class Action final : public Policy::ActionImpl
{
public:
Action()
: Policy::ActionImpl("rand")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
class Create final : public Policy::CreateImpl
{
public:
Create()
: Policy::CreateImpl("rand")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
bool path_preserving() const final { return false; }
};
class Search final : public Policy::SearchImpl
{
public:
Search()
: Policy::SearchImpl("rand")
{}
public:
int operator()(const Branches::CPtr&,const char*,StrVec*) const final;
};
}
}

51
src/policy_rv.hpp

@ -1,51 +0,0 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include <string>
#include <vector>
struct PolicyRV
{
struct RV
{
RV(const int rv_,
const std::string &basepath_)
: rv(rv_),
basepath(basepath_)
{
}
int rv;
std::string basepath;
};
std::vector<RV> success;
std::vector<RV> error;
void
insert(const int err_,
const std::string &basepath_)
{
if(err_ == 0)
success.push_back(RV(err_,basepath_));
else
error.push_back(RV(-err_,basepath_));
}
};

2
src/state.hpp

@ -95,7 +95,7 @@ public:
public:
gfs::path mountpoint;
Branches2 branches;
Branches branches;
public:
LinkEXDEV link_exdev;

Loading…
Cancel
Save