Browse Source

checkpoint

toml
Antonio SJ Musumeci 3 years ago
parent
commit
7a81a5112c
  1. 2
      src/fs_lremovexattr.hpp
  2. 18
      src/fuse_fgetattr.cpp
  3. 140
      src/fuse_getxattr.cpp
  4. 32
      src/fuse_listxattr.cpp
  5. 31
      src/fuse_mknod.cpp
  6. 169
      src/fuse_open.cpp
  7. 6
      src/fuse_opendir.cpp
  8. 19
      src/fuse_readdir.cpp
  9. 50
      src/fuse_readdir_policy.hpp
  10. 39
      src/fuse_readdir_policy_base.hpp
  11. 39
      src/fuse_readdir_policy_factory.cpp
  12. 30
      src/fuse_readdir_policy_factory.hpp
  13. 33
      src/fuse_readdir_policy_posix.cpp
  14. 42
      src/fuse_readdir_policy_posix.hpp
  15. 1
      src/fuse_readlink.cpp
  16. 19
      src/fuse_release.cpp
  17. 1
      src/fuse_releasedir.cpp
  18. 115
      src/fuse_removexattr.cpp
  19. 155
      src/fuse_rename.cpp
  20. 97
      src/fuse_rmdir.cpp
  21. 24
      src/fuse_statfs.cpp
  22. 7
      src/fuse_statfs.hpp
  23. 46
      src/fuse_statfs_policy.hpp
  24. 39
      src/fuse_statfs_policy_base.hpp
  25. 42
      src/fuse_statfs_policy_branch.hpp
  26. 41
      src/fuse_statfs_policy_factory.cpp
  27. 30
      src/fuse_statfs_policy_factory.hpp
  28. 33
      src/fuse_statfs_policy_full.cpp
  29. 38
      src/fuse_statfs_policy_full.hpp
  30. 86
      src/fuse_truncate.cpp
  31. 12
      src/fuse_write.cpp
  32. 84
      src/fuse_write_buf.cpp
  33. 51
      src/fuse_write_policy.hpp
  34. 38
      src/fuse_write_policy_base.hpp
  35. 38
      src/fuse_write_policy_factory.cpp
  36. 30
      src/fuse_write_policy_factory.hpp
  37. 33
      src/fuse_write_policy_null.cpp
  38. 38
      src/fuse_write_policy_null.hpp
  39. 6
      src/state.cpp
  40. 11
      src/state.hpp

2
src/fs_lremovexattr.hpp

@ -21,6 +21,8 @@
#include "errno.hpp"
#include "xattr.hpp"
#include <string>
#include <sys/types.h>

18
src/fuse_fgetattr.cpp

@ -14,13 +14,11 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "toml.hpp"
#include "config.hpp"
#include "errno.hpp"
#include "fileinfo.hpp"
#include "fs_fstat.hpp"
#include "fs_inode.hpp"
#include "state.hpp"
#include "fuse.h"
@ -47,27 +45,21 @@ namespace l
namespace FUSE::FGETATTR
{
int
config(const toml::value &cfg_)
{
return 0;
}
int
fgetattr(const fuse_file_info_t *ffi_,
struct stat *st_,
fuse_timeouts_t *timeout_)
{
int rv;
Config::Read cfg;
State s;
FileInfo *fi = reinterpret_cast<FileInfo*>(ffi_->fh);
rv = l::fgetattr(fi->fd,fi->fusepath,st_);
timeout_->entry = ((rv >= 0) ?
cfg->cache_entry :
cfg->cache_negative_entry);
timeout_->attr = cfg->cache_attr;
s->entry_cache_timeout :
s->neg_entry_cache_timeout);
timeout_->attr = s->attr_cache_timeout;
return rv;
}

140
src/fuse_getxattr.cpp

@ -14,7 +14,6 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config.hpp"
#include "errno.hpp"
#include "fs_findallfiles.hpp"
#include "fs_lgetxattr.hpp"
@ -47,116 +46,6 @@ namespace l
{
return (strcmp(attrname_,SECURITY_CAPABILITY) == 0);
}
static
int
lgetxattr(const string &path_,
const char *attrname_,
void *value_,
const size_t size_)
{
int rv;
rv = fs::lgetxattr(path_,attrname_,value_,size_);
return ((rv == -1) ? -errno : rv);
}
static
int
getxattr_from_string(char *destbuf_,
const size_t destbufsize_,
const string &src_)
{
const size_t srcbufsize = src_.size();
if(destbufsize_ == 0)
return srcbufsize;
if(srcbufsize > destbufsize_)
return -ERANGE;
memcpy(destbuf_,src_.data(),srcbufsize);
return srcbufsize;
}
static
int
getxattr_user_mergerfs_allpaths(const Branches::CPtr &branches_,
const char *fusepath_,
char *buf_,
const size_t count_)
{
string concated;
StrVec paths;
StrVec branches;
branches_->to_paths(branches);
fs::findallfiles(branches,fusepath_,&paths);
concated = str::join(paths,'\0');
return l::getxattr_from_string(buf_,count_,concated);
}
static
int
getxattr_user_mergerfs(const string &basepath_,
const char *fusepath_,
const string &fullpath_,
const Branches &branches_,
const char *attrname_,
char *buf_,
const size_t count_)
{
StrVec attr;
str::split(attrname_,'.',&attr);
if(attr[2] == "basepath")
return l::getxattr_from_string(buf_,count_,basepath_);
else if(attr[2] == "relpath")
return l::getxattr_from_string(buf_,count_,fusepath_);
else if(attr[2] == "fullpath")
return l::getxattr_from_string(buf_,count_,fullpath_);
else if(attr[2] == "allpaths")
return l::getxattr_user_mergerfs_allpaths(branches_,fusepath_,buf_,count_);
return -ENOATTR;
}
static
int
getxattr(const Policy::Search &searchFunc_,
const Branches &branches_,
const char *fusepath_,
const char *attrname_,
char *buf_,
const size_t count_)
{
int rv;
string fullpath;
StrVec basepaths;
rv = searchFunc_(branches_,fusepath_,&basepaths);
if(rv == -1)
return -errno;
fullpath = fs::path::make(basepaths[0],fusepath_);
if(str::startswith(attrname_,"user.mergerfs."))
return l::getxattr_user_mergerfs(basepaths[0],
fusepath_,
fullpath,
branches_,
attrname_,
buf_,
count_);
return l::lgetxattr(fullpath,attrname_,buf_,count_);
}
}
namespace FUSE::GETXATTR
@ -167,24 +56,25 @@ namespace FUSE::GETXATTR
char *buf_,
size_t count_)
{
Config::Read cfg;
return 0;
// Config::Read cfg;
if((cfg->security_capability == false) &&
l::is_attrname_security_capability(attrname_))
return -ENOATTR;
// if((cfg->security_capability == false) &&
// l::is_attrname_security_capability(attrname_))
// return -ENOATTR;
if(cfg->xattr.to_int())
return -cfg->xattr.to_int();
// if(cfg->xattr.to_int())
// return -cfg->xattr.to_int();
const fuse_context *fc = fuse_get_context();
const ugid::Set ugid(fc->uid,fc->gid);
// const fuse_context *fc = fuse_get_context();
// const ugid::Set ugid(fc->uid,fc->gid);
return l::getxattr(cfg->func.getxattr.policy,
cfg->branches,
fusepath_,
attrname_,
buf_,
count_);
// return l::getxattr(cfg->func.getxattr.policy,
// cfg->branches,
// fusepath_,
// attrname_,
// buf_,
// count_);
}
int

32
src/fuse_listxattr.cpp

@ -15,7 +15,6 @@
*/
#include "category.hpp"
#include "config.hpp"
#include "errno.hpp"
#include "fs_llistxattr.hpp"
#include "fs_path.hpp"
@ -60,44 +59,15 @@ namespace l
namespace FUSE::LISTXATTR
{
int
listxattr_old(const char *fusepath_,
char *list_,
size_t size_)
{
Config::Read cfg;
switch(cfg->xattr)
{
case XAttr::ENUM::PASSTHROUGH:
break;
case XAttr::ENUM::NOATTR:
return 0;
case XAttr::ENUM::NOSYS:
return -ENOSYS;
}
const fuse_context *fc = fuse_get_context();
const ugid::Set ugid(fc->uid,fc->gid);
return l::listxattr(cfg->func.listxattr.policy,
cfg->branches,
fusepath_,
list_,
size_);
}
int
listxattr(const char *fusepath_,
char *list_,
size_t size_)
{
State s;
gfs::path fusepath;
const fuse_context *fc = fuse_get_context();
const ugid::Set ugid(fc->uid,fc->gid);
fusepath = &fusepath_[1];
return s->listxattr(fusepath,list_,size_);
return s->listxattr(&fusepath_[1],list_,size_);
}
}

31
src/fuse_mknod.cpp

@ -14,7 +14,6 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config.hpp"
#include "errno.hpp"
#include "fs_acl.hpp"
#include "fs_clonepath.hpp"
@ -114,36 +113,6 @@ namespace l
return -error;
}
static
int
mknod(const Policy::Search &searchFunc_,
const Policy::Create &createFunc_,
const Branches &branches_,
const char *fusepath_,
const mode_t mode_,
const mode_t umask_,
const dev_t dev_)
{
int rv;
string fusedirpath;
vector<string> createpaths;
vector<string> existingpaths;
fusedirpath = fs::path::dirname(fusepath_);
rv = searchFunc_(branches_,fusedirpath,&existingpaths);
if(rv == -1)
return -errno;
rv = createFunc_(branches_,fusedirpath,&createpaths);
if(rv == -1)
return -errno;
return l::mknod_loop(existingpaths[0],createpaths,
fusepath_,fusedirpath,
mode_,umask_,dev_);
}
}
namespace FUSE::MKNOD

169
src/fuse_open.cpp

