checkpoint

This commit is contained in:
Antonio SJ Musumeci 2022-05-19 18:30:29 -04:00
parent 7a81a5112c
commit 8f6467a11c
34 changed files with 462 additions and 954 deletions

View File

@ -14,198 +14,23 @@
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_acl.hpp"
#include "fs_clonepath.hpp"
#include "fs_open.hpp"
#include "fs_path.hpp"
#include "state.hpp"
#include "ugid.hpp"
#include "fuse.h"
#include <string>
#include <vector>
using std::string;
using std::vector;
namespace l
{
/*
The kernel expects being able to issue read requests when running
with writeback caching enabled so we must change O_WRONLY to
O_RDWR.
With writeback caching enabled the kernel handles O_APPEND. Could
be an issue if the underlying file changes out of band but that is
true of any caching.
*/
static
void
tweak_flags_writeback_cache(int *flags_)
{
if((*flags_ & O_ACCMODE) == O_WRONLY)
*flags_ = ((*flags_ & ~O_ACCMODE) | O_RDWR);
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
create_core(const string &fullpath_,
mode_t mode_,
const mode_t umask_,
const int flags_)
{
if(!fs::acl::dir_has_defaults(fullpath_))
mode_ &= ~umask_;
return fs::open(fullpath_,flags_,mode_);
}
static
int
create_core(const string &createpath_,
const char *fusepath_,
const mode_t mode_,
const mode_t umask_,
const int flags_,
uint64_t *fh_)
{
int rv;
string fullpath;
fullpath = fs::path::make(createpath_,fusepath_);
rv = l::create_core(fullpath,mode_,umask_,flags_);
if(rv == -1)
return -errno;
*fh_ = reinterpret_cast<uint64_t>(new FileInfo(rv,fusepath_));
return 0;
}
static
int
create(const Policy::Search &searchFunc_,
const Policy::Create &createFunc_,
const Branches &branches_,
const char *fusepath_,
const mode_t mode_,
const mode_t umask_,
const int flags_,
uint64_t *fh_)
{
int rv;
string fullpath;
string fusedirpath;
StrVec createpaths;
StrVec 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;
rv = fs::clonepath_as_root(existingpaths[0],createpaths[0],fusedirpath);
if(rv == -1)
return -errno;
return l::create_core(createpaths[0],
fusepath_,
mode_,
umask_,
flags_,
fh_);
}
}
namespace FUSE::CREATE
{
int
create2(const char *fusepath_,
mode_t mode_,
fuse_file_info_t *ffi_)
{
Config::Read cfg;
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)
l::tweak_flags_writeback_cache(&ffi_->flags);
return l::create(cfg->func.getattr.policy,
cfg->func.create.policy,
cfg->branches,
fusepath_,
mode_,
fc->umask,
ffi_->flags,
&ffi_->fh);
}
int
create(const char *fusepath_,
mode_t mode_,
fuse_file_info_t *ffi_)
{
State s;
gfs::path fusepath(fusepath_);
const fuse_context *fc = fuse_get_context();
const ugid::Set ugid(fc->uid,fc->gid);
if(s->writeback_cache)
l::tweak_flags_writeback_cache(&ffi_->flags);
return s->create(fusepath,mode_,fc->umask,ffi_);
return s->create(&fusepath_[1],mode_,fc->umask,ffi_);
}
}

View File

