mirror of https://github.com/trapexit/mergerfs.git
Browse Source
Change getattr and statx to bespoke policies
Change getattr and statx to bespoke policies
* Provides: slight improvement in performance as it no longer will need to find and then act on the files. * It doesn't make sense to support all original policy types. Most people used 'newest' or 'ff' and 'combine' is a better default which has same runtime as 'newest' but with better output.bespoke-policies
125 changed files with 3901 additions and 751 deletions
-
17src/config.cpp
-
26src/config.hpp
-
8src/config_follow_symlinks.hpp
-
9src/follow_symlinks_enum.hpp
-
17src/fs_lstat.hpp
-
0src/fs_stat.cpp
-
59src/fs_stat.hpp
-
61src/fs_statx.hpp
-
36src/fsproxy.cpp
-
54src/fsproxy.hpp
-
73src/func_access.hpp
-
29src/func_access_all.cpp
-
19src/func_access_all.hpp
-
24src/func_access_base.hpp
-
30src/func_access_factory.cpp
-
13src/func_access_factory.hpp
-
73src/func_chmod.hpp
-
35src/func_chmod_all.cpp
-
19src/func_chmod_all.hpp
-
23src/func_chmod_base.hpp
-
30src/func_chmod_factory.cpp
-
13src/func_chmod_factory.hpp
-
75src/func_chown.hpp
-
36src/func_chown_all.cpp
-
20src/func_chown_all.hpp
-
24src/func_chown_base.hpp
-
30src/func_chown_factory.cpp
-
13src/func_chown_factory.hpp
-
76src/func_getattr.hpp
-
35src/func_getattr_base.hpp
-
71src/func_getattr_combine.cpp
-
21src/func_getattr_combine.hpp
-
39src/func_getattr_factory.cpp
-
13src/func_getattr_factory.hpp
-
41src/func_getattr_ff.cpp
-
23src/func_getattr_ff.hpp
-
57src/func_getattr_newest.cpp
-
21src/func_getattr_newest.hpp
-
77src/func_getxattr.hpp
-
25src/func_getxattr_base.hpp
-
30src/func_getxattr_factory.cpp
-
13src/func_getxattr_factory.hpp
-
35src/func_getxattr_ff.cpp
-
21src/func_getxattr_ff.hpp
-
73src/func_ioctl.hpp
-
25src/func_ioctl_all.cpp
-
18src/func_ioctl_all.hpp
-
22src/func_ioctl_base.hpp
-
30src/func_ioctl_factory.cpp
-
13src/func_ioctl_factory.hpp
-
73src/func_listxattr.hpp
-
27src/func_listxattr_all.cpp
-
20src/func_listxattr_all.hpp
-
24src/func_listxattr_base.hpp
-
30src/func_listxattr_factory.cpp
-
13src/func_listxattr_factory.hpp
-
73src/func_open.hpp
-
27src/func_open_all.cpp
-
19src/func_open_all.hpp
-
23src/func_open_base.hpp
-
30src/func_open_factory.cpp
-
13src/func_open_factory.hpp
-
75src/func_readlink.hpp
-
28src/func_readlink_all.cpp
-
20src/func_readlink_all.hpp
-
24src/func_readlink_base.hpp
-
30src/func_readlink_factory.cpp
-
13src/func_readlink_factory.hpp
-
73src/func_removexattr.hpp
-
35src/func_removexattr_all.cpp
-
19src/func_removexattr_all.hpp
-
23src/func_removexattr_base.hpp
-
30src/func_removexattr_factory.cpp
-
13src/func_removexattr_factory.hpp
-
71src/func_rmdir.hpp
-
50src/func_rmdir_all.cpp
-
18src/func_rmdir_all.hpp
-
22src/func_rmdir_base.hpp
-
30src/func_rmdir_factory.cpp
-
13src/func_rmdir_factory.hpp
-
79src/func_setxattr.hpp
-
38src/func_setxattr_all.cpp
-
22src/func_setxattr_all.hpp
-
26src/func_setxattr_base.hpp
-
30src/func_setxattr_factory.cpp
-
13src/func_setxattr_factory.hpp
-
81src/func_statx.hpp
-
38src/func_statx_base.hpp
-
79src/func_statx_combine.cpp
-
23src/func_statx_combine.hpp
-
39src/func_statx_factory.cpp
-
13src/func_statx_factory.hpp
-
48src/func_statx_ff.cpp
-
25src/func_statx_ff.hpp
-
64src/func_statx_newest.cpp
-
23src/func_statx_newest.hpp
-
73src/func_truncate.hpp
-
35src/func_truncate_all.cpp
-
19src/func_truncate_all.hpp
-
23src/func_truncate_base.hpp
@ -0,0 +1,9 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
enum class FollowSymlinksEnum |
||||
|
{ |
||||
|
NEVER, |
||||
|
DIRECTORY, |
||||
|
REGULAR, |
||||
|
ALL |
||||
|
}; |
||||
@ -0,0 +1,36 @@ |
|||||
|
#include "fsproxy.hpp"
|
||||
|
|
||||
|
#include "fs_close.hpp"
|
||||
|
|
||||
|
int |
||||
|
FSProxy::_spawn_proxy_if_needed(const uid_t uid_, |
||||
|
const gid_t gid_) |
||||
|
{ |
||||
|
int rv; |
||||
|
FSProxy::Process process; |
||||
|
|
||||
|
if(_proxies.count({uid_,gid_})) |
||||
|
return 0; |
||||
|
|
||||
|
rv = pipe(process.req_pipe); |
||||
|
if(rv == -1) |
||||
|
return rv; |
||||
|
rv = pipe(process.res_pipe); |
||||
|
if(rv == -1) |
||||
|
return rv; |
||||
|
|
||||
|
process.pid = fork(); |
||||
|
if(process.pid != 0) |
||||
|
{ |
||||
|
fs::close(process.req_pipe[1]); |
||||
|
fs::close(process.res_pipe[0]); |
||||
|
// listen on req in loop for instructions
|
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
fs::close(process.req_pipe[0]); |
||||
|
fs::close(process.res_pipe[1]); |
||||
|
_proxies[UGID{uid_,gid_}] = process; |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
@ -0,0 +1,54 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include <unordered_map>
|
||||
|
|
||||
|
#include <fcntl.h>
|
||||
|
#include <unistd.h>
|
||||
|
|
||||
|
class FSProxy |
||||
|
{ |
||||
|
public: |
||||
|
struct UGID |
||||
|
{ |
||||
|
bool |
||||
|
operator==(const UGID &other_) const |
||||
|
{ |
||||
|
return ((uid == other_.uid) && |
||||
|
(gid == other_.gid)); |
||||
|
} |
||||
|
|
||||
|
uid_t uid; |
||||
|
gid_t gid; |
||||
|
}; |
||||
|
|
||||
|
struct UGIDHash |
||||
|
{ |
||||
|
size_t |
||||
|
operator()(const UGID &key_) const |
||||
|
{ |
||||
|
size_t h0 = std::hash<uid_t>{}(key_.uid); |
||||
|
size_t h1 = std::hash<uid_t>{}(key_.gid); |
||||
|
|
||||
|
return (h0 ^ (h1 << 1)); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
struct Process |
||||
|
{ |
||||
|
int pid; |
||||
|
int req_pipe[2]; |
||||
|
int res_pipe[2]; |
||||
|
}; |
||||
|
|
||||
|
public: |
||||
|
int create(uid_t uid, |
||||
|
gid_t gid, |
||||
|
const char *pathname, |
||||
|
mode_t mode); |
||||
|
|
||||
|
private: |
||||
|
int _spawn_proxy_if_needed(uid_t,gid_t); |
||||
|
|
||||
|
private: |
||||
|
std::unordered_map<UGID,Process,UGIDHash> _proxies; |
||||
|
}; |
||||
@ -0,0 +1,73 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "func_access_base.hpp"
|
||||
|
#include "func_access_factory.hpp"
|
||||
|
|
||||
|
#include "tofrom_string.hpp"
|
||||
|
|
||||
|
#include "fmt/core.h"
|
||||
|
|
||||
|
#include <atomic>
|
||||
|
|
||||
|
#include <cassert>
|
||||
|
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class Access : public ToFromString |
||||
|
{ |
||||
|
private: |
||||
|
std::shared_ptr<Func2::AccessBase> _impl; |
||||
|
|
||||
|
public: |
||||
|
Access() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
Access(const std::string &name_) |
||||
|
{ |
||||
|
_impl = Func2::AccessFactory::make(name_); |
||||
|
assert(_impl); |
||||
|
} |
||||
|
|
||||
|
public: |
||||
|
int |
||||
|
operator()(const Branches &branches_, |
||||
|
const fs::path &fusepath_, |
||||
|
const mode_t mode_) |
||||
|
{ |
||||
|
std::shared_ptr<Func2::AccessBase> p; |
||||
|
|
||||
|
p = std::atomic_load(&_impl); |
||||
|
|
||||
|
return (*p)(branches_, |
||||
|
fusepath_, |
||||
|
mode_); |
||||
|
} |
||||
|
|
||||
|
public: |
||||
|
std::string |
||||
|
to_string() const |
||||
|
{ |
||||
|
std::shared_ptr<Func2::AccessBase> p; |
||||
|
|
||||
|
p = std::atomic_load(&_impl); |
||||
|
|
||||
|
return std::string{p->name()}; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
from_string(const std::string_view str_) |
||||
|
{ |
||||
|
std::shared_ptr<Func2::AccessBase> p; |
||||
|
|
||||
|
p = Func2::AccessFactory::make(str_); |
||||
|
if(!p) |
||||
|
return -EINVAL; |
||||
|
|
||||
|
_impl = std::atomic_load(&p); |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,29 @@ |
|||||
|
#include "func_access_all.hpp"
|
||||
|
|
||||
|
#include "error.hpp"
|
||||
|
#include "fs_eaccess.hpp"
|
||||
|
|
||||
|
|
||||
|
std::string_view |
||||
|
Func2::AccessAll::name() const |
||||
|
{ |
||||
|
return "all"; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
Func2::AccessAll::operator()(const Branches &branches_, |
||||
|
const fs::path &fusepath_, |
||||
|
const int mode_) |
||||
|
{ |
||||
|
Err err; |
||||
|
fs::path fullpath; |
||||
|
|
||||
|
for(const auto &branch : branches_) |
||||
|
{ |
||||
|
fullpath = branch.path / fusepath_; |
||||
|
|
||||
|
err = fs::eaccess(fullpath,mode_); |
||||
|
} |
||||
|
|
||||
|
return err; |
||||
|
} |
||||
@ -0,0 +1,19 @@ |
|||||
|
#include "func_access_base.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class AccessAll : public AccessBase |
||||
|
{ |
||||
|
public: |
||||
|
AccessAll() {} |
||||
|
~AccessAll() {} |
||||
|
|
||||
|
public: |
||||
|
std::string_view name() const; |
||||
|
|
||||
|
public: |
||||
|
int operator()(const Branches &branches, |
||||
|
const fs::path &fusepath, |
||||
|
const int mode); |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,24 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "branches.hpp"
|
||||
|
|
||||
|
#include "fs_path.hpp"
|
||||
|
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class AccessBase |
||||
|
{ |
||||
|
public: |
||||
|
AccessBase() {} |
||||
|
~AccessBase() {} |
||||
|
|
||||
|
public: |
||||
|
virtual std::string_view name() const = 0; |
||||
|
|
||||
|
public: |
||||
|
virtual int operator()(const Branches &branches, |
||||
|
const fs::path &fusepath, |
||||
|
const int mode) = 0; |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,30 @@ |
|||||
|
#include "func_access_factory.hpp"
|
||||
|
|
||||
|
#include "func_access_all.hpp"
|
||||
|
|
||||
|
#include "policies.hpp"
|
||||
|
|
||||
|
|
||||
|
bool |
||||
|
Func2::AccessFactory::valid(const std::string str_) |
||||
|
{ |
||||
|
if(str_ == "all") |
||||
|
return true; |
||||
|
|
||||
|
if(Policies::Action::find(str_)) |
||||
|
return true; |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
std::shared_ptr<Func2::AccessBase> |
||||
|
Func2::AccessFactory::make(const std::string_view str_) |
||||
|
{ |
||||
|
if(str_ == "all") |
||||
|
return std::make_shared<Func2::AccessAll>(); |
||||
|
|
||||
|
if(Policies::Action::find(str_)) |
||||
|
return std::make_shared<Func2::AccessAll>(); |
||||
|
|
||||
|
return {}; |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "func_access_base.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class AccessFactory |
||||
|
{ |
||||
|
public: |
||||
|
static bool valid(const std::string str); |
||||
|
static std::shared_ptr<AccessBase> make(const std::string_view str); |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,73 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "func_chmod_base.hpp"
|
||||
|
#include "func_chmod_factory.hpp"
|
||||
|
|
||||
|
#include "tofrom_string.hpp"
|
||||
|
|
||||
|
#include "fmt/core.h"
|
||||
|
|
||||
|
#include <atomic>
|
||||
|
|
||||
|
#include <cassert>
|
||||
|
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class Chmod : public ToFromString |
||||
|
{ |
||||
|
private: |
||||
|
std::shared_ptr<Func2::ChmodBase> _impl; |
||||
|
|
||||
|
public: |
||||
|
Chmod() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
Chmod(const std::string &name_) |
||||
|
{ |
||||
|
_impl = Func2::ChmodFactory::make(name_); |
||||
|
assert(_impl); |
||||
|
} |
||||
|
|
||||
|
public: |
||||
|
int |
||||
|
operator()(const Branches &branches_, |
||||
|
const fs::path &fusepath_, |
||||
|
const mode_t mode_) |
||||
|
{ |
||||
|
std::shared_ptr<Func2::ChmodBase> p; |
||||
|
|
||||
|
p = std::atomic_load(&_impl); |
||||
|
|
||||
|
return (*p)(branches_, |
||||
|
fusepath_, |
||||
|
mode_); |
||||
|
} |
||||
|
|
||||
|
public: |
||||
|
std::string |
||||
|
to_string() const |
||||
|
{ |
||||
|
std::shared_ptr<Func2::ChmodBase> p; |
||||
|
|
||||
|
p = std::atomic_load(&_impl); |
||||
|
|
||||
|
return std::string{p->name()}; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
from_string(const std::string_view str_) |
||||
|
{ |
||||
|
std::shared_ptr<Func2::ChmodBase> p; |
||||
|
|
||||
|
p = Func2::ChmodFactory::make(str_); |
||||
|
if(!p) |
||||
|
return -EINVAL; |
||||
|
|
||||
|
_impl = std::atomic_load(&p); |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,35 @@ |
|||||
|
#include "func_chmod_all.hpp"
|
||||
|
|
||||
|
#include "error.hpp"
|
||||
|
#include "fs_lchmod.hpp"
|
||||
|
|
||||
|
|
||||
|
std::string_view |
||||
|
Func2::ChmodAll::name() const |
||||
|
{ |
||||
|
return "all"; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
Func2::ChmodAll::operator()(const Branches &branches_, |
||||
|
const fs::path &fusepath_, |
||||
|
const mode_t mode_) |
||||
|
{ |
||||
|
Err err; |
||||
|
fs::path fullpath; |
||||
|
|
||||
|
for(const auto &branch : branches_) |
||||
|
{ |
||||
|
if(branch.ro()) |
||||
|
{ |
||||
|
err = -EROFS; |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
fullpath = branch.path / fusepath_; |
||||
|
|
||||
|
err = fs::lchmod(fullpath,mode_); |
||||
|
} |
||||
|
|
||||
|
return err; |
||||
|
} |
||||
@ -0,0 +1,19 @@ |
|||||
|
#include "func_chmod_base.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class ChmodAll : public ChmodBase |
||||
|
{ |
||||
|
public: |
||||
|
ChmodAll() {} |
||||
|
~ChmodAll() {} |
||||
|
|
||||
|
public: |
||||
|
std::string_view name() const; |
||||
|
|
||||
|
public: |
||||
|
int operator()(const Branches &branches, |
||||
|
const fs::path &fusepath, |
||||
|
const mode_t mode); |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "branches.hpp"
|
||||
|
|
||||
|
#include "fs_path.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class ChmodBase |
||||
|
{ |
||||
|
public: |
||||
|
ChmodBase() {} |
||||
|
~ChmodBase() {} |
||||
|
|
||||
|
public: |
||||
|
virtual std::string_view name() const = 0; |
||||
|
|
||||
|
public: |
||||
|
virtual int operator()(const Branches &branches, |
||||
|
const fs::path &fusepath, |
||||
|
const mode_t mode) = 0; |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,30 @@ |
|||||
|
#include "func_chmod_factory.hpp"
|
||||
|
|
||||
|
#include "func_chmod_all.hpp"
|
||||
|
|
||||
|
#include "policies.hpp"
|
||||
|
|
||||
|
|
||||
|
bool |
||||
|
Func2::ChmodFactory::valid(const std::string str_) |
||||
|
{ |
||||
|
if(str_ == "all") |
||||
|
return true; |
||||
|
|
||||
|
if(Policies::Action::find(str_)) |
||||
|
return true; |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
std::shared_ptr<Func2::ChmodBase> |
||||
|
Func2::ChmodFactory::make(const std::string_view str_) |
||||
|
{ |
||||
|
if(str_ == "all") |
||||
|
return std::make_shared<Func2::ChmodAll>(); |
||||
|
|
||||
|
if(Policies::Action::find(str_)) |
||||
|
return std::make_shared<Func2::ChmodAll>(); |
||||
|
|
||||
|
return {}; |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "func_chmod_base.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class ChmodFactory |
||||
|
{ |
||||
|
public: |
||||
|
static bool valid(const std::string str); |
||||
|
static std::shared_ptr<ChmodBase> make(const std::string_view str); |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,75 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "func_chown_base.hpp"
|
||||
|
#include "func_chown_factory.hpp"
|
||||
|
|
||||
|
#include "tofrom_string.hpp"
|
||||
|
|
||||
|
#include "fmt/core.h"
|
||||
|
|
||||
|
#include <atomic>
|
||||
|
|
||||
|
#include <cassert>
|
||||
|
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class Chown : public ToFromString |
||||
|
{ |
||||
|
private: |
||||
|
std::shared_ptr<Func2::ChownBase> _impl; |
||||
|
|
||||
|
public: |
||||
|
Chown() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
Chown(const std::string &name_) |
||||
|
{ |
||||
|
_impl = Func2::ChownFactory::make(name_); |
||||
|
assert(_impl); |
||||
|
} |
||||
|
|
||||
|
public: |
||||
|
int |
||||
|
operator()(const Branches &branches_, |
||||
|
const fs::path &fusepath_, |
||||
|
const uid_t uid_, |
||||
|
const gid_t gid_) |
||||
|
{ |
||||
|
std::shared_ptr<Func2::ChownBase> p; |
||||
|
|
||||
|
p = std::atomic_load(&_impl); |
||||
|
|
||||
|
return (*p)(branches_, |
||||
|
fusepath_, |
||||
|
uid_, |
||||
|
gid_); |
||||
|
} |
||||
|
|
||||
|
public: |
||||
|
std::string |
||||
|
to_string() const |
||||
|
{ |
||||
|
std::shared_ptr<Func2::ChownBase> p; |
||||
|
|
||||
|
p = std::atomic_load(&_impl); |
||||
|
|
||||
|
return std::string{p->name()}; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
from_string(const std::string_view str_) |
||||
|
{ |
||||
|
std::shared_ptr<Func2::ChownBase> p; |
||||
|
|
||||
|
p = Func2::ChownFactory::make(str_); |
||||
|
if(!p) |
||||
|
return -EINVAL; |
||||
|
|
||||
|
_impl = std::atomic_load(&p); |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,36 @@ |
|||||
|
#include "func_chown_all.hpp"
|
||||
|
|
||||
|
#include "error.hpp"
|
||||
|
#include "fs_lchown.hpp"
|
||||
|
|
||||
|
|
||||
|
std::string_view |
||||
|
Func2::ChownAll::name() const |
||||
|
{ |
||||
|
return "all"; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
Func2::ChownAll::operator()(const Branches &branches_, |
||||
|
const fs::path &fusepath_, |
||||
|
const uid_t uid_, |
||||
|
const gid_t gid_) |
||||
|
{ |
||||
|
Err err; |
||||
|
fs::path fullpath; |
||||
|
|
||||
|
for(const auto &branch : branches_) |
||||
|
{ |
||||
|
if(branch.ro()) |
||||
|
{ |
||||
|
err = -EROFS; |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
fullpath = branch.path / fusepath_; |
||||
|
|
||||
|
err = fs::lchown(fullpath,uid_,gid_); |
||||
|
} |
||||
|
|
||||
|
return err; |
||||
|
} |
||||
@ -0,0 +1,20 @@ |
|||||
|
#include "func_chown_base.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class ChownAll : public ChownBase |
||||
|
{ |
||||
|
public: |
||||
|
ChownAll() {} |
||||
|
~ChownAll() {} |
||||
|
|
||||
|
public: |
||||
|
std::string_view name() const; |
||||
|
|
||||
|
public: |
||||
|
int operator()(const Branches &branches, |
||||
|
const fs::path &fusepath, |
||||
|
const uid_t uid, |
||||
|
const gid_t gid); |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,24 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "branches.hpp"
|
||||
|
|
||||
|
#include "fs_path.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class ChownBase |
||||
|
{ |
||||
|
public: |
||||
|
ChownBase() {} |
||||
|
~ChownBase() {} |
||||
|
|
||||
|
public: |
||||
|
virtual std::string_view name() const = 0; |
||||
|
|
||||
|
public: |
||||
|
virtual int operator()(const Branches &branches, |
||||
|
const fs::path &fusepath, |
||||
|
const uid_t uid, |
||||
|
const gid_t gid) = 0; |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,30 @@ |
|||||
|
#include "func_chown_factory.hpp"
|
||||
|
|
||||
|
#include "func_chown_all.hpp"
|
||||
|
|
||||
|
#include "policies.hpp"
|
||||
|
|
||||
|
|
||||
|
bool |
||||
|
Func2::ChownFactory::valid(const std::string str_) |
||||
|
{ |
||||
|
if(str_ == "all") |
||||
|
return true; |
||||
|
|
||||
|
if(Policies::Action::find(str_)) |
||||
|
return true; |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
std::shared_ptr<Func2::ChownBase> |
||||
|
Func2::ChownFactory::make(const std::string_view str_) |
||||
|
{ |
||||
|
if(str_ == "all") |
||||
|
return std::make_shared<Func2::ChownAll>(); |
||||
|
|
||||
|
if(Policies::Action::find(str_)) |
||||
|
return std::make_shared<Func2::ChownAll>(); |
||||
|
|
||||
|
return {}; |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "func_chown_base.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class ChownFactory |
||||
|
{ |
||||
|
public: |
||||
|
static bool valid(const std::string str); |
||||
|
static std::shared_ptr<ChownBase> make(const std::string_view str); |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,76 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "func_getattr_base.hpp"
|
||||
|
#include "func_getattr_factory.hpp"
|
||||
|
|
||||
|
#include "tofrom_string.hpp"
|
||||
|
|
||||
|
#include "fmt/core.h"
|
||||
|
|
||||
|
#include <atomic>
|
||||
|
|
||||
|
#include <cassert>
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class GetAttr : public ToFromString |
||||
|
{ |
||||
|
private: |
||||
|
std::shared_ptr<Func2::GetAttrBase> _impl; |
||||
|
|
||||
|
public: |
||||
|
GetAttr() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
GetAttr(const std::string &name_) |
||||
|
{ |
||||
|
_impl = Func2::GetAttrFactory::make(name_); |
||||
|
assert(_impl); |
||||
|
} |
||||
|
|
||||
|
public: |
||||
|
int |
||||
|
operator()(const Branches &branches_, |
||||
|
const fs::path &fusepath_, |
||||
|
struct stat *st_, |
||||
|
const FollowSymlinksEnum follow_symlinks_, |
||||
|
const s64 symlinkify_timeout_) |
||||
|
{ |
||||
|
std::shared_ptr<Func2::GetAttrBase> p; |
||||
|
|
||||
|
p = std::atomic_load(&_impl); |
||||
|
|
||||
|
return (*p)(branches_, |
||||
|
fusepath_, |
||||
|
st_, |
||||
|
follow_symlinks_, |
||||
|
symlinkify_timeout_); |
||||
|
} |
||||
|
|
||||
|
public: |
||||
|
std::string |
||||
|
to_string() const |
||||
|
{ |
||||
|
std::shared_ptr<Func2::GetAttrBase> p; |
||||
|
|
||||
|
p = std::atomic_load(&_impl); |
||||
|
|
||||
|
return std::string(p->name()); |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
from_string(const std::string_view str_) |
||||
|
{ |
||||
|
std::shared_ptr<Func2::GetAttrBase> p; |
||||
|
|
||||
|
p = Func2::GetAttrFactory::make(str_); |
||||
|
if(!p) |
||||
|
return -EINVAL; |
||||
|
|
||||
|
_impl = std::atomic_load(&p); |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,35 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "follow_symlinks_enum.hpp"
|
||||
|
|
||||
|
#include "fs_path.hpp"
|
||||
|
#include "branches.hpp"
|
||||
|
#include "int_types.h"
|
||||
|
|
||||
|
#include "fuse.h"
|
||||
|
|
||||
|
#include <string_view>
|
||||
|
|
||||
|
#include <sys/types.h>
|
||||
|
#include <sys/stat.h>
|
||||
|
#include <unistd.h>
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class GetAttrBase |
||||
|
{ |
||||
|
public: |
||||
|
GetAttrBase() {} |
||||
|
~GetAttrBase() {} |
||||
|
|
||||
|
public: |
||||
|
virtual std::string_view name() const = 0; |
||||
|
|
||||
|
public: |
||||
|
virtual int operator()(const Branches &branches, |
||||
|
const fs::path &fusepath, |
||||
|
struct stat *st, |
||||
|
const FollowSymlinksEnum follow_symlinks, |
||||
|
const s64 symlinkify_timeout) = 0; |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,71 @@ |
|||||
|
#include "func_getattr_combine.hpp"
|
||||
|
|
||||
|
#include "fs_inode.hpp"
|
||||
|
#include "fs_stat.hpp"
|
||||
|
#include "symlinkify.hpp"
|
||||
|
#include "timespec_utils.hpp"
|
||||
|
|
||||
|
|
||||
|
std::string_view |
||||
|
Func2::GetAttrCombine::name() const |
||||
|
{ |
||||
|
return "combine"; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
Func2::GetAttrCombine::operator()(const Branches &branches_, |
||||
|
const fs::path &fusepath_, |
||||
|
struct stat *st_, |
||||
|
const FollowSymlinksEnum follow_symlinks_, |
||||
|
const s64 symlinkify_timeout_) |
||||
|
{ |
||||
|
int rv; |
||||
|
fs::path fullpath; |
||||
|
const Branch *first_branch; |
||||
|
|
||||
|
first_branch = nullptr; |
||||
|
for(const auto &branch : branches_) |
||||
|
{ |
||||
|
struct stat tmp_st; |
||||
|
|
||||
|
fullpath = branch.path / fusepath_; |
||||
|
rv = fs::stat(fullpath,&tmp_st,follow_symlinks_); |
||||
|
if(rv < 0) |
||||
|
continue; |
||||
|
|
||||
|
if(!first_branch) |
||||
|
{ |
||||
|
*st_ = tmp_st; |
||||
|
first_branch = &branch; |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
// This upgrades the uid:gid because mergerfs now does most
|
||||
|
// file interaction as root and relies on `default_permissions`
|
||||
|
// to manage permissions. Want to ensure that root owned files
|
||||
|
// can't be changed so we treat them all as root owned.
|
||||
|
if(tmp_st.st_uid == 0) |
||||
|
st_->st_uid = 0; |
||||
|
if(tmp_st.st_gid == 0) |
||||
|
st_->st_gid = 0; |
||||
|
st_->st_atim = TimeSpec::newest(st_->st_atim,tmp_st.st_atim); |
||||
|
st_->st_ctim = TimeSpec::newest(st_->st_ctim,tmp_st.st_ctim); |
||||
|
st_->st_mtim = TimeSpec::newest(st_->st_mtim,tmp_st.st_mtim); |
||||
|
st_->st_nlink += tmp_st.st_nlink; |
||||
|
} |
||||
|
|
||||
|
if(!first_branch) |
||||
|
return -ENOENT; |
||||
|
|
||||
|
if(symlinkify_timeout_ >= 0) |
||||
|
{ |
||||
|
fullpath = first_branch->path / fusepath_; |
||||
|
symlinkify::convert_if_can_be_symlink(fullpath, |
||||
|
st_, |
||||
|
symlinkify_timeout_); |
||||
|
} |
||||
|
|
||||
|
fs::inode::calc(first_branch->path,fusepath_,st_); |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
@ -0,0 +1,21 @@ |
|||||
|
#include "func_getattr_base.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class GetAttrCombine : public GetAttrBase |
||||
|
{ |
||||
|
public: |
||||
|
GetAttrCombine() {} |
||||
|
~GetAttrCombine() {} |
||||
|
|
||||
|
public: |
||||
|
std::string_view name() const; |
||||
|
|
||||
|
public: |
||||
|
int operator()(const Branches &branches, |
||||
|
const fs::path &fusepath, |
||||
|
struct stat *st, |
||||
|
const FollowSymlinksEnum follow_symlinks, |
||||
|
const s64 symlinkify_timeout); |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,39 @@ |
|||||
|
#include "func_getattr_factory.hpp"
|
||||
|
|
||||
|
#include "func_getattr_combine.hpp"
|
||||
|
#include "func_getattr_ff.hpp"
|
||||
|
#include "func_getattr_newest.hpp"
|
||||
|
|
||||
|
#include "policies.hpp"
|
||||
|
|
||||
|
bool |
||||
|
Func2::GetAttrFactory::valid(const std::string str_) |
||||
|
{ |
||||
|
if(str_ == "combined") |
||||
|
return true; |
||||
|
if(str_ == "ff") |
||||
|
return true; |
||||
|
if(str_ == "newest") |
||||
|
return true; |
||||
|
|
||||
|
if(Policies::Search::find(str_)) |
||||
|
return true; |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
std::shared_ptr<Func2::GetAttrBase> |
||||
|
Func2::GetAttrFactory::make(const std::string_view str_) |
||||
|
{ |
||||
|
if(str_ == "combine") |
||||
|
return std::make_shared<Func2::GetAttrCombine>(); |
||||
|
if(str_ == "ff") |
||||
|
return std::make_shared<Func2::GetAttrFF>(); |
||||
|
if(str_ == "newest") |
||||
|
return std::make_shared<Func2::GetAttrNewest>(); |
||||
|
|
||||
|
if(Policies::Search::find(str_)) |
||||
|
return std::make_shared<Func2::GetAttrCombine>(); |
||||
|
|
||||
|
return {}; |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "func_getattr_base.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class GetAttrFactory |
||||
|
{ |
||||
|
public: |
||||
|
static bool valid(const std::string str); |
||||
|
static std::shared_ptr<GetAttrBase> make(const std::string_view str); |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,41 @@ |
|||||
|
#include "func_getattr_ff.hpp"
|
||||
|
|
||||
|
#include "fs_stat.hpp"
|
||||
|
#include "fs_inode.hpp"
|
||||
|
#include "symlinkify.hpp"
|
||||
|
|
||||
|
|
||||
|
std::string_view |
||||
|
Func2::GetAttrFF::name() const |
||||
|
{ |
||||
|
return "ff"; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
Func2::GetAttrFF::operator()(const Branches &branches_, |
||||
|
const fs::path &fusepath_, |
||||
|
struct stat *st_, |
||||
|
const FollowSymlinksEnum follow_symlinks_, |
||||
|
const s64 symlinkify_timeout_) |
||||
|
{ |
||||
|
int rv; |
||||
|
fs::path fullpath; |
||||
|
|
||||
|
for(const auto &branch : branches_) |
||||
|
{ |
||||
|
fullpath = branch.path / fusepath_; |
||||
|
rv = fs::stat(fullpath,st_,follow_symlinks_); |
||||
|
if(rv < 0) |
||||
|
continue; |
||||
|
|
||||
|
symlinkify::convert_if_can_be_symlink(fullpath, |
||||
|
st_, |
||||
|
symlinkify_timeout_); |
||||
|
|
||||
|
fs::inode::calc(branch.path,fusepath_,st_); |
||||
|
|
||||
|
return rv; |
||||
|
} |
||||
|
|
||||
|
return -ENOENT; |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "func_getattr_base.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class GetAttrFF : public GetAttrBase |
||||
|
{ |
||||
|
public: |
||||
|
GetAttrFF() {} |
||||
|
~GetAttrFF() {} |
||||
|
|
||||
|
public: |
||||
|
std::string_view name() const; |
||||
|
|
||||
|
public: |
||||
|
int operator()(const Branches &branches, |
||||
|
const fs::path &fusepath, |
||||
|
struct stat *st, |
||||
|
const FollowSymlinksEnum follow_symlinks, |
||||
|
const s64 symlinkify_timeout); |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,57 @@ |
|||||
|
#include "func_getattr_newest.hpp"
|
||||
|
|
||||
|
#include "fs_stat.hpp"
|
||||
|
#include "fs_inode.hpp"
|
||||
|
#include "timespec_utils.hpp"
|
||||
|
#include "symlinkify.hpp"
|
||||
|
|
||||
|
|
||||
|
std::string_view |
||||
|
Func2::GetAttrNewest::name() const |
||||
|
{ |
||||
|
return "newest"; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
Func2::GetAttrNewest::operator()(const Branches &branches_, |
||||
|
const fs::path &fusepath_, |
||||
|
struct stat *st_, |
||||
|
const FollowSymlinksEnum follow_symlinks_, |
||||
|
const s64 symlinkify_timeout_) |
||||
|
{ |
||||
|
int rv; |
||||
|
fs::path fullpath; |
||||
|
const Branch *newest_branch; |
||||
|
|
||||
|
newest_branch = nullptr; |
||||
|
for(const auto &branch : branches_) |
||||
|
{ |
||||
|
struct stat tmp_st; |
||||
|
|
||||
|
fullpath = branch.path / fusepath_; |
||||
|
rv = fs::stat(fullpath,&tmp_st,follow_symlinks_); |
||||
|
if(rv < 0) |
||||
|
continue; |
||||
|
|
||||
|
if(!TimeSpec::is_newer(tmp_st.st_mtim,st_->st_mtim)) |
||||
|
continue; |
||||
|
|
||||
|
*st_ = tmp_st; |
||||
|
newest_branch = &branch; |
||||
|
} |
||||
|
|
||||
|
if(!newest_branch) |
||||
|
return -ENOENT; |
||||
|
|
||||
|
if(symlinkify_timeout_ >= 0) |
||||
|
{ |
||||
|
fullpath = newest_branch->path / fusepath_; |
||||
|
symlinkify::convert_if_can_be_symlink(fullpath, |
||||
|
st_, |
||||
|
symlinkify_timeout_); |
||||
|
} |
||||
|
|
||||
|
fs::inode::calc(newest_branch->path,fusepath_,st_); |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
@ -0,0 +1,21 @@ |
|||||
|
#include "func_getattr_base.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class GetAttrNewest : public GetAttrBase |
||||
|
{ |
||||
|
public: |
||||
|
GetAttrNewest() {} |
||||
|
~GetAttrNewest() {} |
||||
|
|
||||
|
public: |
||||
|
std::string_view name() const; |
||||
|
|
||||
|
public: |
||||
|
int operator()(const Branches &branches, |
||||
|
const fs::path &fusepath, |
||||
|
struct stat *st, |
||||
|
const FollowSymlinksEnum follow_symlinks, |
||||
|
const s64 symlinkify_timeout); |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,77 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "func_getxattr_base.hpp"
|
||||
|
#include "func_getxattr_factory.hpp"
|
||||
|
|
||||
|
#include "tofrom_string.hpp"
|
||||
|
|
||||
|
#include "fmt/core.h"
|
||||
|
|
||||
|
#include <atomic>
|
||||
|
|
||||
|
#include <cassert>
|
||||
|
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class Getxattr : public ToFromString |
||||
|
{ |
||||
|
private: |
||||
|
std::shared_ptr<Func2::GetxattrBase> _impl; |
||||
|
|
||||
|
public: |
||||
|
Getxattr() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
Getxattr(const std::string &name_) |
||||
|
{ |
||||
|
_impl = Func2::GetxattrFactory::make(name_); |
||||
|
assert(_impl); |
||||
|
} |
||||
|
|
||||
|
public: |
||||
|
int |
||||
|
operator()(const Branches &branches_, |
||||
|
const fs::path &fusepath_, |
||||
|
const char *attrname_, |
||||
|
char *attrval_, |
||||
|
const size_t attrvalsize_) |
||||
|
{ |
||||
|
std::shared_ptr<Func2::GetxattrBase> p; |
||||
|
|
||||
|
p = std::atomic_load(&_impl); |
||||
|
|
||||
|
return (*p)(branches_, |
||||
|
fusepath_, |
||||
|
attrname_, |
||||
|
attrval_, |
||||
|
attrvalsize_); |
||||
|
} |
||||
|
|
||||
|
public: |
||||
|
std::string |
||||
|
to_string() const |
||||
|
{ |
||||
|
std::shared_ptr<Func2::GetxattrBase> p; |
||||
|
|
||||
|
p = std::atomic_load(&_impl); |
||||
|
|
||||
|
return std::string{p->name()}; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
from_string(const std::string_view str_) |
||||
|
{ |
||||
|
std::shared_ptr<Func2::GetxattrBase> p; |
||||
|
|
||||
|
p = Func2::GetxattrFactory::make(str_); |
||||
|
if(!p) |
||||
|
return -EINVAL; |
||||
|
|
||||
|
_impl = std::atomic_load(&p); |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,25 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "branches.hpp"
|
||||
|
|
||||
|
#include "fs_path.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class GetxattrBase |
||||
|
{ |
||||
|
public: |
||||
|
GetxattrBase() {} |
||||
|
~GetxattrBase() {} |
||||
|
|
||||
|
public: |
||||
|
virtual std::string_view name() const = 0; |
||||
|
|
||||
|
public: |
||||
|
virtual int operator()(const Branches &branches, |
||||
|
const fs::path &fusepath, |
||||
|
const char *attrname, |
||||
|
char *attrval, |
||||
|
const size_t attrval_size) = 0; |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,30 @@ |
|||||
|
#include "func_getxattr_factory.hpp"
|
||||
|
|
||||
|
#include "func_getxattr_ff.hpp"
|
||||
|
|
||||
|
#include "policies.hpp"
|
||||
|
|
||||
|
|
||||
|
bool |
||||
|
Func2::GetxattrFactory::valid(const std::string str_) |
||||
|
{ |
||||
|
if(str_ == "ff") |
||||
|
return true; |
||||
|
|
||||
|
if(Policies::Action::find(str_)) |
||||
|
return true; |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
std::shared_ptr<Func2::GetxattrBase> |
||||
|
Func2::GetxattrFactory::make(const std::string_view str_) |
||||
|
{ |
||||
|
if(str_ == "ff") |
||||
|
return std::make_shared<Func2::GetxattrFF>(); |
||||
|
|
||||
|
if(Policies::Action::find(str_)) |
||||
|
return std::make_shared<Func2::GetxattrFF>(); |
||||
|
|
||||
|
return {}; |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "func_getxattr_base.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class GetxattrFactory |
||||
|
{ |
||||
|
public: |
||||
|
static bool valid(const std::string str); |
||||
|
static std::shared_ptr<GetxattrBase> make(const std::string_view str); |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,35 @@ |
|||||
|
#include "func_getxattr_ff.hpp"
|
||||
|
|
||||
|
#include "error.hpp"
|
||||
|
#include "fs_lgetxattr.hpp"
|
||||
|
|
||||
|
|
||||
|
std::string_view |
||||
|
Func2::GetxattrFF::name() const |
||||
|
{ |
||||
|
return "ff"; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
Func2::GetxattrFF::operator()(const Branches &branches_, |
||||
|
const fs::path &fusepath_, |
||||
|
const char *attrname_, |
||||
|
char *attrval_, |
||||
|
const size_t attrvalsize_) |
||||
|
{ |
||||
|
int rv; |
||||
|
Err err; |
||||
|
fs::path fullpath; |
||||
|
|
||||
|
for(const auto &branch : branches_) |
||||
|
{ |
||||
|
fullpath = branch.path / fusepath_; |
||||
|
|
||||
|
rv = fs::lgetxattr(fullpath,attrname_,attrval_,attrvalsize_); |
||||
|
if(rv >= 0) |
||||
|
return rv; |
||||
|
err = rv; |
||||
|
} |
||||
|
|
||||
|
return err; |
||||
|
} |
||||
@ -0,0 +1,21 @@ |
|||||
|
#include "func_getxattr_base.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class GetxattrFF : public GetxattrBase |
||||
|
{ |
||||
|
public: |
||||
|
GetxattrFF() {} |
||||
|
~GetxattrFF() {} |
||||
|
|
||||
|
public: |
||||
|
std::string_view name() const; |
||||
|
|
||||
|
public: |
||||
|
int operator()(const Branches &branches, |
||||
|
const fs::path &fusepath, |
||||
|
const char *attrname, |
||||
|
char *attrval, |
||||
|
const size_t attrvalsize); |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,73 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "func_ioctl_base.hpp"
|
||||
|
#include "func_ioctl_factory.hpp"
|
||||
|
|
||||
|
#include "tofrom_string.hpp"
|
||||
|
|
||||
|
#include "fmt/core.h"
|
||||
|
|
||||
|
#include <atomic>
|
||||
|
|
||||
|
#include <cassert>
|
||||
|
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class Ioctl : public ToFromString |
||||
|
{ |
||||
|
private: |
||||
|
std::shared_ptr<Func2::IoctlBase> _impl; |
||||
|
|
||||
|
public: |
||||
|
Ioctl() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
Ioctl(const std::string &name_) |
||||
|
{ |
||||
|
_impl = Func2::IoctlFactory::make(name_); |
||||
|
assert(_impl); |
||||
|
} |
||||
|
|
||||
|
public: |
||||
|
int |
||||
|
operator()(const Branches &branches_, |
||||
|
const fs::path &fusepath_, |
||||
|
const mode_t mode_) |
||||
|
{ |
||||
|
std::shared_ptr<Func2::IoctlBase> p; |
||||
|
|
||||
|
p = std::atomic_load(&_impl); |
||||
|
|
||||
|
return (*p)(branches_, |
||||
|
fusepath_, |
||||
|
mode_); |
||||
|
} |
||||
|
|
||||
|
public: |
||||
|
std::string |
||||
|
to_string() const |
||||
|
{ |
||||
|
std::shared_ptr<Func2::IoctlBase> p; |
||||
|
|
||||
|
p = std::atomic_load(&_impl); |
||||
|
|
||||
|
return std::string{p->name()}; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
from_string(const std::string_view str_) |
||||
|
{ |
||||
|
std::shared_ptr<Func2::IoctlBase> p; |
||||
|
|
||||
|
p = Func2::IoctlFactory::make(str_); |
||||
|
if(!p) |
||||
|
return -EINVAL; |
||||
|
|
||||
|
_impl = std::atomic_load(&p); |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,25 @@ |
|||||
|
#include "func_ioctl_all.hpp"
|
||||
|
|
||||
|
#include "error.hpp"
|
||||
|
#include "fs_ioctl.hpp"
|
||||
|
|
||||
|
|
||||
|
std::string_view |
||||
|
Func2::IoctlAll::name() const |
||||
|
{ |
||||
|
return "all"; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
Func2::IoctlAll::operator()(const Branches &branches_, |
||||
|
const fs::path &fusepath_) |
||||
|
{ |
||||
|
Err err; |
||||
|
fs::path fullpath; |
||||
|
|
||||
|
for(const auto &branch : branches_) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
return err; |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
#include "func_ioctl_base.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class IoctlAll : public IoctlBase |
||||
|
{ |
||||
|
public: |
||||
|
IoctlAll() {} |
||||
|
~IoctlAll() {} |
||||
|
|
||||
|
public: |
||||
|
std::string_view name() const; |
||||
|
|
||||
|
public: |
||||
|
int operator()(const Branches &branches, |
||||
|
const fs::path &fusepath); |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "branches.hpp"
|
||||
|
|
||||
|
#include "fs_path.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class IoctlBase |
||||
|
{ |
||||
|
public: |
||||
|
IoctlBase() {} |
||||
|
~IoctlBase() {} |
||||
|
|
||||
|
public: |
||||
|
virtual std::string_view name() const = 0; |
||||
|
|
||||
|
public: |
||||
|
virtual int operator()(const Branches &branches, |
||||
|
const fs::path &fusepath) = 0; |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,30 @@ |
|||||
|
#include "func_ioctl_factory.hpp"
|
||||
|
|
||||
|
#include "func_ioctl_all.hpp"
|
||||
|
|
||||
|
#include "policies.hpp"
|
||||
|
|
||||
|
|
||||
|
bool |
||||
|
Func2::IoctlFactory::valid(const std::string str_) |
||||
|
{ |
||||
|
if(str_ == "all") |
||||
|
return true; |
||||
|
|
||||
|
if(Policies::Action::find(str_)) |
||||
|
return true; |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
std::shared_ptr<Func2::IoctlBase> |
||||
|
Func2::IoctlFactory::make(const std::string_view str_) |
||||
|
{ |
||||
|
if(str_ == "all") |
||||
|
return std::make_shared<Func2::IoctlAll>(); |
||||
|
|
||||
|
if(Policies::Action::find(str_)) |
||||
|
return std::make_shared<Func2::IoctlAll>(); |
||||
|
|
||||
|
return {}; |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "func_ioctl_base.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class IoctlFactory |
||||
|
{ |
||||
|
public: |
||||
|
static bool valid(const std::string str); |
||||
|
static std::shared_ptr<IoctlBase> make(const std::string_view str); |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,73 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "func_listxattr_base.hpp"
|
||||
|
#include "func_listxattr_factory.hpp"
|
||||
|
|
||||
|
#include "tofrom_string.hpp"
|
||||
|
|
||||
|
#include "fmt/core.h"
|
||||
|
|
||||
|
#include <atomic>
|
||||
|
|
||||
|
#include <cassert>
|
||||
|
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class Listxattr : public ToFromString |
||||
|
{ |
||||
|
private: |
||||
|
std::shared_ptr<Func2::ListxattrBase> _impl; |
||||
|
|
||||
|
public: |
||||
|
Listxattr() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
Listxattr(const std::string &name_) |
||||
|
{ |
||||
|
_impl = Func2::ListxattrFactory::make(name_); |
||||
|
assert(_impl); |
||||
|
} |
||||
|
|
||||
|
public: |
||||
|
int |
||||
|
operator()(const Branches &branches_, |
||||
|
const fs::path &fusepath_, |
||||
|
const mode_t mode_) |
||||
|
{ |
||||
|
std::shared_ptr<Func2::ListxattrBase> p; |
||||
|
|
||||
|
p = std::atomic_load(&_impl); |
||||
|
|
||||
|
return (*p)(branches_, |
||||
|
fusepath_, |
||||
|
mode_); |
||||
|
} |
||||
|
|
||||
|
public: |
||||
|
std::string |
||||
|
to_string() const |
||||
|
{ |
||||
|
std::shared_ptr<Func2::ListxattrBase> p; |
||||
|
|
||||
|
p = std::atomic_load(&_impl); |
||||
|
|
||||
|
return std::string{p->name()}; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
from_string(const std::string_view str_) |
||||
|
{ |
||||
|
std::shared_ptr<Func2::ListxattrBase> p; |
||||
|
|
||||
|
p = Func2::ListxattrFactory::make(str_); |
||||
|
if(!p) |
||||
|
return -EINVAL; |
||||
|
|
||||
|
_impl = std::atomic_load(&p); |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,27 @@ |
|||||
|
#include "func_listxattr_all.hpp"
|
||||
|
|
||||
|
#include "error.hpp"
|
||||
|
#include "fs_llistxattr.hpp"
|
||||
|
|
||||
|
|
||||
|
std::string_view |
||||
|
Func2::ListxattrAll::name() const |
||||
|
{ |
||||
|
return "all"; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
Func2::ListxattrAll::operator()(const Branches &branches_, |
||||
|
const fs::path &fusepath_, |
||||
|
char *list_, |
||||
|
const size_t size_) |
||||
|
{ |
||||
|
Err err; |
||||
|
fs::path fullpath; |
||||
|
|
||||
|
for(const auto &branch : branches_) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
return err; |
||||
|
} |
||||
@ -0,0 +1,20 @@ |
|||||
|
#include "func_listxattr_base.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class ListxattrAll : public ListxattrBase |
||||
|
{ |
||||
|
public: |
||||
|
ListxattrAll() {} |
||||
|
~ListxattrAll() {} |
||||
|
|
||||
|
public: |
||||
|
std::string_view name() const; |
||||
|
|
||||
|
public: |
||||
|
int operator()(const Branches &branches, |
||||
|
const fs::path &fusepath, |
||||
|
char *list, |
||||
|
const size_t size); |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,24 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "branches.hpp"
|
||||
|
|
||||
|
#include "fs_path.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class ListxattrBase |
||||
|
{ |
||||
|
public: |
||||
|
ListxattrBase() {} |
||||
|
~ListxattrBase() {} |
||||
|
|
||||
|
public: |
||||
|
virtual std::string_view name() const = 0; |
||||
|
|
||||
|
public: |
||||
|
virtual int operator()(const Branches &branches, |
||||
|
const fs::path &fusepath, |
||||
|
char *list, |
||||
|
const size_t size) = 0; |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,30 @@ |
|||||
|
#include "func_listxattr_factory.hpp"
|
||||
|
|
||||
|
#include "func_listxattr_all.hpp"
|
||||
|
|
||||
|
#include "policies.hpp"
|
||||
|
|
||||
|
|
||||
|
bool |
||||
|
Func2::ListxattrFactory::valid(const std::string str_) |
||||
|
{ |
||||
|
if(str_ == "all") |
||||
|
return true; |
||||
|
|
||||
|
if(Policies::Action::find(str_)) |
||||
|
return true; |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
std::shared_ptr<Func2::ListxattrBase> |
||||
|
Func2::ListxattrFactory::make(const std::string_view str_) |
||||
|
{ |
||||
|
if(str_ == "all") |
||||
|
return std::make_shared<Func2::ListxattrAll>(); |
||||
|
|
||||
|
if(Policies::Action::find(str_)) |
||||
|
return std::make_shared<Func2::ListxattrAll>(); |
||||
|
|
||||
|
return {}; |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "func_listxattr_base.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class ListxattrFactory |
||||
|
{ |
||||
|
public: |
||||
|
static bool valid(const std::string str); |
||||
|
static std::shared_ptr<ListxattrBase> make(const std::string_view str); |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,73 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "func_open_base.hpp"
|
||||
|
#include "func_open_factory.hpp"
|
||||
|
|
||||
|
#include "tofrom_string.hpp"
|
||||
|
|
||||
|
#include "fmt/core.h"
|
||||
|
|
||||
|
#include <atomic>
|
||||
|
|
||||
|
#include <cassert>
|
||||
|
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class Open : public ToFromString |
||||
|
{ |
||||
|
private: |
||||
|
std::shared_ptr<Func2::OpenBase> _impl; |
||||
|
|
||||
|
public: |
||||
|
Open() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
Open(const std::string &name_) |
||||
|
{ |
||||
|
_impl = Func2::OpenFactory::make(name_); |
||||
|
assert(_impl); |
||||
|
} |
||||
|
|
||||
|
public: |
||||
|
int |
||||
|
operator()(const Branches &branches_, |
||||
|
const fs::path &fusepath_, |
||||
|
const mode_t mode_) |
||||
|
{ |
||||
|
std::shared_ptr<Func2::OpenBase> p; |
||||
|
|
||||
|
p = std::atomic_load(&_impl); |
||||
|
|
||||
|
return (*p)(branches_, |
||||
|
fusepath_, |
||||
|
mode_); |
||||
|
} |
||||
|
|
||||
|
public: |
||||
|
std::string |
||||
|
to_string() const |
||||
|
{ |
||||
|
std::shared_ptr<Func2::OpenBase> p; |
||||
|
|
||||
|
p = std::atomic_load(&_impl); |
||||
|
|
||||
|
return std::string{p->name()}; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
from_string(const std::string_view str_) |
||||
|
{ |
||||
|
std::shared_ptr<Func2::OpenBase> p; |
||||
|
|
||||
|
p = Func2::OpenFactory::make(str_); |
||||
|
if(!p) |
||||
|
return -EINVAL; |
||||
|
|
||||
|
_impl = std::atomic_load(&p); |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,27 @@ |
|||||
|
#include "func_open_all.hpp"
|
||||
|
|
||||
|
#include "error.hpp"
|
||||
|
#include "fs_open.hpp"
|
||||
|
|
||||
|
|
||||
|
std::string_view |
||||
|
Func2::OpenAll::name() const |
||||
|
{ |
||||
|
return "all"; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
Func2::OpenAll::operator()(const Branches &branches_, |
||||
|
const fs::path &fusepath_, |
||||
|
const mode_t mode_) |
||||
|
{ |
||||
|
Err err; |
||||
|
fs::path fullpath; |
||||
|
|
||||
|
for(const auto &branch : branches_) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
return err; |
||||
|
} |
||||
@ -0,0 +1,19 @@ |
|||||
|
#include "func_open_base.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class OpenAll : public OpenBase |
||||
|
{ |
||||
|
public: |
||||
|
OpenAll() {} |
||||
|
~OpenAll() {} |
||||
|
|
||||
|
public: |
||||
|
std::string_view name() const; |
||||
|
|
||||
|
public: |
||||
|
int operator()(const Branches &branches, |
||||
|
const fs::path &fusepath, |
||||
|
const mode_t mode); |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "branches.hpp"
|
||||
|
|
||||
|
#include "fs_path.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class OpenBase |
||||
|
{ |
||||
|
public: |
||||
|
OpenBase() {} |
||||
|
~OpenBase() {} |
||||
|
|
||||
|
public: |
||||
|
virtual std::string_view name() const = 0; |
||||
|
|
||||
|
public: |
||||
|
virtual int operator()(const Branches &branches, |
||||
|
const fs::path &fusepath, |
||||
|
const mode_t mode) = 0; |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,30 @@ |
|||||
|
#include "func_open_factory.hpp"
|
||||
|
|
||||
|
#include "func_open_all.hpp"
|
||||
|
|
||||
|
#include "policies.hpp"
|
||||
|
|
||||
|
|
||||
|
bool |
||||
|
Func2::OpenFactory::valid(const std::string str_) |
||||
|
{ |
||||
|
if(str_ == "all") |
||||
|
return true; |
||||
|
|
||||
|
if(Policies::Action::find(str_)) |
||||
|
return true; |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
std::shared_ptr<Func2::OpenBase> |
||||
|
Func2::OpenFactory::make(const std::string_view str_) |
||||
|
{ |
||||
|
if(str_ == "all") |
||||
|
return std::make_shared<Func2::OpenAll>(); |
||||
|
|
||||
|
if(Policies::Action::find(str_)) |
||||
|
return std::make_shared<Func2::OpenAll>(); |
||||
|
|
||||
|
return {}; |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "func_open_base.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class OpenFactory |
||||
|
{ |
||||
|
public: |
||||
|
static bool valid(const std::string str); |
||||
|
static std::shared_ptr<OpenBase> make(const std::string_view str); |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,75 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "func_readlink_base.hpp"
|
||||
|
#include "func_readlink_factory.hpp"
|
||||
|
|
||||
|
#include "tofrom_string.hpp"
|
||||
|
|
||||
|
#include "fmt/core.h"
|
||||
|
|
||||
|
#include <atomic>
|
||||
|
|
||||
|
#include <cassert>
|
||||
|
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class Readlink : public ToFromString |
||||
|
{ |
||||
|
private: |
||||
|
std::shared_ptr<Func2::ReadlinkBase> _impl; |
||||
|
|
||||
|
public: |
||||
|
Readlink() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
Readlink(const std::string &name_) |
||||
|
{ |
||||
|
_impl = Func2::ReadlinkFactory::make(name_); |
||||
|
assert(_impl); |
||||
|
} |
||||
|
|
||||
|
public: |
||||
|
int |
||||
|
operator()(const Branches &branches_, |
||||
|
const fs::path &fusepath_, |
||||
|
char *buf_, |
||||
|
const size_t bufsize_) |
||||
|
{ |
||||
|
std::shared_ptr<Func2::ReadlinkBase> p; |
||||
|
|
||||
|
p = std::atomic_load(&_impl); |
||||
|
|
||||
|
return (*p)(branches_, |
||||
|
fusepath_, |
||||
|
buf_, |
||||
|
bufsize_); |
||||
|
} |
||||
|
|
||||
|
public: |
||||
|
std::string |
||||
|
to_string() const |
||||
|
{ |
||||
|
std::shared_ptr<Func2::ReadlinkBase> p; |
||||
|
|
||||
|
p = std::atomic_load(&_impl); |
||||
|
|
||||
|
return std::string{p->name()}; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
from_string(const std::string_view str_) |
||||
|
{ |
||||
|
std::shared_ptr<Func2::ReadlinkBase> p; |
||||
|
|
||||
|
p = Func2::ReadlinkFactory::make(str_); |
||||
|
if(!p) |
||||
|
return -EINVAL; |
||||
|
|
||||
|
_impl = std::atomic_load(&p); |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,28 @@ |
|||||
|
#include "func_readlink_all.hpp"
|
||||
|
|
||||
|
#include "error.hpp"
|
||||
|
#include "fs_readlink.hpp"
|
||||
|
|
||||
|
|
||||
|
std::string_view |
||||
|
Func2::ReadlinkAll::name() const |
||||
|
{ |
||||
|
return "all"; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
Func2::ReadlinkAll::operator()(const Branches &branches_, |
||||
|
const fs::path &fusepath_, |
||||
|
char *buf_, |
||||
|
const size_t bufsize_) |
||||
|
{ |
||||
|
Err err; |
||||
|
fs::path fullpath; |
||||
|
|
||||
|
for(const auto &branch : branches_) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
return err; |
||||
|
} |
||||
@ -0,0 +1,20 @@ |
|||||
|
#include "func_readlink_base.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class ReadlinkAll : public ReadlinkBase |
||||
|
{ |
||||
|
public: |
||||
|
ReadlinkAll() {} |
||||
|
~ReadlinkAll() {} |
||||
|
|
||||
|
public: |
||||
|
std::string_view name() const; |
||||
|
|
||||
|
public: |
||||
|
int operator()(const Branches &branches, |
||||
|
const fs::path &fusepath, |
||||
|
char *buf, |
||||
|
const size_t bufsize); |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,24 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "branches.hpp"
|
||||
|
|
||||
|
#include "fs_path.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class ReadlinkBase |
||||
|
{ |
||||
|
public: |
||||
|
ReadlinkBase() {} |
||||
|
~ReadlinkBase() {} |
||||
|
|
||||
|
public: |
||||
|
virtual std::string_view name() const = 0; |
||||
|
|
||||
|
public: |
||||
|
virtual int operator()(const Branches &branches, |
||||
|
const fs::path &fusepath, |
||||
|
char *buf, |
||||
|
const size_t bufsize) = 0; |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,30 @@ |
|||||
|
#include "func_readlink_factory.hpp"
|
||||
|
|
||||
|
#include "func_readlink_all.hpp"
|
||||
|
|
||||
|
#include "policies.hpp"
|
||||
|
|
||||
|
|
||||
|
bool |
||||
|
Func2::ReadlinkFactory::valid(const std::string str_) |
||||
|
{ |
||||
|
if(str_ == "all") |
||||
|
return true; |
||||
|
|
||||
|
if(Policies::Action::find(str_)) |
||||
|
return true; |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
std::shared_ptr<Func2::ReadlinkBase> |
||||
|
Func2::ReadlinkFactory::make(const std::string_view str_) |
||||
|
{ |
||||
|
if(str_ == "all") |
||||
|
return std::make_shared<Func2::ReadlinkAll>(); |
||||
|
|
||||
|
if(Policies::Action::find(str_)) |
||||
|
return std::make_shared<Func2::ReadlinkAll>(); |
||||
|
|
||||
|
return {}; |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "func_readlink_base.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class ReadlinkFactory |
||||
|
{ |
||||
|
public: |
||||
|
static bool valid(const std::string str); |
||||
|
static std::shared_ptr<ReadlinkBase> make(const std::string_view str); |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,73 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "func_removexattr_base.hpp"
|
||||
|
#include "func_removexattr_factory.hpp"
|
||||
|
|
||||
|
#include "tofrom_string.hpp"
|
||||
|
|
||||
|
#include "fmt/core.h"
|
||||
|
|
||||
|
#include <atomic>
|
||||
|
|
||||
|
#include <cassert>
|
||||
|
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class Removexattr : public ToFromString |
||||
|
{ |
||||
|
private: |
||||
|
std::shared_ptr<Func2::RemovexattrBase> _impl; |
||||
|
|
||||
|
public: |
||||
|
Removexattr() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
Removexattr(const std::string &name_) |
||||
|
{ |
||||
|
_impl = Func2::RemovexattrFactory::make(name_); |
||||
|
assert(_impl); |
||||
|
} |
||||
|
|
||||
|
public: |
||||
|
int |
||||
|
operator()(const Branches &branches_, |
||||
|
const fs::path &fusepath_, |
||||
|
const char *attrname_) |
||||
|
{ |
||||
|
std::shared_ptr<Func2::RemovexattrBase> p; |
||||
|
|
||||
|
p = std::atomic_load(&_impl); |
||||
|
|
||||
|
return (*p)(branches_, |
||||
|
fusepath_, |
||||
|
attrname_); |
||||
|
} |
||||
|
|
||||
|
public: |
||||
|
std::string |
||||
|
to_string() const |
||||
|
{ |
||||
|
std::shared_ptr<Func2::RemovexattrBase> p; |
||||
|
|
||||
|
p = std::atomic_load(&_impl); |
||||
|
|
||||
|
return std::string{p->name()}; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
from_string(const std::string_view str_) |
||||
|
{ |
||||
|
std::shared_ptr<Func2::RemovexattrBase> p; |
||||
|
|
||||
|
p = Func2::RemovexattrFactory::make(str_); |
||||
|
if(!p) |
||||
|
return -EINVAL; |
||||
|
|
||||
|
_impl = std::atomic_load(&p); |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,35 @@ |
|||||
|
#include "func_removexattr_all.hpp"
|
||||
|
|
||||
|
#include "error.hpp"
|
||||
|
#include "fs_lremovexattr.hpp"
|
||||
|
|
||||
|
|
||||
|
std::string_view |
||||
|
Func2::RemovexattrAll::name() const |
||||
|
{ |
||||
|
return "all"; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
Func2::RemovexattrAll::operator()(const Branches &branches_, |
||||
|
const fs::path &fusepath_, |
||||
|
const char *attrname_) |
||||
|
{ |
||||
|
Err err; |
||||
|
fs::path fullpath; |
||||
|
|
||||
|
for(const auto &branch : branches_) |
||||
|
{ |
||||
|
if(branch.ro()) |
||||
|
{ |
||||
|
err = -EROFS; |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
fullpath = branch.path / fusepath_; |
||||
|
|
||||
|
err = fs::lremovexattr(fullpath,attrname_); |
||||
|
} |
||||
|
|
||||
|
return err; |
||||
|
} |
||||
@ -0,0 +1,19 @@ |
|||||
|
#include "func_removexattr_base.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class RemovexattrAll : public RemovexattrBase |
||||
|
{ |
||||
|
public: |
||||
|
RemovexattrAll() {} |
||||
|
~RemovexattrAll() {} |
||||
|
|
||||
|
public: |
||||
|
std::string_view name() const; |
||||
|
|
||||
|
public: |
||||
|
int operator()(const Branches &branches, |
||||
|
const fs::path &fusepath, |
||||
|
const char *attrname); |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "branches.hpp"
|
||||
|
|
||||
|
#include "fs_path.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class RemovexattrBase |
||||
|
{ |
||||
|
public: |
||||
|
RemovexattrBase() {} |
||||
|
~RemovexattrBase() {} |
||||
|
|
||||
|
public: |
||||
|
virtual std::string_view name() const = 0; |
||||
|
|
||||
|
public: |
||||
|
virtual int operator()(const Branches &branches, |
||||
|
const fs::path &fusepath, |
||||
|
const char *attrname) = 0; |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,30 @@ |
|||||
|
#include "func_removexattr_factory.hpp"
|
||||
|
|
||||
|
#include "func_removexattr_all.hpp"
|
||||
|
|
||||
|
#include "policies.hpp"
|
||||
|
|
||||
|
|
||||
|
bool |
||||
|
Func2::RemovexattrFactory::valid(const std::string str_) |
||||
|
{ |
||||
|
if(str_ == "all") |
||||
|
return true; |
||||
|
|
||||
|
if(Policies::Action::find(str_)) |
||||
|
return true; |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
std::shared_ptr<Func2::RemovexattrBase> |
||||
|
Func2::RemovexattrFactory::make(const std::string_view str_) |
||||
|
{ |
||||
|
if(str_ == "all") |
||||
|
return std::make_shared<Func2::RemovexattrAll>(); |
||||
|
|
||||
|
if(Policies::Action::find(str_)) |
||||
|
return std::make_shared<Func2::RemovexattrAll>(); |
||||
|
|
||||
|
return {}; |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "func_removexattr_base.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class RemovexattrFactory |
||||
|
{ |
||||
|
public: |
||||
|
static bool valid(const std::string str); |
||||
|
static std::shared_ptr<RemovexattrBase> make(const std::string_view str); |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,71 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "func_rmdir_base.hpp"
|
||||
|
#include "func_rmdir_factory.hpp"
|
||||
|
|
||||
|
#include "tofrom_string.hpp"
|
||||
|
|
||||
|
#include "fmt/core.h"
|
||||
|
|
||||
|
#include <atomic>
|
||||
|
|
||||
|
#include <cassert>
|
||||
|
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class Rmdir : public ToFromString |
||||
|
{ |
||||
|
private: |
||||
|
std::shared_ptr<Func2::RmdirBase> _impl; |
||||
|
|
||||
|
public: |
||||
|
Rmdir() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
Rmdir(const std::string &name_) |
||||
|
{ |
||||
|
_impl = Func2::RmdirFactory::make(name_); |
||||
|
assert(_impl); |
||||
|
} |
||||
|
|
||||
|
public: |
||||
|
int |
||||
|
operator()(const Branches &branches_, |
||||
|
const fs::path &fusepath_) |
||||
|
{ |
||||
|
std::shared_ptr<Func2::RmdirBase> p; |
||||
|
|
||||
|
p = std::atomic_load(&_impl); |
||||
|
|
||||
|
return (*p)(branches_, |
||||
|
fusepath_); |
||||
|
} |
||||
|
|
||||
|
public: |
||||
|
std::string |
||||
|
to_string() const |
||||
|
{ |
||||
|
std::shared_ptr<Func2::RmdirBase> p; |
||||
|
|
||||
|
p = std::atomic_load(&_impl); |
||||
|
|
||||
|
return std::string{p->name()}; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
from_string(const std::string_view str_) |
||||
|
{ |
||||
|
std::shared_ptr<Func2::RmdirBase> p; |
||||
|
|
||||
|
p = Func2::RmdirFactory::make(str_); |
||||
|
if(!p) |
||||
|
return -EINVAL; |
||||
|
|
||||
|
_impl = std::atomic_load(&p); |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,50 @@ |
|||||
|
#include "func_rmdir_all.hpp"
|
||||
|
|
||||
|
#include "config.hpp"
|
||||
|
#include "error.hpp"
|
||||
|
#include "fs_rmdir.hpp"
|
||||
|
#include "fs_unlink.hpp"
|
||||
|
|
||||
|
|
||||
|
std::string_view |
||||
|
Func2::RmdirAll::name() const |
||||
|
{ |
||||
|
return "all"; |
||||
|
} |
||||
|
|
||||
|
static |
||||
|
int |
||||
|
_should_unlink(int rv_) |
||||
|
|
||||
|
{ |
||||
|
return ((rv_ == -ENOTDIR) && |
||||
|
(cfg.follow_symlinks != FollowSymlinks::ENUM::NEVER)); |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
Func2::RmdirAll::operator()(const Branches &branches_, |
||||
|
const fs::path &fusepath_) |
||||
|
{ |
||||
|
Err err; |
||||
|
fs::path fullpath; |
||||
|
|
||||
|
for(const auto &branch : branches_) |
||||
|
{ |
||||
|
int rv; |
||||
|
|
||||
|
if(branch.ro()) |
||||
|
{ |
||||
|
err = -EROFS; |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
fullpath = branch.path / fusepath_; |
||||
|
|
||||
|
rv = fs::rmdir(fullpath); |
||||
|
if(::_should_unlink(rv)) |
||||
|
rv = fs::unlink(fullpath); |
||||
|
err = rv; |
||||
|
} |
||||
|
|
||||
|
return err; |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
#include "func_rmdir_base.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class RmdirAll : public RmdirBase |
||||
|
{ |
||||
|
public: |
||||
|
RmdirAll() {} |
||||
|
~RmdirAll() {} |
||||
|
|
||||
|
public: |
||||
|
std::string_view name() const; |
||||
|
|
||||
|
public: |
||||
|
int operator()(const Branches &branches, |
||||
|
const fs::path &fusepath); |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "branches.hpp"
|
||||
|
|
||||
|
#include "fs_path.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class RmdirBase |
||||
|
{ |
||||
|
public: |
||||
|
RmdirBase() {} |
||||
|
~RmdirBase() {} |
||||
|
|
||||
|
public: |
||||
|
virtual std::string_view name() const = 0; |
||||
|
|
||||
|
public: |
||||
|
virtual int operator()(const Branches &branches, |
||||
|
const fs::path &fusepath) = 0; |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,30 @@ |
|||||
|
#include "func_rmdir_factory.hpp"
|
||||
|
|
||||
|
#include "func_rmdir_all.hpp"
|
||||
|
|
||||
|
#include "policies.hpp"
|
||||
|
|
||||
|
|
||||
|
bool |
||||
|
Func2::RmdirFactory::valid(const std::string str_) |
||||
|
{ |
||||
|
if(str_ == "all") |
||||
|
return true; |
||||
|
|
||||
|
if(Policies::Action::find(str_)) |
||||
|
return true; |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
std::shared_ptr<Func2::RmdirBase> |
||||
|
Func2::RmdirFactory::make(const std::string_view str_) |
||||
|
{ |
||||
|
if(str_ == "all") |
||||
|
return std::make_shared<Func2::RmdirAll>(); |
||||
|
|
||||
|
if(Policies::Action::find(str_)) |
||||
|
return std::make_shared<Func2::RmdirAll>(); |
||||
|
|
||||
|
return {}; |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "func_rmdir_base.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class RmdirFactory |
||||
|
{ |
||||
|
public: |
||||
|
static bool valid(const std::string str); |
||||
|
static std::shared_ptr<RmdirBase> make(const std::string_view str); |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,79 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "func_setxattr_base.hpp"
|
||||
|
#include "func_setxattr_factory.hpp"
|
||||
|
|
||||
|
#include "tofrom_string.hpp"
|
||||
|
|
||||
|
#include "fmt/core.h"
|
||||
|
|
||||
|
#include <atomic>
|
||||
|
|
||||
|
#include <cassert>
|
||||
|
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class Setxattr : public ToFromString |
||||
|
{ |
||||
|
private: |
||||
|
std::shared_ptr<Func2::SetxattrBase> _impl; |
||||
|
|
||||
|
public: |
||||
|
Setxattr() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
Setxattr(const std::string &name_) |
||||
|
{ |
||||
|
_impl = Func2::SetxattrFactory::make(name_); |
||||
|
assert(_impl); |
||||
|
} |
||||
|
|
||||
|
public: |
||||
|
int |
||||
|
operator()(const Branches &branches_, |
||||
|
const fs::path &fusepath_, |
||||
|
const char *attrname_, |
||||
|
const char *attrval_, |
||||
|
const size_t attrvalsize_, |
||||
|
const int flags_) |
||||
|
{ |
||||
|
std::shared_ptr<Func2::SetxattrBase> p; |
||||
|
|
||||
|
p = std::atomic_load(&_impl); |
||||
|
|
||||
|
return (*p)(branches_, |
||||
|
fusepath_, |
||||
|
attrname_, |
||||
|
attrval_, |
||||
|
attrvalsize_, |
||||
|
flags_); |
||||
|
} |
||||
|
|
||||
|
public: |
||||
|
std::string |
||||
|
to_string() const |
||||
|
{ |
||||
|
std::shared_ptr<Func2::SetxattrBase> p; |
||||
|
|
||||
|
p = std::atomic_load(&_impl); |
||||
|
|
||||
|
return std::string{p->name()}; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
from_string(const std::string_view str_) |
||||
|
{ |
||||
|
std::shared_ptr<Func2::SetxattrBase> p; |
||||
|
|
||||
|
p = Func2::SetxattrFactory::make(str_); |
||||
|
if(!p) |
||||
|
return -EINVAL; |
||||
|
|
||||
|
_impl = std::atomic_load(&p); |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,38 @@ |
|||||
|
#include "func_setxattr_all.hpp"
|
||||
|
|
||||
|
#include "error.hpp"
|
||||
|
#include "fs_lsetxattr.hpp"
|
||||
|
|
||||
|
|
||||
|
std::string_view |
||||
|
Func2::SetxattrAll::name() const |
||||
|
{ |
||||
|
return "all"; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
Func2::SetxattrAll::operator()(const Branches &branches_, |
||||
|
const fs::path &fusepath_, |
||||
|
const char *attrname_, |
||||
|
const char *attrval_, |
||||
|
size_t attrvalsize_, |
||||
|
int flags_) |
||||
|
{ |
||||
|
Err err; |
||||
|
fs::path fullpath; |
||||
|
|
||||
|
for(const auto &branch : branches_) |
||||
|
{ |
||||
|
if(branch.ro()) |
||||
|
{ |
||||
|
err = -EROFS; |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
fullpath = branch.path / fusepath_; |
||||
|
|
||||
|
err = fs::lsetxattr(fullpath,attrname_,attrval_,attrvalsize_,flags_); |
||||
|
} |
||||
|
|
||||
|
return err; |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
#include "func_setxattr_base.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class SetxattrAll : public SetxattrBase |
||||
|
{ |
||||
|
public: |
||||
|
SetxattrAll() {} |
||||
|
~SetxattrAll() {} |
||||
|
|
||||
|
public: |
||||
|
std::string_view name() const; |
||||
|
|
||||
|
public: |
||||
|
int operator()(const Branches &branches, |
||||
|
const fs::path &fusepath, |
||||
|
const char *attrname_, |
||||
|
const char *attrval_, |
||||
|
size_t attrvalsize_, |
||||
|
int flags_); |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,26 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "branches.hpp"
|
||||
|
|
||||
|
#include "fs_path.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class SetxattrBase |
||||
|
{ |
||||
|
public: |
||||
|
SetxattrBase() {} |
||||
|
~SetxattrBase() {} |
||||
|
|
||||
|
public: |
||||
|
virtual std::string_view name() const = 0; |
||||
|
|
||||
|
public: |
||||
|
virtual int operator()(const Branches &branches, |
||||
|
const fs::path &fusepath, |
||||
|
const char *attrname, |
||||
|
const char *attrval, |
||||
|
size_t attrvalsize, |
||||
|
int flags) = 0; |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,30 @@ |
|||||
|
#include "func_setxattr_factory.hpp"
|
||||
|
|
||||
|
#include "func_setxattr_all.hpp"
|
||||
|
|
||||
|
#include "policies.hpp"
|
||||
|
|
||||
|
|
||||
|
bool |
||||
|
Func2::SetxattrFactory::valid(const std::string str_) |
||||
|
{ |
||||
|
if(str_ == "all") |
||||
|
return true; |
||||
|
|
||||
|
if(Policies::Action::find(str_)) |
||||
|
return true; |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
std::shared_ptr<Func2::SetxattrBase> |
||||
|
Func2::SetxattrFactory::make(const std::string_view str_) |
||||
|
{ |
||||
|
if(str_ == "all") |
||||
|
return std::make_shared<Func2::SetxattrAll>(); |
||||
|
|
||||
|
if(Policies::Action::find(str_)) |
||||
|
return std::make_shared<Func2::SetxattrAll>(); |
||||
|
|
||||
|
return {}; |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "func_setxattr_base.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class SetxattrFactory |
||||
|
{ |
||||
|
public: |
||||
|
static bool valid(const std::string str); |
||||
|
static std::shared_ptr<SetxattrBase> make(const std::string_view str); |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,81 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "func_statx_base.hpp"
|
||||
|
#include "func_statx_factory.hpp"
|
||||
|
|
||||
|
#include "tofrom_string.hpp"
|
||||
|
|
||||
|
#include "fmt/core.h"
|
||||
|
|
||||
|
#include <atomic>
|
||||
|
|
||||
|
#include <assert.h>
|
||||
|
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class Statx : public ToFromString |
||||
|
{ |
||||
|
private: |
||||
|
std::shared_ptr<Func2::StatxBase> _impl; |
||||
|
|
||||
|
public: |
||||
|
Statx() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
Statx(const std::string &name_) |
||||
|
{ |
||||
|
_impl = Func2::StatxFactory::make(name_); |
||||
|
assert(_impl); |
||||
|
} |
||||
|
|
||||
|
public: |
||||
|
int |
||||
|
operator()(const Branches &branches_, |
||||
|
const fs::path &fusepath_, |
||||
|
const u32 flags_, |
||||
|
const u32 mask_, |
||||
|
struct fuse_statx *st_, |
||||
|
const FollowSymlinksEnum follow_symlinks_, |
||||
|
const s64 symlinkify_timeout_) |
||||
|
{ |
||||
|
std::shared_ptr<Func2::StatxBase> p; |
||||
|
|
||||
|
p = std::atomic_load(&_impl); |
||||
|
|
||||
|
return (*p)(branches_, |
||||
|
fusepath_, |
||||
|
flags_, |
||||
|
mask_, |
||||
|
st_, |
||||
|
follow_symlinks_, |
||||
|
symlinkify_timeout_); |
||||
|
} |
||||
|
|
||||
|
public: |
||||
|
std::string |
||||
|
to_string() const |
||||
|
{ |
||||
|
std::shared_ptr<Func2::StatxBase> p; |
||||
|
|
||||
|
p = std::atomic_load(&_impl); |
||||
|
|
||||
|
return std::string(p->name()); |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
from_string(const std::string_view str_) |
||||
|
{ |
||||
|
std::shared_ptr<Func2::StatxBase> p; |
||||
|
|
||||
|
p = Func2::StatxFactory::make(str_); |
||||
|
if(!p) |
||||
|
return -EINVAL; |
||||
|
|
||||
|
_impl = std::atomic_load(&p); |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,38 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "follow_symlinks_enum.hpp"
|
||||
|
|
||||
|
#include "fs_path.hpp"
|
||||
|
#include "branches.hpp"
|
||||
|
#include "int_types.h"
|
||||
|
|
||||
|
#include "fuse.h"
|
||||
|
|
||||
|
#include <string_view>
|
||||
|
|
||||
|
#include <sys/types.h>
|
||||
|
#include <sys/stat.h>
|
||||
|
#include <unistd.h>
|
||||
|
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class StatxBase |
||||
|
{ |
||||
|
public: |
||||
|
StatxBase() {} |
||||
|
~StatxBase() {} |
||||
|
|
||||
|
public: |
||||
|
virtual std::string_view name() const = 0; |
||||
|
|
||||
|
public: |
||||
|
virtual int operator()(const Branches &branches, |
||||
|
const fs::path &fusepath, |
||||
|
const u32 flags_, |
||||
|
const u32 mask_, |
||||
|
struct fuse_statx *st, |
||||
|
const FollowSymlinksEnum follow_symlinks, |
||||
|
const s64 symlinkify_timeout) = 0; |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,79 @@ |
|||||
|
#include "func_statx_combine.hpp"
|
||||
|
|
||||
|
#include "fs_inode.hpp"
|
||||
|
#include "fs_statx.hpp"
|
||||
|
#include "symlinkify.hpp"
|
||||
|
#include "timespec_utils.hpp"
|
||||
|
|
||||
|
|
||||
|
std::string_view |
||||
|
Func2::StatxCombine::name() const |
||||
|
{ |
||||
|
return "combine"; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
Func2::StatxCombine::operator()(const Branches &branches_, |
||||
|
const fs::path &fusepath_, |
||||
|
const u32 flags_, |
||||
|
const u32 mask_, |
||||
|
struct fuse_statx *st_, |
||||
|
const FollowSymlinksEnum follow_symlinks_, |
||||
|
const s64 symlinkify_timeout_) |
||||
|
{ |
||||
|
int rv; |
||||
|
fs::path fullpath; |
||||
|
const Branch *first_branch; |
||||
|
|
||||
|
first_branch = nullptr; |
||||
|
for(const auto &branch : branches_) |
||||
|
{ |
||||
|
struct fuse_statx tmp_st; |
||||
|
|
||||
|
fullpath = branch.path / fusepath_; |
||||
|
rv = fs::statx(AT_FDCWD, |
||||
|
fullpath, |
||||
|
flags_|AT_SYMLINK_NOFOLLOW, |
||||
|
mask_, |
||||
|
&tmp_st, |
||||
|
follow_symlinks_); |
||||
|
if(rv < 0) |
||||
|
continue; |
||||
|
|
||||
|
if(!first_branch) |
||||
|
{ |
||||
|
*st_ = tmp_st; |
||||
|
first_branch = &branch; |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
// This upgrades the uid:gid because mergerfs now does most
|
||||
|
// file interaction as root and relies on `default_permissions`
|
||||
|
// to manage permissions. Want to ensure that root owned files
|
||||
|
// can't be changed so we treat them all as root owned.
|
||||
|
if(tmp_st.uid == 0) |
||||
|
st_->uid = 0; |
||||
|
if(tmp_st.gid == 0) |
||||
|
st_->gid = 0; |
||||
|
st_->atime = TimeSpec::newest(st_->atime,tmp_st.atime); |
||||
|
st_->ctime = TimeSpec::newest(st_->ctime,tmp_st.ctime); |
||||
|
st_->mtime = TimeSpec::newest(st_->mtime,tmp_st.mtime); |
||||
|
st_->btime = TimeSpec::newest(st_->btime,tmp_st.btime); |
||||
|
st_->nlink += tmp_st.nlink; |
||||
|
} |
||||
|
|
||||
|
if(!first_branch) |
||||
|
return -ENOENT; |
||||
|
|
||||
|
if(symlinkify_timeout_ >= 0) |
||||
|
{ |
||||
|
fullpath = first_branch->path / fusepath_; |
||||
|
symlinkify::convert_if_can_be_symlink(fullpath, |
||||
|
st_, |
||||
|
symlinkify_timeout_); |
||||
|
} |
||||
|
|
||||
|
fs::inode::calc(first_branch->path,fusepath_,st_); |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
#include "func_statx_base.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class StatxCombine : public StatxBase |
||||
|
{ |
||||
|
public: |
||||
|
StatxCombine() {} |
||||
|
~StatxCombine() {} |
||||
|
|
||||
|
public: |
||||
|
std::string_view name() const; |
||||
|
|
||||
|
public: |
||||
|
int operator()(const Branches &branches, |
||||
|
const fs::path &fusepath, |
||||
|
const u32 flags_, |
||||
|
const u32 mask_, |
||||
|
struct fuse_statx *st, |
||||
|
const FollowSymlinksEnum follow_symlinks, |
||||
|
const s64 symlinkify_timeout); |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,39 @@ |
|||||
|
#include "func_statx_factory.hpp"
|
||||
|
|
||||
|
#include "func_statx_combine.hpp"
|
||||
|
#include "func_statx_ff.hpp"
|
||||
|
#include "func_statx_newest.hpp"
|
||||
|
|
||||
|
#include "policies.hpp"
|
||||
|
|
||||
|
bool |
||||
|
Func2::StatxFactory::valid(const std::string str_) |
||||
|
{ |
||||
|
if(str_ == "combined") |
||||
|
return true; |
||||
|
if(str_ == "ff") |
||||
|
return true; |
||||
|
if(str_ == "newest") |
||||
|
return true; |
||||
|
|
||||
|
if(Policies::Search::find(str_)) |
||||
|
return true; |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
std::shared_ptr<Func2::StatxBase> |
||||
|
Func2::StatxFactory::make(const std::string_view str_) |
||||
|
{ |
||||
|
if(str_ == "combine") |
||||
|
return std::make_shared<Func2::StatxCombine>(); |
||||
|
if(str_ == "ff") |
||||
|
return std::make_shared<Func2::StatxFF>(); |
||||
|
if(str_ == "newest") |
||||
|
return std::make_shared<Func2::StatxNewest>(); |
||||
|
|
||||
|
if(Policies::Search::find(str_)) |
||||
|
return std::make_shared<Func2::StatxCombine>(); |
||||
|
|
||||
|
return {}; |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "func_statx_base.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class StatxFactory |
||||
|
{ |
||||
|
public: |
||||
|
static bool valid(const std::string str); |
||||
|
static std::shared_ptr<StatxBase> make(const std::string_view str); |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,48 @@ |
|||||
|
#include "func_statx_ff.hpp"
|
||||
|
|
||||
|
#include "fs_statx.hpp"
|
||||
|
#include "fs_inode.hpp"
|
||||
|
#include "symlinkify.hpp"
|
||||
|
|
||||
|
|
||||
|
std::string_view |
||||
|
Func2::StatxFF::name() const |
||||
|
{ |
||||
|
return "ff"; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
Func2::StatxFF::operator()(const Branches &branches_, |
||||
|
const fs::path &fusepath_, |
||||
|
const u32 flags_, |
||||
|
const u32 mask_, |
||||
|
struct fuse_statx *st_, |
||||
|
const FollowSymlinksEnum follow_symlinks_, |
||||
|
const s64 symlinkify_timeout_) |
||||
|
{ |
||||
|
int rv; |
||||
|
fs::path fullpath; |
||||
|
|
||||
|
for(const auto &branch : branches_) |
||||
|
{ |
||||
|
fullpath = branch.path / fusepath_; |
||||
|
rv = fs::statx(AT_FDCWD, |
||||
|
fullpath, |
||||
|
flags_|AT_SYMLINK_NOFOLLOW, |
||||
|
mask_, |
||||
|
st_, |
||||
|
follow_symlinks_); |
||||
|
if(rv < 0) |
||||
|
continue; |
||||
|
|
||||
|
symlinkify::convert_if_can_be_symlink(fullpath, |
||||
|
st_, |
||||
|
symlinkify_timeout_); |
||||
|
|
||||
|
fs::inode::calc(branch.path,fusepath_,st_); |
||||
|
|
||||
|
return rv; |
||||
|
} |
||||
|
|
||||
|
return -ENOENT; |
||||
|
} |
||||
@ -0,0 +1,25 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "func_statx_base.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class StatxFF : public StatxBase |
||||
|
{ |
||||
|
public: |
||||
|
StatxFF() {} |
||||
|
~StatxFF() {} |
||||
|
|
||||
|
public: |
||||
|
std::string_view name() const; |
||||
|
|
||||
|
public: |
||||
|
int operator()(const Branches &branches, |
||||
|
const fs::path &fusepath, |
||||
|
const u32 flags_, |
||||
|
const u32 mask_, |
||||
|
struct fuse_statx *st, |
||||
|
const FollowSymlinksEnum follow_symlinks, |
||||
|
const s64 symlinkify_timeout); |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,64 @@ |
|||||
|
#include "func_statx_newest.hpp"
|
||||
|
|
||||
|
#include "fs_statx.hpp"
|
||||
|
#include "fs_inode.hpp"
|
||||
|
#include "symlinkify.hpp"
|
||||
|
#include "timespec_utils.hpp"
|
||||
|
|
||||
|
|
||||
|
std::string_view |
||||
|
Func2::StatxNewest::name() const |
||||
|
{ |
||||
|
return "newest"; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
Func2::StatxNewest::operator()(const Branches &branches_, |
||||
|
const fs::path &fusepath_, |
||||
|
const u32 flags_, |
||||
|
const u32 mask_, |
||||
|
struct fuse_statx *st_, |
||||
|
const FollowSymlinksEnum follow_symlinks_, |
||||
|
const s64 symlinkify_timeout_) |
||||
|
{ |
||||
|
int rv; |
||||
|
fs::path fullpath; |
||||
|
const Branch *newest_branch; |
||||
|
|
||||
|
newest_branch = nullptr; |
||||
|
for(const auto &branch : branches_) |
||||
|
{ |
||||
|
struct fuse_statx tmp_st; |
||||
|
|
||||
|
fullpath = branch.path / fusepath_; |
||||
|
rv = fs::statx(AT_FDCWD, |
||||
|
fullpath, |
||||
|
flags_|AT_SYMLINK_NOFOLLOW, |
||||
|
mask_, |
||||
|
&tmp_st, |
||||
|
follow_symlinks_); |
||||
|
if(rv < 0) |
||||
|
continue; |
||||
|
|
||||
|
if(not TimeSpec::is_newer(tmp_st.mtime,st_->mtime)) |
||||
|
continue; |
||||
|
|
||||
|
*st_ = tmp_st; |
||||
|
newest_branch = &branch; |
||||
|
} |
||||
|
|
||||
|
if(!newest_branch) |
||||
|
return -ENOENT; |
||||
|
|
||||
|
if(symlinkify_timeout_ >= 0) |
||||
|
{ |
||||
|
fullpath = newest_branch->path / fusepath_; |
||||
|
symlinkify::convert_if_can_be_symlink(fullpath, |
||||
|
st_, |
||||
|
symlinkify_timeout_); |
||||
|
} |
||||
|
|
||||
|
fs::inode::calc(newest_branch->path,fusepath_,st_); |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
#include "func_statx_base.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class StatxNewest : public StatxBase |
||||
|
{ |
||||
|
public: |
||||
|
StatxNewest() {} |
||||
|
~StatxNewest() {} |
||||
|
|
||||
|
public: |
||||
|
std::string_view name() const; |
||||
|
|
||||
|
public: |
||||
|
int operator()(const Branches &branches, |
||||
|
const fs::path &fusepath, |
||||
|
const u32 flags_, |
||||
|
const u32 mask_, |
||||
|
struct fuse_statx *st, |
||||
|
const FollowSymlinksEnum follow_symlinks, |
||||
|
const s64 symlinkify_timeout); |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,73 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "func_truncate_base.hpp"
|
||||
|
#include "func_truncate_factory.hpp"
|
||||
|
|
||||
|
#include "tofrom_string.hpp"
|
||||
|
|
||||
|
#include "fmt/core.h"
|
||||
|
|
||||
|
#include <atomic>
|
||||
|
|
||||
|
#include <cassert>
|
||||
|
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class Truncate : public ToFromString |
||||
|
{ |
||||
|
private: |
||||
|
std::shared_ptr<Func2::TruncateBase> _impl; |
||||
|
|
||||
|
public: |
||||
|
Truncate() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
Truncate(const std::string &name_) |
||||
|
{ |
||||
|
_impl = Func2::TruncateFactory::make(name_); |
||||
|
assert(_impl); |
||||
|
} |
||||
|
|
||||
|
public: |
||||
|
int |
||||
|
operator()(const Branches &branches_, |
||||
|
const fs::path &fusepath_, |
||||
|
const off_t size_) |
||||
|
{ |
||||
|
std::shared_ptr<Func2::TruncateBase> p; |
||||
|
|
||||
|
p = std::atomic_load(&_impl); |
||||
|
|
||||
|
return (*p)(branches_, |
||||
|
fusepath_, |
||||
|
size_); |
||||
|
} |
||||
|
|
||||
|
public: |
||||
|
std::string |
||||
|
to_string() const |
||||
|
{ |
||||
|
std::shared_ptr<Func2::TruncateBase> p; |
||||
|
|
||||
|
p = std::atomic_load(&_impl); |
||||
|
|
||||
|
return std::string{p->name()}; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
from_string(const std::string_view str_) |
||||
|
{ |
||||
|
std::shared_ptr<Func2::TruncateBase> p; |
||||
|
|
||||
|
p = Func2::TruncateFactory::make(str_); |
||||
|
if(!p) |
||||
|
return -EINVAL; |
||||
|
|
||||
|
_impl = std::atomic_load(&p); |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,35 @@ |
|||||
|
#include "func_truncate_all.hpp"
|
||||
|
|
||||
|
#include "error.hpp"
|
||||
|
#include "fs_truncate.hpp"
|
||||
|
|
||||
|
|
||||
|
std::string_view |
||||
|
Func2::TruncateAll::name() const |
||||
|
{ |
||||
|
return "all"; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
Func2::TruncateAll::operator()(const Branches &branches_, |
||||
|
const fs::path &fusepath_, |
||||
|
const off_t size_) |
||||
|
{ |
||||
|
Err err; |
||||
|
fs::path fullpath; |
||||
|
|
||||
|
for(const auto &branch : branches_) |
||||
|
{ |
||||
|
if(branch.ro()) |
||||
|
{ |
||||
|
err = -EROFS; |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
fullpath = branch.path / fusepath_; |
||||
|
|
||||
|
err = fs::truncate(fullpath,size_); |
||||
|
} |
||||
|
|
||||
|
return err; |
||||
|
} |
||||
@ -0,0 +1,19 @@ |
|||||
|
#include "func_truncate_base.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class TruncateAll : public TruncateBase |
||||
|
{ |
||||
|
public: |
||||
|
TruncateAll() {} |
||||
|
~TruncateAll() {} |
||||
|
|
||||
|
public: |
||||
|
std::string_view name() const; |
||||
|
|
||||
|
public: |
||||
|
int operator()(const Branches &branches, |
||||
|
const fs::path &fusepath, |
||||
|
const off_t size_); |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include "branches.hpp"
|
||||
|
|
||||
|
#include "fs_path.hpp"
|
||||
|
|
||||
|
namespace Func2 |
||||
|
{ |
||||
|
class TruncateBase |
||||
|
{ |
||||
|
public: |
||||
|
TruncateBase() {} |
||||
|
~TruncateBase() {} |
||||
|
|
||||
|
public: |
||||
|
virtual std::string_view name() const = 0; |
||||
|
|
||||
|
public: |
||||
|
virtual int operator()(const Branches &branches, |
||||
|
const fs::path &fusepath, |
||||
|
const off_t size) = 0; |
||||
|
}; |
||||
|
} |
||||
Some files were not shown because too many files changed in this diff
Write
Preview
Loading…
Cancel
Save
Reference in new issue