@ -14,7 +14,6 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config.hpp"
#include "errno.hpp"
#include "fileinfo.hpp"
#include "fs_lchmod.hpp"
@ -35,68 +34,8 @@
using std::string;
using std::vector;
namespace l
{
static
bool
rdonly(const int flags_)
{
return ((flags_ & O_ACCMODE) == O_RDONLY);
}
static
int
lchmod_and_open_if_not_writable_and_empty(const string &fullpath_,
const int flags_)
{
int rv;
struct stat st;
rv = fs::lstat(fullpath_,&st);
if(rv == -1)
return (errno=EACCES,-1);
if(StatUtil::writable(st))
return (errno=EACCES,-1);
rv = fs::lchmod(fullpath_,(st.st_mode|S_IWUSR|S_IWGRP));
if(rv == -1)
return (errno=EACCES,-1);
rv = fs::open(fullpath_,flags_);
if(rv == -1)
return (errno=EACCES,-1);
fs::fchmod(rv,st.st_mode);
return rv;
}
static
int
nfsopenhack(const std::string &fullpath_,
const int flags_,
const NFSOpenHack nfsopenhack_)
{
switch(nfsopenhack_)
{
default:
case NFSOpenHack::ENUM::OFF:
return (errno=EACCES,-1);
case NFSOpenHack::ENUM::GIT:
if(l::rdonly(flags_))
return (errno=EACCES,-1);
if(fullpath_.find("/.git/") == string::npos)
return (errno=EACCES,-1);
return l::lchmod_and_open_if_not_writable_and_empty(fullpath_,flags_);
case NFSOpenHack::ENUM::ALL:
if(l::rdonly(flags_))
return (errno=EACCES,-1);
return l::lchmod_and_open_if_not_writable_and_empty(fullpath_,flags_);
}
}
/*
The kernel expects being able to issue read requests when running
with writeback caching enabled so we must change O_WRONLY to
@ -115,121 +54,21 @@ namespace l
if(*flags_ & O_APPEND)
*flags_ &= ~O_APPEND;
}
static
void
config_to_ffi_flags(Config::Read &cfg_,
fuse_file_info_t *ffi_)
{
switch(cfg_->cache_files)
{
case CacheFiles::ENUM::LIBFUSE:
ffi_->direct_io = cfg_->direct_io;
ffi_->keep_cache = cfg_->kernel_cache;
ffi_->auto_cache = cfg_->auto_cache;
break;
case CacheFiles::ENUM::OFF:
ffi_->direct_io = 1;
ffi_->keep_cache = 0;
ffi_->auto_cache = 0;
break;
case CacheFiles::ENUM::PARTIAL:
ffi_->direct_io = 0;
ffi_->keep_cache = 0;
ffi_->auto_cache = 0;
break;
case CacheFiles::ENUM::FULL:
ffi_->direct_io = 0;
ffi_->keep_cache = 1;
ffi_->auto_cache = 0;
break;
case CacheFiles::ENUM::AUTO_FULL:
ffi_->direct_io = 0;
ffi_->keep_cache = 0;
ffi_->auto_cache = 1;
break;
}
}
static
int
open_core(const string &basepath_,
const char *fusepath_,
const int flags_,
const bool link_cow_,
const NFSOpenHack nfsopenhack_,
uint64_t *fh_)
{
int fd;
string fullpath;
fullpath = fs::path::make(basepath_,fusepath_);
if(link_cow_ && fs::cow::is_eligible(fullpath.c_str(),flags_))
fs::cow::break_link(fullpath.c_str());
fd = fs::open(fullpath,flags_);
if((fd == -1) && (errno == EACCES))
fd = l::nfsopenhack(fullpath,flags_,nfsopenhack_);
if(fd == -1)
return -errno;
*fh_ = reinterpret_cast<uint64_t>(new FileInfo(fd,fusepath_));
return 0;
}
static
int
open(const Policy::Search &searchFunc_,
const Branches &branches_,
const char *fusepath_,
const int flags_,
const bool link_cow_,
const NFSOpenHack nfsopenhack_,
uint64_t *fh_)
{
int rv;
StrVec basepaths;
rv = searchFunc_(branches_,fusepath_,&basepaths);
if(rv == -1)
return -errno;
return l::open_core(basepaths[0],fusepath_,flags_,link_cow_,nfsopenhack_,fh_);
}
}
namespace FUSE::OPEN
{
int
open_old(const char *fusepath_,
fuse_file_info_t *ffi_)
open(const char *fusepath_,
fuse_file_info_t *ffi_)
{
Config::Read cfg;
State s;
const fuse_context *fc = fuse_get_context();
const ugid::Set ugid(fc->uid,fc->gid);
l::config_to_ffi_flags(cfg,ffi_);
if(cfg->writeback_cache)
if(s->writeback_cache)
l::tweak_flags_writeback_cache(&ffi_->flags);
return l::open(cfg->func.open.policy,
cfg->branches,
fusepath_,
ffi_->flags,
cfg->link_cow,
cfg->nfsopenhack,
&ffi_->fh);
}
int
open(const char *fusepath_,
fuse_file_info_t *ffi_)
{
State s;
return s->open(fusepath_,ffi_);
}
}

6
src/fuse_opendir.cpp

@ -14,8 +14,8 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config.hpp"
#include "dirinfo.hpp"
#include "state.hpp"
#include "fuse.h"
@ -26,11 +26,11 @@ namespace FUSE::OPENDIR
opendir(const char *fusepath_,
fuse_file_info_t *ffi_)
{
Config::Read cfg;
State s;
ffi_->fh = reinterpret_cast<uint64_t>(new DirInfo(fusepath_));
if(cfg->cache_readdir)
if(s->cache_readdir)
{
ffi_->keep_cache = 1;
ffi_->cache_readdir = 1;

19
src/fuse_readdir.cpp

@ -16,12 +16,7 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "fuse_readdir_posix.hpp"
#include "fuse_readdir_linux.hpp"
#include "config.hpp"
#include "dirinfo.hpp"
#include "rwlock.hpp"
#include "state.hpp"
#include "ugid.hpp"
#include "fuse.h"
@ -33,18 +28,10 @@ namespace FUSE::READDIR
readdir(const fuse_file_info_t *ffi_,
fuse_dirents_t *buf_)
{
Config::Read cfg;
DirInfo *di = reinterpret_cast<DirInfo*>(ffi_->fh);
State s;
const fuse_context *fc = fuse_get_context();
const ugid::Set ugid(fc->uid,fc->gid);
switch(cfg->readdir)
{
case ReadDir::ENUM::LINUX:
return FUSE::READDIR_LINUX::readdir_linux(cfg->branches,di->fusepath.c_str(),buf_);
default:
case ReadDir::ENUM::POSIX:
return FUSE::READDIR_POSIX::readdir_posix(cfg->branches,di->fusepath.c_str(),buf_);
}
return s->readdir(ffi_,buf_);
}
}

50
src/fuse_readdir_policy.hpp

@ -0,0 +1,50 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "fuse_readdir_policy_base.hpp"
#include "fuse_readdir_policy_factory.hpp"
#include "fuse.h"
#include <memory>
namespace FUSE::READDIR
{
class Policy
{
public:
Policy(const toml::value &toml_)
{
_readdir = POLICY::factory(toml_);
}
public:
int
operator()(const fuse_file_info_t *ffi_,
fuse_dirents_t *buf_)
{
return (*_readdir)(ffi_,buf_);
}
private:
POLICY::Base::Ptr _readdir;
};
}

39
src/fuse_readdir_policy_base.hpp

@ -0,0 +1,39 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "fs_path.hpp"
#include "fuse.h"
#include <memory>
namespace FUSE::READDIR::POLICY
{
class Base
{
public:
typedef std::shared_ptr<Base> Ptr;
public:
virtual int operator()(const fuse_file_info_t *ffi,
fuse_dirents_t *buf) = 0;
};
}

39
src/fuse_readdir_policy_factory.cpp

@ -0,0 +1,39 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "fuse_readdir_policy_factory.hpp"
#include "fuse_readdir_policy_posix.hpp"
#include <stdexcept>
namespace FUSE::READDIR::POLICY
{
Base::Ptr
factory(const toml::value &toml_)
{
std::string str;
str = toml::find_or(toml_,"func","readdir","policy","posix");
if(str == "posix")
return std::make_shared<POSIX>(toml_);
throw std::runtime_error("readdir");
}
}

30
src/fuse_readdir_policy_factory.hpp

@ -0,0 +1,30 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "fuse_readdir_policy_base.hpp"
#include "toml.hpp"
namespace FUSE::READDIR::POLICY
{
Base::Ptr
factory(const toml::value &);
}

33
src/fuse_readdir_policy_posix.cpp

@ -0,0 +1,33 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "fuse_readdir_policy_posix.hpp"
FUSE::READDIR::POLICY::POSIX::POSIX(const toml::value &toml_)
: _branches(toml_)
{
}
int
FUSE::READDIR::POLICY::POSIX::operator()(const fuse_file_info_t *ffi_,
fuse_dirents_t *buf_)
{
return -ENOENT;
}

42
src/fuse_readdir_policy_posix.hpp

@ -0,0 +1,42 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "fuse_readdir_policy_base.hpp"
#include "branches.hpp"
#include "toml.hpp"
namespace FUSE::READDIR::POLICY
{
class POSIX : public Base
{
public:
POSIX(const toml::value &);
public:
int operator()(const fuse_file_info_t *ffi,
fuse_dirents_t *buf) final;
private:
Branches2 _branches;
};
}

1
src/fuse_readlink.cpp

@ -14,7 +14,6 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config.hpp"
#include "errno.hpp"
#include "fs_lstat.hpp"
#include "fs_path.hpp"

19
src/fuse_release.cpp

@ -14,16 +14,13 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config.hpp"
#include "errno.hpp"
#include "fileinfo.hpp"
#include "fs_close.hpp"
#include "fs_fadvise.hpp"
#include "state.hpp"
#include "fuse.h"
#include <string>
namespace l
{
@ -50,22 +47,12 @@ namespace l
namespace FUSE::RELEASE
{
int
config(const toml::value &toml_)
{
Config::Write cfg;
cfg->dropcacheonclose = toml::find<bool>(toml_,"func","release","drop-cache");
return 0;
}
int
release(const fuse_file_info_t *ffi_)
{
Config::Read cfg;
State s;
FileInfo *fi = reinterpret_cast<FileInfo*>(ffi_->fh);
return l::release(fi,cfg->dropcacheonclose);
return l::release(fi,s->drop_cache_on_release);
}
}

1
src/fuse_releasedir.cpp

@ -14,7 +14,6 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config.hpp"
#include "dirinfo.hpp"
#include "fuse.h"

115
src/fuse_removexattr.cpp

@ -14,127 +14,14 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config.hpp"
#include "errno.hpp"
#include "fs_lremovexattr.hpp"
#include "fs_path.hpp"
#include "policy_rv.hpp"
#include "state.hpp"
#include "ugid.hpp"
#include "fuse.h"
#include <string>
#include <vector>
using std::string;
using std::vector;
namespace l
{
static
int
get_error(const PolicyRV &prv_,
const string &basepath_)
{
for(int i = 0, ei = prv_.success.size(); i < ei; i++)
{
if(prv_.success[i].basepath == basepath_)
return prv_.success[i].rv;
}
for(int i = 0, ei = prv_.error.size(); i < ei; i++)
{
if(prv_.error[i].basepath == basepath_)
return prv_.error[i].rv;
}
return 0;
}
static
void
removexattr_loop_core(const string &basepath_,
const char *fusepath_,
const char *attrname_,
PolicyRV *prv_)
{
string fullpath;
fullpath = fs::path::make(basepath_,fusepath_);
errno = 0;
fs::lremovexattr(fullpath,attrname_);
prv_->insert(errno,basepath_);
}
static
void
removexattr_loop(const vector<string> &basepaths_,
const char *fusepath_,
const char *attrname_,
PolicyRV *prv_)
{
for(size_t i = 0, ei = basepaths_.size(); i != ei; i++)
{
l::removexattr_loop_core(basepaths_[i],fusepath_,attrname_,prv_);
}
}
static
int
removexattr(const Policy::Action &actionFunc_,
const Policy::Search &searchFunc_,
const Branches &branches_,
const char *fusepath_,
const char *attrname_)
{
int rv;
PolicyRV prv;
vector<string> basepaths;
rv = actionFunc_(branches_,fusepath_,&basepaths);
if(rv == -1)
return -errno;
l::removexattr_loop(basepaths,fusepath_,attrname_,&prv);
if(prv.error.empty())
return 0;
if(prv.success.empty())
return prv.error[0].rv;
basepaths.clear();
rv = searchFunc_(branches_,fusepath_,&basepaths);
if(rv == -1)
return -errno;
return l::get_error(prv,basepaths[0]);
}
}
namespace FUSE::REMOVEXATTR
{
int
removexattr_old(const char *fusepath_,
const char *attrname_)
{
Config::Read cfg;
if(cfg->xattr.to_int())
return -cfg->xattr.to_int();
const fuse_context *fc = fuse_get_context();
const ugid::Set ugid(fc->uid,fc->gid);
return l::removexattr(cfg->func.removexattr.policy,
cfg->func.getxattr.policy,
cfg->branches,
fusepath_,
attrname_);
}
int
removexattr(const char *fusepath_,
const char *attrname_)
@ -143,6 +30,6 @@ namespace FUSE::REMOVEXATTR
const fuse_context *fc = fuse_get_context();
const ugid::Set ugid(fc->uid,fc->gid);
return s->removexattr(fusepath_,attrname_);
return s->removexattr(&fusepath_[1],attrname_);
}
}

155
src/fuse_rename.cpp

@ -14,7 +14,6 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config.hpp"
#include "errno.hpp"
#include "fs_clonepath.hpp"
#include "fs_link.hpp"
@ -36,170 +35,18 @@
#include <iostream>
using std::string;
namespace l
{
void
rename_exdev_rename_back(const StrVec &basepaths_,
const gfs::path &oldfusepath_)
{
gfs::path oldpath;
gfs::path newpath;
for(auto &basepath : basepaths_)
{
oldpath = basepath;
oldpath /= ".mergerfs_rename_exdev";
oldpath += oldfusepath_;
newpath = basepath;
newpath += oldfusepath_;
fs::rename(oldpath,newpath);
}
}
static
int
rename_exdev_rename_target(const gfs::path &oldfusepath_,
StrVec *basepaths_)
{
int rv;
gfs::path clonesrc;
gfs::path clonetgt;
// rv = actionPolicy_(branches_,oldfusepath_,basepaths_);
// if(rv == -1)
// return -errno;
ugid::SetRootGuard ugidGuard;
for(auto &basepath : *basepaths_)
{
clonesrc = basepath;
clonetgt = basepath;
clonetgt /= ".mergerfs_rename_exdev";
rv = fs::clonepath(clonesrc,clonetgt,oldfusepath_.parent_path());
if((rv == -1) && (errno == ENOENT))
{
fs::mkdir(clonetgt,01777);
rv = fs::clonepath(clonesrc,clonetgt,oldfusepath_.parent_path());
}
if(rv == -1)
goto error;
clonesrc += oldfusepath_;
clonetgt += oldfusepath_;
rv = fs::rename(clonesrc,clonetgt);
if(rv == -1)
goto error;
}
return 0;
error:
l::rename_exdev_rename_back(*basepaths_,oldfusepath_);
return -EXDEV;
}
static
int
rename_exdev_rel_symlink(const Policy::Action &actionPolicy_,
const Branches::CPtr &branches_,
const gfs::path &oldfusepath_,
const gfs::path &newfusepath_)
{
int rv;
StrVec basepaths;
gfs::path target;
gfs::path linkpath;
// rv = l::rename_exdev_rename_target(actionPolicy_,branches_,oldfusepath_,&basepaths);
// if(rv < 0)
// return rv;
linkpath = newfusepath_;
target = "/.mergerfs_rename_exdev";
target += oldfusepath_;
target = target.lexically_relative(linkpath.parent_path());
rv = FUSE::SYMLINK::symlink(target.c_str(),linkpath.c_str());
if(rv < 0)
l::rename_exdev_rename_back(basepaths,oldfusepath_);
return rv;
}
static
int
rename_exdev_abs_symlink(const gfs::path &mountpoint_,
const gfs::path &oldfusepath_,
const gfs::path &newfusepath_)
{
int rv;
StrVec basepaths;
gfs::path target;
gfs::path linkpath;
// rv = l::rename_exdev_rename_target(actionPolicy_,branches_,oldfusepath_,&basepaths);
// if(rv < 0)
// return rv;
linkpath = newfusepath_;
target = mountpoint_;
target /= ".mergerfs_rename_exdev";
target += oldfusepath_;
rv = FUSE::SYMLINK::symlink(target.c_str(),linkpath.c_str());
if(rv < 0)
l::rename_exdev_rename_back(basepaths,oldfusepath_);
return rv;
}
static
int
rename_exdev(State &s_,
const gfs::path &oldfusepath_,
const gfs::path &newfusepath_)
{
switch(s_->rename_exdev)
{
case RenameEXDEV::INVALID:
case RenameEXDEV::PASSTHROUGH:
return -EXDEV;
case RenameEXDEV::REL_SYMLINK:
return -EXDEV;
// return l::rename_exdev_rel_symlink(oldfusepath_,newfusepath_);
case RenameEXDEV::ABS_SYMLINK:
return l::rename_exdev_abs_symlink(s_->mountpoint,oldfusepath_,newfusepath_);
}
return -EXDEV;
}
}
namespace FUSE::RENAME
{
int
rename(const char *oldfusepath_,
const char *newfusepath_)
{
int rv;
State s;
gfs::path oldfusepath(&oldfusepath_[1]);
gfs::path newfusepath(&newfusepath_[1]);
const fuse_context *fc = fuse_get_context();
const ugid::Set ugid(fc->uid,fc->gid);
rv = s->rename(oldfusepath_,newfusepath_);
if(rv == -EXDEV)
return l::rename_exdev(s,oldfusepath,newfusepath);
return rv;
return s->rename(oldfusepath_,newfusepath_);
}
}

97
src/fuse_rmdir.cpp

@ -14,106 +14,11 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config.hpp"
#include "errno.hpp"
#include "fs_path.hpp"
#include "fs_rmdir.hpp"
#include "fs_unlink.hpp"
#include "state.hpp"
#include "ugid.hpp"
#include "fuse.h"
#include <string>
#include <unistd.h>
using std::string;
using std::vector;
namespace error
{
static
int
calc(const int rv_,
const int prev_,
const int cur_)
{
if(prev_ != 0)
return prev_;
if(rv_ == -1)
return cur_;
return 0;
}
}
namespace l
{
static
int
should_unlink(int rv_,
int errno_,
FollowSymlinks followsymlinks_)
{
return ((rv_ == -1) &&
(errno_ == ENOTDIR) &&
(followsymlinks_ != FollowSymlinks::ENUM::NEVER));
}
static
int
rmdir_core(const string &basepath_,
const char *fusepath_,
const FollowSymlinks followsymlinks_,
const int error_)
{
int rv;
string fullpath;
fullpath = fs::path::make(basepath_,fusepath_);
rv = fs::rmdir(fullpath);
if(l::should_unlink(rv,errno,followsymlinks_))
rv = fs::unlink(fullpath);
return error::calc(rv,error_,errno);
}
static
int
rmdir_loop(const StrVec &basepaths_,
const char *fusepath_,
const FollowSymlinks followsymlinks_)
{
int error;
error = 0;
for(size_t i = 0, ei = basepaths_.size(); i != ei; i++)
{
error = l::rmdir_core(basepaths_[i],fusepath_,followsymlinks_,error);
}
return -error;
}
static
int
rmdir(const Policy::Action &actionFunc_,
const Branches &branches_,
const FollowSymlinks followsymlinks_,
const char *fusepath_)
{
int rv;
vector<string> basepaths;
rv = actionFunc_(branches_,fusepath_,&basepaths);
if(rv == -1)
return -errno;
return l::rmdir_loop(basepaths,fusepath_,followsymlinks_);
}
}
namespace FUSE::RMDIR
{
@ -124,6 +29,6 @@ namespace FUSE::RMDIR
const fuse_context *fc = fuse_get_context();
const ugid::Set ugid(fc->uid,fc->gid);
return s->rmdir(fusepath_);
return s->rmdir(&fusepath_[1]);
}
}

24
src/fuse_statfs.cpp

@ -14,7 +14,6 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config.hpp"
#include "errno.hpp"
#include "fs_lstat.hpp"
#include "fs_path.hpp"
@ -147,33 +146,14 @@ namespace l
namespace FUSE::STATFS
{
int
config(const toml::value &toml_)
{
std::string val;
Config::Write cfg;
val = toml::find<std::string>(toml_,"func","statfs","policy");
cfg->statfs.from_string(val);
val = toml::find<std::string>(toml_,"func","statfs","ignore");
cfg->statfs_ignore.from_string(val);
return 0;
}
int
statfs(const char *fusepath_,
struct statvfs *st_)
{
Config::Read cfg;
State s;
const fuse_context *fc = fuse_get_context();
const ugid::Set ugid(fc->uid,fc->gid);
return l::statfs(cfg->branches,
fusepath_,
cfg->statfs,
cfg->statfs_ignore,
st_);
return s->statfs(&fusepath_[1],st_);
}
}

7
src/fuse_statfs.hpp

@ -1,5 +1,5 @@
/*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@ -16,16 +16,11 @@
#pragma once
#include "toml.hpp"
#include <sys/statvfs.h>
namespace FUSE::STATFS
{
int
config(const toml::value &);
int
statfs(const char *fusepath,
struct statvfs *fsstat);

46
src/fuse_statfs_policy.hpp

@ -0,0 +1,46 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "fuse_statfs_policy_base.hpp"
#include "fuse_statfs_policy_factory.hpp"
namespace FUSE::STATFS
{
class Policy
{
public:
Policy(const toml::value &toml_)
{
_statfs = POLICY::factory(toml_);
}
public:
int
operator()(const gfs::path &fusepath_,
struct statvfs *fsstat_)
{
return (*_statfs)(fusepath_,fsstat_);
}
private:
POLICY::Base::Ptr _statfs;
};
}

39
src/fuse_statfs_policy_base.hpp

@ -0,0 +1,39 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "fs_path.hpp"
#include <memory>
#include <sys/statvfs.h>
namespace FUSE::STATFS::POLICY
{
class Base
{
public:
typedef std::shared_ptr<Base> Ptr;
public:
virtual int operator()(const gfs::path &fusepath,
struct statvfs *fsstat) = 0;
};
}

42
src/fuse_statfs_policy_branch.hpp

@ -0,0 +1,42 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "fuse_statfs_policy_base.hpp"
#include "branches.hpp"
#include "toml.hpp"
namespace FUSE::STATFS::POLICY
{
class Branch : public Base
{
public:
Branch(const toml::value &);
public:
int operator()(const gfs::path &fusepath,
struct statvfs *fsstat) final;
private:
Branches2 _branches;
};
}

41
src/fuse_statfs_policy_factory.cpp

@ -0,0 +1,41 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "fuse_statfs_policy_factory.hpp"
#include "fuse_statfs_policy_branch.hpp"
#include "fuse_statfs_policy_full.hpp"
#include <stdexcept>
namespace FUSE::STATFS::POLICY
{
Base::Ptr
factory(const toml::value &toml_)
{
std::string str;
str = toml::find_or(toml_,"func","readlink","policy","branch");
if(str == "branch")
return std::make_shared<Branch>(toml_);
if(str == "full")
return std::make_shared<Full>(toml_);
throw std::runtime_error("statfs");
}
}

30
src/fuse_statfs_policy_factory.hpp

@ -0,0 +1,30 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "fuse_statfs_policy_base.hpp"
#include "toml.hpp"
namespace FUSE::STATFS::POLICY
{
Base::Ptr
factory(const toml::value &);
}

33
src/fuse_statfs_policy_full.cpp

@ -0,0 +1,33 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "fuse_statfs_policy_full.hpp"
FUSE::STATFS::POLICY::Full::Full(const toml::value &toml_)
: _branches(toml_)
{
}
int
FUSE::STATFS::POLICY::Full::operator()(const gfs::path &fusepath_,
struct statvfs *fsstat)
{
return 0;
}

38
src/fuse_statfs_policy_full.hpp

@ -0,0 +1,38 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "fuse_statfs_policy_full.hpp"
namespace FUSE::STATFS::POLICY
{
class Full : public Base
{
public:
Full(const toml::value &);
public:
int operator()(const gfs::path &fusepath,
struct statvfs *fsstat) final;
private:
Branches2 _branches;
};
}

86
src/fuse_truncate.cpp

@ -14,7 +14,6 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config.hpp"
#include "errno.hpp"
#include "fs_path.hpp"
#include "fs_truncate.hpp"
@ -31,91 +30,6 @@
#include <sys/types.h>
#include <unistd.h>
using std::string;
namespace l
{
static
int
get_error(const PolicyRV &prv_,
const string &basepath_)
{
for(int i = 0, ei = prv_.success.size(); i < ei; i++)
{
if(prv_.success[i].basepath == basepath_)
return prv_.success[i].rv;
}
for(int i = 0, ei = prv_.error.size(); i < ei; i++)
{
if(prv_.error[i].basepath == basepath_)
return prv_.error[i].rv;
}
return 0;
}
static
void
truncate_loop_core(const string &basepath_,
const char *fusepath_,
const off_t size_,
PolicyRV *prv_)
{
string fullpath;
fullpath = fs::path::make(basepath_,fusepath_);
errno = 0;
fs::truncate(fullpath,size_);
prv_->insert(errno,basepath_);
}
static
void
truncate_loop(const StrVec &basepaths_,
const char *fusepath_,
const off_t size_,
PolicyRV *prv_)
{
for(size_t i = 0, ei = basepaths_.size(); i != ei; i++)
{
l::truncate_loop_core(basepaths_[i],fusepath_,size_,prv_);
}
}
static
int
truncate(const Policy::Action &actionFunc_,
const Policy::Search &searchFunc_,
const Branches &branches_,
const char *fusepath_,
const off_t size_)
{
int rv;
PolicyRV prv;
StrVec basepaths;
rv = actionFunc_(branches_,fusepath_,&basepaths);
if(rv == -1)
return -errno;
l::truncate_loop(basepaths,fusepath_,size_,&prv);
if(prv.error.empty())
return 0;
if(prv.success.empty())
return prv.error[0].rv;
basepaths.clear();
rv = searchFunc_(branches_,fusepath_,&basepaths);
if(rv == -1)
return -errno;
return l::get_error(prv,basepaths[0]);
}
}
namespace FUSE::TRUNCATE
{

12
src/fuse_write.cpp

@ -14,7 +14,6 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config.hpp"
#include "errno.hpp"
#include "fileinfo.hpp"
#include "fs_movefile.hpp"
@ -86,15 +85,14 @@ namespace l
int err_)
{
int rv;
Config::Read cfg;
if(cfg->moveonenospc.enabled == false)
//if(cfg->moveonenospc.enabled == false)
return err_;
rv = fs::movefile_as_root(cfg->moveonenospc.policy,
cfg->branches,
fi_->fusepath,
&fi_->fd);
// rv = fs::movefile_as_root(cfg->moveonenospc.policy,
// cfg->branches,
// fi_->fusepath,
// &fi_->fd);
if(rv == -1)
return err_;

84
src/fuse_write_buf.cpp

@ -14,75 +14,10 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config.hpp"
#include "errno.hpp"
#include "fileinfo.hpp"
#include "fs_movefile.hpp"
#include "fuse_write.hpp"
#include "state.hpp"
#include "fuse.h"
#include <string>
#include <vector>
#include <stdlib.h>
#include <unistd.h>
using std::string;
using std::vector;
namespace l
{
static
bool
out_of_space(const int error_)
{
return ((error_ == ENOSPC) ||
(error_ == EDQUOT));
}
static
int
write_buf(const int fd_,
fuse_bufvec *src_,
const off_t offset_)
{
size_t size = fuse_buf_size(src_);
fuse_bufvec dst = FUSE_BUFVEC_INIT(size);
const fuse_buf_copy_flags cpflags =
(fuse_buf_copy_flags)(FUSE_BUF_SPLICE_MOVE|FUSE_BUF_SPLICE_NONBLOCK);
dst.buf->flags = (fuse_buf_flags)(FUSE_BUF_IS_FD|FUSE_BUF_FD_SEEK);
dst.buf->fd = fd_;
dst.buf->pos = offset_;
return fuse_buf_copy(&dst,src_,cpflags);
}
static
int
move_and_write_buf(FileInfo *fi_,
fuse_bufvec *src_,
off_t offset_,
int err_)
{
int rv;
Config::Read cfg;
if(cfg->moveonenospc.enabled == false)
return err_;
rv = fs::movefile_as_root(cfg->moveonenospc.policy,
cfg->branches,
fi_->fusepath,
&fi_->fd);
if(rv == -1)
return err_;
return l::write_buf(fi_->fd,src_,offset_);
}
}
namespace FUSE::WRITE_BUF
{
@ -91,21 +26,8 @@ namespace FUSE::WRITE_BUF
fuse_bufvec *src_,
off_t offset_)
{
int rv;
FileInfo *fi = reinterpret_cast<FileInfo*>(ffi_->fh);
rv = l::write_buf(fi->fd,src_,offset_);
if(l::out_of_space(-rv))
rv = l::move_and_write_buf(fi,src_,offset_,rv);
return rv;
}
State s;
int
write_buf_null(const fuse_file_info_t *ffi_,
fuse_bufvec *src_,
off_t offset_)
{
return src_->buf[0].size;
return s->write(ffi_,src_,offset_);
}
}

51
src/fuse_write_policy.hpp

@ -0,0 +1,51 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "fuse_write_policy_base.hpp"
#include "fuse_write_policy_factory.hpp"
#include "fuse_timeouts.h"
#include <memory>
namespace FUSE::WRITE
{
class Policy
{
public:
Policy(const toml::value &toml_)
{
_write = POLICY::factory(toml_);
}
public:
int
operator()(const fuse_file_info_t *ffi_,
struct fuse_bufvec *buf_,
const off_t offset_)
{
return (*_write)(ffi_,buf_,offset_);
}
private:
POLICY::Base::Ptr _write;
};
}

38
src/fuse_write_policy_base.hpp

@ -0,0 +1,38 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "fuse.h"
#include <memory>
namespace FUSE::WRITE::POLICY
{
class Base
{
public:
typedef std::shared_ptr<Base> Ptr;
public:
virtual int operator()(const fuse_file_info_t *ffi,
struct fuse_bufvec *buf,
const off_t offset) = 0;
};
}

38
src/fuse_write_policy_factory.cpp

@ -0,0 +1,38 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "fuse_write_policy_factory.hpp"
#include "fuse_write_policy_null.hpp"
#include <stdexcept>
namespace FUSE::WRITE::POLICY
{
Base::Ptr
factory(const toml::value &toml_)
{
std::string str;
str = toml::find_or(toml_,"func","write","policy","null");
if(str == "null")
return std::make_shared<null>(toml_);
throw std::runtime_error("write");
}
}

30
src/fuse_write_policy_factory.hpp

@ -0,0 +1,30 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "fuse_write_policy_base.hpp"
#include "toml.hpp"
namespace FUSE::WRITE::POLICY
{
Base::Ptr
factory(const toml::value &);
}

33
src/fuse_write_policy_null.cpp

@ -0,0 +1,33 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "fuse_write_policy_null.hpp"
FUSE::WRITE::POLICY::null::null(const toml::value &toml_)
{
}
int
FUSE::WRITE::POLICY::null::operator()(const fuse_file_info_t *ffi_,
struct fuse_bufvec *buf_,
off_t offset_)
{
return buf_->buf[0].size;
}

38
src/fuse_write_policy_null.hpp

@ -0,0 +1,38 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "fuse_write_policy_base.hpp"
#include "toml.hpp"
namespace FUSE::WRITE::POLICY
{
class null : public Base
{
public:
null(const toml::value &);
public:
int operator()(const fuse_file_info_t *ffi,
struct fuse_bufvec *buf,
const off_t offset) final;
};
}

6
src/state.cpp

@ -39,6 +39,7 @@ StateBase::StateBase(const toml::value &toml_)
mkdir(toml_),
mknod(toml_),
open(toml_),
readdir(toml_),
readlink(toml_),
removexattr(toml_),
rename(toml_),
@ -46,13 +47,14 @@ StateBase::StateBase(const toml::value &toml_)
setxattr(toml_),
symlink(toml_),
truncate(toml_),
write(toml_),
unlink(toml_)
{
mountpoint = toml::find<std::string>(toml_,"filesystem","mountpoint");
link_exdev = toml::find_or(toml_,"func","link","exdev",DEFAULT_LINK_EXDEV);
rename_exdev = toml::find_or(toml_,"func","rename","exdev",DEFAULT_RENAME_EXDEV);
entry_cache_timeout = toml::find_or(toml_,"cache","entry-timeout",60);
neg_entry_cache_timeout = toml::find_or(toml_,"cache","negative-entry-timeout",0);
attr_cache_timeout = toml::find_or(toml_,"cache","attr-timeout",60);
@ -60,4 +62,6 @@ StateBase::StateBase(const toml::value &toml_)
symlinkify = toml::find_or(toml_,"func","symlinkify",false);
symlinkify_timeout = toml::find_or(toml_,"func","symlinkify-timeout",3600);
security_capability = toml::find_or(toml_,"xattr","security-capability",true);
drop_cache_on_release = toml::find_or(toml_,"func","release","drop-cache",false);
}

11
src/state.hpp

@ -30,6 +30,7 @@
#include "fuse_mkdir_policy.hpp"
#include "fuse_mknod_policy.hpp"
#include "fuse_open_policy.hpp"
#include "fuse_readdir_policy.hpp"
#include "fuse_readlink_policy.hpp"
#include "fuse_removexattr_policy.hpp"
#include "fuse_rename_policy.hpp"
@ -38,6 +39,7 @@
#include "fuse_symlink_policy.hpp"
#include "fuse_truncate_policy.hpp"
#include "fuse_unlink_policy.hpp"
#include "fuse_write_policy.hpp"
#include "branches.hpp"
@ -85,6 +87,12 @@ public:
LinkEXDEV link_exdev;
RenameEXDEV rename_exdev;
public:
bool drop_cache_on_release;
public:
bool cache_readdir;
public:
FUSE::ACCESS::Policy access;
FUSE::CHMOD::Policy chmod;
@ -98,6 +106,7 @@ public:
FUSE::MKDIR::Policy mkdir;
FUSE::MKNOD::Policy mknod;
FUSE::OPEN::Policy open;
FUSE::READDIR::Policy readdir;
FUSE::READLINK::Policy readlink;
FUSE::REMOVEXATTR::Policy removexattr;
FUSE::RENAME::Policy rename;
@ -106,6 +115,8 @@ public:
FUSE::SYMLINK::Policy symlink;
FUSE::TRUNCATE::Policy truncate;
FUSE::UNLINK::Policy unlink;
FUSE::WRITE::Policy write;
public:
const toml::value _toml;

|||||||
100:0
Loading…
Cancel
Save