@ -14,8 +14,8 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config.hpp"
#include "ugid.hpp"
#include "state.hpp"
#include "fuse.h"
@ -51,7 +51,7 @@ namespace l
void
want_if_capable(fuse_conn_info *conn_,
const int flag_,
ConfigBOOL *want_)
bool *want_)
{
if(*want_ && l::capable(conn_,flag_))
{
@ -65,16 +65,16 @@ namespace l
static
void
want_if_capable_max_pages(fuse_conn_info *conn_,
Config::Write &cfg_)
State &s_)
{
if(l::capable(conn_,FUSE_CAP_MAX_PAGES))
{
l::want(conn_,FUSE_CAP_MAX_PAGES);
conn_->max_pages = cfg_->fuse_msg_size;
conn_->max_pages = s_->fuse_msg_size;
}
else
{
cfg_->fuse_msg_size = FUSE_DEFAULT_MAX_PAGES_PER_REQ;
s_->fuse_msg_size = FUSE_DEFAULT_MAX_PAGES_PER_REQ;
}
}
}
@ -84,23 +84,34 @@ namespace FUSE::INIT
void *
init(fuse_conn_info *conn_)
{
Config::Write cfg;
State s;
bool async_read;
bool posix_acl;
bool wb_cache;
bool readdirplus;
bool cache_symlinks;
async_read = toml::find_or(s->config_toml,"fuse","async-read",true);
posix_acl = toml::find_or(s->config_toml,"fuse","posix-acl",false);
wb_cache = toml::find_or(s->config_toml,"cache","writeback",false);
readdirplus = toml::find_or(s->config_toml,"func","readdir","readdirplus",false);
cache_symlinks = toml::find_or(s->config_toml,"cache","symlinks",false);
ugid::init();
l::want_if_capable(conn_,FUSE_CAP_ASYNC_DIO);
l::want_if_capable(conn_,FUSE_CAP_ASYNC_READ,&cfg->async_read);
l::want_if_capable(conn_,FUSE_CAP_ASYNC_READ,&async_read);
l::want_if_capable(conn_,FUSE_CAP_ATOMIC_O_TRUNC);
l::want_if_capable(conn_,FUSE_CAP_BIG_WRITES);
l::want_if_capable(conn_,FUSE_CAP_CACHE_SYMLINKS,&cfg->cache_symlinks);
l::want_if_capable(conn_,FUSE_CAP_CACHE_SYMLINKS,&cache_symlinks);
l::want_if_capable(conn_,FUSE_CAP_DONT_MASK);
l::want_if_capable(conn_,FUSE_CAP_IOCTL_DIR);
l::want_if_capable(conn_,FUSE_CAP_PARALLEL_DIROPS);
l::want_if_capable(conn_,FUSE_CAP_READDIR_PLUS,&cfg->readdirplus);
l::want_if_capable(conn_,FUSE_CAP_READDIR_PLUS,&readdirplus);
//l::want_if_capable(conn_,FUSE_CAP_READDIR_PLUS_AUTO);
l::want_if_capable(conn_,FUSE_CAP_POSIX_ACL,&cfg->posix_acl);
l::want_if_capable(conn_,FUSE_CAP_WRITEBACK_CACHE,&cfg->writeback_cache);
l::want_if_capable_max_pages(conn_,cfg);
l::want_if_capable(conn_,FUSE_CAP_POSIX_ACL,&posix_acl);
l::want_if_capable(conn_,FUSE_CAP_WRITEBACK_CACHE,&wb_cache);
l::want_if_capable_max_pages(conn_,s);
conn_->want &= ~FUSE_CAP_POSIX_LOCKS;
conn_->want &= ~FUSE_CAP_FLOCK_LOCKS;

View File

@ -14,129 +14,12 @@
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"
#include "fs_lstat.hpp"
#include "fs_path.hpp"
#include "fuse_getattr.hpp"
#include "fuse_symlink.hpp"
#include "state.hpp"
#include "ugid.hpp"
#include "fuse.h"
namespace l
{
static
int
link_exdev_rel_symlink(const char *oldpath_,
const char *newpath_,
struct stat *st_,
fuse_timeouts_t *timeouts_)
{
int rv;
gfs::path target(oldpath_);
gfs::path linkpath(newpath_);
target = target.lexically_relative(linkpath.parent_path());
rv = FUSE::SYMLINK::symlink(target.c_str(),linkpath.c_str());
if(rv == 0)
rv = FUSE::GETATTR::getattr(oldpath_,st_,timeouts_);
// Disable caching since we created a symlink but should be a regular.
timeouts_->attr = 0;
timeouts_->entry = 0;
return rv;
}
static
int
link_exdev_abs_base_symlink(const char *oldpath_,
const char *newpath_,
struct stat *st_,
fuse_timeouts_t *timeouts_)
{
int rv;
StrVec basepaths;
gfs::path target;
target = "FIXME";
rv = FUSE::SYMLINK::symlink(target.c_str(),newpath_);
if(rv == 0)
rv = FUSE::GETATTR::getattr(oldpath_,st_,timeouts_);
// Disable caching since we created a symlink but should be a regular.
timeouts_->attr = 0;
timeouts_->entry = 0;
return rv;
}
static
int
link_exdev_abs_pool_symlink(const gfs::path &mount_,
const char *oldpath_,
const char *newpath_,
struct stat *st_,
fuse_timeouts_t *timeouts_)
{
int rv;
gfs::path target;
target = mount_ / &oldpath_[1];
rv = FUSE::SYMLINK::symlink(target.c_str(),newpath_);
if(rv == 0)
rv = FUSE::GETATTR::getattr(oldpath_,st_,timeouts_);
// Disable caching since we created a symlink but should be a regular.
timeouts_->attr = 0;
timeouts_->entry = 0;
return rv;
}
static
int
link_exdev(State &s_,
const char *oldpath_,
const char *newpath_,
struct stat *st_,
fuse_timeouts_t *timeouts_)
{
switch(s_->link_exdev)
{
case LinkEXDEV::INVALID:
case LinkEXDEV::PASSTHROUGH:
return -EXDEV;
case LinkEXDEV::REL_SYMLINK:
return l::link_exdev_rel_symlink(oldpath_,
newpath_,
st_,
timeouts_);
case LinkEXDEV::ABS_BASE_SYMLINK:
return l::link_exdev_abs_base_symlink(oldpath_,
newpath_,
st_,
timeouts_);
case LinkEXDEV::ABS_POOL_SYMLINK:
return l::link_exdev_abs_pool_symlink(s_->mountpoint,
oldpath_,
newpath_,
st_,
timeouts_);
}
return -EXDEV;
}
}
namespace FUSE::LINK
{
int
@ -155,8 +38,8 @@ namespace FUSE::LINK
oldpath = &oldpath_[1];
newpath = &newpath_[1];
rv = s->link(oldpath,newpath);
if(rv == -EXDEV)
return l::link_exdev(s,oldpath_,newpath_,st_,timeouts_);
if(rv < 0)
return rv;
return s->getattr(newpath,st_,timeouts_);
}

View File

@ -14,137 +14,11 @@
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"
#include "fs_mkdir.hpp"
#include "fs_path.hpp"
#include "ghc/filesystem.hpp"
#include "policy.hpp"
#include "state.hpp"
#include "ugid.hpp"
#include "fuse.h"
#include <string>
using std::string;
namespace error
{
static
inline
int
calc(const int rv_,
const int prev_,
const int cur_)
{
if(rv_ == -1)
{
if(prev_ == 0)
return 0;
return cur_;
}
return 0;
}
}
namespace l
{
static
int
mkdir_core(const string &fullpath_,
mode_t mode_,
const mode_t umask_)
{
if(!fs::acl::dir_has_defaults(fullpath_))
mode_ &= ~umask_;
return fs::mkdir(fullpath_,mode_);
}
static
int
mkdir_loop_core(const string &createpath_,
const char *fusepath_,
const mode_t mode_,
const mode_t umask_,
const int error_)
{
int rv;
string fullpath;
fullpath = fs::path::make(createpath_,fusepath_);
rv = l::mkdir_core(fullpath,mode_,umask_);
return error::calc(rv,error_,errno);
}
static
int
mkdir_loop(const string &existingpath_,
const StrVec &createpaths_,
const char *fusepath_,
const string &fusedirpath_,
const mode_t mode_,
const mode_t umask_)
{
int rv;
int error;
error = -1;
for(size_t i = 0, ei = createpaths_.size(); i != ei; i++)
{
rv = fs::clonepath_as_root(existingpath_,createpaths_[i],fusedirpath_);
if(rv == -1)
error = error::calc(rv,error,errno);
else
error = l::mkdir_loop_core(createpaths_[i],
fusepath_,
mode_,
umask_,
error);
}
return -error;
}
static
int
mkdir(const Policy::Search &getattrPolicy_,
const Policy::Create &mkdirPolicy_,
const Branches &branches_,
const char *fusepath_,
const mode_t mode_,
const mode_t umask_)
{
int rv;
string fusedirpath;
StrVec createpaths;
StrVec existingpaths;
fusedirpath = fs::path::dirname(fusepath_);
rv = getattrPolicy_(branches_,fusedirpath.c_str(),&existingpaths);
if(rv == -1)
return -errno;
rv = mkdirPolicy_(branches_,fusedirpath.c_str(),&createpaths);
if(rv == -1)
return -errno;
return l::mkdir_loop(existingpaths[0],
createpaths,
fusepath_,
fusedirpath,
mode_,
umask_);
}
}
namespace FUSE::MKDIR
{
@ -153,11 +27,9 @@ namespace FUSE::MKDIR
mode_t mode_)
{
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->mkdir(fusepath,mode_,fc->umask);
return s->mkdir(&fusepath_[1],mode_,fc->umask);
}
}

View File

@ -1,58 +0,0 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "fuse_readdir_plus_linux.hpp"
#include "fuse_readdir_plus_posix.hpp"
#include "config.hpp"
#include "dirinfo.hpp"
#include "rwlock.hpp"
#include "ugid.hpp"
#include "fuse.h"
namespace FUSE::READDIR_PLUS
{
int
readdir_plus(const fuse_file_info_t *ffi_,
fuse_dirents_t *buf_)
{
Config::Read cfg;
DirInfo *di = reinterpret_cast<DirInfo*>(ffi_->fh);
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_PLUS_LINUX::readdir_plus_linux(cfg->branches,
di->fusepath.c_str(),
cfg->cache_entry,
cfg->cache_attr,
buf_);
default:
case ReadDir::ENUM::POSIX:
return FUSE::READDIR_PLUS_POSIX::readdir_plus_posix(cfg->branches,
di->fusepath.c_str(),
cfg->cache_entry,
cfg->cache_attr,
buf_);
}
}
}

37
src/fuse_readdirplus.cpp Normal file
View File

@ -0,0 +1,37 @@
/*
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 "state.hpp"
#include "ugid.hpp"
#include "fuse.h"
namespace FUSE::READDIRPLUS
{
int
readdirplus(const fuse_file_info_t *ffi_,
fuse_dirents_t *buf_)
{
State s;
const fuse_context *fc = fuse_get_context();
const ugid::Set ugid(fc->uid,fc->gid);
return s->readdirplus(ffi_,buf_);
}
}

View File

@ -19,9 +19,9 @@
#include "fuse.h"
namespace FUSE::READDIR_PLUS
namespace FUSE::READDIRPLUS
{
int
readdir_plus(const fuse_file_info_t *ffi,
fuse_dirents_t *buf);
readdirplus(const fuse_file_info_t *ffi,
fuse_dirents_t *buf);
}

View File

@ -0,0 +1,48 @@
/*
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_readdirplus_policy_base.hpp"
#include "fuse_readdirplus_policy_factory.hpp"
#include "fuse.h"
namespace FUSE::READDIRPLUS
{
class Policy
{
public:
Policy(const toml::value &toml_)
{
_readdirplus = POLICY::factory(toml_);
}
public:
int
operator()(const fuse_file_info_t *ffi_,
fuse_dirents_t *buf_)
{
return (*_readdirplus)(ffi_,buf_);
}
private:
POLICY::Base::Ptr _readdirplus;
};
}

View File

@ -0,0 +1,37 @@
/*
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::READDIRPLUS::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;
};
}

View File

@ -0,0 +1,34 @@
/*
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_readdirplus_policy_enosys.hpp"
#include "errno.hpp"
FUSE::READDIRPLUS::POLICY::enosys::enosys(const toml::value &toml_)
{
}
int
FUSE::READDIRPLUS::POLICY::enosys::operator()(const fuse_file_info_t *ffi_,
fuse_dirents_t *buf_)
{
return -ENOSYS;
}

View File

@ -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 "fuse_readdirplus_policy_base.hpp"
#include "branches.hpp"
#include "toml.hpp"
namespace FUSE::READDIRPLUS::POLICY
{
class enosys : public Base
{
public:
enosys(const toml::value &);
public:
int operator()(const fuse_file_info_t *ffi,
fuse_dirents_t *buf) final;
};
}

View File

@ -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_readdirplus_policy_factory.hpp"
#include "fuse_readdirplus_policy_enosys.hpp"
#include <stdexcept>
namespace FUSE::READDIRPLUS::POLICY
{
Base::Ptr
factory(const toml::value &toml_)
{
std::string str;
str = toml::find_or(toml_,"func","readdirplus","policy","enosys");
if(str == "enosys")
return std::make_shared<enosys>(toml_);
throw std::runtime_error("readdirplus");
}
}

View File

@ -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_readdirplus_policy_base.hpp"
#include "toml.hpp"
namespace FUSE::READDIRPLUS::POLICY
{
Base::Ptr
factory(const toml::value &);
}

View File

@ -14,6 +14,8 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "fuse_readdirplus_policy_linux.hpp"
#include "branches.hpp"
#include "errno.hpp"
#include "fs_close.hpp"
@ -137,15 +139,16 @@ namespace l
}
}
namespace FUSE::READDIR_PLUS_LINUX
FUSE::READDIRPLUS::POLICY::linux::linux(const toml::value &toml_)
: _branches(toml_)
{
int
readdir_plus_linux(const Branches::CPtr &branches_,
const char *dirname_,
const uint64_t entry_timeout_,
const uint64_t attr_timeout_,
fuse_dirents_t *buf_)
{
return l::readdir_plus(branches_,dirname_,entry_timeout_,attr_timeout_,buf_);
}
}
int
FUSE::READDIRPLUS::POLICY::linux::operator()(const fuse_file_info_t *ffi_,
fuse_dirents_t *buf_)
{
return -ENOENT;
}

View File

@ -18,19 +18,25 @@
#pragma once
#include "fuse_readdirplus_policy_base.hpp"
#include "branches.hpp"
#include "fuse.h"
#include <cstdint>
namespace FUSE::READDIR_PLUS_POSIX
namespace FUSE::READDIRPLUS::POLICY
{
int
readdir_plus_posix(const Branches::CPtr &branches,
const char *dirname,
const uint64_t entry_timeout,
const uint64_t attr_timeout,
fuse_dirents_t *buf);
class linux : public Base
{
public:
linux(const toml::value &);
public:
int operator()(const fuse_file_info_t *ffi,
fuse_dirents_t *buf) final;
private:
Branches2 _branches;
};
}

View File

@ -16,6 +16,8 @@
#define _DEFAULT_SOURCE
#include "fuse_readdirplus_policy_posix.hpp"
#include "branches.hpp"
#include "errno.hpp"
#include "fs_closedir.hpp"
@ -128,15 +130,16 @@ namespace l
}
}
namespace FUSE::READDIR_PLUS_POSIX
FUSE::READDIRPLUS::POLICY::POSIX::POSIX(const toml::value &toml_)
: _branches(toml_)
{
int
readdir_plus_posix(const Branches::CPtr &branches_,
const char *dirname_,
const uint64_t entry_timeout_,
const uint64_t attr_timeout_,
fuse_dirents_t *buf_)
{
return l::readdir_plus(branches_,dirname_,entry_timeout_,attr_timeout_,buf_);
}
}
int
FUSE::READDIRPLUS::POLICY::POSIX::operator()(const fuse_file_info_t *ffi_,
fuse_dirents_t *buf_)
{
return -ENOENT;
}

View File

@ -1,7 +1,7 @@
/*
ISC License
Copyright (c) 2020, 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
@ -18,19 +18,25 @@
#pragma once
#include "fuse_readdirplus_policy_base.hpp"
#include "branches.hpp"
#include "fuse.h"
#include <cstdint>
namespace FUSE::READDIR_PLUS_LINUX
namespace FUSE::READDIRPLUS::POLICY
{
int
readdir_plus_linux(const Branches::CPtr &branches,
const char *dirname,
const uint64_t entry_timeout,
const uint64_t attr_timeout,
fuse_dirents_t *buf);
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;
};
}

View File

@ -14,135 +14,11 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "errno.hpp"
#include "fs_lstat.hpp"
#include "fs_path.hpp"
#include "fs_statvfs.hpp"
#include "statvfs_util.hpp"
#include "state.hpp"
#include "ugid.hpp"
#include "fuse.h"
#include <algorithm>
#include <limits>
#include <map>
#include <string>
#include <vector>
using std::string;
using std::map;
using std::vector;
namespace l
{
static
void
normalize_statvfs(struct statvfs *fsstat_,
const unsigned long min_bsize_,
const unsigned long min_frsize_,
const unsigned long min_namemax_)
{
fsstat_->f_blocks = (fsblkcnt_t)((fsstat_->f_blocks * fsstat_->f_frsize) / min_frsize_);
fsstat_->f_bfree = (fsblkcnt_t)((fsstat_->f_bfree * fsstat_->f_frsize) / min_frsize_);
fsstat_->f_bavail = (fsblkcnt_t)((fsstat_->f_bavail * fsstat_->f_frsize) / min_frsize_);
fsstat_->f_bsize = min_bsize_;
fsstat_->f_frsize = min_frsize_;
fsstat_->f_namemax = min_namemax_;
}
static
void
merge_statvfs(struct statvfs * const out_,
const struct statvfs * const in_)
{
out_->f_blocks += in_->f_blocks;
out_->f_bfree += in_->f_bfree;
out_->f_bavail += in_->f_bavail;
out_->f_files += in_->f_files;
out_->f_ffree += in_->f_ffree;
out_->f_favail += in_->f_favail;
}
static
bool
should_ignore(const StatFSIgnore ignore_,
const Branch &branch_,
const bool readonly_)
{
return ((((ignore_ == StatFSIgnore::ENUM::RO) || readonly_) &&
(branch_.ro_or_nc())) ||
((ignore_ == StatFSIgnore::ENUM::NC) && (branch_.nc())));
}
static
int
statfs(const Branches::CPtr &branches_,
const char *fusepath_,
const StatFS mode_,
const StatFSIgnore ignore_,
struct statvfs *fsstat_)
{
int rv;
string fullpath;
struct stat st;
struct statvfs stvfs;
unsigned long min_bsize;
unsigned long min_frsize;
unsigned long min_namemax;
map<dev_t,struct statvfs> fsstats;
min_bsize = std::numeric_limits<unsigned long>::max();
min_frsize = std::numeric_limits<unsigned long>::max();
min_namemax = std::numeric_limits<unsigned long>::max();
for(const auto &branch : *branches_)
{
fullpath = ((mode_ == StatFS::ENUM::FULL) ?
fs::path::make(branch.path,fusepath_) :
branch.path);
rv = fs::lstat(fullpath,&st);
if(rv == -1)
continue;
rv = fs::lstatvfs(fullpath,&stvfs);
if(rv == -1)
continue;
if(stvfs.f_bsize && (min_bsize > stvfs.f_bsize))
min_bsize = stvfs.f_bsize;
if(stvfs.f_frsize && (min_frsize > stvfs.f_frsize))
min_frsize = stvfs.f_frsize;
if(stvfs.f_namemax && (min_namemax > stvfs.f_namemax))
min_namemax = stvfs.f_namemax;
if(l::should_ignore(ignore_,branch,StatVFS::readonly(stvfs)))
{
stvfs.f_bavail = 0;
stvfs.f_favail = 0;
}
fsstats.insert(std::make_pair(st.st_dev,stvfs));
}
map<dev_t,struct statvfs>::iterator iter = fsstats.begin();
map<dev_t,struct statvfs>::iterator enditer = fsstats.end();
if(iter != enditer)
{
*fsstat_ = iter->second;
l::normalize_statvfs(fsstat_,min_bsize,min_frsize,min_namemax);
for(++iter; iter != enditer; ++iter)
{
l::normalize_statvfs(&iter->second,min_bsize,min_frsize,min_namemax);
l::merge_statvfs(fsstat_,&iter->second);
}
}
return 0;
}
}
namespace FUSE::STATFS
{

View File

@ -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_branch.hpp"
FUSE::STATFS::POLICY::Branch::Branch(const toml::value &toml_)
: _branches(toml_)
{
}
int
FUSE::STATFS::POLICY::Branch::operator()(const gfs::path &fusepath_,
struct statvfs *fsstat)
{
return 0;
}

View File

@ -18,7 +18,11 @@
#pragma once
#include "fuse_statfs_policy_full.hpp"
#include "fuse_statfs_policy_base.hpp"
#include "branches.hpp"
#include "toml.hpp"
namespace FUSE::STATFS::POLICY

View File

@ -14,130 +14,11 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config.hpp"
#include "errno.hpp"
#include "fs_clonepath.hpp"
#include "fs_lstat.hpp"
#include "fs_path.hpp"
#include "fs_inode.hpp"
#include "fs_symlink.hpp"
#include "fuse_getattr.hpp"
#include "ugid.hpp"
#include "state.hpp"
#include "ugid.hpp"
#include "fuse.h"
#include <string>
#include <sys/types.h>
#include <unistd.h>
using std::string;
namespace error
{
static
inline
int
calc(const int rv_,
const int prev_,
const int cur_)
{
if(rv_ == -1)
{
if(prev_ == 0)
return 0;
return cur_;
}
return 0;
}
}
namespace l
{
static
int
symlink_loop_core(const string &newbasepath_,
const char *target_,
const char *linkpath_,
struct stat *st_,
const int error_)
{
int rv;
string fullnewpath;
fullnewpath = fs::path::make(newbasepath_,linkpath_);
rv = fs::symlink(target_,fullnewpath);
if((rv != -1) && (st_ != NULL) && (st_->st_ino == 0))
{
fs::lstat(fullnewpath,st_);
if(st_->st_ino != 0)
fs::inode::calc(linkpath_,st_);
}
return error::calc(rv,error_,errno);
}
static
int
symlink_loop(const string &existingpath_,
const StrVec &newbasepaths_,
const char *target_,
const char *linkpath_,
const string &newdirpath_,
struct stat *st_)
{
int rv;
int error;
error = -1;
for(size_t i = 0, ei = newbasepaths_.size(); i != ei; i++)
{
rv = fs::clonepath_as_root(existingpath_,newbasepaths_[i],newdirpath_);
if(rv == -1)
error = error::calc(rv,error,errno);
else
error = l::symlink_loop_core(newbasepaths_[i],
target_,
linkpath_,
st_,
error);
}
return -error;
}
static
int
symlink(const Policy::Search &searchFunc_,
const Policy::Create &createFunc_,
const Branches &branches_,
const char *target_,
const char *linkpath_,
struct stat *st_)
{
int rv;
string newdirpath;
StrVec newbasepaths;
StrVec existingpaths;
newdirpath = fs::path::dirname(linkpath_);
rv = searchFunc_(branches_,newdirpath,&existingpaths);
if(rv == -1)
return -errno;
rv = createFunc_(branches_,newdirpath,&newbasepaths);
if(rv == -1)
return -errno;
return l::symlink_loop(existingpaths[0],newbasepaths,
target_,linkpath_,newdirpath,st_);
}
}
namespace FUSE::SYMLINK
{
@ -147,35 +28,10 @@ namespace FUSE::SYMLINK
struct stat *st_,
fuse_timeouts_t *timeouts_)
{
int rv;
Config::Read cfg;
const fuse_context *fc = fuse_get_context();
State s;
const fuse_context *fc = fuse_get_context();
const ugid::Set ugid(fc->uid,fc->gid);
rv = l::symlink(cfg->func.getattr.policy,
cfg->func.symlink.policy,
cfg->branches,
target_,
linkpath_,
st_);
if(timeouts_ != NULL)
{
switch(cfg->follow_symlinks)
{
case FollowSymlinks::ENUM::NEVER:
timeouts_->entry = ((rv >= 0) ?
cfg->cache_entry :
cfg->cache_negative_entry);
timeouts_->attr = cfg->cache_attr;
break;
default:
timeouts_->entry = 0;
timeouts_->attr = 0;
break;
}
}
return rv;
return s->symlink(target_,&linkpath_[1],st_,timeouts_);
}
}

View File

@ -18,9 +18,6 @@
#include "fuse.h"
#include "toml.hpp"
#include <sys/stat.h>
namespace FUSE::SYMLINK
{

View File

@ -37,9 +37,11 @@ namespace FUSE::SYMLINK
public:
int
operator()(const char *target_,
const gfs::path &linkpath_)
const gfs::path &linkpath_,
struct stat *st_ = NULL,
fuse_timeouts_t *timeouts_ = NULL)
{
return (*_symlink)(target_,linkpath_);
return (*_symlink)(target_,linkpath_,st_,timeouts_);
}
private:

View File

@ -20,6 +20,8 @@
#include "fs_path.hpp"
#include "fuse.h"
#include <memory>
@ -32,6 +34,8 @@ namespace FUSE::SYMLINK::POLICY
public:
virtual int operator()(const char *target,
const gfs::path &linkpath) = 0;
const gfs::path &linkpath,
struct stat *st_ = NULL,
fuse_timeouts_t *timeouts_ = NULL) = 0;
};
}

View File

@ -29,7 +29,9 @@ FUSE::SYMLINK::POLICY::EPFF::EPFF(const toml::value &toml_)
int
FUSE::SYMLINK::POLICY::EPFF::operator()(const char *target_,
const gfs::path &linkpath_)
const gfs::path &linkpath_,
struct stat *st_,
fuse_timeouts_t *timeouts_)
{
int rv;
gfs::path fullpath;

View File

@ -32,7 +32,9 @@ namespace FUSE::SYMLINK::POLICY
public:
int operator()(const char *target,
const gfs::path &linkpath) final;
const gfs::path &linkpath,
struct stat *st,
fuse_timeouts_t *timeouts) final;
private:
Branches2 _branches;

View File

@ -32,7 +32,9 @@ FUSE::SYMLINK::POLICY::FF::FF(const toml::value &toml_)
int
FUSE::SYMLINK::POLICY::FF::operator()(const char *target_,
const gfs::path &linkpath_)
const gfs::path &linkpath_,
struct stat *st_,
fuse_timeouts_t *timeouts_)
{
int rv;
gfs::path fullpath;

View File

@ -32,7 +32,9 @@ namespace FUSE::SYMLINK::POLICY
public:
int operator()(const char *target,
const gfs::path &linkpath) final;
const gfs::path &linkpath,
struct stat *st,
fuse_timeouts_t *timeouts) final;
private:
Branches2 _branches;

View File

@ -14,132 +14,22 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config.hpp"
#include "errno.hpp"
#include "fs_lutimens.hpp"
#include "fs_path.hpp"
#include "policy_rv.hpp"
#include "state.hpp"
#include "ugid.hpp"
#include "fuse.h"
#include <string>
#include <fcntl.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
utimens_loop_core(const string &basepath_,
const char *fusepath_,
const timespec ts_[2],
PolicyRV *prv_)
{
string fullpath;
fullpath = fs::path::make(basepath_,fusepath_);
errno = 0;
fs::lutimens(fullpath,ts_);
prv_->insert(errno,basepath_);
}
static
void
utimens_loop(const StrVec &basepaths_,
const char *fusepath_,
const timespec ts_[2],
PolicyRV *prv_)
{
for(size_t i = 0, ei = basepaths_.size(); i != ei; i++)
{
l::utimens_loop_core(basepaths_[i],fusepath_,ts_,prv_);
}
}
static
int
utimens(const Policy::Action &utimensPolicy_,
const Policy::Search &getattrPolicy_,
const Branches &branches_,
const char *fusepath_,
const timespec ts_[2])
{
int rv;
PolicyRV prv;
StrVec basepaths;
rv = utimensPolicy_(branches_,fusepath_,&basepaths);
if(rv == -1)
return -errno;
l::utimens_loop(basepaths,fusepath_,ts_,&prv);
if(prv.error.empty())
return 0;
if(prv.success.empty())
return prv.error[0].rv;
basepaths.clear();
rv = getattrPolicy_(branches_,fusepath_,&basepaths);
if(rv == -1)
return -errno;
return l::get_error(prv,basepaths[0]);
}
}
namespace FUSE::UTIMENS
{
int
config(const toml::value &toml_)
{
std::string val;
Config::Write cfg;
val = toml::find<std::string>(toml_,"func","utimens","policy");
cfg->func.utimens.from_string(val);
return 0;
}
int
utimens(const char *fusepath_,
const timespec ts_[2])
{
Config::Read cfg;
State s;
const fuse_context *fc = fuse_get_context();
const ugid::Set ugid(fc->uid,fc->gid);
return l::utimens(cfg->func.utimens.policy,
cfg->func.getattr.policy,
cfg->branches,
fusepath_,
ts_);
return s->utimens(&fusepath_[1],ts_);
}
}

View File

@ -18,25 +18,31 @@
#pragma once
#include "fuse_utimens_func_base.hpp"
#include "fuse_utimens_policy_base.hpp"
#include "fuse_utimens_policy_factory.hpp"
#include "toml.hpp"
#include <sys/stat.h>
namespace FUSE::UTIMENS
{
class Func
class Policy
{
public:
Func(const toml::value &);
Policy(const toml::value &toml_)
{
_utimens = POLICY::factory(toml_);
}
public:
int operator()(const char *fusepath,
const timespec ts_[2]);
int
operator()(const gfs::path &fusepath_,
const timespec ts_[2])
{
return (*_utimens)(fusepath_,ts_);
}
private:
FuncBase::Ptr _utimens;
POLICY::Base::Ptr _utimens;
};
}

View File

@ -20,6 +20,8 @@
#include "fs_path.hpp"
#include "fuse.h"
#include <memory>

View File

@ -54,7 +54,7 @@
#include "fuse_prepare_hide.hpp"
#include "fuse_read_buf.hpp"
#include "fuse_readdir.hpp"
#include "fuse_readdir_plus.hpp"
#include "fuse_readdirplus.hpp"
#include "fuse_readlink.hpp"
#include "fuse_release.hpp"
#include "fuse_releasedir.hpp"
@ -84,8 +84,7 @@ namespace l
{
static
void
get_fuse_operations(struct fuse_operations &ops_,
const bool nullrw_)
get_fuse_operations(struct fuse_operations &ops_)
{
ops_.access = FUSE::ACCESS::access;
ops_.bmap = FUSE::BMAP::bmap;
@ -118,9 +117,9 @@ namespace l
ops_.opendir = FUSE::OPENDIR::opendir;
ops_.poll = FUSE::POLL::poll;;
ops_.prepare_hide = FUSE::PREPARE_HIDE::prepare_hide;
ops_.read_buf = (nullrw_ ? FUSE::READ_BUF::read_buf_null : FUSE::READ_BUF::read_buf);
// ops_.read_buf = FUSE::READ::read;
ops_.readdir = FUSE::READDIR::readdir;
ops_.readdir_plus = FUSE::READDIR_PLUS::readdir_plus;
ops_.readdir_plus = FUSE::READDIRPLUS::readdirplus;
ops_.readlink = FUSE::READLINK::readlink;
ops_.release = FUSE::RELEASE::release;
ops_.releasedir = FUSE::RELEASEDIR::releasedir;
@ -133,7 +132,7 @@ namespace l
ops_.truncate = FUSE::TRUNCATE::truncate;
ops_.unlink = FUSE::UNLINK::unlink;
ops_.utimens = FUSE::UTIMENS::utimens;
ops_.write_buf = (nullrw_ ? FUSE::WRITE_BUF::write_buf_null : FUSE::WRITE_BUF::write_buf);
// ops_.write_buf = FUSE::WRITE::write;
return;
}
@ -165,7 +164,7 @@ namespace l
args.allocated = 0;
l::setup_resources();
l::get_fuse_operations(ops,false);
l::get_fuse_operations(ops);
return fuse_main(args.argc,
args.argv,

View File

@ -40,15 +40,18 @@ StateBase::StateBase(const toml::value &toml_)
mknod(toml_),
open(toml_),
readdir(toml_),
readdirplus(toml_),
readlink(toml_),
removexattr(toml_),
rename(toml_),
rmdir(toml_),
setxattr(toml_),
statfs(toml_),
symlink(toml_),
truncate(toml_),
write(toml_),
unlink(toml_)
unlink(toml_),
utimens(toml_),
write(toml_)
{
mountpoint = toml::find<std::string>(toml_,"filesystem","mountpoint");

View File

@ -31,14 +31,17 @@
#include "fuse_mknod_policy.hpp"
#include "fuse_open_policy.hpp"
#include "fuse_readdir_policy.hpp"
#include "fuse_readdirplus_policy.hpp"
#include "fuse_readlink_policy.hpp"
#include "fuse_removexattr_policy.hpp"
#include "fuse_rename_policy.hpp"
#include "fuse_rmdir_policy.hpp"
#include "fuse_setxattr_policy.hpp"
#include "fuse_statfs_policy.hpp"
#include "fuse_symlink_policy.hpp"
#include "fuse_truncate_policy.hpp"
#include "fuse_unlink_policy.hpp"
#include "fuse_utimens_policy.hpp"
#include "fuse_write_policy.hpp"
#include "branches.hpp"
@ -46,7 +49,7 @@
#include "link_exdev_enum.hpp"
#include "rename_exdev_enum.hpp"
#include "ghc/filesystem.hpp"
#include "fs_path.hpp"
#include <atomic>
#include <memory>
@ -64,6 +67,14 @@ public:
public:
StateBase(const toml::value &);
public:
uint64_t fuse_msg_size;
public:
bool async_read;
bool cache_symlinks;
bool posix_acl;
public:
int entry_cache_timeout;
int neg_entry_cache_timeout;
@ -80,7 +91,7 @@ public:
bool security_capability;
public:
ghc::filesystem::path mountpoint;
gfs::path mountpoint;
Branches2 branches;
public:
@ -107,19 +118,21 @@ public:
FUSE::MKNOD::Policy mknod;
FUSE::OPEN::Policy open;
FUSE::READDIR::Policy readdir;
FUSE::READDIRPLUS::Policy readdirplus;
FUSE::READLINK::Policy readlink;
FUSE::REMOVEXATTR::Policy removexattr;
FUSE::RENAME::Policy rename;
FUSE::RMDIR::Policy rmdir;
FUSE::SETXATTR::Policy setxattr;
FUSE::STATFS::Policy statfs;
FUSE::SYMLINK::Policy symlink;
FUSE::TRUNCATE::Policy truncate;
FUSE::UNLINK::Policy unlink;
FUSE::UTIMENS::Policy utimens;
FUSE::WRITE::Policy write;
public:
const toml::value _toml;
const toml::value config_toml;
};
class State