mirror of
https://github.com/trapexit/mergerfs.git
synced 2026-10-25 18:40:18 -04:00
checkpoint
This commit is contained in:
parent
96d8232853
commit
d8ba75cca3
80 changed files with 1051 additions and 373 deletions
|
|
@ -27,6 +27,13 @@ Category::Base::from_string(const std::string_view s_)
|
|||
{
|
||||
int rv;
|
||||
|
||||
// "mixed" is the sentinel to_string emits when constituent funcs
|
||||
// disagree. Accepting it as a no-op makes config save/restore work
|
||||
// even when per-function overrides have diverged from the
|
||||
// category-wide value.
|
||||
if(s_ == "mixed")
|
||||
return 0;
|
||||
|
||||
for(auto func : funcs)
|
||||
{
|
||||
rv = func->from_string(s_);
|
||||
|
|
|
|||
|
|
@ -20,21 +20,42 @@
|
|||
|
||||
#include "errno.hpp"
|
||||
#include "from_string.hpp"
|
||||
#include "func_create_factory.hpp"
|
||||
|
||||
|
||||
MoveOnENOSPC::MoveOnENOSPC(const bool enabled_)
|
||||
: enabled(enabled_),
|
||||
policy_name("pfrd")
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
MoveOnENOSPC::from_string(const std::string_view s_)
|
||||
{
|
||||
bool tmp;
|
||||
const int rv = str::from(s_,&tmp);
|
||||
if(rv != 0)
|
||||
if(rv == 0)
|
||||
{
|
||||
enabled = tmp;
|
||||
if(enabled)
|
||||
policy_name = "pfrd";
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Not a bool — try a create-policy name.
|
||||
auto impl = Func2::CreateFactory::make(s_);
|
||||
if(!impl)
|
||||
return -EINVAL;
|
||||
enabled = tmp;
|
||||
|
||||
policy_name = std::string(s_);
|
||||
enabled = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string
|
||||
MoveOnENOSPC::to_string(void) const
|
||||
{
|
||||
return (enabled ? "true" : "false");
|
||||
if(enabled)
|
||||
return policy_name;
|
||||
return "false";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,15 +26,13 @@
|
|||
class MoveOnENOSPC : public ToFromString
|
||||
{
|
||||
public:
|
||||
MoveOnENOSPC(const bool enabled_)
|
||||
: enabled(enabled_)
|
||||
{
|
||||
}
|
||||
MoveOnENOSPC(const bool enabled_);
|
||||
|
||||
public:
|
||||
int from_string(const std::string_view s) final;
|
||||
std::string to_string() const final;
|
||||
|
||||
public:
|
||||
bool enabled;
|
||||
bool enabled;
|
||||
std::string policy_name; // default "pfrd"; one of the create policy names
|
||||
};
|
||||
|
|
|
|||
|
|
@ -51,12 +51,109 @@ _cleanup_flags(const int flags_)
|
|||
return rv;
|
||||
}
|
||||
|
||||
// Pick a writable destination branch using PFRD (proportional to free
|
||||
// space). Self-contained for moveonenospc — mirrors the same algorithm
|
||||
// used by Func2::CreatePFRD but on a fresh selection (no clonepath/open).
|
||||
// FF pick: first writable branch (excluding the source).
|
||||
static
|
||||
int
|
||||
_pick_ff_branch(const Branches &branches_,
|
||||
const fs::path &exclude_path_,
|
||||
Branch *&chosen_)
|
||||
{
|
||||
int err = ENOENT;
|
||||
Branches::Ptr branches = branches_;
|
||||
fs::info_t info;
|
||||
|
||||
for(auto &branch : *branches)
|
||||
{
|
||||
if(branch.path == exclude_path_)
|
||||
continue;
|
||||
if(branch.ro_or_nc())
|
||||
{ if(err == ENOENT) err = EROFS; continue; }
|
||||
const int irv = fs::info(branch.path,&info);
|
||||
if(irv < 0)
|
||||
{ if(err == ENOENT) err = ENOENT; continue; }
|
||||
if(info.readonly)
|
||||
{ if(err == ENOENT) err = EROFS; continue; }
|
||||
if(info.spaceavail < branch.minfreespace())
|
||||
{ if(err == ENOENT) err = ENOSPC; continue; }
|
||||
|
||||
chosen_ = &branch;
|
||||
return 0;
|
||||
}
|
||||
return -err;
|
||||
}
|
||||
|
||||
// MFS pick: most-free-space branch (excluding the source).
|
||||
static
|
||||
int
|
||||
_pick_mfs_branch(const Branches &branches_,
|
||||
const fs::path &exclude_path_,
|
||||
Branch *&chosen_)
|
||||
{
|
||||
int err = ENOENT;
|
||||
Branches::Ptr branches = branches_;
|
||||
fs::info_t info;
|
||||
uint64_t best = 0;
|
||||
|
||||
for(auto &branch : *branches)
|
||||
{
|
||||
if(branch.path == exclude_path_)
|
||||
continue;
|
||||
if(branch.ro_or_nc())
|
||||
{ if(err == ENOENT) err = EROFS; continue; }
|
||||
const int irv = fs::info(branch.path,&info);
|
||||
if(irv < 0)
|
||||
{ if(err == ENOENT) err = ENOENT; continue; }
|
||||
if(info.readonly)
|
||||
{ if(err == ENOENT) err = EROFS; continue; }
|
||||
if(info.spaceavail < branch.minfreespace())
|
||||
{ if(err == ENOENT) err = ENOSPC; continue; }
|
||||
|
||||
if(chosen_ && info.spaceavail <= best)
|
||||
continue;
|
||||
best = info.spaceavail;
|
||||
chosen_ = &branch;
|
||||
}
|
||||
return chosen_ ? 0 : -err;
|
||||
}
|
||||
|
||||
// LFS pick: least-free-space branch (excluding the source).
|
||||
static
|
||||
int
|
||||
_pick_lfs_branch(const Branches &branches_,
|
||||
const fs::path &exclude_path_,
|
||||
Branch *&chosen_)
|
||||
{
|
||||
int err = ENOENT;
|
||||
Branches::Ptr branches = branches_;
|
||||
fs::info_t info;
|
||||
uint64_t best = UINT64_MAX;
|
||||
|
||||
for(auto &branch : *branches)
|
||||
{
|
||||
if(branch.path == exclude_path_)
|
||||
continue;
|
||||
if(branch.ro_or_nc())
|
||||
{ if(err == ENOENT) err = EROFS; continue; }
|
||||
const int irv = fs::info(branch.path,&info);
|
||||
if(irv < 0)
|
||||
{ if(err == ENOENT) err = ENOENT; continue; }
|
||||
if(info.readonly)
|
||||
{ if(err == ENOENT) err = EROFS; continue; }
|
||||
if(info.spaceavail < branch.minfreespace())
|
||||
{ if(err == ENOENT) err = ENOSPC; continue; }
|
||||
|
||||
if(info.spaceavail >= best)
|
||||
continue;
|
||||
best = info.spaceavail;
|
||||
chosen_ = &branch;
|
||||
}
|
||||
return chosen_ ? 0 : -err;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_pick_pfrd_branch(const Branches &branches_,
|
||||
const fs::path &exclude_path_,
|
||||
Branch *&chosen_)
|
||||
{
|
||||
int err = ENOENT;
|
||||
|
|
@ -68,6 +165,11 @@ _pick_pfrd_branch(const Branches &branches_,
|
|||
|
||||
for(auto &branch : *branches)
|
||||
{
|
||||
// Never reselect the source branch — the caller is here precisely
|
||||
// because writing to this branch failed (ENOSPC/quota). Picking it
|
||||
// again would cause copyfile+unlink to delete the file.
|
||||
if(branch.path == exclude_path_)
|
||||
continue;
|
||||
if(branch.ro_or_nc())
|
||||
{ if(err == ENOENT) err = EROFS; continue; }
|
||||
const int irv = fs::info(branch.path,&info);
|
||||
|
|
@ -100,12 +202,33 @@ _pick_pfrd_branch(const Branches &branches_,
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Dispatch on policy name. Implements the most common create policies
|
||||
// (ff, mfs, lfs, pfrd) inline; any other valid create policy name falls
|
||||
// back to pfrd (the historical default for moveonenospc).
|
||||
static
|
||||
int
|
||||
_movefile_and_open(const Branches &branches_,
|
||||
const fs::path &branchpath_,
|
||||
const fs::path &fusepath_,
|
||||
int origfd_)
|
||||
_pick_branch(const std::string &policy_name_,
|
||||
const Branches &branches_,
|
||||
const fs::path &exclude_path_,
|
||||
Branch *&chosen_)
|
||||
{
|
||||
if(policy_name_ == "ff")
|
||||
return ::_pick_ff_branch(branches_,exclude_path_,chosen_);
|
||||
if(policy_name_ == "mfs" || policy_name_ == "epmfs" || policy_name_ == "mspmfs")
|
||||
return ::_pick_mfs_branch(branches_,exclude_path_,chosen_);
|
||||
if(policy_name_ == "lfs" || policy_name_ == "eplfs" || policy_name_ == "msplfs")
|
||||
return ::_pick_lfs_branch(branches_,exclude_path_,chosen_);
|
||||
|
||||
return ::_pick_pfrd_branch(branches_,exclude_path_,chosen_);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_movefile_and_open(const std::string &policy_name_,
|
||||
const Branches &branches_,
|
||||
const fs::path &branchpath_,
|
||||
const fs::path &fusepath_,
|
||||
int origfd_)
|
||||
{
|
||||
int rv;
|
||||
int dstfd_flags;
|
||||
|
|
@ -119,7 +242,7 @@ _movefile_and_open(const Branches &branches_,
|
|||
|
||||
src_branch = branchpath_;
|
||||
|
||||
rv = ::_pick_pfrd_branch(branches_,dst_branch);
|
||||
rv = ::_pick_branch(policy_name_,branches_,branchpath_,dst_branch);
|
||||
if(rv < 0)
|
||||
return rv;
|
||||
if(dst_branch == nullptr)
|
||||
|
|
@ -160,19 +283,21 @@ _movefile_and_open(const Branches &branches_,
|
|||
}
|
||||
|
||||
int
|
||||
fs::movefile_and_open(const Branches &branches_,
|
||||
const fs::path &branchpath_,
|
||||
const fs::path &fusepath_,
|
||||
const int origfd_)
|
||||
fs::movefile_and_open(const std::string &policy_name_,
|
||||
const Branches &branches_,
|
||||
const fs::path &branchpath_,
|
||||
const fs::path &fusepath_,
|
||||
const int origfd_)
|
||||
{
|
||||
return ::_movefile_and_open(branches_,branchpath_,fusepath_,origfd_);
|
||||
return ::_movefile_and_open(policy_name_,branches_,branchpath_,fusepath_,origfd_);
|
||||
}
|
||||
|
||||
int
|
||||
fs::movefile_and_open_as_root(const Branches &branches_,
|
||||
const fs::path &branchpath_,
|
||||
const fs::path &fusepath_,
|
||||
const int origfd_)
|
||||
fs::movefile_and_open_as_root(const std::string &policy_name_,
|
||||
const Branches &branches_,
|
||||
const fs::path &branchpath_,
|
||||
const fs::path &fusepath_,
|
||||
const int origfd_)
|
||||
{
|
||||
return fs::movefile_and_open(branches_,branchpath_,fusepath_,origfd_);
|
||||
return fs::movefile_and_open(policy_name_,branches_,branchpath_,fusepath_,origfd_);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,18 +21,22 @@
|
|||
#include "branches.hpp"
|
||||
#include "fs_path.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace fs
|
||||
{
|
||||
int
|
||||
movefile_and_open(const Branches &branches,
|
||||
const fs::path &branchpath,
|
||||
const fs::path &fusepath,
|
||||
const int origfd);
|
||||
movefile_and_open(const std::string &policy_name,
|
||||
const Branches &branches,
|
||||
const fs::path &branchpath,
|
||||
const fs::path &fusepath,
|
||||
const int origfd);
|
||||
|
||||
int
|
||||
movefile_and_open_as_root(const Branches &branches,
|
||||
const fs::path &branchpath,
|
||||
const fs::path &fusepath,
|
||||
int origfd);
|
||||
movefile_and_open_as_root(const std::string &policy_name,
|
||||
const Branches &branches,
|
||||
const fs::path &branchpath,
|
||||
const fs::path &fusepath,
|
||||
int origfd);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ namespace Func2
|
|||
{
|
||||
public:
|
||||
AccessBase() {}
|
||||
~AccessBase() {}
|
||||
virtual ~AccessBase() = default;
|
||||
|
||||
public:
|
||||
virtual std::string_view name() const = 0;
|
||||
|
|
|
|||
|
|
@ -15,10 +15,27 @@ Func2::AccessFactory::valid(const std::string str_)
|
|||
std::shared_ptr<Func2::AccessBase>
|
||||
Func2::AccessFactory::make(const std::string_view str_)
|
||||
{
|
||||
if(str_ == "all") return std::make_shared<Func2::AccessAll>();
|
||||
if(str_ == "epall") return std::make_shared<Func2::AccessEPAll>();
|
||||
if(str_ == "erofs") return std::make_shared<Func2::AccessEROFS>();
|
||||
if(str_ == "ff") return std::make_shared<Func2::AccessFF>();
|
||||
if(str_ == "erofs") return std::make_shared<Func2::AccessEROFS>();
|
||||
if(str_ == "all") return std::make_shared<Func2::AccessAll>();
|
||||
if(str_ == "epall") return std::make_shared<Func2::AccessEPAll>();
|
||||
if(str_ == "epff") return std::make_shared<Func2::AccessEPAll>();
|
||||
if(str_ == "eplfs") return std::make_shared<Func2::AccessEPAll>();
|
||||
if(str_ == "eplus") return std::make_shared<Func2::AccessEPAll>();
|
||||
if(str_ == "epmfs") return std::make_shared<Func2::AccessEPAll>();
|
||||
if(str_ == "eppfrd") return std::make_shared<Func2::AccessEPAll>();
|
||||
if(str_ == "eprand") return std::make_shared<Func2::AccessEPAll>();
|
||||
if(str_ == "ff") return std::make_shared<Func2::AccessFF>();
|
||||
if(str_ == "lfs") return std::make_shared<Func2::AccessFF>();
|
||||
if(str_ == "lup") return std::make_shared<Func2::AccessFF>();
|
||||
if(str_ == "lus") return std::make_shared<Func2::AccessFF>();
|
||||
if(str_ == "mfs") return std::make_shared<Func2::AccessFF>();
|
||||
if(str_ == "msplfs") return std::make_shared<Func2::AccessEPAll>();
|
||||
if(str_ == "msplus") return std::make_shared<Func2::AccessEPAll>();
|
||||
if(str_ == "mspmfs") return std::make_shared<Func2::AccessEPAll>();
|
||||
if(str_ == "msppfrd") return std::make_shared<Func2::AccessEPAll>();
|
||||
if(str_ == "newest") return std::make_shared<Func2::AccessFF>();
|
||||
if(str_ == "pfrd") return std::make_shared<Func2::AccessFF>();
|
||||
if(str_ == "rand") return std::make_shared<Func2::AccessFF>();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,8 +31,13 @@ Func2::ChmodAll::operator()(const Branches &branches_,
|
|||
if(rv == -ENOENT)
|
||||
continue;
|
||||
|
||||
found = true;
|
||||
err = rv;
|
||||
if(!found)
|
||||
{ err = rv; found = true; continue; }
|
||||
if(rv == 0)
|
||||
{ err = 0; continue; }
|
||||
if(err == 0)
|
||||
continue;
|
||||
err = rv;
|
||||
}
|
||||
|
||||
if(!found)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ namespace Func2
|
|||
{
|
||||
public:
|
||||
ChmodBase() {}
|
||||
~ChmodBase() {}
|
||||
virtual ~ChmodBase() = default;
|
||||
|
||||
public:
|
||||
virtual std::string_view name() const = 0;
|
||||
|
|
|
|||
|
|
@ -13,8 +13,27 @@ Func2::ChmodFactory::valid(const std::string str_)
|
|||
std::shared_ptr<Func2::ChmodBase>
|
||||
Func2::ChmodFactory::make(const std::string_view str_)
|
||||
{
|
||||
if(str_ == "erofs") return std::make_shared<Func2::ChmodEROFS>();
|
||||
if(str_ == "all" || str_ == "epall") return std::make_shared<Func2::ChmodAll>();
|
||||
if(str_ == "erofs") return std::make_shared<Func2::ChmodEROFS>();
|
||||
if(str_ == "all") return std::make_shared<Func2::ChmodAll>();
|
||||
if(str_ == "epall") return std::make_shared<Func2::ChmodAll>();
|
||||
if(str_ == "epff") return std::make_shared<Func2::ChmodAll>();
|
||||
if(str_ == "eplfs") return std::make_shared<Func2::ChmodAll>();
|
||||
if(str_ == "eplus") return std::make_shared<Func2::ChmodAll>();
|
||||
if(str_ == "epmfs") return std::make_shared<Func2::ChmodAll>();
|
||||
if(str_ == "eppfrd") return std::make_shared<Func2::ChmodAll>();
|
||||
if(str_ == "eprand") return std::make_shared<Func2::ChmodAll>();
|
||||
if(str_ == "ff") return std::make_shared<Func2::ChmodAll>();
|
||||
if(str_ == "lfs") return std::make_shared<Func2::ChmodAll>();
|
||||
if(str_ == "lup") return std::make_shared<Func2::ChmodAll>();
|
||||
if(str_ == "lus") return std::make_shared<Func2::ChmodAll>();
|
||||
if(str_ == "mfs") return std::make_shared<Func2::ChmodAll>();
|
||||
if(str_ == "msplfs") return std::make_shared<Func2::ChmodAll>();
|
||||
if(str_ == "msplus") return std::make_shared<Func2::ChmodAll>();
|
||||
if(str_ == "mspmfs") return std::make_shared<Func2::ChmodAll>();
|
||||
if(str_ == "msppfrd") return std::make_shared<Func2::ChmodAll>();
|
||||
if(str_ == "newest") return std::make_shared<Func2::ChmodAll>();
|
||||
if(str_ == "pfrd") return std::make_shared<Func2::ChmodAll>();
|
||||
if(str_ == "rand") return std::make_shared<Func2::ChmodAll>();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,8 +32,13 @@ Func2::ChownAll::operator()(const Branches &branches_,
|
|||
if(rv == -ENOENT)
|
||||
continue;
|
||||
|
||||
found = true;
|
||||
err = rv;
|
||||
if(!found)
|
||||
{ err = rv; found = true; continue; }
|
||||
if(rv == 0)
|
||||
{ err = 0; continue; }
|
||||
if(err == 0)
|
||||
continue;
|
||||
err = rv;
|
||||
}
|
||||
|
||||
if(!found)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ namespace Func2
|
|||
{
|
||||
public:
|
||||
ChownBase() {}
|
||||
~ChownBase() {}
|
||||
virtual ~ChownBase() = default;
|
||||
|
||||
public:
|
||||
virtual std::string_view name() const = 0;
|
||||
|
|
|
|||
|
|
@ -13,8 +13,27 @@ Func2::ChownFactory::valid(const std::string str_)
|
|||
std::shared_ptr<Func2::ChownBase>
|
||||
Func2::ChownFactory::make(const std::string_view str_)
|
||||
{
|
||||
if(str_ == "erofs") return std::make_shared<Func2::ChownEROFS>();
|
||||
if(str_ == "all" || str_ == "epall") return std::make_shared<Func2::ChownAll>();
|
||||
if(str_ == "erofs") return std::make_shared<Func2::ChownEROFS>();
|
||||
if(str_ == "all") return std::make_shared<Func2::ChownAll>();
|
||||
if(str_ == "epall") return std::make_shared<Func2::ChownAll>();
|
||||
if(str_ == "epff") return std::make_shared<Func2::ChownAll>();
|
||||
if(str_ == "eplfs") return std::make_shared<Func2::ChownAll>();
|
||||
if(str_ == "eplus") return std::make_shared<Func2::ChownAll>();
|
||||
if(str_ == "epmfs") return std::make_shared<Func2::ChownAll>();
|
||||
if(str_ == "eppfrd") return std::make_shared<Func2::ChownAll>();
|
||||
if(str_ == "eprand") return std::make_shared<Func2::ChownAll>();
|
||||
if(str_ == "ff") return std::make_shared<Func2::ChownAll>();
|
||||
if(str_ == "lfs") return std::make_shared<Func2::ChownAll>();
|
||||
if(str_ == "lup") return std::make_shared<Func2::ChownAll>();
|
||||
if(str_ == "lus") return std::make_shared<Func2::ChownAll>();
|
||||
if(str_ == "mfs") return std::make_shared<Func2::ChownAll>();
|
||||
if(str_ == "msplfs") return std::make_shared<Func2::ChownAll>();
|
||||
if(str_ == "msplus") return std::make_shared<Func2::ChownAll>();
|
||||
if(str_ == "mspmfs") return std::make_shared<Func2::ChownAll>();
|
||||
if(str_ == "msppfrd") return std::make_shared<Func2::ChownAll>();
|
||||
if(str_ == "newest") return std::make_shared<Func2::ChownAll>();
|
||||
if(str_ == "pfrd") return std::make_shared<Func2::ChownAll>();
|
||||
if(str_ == "rand") return std::make_shared<Func2::ChownAll>();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ namespace Func2
|
|||
{
|
||||
public:
|
||||
CreateBase() {}
|
||||
~CreateBase() {}
|
||||
virtual ~CreateBase() = default;
|
||||
|
||||
public:
|
||||
virtual std::string_view name() const = 0;
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ Func2::CreateLUP::operator()(const ugid_t &ugid_,
|
|||
long double ratio;
|
||||
|
||||
if(total == 0)
|
||||
{ used = 0; total = 1; }
|
||||
{ used = 1; total = 1; }
|
||||
ratio = (long double)used / (long double)total;
|
||||
if(ratio >= best_ratio)
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ namespace Func2
|
|||
{
|
||||
public:
|
||||
GetAttrBase() {}
|
||||
~GetAttrBase() {}
|
||||
virtual ~GetAttrBase() = default;
|
||||
|
||||
public:
|
||||
virtual std::string_view name() const = 0;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@ Func2::GetAttrCDCO::operator()(const Branches &branches_,
|
|||
|
||||
err = 0;
|
||||
first_branch = nullptr;
|
||||
for(const auto &branch : branches_)
|
||||
Branches::Ptr branches = branches_;
|
||||
for(const auto &branch : *branches)
|
||||
{
|
||||
struct stat tmp_st;
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
std::string_view
|
||||
Func2::GetAttrCDFO::name() const
|
||||
{
|
||||
|
||||
return "cdfo";
|
||||
}
|
||||
|
||||
|
|
@ -27,7 +28,8 @@ Func2::GetAttrCDFO::operator()(const Branches &branches_,
|
|||
|
||||
err = 0;
|
||||
first_branch = nullptr;
|
||||
for(const auto &branch : branches_)
|
||||
Branches::Ptr branches = branches_;
|
||||
for(const auto &branch : *branches)
|
||||
{
|
||||
struct stat tmp_st;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#include "func_getattr_factory.hpp"
|
||||
|
||||
#include "func_getattr_cdfo.hpp"
|
||||
#include "func_getattr_cdco.hpp"
|
||||
#include "func_getattr_cdfo.hpp"
|
||||
#include "func_getattr_ff.hpp"
|
||||
#include "func_getattr_newest.hpp"
|
||||
|
||||
|
|
@ -19,6 +19,26 @@ Func2::GetAttrFactory::make(const std::string_view str_)
|
|||
if(str_ == "cdco") return std::make_shared<Func2::GetAttrCDCO>();
|
||||
if(str_ == "ff") return std::make_shared<Func2::GetAttrFF>();
|
||||
if(str_ == "newest") return std::make_shared<Func2::GetAttrNewest>();
|
||||
if(str_ == "all") return std::make_shared<Func2::GetAttrFF>();
|
||||
if(str_ == "epall") return std::make_shared<Func2::GetAttrFF>();
|
||||
if(str_ == "epff") return std::make_shared<Func2::GetAttrFF>();
|
||||
if(str_ == "eplfs") return std::make_shared<Func2::GetAttrCDFO>();
|
||||
if(str_ == "eplus") return std::make_shared<Func2::GetAttrCDFO>();
|
||||
if(str_ == "epmfs") return std::make_shared<Func2::GetAttrCDFO>();
|
||||
if(str_ == "eppfrd") return std::make_shared<Func2::GetAttrCDFO>();
|
||||
if(str_ == "eprand") return std::make_shared<Func2::GetAttrCDFO>();
|
||||
if(str_ == "ff") return std::make_shared<Func2::GetAttrFF>();
|
||||
if(str_ == "lfs") return std::make_shared<Func2::GetAttrCDFO>();
|
||||
if(str_ == "lup") return std::make_shared<Func2::GetAttrCDFO>();
|
||||
if(str_ == "lus") return std::make_shared<Func2::GetAttrCDFO>();
|
||||
if(str_ == "mfs") return std::make_shared<Func2::GetAttrCDFO>();
|
||||
if(str_ == "msplfs") return std::make_shared<Func2::GetAttrCDFO>();
|
||||
if(str_ == "msplus") return std::make_shared<Func2::GetAttrCDFO>();
|
||||
if(str_ == "mspmfs") return std::make_shared<Func2::GetAttrCDFO>();
|
||||
if(str_ == "msppfrd") return std::make_shared<Func2::GetAttrCDFO>();
|
||||
if(str_ == "newest") return std::make_shared<Func2::GetAttrNewest>();
|
||||
if(str_ == "pfrd") return std::make_shared<Func2::GetAttrCDFO>();
|
||||
if(str_ == "rand") return std::make_shared<Func2::GetAttrCDFO>();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
std::string_view
|
||||
Func2::GetAttrFF::name() const
|
||||
{
|
||||
|
||||
return "ff";
|
||||
}
|
||||
|
||||
|
|
@ -22,7 +23,8 @@ Func2::GetAttrFF::operator()(const Branches &branches_,
|
|||
{
|
||||
fs::path fullpath;
|
||||
|
||||
for(const auto &branch : branches_)
|
||||
Branches::Ptr branches = branches_;
|
||||
for(const auto &branch : *branches)
|
||||
{
|
||||
fullpath = branch.path / fusepath_;
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
std::string_view
|
||||
Func2::GetAttrNewest::name() const
|
||||
{
|
||||
|
||||
return "newest";
|
||||
}
|
||||
|
||||
|
|
@ -27,7 +28,8 @@ Func2::GetAttrNewest::operator()(const Branches &branches_,
|
|||
|
||||
err = 0;
|
||||
newest_branch = nullptr;
|
||||
for(const auto &branch : branches_)
|
||||
Branches::Ptr branches = branches_;
|
||||
for(const auto &branch : *branches)
|
||||
{
|
||||
struct stat tmp_st;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ namespace Func2
|
|||
{
|
||||
public:
|
||||
GetxattrBase() {}
|
||||
~GetxattrBase() {}
|
||||
virtual ~GetxattrBase() = default;
|
||||
|
||||
public:
|
||||
virtual std::string_view name() const = 0;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#include "func_getxattr_factory.hpp"
|
||||
|
||||
#include "func_getxattr_ff.hpp"
|
||||
#include "func_getxattr_erofs.hpp"
|
||||
#include "func_getxattr_ff.hpp"
|
||||
|
||||
|
||||
bool
|
||||
|
|
@ -14,7 +14,26 @@ std::shared_ptr<Func2::GetxattrBase>
|
|||
Func2::GetxattrFactory::make(const std::string_view str_)
|
||||
{
|
||||
if(str_ == "erofs") return std::make_shared<Func2::GetxattrEROFS>();
|
||||
if(str_ == "ff") return std::make_shared<Func2::GetxattrFF>();
|
||||
if(str_ == "all") return std::make_shared<Func2::GetxattrFF>();
|
||||
if(str_ == "epall") return std::make_shared<Func2::GetxattrFF>();
|
||||
if(str_ == "epff") return std::make_shared<Func2::GetxattrFF>();
|
||||
if(str_ == "eplfs") return std::make_shared<Func2::GetxattrFF>();
|
||||
if(str_ == "eplus") return std::make_shared<Func2::GetxattrFF>();
|
||||
if(str_ == "epmfs") return std::make_shared<Func2::GetxattrFF>();
|
||||
if(str_ == "eppfrd") return std::make_shared<Func2::GetxattrFF>();
|
||||
if(str_ == "eprand") return std::make_shared<Func2::GetxattrFF>();
|
||||
if(str_ == "ff") return std::make_shared<Func2::GetxattrFF>();
|
||||
if(str_ == "lfs") return std::make_shared<Func2::GetxattrFF>();
|
||||
if(str_ == "lup") return std::make_shared<Func2::GetxattrFF>();
|
||||
if(str_ == "lus") return std::make_shared<Func2::GetxattrFF>();
|
||||
if(str_ == "mfs") return std::make_shared<Func2::GetxattrFF>();
|
||||
if(str_ == "msplfs") return std::make_shared<Func2::GetxattrFF>();
|
||||
if(str_ == "msplus") return std::make_shared<Func2::GetxattrFF>();
|
||||
if(str_ == "mspmfs") return std::make_shared<Func2::GetxattrFF>();
|
||||
if(str_ == "msppfrd") return std::make_shared<Func2::GetxattrFF>();
|
||||
if(str_ == "newest") return std::make_shared<Func2::GetxattrFF>();
|
||||
if(str_ == "pfrd") return std::make_shared<Func2::GetxattrFF>();
|
||||
if(str_ == "rand") return std::make_shared<Func2::GetxattrFF>();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ namespace Func2
|
|||
{
|
||||
public:
|
||||
IoctlBase() {}
|
||||
~IoctlBase() {}
|
||||
virtual ~IoctlBase() = default;
|
||||
|
||||
public:
|
||||
virtual std::string_view name() const = 0;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#include "func_ioctl_factory.hpp"
|
||||
|
||||
#include "func_ioctl_ff.hpp"
|
||||
#include "func_ioctl_erofs.hpp"
|
||||
#include "func_ioctl_ff.hpp"
|
||||
|
||||
|
||||
bool
|
||||
|
|
@ -14,7 +14,26 @@ std::shared_ptr<Func2::IoctlBase>
|
|||
Func2::IoctlFactory::make(const std::string_view str_)
|
||||
{
|
||||
if(str_ == "erofs") return std::make_shared<Func2::IoctlEROFS>();
|
||||
if(str_ == "ff") return std::make_shared<Func2::IoctlFF>();
|
||||
if(str_ == "all") return std::make_shared<Func2::IoctlFF>();
|
||||
if(str_ == "epall") return std::make_shared<Func2::IoctlFF>();
|
||||
if(str_ == "epff") return std::make_shared<Func2::IoctlFF>();
|
||||
if(str_ == "eplfs") return std::make_shared<Func2::IoctlFF>();
|
||||
if(str_ == "eplus") return std::make_shared<Func2::IoctlFF>();
|
||||
if(str_ == "epmfs") return std::make_shared<Func2::IoctlFF>();
|
||||
if(str_ == "eppfrd") return std::make_shared<Func2::IoctlFF>();
|
||||
if(str_ == "eprand") return std::make_shared<Func2::IoctlFF>();
|
||||
if(str_ == "ff") return std::make_shared<Func2::IoctlFF>();
|
||||
if(str_ == "lfs") return std::make_shared<Func2::IoctlFF>();
|
||||
if(str_ == "lup") return std::make_shared<Func2::IoctlFF>();
|
||||
if(str_ == "lus") return std::make_shared<Func2::IoctlFF>();
|
||||
if(str_ == "mfs") return std::make_shared<Func2::IoctlFF>();
|
||||
if(str_ == "msplfs") return std::make_shared<Func2::IoctlFF>();
|
||||
if(str_ == "msplus") return std::make_shared<Func2::IoctlFF>();
|
||||
if(str_ == "mspmfs") return std::make_shared<Func2::IoctlFF>();
|
||||
if(str_ == "msppfrd") return std::make_shared<Func2::IoctlFF>();
|
||||
if(str_ == "newest") return std::make_shared<Func2::IoctlFF>();
|
||||
if(str_ == "pfrd") return std::make_shared<Func2::IoctlFF>();
|
||||
if(str_ == "rand") return std::make_shared<Func2::IoctlFF>();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ namespace Func2
|
|||
{
|
||||
public:
|
||||
LinkBase() {}
|
||||
~LinkBase() {}
|
||||
virtual ~LinkBase() = default;
|
||||
|
||||
public:
|
||||
virtual std::string_view name() const = 0;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
#include "func_link_epall.hpp"
|
||||
|
||||
#include "clone_source.hpp"
|
||||
#include "config.hpp"
|
||||
#include "errno.hpp"
|
||||
#include "fs_clonepath.hpp"
|
||||
#include "fs_exists.hpp"
|
||||
|
|
@ -46,16 +48,9 @@ Func2::LinkEPAll::operator()(const Branches &branches_,
|
|||
continue;
|
||||
|
||||
if(clone_src == nullptr)
|
||||
{
|
||||
for(auto &b : *branches)
|
||||
{
|
||||
if(fs::exists(b.path,newfusedirpath))
|
||||
{
|
||||
clone_src = &b;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
clone_src = CloneSource::find(*branches,
|
||||
newfusedirpath,
|
||||
cfg.getattr.to_string());
|
||||
|
||||
if(clone_src != nullptr)
|
||||
{
|
||||
|
|
@ -65,8 +60,13 @@ Func2::LinkEPAll::operator()(const Branches &branches_,
|
|||
}
|
||||
}
|
||||
|
||||
found = true;
|
||||
err = rv;
|
||||
if(!found)
|
||||
{ err = rv; found = true; continue; }
|
||||
if(rv == 0)
|
||||
{ err = 0; continue; }
|
||||
if(err == 0)
|
||||
continue;
|
||||
err = rv;
|
||||
}
|
||||
|
||||
if(!found)
|
||||
|
|
|
|||
|
|
@ -13,8 +13,27 @@ Func2::LinkFactory::valid(const std::string str_)
|
|||
std::shared_ptr<Func2::LinkBase>
|
||||
Func2::LinkFactory::make(const std::string_view str_)
|
||||
{
|
||||
if(str_ == "erofs") return std::make_shared<Func2::LinkEROFS>();
|
||||
if(str_ == "all" || str_ == "epall") return std::make_shared<Func2::LinkEPAll>();
|
||||
if(str_ == "erofs") return std::make_shared<Func2::LinkEROFS>();
|
||||
if(str_ == "all") return std::make_shared<Func2::LinkEPAll>();
|
||||
if(str_ == "epall") return std::make_shared<Func2::LinkEPAll>();
|
||||
if(str_ == "epff") return std::make_shared<Func2::LinkEPAll>();
|
||||
if(str_ == "eplfs") return std::make_shared<Func2::LinkEPAll>();
|
||||
if(str_ == "eplus") return std::make_shared<Func2::LinkEPAll>();
|
||||
if(str_ == "epmfs") return std::make_shared<Func2::LinkEPAll>();
|
||||
if(str_ == "eppfrd") return std::make_shared<Func2::LinkEPAll>();
|
||||
if(str_ == "eprand") return std::make_shared<Func2::LinkEPAll>();
|
||||
if(str_ == "ff") return std::make_shared<Func2::LinkEPAll>();
|
||||
if(str_ == "lfs") return std::make_shared<Func2::LinkEPAll>();
|
||||
if(str_ == "lup") return std::make_shared<Func2::LinkEPAll>();
|
||||
if(str_ == "lus") return std::make_shared<Func2::LinkEPAll>();
|
||||
if(str_ == "mfs") return std::make_shared<Func2::LinkEPAll>();
|
||||
if(str_ == "msplfs") return std::make_shared<Func2::LinkEPAll>();
|
||||
if(str_ == "msplus") return std::make_shared<Func2::LinkEPAll>();
|
||||
if(str_ == "mspmfs") return std::make_shared<Func2::LinkEPAll>();
|
||||
if(str_ == "msppfrd") return std::make_shared<Func2::LinkEPAll>();
|
||||
if(str_ == "newest") return std::make_shared<Func2::LinkEPAll>();
|
||||
if(str_ == "pfrd") return std::make_shared<Func2::LinkEPAll>();
|
||||
if(str_ == "rand") return std::make_shared<Func2::LinkEPAll>();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ namespace Func2
|
|||
{
|
||||
public:
|
||||
ListxattrBase() {}
|
||||
~ListxattrBase() {}
|
||||
virtual ~ListxattrBase() = default;
|
||||
|
||||
public:
|
||||
virtual std::string_view name() const = 0;
|
||||
|
|
|
|||
|
|
@ -14,10 +14,27 @@ Func2::ListxattrFactory::valid(const std::string str_)
|
|||
std::shared_ptr<Func2::ListxattrBase>
|
||||
Func2::ListxattrFactory::make(const std::string_view str_)
|
||||
{
|
||||
if(str_ == "all") return std::make_shared<Func2::ListxattrAll>();
|
||||
if(str_ == "epall") return std::make_shared<Func2::ListxattrAll>();
|
||||
if(str_ == "erofs") return std::make_shared<Func2::ListxattrEROFS>();
|
||||
if(str_ == "ff") return std::make_shared<Func2::ListxattrFF>();
|
||||
if(str_ == "all") return std::make_shared<Func2::ListxattrAll>();
|
||||
if(str_ == "epall") return std::make_shared<Func2::ListxattrAll>();
|
||||
if(str_ == "epff") return std::make_shared<Func2::ListxattrAll>();
|
||||
if(str_ == "eplfs") return std::make_shared<Func2::ListxattrAll>();
|
||||
if(str_ == "eplus") return std::make_shared<Func2::ListxattrAll>();
|
||||
if(str_ == "epmfs") return std::make_shared<Func2::ListxattrAll>();
|
||||
if(str_ == "eppfrd") return std::make_shared<Func2::ListxattrAll>();
|
||||
if(str_ == "eprand") return std::make_shared<Func2::ListxattrAll>();
|
||||
if(str_ == "ff") return std::make_shared<Func2::ListxattrFF>();
|
||||
if(str_ == "lfs") return std::make_shared<Func2::ListxattrFF>();
|
||||
if(str_ == "lup") return std::make_shared<Func2::ListxattrFF>();
|
||||
if(str_ == "lus") return std::make_shared<Func2::ListxattrFF>();
|
||||
if(str_ == "mfs") return std::make_shared<Func2::ListxattrFF>();
|
||||
if(str_ == "msplfs") return std::make_shared<Func2::ListxattrAll>();
|
||||
if(str_ == "msplus") return std::make_shared<Func2::ListxattrAll>();
|
||||
if(str_ == "mspmfs") return std::make_shared<Func2::ListxattrAll>();
|
||||
if(str_ == "msppfrd") return std::make_shared<Func2::ListxattrAll>();
|
||||
if(str_ == "newest") return std::make_shared<Func2::ListxattrFF>();
|
||||
if(str_ == "pfrd") return std::make_shared<Func2::ListxattrFF>();
|
||||
if(str_ == "rand") return std::make_shared<Func2::ListxattrFF>();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,21 +1,15 @@
|
|||
#include "func_mkdir_all.hpp"
|
||||
|
||||
#include "errno.hpp"
|
||||
#include "fs_acl.hpp"
|
||||
#include "fs_clonepath.hpp"
|
||||
#include "fs_exists.hpp"
|
||||
#include "fs_info.hpp"
|
||||
#include "fs_info_t.hpp"
|
||||
#include "fs_path.hpp"
|
||||
#include "fs_acl.hpp"
|
||||
#include "fs_mkdir_as.hpp"
|
||||
#include "fs_path.hpp"
|
||||
|
||||
|
||||
#define error_and_continue(CUR,ERR) \
|
||||
do { \
|
||||
::_calc_error(CUR,ERR); \
|
||||
continue; \
|
||||
} while(0)
|
||||
|
||||
static
|
||||
inline
|
||||
void
|
||||
|
|
@ -39,6 +33,12 @@ _calc_error(int &cur_,
|
|||
}
|
||||
}
|
||||
|
||||
#define error_and_continue(CUR,ERR) \
|
||||
do { \
|
||||
::_calc_error(CUR,ERR); \
|
||||
continue; \
|
||||
} while(0)
|
||||
|
||||
|
||||
std::string_view
|
||||
Func2::MkdirAll::name() const
|
||||
|
|
@ -55,17 +55,25 @@ Func2::MkdirAll::operator()(const ugid_t &ugid_,
|
|||
{
|
||||
int rv;
|
||||
int error;
|
||||
bool any;
|
||||
fs::info_t info;
|
||||
Branches::Ptr branches;
|
||||
const Branch *chosen;
|
||||
const Branch *clone_src;
|
||||
fs::path fullpath;
|
||||
mode_t mode;
|
||||
|
||||
branches = branches_;
|
||||
chosen = nullptr;
|
||||
clone_src = nullptr;
|
||||
error = ENOENT;
|
||||
any = false;
|
||||
|
||||
for(auto &branch : *branches)
|
||||
{
|
||||
if(!fs::exists(branch.path,fusepath_.parent_path()))
|
||||
continue;
|
||||
clone_src = &branch;
|
||||
break;
|
||||
}
|
||||
|
||||
for(auto &branch : *branches)
|
||||
{
|
||||
|
|
@ -79,35 +87,30 @@ Func2::MkdirAll::operator()(const ugid_t &ugid_,
|
|||
if(info.spaceavail < branch.minfreespace())
|
||||
error_and_continue(error,ENOSPC);
|
||||
|
||||
chosen = &branch;
|
||||
break;
|
||||
if(clone_src && (clone_src != &branch))
|
||||
{
|
||||
rv = fs::clonepath(clone_src->path,branch.path,fusepath_.parent_path());
|
||||
if(rv < 0)
|
||||
error_and_continue(error,-rv);
|
||||
}
|
||||
|
||||
fullpath = branch.path / fusepath_;
|
||||
mode = mode_;
|
||||
if(!fs::acl::dir_has_defaults(fullpath))
|
||||
mode &= ~umask_;
|
||||
|
||||
rv = fs::mkdir_as(ugid_,fullpath,mode);
|
||||
if(rv < 0)
|
||||
{
|
||||
::_calc_error(error,-rv);
|
||||
continue;
|
||||
}
|
||||
|
||||
any = true;
|
||||
}
|
||||
|
||||
if(!chosen)
|
||||
if(!any)
|
||||
return -error;
|
||||
|
||||
for(auto &branch : *branches)
|
||||
{
|
||||
if(!fs::exists(branch.path,fusepath_.parent_path()))
|
||||
continue;
|
||||
clone_src = &branch;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!clone_src)
|
||||
return -ENOENT;
|
||||
|
||||
if(clone_src != chosen)
|
||||
{
|
||||
rv = fs::clonepath(clone_src->path,chosen->path,fusepath_.parent_path());
|
||||
if(rv < 0)
|
||||
return rv;
|
||||
}
|
||||
|
||||
fullpath = chosen->path / fusepath_;
|
||||
mode = mode_;
|
||||
if(!fs::acl::dir_has_defaults(fullpath))
|
||||
mode &= ~umask_;
|
||||
|
||||
return fs::mkdir_as(ugid_,fullpath,mode);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ namespace Func2
|
|||
{
|
||||
public:
|
||||
MkdirBase() {}
|
||||
~MkdirBase() {}
|
||||
virtual ~MkdirBase() = default;
|
||||
|
||||
public:
|
||||
virtual std::string_view name() const = 0;
|
||||
|
|
|
|||
|
|
@ -1,21 +1,14 @@
|
|||
#include "func_mkdir_epall.hpp"
|
||||
|
||||
#include "errno.hpp"
|
||||
#include "fs_clonepath.hpp"
|
||||
#include "fs_acl.hpp"
|
||||
#include "fs_exists.hpp"
|
||||
#include "fs_info.hpp"
|
||||
#include "fs_info_t.hpp"
|
||||
#include "fs_path.hpp"
|
||||
#include "fs_acl.hpp"
|
||||
#include "fs_mkdir_as.hpp"
|
||||
#include "fs_path.hpp"
|
||||
|
||||
|
||||
#define error_and_continue(CUR,ERR) \
|
||||
do { \
|
||||
::_calc_error(CUR,ERR); \
|
||||
continue; \
|
||||
} while(0)
|
||||
|
||||
static
|
||||
inline
|
||||
void
|
||||
|
|
@ -39,6 +32,12 @@ _calc_error(int &cur_,
|
|||
}
|
||||
}
|
||||
|
||||
#define error_and_continue(CUR,ERR) \
|
||||
do { \
|
||||
::_calc_error(CUR,ERR); \
|
||||
continue; \
|
||||
} while(0)
|
||||
|
||||
|
||||
std::string_view
|
||||
Func2::MkdirEPALL::name() const
|
||||
|
|
@ -55,15 +54,15 @@ Func2::MkdirEPALL::operator()(const ugid_t &ugid_,
|
|||
{
|
||||
int rv;
|
||||
int error;
|
||||
bool any;
|
||||
fs::info_t info;
|
||||
Branches::Ptr branches;
|
||||
const Branch *chosen;
|
||||
fs::path fullpath;
|
||||
mode_t mode;
|
||||
|
||||
branches = branches_;
|
||||
chosen = nullptr;
|
||||
error = ENOENT;
|
||||
any = false;
|
||||
|
||||
for(auto &branch : *branches)
|
||||
{
|
||||
|
|
@ -79,17 +78,23 @@ Func2::MkdirEPALL::operator()(const ugid_t &ugid_,
|
|||
if(info.spaceavail < branch.minfreespace())
|
||||
error_and_continue(error,ENOSPC);
|
||||
|
||||
chosen = &branch;
|
||||
break;
|
||||
fullpath = branch.path / fusepath_;
|
||||
mode = mode_;
|
||||
if(!fs::acl::dir_has_defaults(fullpath))
|
||||
mode &= ~umask_;
|
||||
|
||||
rv = fs::mkdir_as(ugid_,fullpath,mode);
|
||||
if(rv < 0)
|
||||
{
|
||||
::_calc_error(error,-rv);
|
||||
continue;
|
||||
}
|
||||
|
||||
any = true;
|
||||
}
|
||||
|
||||
if(!chosen)
|
||||
if(!any)
|
||||
return -error;
|
||||
|
||||
fullpath = chosen->path / fusepath_;
|
||||
mode = mode_;
|
||||
if(!fs::acl::dir_has_defaults(fullpath))
|
||||
mode &= ~umask_;
|
||||
|
||||
return fs::mkdir_as(ugid_,fullpath,mode);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ Func2::MkdirLUP::operator()(const ugid_t &ugid_,
|
|||
long double ratio;
|
||||
|
||||
if(total == 0)
|
||||
{ used = 0; total = 1; }
|
||||
{ used = 1; total = 1; }
|
||||
ratio = (long double)used / (long double)total;
|
||||
if(ratio >= best_ratio)
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -5,16 +5,10 @@
|
|||
#include "fs_exists.hpp"
|
||||
#include "fs_info.hpp"
|
||||
#include "fs_info_t.hpp"
|
||||
#include "fs_path.hpp"
|
||||
#include "fs_mknod_as.hpp"
|
||||
#include "fs_path.hpp"
|
||||
|
||||
|
||||
#define error_and_continue(CUR,ERR) \
|
||||
do { \
|
||||
::_calc_error(CUR,ERR); \
|
||||
continue; \
|
||||
} while(0)
|
||||
|
||||
static
|
||||
inline
|
||||
void
|
||||
|
|
@ -38,6 +32,12 @@ _calc_error(int &cur_,
|
|||
}
|
||||
}
|
||||
|
||||
#define error_and_continue(CUR,ERR) \
|
||||
do { \
|
||||
::_calc_error(CUR,ERR); \
|
||||
continue; \
|
||||
} while(0)
|
||||
|
||||
|
||||
std::string_view
|
||||
Func2::MknodAll::name() const
|
||||
|
|
@ -55,16 +55,24 @@ Func2::MknodAll::operator()(const ugid_t &ugid_,
|
|||
{
|
||||
int rv;
|
||||
int error;
|
||||
bool any;
|
||||
fs::info_t info;
|
||||
Branches::Ptr branches;
|
||||
const Branch *chosen;
|
||||
const Branch *clone_src;
|
||||
fs::path fullpath;
|
||||
|
||||
branches = branches_;
|
||||
chosen = nullptr;
|
||||
clone_src = nullptr;
|
||||
error = ENOENT;
|
||||
any = false;
|
||||
|
||||
for(auto &branch : *branches)
|
||||
{
|
||||
if(!fs::exists(branch.path,fusepath_.parent_path()))
|
||||
continue;
|
||||
clone_src = &branch;
|
||||
break;
|
||||
}
|
||||
|
||||
for(auto &branch : *branches)
|
||||
{
|
||||
|
|
@ -78,32 +86,26 @@ Func2::MknodAll::operator()(const ugid_t &ugid_,
|
|||
if(info.spaceavail < branch.minfreespace())
|
||||
error_and_continue(error,ENOSPC);
|
||||
|
||||
chosen = &branch;
|
||||
break;
|
||||
if(clone_src && (clone_src != &branch))
|
||||
{
|
||||
rv = fs::clonepath(clone_src->path,branch.path,fusepath_.parent_path());
|
||||
if(rv < 0)
|
||||
error_and_continue(error,-rv);
|
||||
}
|
||||
|
||||
fullpath = branch.path / fusepath_;
|
||||
rv = fs::mknod_as(ugid_,fullpath,mode_,dev_,umask_);
|
||||
if(rv < 0)
|
||||
{
|
||||
::_calc_error(error,-rv);
|
||||
continue;
|
||||
}
|
||||
|
||||
any = true;
|
||||
}
|
||||
|
||||
if(!chosen)
|
||||
if(!any)
|
||||
return -error;
|
||||
|
||||
for(auto &branch : *branches)
|
||||
{
|
||||
if(!fs::exists(branch.path,fusepath_.parent_path()))
|
||||
continue;
|
||||
clone_src = &branch;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!clone_src)
|
||||
return -ENOENT;
|
||||
|
||||
if(clone_src != chosen)
|
||||
{
|
||||
rv = fs::clonepath(clone_src->path,chosen->path,fusepath_.parent_path());
|
||||
if(rv < 0)
|
||||
return rv;
|
||||
}
|
||||
|
||||
fullpath = chosen->path / fusepath_;
|
||||
|
||||
return fs::mknod_as(ugid_,fullpath,mode_,dev_,umask_);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ namespace Func2
|
|||
{
|
||||
public:
|
||||
MknodBase() {}
|
||||
~MknodBase() {}
|
||||
virtual ~MknodBase() = default;
|
||||
|
||||
public:
|
||||
virtual std::string_view name() const = 0;
|
||||
|
|
|
|||
|
|
@ -1,20 +1,13 @@
|
|||
#include "func_mknod_epall.hpp"
|
||||
|
||||
#include "errno.hpp"
|
||||
#include "fs_clonepath.hpp"
|
||||
#include "fs_exists.hpp"
|
||||
#include "fs_info.hpp"
|
||||
#include "fs_info_t.hpp"
|
||||
#include "fs_path.hpp"
|
||||
#include "fs_mknod_as.hpp"
|
||||
#include "fs_path.hpp"
|
||||
|
||||
|
||||
#define error_and_continue(CUR,ERR) \
|
||||
do { \
|
||||
::_calc_error(CUR,ERR); \
|
||||
continue; \
|
||||
} while(0)
|
||||
|
||||
static
|
||||
inline
|
||||
void
|
||||
|
|
@ -38,6 +31,12 @@ _calc_error(int &cur_,
|
|||
}
|
||||
}
|
||||
|
||||
#define error_and_continue(CUR,ERR) \
|
||||
do { \
|
||||
::_calc_error(CUR,ERR); \
|
||||
continue; \
|
||||
} while(0)
|
||||
|
||||
|
||||
std::string_view
|
||||
Func2::MknodEPALL::name() const
|
||||
|
|
@ -55,14 +54,14 @@ Func2::MknodEPALL::operator()(const ugid_t &ugid_,
|
|||
{
|
||||
int rv;
|
||||
int error;
|
||||
bool any;
|
||||
fs::info_t info;
|
||||
Branches::Ptr branches;
|
||||
const Branch *chosen;
|
||||
fs::path fullpath;
|
||||
|
||||
branches = branches_;
|
||||
chosen = nullptr;
|
||||
error = ENOENT;
|
||||
any = false;
|
||||
|
||||
for(auto &branch : *branches)
|
||||
{
|
||||
|
|
@ -78,14 +77,19 @@ Func2::MknodEPALL::operator()(const ugid_t &ugid_,
|
|||
if(info.spaceavail < branch.minfreespace())
|
||||
error_and_continue(error,ENOSPC);
|
||||
|
||||
chosen = &branch;
|
||||
break;
|
||||
fullpath = branch.path / fusepath_;
|
||||
rv = fs::mknod_as(ugid_,fullpath,mode_,dev_,umask_);
|
||||
if(rv < 0)
|
||||
{
|
||||
::_calc_error(error,-rv);
|
||||
continue;
|
||||
}
|
||||
|
||||
any = true;
|
||||
}
|
||||
|
||||
if(!chosen)
|
||||
if(!any)
|
||||
return -error;
|
||||
|
||||
fullpath = chosen->path / fusepath_;
|
||||
|
||||
return fs::mknod_as(ugid_,fullpath,mode_,dev_,umask_);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ Func2::MknodLUP::operator()(const ugid_t &ugid_,
|
|||
long double ratio;
|
||||
|
||||
if(total == 0)
|
||||
{ used = 0; total = 1; }
|
||||
{ used = 1; total = 1; }
|
||||
ratio = (long double)used / (long double)total;
|
||||
if(ratio >= best_ratio)
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ namespace Func2
|
|||
{
|
||||
public:
|
||||
OpenBase() {}
|
||||
~OpenBase() {}
|
||||
virtual ~OpenBase() = default;
|
||||
|
||||
public:
|
||||
virtual std::string_view name() const = 0;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#include "func_open_factory.hpp"
|
||||
|
||||
#include "func_open_ff.hpp"
|
||||
#include "func_open_erofs.hpp"
|
||||
#include "func_open_ff.hpp"
|
||||
|
||||
|
||||
bool
|
||||
|
|
@ -14,7 +14,26 @@ std::shared_ptr<Func2::OpenBase>
|
|||
Func2::OpenFactory::make(const std::string_view str_)
|
||||
{
|
||||
if(str_ == "erofs") return std::make_shared<Func2::OpenEROFS>();
|
||||
if(str_ == "ff") return std::make_shared<Func2::OpenFF>();
|
||||
if(str_ == "all") return std::make_shared<Func2::OpenFF>();
|
||||
if(str_ == "epall") return std::make_shared<Func2::OpenFF>();
|
||||
if(str_ == "epff") return std::make_shared<Func2::OpenFF>();
|
||||
if(str_ == "eplfs") return std::make_shared<Func2::OpenFF>();
|
||||
if(str_ == "eplus") return std::make_shared<Func2::OpenFF>();
|
||||
if(str_ == "epmfs") return std::make_shared<Func2::OpenFF>();
|
||||
if(str_ == "eppfrd") return std::make_shared<Func2::OpenFF>();
|
||||
if(str_ == "eprand") return std::make_shared<Func2::OpenFF>();
|
||||
if(str_ == "ff") return std::make_shared<Func2::OpenFF>();
|
||||
if(str_ == "lfs") return std::make_shared<Func2::OpenFF>();
|
||||
if(str_ == "lup") return std::make_shared<Func2::OpenFF>();
|
||||
if(str_ == "lus") return std::make_shared<Func2::OpenFF>();
|
||||
if(str_ == "mfs") return std::make_shared<Func2::OpenFF>();
|
||||
if(str_ == "msplfs") return std::make_shared<Func2::OpenFF>();
|
||||
if(str_ == "msplus") return std::make_shared<Func2::OpenFF>();
|
||||
if(str_ == "mspmfs") return std::make_shared<Func2::OpenFF>();
|
||||
if(str_ == "msppfrd") return std::make_shared<Func2::OpenFF>();
|
||||
if(str_ == "newest") return std::make_shared<Func2::OpenFF>();
|
||||
if(str_ == "pfrd") return std::make_shared<Func2::OpenFF>();
|
||||
if(str_ == "rand") return std::make_shared<Func2::OpenFF>();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ namespace Func2
|
|||
{
|
||||
public:
|
||||
ReadlinkBase() {}
|
||||
~ReadlinkBase() {}
|
||||
virtual ~ReadlinkBase() = default;
|
||||
|
||||
public:
|
||||
virtual std::string_view name() const = 0;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#include "func_readlink_factory.hpp"
|
||||
|
||||
#include "func_readlink_ff.hpp"
|
||||
#include "func_readlink_erofs.hpp"
|
||||
#include "func_readlink_ff.hpp"
|
||||
|
||||
|
||||
bool
|
||||
|
|
@ -14,7 +14,26 @@ std::shared_ptr<Func2::ReadlinkBase>
|
|||
Func2::ReadlinkFactory::make(const std::string_view str_)
|
||||
{
|
||||
if(str_ == "erofs") return std::make_shared<Func2::ReadlinkEROFS>();
|
||||
if(str_ == "ff") return std::make_shared<Func2::ReadlinkFF>();
|
||||
if(str_ == "all") return std::make_shared<Func2::ReadlinkFF>();
|
||||
if(str_ == "epall") return std::make_shared<Func2::ReadlinkFF>();
|
||||
if(str_ == "epff") return std::make_shared<Func2::ReadlinkFF>();
|
||||
if(str_ == "eplfs") return std::make_shared<Func2::ReadlinkFF>();
|
||||
if(str_ == "eplus") return std::make_shared<Func2::ReadlinkFF>();
|
||||
if(str_ == "epmfs") return std::make_shared<Func2::ReadlinkFF>();
|
||||
if(str_ == "eppfrd") return std::make_shared<Func2::ReadlinkFF>();
|
||||
if(str_ == "eprand") return std::make_shared<Func2::ReadlinkFF>();
|
||||
if(str_ == "ff") return std::make_shared<Func2::ReadlinkFF>();
|
||||
if(str_ == "lfs") return std::make_shared<Func2::ReadlinkFF>();
|
||||
if(str_ == "lup") return std::make_shared<Func2::ReadlinkFF>();
|
||||
if(str_ == "lus") return std::make_shared<Func2::ReadlinkFF>();
|
||||
if(str_ == "mfs") return std::make_shared<Func2::ReadlinkFF>();
|
||||
if(str_ == "msplfs") return std::make_shared<Func2::ReadlinkFF>();
|
||||
if(str_ == "msplus") return std::make_shared<Func2::ReadlinkFF>();
|
||||
if(str_ == "mspmfs") return std::make_shared<Func2::ReadlinkFF>();
|
||||
if(str_ == "msppfrd") return std::make_shared<Func2::ReadlinkFF>();
|
||||
if(str_ == "newest") return std::make_shared<Func2::ReadlinkFF>();
|
||||
if(str_ == "pfrd") return std::make_shared<Func2::ReadlinkFF>();
|
||||
if(str_ == "rand") return std::make_shared<Func2::ReadlinkFF>();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,8 +31,13 @@ Func2::RemovexattrAll::operator()(const Branches &branches_,
|
|||
if(rv == -ENOENT)
|
||||
continue;
|
||||
|
||||
found = true;
|
||||
err = rv;
|
||||
if(!found)
|
||||
{ err = rv; found = true; continue; }
|
||||
if(rv == 0)
|
||||
{ err = 0; continue; }
|
||||
if(err == 0)
|
||||
continue;
|
||||
err = rv;
|
||||
}
|
||||
|
||||
if(!found)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ namespace Func2
|
|||
{
|
||||
public:
|
||||
RemovexattrBase() {}
|
||||
~RemovexattrBase() {}
|
||||
virtual ~RemovexattrBase() = default;
|
||||
|
||||
public:
|
||||
virtual std::string_view name() const = 0;
|
||||
|
|
|
|||
|
|
@ -13,8 +13,27 @@ Func2::RemovexattrFactory::valid(const std::string str_)
|
|||
std::shared_ptr<Func2::RemovexattrBase>
|
||||
Func2::RemovexattrFactory::make(const std::string_view str_)
|
||||
{
|
||||
if(str_ == "erofs") return std::make_shared<Func2::RemovexattrEROFS>();
|
||||
if(str_ == "all" || str_ == "epall") return std::make_shared<Func2::RemovexattrAll>();
|
||||
if(str_ == "erofs") return std::make_shared<Func2::RemovexattrEROFS>();
|
||||
if(str_ == "all") return std::make_shared<Func2::RemovexattrAll>();
|
||||
if(str_ == "epall") return std::make_shared<Func2::RemovexattrAll>();
|
||||
if(str_ == "epff") return std::make_shared<Func2::RemovexattrAll>();
|
||||
if(str_ == "eplfs") return std::make_shared<Func2::RemovexattrAll>();
|
||||
if(str_ == "eplus") return std::make_shared<Func2::RemovexattrAll>();
|
||||
if(str_ == "epmfs") return std::make_shared<Func2::RemovexattrAll>();
|
||||
if(str_ == "eppfrd") return std::make_shared<Func2::RemovexattrAll>();
|
||||
if(str_ == "eprand") return std::make_shared<Func2::RemovexattrAll>();
|
||||
if(str_ == "ff") return std::make_shared<Func2::RemovexattrAll>();
|
||||
if(str_ == "lfs") return std::make_shared<Func2::RemovexattrAll>();
|
||||
if(str_ == "lup") return std::make_shared<Func2::RemovexattrAll>();
|
||||
if(str_ == "lus") return std::make_shared<Func2::RemovexattrAll>();
|
||||
if(str_ == "mfs") return std::make_shared<Func2::RemovexattrAll>();
|
||||
if(str_ == "msplfs") return std::make_shared<Func2::RemovexattrAll>();
|
||||
if(str_ == "msplus") return std::make_shared<Func2::RemovexattrAll>();
|
||||
if(str_ == "mspmfs") return std::make_shared<Func2::RemovexattrAll>();
|
||||
if(str_ == "msppfrd") return std::make_shared<Func2::RemovexattrAll>();
|
||||
if(str_ == "newest") return std::make_shared<Func2::RemovexattrAll>();
|
||||
if(str_ == "pfrd") return std::make_shared<Func2::RemovexattrAll>();
|
||||
if(str_ == "rand") return std::make_shared<Func2::RemovexattrAll>();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ namespace Func2
|
|||
{
|
||||
public:
|
||||
RenameBase() {}
|
||||
~RenameBase() {}
|
||||
virtual ~RenameBase() = default;
|
||||
|
||||
public:
|
||||
virtual std::string_view name() const = 0;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
#include "func_rename_epall.hpp"
|
||||
|
||||
#include "clone_source.hpp"
|
||||
#include "config.hpp"
|
||||
#include "errno.hpp"
|
||||
#include "fs_clonepath.hpp"
|
||||
#include "fs_exists.hpp"
|
||||
|
|
@ -51,16 +53,9 @@ Func2::RenameEPAll::operator()(const Branches &branches_,
|
|||
if(rv == -ENOENT)
|
||||
{
|
||||
if(clone_src == nullptr)
|
||||
{
|
||||
for(auto &b : *branches)
|
||||
{
|
||||
if(fs::exists(b.path,newfusedirpath))
|
||||
{
|
||||
clone_src = &b;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
clone_src = CloneSource::find(*branches,
|
||||
newfusedirpath,
|
||||
cfg.getattr.to_string());
|
||||
|
||||
if(clone_src != nullptr)
|
||||
{
|
||||
|
|
@ -70,8 +65,19 @@ Func2::RenameEPAll::operator()(const Branches &branches_,
|
|||
}
|
||||
}
|
||||
|
||||
found = true;
|
||||
err = rv;
|
||||
// If rename failed on this branch but the source still exists, queue
|
||||
// the stale source for removal on overall success so the file is not
|
||||
// left at both old and new paths.
|
||||
if(rv < 0)
|
||||
toremove.push_back(oldfullpath);
|
||||
|
||||
if(!found)
|
||||
{ err = rv; found = true; continue; }
|
||||
if(rv == 0)
|
||||
{ err = 0; continue; }
|
||||
if(err == 0)
|
||||
continue;
|
||||
err = rv;
|
||||
}
|
||||
|
||||
if(!found)
|
||||
|
|
|
|||
|
|
@ -13,8 +13,27 @@ Func2::RenameFactory::valid(const std::string str_)
|
|||
std::shared_ptr<Func2::RenameBase>
|
||||
Func2::RenameFactory::make(const std::string_view str_)
|
||||
{
|
||||
if(str_ == "erofs") return std::make_shared<Func2::RenameEROFS>();
|
||||
if(str_ == "all" || str_ == "epall") return std::make_shared<Func2::RenameEPAll>();
|
||||
if(str_ == "erofs") return std::make_shared<Func2::RenameEROFS>();
|
||||
if(str_ == "all") return std::make_shared<Func2::RenameEPAll>();
|
||||
if(str_ == "epall") return std::make_shared<Func2::RenameEPAll>();
|
||||
if(str_ == "epff") return std::make_shared<Func2::RenameEPAll>();
|
||||
if(str_ == "eplfs") return std::make_shared<Func2::RenameEPAll>();
|
||||
if(str_ == "eplus") return std::make_shared<Func2::RenameEPAll>();
|
||||
if(str_ == "epmfs") return std::make_shared<Func2::RenameEPAll>();
|
||||
if(str_ == "eppfrd") return std::make_shared<Func2::RenameEPAll>();
|
||||
if(str_ == "eprand") return std::make_shared<Func2::RenameEPAll>();
|
||||
if(str_ == "ff") return std::make_shared<Func2::RenameEPAll>();
|
||||
if(str_ == "lfs") return std::make_shared<Func2::RenameEPAll>();
|
||||
if(str_ == "lup") return std::make_shared<Func2::RenameEPAll>();
|
||||
if(str_ == "lus") return std::make_shared<Func2::RenameEPAll>();
|
||||
if(str_ == "mfs") return std::make_shared<Func2::RenameEPAll>();
|
||||
if(str_ == "msplfs") return std::make_shared<Func2::RenameEPAll>();
|
||||
if(str_ == "msplus") return std::make_shared<Func2::RenameEPAll>();
|
||||
if(str_ == "mspmfs") return std::make_shared<Func2::RenameEPAll>();
|
||||
if(str_ == "msppfrd") return std::make_shared<Func2::RenameEPAll>();
|
||||
if(str_ == "newest") return std::make_shared<Func2::RenameEPAll>();
|
||||
if(str_ == "pfrd") return std::make_shared<Func2::RenameEPAll>();
|
||||
if(str_ == "rand") return std::make_shared<Func2::RenameEPAll>();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,8 +42,19 @@ Func2::RmdirAll::operator()(const Branches &branches_,
|
|||
if(rv == -ENOENT)
|
||||
continue;
|
||||
|
||||
found = true;
|
||||
err = rv;
|
||||
if(!found)
|
||||
{ err = rv; found = true; continue; }
|
||||
// -ENOTEMPTY / -EEXIST are strongest: a remaining-content failure must
|
||||
// override a sibling-branch success since the directory is not fully gone.
|
||||
if((rv == -ENOTEMPTY) || (rv == -EEXIST))
|
||||
{ err = rv; continue; }
|
||||
if((err == -ENOTEMPTY) || (err == -EEXIST))
|
||||
continue;
|
||||
if(rv == 0)
|
||||
{ err = 0; continue; }
|
||||
if(err == 0)
|
||||
continue;
|
||||
err = rv;
|
||||
}
|
||||
|
||||
if(!found)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ namespace Func2
|
|||
{
|
||||
public:
|
||||
RmdirBase() {}
|
||||
~RmdirBase() {}
|
||||
virtual ~RmdirBase() = default;
|
||||
|
||||
public:
|
||||
virtual std::string_view name() const = 0;
|
||||
|
|
|
|||
|
|
@ -13,8 +13,27 @@ Func2::RmdirFactory::valid(const std::string str_)
|
|||
std::shared_ptr<Func2::RmdirBase>
|
||||
Func2::RmdirFactory::make(const std::string_view str_)
|
||||
{
|
||||
if(str_ == "erofs") return std::make_shared<Func2::RmdirEROFS>();
|
||||
if(str_ == "all" || str_ == "epall") return std::make_shared<Func2::RmdirAll>();
|
||||
if(str_ == "erofs") return std::make_shared<Func2::RmdirEROFS>();
|
||||
if(str_ == "all") return std::make_shared<Func2::RmdirAll>();
|
||||
if(str_ == "epall") return std::make_shared<Func2::RmdirAll>();
|
||||
if(str_ == "epff") return std::make_shared<Func2::RmdirAll>();
|
||||
if(str_ == "eplfs") return std::make_shared<Func2::RmdirAll>();
|
||||
if(str_ == "eplus") return std::make_shared<Func2::RmdirAll>();
|
||||
if(str_ == "epmfs") return std::make_shared<Func2::RmdirAll>();
|
||||
if(str_ == "eppfrd") return std::make_shared<Func2::RmdirAll>();
|
||||
if(str_ == "eprand") return std::make_shared<Func2::RmdirAll>();
|
||||
if(str_ == "ff") return std::make_shared<Func2::RmdirAll>();
|
||||
if(str_ == "lfs") return std::make_shared<Func2::RmdirAll>();
|
||||
if(str_ == "lup") return std::make_shared<Func2::RmdirAll>();
|
||||
if(str_ == "lus") return std::make_shared<Func2::RmdirAll>();
|
||||
if(str_ == "mfs") return std::make_shared<Func2::RmdirAll>();
|
||||
if(str_ == "msplfs") return std::make_shared<Func2::RmdirAll>();
|
||||
if(str_ == "msplus") return std::make_shared<Func2::RmdirAll>();
|
||||
if(str_ == "mspmfs") return std::make_shared<Func2::RmdirAll>();
|
||||
if(str_ == "msppfrd") return std::make_shared<Func2::RmdirAll>();
|
||||
if(str_ == "newest") return std::make_shared<Func2::RmdirAll>();
|
||||
if(str_ == "pfrd") return std::make_shared<Func2::RmdirAll>();
|
||||
if(str_ == "rand") return std::make_shared<Func2::RmdirAll>();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,8 +34,13 @@ Func2::SetxattrAll::operator()(const Branches &branches_,
|
|||
if(rv == -ENOENT)
|
||||
continue;
|
||||
|
||||
found = true;
|
||||
err = rv;
|
||||
if(!found)
|
||||
{ err = rv; found = true; continue; }
|
||||
if(rv == 0)
|
||||
{ err = 0; continue; }
|
||||
if(err == 0)
|
||||
continue;
|
||||
err = rv;
|
||||
}
|
||||
|
||||
if(!found)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ namespace Func2
|
|||
{
|
||||
public:
|
||||
SetxattrBase() {}
|
||||
~SetxattrBase() {}
|
||||
virtual ~SetxattrBase() = default;
|
||||
|
||||
public:
|
||||
virtual std::string_view name() const = 0;
|
||||
|
|
|
|||
|
|
@ -13,8 +13,27 @@ Func2::SetxattrFactory::valid(const std::string str_)
|
|||
std::shared_ptr<Func2::SetxattrBase>
|
||||
Func2::SetxattrFactory::make(const std::string_view str_)
|
||||
{
|
||||
if(str_ == "erofs") return std::make_shared<Func2::SetxattrEROFS>();
|
||||
if(str_ == "all" || str_ == "epall") return std::make_shared<Func2::SetxattrAll>();
|
||||
if(str_ == "erofs") return std::make_shared<Func2::SetxattrEROFS>();
|
||||
if(str_ == "all") return std::make_shared<Func2::SetxattrAll>();
|
||||
if(str_ == "epall") return std::make_shared<Func2::SetxattrAll>();
|
||||
if(str_ == "epff") return std::make_shared<Func2::SetxattrAll>();
|
||||
if(str_ == "eplfs") return std::make_shared<Func2::SetxattrAll>();
|
||||
if(str_ == "eplus") return std::make_shared<Func2::SetxattrAll>();
|
||||
if(str_ == "epmfs") return std::make_shared<Func2::SetxattrAll>();
|
||||
if(str_ == "eppfrd") return std::make_shared<Func2::SetxattrAll>();
|
||||
if(str_ == "eprand") return std::make_shared<Func2::SetxattrAll>();
|
||||
if(str_ == "ff") return std::make_shared<Func2::SetxattrAll>();
|
||||
if(str_ == "lfs") return std::make_shared<Func2::SetxattrAll>();
|
||||
if(str_ == "lup") return std::make_shared<Func2::SetxattrAll>();
|
||||
if(str_ == "lus") return std::make_shared<Func2::SetxattrAll>();
|
||||
if(str_ == "mfs") return std::make_shared<Func2::SetxattrAll>();
|
||||
if(str_ == "msplfs") return std::make_shared<Func2::SetxattrAll>();
|
||||
if(str_ == "msplus") return std::make_shared<Func2::SetxattrAll>();
|
||||
if(str_ == "mspmfs") return std::make_shared<Func2::SetxattrAll>();
|
||||
if(str_ == "msppfrd") return std::make_shared<Func2::SetxattrAll>();
|
||||
if(str_ == "newest") return std::make_shared<Func2::SetxattrAll>();
|
||||
if(str_ == "pfrd") return std::make_shared<Func2::SetxattrAll>();
|
||||
if(str_ == "rand") return std::make_shared<Func2::SetxattrAll>();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ namespace Func2
|
|||
{
|
||||
public:
|
||||
StatxBase() {}
|
||||
~StatxBase() {}
|
||||
virtual ~StatxBase() = default;
|
||||
|
||||
public:
|
||||
virtual std::string_view name() const = 0;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
std::string_view
|
||||
Func2::StatxCDCO::name() const
|
||||
{
|
||||
|
||||
return "cdco";
|
||||
}
|
||||
|
||||
|
|
@ -29,7 +30,8 @@ Func2::StatxCDCO::operator()(const Branches &branches_,
|
|||
|
||||
err = 0;
|
||||
first_branch = nullptr;
|
||||
for(const auto &branch : branches_)
|
||||
Branches::Ptr branches = branches_;
|
||||
for(const auto &branch : *branches)
|
||||
{
|
||||
struct fuse_statx tmp_st;
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
std::string_view
|
||||
Func2::StatxCDFO::name() const
|
||||
{
|
||||
|
||||
return "cdfo";
|
||||
}
|
||||
|
||||
|
|
@ -29,7 +30,8 @@ Func2::StatxCDFO::operator()(const Branches &branches_,
|
|||
|
||||
err = 0;
|
||||
first_branch = nullptr;
|
||||
for(const auto &branch : branches_)
|
||||
Branches::Ptr branches = branches_;
|
||||
for(const auto &branch : *branches)
|
||||
{
|
||||
struct fuse_statx tmp_st;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#include "func_statx_factory.hpp"
|
||||
|
||||
#include "func_statx_cdfo.hpp"
|
||||
#include "func_statx_cdco.hpp"
|
||||
#include "func_statx_cdfo.hpp"
|
||||
#include "func_statx_ff.hpp"
|
||||
#include "func_statx_newest.hpp"
|
||||
|
||||
|
|
@ -19,6 +19,26 @@ Func2::StatxFactory::make(const std::string_view str_)
|
|||
if(str_ == "cdco") return std::make_shared<Func2::StatxCDCO>();
|
||||
if(str_ == "ff") return std::make_shared<Func2::StatxFF>();
|
||||
if(str_ == "newest") return std::make_shared<Func2::StatxNewest>();
|
||||
if(str_ == "all") return std::make_shared<Func2::StatxFF>();
|
||||
if(str_ == "epall") return std::make_shared<Func2::StatxFF>();
|
||||
if(str_ == "epff") return std::make_shared<Func2::StatxFF>();
|
||||
if(str_ == "eplfs") return std::make_shared<Func2::StatxCDFO>();
|
||||
if(str_ == "eplus") return std::make_shared<Func2::StatxCDFO>();
|
||||
if(str_ == "epmfs") return std::make_shared<Func2::StatxCDFO>();
|
||||
if(str_ == "eppfrd") return std::make_shared<Func2::StatxCDFO>();
|
||||
if(str_ == "eprand") return std::make_shared<Func2::StatxCDFO>();
|
||||
if(str_ == "ff") return std::make_shared<Func2::StatxFF>();
|
||||
if(str_ == "lfs") return std::make_shared<Func2::StatxCDFO>();
|
||||
if(str_ == "lup") return std::make_shared<Func2::StatxCDFO>();
|
||||
if(str_ == "lus") return std::make_shared<Func2::StatxCDFO>();
|
||||
if(str_ == "mfs") return std::make_shared<Func2::StatxCDFO>();
|
||||
if(str_ == "msplfs") return std::make_shared<Func2::StatxCDFO>();
|
||||
if(str_ == "msplus") return std::make_shared<Func2::StatxCDFO>();
|
||||
if(str_ == "mspmfs") return std::make_shared<Func2::StatxCDFO>();
|
||||
if(str_ == "msppfrd") return std::make_shared<Func2::StatxCDFO>();
|
||||
if(str_ == "newest") return std::make_shared<Func2::StatxNewest>();
|
||||
if(str_ == "pfrd") return std::make_shared<Func2::StatxCDFO>();
|
||||
if(str_ == "rand") return std::make_shared<Func2::StatxCDFO>();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
std::string_view
|
||||
Func2::StatxFF::name() const
|
||||
{
|
||||
|
||||
return "ff";
|
||||
}
|
||||
|
||||
|
|
@ -24,7 +25,8 @@ Func2::StatxFF::operator()(const Branches &branches_,
|
|||
{
|
||||
fs::path fullpath;
|
||||
|
||||
for(const auto &branch : branches_)
|
||||
Branches::Ptr branches = branches_;
|
||||
for(const auto &branch : *branches)
|
||||
{
|
||||
fullpath = branch.path / fusepath_;
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
std::string_view
|
||||
Func2::StatxNewest::name() const
|
||||
{
|
||||
|
||||
return "newest";
|
||||
}
|
||||
|
||||
|
|
@ -29,7 +30,8 @@ Func2::StatxNewest::operator()(const Branches &branches_,
|
|||
|
||||
err = 0;
|
||||
newest_branch = nullptr;
|
||||
for(const auto &branch : branches_)
|
||||
Branches::Ptr branches = branches_;
|
||||
for(const auto &branch : *branches)
|
||||
{
|
||||
struct fuse_statx tmp_st;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,18 +5,12 @@
|
|||
#include "fs_exists.hpp"
|
||||
#include "fs_info.hpp"
|
||||
#include "fs_info_t.hpp"
|
||||
#include "fs_path.hpp"
|
||||
#include "fs_inode.hpp"
|
||||
#include "fs_lstat.hpp"
|
||||
#include "fs_path.hpp"
|
||||
#include "fs_symlink_as.hpp"
|
||||
|
||||
|
||||
#define error_and_continue(CUR,ERR) \
|
||||
do { \
|
||||
::_calc_error(CUR,ERR); \
|
||||
continue; \
|
||||
} while(0)
|
||||
|
||||
static
|
||||
inline
|
||||
void
|
||||
|
|
@ -40,6 +34,12 @@ _calc_error(int &cur_,
|
|||
}
|
||||
}
|
||||
|
||||
#define error_and_continue(CUR,ERR) \
|
||||
do { \
|
||||
::_calc_error(CUR,ERR); \
|
||||
continue; \
|
||||
} while(0)
|
||||
|
||||
|
||||
std::string_view
|
||||
Func2::SymlinkAll::name() const
|
||||
|
|
@ -56,16 +56,26 @@ Func2::SymlinkAll::operator()(const ugid_t &ugid_,
|
|||
{
|
||||
int rv;
|
||||
int error;
|
||||
bool any;
|
||||
fs::info_t info;
|
||||
Branches::Ptr branches;
|
||||
const Branch *chosen;
|
||||
const Branch *clone_src;
|
||||
const Branch *last_success;
|
||||
fs::path fullpath;
|
||||
|
||||
branches = branches_;
|
||||
chosen = nullptr;
|
||||
clone_src = nullptr;
|
||||
error = ENOENT;
|
||||
branches = branches_;
|
||||
clone_src = nullptr;
|
||||
last_success = nullptr;
|
||||
error = ENOENT;
|
||||
any = false;
|
||||
|
||||
for(auto &branch : *branches)
|
||||
{
|
||||
if(!fs::exists(branch.path,linkpath_.parent_path()))
|
||||
continue;
|
||||
clone_src = &branch;
|
||||
break;
|
||||
}
|
||||
|
||||
for(auto &branch : *branches)
|
||||
{
|
||||
|
|
@ -79,40 +89,35 @@ Func2::SymlinkAll::operator()(const ugid_t &ugid_,
|
|||
if(info.spaceavail < branch.minfreespace())
|
||||
error_and_continue(error,ENOSPC);
|
||||
|
||||
chosen = &branch;
|
||||
break;
|
||||
if(clone_src && (clone_src != &branch))
|
||||
{
|
||||
rv = fs::clonepath(clone_src->path,branch.path,linkpath_.parent_path());
|
||||
if(rv < 0)
|
||||
error_and_continue(error,-rv);
|
||||
}
|
||||
|
||||
fullpath = branch.path / linkpath_;
|
||||
rv = fs::symlink_as(ugid_,target_,fullpath);
|
||||
if(rv < 0)
|
||||
{
|
||||
::_calc_error(error,-rv);
|
||||
continue;
|
||||
}
|
||||
|
||||
any = true;
|
||||
last_success = &branch;
|
||||
}
|
||||
|
||||
if(!chosen)
|
||||
if(!any)
|
||||
return -error;
|
||||
|
||||
for(auto &branch : *branches)
|
||||
{
|
||||
if(!fs::exists(branch.path,linkpath_.parent_path()))
|
||||
continue;
|
||||
clone_src = &branch;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!clone_src)
|
||||
return -ENOENT;
|
||||
|
||||
if(clone_src != chosen)
|
||||
{
|
||||
rv = fs::clonepath(clone_src->path,chosen->path,linkpath_.parent_path());
|
||||
if(rv < 0)
|
||||
return rv;
|
||||
}
|
||||
|
||||
fullpath = chosen->path / linkpath_;
|
||||
|
||||
rv = fs::symlink_as(ugid_,target_,fullpath);
|
||||
if((rv >= 0) && (st_ != NULL) && (st_->st_ino == 0))
|
||||
if(last_success && (st_ != NULL) && (st_->st_ino == 0))
|
||||
{
|
||||
fullpath = last_success->path / linkpath_;
|
||||
fs::lstat(fullpath,st_);
|
||||
if(st_->st_ino != 0)
|
||||
fs::inode::calc(chosen->path,linkpath_,st_);
|
||||
fs::inode::calc(last_success->path,linkpath_,st_);
|
||||
}
|
||||
|
||||
return rv;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ namespace Func2
|
|||
{
|
||||
public:
|
||||
SymlinkBase() {}
|
||||
~SymlinkBase() {}
|
||||
virtual ~SymlinkBase() = default;
|
||||
|
||||
public:
|
||||
virtual std::string_view name() const = 0;
|
||||
|
|
|
|||
|
|
@ -1,22 +1,15 @@
|
|||
#include "func_symlink_epall.hpp"
|
||||
|
||||
#include "errno.hpp"
|
||||
#include "fs_clonepath.hpp"
|
||||
#include "fs_exists.hpp"
|
||||
#include "fs_info.hpp"
|
||||
#include "fs_info_t.hpp"
|
||||
#include "fs_path.hpp"
|
||||
#include "fs_inode.hpp"
|
||||
#include "fs_lstat.hpp"
|
||||
#include "fs_path.hpp"
|
||||
#include "fs_symlink_as.hpp"
|
||||
|
||||
|
||||
#define error_and_continue(CUR,ERR) \
|
||||
do { \
|
||||
::_calc_error(CUR,ERR); \
|
||||
continue; \
|
||||
} while(0)
|
||||
|
||||
static
|
||||
inline
|
||||
void
|
||||
|
|
@ -40,6 +33,12 @@ _calc_error(int &cur_,
|
|||
}
|
||||
}
|
||||
|
||||
#define error_and_continue(CUR,ERR) \
|
||||
do { \
|
||||
::_calc_error(CUR,ERR); \
|
||||
continue; \
|
||||
} while(0)
|
||||
|
||||
|
||||
std::string_view
|
||||
Func2::SymlinkEPALL::name() const
|
||||
|
|
@ -56,14 +55,16 @@ Func2::SymlinkEPALL::operator()(const ugid_t &ugid_,
|
|||
{
|
||||
int rv;
|
||||
int error;
|
||||
bool any;
|
||||
fs::info_t info;
|
||||
Branches::Ptr branches;
|
||||
const Branch *chosen;
|
||||
const Branch *last_success;
|
||||
fs::path fullpath;
|
||||
|
||||
branches = branches_;
|
||||
chosen = nullptr;
|
||||
error = ENOENT;
|
||||
branches = branches_;
|
||||
last_success = nullptr;
|
||||
error = ENOENT;
|
||||
any = false;
|
||||
|
||||
for(auto &branch : *branches)
|
||||
{
|
||||
|
|
@ -79,22 +80,28 @@ Func2::SymlinkEPALL::operator()(const ugid_t &ugid_,
|
|||
if(info.spaceavail < branch.minfreespace())
|
||||
error_and_continue(error,ENOSPC);
|
||||
|
||||
chosen = &branch;
|
||||
break;
|
||||
fullpath = branch.path / linkpath_;
|
||||
rv = fs::symlink_as(ugid_,target_,fullpath);
|
||||
if(rv < 0)
|
||||
{
|
||||
::_calc_error(error,-rv);
|
||||
continue;
|
||||
}
|
||||
|
||||
any = true;
|
||||
last_success = &branch;
|
||||
}
|
||||
|
||||
if(!chosen)
|
||||
if(!any)
|
||||
return -error;
|
||||
|
||||
fullpath = chosen->path / linkpath_;
|
||||
|
||||
rv = fs::symlink_as(ugid_,target_,fullpath);
|
||||
if((rv >= 0) && (st_ != NULL) && (st_->st_ino == 0))
|
||||
if(last_success && (st_ != NULL) && (st_->st_ino == 0))
|
||||
{
|
||||
fullpath = last_success->path / linkpath_;
|
||||
fs::lstat(fullpath,st_);
|
||||
if(st_->st_ino != 0)
|
||||
fs::inode::calc(chosen->path,linkpath_,st_);
|
||||
fs::inode::calc(last_success->path,linkpath_,st_);
|
||||
}
|
||||
|
||||
return rv;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ Func2::SymlinkLUP::operator()(const ugid_t &ugid_,
|
|||
long double ratio;
|
||||
|
||||
if(total == 0)
|
||||
{ used = 0; total = 1; }
|
||||
{ used = 1; total = 1; }
|
||||
ratio = (long double)used / (long double)total;
|
||||
if(ratio >= best_ratio)
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ Func2::SymlinkMSPLFS::operator()(const ugid_t &ugid_,
|
|||
p = p.parent_path())
|
||||
segments.push_back(p);
|
||||
|
||||
dirmode = 0777;
|
||||
dirmode = 0755;
|
||||
for(auto it = segments.rbegin(); it != segments.rend(); ++it)
|
||||
{
|
||||
const Branch *src;
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ Func2::SymlinkMSPLUS::operator()(const ugid_t &ugid_,
|
|||
p = p.parent_path())
|
||||
segments.push_back(p);
|
||||
|
||||
dirmode = 0777;
|
||||
dirmode = 0755;
|
||||
for(auto it = segments.rbegin(); it != segments.rend(); ++it)
|
||||
{
|
||||
const Branch *src;
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ Func2::SymlinkMSPMFS::operator()(const ugid_t &ugid_,
|
|||
p = p.parent_path())
|
||||
segments.push_back(p);
|
||||
|
||||
dirmode = 0777;
|
||||
dirmode = 0755;
|
||||
for(auto it = segments.rbegin(); it != segments.rend(); ++it)
|
||||
{
|
||||
const Branch *src;
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ Func2::SymlinkMSPPFRD::operator()(const ugid_t &ugid_,
|
|||
p = p.parent_path())
|
||||
segments.push_back(p);
|
||||
|
||||
dirmode = 0777;
|
||||
dirmode = 0755;
|
||||
for(auto it = segments.rbegin(); it != segments.rend(); ++it)
|
||||
{
|
||||
const Branch *src;
|
||||
|
|
|
|||
|
|
@ -31,8 +31,13 @@ Func2::TruncateAll::operator()(const Branches &branches_,
|
|||
if(rv == -ENOENT)
|
||||
continue;
|
||||
|
||||
found = true;
|
||||
err = rv;
|
||||
if(!found)
|
||||
{ err = rv; found = true; continue; }
|
||||
if(rv == 0)
|
||||
{ err = 0; continue; }
|
||||
if(err == 0)
|
||||
continue;
|
||||
err = rv;
|
||||
}
|
||||
|
||||
if(!found)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ namespace Func2
|
|||
{
|
||||
public:
|
||||
TruncateBase() {}
|
||||
~TruncateBase() {}
|
||||
virtual ~TruncateBase() = default;
|
||||
|
||||
public:
|
||||
virtual std::string_view name() const = 0;
|
||||
|
|
|
|||
|
|
@ -13,8 +13,27 @@ Func2::TruncateFactory::valid(const std::string str_)
|
|||
std::shared_ptr<Func2::TruncateBase>
|
||||
Func2::TruncateFactory::make(const std::string_view str_)
|
||||
{
|
||||
if(str_ == "erofs") return std::make_shared<Func2::TruncateEROFS>();
|
||||
if(str_ == "all" || str_ == "epall") return std::make_shared<Func2::TruncateAll>();
|
||||
if(str_ == "erofs") return std::make_shared<Func2::TruncateEROFS>();
|
||||
if(str_ == "all") return std::make_shared<Func2::TruncateAll>();
|
||||
if(str_ == "epall") return std::make_shared<Func2::TruncateAll>();
|
||||
if(str_ == "epff") return std::make_shared<Func2::TruncateAll>();
|
||||
if(str_ == "eplfs") return std::make_shared<Func2::TruncateAll>();
|
||||
if(str_ == "eplus") return std::make_shared<Func2::TruncateAll>();
|
||||
if(str_ == "epmfs") return std::make_shared<Func2::TruncateAll>();
|
||||
if(str_ == "eppfrd") return std::make_shared<Func2::TruncateAll>();
|
||||
if(str_ == "eprand") return std::make_shared<Func2::TruncateAll>();
|
||||
if(str_ == "ff") return std::make_shared<Func2::TruncateAll>();
|
||||
if(str_ == "lfs") return std::make_shared<Func2::TruncateAll>();
|
||||
if(str_ == "lup") return std::make_shared<Func2::TruncateAll>();
|
||||
if(str_ == "lus") return std::make_shared<Func2::TruncateAll>();
|
||||
if(str_ == "mfs") return std::make_shared<Func2::TruncateAll>();
|
||||
if(str_ == "msplfs") return std::make_shared<Func2::TruncateAll>();
|
||||
if(str_ == "msplus") return std::make_shared<Func2::TruncateAll>();
|
||||
if(str_ == "mspmfs") return std::make_shared<Func2::TruncateAll>();
|
||||
if(str_ == "msppfrd") return std::make_shared<Func2::TruncateAll>();
|
||||
if(str_ == "newest") return std::make_shared<Func2::TruncateAll>();
|
||||
if(str_ == "pfrd") return std::make_shared<Func2::TruncateAll>();
|
||||
if(str_ == "rand") return std::make_shared<Func2::TruncateAll>();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,8 +30,13 @@ Func2::UnlinkAll::operator()(const Branches &branches_,
|
|||
if(rv == -ENOENT)
|
||||
continue;
|
||||
|
||||
found = true;
|
||||
err = rv;
|
||||
if(!found)
|
||||
{ err = rv; found = true; continue; }
|
||||
if(rv == 0)
|
||||
{ err = 0; continue; }
|
||||
if(err == 0)
|
||||
continue;
|
||||
err = rv;
|
||||
}
|
||||
|
||||
if(!found)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ namespace Func2
|
|||
{
|
||||
public:
|
||||
UnlinkBase() {}
|
||||
~UnlinkBase() {}
|
||||
virtual ~UnlinkBase() = default;
|
||||
|
||||
public:
|
||||
virtual std::string_view name() const = 0;
|
||||
|
|
|
|||
|
|
@ -14,10 +14,27 @@ Func2::UnlinkFactory::valid(const std::string str_)
|
|||
std::shared_ptr<Func2::UnlinkBase>
|
||||
Func2::UnlinkFactory::make(const std::string_view str_)
|
||||
{
|
||||
if(str_ == "all") return std::make_shared<Func2::UnlinkAll>();
|
||||
if(str_ == "epall") return std::make_shared<Func2::UnlinkAll>();
|
||||
if(str_ == "erofs") return std::make_shared<Func2::UnlinkEROFS>();
|
||||
if(str_ == "newest") return std::make_shared<Func2::UnlinkNewest>();
|
||||
if(str_ == "all") return std::make_shared<Func2::UnlinkAll>();
|
||||
if(str_ == "epall") return std::make_shared<Func2::UnlinkAll>();
|
||||
if(str_ == "epff") return std::make_shared<Func2::UnlinkAll>();
|
||||
if(str_ == "eplfs") return std::make_shared<Func2::UnlinkAll>();
|
||||
if(str_ == "eplus") return std::make_shared<Func2::UnlinkAll>();
|
||||
if(str_ == "epmfs") return std::make_shared<Func2::UnlinkAll>();
|
||||
if(str_ == "eppfrd") return std::make_shared<Func2::UnlinkAll>();
|
||||
if(str_ == "eprand") return std::make_shared<Func2::UnlinkAll>();
|
||||
if(str_ == "ff") return std::make_shared<Func2::UnlinkAll>();
|
||||
if(str_ == "lfs") return std::make_shared<Func2::UnlinkAll>();
|
||||
if(str_ == "lup") return std::make_shared<Func2::UnlinkAll>();
|
||||
if(str_ == "lus") return std::make_shared<Func2::UnlinkAll>();
|
||||
if(str_ == "mfs") return std::make_shared<Func2::UnlinkAll>();
|
||||
if(str_ == "msplfs") return std::make_shared<Func2::UnlinkAll>();
|
||||
if(str_ == "msplus") return std::make_shared<Func2::UnlinkAll>();
|
||||
if(str_ == "mspmfs") return std::make_shared<Func2::UnlinkAll>();
|
||||
if(str_ == "msppfrd") return std::make_shared<Func2::UnlinkAll>();
|
||||
if(str_ == "pfrd") return std::make_shared<Func2::UnlinkAll>();
|
||||
if(str_ == "rand") return std::make_shared<Func2::UnlinkAll>();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,8 +31,13 @@ Func2::UtimensAll::operator()(const Branches &branches_,
|
|||
if(rv == -ENOENT)
|
||||
continue;
|
||||
|
||||
found = true;
|
||||
err = rv;
|
||||
if(!found)
|
||||
{ err = rv; found = true; continue; }
|
||||
if(rv == 0)
|
||||
{ err = 0; continue; }
|
||||
if(err == 0)
|
||||
continue;
|
||||
err = rv;
|
||||
}
|
||||
|
||||
if(!found)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ namespace Func2
|
|||
{
|
||||
public:
|
||||
UtimensBase() {}
|
||||
~UtimensBase() {}
|
||||
virtual ~UtimensBase() = default;
|
||||
|
||||
public:
|
||||
virtual std::string_view name() const = 0;
|
||||
|
|
|
|||
|
|
@ -13,8 +13,27 @@ Func2::UtimensFactory::valid(const std::string str_)
|
|||
std::shared_ptr<Func2::UtimensBase>
|
||||
Func2::UtimensFactory::make(const std::string_view str_)
|
||||
{
|
||||
if(str_ == "erofs") return std::make_shared<Func2::UtimensEROFS>();
|
||||
if(str_ == "all" || str_ == "epall") return std::make_shared<Func2::UtimensAll>();
|
||||
if(str_ == "erofs") return std::make_shared<Func2::UtimensEROFS>();
|
||||
if(str_ == "all") return std::make_shared<Func2::UtimensAll>();
|
||||
if(str_ == "epall") return std::make_shared<Func2::UtimensAll>();
|
||||
if(str_ == "epff") return std::make_shared<Func2::UtimensAll>();
|
||||
if(str_ == "eplfs") return std::make_shared<Func2::UtimensAll>();
|
||||
if(str_ == "eplus") return std::make_shared<Func2::UtimensAll>();
|
||||
if(str_ == "epmfs") return std::make_shared<Func2::UtimensAll>();
|
||||
if(str_ == "eppfrd") return std::make_shared<Func2::UtimensAll>();
|
||||
if(str_ == "eprand") return std::make_shared<Func2::UtimensAll>();
|
||||
if(str_ == "ff") return std::make_shared<Func2::UtimensAll>();
|
||||
if(str_ == "lfs") return std::make_shared<Func2::UtimensAll>();
|
||||
if(str_ == "lup") return std::make_shared<Func2::UtimensAll>();
|
||||
if(str_ == "lus") return std::make_shared<Func2::UtimensAll>();
|
||||
if(str_ == "mfs") return std::make_shared<Func2::UtimensAll>();
|
||||
if(str_ == "msplfs") return std::make_shared<Func2::UtimensAll>();
|
||||
if(str_ == "msplus") return std::make_shared<Func2::UtimensAll>();
|
||||
if(str_ == "mspmfs") return std::make_shared<Func2::UtimensAll>();
|
||||
if(str_ == "msppfrd") return std::make_shared<Func2::UtimensAll>();
|
||||
if(str_ == "newest") return std::make_shared<Func2::UtimensAll>();
|
||||
if(str_ == "pfrd") return std::make_shared<Func2::UtimensAll>();
|
||||
if(str_ == "rand") return std::make_shared<Func2::UtimensAll>();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "fuse_link.hpp"
|
||||
|
||||
#include "clone_source.hpp"
|
||||
#include "config.hpp"
|
||||
#include "errno.hpp"
|
||||
#include "fs_clonepath.hpp"
|
||||
|
|
@ -44,6 +45,51 @@ _create_is_path_preserving()
|
|||
return impl && impl->path_preserving();
|
||||
}
|
||||
|
||||
// Path-preserving link: only link on branches that already have BOTH oldpath
|
||||
// and newdir; never clone newdir into branches that lacked it.
|
||||
static
|
||||
int
|
||||
_link_preserve_path(const fs::path &oldpath_,
|
||||
const fs::path &newpath_)
|
||||
{
|
||||
Branches::Ptr branches = cfg.branches;
|
||||
const fs::path newdir = newpath_.parent_path();
|
||||
int err;
|
||||
bool found;
|
||||
fs::path oldfullpath;
|
||||
fs::path newfullpath;
|
||||
|
||||
err = 0;
|
||||
found = false;
|
||||
for(auto &branch : *branches)
|
||||
{
|
||||
if(branch.ro())
|
||||
continue;
|
||||
if(!fs::exists(branch.path,oldpath_))
|
||||
continue;
|
||||
if(!fs::exists(branch.path,newdir))
|
||||
continue;
|
||||
|
||||
oldfullpath = branch.path / oldpath_;
|
||||
newfullpath = branch.path / newpath_;
|
||||
|
||||
const int rv = fs::link(oldfullpath,newfullpath);
|
||||
|
||||
if(!found)
|
||||
{ err = rv; found = true; continue; }
|
||||
if(rv == 0)
|
||||
{ err = 0; continue; }
|
||||
if(err == 0)
|
||||
continue;
|
||||
err = rv;
|
||||
}
|
||||
|
||||
if(!found)
|
||||
return -EXDEV;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_link(const fuse_req_ctx_t *ctx_,
|
||||
|
|
@ -54,27 +100,16 @@ _link(const fuse_req_ctx_t *ctx_,
|
|||
{
|
||||
int rv;
|
||||
|
||||
// Honor path-preserving create policies: don't clone the new path
|
||||
// Honor path-preserving create policies: link only on branches that
|
||||
// already have both old and new-parent path; never clone the new path
|
||||
// structure into branches that don't already have it. Fall through
|
||||
// to the link_exdev handling (PASSTHROUGH/REL_SYMLINK/etc.).
|
||||
// to the link_exdev handling (PASSTHROUGH/REL_SYMLINK/etc.) when no
|
||||
// qualifying branch exists.
|
||||
if(!cfg.ignorepponrename && ::_create_is_path_preserving())
|
||||
{
|
||||
Branches::Ptr branches = cfg.branches;
|
||||
const fs::path newdir = newpath_.parent_path();
|
||||
bool any_target = false;
|
||||
for(const auto &branch : *branches)
|
||||
{
|
||||
if(branch.ro())
|
||||
continue;
|
||||
if(fs::exists(branch.path,oldpath_) &&
|
||||
fs::exists(branch.path,newdir))
|
||||
{ any_target = true; break; }
|
||||
}
|
||||
if(!any_target)
|
||||
return -EXDEV;
|
||||
}
|
||||
rv = ::_link_preserve_path(oldpath_,newpath_);
|
||||
else
|
||||
rv = cfg.link(cfg.branches,oldpath_,newpath_);
|
||||
|
||||
rv = cfg.link(cfg.branches,oldpath_,newpath_);
|
||||
if(rv < 0)
|
||||
return rv;
|
||||
|
||||
|
|
@ -118,25 +153,25 @@ _link_exdev_abs_base_symlink(const fuse_req_ctx_t *ctx_,
|
|||
int rv;
|
||||
fs::path target;
|
||||
|
||||
for(const auto &branch : branches_)
|
||||
{
|
||||
if(!fs::exists(branch.path,oldpath_))
|
||||
continue;
|
||||
// Honor func.open: pick the source branch via the configured open
|
||||
// policy. For 'newest' this picks the branch holding the newest copy
|
||||
// of oldpath; for the other defaults this is first-found.
|
||||
Branches::Ptr branches = branches_;
|
||||
const Branch *src = CloneSource::find(*branches,oldpath_,cfg.open.to_string());
|
||||
if(src == nullptr)
|
||||
return -ENOENT;
|
||||
|
||||
target = branch.path / oldpath_;
|
||||
target = src->path / oldpath_;
|
||||
|
||||
rv = FUSE::symlink(ctx_,target.c_str(),newpath_);
|
||||
if(rv == 0)
|
||||
rv = FUSE::getattr(ctx_,oldpath_,st_,timeouts_);
|
||||
rv = FUSE::symlink(ctx_,target.c_str(),newpath_);
|
||||
if(rv == 0)
|
||||
rv = FUSE::getattr(ctx_,oldpath_,st_,timeouts_);
|
||||
|
||||
// Disable caching since we created a symlink but should be a regular.
|
||||
timeouts_->attr = 0;
|
||||
timeouts_->entry = 0;
|
||||
// Disable caching since we created a symlink but should be a regular.
|
||||
timeouts_->attr = 0;
|
||||
timeouts_->entry = 0;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
return -ENOENT;
|
||||
return rv;
|
||||
}
|
||||
|
||||
static
|
||||
|
|
|
|||
|
|
@ -206,35 +206,90 @@ _create_is_path_preserving()
|
|||
return impl && impl->path_preserving();
|
||||
}
|
||||
|
||||
// Path-preserving rename: rename only on branches that already have BOTH
|
||||
// oldpath and newdir. Never clone newdir into branches that lacked it. Other
|
||||
// branches with oldpath get their stale source queued for removal so the file
|
||||
// does not end up at both old and new paths.
|
||||
static
|
||||
int
|
||||
_rename_preserve_path(const fs::path &oldpath_,
|
||||
const fs::path &newpath_)
|
||||
{
|
||||
Branches::Ptr branches = cfg.branches;
|
||||
const fs::path newdir = newpath_.parent_path();
|
||||
StrVec toremove;
|
||||
int err;
|
||||
bool found;
|
||||
fs::path oldfullpath;
|
||||
fs::path newfullpath;
|
||||
|
||||
err = 0;
|
||||
found = false;
|
||||
for(auto &branch : *branches)
|
||||
{
|
||||
if(branch.ro())
|
||||
continue;
|
||||
|
||||
oldfullpath = branch.path / oldpath_;
|
||||
newfullpath = branch.path / newpath_;
|
||||
|
||||
const bool has_old = fs::exists(branch.path,oldpath_);
|
||||
const bool has_newdir = fs::exists(branch.path,newdir);
|
||||
|
||||
if(!has_old)
|
||||
{
|
||||
if(has_newdir)
|
||||
toremove.push_back(newfullpath);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!has_newdir)
|
||||
{
|
||||
// Branch has source but lacks newdir. Path-preserving: do NOT
|
||||
// clonepath. Queue source for removal on overall success so the
|
||||
// file ends up only at branches that did rename successfully.
|
||||
toremove.push_back(oldfullpath);
|
||||
continue;
|
||||
}
|
||||
|
||||
const int rv = fs::rename(oldfullpath,newfullpath);
|
||||
if(rv < 0)
|
||||
toremove.push_back(oldfullpath);
|
||||
|
||||
if(!found)
|
||||
{ err = rv; found = true; continue; }
|
||||
if(rv == 0)
|
||||
{ err = 0; continue; }
|
||||
if(err == 0)
|
||||
continue;
|
||||
err = rv;
|
||||
}
|
||||
|
||||
if(!found)
|
||||
return -EXDEV;
|
||||
|
||||
if(err == 0)
|
||||
{
|
||||
for(const auto &path : toremove)
|
||||
fs::remove(path);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_rename(const fs::path &oldpath_,
|
||||
const fs::path &newpath_)
|
||||
{
|
||||
// Honor ignorepponrename: when the create policy is path-preserving
|
||||
// and the user has not opted out, refuse to clone the new path
|
||||
// structure into branches that don't already have it. The fallback
|
||||
// is the EXDEV path which lets the caller handle the move via
|
||||
// copy+unlink or symlink per cfg.rename_exdev.
|
||||
// Honor ignorepponrename: when the create policy is path-preserving and
|
||||
// the user has not opted out, perform the rename only on branches that
|
||||
// already have both oldpath and newdir — never clone newdir into a branch
|
||||
// that previously lacked it. Fall through to EXDEV when no qualifying
|
||||
// branch exists, letting cfg.rename_exdev decide on copy+unlink or
|
||||
// symlink fallback.
|
||||
if(!cfg.ignorepponrename && ::_create_is_path_preserving())
|
||||
{
|
||||
// Snapshot the Branches::Impl so the per-branch fs::exists
|
||||
// calls below all observe the same set of branches even if
|
||||
// cfg.branches is concurrently mutated.
|
||||
Branches::Ptr branches = cfg.branches;
|
||||
const fs::path newdir = newpath_.parent_path();
|
||||
bool any_target = false;
|
||||
for(const auto &branch : *branches)
|
||||
{
|
||||
if(branch.ro())
|
||||
continue;
|
||||
if(fs::exists(branch.path,oldpath_) &&
|
||||
fs::exists(branch.path,newdir))
|
||||
{ any_target = true; break; }
|
||||
}
|
||||
if(!any_target)
|
||||
return -EXDEV;
|
||||
}
|
||||
return ::_rename_preserve_path(oldpath_,newpath_);
|
||||
|
||||
return cfg.rename(cfg.branches,oldpath_,newpath_);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,8 @@ _move_and_pwrite(const char *buf_,
|
|||
if(cfg.moveonenospc.enabled == false)
|
||||
return err_;
|
||||
|
||||
rv = fs::movefile_and_open_as_root(cfg.branches,
|
||||
rv = fs::movefile_and_open_as_root(cfg.moveonenospc.policy_name,
|
||||
cfg.branches,
|
||||
fi_->branch.path,
|
||||
fi_->fusepath,
|
||||
fi_->fd);
|
||||
|
|
@ -89,7 +90,8 @@ _move_and_pwriten(char const *buf_,
|
|||
if(cfg.moveonenospc.enabled == false)
|
||||
return err_;
|
||||
|
||||
rv = fs::movefile_and_open_as_root(cfg.branches,
|
||||
rv = fs::movefile_and_open_as_root(cfg.moveonenospc.policy_name,
|
||||
cfg.branches,
|
||||
fi_->branch.path,
|
||||
fi_->fusepath,
|
||||
fi_->fd);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue