From 9d9ee7b71d9ec898b47446a6c5b43fa2e6552dce Mon Sep 17 00:00:00 2001 From: Antonio SJ Musumeci Date: Fri, 25 Jan 2019 07:03:46 -0500 Subject: [PATCH] general code cleanup --- src/buildvector.hpp | 1 + src/chmod.cpp | 105 ----- src/chown.cpp | 111 ----- src/config.cpp | 177 ++++--- src/config.hpp | 209 +++++---- src/fallocate.hpp | 30 -- src/flock.hpp | 28 -- src/fs.cpp | 8 +- src/fs.hpp | 30 +- src/fs_acl.hpp | 2 +- src/fs_attr.hpp | 10 +- src/fs_base_access.hpp | 24 +- src/fs_base_chmod.hpp | 42 +- src/fs_base_chown.hpp | 70 +-- src/fs_base_close.hpp | 4 +- src/fs_base_closedir.hpp | 4 +- src/fs_base_dirfd.hpp | 4 +- src/fs_base_dup.hpp | 4 +- src/fs_base_fadvise.hpp | 18 +- src/fs_base_fallocate.hpp | 8 +- src/fs_base_flock.hpp | 6 +- src/fs_base_fsync.hpp | 8 +- src/fs_base_ftruncate.hpp | 6 +- src/fs_base_futimesat.hpp | 8 +- src/fs_base_getxattr.hpp | 4 +- src/fs_base_link.hpp | 7 +- src/fs_base_listxattr.hpp | 4 +- src/fs_base_lseek.hpp | 8 +- src/fs_base_mkdir.hpp | 6 +- src/fs_base_mknod.hpp | 8 +- src/fs_base_mkstemp.hpp | 14 +- src/fs_base_open.hpp | 4 +- src/fs_base_opendir.hpp | 4 +- src/fs_base_read.hpp | 18 +- src/fs_base_readdir.hpp | 4 +- src/fs_base_readlink.hpp | 8 +- src/fs_base_realpath.hpp | 10 +- src/fs_base_remove.hpp | 12 +- src/fs_base_removexattr.hpp | 10 +- src/fs_base_rmdir.hpp | 12 +- src/fs_base_setxattr.hpp | 4 +- src/fs_base_stat.hpp | 57 ++- src/fs_base_statvfs.hpp | 4 +- src/fs_base_symlink.hpp | 24 +- src/fs_base_truncate.hpp | 15 +- src/fs_base_utime.hpp | 26 +- src/fs_base_utime_generic.hpp | 132 +++--- src/fs_clonefile.cpp | 2 +- src/fs_clonepath.cpp | 22 +- src/fs_copyfile.cpp | 2 +- src/fs_cow.cpp | 2 +- src/fs_devid.hpp | 4 +- src/fs_exists.hpp | 8 +- src/fs_glob.hpp | 7 +- src/fs_inode.hpp | 15 +- src/fs_movefile.cpp | 2 +- src/fs_path.hpp | 41 +- src/fs_statvfs_cache.cpp | 4 +- src/{access.cpp => fuse_access.cpp} | 56 +-- src/{rmdir.hpp => fuse_access.hpp} | 10 +- src/fuse_chmod.cpp | 105 +++++ src/{unlink.hpp => fuse_chmod.hpp} | 10 +- src/fuse_chown.cpp | 110 +++++ src/{link.hpp => fuse_chown.hpp} | 12 +- src/{create.cpp => fuse_create.cpp} | 62 ++- src/{truncate.hpp => fuse_create.hpp} | 14 +- src/{destroy.cpp => fuse_destroy.cpp} | 9 +- src/{destroy.hpp => fuse_destroy.hpp} | 9 +- src/{fallocate.cpp => fuse_fallocate.cpp} | 54 +-- src/fuse_fallocate.hpp | 27 ++ src/{fgetattr.cpp => fuse_fgetattr.cpp} | 47 +- src/{ftruncate.hpp => fuse_fgetattr.hpp} | 14 +- src/{flock.cpp => fuse_flock.cpp} | 40 +- src/{open.hpp => fuse_flock.hpp} | 12 +- src/{flush.cpp => fuse_flush.cpp} | 44 +- src/fuse_flush.hpp | 26 ++ src/{fsync.cpp => fuse_fsync.cpp} | 48 +- src/{releasedir.hpp => fuse_fsync.hpp} | 12 +- src/{fsyncdir.cpp => fuse_fsyncdir.cpp} | 46 +- src/{fsyncdir.hpp => fuse_fsyncdir.hpp} | 13 +- src/{ftruncate.cpp => fuse_ftruncate.cpp} | 40 +- src/{create.hpp => fuse_ftruncate.hpp} | 14 +- src/fuse_getattr.cpp | 117 +++++ src/{getattr.hpp => fuse_getattr.hpp} | 11 +- src/fuse_getxattr.cpp | 467 +++++++++++++++++++ src/{chown.hpp => fuse_getxattr.hpp} | 14 +- src/{init.cpp => fuse_init.cpp} | 27 +- src/{init.hpp => fuse_init.hpp} | 11 +- src/{ioctl.cpp => fuse_ioctl.cpp} | 49 +- src/{fsync.hpp => fuse_ioctl.hpp} | 16 +- src/fuse_link.cpp | 249 ++++++++++ src/fuse_link.hpp | 24 + src/fuse_listxattr.cpp | 146 ++++++ src/fuse_listxattr.hpp | 25 + src/fuse_mkdir.cpp | 149 ++++++ src/fuse_mkdir.hpp | 24 + src/fuse_mknod.cpp | 151 ++++++ src/fuse_mknod.hpp | 26 ++ src/{open.cpp => fuse_open.cpp} | 45 +- src/fuse_open.hpp | 26 ++ src/{opendir.hpp => fuse_opendir.cpp} | 16 +- src/{rename.hpp => fuse_opendir.hpp} | 13 +- src/{read.cpp => fuse_read.cpp} | 47 +- src/{read_buf.hpp => fuse_read.hpp} | 26 +- src/{read_buf.cpp => fuse_read_buf.cpp} | 68 +-- src/fuse_read_buf.hpp | 31 ++ src/fuse_readdir.cpp | 118 +++++ src/{fgetattr.hpp => fuse_readdir.hpp} | 19 +- src/fuse_readlink.cpp | 138 ++++++ src/{access.hpp => fuse_readlink.hpp} | 12 +- src/{release.cpp => fuse_release.cpp} | 23 +- src/fuse_release.hpp | 26 ++ src/{releasedir.cpp => fuse_releasedir.cpp} | 19 +- src/{flush.hpp => fuse_releasedir.hpp} | 13 +- src/fuse_removexattr.cpp | 112 +++++ src/fuse_removexattr.hpp | 24 + src/{rename.cpp => fuse_rename.cpp} | 66 ++- src/fuse_rename.hpp | 24 + src/fuse_rmdir.cpp | 102 +++++ src/fuse_rmdir.hpp | 23 + src/fuse_setxattr.cpp | 480 +++++++++++++++++++ src/fuse_setxattr.hpp | 27 ++ src/fuse_statfs.cpp | 167 +++++++ src/fuse_statfs.hpp | 26 ++ src/fuse_symlink.cpp | 129 ++++++ src/fuse_symlink.hpp | 24 + src/fuse_truncate.cpp | 108 +++++ src/fuse_truncate.hpp | 26 ++ src/{unlink.cpp => fuse_unlink.cpp} | 39 +- src/fuse_unlink.hpp | 23 + src/fuse_utimens.cpp | 106 +++++ src/{chmod.hpp => fuse_utimens.hpp} | 13 +- src/{write.cpp => fuse_write.cpp} | 61 ++- src/fuse_write.hpp | 36 ++ src/fuse_write_buf.cpp | 112 +++++ src/{readdir.hpp => fuse_write_buf.hpp} | 27 +- src/fusefunc.cpp | 128 +++--- src/fusefunc.hpp | 205 ++++----- src/getattr.cpp | 117 ----- src/getxattr.cpp | 464 ------------------- src/getxattr.hpp | 29 -- src/ioctl.hpp | 33 -- src/link.cpp | 250 ---------- src/listxattr.cpp | 147 ------ src/listxattr.hpp | 28 -- src/mergerfs.cpp | 204 ++++----- src/mkdir.cpp | 144 ------ src/mkdir.hpp | 27 -- src/mknod.cpp | 152 ------ src/mknod.hpp | 29 -- src/opendir.cpp | 34 -- src/option_parser.cpp | 49 +- src/option_parser.hpp | 15 +- src/policy_cache.cpp | 6 +- src/policy_newest.cpp | 6 +- src/read.hpp | 44 -- src/readdir.cpp | 119 ----- src/readlink.cpp | 138 ------ src/readlink.hpp | 28 -- src/release.hpp | 27 -- src/removexattr.cpp | 112 ----- src/removexattr.hpp | 27 -- src/resources.cpp | 91 ++-- src/resources.hpp | 15 +- src/rmdir.cpp | 102 ----- src/rwlock.hpp | 67 ++- src/setxattr.cpp | 482 -------------------- src/setxattr.hpp | 30 -- src/statfs.cpp | 168 ------- src/statfs.hpp | 27 -- src/symlink.cpp | 130 ------ src/symlink.hpp | 27 -- src/truncate.cpp | 108 ----- src/utimens.cpp | 107 ----- src/utimens.hpp | 27 -- src/write.hpp | 44 -- src/write_buf.cpp | 113 ----- src/write_buf.hpp | 39 -- 178 files changed, 5070 insertions(+), 5225 deletions(-) delete mode 100644 src/chmod.cpp delete mode 100644 src/chown.cpp delete mode 100644 src/fallocate.hpp delete mode 100644 src/flock.hpp rename src/{access.cpp => fuse_access.cpp} (56%) rename src/{rmdir.hpp => fuse_access.hpp} (90%) create mode 100644 src/fuse_chmod.cpp rename src/{unlink.hpp => fuse_chmod.hpp} (90%) create mode 100644 src/fuse_chown.cpp rename src/{link.hpp => fuse_chown.hpp} (88%) rename src/{create.cpp => fuse_create.cpp} (69%) rename src/{truncate.hpp => fuse_create.hpp} (85%) rename src/{destroy.cpp => fuse_destroy.cpp} (91%) rename src/{destroy.hpp => fuse_destroy.hpp} (91%) rename src/{fallocate.cpp => fuse_fallocate.cpp} (58%) create mode 100644 src/fuse_fallocate.hpp rename src/{fgetattr.cpp => fuse_fgetattr.cpp} (68%) rename src/{ftruncate.hpp => fuse_fgetattr.hpp} (84%) rename src/{flock.cpp => fuse_flock.cpp} (70%) rename src/{open.hpp => fuse_flock.hpp} (87%) rename src/{flush.cpp => fuse_flush.cpp} (71%) create mode 100644 src/fuse_flush.hpp rename src/{fsync.cpp => fuse_fsync.cpp} (67%) rename src/{releasedir.hpp => fuse_fsync.hpp} (86%) rename src/{fsyncdir.cpp => fuse_fsyncdir.cpp} (68%) rename src/{fsyncdir.hpp => fuse_fsyncdir.hpp} (83%) rename src/{ftruncate.cpp => fuse_ftruncate.cpp} (68%) rename src/{create.hpp => fuse_ftruncate.hpp} (84%) create mode 100644 src/fuse_getattr.cpp rename src/{getattr.hpp => fuse_getattr.hpp} (88%) create mode 100644 src/fuse_getxattr.cpp rename src/{chown.hpp => fuse_getxattr.hpp} (84%) rename src/{init.cpp => fuse_init.cpp} (70%) rename src/{init.hpp => fuse_init.hpp} (90%) rename src/{ioctl.cpp => fuse_ioctl.cpp} (76%) rename src/{fsync.hpp => fuse_ioctl.hpp} (79%) create mode 100644 src/fuse_link.cpp create mode 100644 src/fuse_link.hpp create mode 100644 src/fuse_listxattr.cpp create mode 100644 src/fuse_listxattr.hpp create mode 100644 src/fuse_mkdir.cpp create mode 100644 src/fuse_mkdir.hpp create mode 100644 src/fuse_mknod.cpp create mode 100644 src/fuse_mknod.hpp rename src/{open.cpp => fuse_open.cpp} (70%) create mode 100644 src/fuse_open.hpp rename src/{opendir.hpp => fuse_opendir.cpp} (80%) rename src/{rename.hpp => fuse_opendir.hpp} (88%) rename src/{read.cpp => fuse_read.cpp} (68%) rename src/{read_buf.hpp => fuse_read.hpp} (69%) rename src/{read_buf.cpp => fuse_read_buf.cpp} (52%) create mode 100644 src/fuse_read_buf.hpp create mode 100644 src/fuse_readdir.cpp rename src/{fgetattr.hpp => fuse_readdir.hpp} (80%) create mode 100644 src/fuse_readlink.cpp rename src/{access.hpp => fuse_readlink.hpp} (87%) rename src/{release.cpp => fuse_release.cpp} (77%) create mode 100644 src/fuse_release.hpp rename src/{releasedir.cpp => fuse_releasedir.cpp} (79%) rename src/{flush.hpp => fuse_releasedir.hpp} (87%) create mode 100644 src/fuse_removexattr.cpp create mode 100644 src/fuse_removexattr.hpp rename src/{rename.cpp => fuse_rename.cpp} (83%) create mode 100644 src/fuse_rename.hpp create mode 100644 src/fuse_rmdir.cpp create mode 100644 src/fuse_rmdir.hpp create mode 100644 src/fuse_setxattr.cpp create mode 100644 src/fuse_setxattr.hpp create mode 100644 src/fuse_statfs.cpp create mode 100644 src/fuse_statfs.hpp create mode 100644 src/fuse_symlink.cpp create mode 100644 src/fuse_symlink.hpp create mode 100644 src/fuse_truncate.cpp create mode 100644 src/fuse_truncate.hpp rename src/{unlink.cpp => fuse_unlink.cpp} (72%) create mode 100644 src/fuse_unlink.hpp create mode 100644 src/fuse_utimens.cpp rename src/{chmod.hpp => fuse_utimens.hpp} (87%) rename src/{write.cpp => fuse_write.cpp} (79%) create mode 100644 src/fuse_write.hpp create mode 100644 src/fuse_write_buf.cpp rename src/{readdir.hpp => fuse_write_buf.hpp} (69%) delete mode 100644 src/getattr.cpp delete mode 100644 src/getxattr.cpp delete mode 100644 src/getxattr.hpp delete mode 100644 src/ioctl.hpp delete mode 100644 src/link.cpp delete mode 100644 src/listxattr.cpp delete mode 100644 src/listxattr.hpp delete mode 100644 src/mkdir.cpp delete mode 100644 src/mkdir.hpp delete mode 100644 src/mknod.cpp delete mode 100644 src/mknod.hpp delete mode 100644 src/opendir.cpp delete mode 100644 src/read.hpp delete mode 100644 src/readdir.cpp delete mode 100644 src/readlink.cpp delete mode 100644 src/readlink.hpp delete mode 100644 src/release.hpp delete mode 100644 src/removexattr.cpp delete mode 100644 src/removexattr.hpp delete mode 100644 src/rmdir.cpp delete mode 100644 src/setxattr.cpp delete mode 100644 src/setxattr.hpp delete mode 100644 src/statfs.cpp delete mode 100644 src/statfs.hpp delete mode 100644 src/symlink.cpp delete mode 100644 src/symlink.hpp delete mode 100644 src/truncate.cpp delete mode 100644 src/utimens.cpp delete mode 100644 src/utimens.hpp delete mode 100644 src/write.hpp delete mode 100644 src/write_buf.cpp delete mode 100644 src/write_buf.hpp diff --git a/src/buildvector.hpp b/src/buildvector.hpp index bb2ff50d..b6a6d4a2 100644 --- a/src/buildvector.hpp +++ b/src/buildvector.hpp @@ -17,6 +17,7 @@ #pragma once #include +#include template class buildvector diff --git a/src/chmod.cpp b/src/chmod.cpp deleted file mode 100644 index 7aa5da7b..00000000 --- a/src/chmod.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/* - Copyright (c) 2016, Antonio SJ Musumeci - - 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 - -#include -#include - -#include "config.hpp" -#include "errno.hpp" -#include "fs_base_chmod.hpp" -#include "fs_path.hpp" -#include "rv.hpp" -#include "rwlock.hpp" -#include "ugid.hpp" - -using std::string; -using std::vector; - -static -int -_chmod_loop_core(const string *basepath, - const char *fusepath, - const mode_t mode, - const int error) -{ - int rv; - string fullpath; - - fs::path::make(basepath,fusepath,fullpath); - - rv = fs::chmod(fullpath,mode); - - return error::calc(rv,error,errno); -} - -static -int -_chmod_loop(const vector &basepaths, - const char *fusepath, - const mode_t mode) -{ - int error; - - error = -1; - for(size_t i = 0, ei = basepaths.size(); i != ei; i++) - { - error = _chmod_loop_core(basepaths[i],fusepath,mode,error); - } - - return -error; -} - -static -int -_chmod(Policy::Func::Action actionFunc, - const Branches &branches_, - const uint64_t minfreespace, - const char *fusepath, - const mode_t mode) -{ - int rv; - vector basepaths; - - rv = actionFunc(branches_,fusepath,minfreespace,basepaths); - if(rv == -1) - return -errno; - - return _chmod_loop(basepaths,fusepath,mode); -} - -namespace mergerfs -{ - namespace fuse - { - int - chmod(const char *fusepath, - mode_t mode) - { - const fuse_context *fc = fuse_get_context(); - const Config &config = Config::get(fc); - const ugid::Set ugid(fc->uid,fc->gid); - const rwlock::ReadGuard readlock(&config.branches_lock); - - return _chmod(config.chmod, - config.branches, - config.minfreespace, - fusepath, - mode); - } - } -} diff --git a/src/chown.cpp b/src/chown.cpp deleted file mode 100644 index a3708f9d..00000000 --- a/src/chown.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* - Copyright (c) 2016, Antonio SJ Musumeci - - 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 - -#include -#include - -#include "config.hpp" -#include "errno.hpp" -#include "fs_base_chown.hpp" -#include "fs_path.hpp" -#include "rv.hpp" -#include "rwlock.hpp" -#include "ugid.hpp" - -using std::string; -using std::vector; -using mergerfs::Config; - -static -int -_chown_loop_core(const string *basepath, - const char *fusepath, - const uid_t uid, - const gid_t gid, - const int error) -{ - int rv; - string fullpath; - - fs::path::make(basepath,fusepath,fullpath); - - rv = fs::lchown(fullpath,uid,gid); - - return error::calc(rv,error,errno); -} - -static -int -_chown_loop(const vector &basepaths, - const char *fusepath, - const uid_t uid, - const gid_t gid) -{ - int error; - - error = -1; - for(size_t i = 0, ei = basepaths.size(); i != ei; i++) - { - error = _chown_loop_core(basepaths[i],fusepath,uid,gid,error); - } - - return -error; -} - -static -int -_chown(Policy::Func::Action actionFunc, - const Branches &branches_, - const uint64_t minfreespace, - const char *fusepath, - const uid_t uid, - const gid_t gid) -{ - int rv; - vector basepaths; - - rv = actionFunc(branches_,fusepath,minfreespace,basepaths); - if(rv == -1) - return -errno; - - return _chown_loop(basepaths,fusepath,uid,gid); -} - -namespace mergerfs -{ - namespace fuse - { - int - chown(const char *fusepath, - uid_t uid, - gid_t gid) - { - const fuse_context *fc = fuse_get_context(); - const Config &config = Config::get(fc); - const ugid::Set ugid(fc->uid,fc->gid); - const rwlock::ReadGuard readlock(&config.branches_lock); - - return _chown(config.chown, - config.branches, - config.minfreespace, - fusepath, - uid, - gid); - } - } -} diff --git a/src/config.cpp b/src/config.cpp index ef5b4bbd..898c8a95 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -31,95 +31,92 @@ using std::string; using std::vector; -namespace mergerfs +Config::Config() + : destmount(), + branches(), + branches_lock(), + minfreespace(MINFREESPACE_DEFAULT), + moveonenospc(false), + direct_io(false), + dropcacheonclose(false), + symlinkify(false), + symlinkify_timeout(3600), + nullrw(false), + ignorepponrename(false), + security_capability(true), + link_cow(false), + xattr(0), + statfs(StatFS::BASE), + statfs_ignore(StatFSIgnore::NONE), + POLICYINIT(access), + POLICYINIT(chmod), + POLICYINIT(chown), + POLICYINIT(create), + POLICYINIT(getattr), + POLICYINIT(getxattr), + POLICYINIT(link), + POLICYINIT(listxattr), + POLICYINIT(mkdir), + POLICYINIT(mknod), + POLICYINIT(open), + POLICYINIT(readlink), + POLICYINIT(removexattr), + POLICYINIT(rename), + POLICYINIT(rmdir), + POLICYINIT(setxattr), + POLICYINIT(symlink), + POLICYINIT(truncate), + POLICYINIT(unlink), + POLICYINIT(utimens), + controlfile("/.mergerfs") { - Config::Config() - : destmount(), - branches(), - branches_lock(), - minfreespace(MINFREESPACE_DEFAULT), - moveonenospc(false), - direct_io(false), - dropcacheonclose(false), - symlinkify(false), - symlinkify_timeout(3600), - nullrw(false), - ignorepponrename(false), - security_capability(true), - link_cow(false), - xattr(0), - statfs(StatFS::BASE), - statfs_ignore(StatFSIgnore::NONE), - POLICYINIT(access), - POLICYINIT(chmod), - POLICYINIT(chown), - POLICYINIT(create), - POLICYINIT(getattr), - POLICYINIT(getxattr), - POLICYINIT(link), - POLICYINIT(listxattr), - POLICYINIT(mkdir), - POLICYINIT(mknod), - POLICYINIT(open), - POLICYINIT(readlink), - POLICYINIT(removexattr), - POLICYINIT(rename), - POLICYINIT(rmdir), - POLICYINIT(setxattr), - POLICYINIT(symlink), - POLICYINIT(truncate), - POLICYINIT(unlink), - POLICYINIT(utimens), - controlfile("/.mergerfs") - { - pthread_rwlock_init(&branches_lock,NULL); - - set_category_policy("action","epall"); - set_category_policy("create","epmfs"); - set_category_policy("search","ff"); - } - - int - Config::set_func_policy(const string &fusefunc_, - const string &policy_) - { - const Policy *policy; - const FuseFunc *fusefunc; - - fusefunc = FuseFunc::find(fusefunc_); - if(fusefunc == FuseFunc::invalid) - return (errno=ENODATA,-1); - - policy = Policy::find(policy_); - if(policy == Policy::invalid) - return (errno=EINVAL,-1); - - policies[(FuseFunc::Enum::Type)*fusefunc] = policy; - - return 0; - } - - int - Config::set_category_policy(const string &category_, - const string &policy_) - { - const Policy *policy; - const Category *category; - - category = Category::find(category_); - if(category == Category::invalid) - return (errno=ENODATA,-1); - - policy = Policy::find(policy_); - if(policy == Policy::invalid) - return (errno=EINVAL,-1); - - for(int i = 0; i < FuseFunc::Enum::END; i++) - { - if(FuseFunc::fusefuncs[i] == (Category::Enum::Type)*category) - policies[(FuseFunc::Enum::Type)FuseFunc::fusefuncs[i]] = policy; - } - - return 0; - } + pthread_rwlock_init(&branches_lock,NULL); + + set_category_policy("action","epall"); + set_category_policy("create","epmfs"); + set_category_policy("search","ff"); +} + +int +Config::set_func_policy(const string &fusefunc_, + const string &policy_) +{ + const Policy *policy; + const FuseFunc *fusefunc; + + fusefunc = FuseFunc::find(fusefunc_); + if(fusefunc == FuseFunc::invalid) + return (errno=ENODATA,-1); + + policy = Policy::find(policy_); + if(policy == Policy::invalid) + return (errno=EINVAL,-1); + + policies[(FuseFunc::Enum::Type)*fusefunc] = policy; + + return 0; +} + +int +Config::set_category_policy(const string &category_, + const string &policy_) +{ + const Policy *policy; + const Category *category; + + category = Category::find(category_); + if(category == Category::invalid) + return (errno=ENODATA,-1); + + policy = Policy::find(policy_); + if(policy == Policy::invalid) + return (errno=EINVAL,-1); + + for(int i = 0; i < FuseFunc::Enum::END; i++) + { + if(FuseFunc::fusefuncs[i] == (Category::Enum::Type)*category) + policies[(FuseFunc::Enum::Type)FuseFunc::fusefuncs[i]] = policy; + } + + return 0; } diff --git a/src/config.hpp b/src/config.hpp index aa81c313..ee6cd647 100644 --- a/src/config.hpp +++ b/src/config.hpp @@ -23,115 +23,112 @@ #include -#include -#include - #include #include -namespace mergerfs +#include +#include + +class Config { - class Config +public: + struct StatFS + { + enum Enum + { + BASE, + FULL + }; + }; + + struct StatFSIgnore { - public: - struct StatFS - { - enum Enum - { - BASE, - FULL - }; - }; - - struct StatFSIgnore - { - enum Enum - { - NONE, - RO, - NC - }; - }; - - public: - Config(); - - public: - int set_func_policy(const std::string &fusefunc_, - const std::string &policy_); - int set_category_policy(const std::string &category_, - const std::string &policy_); - - public: - std::string destmount; - Branches branches; - mutable pthread_rwlock_t branches_lock; - uint64_t minfreespace; - bool moveonenospc; - bool direct_io; - bool dropcacheonclose; - bool symlinkify; - time_t symlinkify_timeout; - bool nullrw; - bool ignorepponrename; - bool security_capability; - bool link_cow; - int xattr; - StatFS::Enum statfs; - StatFSIgnore::Enum statfs_ignore; - - public: - const Policy *policies[FuseFunc::Enum::END]; - const Policy *&access; - const Policy *&chmod; - const Policy *&chown; - const Policy *&create; - const Policy *&getattr; - const Policy *&getxattr; - const Policy *&link; - const Policy *&listxattr; - const Policy *&mkdir; - const Policy *&mknod; - const Policy *&open; - const Policy *&readlink; - const Policy *&removexattr; - const Policy *&rename; - const Policy *&rmdir; - const Policy *&setxattr; - const Policy *&symlink; - const Policy *&truncate; - const Policy *&unlink; - const Policy *&utimens; - - public: - mutable PolicyCache open_cache; - - public: - const std::string controlfile; - - public: - static - const - Config & - get(void) - { - const fuse_context *fc = fuse_get_context(); - - return get(fc); - } - - static - const Config & - get(const fuse_context *fc) - { - return *((Config*)fc->private_data); - } - - static - Config & - get_writable(void) - { - return (*((Config*)fuse_get_context()->private_data)); - } + enum Enum + { + NONE, + RO, + NC + }; }; -} + +public: + Config(); + +public: + int set_func_policy(const std::string &fusefunc_, + const std::string &policy_); + int set_category_policy(const std::string &category_, + const std::string &policy_); + +public: + std::string destmount; + Branches branches; + mutable pthread_rwlock_t branches_lock; + uint64_t minfreespace; + bool moveonenospc; + bool direct_io; + bool dropcacheonclose; + bool symlinkify; + time_t symlinkify_timeout; + bool nullrw; + bool ignorepponrename; + bool security_capability; + bool link_cow; + int xattr; + StatFS::Enum statfs; + StatFSIgnore::Enum statfs_ignore; + +public: + const Policy *policies[FuseFunc::Enum::END]; + const Policy *&access; + const Policy *&chmod; + const Policy *&chown; + const Policy *&create; + const Policy *&getattr; + const Policy *&getxattr; + const Policy *&link; + const Policy *&listxattr; + const Policy *&mkdir; + const Policy *&mknod; + const Policy *&open; + const Policy *&readlink; + const Policy *&removexattr; + const Policy *&rename; + const Policy *&rmdir; + const Policy *&setxattr; + const Policy *&symlink; + const Policy *&truncate; + const Policy *&unlink; + const Policy *&utimens; + +public: + mutable PolicyCache open_cache; + +public: + const std::string controlfile; + +public: + static + const + Config & + get(void) + { + const fuse_context *fc = fuse_get_context(); + + return get(fc); + } + + static + const Config & + get(const fuse_context *fc) + { + return *((Config*)fc->private_data); + } + + static + Config & + get_writable(void) + { + return (*((Config*)fuse_get_context()->private_data)); + } +}; diff --git a/src/fallocate.hpp b/src/fallocate.hpp deleted file mode 100644 index 4720c810..00000000 --- a/src/fallocate.hpp +++ /dev/null @@ -1,30 +0,0 @@ -/* - Copyright (c) 2016, Antonio SJ Musumeci - - 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 - -namespace mergerfs -{ - namespace fuse - { - int - fallocate(const char *fusepath, - int mode, - off_t offset, - off_t len, - fuse_file_info *fi); - } -} diff --git a/src/flock.hpp b/src/flock.hpp deleted file mode 100644 index 868fb20b..00000000 --- a/src/flock.hpp +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (c) 2016, Antonio SJ Musumeci - - 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 - -namespace mergerfs -{ - namespace fuse - { - int - flock(const char *fusepath, - fuse_file_info *ffi, - int op); - } -} diff --git a/src/fs.cpp b/src/fs.cpp index a587f0cb..f6c6daf3 100644 --- a/src/fs.cpp +++ b/src/fs.cpp @@ -46,7 +46,7 @@ namespace fs for(size_t i = 0, ei = basepaths.size(); i != ei; i++) { - fs::path::make(&basepaths[i],fusepath,fullpath); + fullpath = fs::path::make(basepaths[i],fusepath); if(!fs::exists(fullpath)) continue; @@ -66,16 +66,16 @@ namespace fs string fullpath; struct stat st; - rv = fs::fstat(fd,st); + rv = fs::fstat(fd,&st); if(rv == -1) return -1; dev = st.st_dev; for(size_t i = 0, ei = basepaths.size(); i != ei; i++) { - fs::path::make(&basepaths[i],fusepath,fullpath); + fullpath = fs::path::make(basepaths[i],fusepath); - rv = fs::lstat(fullpath,st); + rv = fs::lstat(fullpath,&st); if(rv == -1) continue; diff --git a/src/fs.hpp b/src/fs.hpp index 7d439b85..f1cfd140 100644 --- a/src/fs.hpp +++ b/src/fs.hpp @@ -27,22 +27,22 @@ namespace fs using std::string; using std::vector; - void findallfiles(const vector &basepaths, - const char *fusepath, - vector &paths); + void findallfiles(const vector &basepaths_, + const char *fusepath_, + vector &paths_); - int findonfs(const vector &basepaths, - const string &fusepath, - const int fd, - string &basepath); + int findonfs(const vector &basepaths_, + const string &fusepath_, + const int fd_, + string &basepath_); - void realpathize(vector &strs); + void realpathize(vector &strs_); - int getfl(const int fd); - int setfl(const int fd, - const mode_t mode); + int getfl(const int fd_); + int setfl(const int fd_, + const mode_t mode_); - int mfs(const vector &srcs, - const uint64_t minfreespace, - string &path); -}; + int mfs(const vector &srcs_, + const uint64_t minfreespace_, + string &path_); +} diff --git a/src/fs_acl.hpp b/src/fs_acl.hpp index f3b16e43..95546075 100644 --- a/src/fs_acl.hpp +++ b/src/fs_acl.hpp @@ -25,6 +25,6 @@ namespace fs namespace acl { bool - dir_has_defaults(const std::string &fullpath); + dir_has_defaults(const std::string &fullpath_); } } diff --git a/src/fs_attr.hpp b/src/fs_attr.hpp index 06210413..e92491bf 100644 --- a/src/fs_attr.hpp +++ b/src/fs_attr.hpp @@ -22,11 +22,9 @@ namespace fs { namespace attr { - using std::string; - - int copy(const int fdin, - const int fdout); - int copy(const string &from, - const string &to); + int copy(const int fdin_, + const int fdout_); + int copy(const std::string &from_, + const std::string &to_); } } diff --git a/src/fs_base_access.hpp b/src/fs_base_access.hpp index c11b25a8..8e9e5765 100644 --- a/src/fs_base_access.hpp +++ b/src/fs_base_access.hpp @@ -28,30 +28,30 @@ namespace fs static inline int - access(const int dirfd, - const std::string &path, - const int mode, - const int flags) + access(const int dirfd_, + const std::string &path_, + const int mode_, + const int flags_) { - return ::faccessat(dirfd,path.c_str(),mode,flags); + return ::faccessat(dirfd_,path_.c_str(),mode_,flags_); } static inline int - access(const std::string &path, - const int mode, - const int flags) + access(const std::string &path_, + const int mode_, + const int flags_) { - return fs::access(AT_FDCWD,path,mode,flags); + return fs::access(AT_FDCWD,path_,mode_,flags_); } static inline int - eaccess(const std::string &path, - const int mode) + eaccess(const std::string &path_, + const int mode_) { - return fs::access(path,mode,AT_EACCESS); + return fs::access(path_,mode_,AT_EACCESS); } } diff --git a/src/fs_base_chmod.hpp b/src/fs_base_chmod.hpp index bab2cb4a..48654e69 100644 --- a/src/fs_base_chmod.hpp +++ b/src/fs_base_chmod.hpp @@ -18,10 +18,10 @@ #pragma once -#include - #include "fs_base_stat.hpp" +#include + #define MODE_BITS (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO) namespace fs @@ -29,50 +29,50 @@ namespace fs static inline int - chmod(const std::string &path, - const mode_t mode) + chmod(const std::string &path_, + const mode_t mode_) { - return ::chmod(path.c_str(),mode); + return ::chmod(path_.c_str(),mode_); } static inline int - fchmod(const int fd, - const mode_t mode) + fchmod(const int fd_, + const mode_t mode_) { - return ::fchmod(fd,mode); + return ::fchmod(fd_,mode_); } static inline int - fchmod(const int fd, - const struct stat &st) + fchmod(const int fd_, + const struct stat &st_) { - return ::fchmod(fd,st.st_mode); + return ::fchmod(fd_,st_.st_mode); } static inline int - chmod_check_on_error(const std::string &path, - const mode_t mode) + chmod_check_on_error(const std::string &path_, + const mode_t mode_) { int rv; - rv = fs::chmod(path,mode); + rv = fs::chmod(path_,mode_); if(rv == -1) { int error; struct stat st; error = errno; - rv = fs::stat(path,st); + rv = fs::stat(path_,&st); if(rv == -1) return -1; - if((st.st_mode & MODE_BITS) != (mode & MODE_BITS)) + if((st.st_mode & MODE_BITS) != (mode_ & MODE_BITS)) return (errno=error,-1); } @@ -82,23 +82,23 @@ namespace fs static inline int - fchmod_check_on_error(const int fd, - const struct stat &st) + fchmod_check_on_error(const int fd_, + const struct stat &st_) { int rv; - rv = fs::fchmod(fd,st); + rv = fs::fchmod(fd_,st_); if(rv == -1) { int error; struct stat tmpst; error = errno; - rv = fs::fstat(fd,tmpst); + rv = fs::fstat(fd_,&tmpst); if(rv == -1) return -1; - if((st.st_mode & MODE_BITS) != (tmpst.st_mode & MODE_BITS)) + if((st_.st_mode & MODE_BITS) != (tmpst.st_mode & MODE_BITS)) return (errno=error,-1); } diff --git a/src/fs_base_chown.hpp b/src/fs_base_chown.hpp index 57ae30f8..95ba4fd9 100644 --- a/src/fs_base_chown.hpp +++ b/src/fs_base_chown.hpp @@ -18,94 +18,94 @@ #pragma once +#include "fs_base_stat.hpp" + #include #include #include #include -#include "fs_base_stat.hpp" - namespace fs { static inline int - chown(const std::string &path, - const uid_t uid, - const gid_t gid) + chown(const std::string &path_, + const uid_t uid_, + const gid_t gid_) { - return ::chown(path.c_str(),uid,gid); + return ::chown(path_.c_str(),uid_,gid_); } static inline int - chown(const std::string &path, - const struct stat &st) + chown(const std::string &path_, + const struct stat &st_) { - return fs::chown(path,st.st_uid,st.st_gid); + return fs::chown(path_,st_.st_uid,st_.st_gid); } static inline int - lchown(const std::string &path, - const uid_t uid, - const gid_t gid) + lchown(const std::string &path_, + const uid_t uid_, + const gid_t gid_) { - return ::lchown(path.c_str(),uid,gid); + return ::lchown(path_.c_str(),uid_,gid_); } static inline int - lchown(const std::string &path, - const struct stat &st) + lchown(const std::string &path_, + const struct stat &st_) { - return fs::lchown(path,st.st_uid,st.st_gid); + return fs::lchown(path_,st_.st_uid,st_.st_gid); } static inline int - fchown(const int fd, - const uid_t uid, - const gid_t gid) + fchown(const int fd_, + const uid_t uid_, + const gid_t gid_) { - return ::fchown(fd,uid,gid); + return ::fchown(fd_,uid_,gid_); } static inline int - fchown(const int fd, - const struct stat &st) + fchown(const int fd_, + const struct stat &st_) { - return fs::fchown(fd,st.st_uid,st.st_gid); + return fs::fchown(fd_,st_.st_uid,st_.st_gid); } static inline int - lchown_check_on_error(const std::string &path, - const struct stat &st) + lchown_check_on_error(const std::string &path_, + const struct stat &st_) { int rv; - rv = fs::lchown(path,st); + rv = fs::lchown(path_,st_); if(rv == -1) { int error; struct stat tmpst; error = errno; - rv = fs::lstat(path,tmpst); + rv = fs::lstat(path_,&tmpst); if(rv == -1) return -1; - if((st.st_uid != tmpst.st_uid) || - (st.st_gid != tmpst.st_gid)) + if((st_.st_uid != tmpst.st_uid) || + (st_.st_gid != tmpst.st_gid)) return (errno=error,-1); } @@ -115,24 +115,24 @@ namespace fs static inline int - fchown_check_on_error(const int fd, - const struct stat &st) + fchown_check_on_error(const int fd_, + const struct stat &st_) { int rv; - rv = fs::fchown(fd,st); + rv = fs::fchown(fd_,st_); if(rv == -1) { int error; struct stat tmpst; error = errno; - rv = fs::fstat(fd,tmpst); + rv = fs::fstat(fd_,&tmpst); if(rv == -1) return -1; - if((st.st_uid != tmpst.st_uid) || - (st.st_gid != tmpst.st_gid)) + if((st_.st_uid != tmpst.st_uid) || + (st_.st_gid != tmpst.st_gid)) return (errno=error,-1); } diff --git a/src/fs_base_close.hpp b/src/fs_base_close.hpp index 4d904907..236d290d 100644 --- a/src/fs_base_close.hpp +++ b/src/fs_base_close.hpp @@ -25,8 +25,8 @@ namespace fs static inline int - close(const int fd) + close(const int fd_) { - return ::close(fd); + return ::close(fd_); } } diff --git a/src/fs_base_closedir.hpp b/src/fs_base_closedir.hpp index d5d9c46d..03ae8785 100644 --- a/src/fs_base_closedir.hpp +++ b/src/fs_base_closedir.hpp @@ -26,8 +26,8 @@ namespace fs static inline int - closedir(DIR *dirp) + closedir(DIR *dirp_) { - return ::closedir(dirp); + return ::closedir(dirp_); } } diff --git a/src/fs_base_dirfd.hpp b/src/fs_base_dirfd.hpp index 293b2868..d4afa76e 100644 --- a/src/fs_base_dirfd.hpp +++ b/src/fs_base_dirfd.hpp @@ -26,8 +26,8 @@ namespace fs static inline int - dirfd(DIR *dirp) + dirfd(DIR *dirp_) { - return ::dirfd(dirp); + return ::dirfd(dirp_); } } diff --git a/src/fs_base_dup.hpp b/src/fs_base_dup.hpp index 6cafbba9..fc1dd106 100644 --- a/src/fs_base_dup.hpp +++ b/src/fs_base_dup.hpp @@ -25,8 +25,8 @@ namespace fs static inline int - dup(const int fd) + dup(const int fd_) { - return ::dup(fd); + return ::dup(fd_); } } diff --git a/src/fs_base_fadvise.hpp b/src/fs_base_fadvise.hpp index 56335082..3a89caa2 100644 --- a/src/fs_base_fadvise.hpp +++ b/src/fs_base_fadvise.hpp @@ -19,17 +19,17 @@ namespace fs { int - fadvise_dontneed(const int fd, - const off_t offset = 0, - const off_t len = 0); + fadvise_dontneed(const int fd_, + const off_t offset_ = 0, + const off_t len_ = 0); int - fadvise_willneed(const int fd, - const off_t offset = 0, - const off_t len = 0); + fadvise_willneed(const int fd_, + const off_t offset_ = 0, + const off_t len_ = 0); int - fadvise_sequential(const int fd, - const off_t offset = 0, - const off_t len = 0); + fadvise_sequential(const int fd_, + const off_t offset_ = 0, + const off_t len_ = 0); } diff --git a/src/fs_base_fallocate.hpp b/src/fs_base_fallocate.hpp index d6691472..cd10cbb2 100644 --- a/src/fs_base_fallocate.hpp +++ b/src/fs_base_fallocate.hpp @@ -21,8 +21,8 @@ namespace fs { int - fallocate(const int fd, - const int mode, - const off_t offset, - const off_t len); + fallocate(const int fd_, + const int mode_, + const off_t offset_, + const off_t len_); } diff --git a/src/fs_base_flock.hpp b/src/fs_base_flock.hpp index d7059e3b..1cee9c6d 100644 --- a/src/fs_base_flock.hpp +++ b/src/fs_base_flock.hpp @@ -25,9 +25,9 @@ namespace fs static inline int - flock(const int fd, - const int operation) + flock(const int fd_, + const int operation_) { - return ::flock(fd,operation); + return ::flock(fd_,operation_); } } diff --git a/src/fs_base_fsync.hpp b/src/fs_base_fsync.hpp index f4fe224b..e2fd1c0e 100644 --- a/src/fs_base_fsync.hpp +++ b/src/fs_base_fsync.hpp @@ -31,18 +31,18 @@ namespace fs static inline int - fsync(const int fd) + fsync(const int fd_) { - return ::fsync(fd); + return ::fsync(fd_); } static inline int - fdatasync(const int fd) + fdatasync(const int fd_) { #if _POSIX_SYNCHRONIZED_IO > 0 - return ::fdatasync(fd); + return ::fdatasync(fd_); #else return (errno=ENOSYS,-1); #endif diff --git a/src/fs_base_ftruncate.hpp b/src/fs_base_ftruncate.hpp index e204f4b7..0244bd2d 100644 --- a/src/fs_base_ftruncate.hpp +++ b/src/fs_base_ftruncate.hpp @@ -26,9 +26,9 @@ namespace fs static inline int - ftruncate(const int fd, - const off_t size) + ftruncate(const int fd_, + const off_t size_) { - return ::ftruncate(fd,size); + return ::ftruncate(fd_,size_); } } diff --git a/src/fs_base_futimesat.hpp b/src/fs_base_futimesat.hpp index e5c4bfdc..a6de50a4 100644 --- a/src/fs_base_futimesat.hpp +++ b/src/fs_base_futimesat.hpp @@ -18,10 +18,12 @@ #pragma once +#include + namespace fs { int - futimesat(const int dirfd, - const char *pathname, - const struct timeval times[2]); + futimesat(const int dirfd_, + const char *pathname_, + const struct timeval times_[2]); } diff --git a/src/fs_base_getxattr.hpp b/src/fs_base_getxattr.hpp index edecc1f9..65dd5137 100644 --- a/src/fs_base_getxattr.hpp +++ b/src/fs_base_getxattr.hpp @@ -21,10 +21,10 @@ #include "errno.hpp" #include "xattr.hpp" -#include - #include +#include + namespace fs { static diff --git a/src/fs_base_link.hpp b/src/fs_base_link.hpp index c733c4b8..09ef6459 100644 --- a/src/fs_base_link.hpp +++ b/src/fs_base_link.hpp @@ -27,9 +27,10 @@ namespace fs static inline int - link(const std::string &oldpath, - const std::string &newpath) + link(const std::string &oldpath_, + const std::string &newpath_) { - return ::link(oldpath.c_str(),newpath.c_str()); + return ::link(oldpath_.c_str(), + newpath_.c_str()); } } diff --git a/src/fs_base_listxattr.hpp b/src/fs_base_listxattr.hpp index 766e4857..ea5c5b7b 100644 --- a/src/fs_base_listxattr.hpp +++ b/src/fs_base_listxattr.hpp @@ -21,10 +21,10 @@ #include "errno.hpp" #include "xattr.hpp" -#include - #include +#include + namespace fs { static diff --git a/src/fs_base_lseek.hpp b/src/fs_base_lseek.hpp index 94bdeb6e..34744c49 100644 --- a/src/fs_base_lseek.hpp +++ b/src/fs_base_lseek.hpp @@ -26,10 +26,10 @@ namespace fs static inline off_t - lseek(const int fd, - const off_t offset, - const int whence) + lseek(const int fd_, + const off_t offset_, + const int whence_) { - return ::lseek(fd,offset,whence); + return ::lseek(fd_,offset_,whence_); } } diff --git a/src/fs_base_mkdir.hpp b/src/fs_base_mkdir.hpp index b7237c40..05eb78b5 100644 --- a/src/fs_base_mkdir.hpp +++ b/src/fs_base_mkdir.hpp @@ -28,9 +28,9 @@ namespace fs static inline int - mkdir(const std::string &path, - const mode_t mode) + mkdir(const std::string &path_, + const mode_t mode_) { - return ::mkdir(path.c_str(),mode); + return ::mkdir(path_.c_str(),mode_); } } diff --git a/src/fs_base_mknod.hpp b/src/fs_base_mknod.hpp index b80c9c27..bf85f3b2 100644 --- a/src/fs_base_mknod.hpp +++ b/src/fs_base_mknod.hpp @@ -28,10 +28,10 @@ namespace fs static inline int - mknod(const std::string &path, - const mode_t mode, - const dev_t dev) + mknod(const std::string &path_, + const mode_t mode_, + const dev_t dev_) { - return ::mknod(path.c_str(),mode,dev); + return ::mknod(path_.c_str(),mode_,dev_); } } diff --git a/src/fs_base_mkstemp.hpp b/src/fs_base_mkstemp.hpp index f4638266..744794db 100644 --- a/src/fs_base_mkstemp.hpp +++ b/src/fs_base_mkstemp.hpp @@ -18,29 +18,29 @@ #pragma once +#include + #include #include -#include - namespace fs { static inline int - mkstemp(std::string &filepath) + mkstemp(std::string &filepath_) { int fd; - char buf[filepath.size()+8]; + char buf[filepath_.size()+8]; - strcpy(buf,filepath.c_str()); - strcpy(buf+filepath.size(),".XXXXXX"); + strcpy(buf,filepath_.c_str()); + strcpy(buf+filepath_.size(),".XXXXXX"); fd = ::mkstemp(buf); if(fd == -1) return -1; - filepath = buf; + filepath_ = buf; return fd; } diff --git a/src/fs_base_open.hpp b/src/fs_base_open.hpp index 364ad003..6346095e 100644 --- a/src/fs_base_open.hpp +++ b/src/fs_base_open.hpp @@ -18,12 +18,12 @@ #pragma once +#include + #include #include #include -#include - namespace fs { static diff --git a/src/fs_base_opendir.hpp b/src/fs_base_opendir.hpp index 851463f6..7b62aecf 100644 --- a/src/fs_base_opendir.hpp +++ b/src/fs_base_opendir.hpp @@ -28,8 +28,8 @@ namespace fs static inline DIR * - opendir(const std::string &name) + opendir(const std::string &name_) { - return ::opendir(name.c_str()); + return ::opendir(name_.c_str()); } } diff --git a/src/fs_base_read.hpp b/src/fs_base_read.hpp index c634b85a..d794543e 100644 --- a/src/fs_base_read.hpp +++ b/src/fs_base_read.hpp @@ -25,21 +25,21 @@ namespace fs static inline ssize_t - read(const int fd, - void *buf, - const size_t count) + read(const int fd_, + void *buf_, + const size_t count_) { - return ::read(fd,buf,count); + return ::read(fd_,buf_,count_); } static inline ssize_t - pread(const int fd, - void *buf, - const size_t count, - const off_t offset) + pread(const int fd_, + void *buf_, + const size_t count_, + const off_t offset_) { - return ::pread(fd,buf,count,offset); + return ::pread(fd_,buf_,count_,offset_); } } diff --git a/src/fs_base_readdir.hpp b/src/fs_base_readdir.hpp index b913d62e..7a82d61e 100644 --- a/src/fs_base_readdir.hpp +++ b/src/fs_base_readdir.hpp @@ -25,8 +25,8 @@ namespace fs static inline struct dirent * - readdir(DIR *dirp) + readdir(DIR *dirp_) { - return ::readdir(dirp); + return ::readdir(dirp_); } } diff --git a/src/fs_base_readlink.hpp b/src/fs_base_readlink.hpp index 6c589b49..a8fc1a5b 100644 --- a/src/fs_base_readlink.hpp +++ b/src/fs_base_readlink.hpp @@ -27,10 +27,10 @@ namespace fs static inline int - readlink(const std::string &path, - char *buf, - const size_t bufsiz) + readlink(const std::string &path_, + char *buf_, + const size_t bufsiz_) { - return ::readlink(path.c_str(),buf,bufsiz); + return ::readlink(path_.c_str(),buf_,bufsiz_); } } diff --git a/src/fs_base_realpath.hpp b/src/fs_base_realpath.hpp index 16edeee8..d31a270c 100644 --- a/src/fs_base_realpath.hpp +++ b/src/fs_base_realpath.hpp @@ -28,17 +28,17 @@ namespace fs static inline char * - realpath(const std::string &path, - char *resolved_path) + realpath(const std::string &path_, + char *resolved_path_) { - return ::realpath(path.c_str(),resolved_path); + return ::realpath(path_.c_str(),resolved_path_); } static inline char * - realpath(const std::string &path) + realpath(const std::string &path_) { - return fs::realpath(path,NULL); + return fs::realpath(path_,NULL); } } diff --git a/src/fs_base_remove.hpp b/src/fs_base_remove.hpp index bed37c4c..07ae25cc 100644 --- a/src/fs_base_remove.hpp +++ b/src/fs_base_remove.hpp @@ -27,8 +27,16 @@ namespace fs static inline int - remove(const std::string &pathname) + remove(const char *pathname_) { - return ::remove(pathname.c_str()); + return ::remove(pathname_); + } + + static + inline + int + remove(const std::string &pathname_) + { + return fs::remove(pathname_.c_str()); } } diff --git a/src/fs_base_removexattr.hpp b/src/fs_base_removexattr.hpp index 08357d23..4d9f3f53 100644 --- a/src/fs_base_removexattr.hpp +++ b/src/fs_base_removexattr.hpp @@ -18,21 +18,21 @@ #pragma once -#include - #include "errno.hpp" #include "xattr.hpp" +#include + namespace fs { static inline int - lremovexattr(const std::string &path, - const char *attrname) + lremovexattr(const std::string &path_, + const char *attrname_) { #ifdef USE_XATTR - return ::lremovexattr(path.c_str(),attrname); + return ::lremovexattr(path_.c_str(),attrname_); #else return (errno=ENOTSUP,-1); #endif diff --git a/src/fs_base_rmdir.hpp b/src/fs_base_rmdir.hpp index 3d9c02f2..d87a3f42 100644 --- a/src/fs_base_rmdir.hpp +++ b/src/fs_base_rmdir.hpp @@ -27,8 +27,16 @@ namespace fs static inline int - rmdir(const std::string &path) + rmdir(const char *path_) { - return ::rmdir(path.c_str()); + return ::rmdir(path_); + } + + static + inline + int + rmdir(const std::string &path_) + { + return fs::rmdir(path_.c_str()); } } diff --git a/src/fs_base_setxattr.hpp b/src/fs_base_setxattr.hpp index ee91b6c1..29f05cd7 100644 --- a/src/fs_base_setxattr.hpp +++ b/src/fs_base_setxattr.hpp @@ -21,10 +21,10 @@ #include "errno.hpp" #include "xattr.hpp" -#include - #include +#include + namespace fs { static diff --git a/src/fs_base_stat.hpp b/src/fs_base_stat.hpp index bbf1406c..4292f697 100644 --- a/src/fs_base_stat.hpp +++ b/src/fs_base_stat.hpp @@ -29,48 +29,57 @@ namespace fs static inline int - stat(const char *path, - struct stat &st) + stat(const char *path_, + struct stat *st_) { - return ::stat(path,&st); + return ::stat(path_,st_); } static inline int - stat(const std::string &path, - struct stat &st) + stat(const std::string &path_, + struct stat *st_) { - return fs::stat(path.c_str(),st); + return fs::stat(path_.c_str(),st_); } static inline int - lstat(const std::string &path, - struct stat &st) + lstat(const char *path_, + struct stat *st_) { - return ::lstat(path.c_str(),&st); + return ::lstat(path_,st_); } static inline int - fstat(const int fd, - struct stat &st) + lstat(const std::string &path_, + struct stat *st_) { - return ::fstat(fd,&st); + return fs::lstat(path_.c_str(),st_); + } + + static + inline + int + fstat(const int fd_, + struct stat *st_) + { + return ::fstat(fd_,st_); } static inline timespec * - stat_atime(struct stat &st) + stat_atime(struct stat *st_) { #if __APPLE__ - return &st.st_atimespec; + return &st_->st_atimespec; #else - return &st.st_atim; + return &st_->st_atim; #endif } @@ -78,24 +87,24 @@ namespace fs inline const timespec * - stat_atime(const struct stat &st) + stat_atime(const struct stat *st_) { #if __APPLE__ - return &st.st_atimespec; + return &st_->st_atimespec; #else - return &st.st_atim; + return &st_->st_atim; #endif } static inline timespec * - stat_mtime(struct stat &st) + stat_mtime(struct stat *st_) { #if __APPLE__ - return &st.st_mtimespec; + return &st_->st_mtimespec; #else - return &st.st_mtim; + return &st_->st_mtim; #endif } @@ -103,12 +112,12 @@ namespace fs inline const timespec * - stat_mtime(const struct stat &st) + stat_mtime(const struct stat *st_) { #if __APPLE__ - return &st.st_mtimespec; + return &st_->st_mtimespec; #else - return &st.st_mtim; + return &st_->st_mtim; #endif } } diff --git a/src/fs_base_statvfs.hpp b/src/fs_base_statvfs.hpp index 2ba2567f..25d1cbbb 100644 --- a/src/fs_base_statvfs.hpp +++ b/src/fs_base_statvfs.hpp @@ -22,10 +22,10 @@ #include "fs_base_close.hpp" #include "fs_base_open.hpp" -#include - #include +#include + #ifndef O_PATH # define O_PATH 0 #endif diff --git a/src/fs_base_symlink.hpp b/src/fs_base_symlink.hpp index 0f88926f..6fa9e535 100644 --- a/src/fs_base_symlink.hpp +++ b/src/fs_base_symlink.hpp @@ -27,18 +27,30 @@ namespace fs static inline int - symlink(const std::string &oldpath, - const std::string &newpath) + symlink(const char *oldpath_, + const char *newpath_) { - return ::symlink(oldpath.c_str(),newpath.c_str()); + return ::symlink(oldpath_, + newpath_); } static inline int - symlink(const char *oldpath, - const std::string &newpath) + symlink(const std::string &oldpath_, + const std::string &newpath_) { - return ::symlink(oldpath,newpath.c_str()); + return fs::symlink(oldpath_.c_str(), + newpath_.c_str()); + } + + static + inline + int + symlink(const char *oldpath_, + const std::string &newpath_) + { + return fs::symlink(oldpath_, + newpath_.c_str()); } } diff --git a/src/fs_base_truncate.hpp b/src/fs_base_truncate.hpp index aa7148a2..512214cc 100644 --- a/src/fs_base_truncate.hpp +++ b/src/fs_base_truncate.hpp @@ -28,9 +28,18 @@ namespace fs static inline int - truncate(const std::string &path, - const off_t length) + truncate(const char *path_, + const off_t length_) { - return ::truncate(path.c_str(),length); + return ::truncate(path_,length_); + } + + static + inline + int + truncate(const std::string &path_, + const off_t length_) + { + return fs::truncate(path_.c_str(),length_); } } diff --git a/src/fs_base_utime.hpp b/src/fs_base_utime.hpp index 8ab6f46b..edd6870d 100644 --- a/src/fs_base_utime.hpp +++ b/src/fs_base_utime.hpp @@ -31,37 +31,37 @@ namespace fs static inline int - utime(const std::string &path, - const struct stat &st) + utime(const std::string &path_, + const struct stat &st_) { struct timespec times[2]; - times[0] = *fs::stat_atime(st); - times[1] = *fs::stat_mtime(st); + times[0] = *fs::stat_atime(&st_); + times[1] = *fs::stat_mtime(&st_); - return fs::utime(AT_FDCWD,path,times,0); + return fs::utime(AT_FDCWD,path_,times,0); } static inline int - utime(const int fd, - const struct stat &st) + utime(const int fd_, + const struct stat &st_) { struct timespec times[2]; - times[0] = *fs::stat_atime(st); - times[1] = *fs::stat_mtime(st); + times[0] = *fs::stat_atime(&st_); + times[1] = *fs::stat_mtime(&st_); - return fs::utime(fd,times); + return fs::utime(fd_,times); } static inline int - lutime(const std::string &path, - const struct timespec times[2]) + lutime(const std::string &path_, + const struct timespec times_[2]) { - return fs::utime(AT_FDCWD,path,times,AT_SYMLINK_NOFOLLOW); + return fs::utime(AT_FDCWD,path_,times_,AT_SYMLINK_NOFOLLOW); } } diff --git a/src/fs_base_utime_generic.hpp b/src/fs_base_utime_generic.hpp index cdd90a14..096ed878 100644 --- a/src/fs_base_utime_generic.hpp +++ b/src/fs_base_utime_generic.hpp @@ -18,15 +18,15 @@ #pragma once +#include "fs_base_futimesat.hpp" +#include "fs_base_stat.hpp" + #include #include #include #include -#include "fs_base_futimesat.hpp" -#include "fs_base_stat.hpp" - #ifndef UTIME_NOW # define UTIME_NOW ((1l << 30) - 1l) #endif @@ -38,54 +38,54 @@ static inline bool -_can_call_lutimes(const int dirfd, - const std::string &path, - const int flags) +_can_call_lutimes(const int dirfd_, + const std::string &path_, + const int flags_) { - return ((flags == AT_SYMLINK_NOFOLLOW) && - ((dirfd == AT_FDCWD) || - (path[0] == '/'))); + return ((flags_ == AT_SYMLINK_NOFOLLOW) && + ((dirfd_ == AT_FDCWD) || + (path_[0] == '/'))); } static inline bool -_should_ignore(const struct timespec ts[2]) +_should_ignore(const struct timespec ts_[2]) { - return ((ts != NULL) && - (ts[0].tv_nsec == UTIME_OMIT) && - (ts[1].tv_nsec == UTIME_OMIT)); + return ((ts_ != NULL) && + (ts_[0].tv_nsec == UTIME_OMIT) && + (ts_[1].tv_nsec == UTIME_OMIT)); } static inline bool -_should_be_set_to_now(const struct timespec ts[2]) +_should_be_set_to_now(const struct timespec ts_[2]) { - return ((ts == NULL) || - ((ts[0].tv_nsec == UTIME_NOW) && - (ts[1].tv_nsec == UTIME_NOW))); + return ((ts_ == NULL) || + ((ts_[0].tv_nsec == UTIME_NOW) && + (ts_[1].tv_nsec == UTIME_NOW))); } static inline bool -_timespec_invalid(const struct timespec &ts) +_timespec_invalid(const struct timespec &ts_) { - return (((ts.tv_nsec < 0) || - (ts.tv_nsec > 999999999)) && - ((ts.tv_nsec != UTIME_NOW) && - (ts.tv_nsec != UTIME_OMIT))); + return (((ts_.tv_nsec < 0) || + (ts_.tv_nsec > 999999999)) && + ((ts_.tv_nsec != UTIME_NOW) && + (ts_.tv_nsec != UTIME_OMIT))); } static inline bool -_timespec_invalid(const struct timespec ts[2]) +_timespec_invalid(const struct timespec ts_[2]) { - return ((ts != NULL) && - (_timespec_invalid(ts[0]) || - _timespec_invalid(ts[1]))); + return ((ts_ != NULL) && + (_timespec_invalid(ts_[0]) || + _timespec_invalid(ts_[1]))); } static @@ -99,19 +99,19 @@ _flags_invalid(const int flags) static inline bool -_any_timespec_is_utime_omit(const struct timespec ts[2]) +_any_timespec_is_utime_omit(const struct timespec ts_[2]) { - return ((ts[0].tv_nsec == UTIME_OMIT) || - (ts[1].tv_nsec == UTIME_OMIT)); + return ((ts_[0].tv_nsec == UTIME_OMIT) || + (ts_[1].tv_nsec == UTIME_OMIT)); } static inline bool -_any_timespec_is_utime_now(const struct timespec ts[2]) +_any_timespec_is_utime_now(const struct timespec ts_[2]) { - return ((ts[0].tv_nsec == UTIME_NOW) || - (ts[1].tv_nsec == UTIME_NOW)); + return ((ts_[0].tv_nsec == UTIME_NOW) || + (ts_[1].tv_nsec == UTIME_NOW)); } static @@ -119,7 +119,7 @@ inline int _set_utime_omit_to_current_value(const int dirfd, const std::string &path, - const struct timespec ts[2], + const struct timespec ts_[2], struct timeval tv[2], const int flags) { @@ -128,7 +128,7 @@ _set_utime_omit_to_current_value(const int dirfd, timespec *atime; timespec *mtime; - if(!_any_timespec_is_utime_omit(ts)) + if(!_any_timespec_is_utime_omit(ts_)) return 0; rv = ::fstatat(dirfd,path.c_str(),&st,flags); @@ -138,9 +138,9 @@ _set_utime_omit_to_current_value(const int dirfd, atime = fs::stat_atime(st); mtime = fs::stat_mtime(st); - if(ts[0].tv_nsec == UTIME_OMIT) + if(ts_[0].tv_nsec == UTIME_OMIT) TIMESPEC_TO_TIMEVAL(&tv[0],atime); - if(ts[1].tv_nsec == UTIME_OMIT) + if(ts_[1].tv_nsec == UTIME_OMIT) TIMESPEC_TO_TIMEVAL(&tv[1],mtime); return 0; @@ -150,7 +150,7 @@ static inline int _set_utime_omit_to_current_value(const int fd, - const struct timespec ts[2], + const struct timespec ts_[2], struct timeval tv[2]) { int rv; @@ -158,7 +158,7 @@ _set_utime_omit_to_current_value(const int fd, timespec *atime; timespec *mtime; - if(!_any_timespec_is_utime_omit(ts)) + if(!_any_timespec_is_utime_omit(ts_)) return 0; rv = ::fstat(fd,&st); @@ -168,9 +168,9 @@ _set_utime_omit_to_current_value(const int fd, atime = fs::stat_atime(st); mtime = fs::stat_mtime(st); - if(ts[0].tv_nsec == UTIME_OMIT) + if(ts_[0].tv_nsec == UTIME_OMIT) TIMESPEC_TO_TIMEVAL(&tv[0],atime); - if(ts[1].tv_nsec == UTIME_OMIT) + if(ts_[1].tv_nsec == UTIME_OMIT) TIMESPEC_TO_TIMEVAL(&tv[1],mtime); return 0; @@ -179,22 +179,22 @@ _set_utime_omit_to_current_value(const int fd, static inline int -_set_utime_now_to_now(const struct timespec ts[2], +_set_utime_now_to_now(const struct timespec ts_[2], struct timeval tv[2]) { int rv; struct timeval now; - if(_any_timespec_is_utime_now(ts)) + if(_any_timespec_is_utime_now(ts_)) return 0; rv = ::gettimeofday(&now,NULL); if(rv == -1) return -1; - if(ts[0].tv_nsec == UTIME_NOW) + if(ts_[0].tv_nsec == UTIME_NOW) tv[0] = now; - if(ts[1].tv_nsec == UTIME_NOW) + if(ts_[1].tv_nsec == UTIME_NOW) tv[1] = now; return 0; @@ -205,24 +205,24 @@ inline int _convert_timespec_to_timeval(const int dirfd, const std::string &path, - const struct timespec ts[2], + const struct timespec ts_[2], struct timeval tv[2], struct timeval *&tvp, const int flags) { int rv; - if(_should_be_set_to_now(ts)) + if(_should_be_set_to_now(ts_)) return (tvp=NULL,0); - TIMESPEC_TO_TIMEVAL(&tv[0],&ts[0]); - TIMESPEC_TO_TIMEVAL(&tv[1],&ts[1]); + TIMESPEC_TO_TIMEVAL(&tv[0],&ts_[0]); + TIMESPEC_TO_TIMEVAL(&tv[1],&ts_[1]); - rv = _set_utime_omit_to_current_value(dirfd,path,ts,tv,flags); + rv = _set_utime_omit_to_current_value(dirfd,path,ts_,tv,flags); if(rv == -1) return -1; - rv = _set_utime_now_to_now(ts,tv); + rv = _set_utime_now_to_now(ts_,tv); if(rv == -1) return -1; @@ -233,23 +233,23 @@ static inline int _convert_timespec_to_timeval(const int fd, - const struct timespec ts[2], + const struct timespec ts_[2], struct timeval tv[2], struct timeval *&tvp) { int rv; - if(_should_be_set_to_now(ts)) + if(_should_be_set_to_now(ts_)) return (tvp=NULL,0); - TIMESPEC_TO_TIMEVAL(&tv[0],&ts[0]); - TIMESPEC_TO_TIMEVAL(&tv[1],&ts[1]); + TIMESPEC_TO_TIMEVAL(&tv[0],&ts_[0]); + TIMESPEC_TO_TIMEVAL(&tv[1],&ts_[1]); - rv = _set_utime_omit_to_current_value(fd,ts,tv); + rv = _set_utime_omit_to_current_value(fd,ts_,tv); if(rv == -1) return -1; - rv = _set_utime_now_to_now(ts,tv); + rv = _set_utime_now_to_now(ts_,tv); if(rv == -1) return -1; @@ -263,7 +263,7 @@ namespace fs int utime(const int dirfd, const std::string &path, - const struct timespec ts[2], + const struct timespec ts_[2], const int flags) { int rv; @@ -272,12 +272,12 @@ namespace fs if(_flags_invalid(flags)) return (errno=EINVAL,-1); - if(_timespec_invalid(ts)) + if(_timespec_invalid(ts_)) return (errno=EINVAL,-1); - if(_should_ignore(ts)) + if(_should_ignore(ts_)) return 0; - rv = _convert_timespec_to_timeval(dirfd,path,ts,tv,tvp,flags); + rv = _convert_timespec_to_timeval(dirfd,path,ts_,tv,tvp,flags); if(rv == -1) return -1; @@ -292,22 +292,22 @@ namespace fs static inline int - utime(const int fd, - const struct timespec ts[2]) + utime(const int fd_, + const struct timespec ts_[2]) { int rv; struct timeval tv[2]; struct timeval *tvp; - if(_timespec_invalid(ts)) + if(_timespec_invalid(ts_)) return (errno=EINVAL,-1); - if(_should_ignore(ts)) + if(_should_ignore(ts_)) return 0; - rv = _convert_timespec_to_timeval(fd,ts,tv,tvp); + rv = _convert_timespec_to_timeval(fd_,ts_,tv,tvp); if(rv == -1) return -1; - return ::futimes(fd,tvp); + return ::futimes(fd_,tvp); } } diff --git a/src/fs_clonefile.cpp b/src/fs_clonefile.cpp index 24bf6b3b..6b23b420 100644 --- a/src/fs_clonefile.cpp +++ b/src/fs_clonefile.cpp @@ -84,7 +84,7 @@ namespace fs int rv; struct stat src_st; - rv = fs::fstat(src_fd_,src_st); + rv = fs::fstat(src_fd_,&src_st); if(rv == -1) return -1; diff --git a/src/fs_clonepath.cpp b/src/fs_clonepath.cpp index 85acf449..8966f00d 100644 --- a/src/fs_clonepath.cpp +++ b/src/fs_clonepath.cpp @@ -78,14 +78,14 @@ namespace fs return -1; } - fs::path::make(&fromsrc,relative,frompath); - rv = fs::stat(frompath,st); + frompath = fs::path::make(fromsrc,relative); + rv = fs::stat(frompath,&st); if(rv == -1) return -1; else if(!S_ISDIR(st.st_mode)) return (errno=ENOTDIR,-1); - fs::path::make(&tosrc,relative,topath); + topath = fs::path::make(tosrc,relative); rv = fs::mkdir(topath,st.st_mode); if(rv == -1) { @@ -117,10 +117,10 @@ namespace fs } int - clonepath(const std::string &from, - const std::string &to, - const std::string &relative, - const bool return_metadata_errors) + clonepath(const string &from, + const string &to, + const string &relative, + const bool return_metadata_errors) { return fs::clonepath(from,to,relative.c_str(),return_metadata_errors); } @@ -144,10 +144,10 @@ namespace fs } int - clonepath_as_root(const std::string &from, - const std::string &to, - const std::string &relative, - const bool return_metadata_errors) + clonepath_as_root(const string &from, + const string &to, + const string &relative, + const bool return_metadata_errors) { return fs::clonepath_as_root(from,to,relative.c_str(),return_metadata_errors); } diff --git a/src/fs_copyfile.cpp b/src/fs_copyfile.cpp index e90b1114..dd0fbf68 100644 --- a/src/fs_copyfile.cpp +++ b/src/fs_copyfile.cpp @@ -98,7 +98,7 @@ namespace fs int rv; struct stat st; - rv = fs::fstat(src_fd_,st); + rv = fs::fstat(src_fd_,&st); if(rv == -1) return rv; diff --git a/src/fs_cow.cpp b/src/fs_cow.cpp index 6e9ea773..95809ef2 100644 --- a/src/fs_cow.cpp +++ b/src/fs_cow.cpp @@ -89,7 +89,7 @@ namespace fs if(!is_eligible(flags_)) return false; - rv = fs::lstat(fullpath_,st); + rv = fs::lstat(fullpath_,&st); if(rv == -1) return false; diff --git a/src/fs_devid.hpp b/src/fs_devid.hpp index 5ab5758f..cf897ce6 100644 --- a/src/fs_devid.hpp +++ b/src/fs_devid.hpp @@ -27,12 +27,12 @@ namespace fs static inline dev_t - devid(const int fd) + devid(const int fd_) { int rv; struct stat st; - rv = ::fstat(fd,&st); + rv = ::fstat(fd_,&st); if(rv == -1) return -1; diff --git a/src/fs_exists.hpp b/src/fs_exists.hpp index cc699676..7895f390 100644 --- a/src/fs_exists.hpp +++ b/src/fs_exists.hpp @@ -29,7 +29,7 @@ namespace fs inline bool exists(const std::string &path_, - struct stat &st_) + struct stat *st_) { int rv; @@ -45,7 +45,7 @@ namespace fs { struct stat st; - return fs::exists(path_,st); + return fs::exists(path_,&st); } @@ -54,7 +54,7 @@ namespace fs bool exists(const std::string &basepath_, const char *relpath_, - struct stat &st_) + struct stat *st_) { std::string fullpath; @@ -71,6 +71,6 @@ namespace fs { struct stat st; - return fs::exists(basepath_,relpath_,st); + return fs::exists(basepath_,relpath_,&st); } } diff --git a/src/fs_glob.hpp b/src/fs_glob.hpp index 28c49dc0..82f28f44 100644 --- a/src/fs_glob.hpp +++ b/src/fs_glob.hpp @@ -19,10 +19,7 @@ namespace fs { - using std::string; - using std::vector; - void - glob(const string &pattern_, - vector &strs_); + glob(const std::string &pattern_, + std::vector &strs_); } diff --git a/src/fs_inode.hpp b/src/fs_inode.hpp index 8d2256cd..29127fa1 100644 --- a/src/fs_inode.hpp +++ b/src/fs_inode.hpp @@ -25,20 +25,17 @@ namespace fs { namespace inode { - enum - { - MAGIC = 0x7472617065786974 - }; + static const uint64_t MAGIC = 0x7472617065786974; inline void - recompute(struct stat &st) + recompute(struct stat *st_) { - // not ideal to do this at runtime but likely gets optimized out - if(sizeof(st.st_ino) == 4) - st.st_ino |= ((uint32_t)st.st_dev << 16); + /* not ideal to do this at runtime but likely gets optimized out */ + if(sizeof(st_->st_ino) == 4) + st_->st_ino |= ((uint32_t)st_->st_dev << 16); else - st.st_ino |= ((uint64_t)st.st_dev << 32); + st_->st_ino |= ((uint64_t)st_->st_dev << 32); } } } diff --git a/src/fs_movefile.cpp b/src/fs_movefile.cpp index 9c3ca66e..39514a3f 100644 --- a/src/fs_movefile.cpp +++ b/src/fs_movefile.cpp @@ -58,7 +58,7 @@ namespace fs fdin = origfd; - rv = fs::fstat(fdin,fdin_st); + rv = fs::fstat(fdin,&fdin_st); if(rv == -1) return -1; diff --git a/src/fs_path.hpp b/src/fs_path.hpp index 1f82a970..f0895325 100644 --- a/src/fs_path.hpp +++ b/src/fs_path.hpp @@ -30,6 +30,7 @@ namespace fs string basename(const string &path); + static inline void append(string &base, @@ -38,6 +39,7 @@ namespace fs base += suffix; } + static inline void append(string &base, @@ -46,36 +48,16 @@ namespace fs base += suffix; } + static inline - void + string make(const string &base_, - const char *suffix_, - string *output_) - { - *output_ = base_; - *output_ += suffix_; - } - - inline - void - make(const string *base, - const char *suffix, - string &output) - { - output = *base; - output += suffix; - } - - inline - void - make(const string *base, - const string &suffix, - string &output) + const char *suffix_) { - output = *base; - output += suffix; + return (base_ + suffix_); } + static inline string make(const string *base_, @@ -92,5 +74,14 @@ namespace fs { return (*base_ + *suffix_); } + + static + inline + string + make(const string &base_, + const string &suffix_) + { + return (base_ + suffix_); + } } }; diff --git a/src/fs_statvfs_cache.cpp b/src/fs_statvfs_cache.cpp index 2f9aa683..77b25fd9 100644 --- a/src/fs_statvfs_cache.cpp +++ b/src/fs_statvfs_cache.cpp @@ -39,7 +39,7 @@ static uint64_t g_timeout = 0; static statvfs_cache g_cache; static pthread_mutex_t g_cache_lock = PTHREAD_MUTEX_INITIALIZER; -namespace local +namespace l { static uint64_t @@ -82,7 +82,7 @@ namespace fs return fs::statvfs(path_,st_); rv = 0; - now = local::get_time(); + now = l::get_time(); pthread_mutex_lock(&g_cache_lock); diff --git a/src/access.cpp b/src/fuse_access.cpp similarity index 56% rename from src/access.cpp rename to src/fuse_access.cpp index 96a124f4..f5b93bbb 100644 --- a/src/access.cpp +++ b/src/fuse_access.cpp @@ -27,47 +27,47 @@ using std::string; using std::vector; -static -int -_access(Policy::Func::Search searchFunc, - const Branches &branches_, - const uint64_t minfreespace, - const char *fusepath, - const int mask) +namespace l { - int rv; - string fullpath; - vector basepaths; + static + int + access(Policy::Func::Search searchFunc, + const Branches &branches_, + const uint64_t minfreespace, + const char *fusepath, + const int mask) + { + int rv; + string fullpath; + vector basepaths; - rv = searchFunc(branches_,fusepath,minfreespace,basepaths); - if(rv == -1) - return -errno; + rv = searchFunc(branches_,fusepath,minfreespace,basepaths); + if(rv == -1) + return -errno; - fs::path::make(basepaths[0],fusepath,fullpath); + fullpath = fs::path::make(basepaths[0],fusepath); - rv = fs::eaccess(fullpath,mask); + rv = fs::eaccess(fullpath,mask); - return ((rv == -1) ? -errno : 0); + return ((rv == -1) ? -errno : 0); + } } -namespace mergerfs +namespace FUSE { - namespace fuse + int + access(const char *fusepath, + int mask) { - int - access(const char *fusepath, - int mask) - { - const fuse_context *fc = fuse_get_context(); - const Config &config = Config::get(fc); - const ugid::Set ugid(fc->uid,fc->gid); - const rwlock::ReadGuard readlock(&config.branches_lock); + const fuse_context *fc = fuse_get_context(); + const Config &config = Config::get(fc); + const ugid::Set ugid(fc->uid,fc->gid); + const rwlock::ReadGuard readlock(&config.branches_lock); - return _access(config.access, + return l::access(config.access, config.branches, config.minfreespace, fusepath, mask); - } } } diff --git a/src/rmdir.hpp b/src/fuse_access.hpp similarity index 90% rename from src/rmdir.hpp rename to src/fuse_access.hpp index a5ee55ba..f1586a69 100644 --- a/src/rmdir.hpp +++ b/src/fuse_access.hpp @@ -16,11 +16,9 @@ #pragma once -namespace mergerfs +namespace FUSE { - namespace fuse - { - int - rmdir(const char *fusepath); - } + int + access(const char *fusepath_, + int mask_); } diff --git a/src/fuse_chmod.cpp b/src/fuse_chmod.cpp new file mode 100644 index 00000000..486b2dfa --- /dev/null +++ b/src/fuse_chmod.cpp @@ -0,0 +1,105 @@ +/* + Copyright (c) 2016, Antonio SJ Musumeci + + 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 "config.hpp" +#include "errno.hpp" +#include "fs_base_chmod.hpp" +#include "fs_path.hpp" +#include "rv.hpp" +#include "rwlock.hpp" +#include "ugid.hpp" + +#include + +#include +#include + +using std::string; +using std::vector; + +namespace l +{ + static + int + chmod_loop_core(const string *basepath_, + const char *fusepath_, + const mode_t mode_, + const int error_) + { + int rv; + string fullpath; + + fullpath = fs::path::make(basepath_,fusepath_); + + rv = fs::chmod(fullpath,mode_); + + return error::calc(rv,error_,errno); + } + + static + int + chmod_loop(const vector &basepaths_, + const char *fusepath_, + const mode_t mode_) + { + int error; + + error = -1; + for(size_t i = 0, ei = basepaths_.size(); i != ei; i++) + { + error = l::chmod_loop_core(basepaths_[i],fusepath_,mode_,error); + } + + return -error; + } + + static + int + chmod(Policy::Func::Action actionFunc_, + const Branches &branches_, + const uint64_t minfreespace_, + const char *fusepath_, + const mode_t mode_) + { + int rv; + vector basepaths; + + rv = actionFunc_(branches_,fusepath_,minfreespace_,basepaths); + if(rv == -1) + return -errno; + + return l::chmod_loop(basepaths,fusepath_,mode_); + } +} + +namespace FUSE +{ + int + chmod(const char *fusepath_, + mode_t mode_) + { + const fuse_context *fc = fuse_get_context(); + const Config &config = Config::get(fc); + const ugid::Set ugid(fc->uid,fc->gid); + const rwlock::ReadGuard readlock(&config.branches_lock); + + return l::chmod(config.chmod, + config.branches, + config.minfreespace, + fusepath_, + mode_); + } +} diff --git a/src/unlink.hpp b/src/fuse_chmod.hpp similarity index 90% rename from src/unlink.hpp rename to src/fuse_chmod.hpp index e0ce8743..6466036b 100644 --- a/src/unlink.hpp +++ b/src/fuse_chmod.hpp @@ -16,11 +16,9 @@ #pragma once -namespace mergerfs +namespace FUSE { - namespace fuse - { - int - unlink(const char *fusepath); - } + int + chmod(const char *fusepath_, + mode_t mode_); } diff --git a/src/fuse_chown.cpp b/src/fuse_chown.cpp new file mode 100644 index 00000000..0cc0a381 --- /dev/null +++ b/src/fuse_chown.cpp @@ -0,0 +1,110 @@ +/* + Copyright (c) 2016, Antonio SJ Musumeci + + 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 "config.hpp" +#include "errno.hpp" +#include "fs_base_chown.hpp" +#include "fs_path.hpp" +#include "rv.hpp" +#include "rwlock.hpp" +#include "ugid.hpp" + +#include + +#include +#include + +using std::string; +using std::vector; + +namespace l +{ + static + int + chown_loop_core(const string *basepath_, + const char *fusepath_, + const uid_t uid_, + const gid_t gid_, + const int error_) + { + int rv; + string fullpath; + + fullpath = fs::path::make(basepath_,fusepath_); + + rv = fs::lchown(fullpath,uid_,gid_); + + return error::calc(rv,error_,errno); + } + + static + int + chown_loop(const vector &basepaths_, + const char *fusepath_, + const uid_t uid_, + const gid_t gid_) + { + int error; + + error = -1; + for(size_t i = 0, ei = basepaths_.size(); i != ei; i++) + { + error = l::chown_loop_core(basepaths_[i],fusepath_,uid_,gid_,error); + } + + return -error; + } + + static + int + chown(Policy::Func::Action actionFunc_, + const Branches &branches_, + const uint64_t minfreespace_, + const char *fusepath_, + const uid_t uid_, + const gid_t gid_) + { + int rv; + vector basepaths; + + rv = actionFunc_(branches_,fusepath_,minfreespace_,basepaths); + if(rv == -1) + return -errno; + + return l::chown_loop(basepaths,fusepath_,uid_,gid_); + } +} + +namespace FUSE +{ + int + chown(const char *fusepath_, + uid_t uid_, + gid_t gid_) + { + const fuse_context *fc = fuse_get_context(); + const Config &config = Config::get(fc); + const ugid::Set ugid(fc->uid,fc->gid); + const rwlock::ReadGuard readlock(&config.branches_lock); + + return l::chown(config.chown, + config.branches, + config.minfreespace, + fusepath_, + uid_, + gid_); + } +} diff --git a/src/link.hpp b/src/fuse_chown.hpp similarity index 88% rename from src/link.hpp rename to src/fuse_chown.hpp index 115c0d7e..189052af 100644 --- a/src/link.hpp +++ b/src/fuse_chown.hpp @@ -16,12 +16,10 @@ #pragma once -namespace mergerfs +namespace FUSE { - namespace fuse - { - int - link(const char *from, - const char *to); - } + int + chown(const char *fusepath_, + uid_t uid_, + gid_t gid_); } diff --git a/src/create.cpp b/src/fuse_create.cpp similarity index 69% rename from src/create.cpp rename to src/fuse_create.cpp index 78a94b21..14ac1235 100644 --- a/src/create.cpp +++ b/src/fuse_create.cpp @@ -31,9 +31,8 @@ using std::string; using std::vector; -using namespace mergerfs; -namespace local +namespace l { static int @@ -60,9 +59,9 @@ namespace local int rv; string fullpath; - fs::path::make(&createpath_,fusepath_,fullpath); + fullpath = fs::path::make(createpath_,fusepath_); - rv = local::create_core(fullpath,mode_,umask_,flags_); + rv = l::create_core(fullpath,mode_,umask_,flags_); if(rv == -1) return -errno; @@ -103,39 +102,36 @@ namespace local if(rv == -1) return -errno; - return local::create_core(*createpaths[0], - fusepath_, - mode_, - umask_, - flags_, - fh_); + return l::create_core(*createpaths[0], + fusepath_, + mode_, + umask_, + flags_, + fh_); } } -namespace mergerfs +namespace FUSE { - namespace fuse + int + create(const char *fusepath_, + mode_t mode_, + fuse_file_info *ffi_) { - int - create(const char *fusepath_, - mode_t mode_, - fuse_file_info *ffi_) - { - const fuse_context *fc = fuse_get_context(); - const Config &config = Config::get(fc); - const ugid::Set ugid(fc->uid,fc->gid); - const rwlock::ReadGuard readlock(&config.branches_lock); - - ffi_->direct_io = config.direct_io; - return local::create(config.getattr, - config.create, - config.branches, - config.minfreespace, - fusepath_, - mode_, - fc->umask, - ffi_->flags, - &ffi_->fh); - } + const fuse_context *fc = fuse_get_context(); + const Config &config = Config::get(fc); + const ugid::Set ugid(fc->uid,fc->gid); + const rwlock::ReadGuard readlock(&config.branches_lock); + + ffi_->direct_io = config.direct_io; + return l::create(config.getattr, + config.create, + config.branches, + config.minfreespace, + fusepath_, + mode_, + fc->umask, + ffi_->flags, + &ffi_->fh); } } diff --git a/src/truncate.hpp b/src/fuse_create.hpp similarity index 85% rename from src/truncate.hpp rename to src/fuse_create.hpp index cbf677df..bf42d3d0 100644 --- a/src/truncate.hpp +++ b/src/fuse_create.hpp @@ -16,14 +16,14 @@ #pragma once +#include + #include -namespace mergerfs +namespace FUSE { - namespace fuse - { - int - truncate(const char *fusepath, - off_t size); - } + int + create(const char *fusepath_, + mode_t mode_, + fuse_file_info *ffi_); } diff --git a/src/destroy.cpp b/src/fuse_destroy.cpp similarity index 91% rename from src/destroy.cpp rename to src/fuse_destroy.cpp index 6acd8e8b..90d1737d 100644 --- a/src/destroy.cpp +++ b/src/fuse_destroy.cpp @@ -14,14 +14,11 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -namespace mergerfs +namespace FUSE { - namespace fuse + void + destroy(void *) { - void - destroy(void *) - { - } } } diff --git a/src/destroy.hpp b/src/fuse_destroy.hpp similarity index 91% rename from src/destroy.hpp rename to src/fuse_destroy.hpp index 5b9727f5..60ae8577 100644 --- a/src/destroy.hpp +++ b/src/fuse_destroy.hpp @@ -16,11 +16,8 @@ #pragma once -namespace mergerfs +namespace FUSE { - namespace fuse - { - void - destroy(void *); - } + void + destroy(void *); } diff --git a/src/fallocate.cpp b/src/fuse_fallocate.cpp similarity index 58% rename from src/fallocate.cpp rename to src/fuse_fallocate.cpp index a13a7c02..85f47399 100644 --- a/src/fallocate.cpp +++ b/src/fuse_fallocate.cpp @@ -14,43 +14,43 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include - #include "errno.hpp" #include "fileinfo.hpp" #include "fs_base_fallocate.hpp" -static -int -_fallocate(const int fd, - const int mode, - const off_t offset, - const off_t len) +#include + +namespace l { - int rv; + static + int + fallocate(const int fd_, + const int mode_, + const off_t offset_, + const off_t len_) + { + int rv; - rv = fs::fallocate(fd,mode,offset,len); + rv = fs::fallocate(fd_,mode_,offset_,len_); - return ((rv == -1) ? -errno : 0); + return ((rv == -1) ? -errno : 0); + } } -namespace mergerfs +namespace FUSE { - namespace fuse + int + fallocate(const char *fusepath_, + int mode_, + off_t offset_, + off_t len_, + fuse_file_info *ffi_) { - int - fallocate(const char *fusepath, - int mode, - off_t offset, - off_t len, - fuse_file_info *ffi) - { - FileInfo *fi = reinterpret_cast(ffi->fh); - - return _fallocate(fi->fd, - mode, - offset, - len); - } + FileInfo *fi = reinterpret_cast(ffi_->fh); + + return l::fallocate(fi->fd, + mode_, + offset_, + len_); } } diff --git a/src/fuse_fallocate.hpp b/src/fuse_fallocate.hpp new file mode 100644 index 00000000..fc05306a --- /dev/null +++ b/src/fuse_fallocate.hpp @@ -0,0 +1,27 @@ +/* + Copyright (c) 2016, Antonio SJ Musumeci + + 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 + +namespace FUSE +{ + int + fallocate(const char *fusepath_, + int mode_, + off_t offset_, + off_t len_, + fuse_file_info *ffi_); +} diff --git a/src/fgetattr.cpp b/src/fuse_fgetattr.cpp similarity index 68% rename from src/fgetattr.cpp rename to src/fuse_fgetattr.cpp index 05186803..e4c5c176 100644 --- a/src/fgetattr.cpp +++ b/src/fuse_fgetattr.cpp @@ -14,41 +14,42 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include - #include "errno.hpp" #include "fileinfo.hpp" #include "fs_base_stat.hpp" #include "fs_inode.hpp" -static -int -_fgetattr(const int fd, - struct stat &st) +#include + +namespace l { - int rv; + static + int + fgetattr(const int fd_, + struct stat *st_) + { + int rv; - rv = fs::fstat(fd,st); - if(rv == -1) - return -errno; + rv = fs::fstat(fd_,st_); + if(rv == -1) + return -errno; - fs::inode::recompute(st); + fs::inode::recompute(st_); - return 0; + return 0; + } } -namespace mergerfs +namespace FUSE { - namespace fuse + int + fgetattr(const char *fusepath_, + struct stat *st_, + fuse_file_info *ffi_) { - int - fgetattr(const char *fusepath, - struct stat *st, - fuse_file_info *ffi) - { - FileInfo *fi = reinterpret_cast(ffi->fh); - - return ::_fgetattr(fi->fd,*st); - } + FileInfo *fi = reinterpret_cast(ffi_->fh); + + return l::fgetattr(fi->fd,st_); } } + diff --git a/src/ftruncate.hpp b/src/fuse_fgetattr.hpp similarity index 84% rename from src/ftruncate.hpp rename to src/fuse_fgetattr.hpp index 92db5db7..0a9ae76f 100644 --- a/src/ftruncate.hpp +++ b/src/fuse_fgetattr.hpp @@ -18,16 +18,14 @@ #include +#include #include #include -namespace mergerfs +namespace FUSE { - namespace fuse - { - int - ftruncate(const char *fusepath, - off_t size, - fuse_file_info *fi); - } + int + fgetattr(const char *fusepath_, + struct stat *st_, + fuse_file_info *ffi_); } diff --git a/src/flock.cpp b/src/fuse_flock.cpp similarity index 70% rename from src/flock.cpp rename to src/fuse_flock.cpp index ba034b86..8361c4d8 100644 --- a/src/flock.cpp +++ b/src/fuse_flock.cpp @@ -14,36 +14,36 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include - #include "errno.hpp" #include "fileinfo.hpp" #include "fs_base_flock.hpp" -static -int -_flock(const int fd, - const int operation) +#include + +namespace l { - int rv; + static + int + flock(const int fd_, + const int operation_) + { + int rv; - rv = fs::flock(fd,operation); + rv = fs::flock(fd_,operation_); - return ((rv == -1) ? -errno : 0); + return ((rv == -1) ? -errno : 0); + } } -namespace mergerfs +namespace FUSE { - namespace fuse + int + flock(const char *fusepath_, + fuse_file_info *ffi_, + int op_) { - int - flock(const char *fusepath, - fuse_file_info *ffi, - int op) - { - FileInfo* fi = reinterpret_cast(ffi->fh); - - return _flock(fi->fd,op); - } + FileInfo* fi = reinterpret_cast(ffi_->fh); + + return l::flock(fi->fd,op_); } } diff --git a/src/open.hpp b/src/fuse_flock.hpp similarity index 87% rename from src/open.hpp rename to src/fuse_flock.hpp index 3950e4fc..fdf12f45 100644 --- a/src/open.hpp +++ b/src/fuse_flock.hpp @@ -18,12 +18,10 @@ #include -namespace mergerfs +namespace FUSE { - namespace fuse - { - int - open(const char *fusepath, - fuse_file_info *ffi); - } + int + flock(const char *fusepath_, + fuse_file_info *ffi_, + int op_); } diff --git a/src/flush.cpp b/src/fuse_flush.cpp similarity index 71% rename from src/flush.cpp rename to src/fuse_flush.cpp index e2062d12..7d9067d1 100644 --- a/src/flush.cpp +++ b/src/fuse_flush.cpp @@ -14,39 +14,39 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include - #include "errno.hpp" #include "fileinfo.hpp" #include "fs_base_close.hpp" #include "fs_base_dup.hpp" -static -int -_flush(const int fd) +#include + +namespace l { - int rv; + static + int + flush(const int fd_) + { + int rv; - rv = fs::dup(fd); - if(rv == -1) - errno = EIO; - else - rv = fs::close(rv); + rv = fs::dup(fd_); + if(rv == -1) + errno = EIO; + else + rv = fs::close(rv); - return ((rv == -1) ? -errno : 0); + return ((rv == -1) ? -errno : 0); + } } -namespace mergerfs +namespace FUSE { - namespace fuse + int + flush(const char *fusepath_, + fuse_file_info *ffi_) { - int - flush(const char *fusepath, - fuse_file_info *ffi) - { - FileInfo *fi = reinterpret_cast(ffi->fh); - - return ::_flush(fi->fd); - } + FileInfo *fi = reinterpret_cast(ffi_->fh); + + return l::flush(fi->fd); } } diff --git a/src/fuse_flush.hpp b/src/fuse_flush.hpp new file mode 100644 index 00000000..8b99899e --- /dev/null +++ b/src/fuse_flush.hpp @@ -0,0 +1,26 @@ +/* + Copyright (c) 2016, Antonio SJ Musumeci + + 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 + +namespace FUSE +{ + int + flush(const char *path_, + fuse_file_info *ffi_); +} diff --git a/src/fsync.cpp b/src/fuse_fsync.cpp similarity index 67% rename from src/fsync.cpp rename to src/fuse_fsync.cpp index 03d45b0b..fb28b0a0 100644 --- a/src/fsync.cpp +++ b/src/fuse_fsync.cpp @@ -14,41 +14,41 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "errno.hpp" +#include "fileinfo.hpp" +#include "fs_base_fsync.hpp" + #include #include #include -#include "errno.hpp" -#include "fileinfo.hpp" -#include "fs_base_fsync.hpp" - -static -int -_fsync(const int fd, - const int isdatasync) +namespace l { - int rv; + static + int + fsync(const int fd_, + const int isdatasync_) + { + int rv; - rv = (isdatasync ? - fs::fdatasync(fd) : - fs::fsync(fd)); + rv = (isdatasync_ ? + fs::fdatasync(fd_) : + fs::fsync(fd_)); - return ((rv == -1) ? -errno : 0); + return ((rv == -1) ? -errno : 0); + } } -namespace mergerfs +namespace FUSE { - namespace fuse + int + fsync(const char *fusepath_, + int isdatasync_, + fuse_file_info *ffi_) { - int - fsync(const char *fusepath, - int isdatasync, - fuse_file_info *ffi) - { - FileInfo *fi = reinterpret_cast(ffi->fh); - - return ::_fsync(fi->fd,isdatasync); - } + FileInfo *fi = reinterpret_cast(ffi_->fh); + + return l::fsync(fi->fd,isdatasync_); } } diff --git a/src/releasedir.hpp b/src/fuse_fsync.hpp similarity index 86% rename from src/releasedir.hpp rename to src/fuse_fsync.hpp index 14c4cf59..96766daa 100644 --- a/src/releasedir.hpp +++ b/src/fuse_fsync.hpp @@ -18,12 +18,10 @@ #include -namespace mergerfs +namespace FUSE { - namespace fuse - { - int - releasedir(const char *fusepath, - fuse_file_info *ffi); - } + int + fsync(const char *fusepath_, + int isdatasync_, + fuse_file_info *ffi_); } diff --git a/src/fsyncdir.cpp b/src/fuse_fsyncdir.cpp similarity index 68% rename from src/fsyncdir.cpp rename to src/fuse_fsyncdir.cpp index 0f5b9248..333ecdd7 100644 --- a/src/fsyncdir.cpp +++ b/src/fuse_fsyncdir.cpp @@ -14,40 +14,40 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "errno.hpp" +#include "dirinfo.hpp" +#include "fs_base_fsync.hpp" + #include #include #include -#include "errno.hpp" -#include "dirinfo.hpp" -#include "fs_base_fsync.hpp" - -static -int -_fsyncdir(const DirInfo *di, - const int isdatasync) +namespace l { - int rv; + static + int + fsyncdir(const DirInfo *di_, + const int isdatasync_) + { + int rv; - rv = -1; - errno = ENOSYS; + rv = -1; + errno = ENOSYS; - return ((rv == -1) ? -errno : 0); + return ((rv == -1) ? -errno : 0); + } } -namespace mergerfs +namespace FUSE { - namespace fuse + int + fsyncdir(const char *fusepath_, + int isdatasync_, + fuse_file_info *ffi_) { - int - fsyncdir(const char *fusepath, - int isdatasync, - fuse_file_info *ffi) - { - DirInfo *di = reinterpret_cast(ffi->fh); - - return ::_fsyncdir(di,isdatasync); - } + DirInfo *di = reinterpret_cast(ffi_->fh); + + return l::fsyncdir(di,isdatasync_); } } diff --git a/src/fsyncdir.hpp b/src/fuse_fsyncdir.hpp similarity index 83% rename from src/fsyncdir.hpp rename to src/fuse_fsyncdir.hpp index 17fa4cc0..2f135416 100644 --- a/src/fsyncdir.hpp +++ b/src/fuse_fsyncdir.hpp @@ -18,13 +18,10 @@ #include -namespace mergerfs +namespace FUSE { - namespace fuse - { - int - fsyncdir(const char *fusepath, - int isdatasync, - fuse_file_info *ffi); - } + int + fsyncdir(const char *fusepath_, + int isdatasync_, + fuse_file_info *ffi_); } diff --git a/src/ftruncate.cpp b/src/fuse_ftruncate.cpp similarity index 68% rename from src/ftruncate.cpp rename to src/fuse_ftruncate.cpp index 920087a7..0706968d 100644 --- a/src/ftruncate.cpp +++ b/src/fuse_ftruncate.cpp @@ -14,36 +14,36 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include - #include "errno.hpp" #include "fileinfo.hpp" #include "fs_base_ftruncate.hpp" -static -int -_ftruncate(const int fd, - const off_t size) +#include + +namespace l { - int rv; + static + int + ftruncate(const int fd_, + const off_t size_) + { + int rv; - rv = fs::ftruncate(fd,size); + rv = fs::ftruncate(fd_,size_); - return ((rv == -1) ? -errno : 0); + return ((rv == -1) ? -errno : 0); + } } -namespace mergerfs +namespace FUSE { - namespace fuse + int + ftruncate(const char *fusepath_, + off_t size_, + fuse_file_info *ffi_) { - int - ftruncate(const char *fusepath, - off_t size, - fuse_file_info *ffi) - { - FileInfo *fi = reinterpret_cast(ffi->fh); - - return ::_ftruncate(fi->fd,size); - } + FileInfo *fi = reinterpret_cast(ffi_->fh); + + return l::ftruncate(fi->fd,size_); } } diff --git a/src/create.hpp b/src/fuse_ftruncate.hpp similarity index 84% rename from src/create.hpp rename to src/fuse_ftruncate.hpp index 6935c692..0cb23aba 100644 --- a/src/create.hpp +++ b/src/fuse_ftruncate.hpp @@ -19,14 +19,12 @@ #include #include +#include -namespace mergerfs +namespace FUSE { - namespace fuse - { - int - create(const char *fusepath, - mode_t mode, - fuse_file_info *ffi); - } + int + ftruncate(const char *fusepath_, + off_t size_, + fuse_file_info *ffi_); } diff --git a/src/fuse_getattr.cpp b/src/fuse_getattr.cpp new file mode 100644 index 00000000..9db004e2 --- /dev/null +++ b/src/fuse_getattr.cpp @@ -0,0 +1,117 @@ +/* + Copyright (c) 2016, Antonio SJ Musumeci + + 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 "config.hpp" +#include "errno.hpp" +#include "fs_base_stat.hpp" +#include "fs_inode.hpp" +#include "fs_path.hpp" +#include "rwlock.hpp" +#include "symlinkify.hpp" +#include "ugid.hpp" + +#include + +#include +#include + +using std::string; +using std::vector; + +namespace l +{ + static + int + getattr_controlfile(struct stat *st_) + { + static const uid_t uid = ::getuid(); + static const gid_t gid = ::getgid(); + static const time_t now = ::time(NULL); + + st_->st_dev = 0; + st_->st_ino = fs::inode::MAGIC; + st_->st_mode = (S_IFREG|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH); + st_->st_nlink = 1; + st_->st_uid = uid; + st_->st_gid = gid; + st_->st_rdev = 0; + st_->st_size = 0; + st_->st_blksize = 512; + st_->st_blocks = 0; + st_->st_atime = now; + st_->st_mtime = now; + st_->st_ctime = now; + + return 0; + } + + static + int + getattr(Policy::Func::Search searchFunc_, + const Branches &branches_, + const uint64_t minfreespace_, + const char *fusepath_, + struct stat *st_, + const bool symlinkify_, + const time_t symlinkify_timeout_) + { + int rv; + string fullpath; + vector basepaths; + + rv = searchFunc_(branches_,fusepath_,minfreespace_,basepaths); + if(rv == -1) + return -errno; + + fullpath = fs::path::make(basepaths[0],fusepath_); + + rv = fs::lstat(fullpath,st_); + if(rv == -1) + return -errno; + + if(symlinkify_ && symlinkify::can_be_symlink(*st_,symlinkify_timeout_)) + st_->st_mode = symlinkify::convert(st_->st_mode); + + fs::inode::recompute(st_); + + return 0; + } +} + +namespace FUSE +{ + int + getattr(const char *fusepath_, + struct stat *st_) + { + const fuse_context *fc = fuse_get_context(); + const Config &config = Config::get(fc); + + if(fusepath_ == config.controlfile) + return l::getattr_controlfile(st_); + + const ugid::Set ugid(fc->uid,fc->gid); + const rwlock::ReadGuard readlock(&config.branches_lock); + + return l::getattr(config.getattr, + config.branches, + config.minfreespace, + fusepath_, + st_, + config.symlinkify, + config.symlinkify_timeout); + } +} diff --git a/src/getattr.hpp b/src/fuse_getattr.hpp similarity index 88% rename from src/getattr.hpp rename to src/fuse_getattr.hpp index 819bc61c..17430f1d 100644 --- a/src/getattr.hpp +++ b/src/fuse_getattr.hpp @@ -20,12 +20,9 @@ #include #include -namespace mergerfs +namespace FUSE { - namespace fuse - { - int - getattr(const char *fusepath, - struct stat *buf); - } + int + getattr(const char *fusepath_, + struct stat *buf_); } diff --git a/src/fuse_getxattr.cpp b/src/fuse_getxattr.cpp new file mode 100644 index 00000000..dcd3be97 --- /dev/null +++ b/src/fuse_getxattr.cpp @@ -0,0 +1,467 @@ +/* + Copyright (c) 2018, Antonio SJ Musumeci + + 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 "config.hpp" +#include "errno.hpp" +#include "fs_base_getxattr.hpp" +#include "fs_path.hpp" +#include "fs_statvfs_cache.hpp" +#include "rwlock.hpp" +#include "str.hpp" +#include "ugid.hpp" +#include "version.hpp" + +#include + +#include +#include +#include +#include +#include + +#include +#include + +static const char SECURITY_CAPABILITY[] = "security.capability"; + +using std::string; +using std::vector; +using std::set; + +namespace l +{ + static + bool + is_attrname_security_capability(const char *attrname_) + { + 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 + void + getxattr_controlfile_fusefunc_policy(const Config &config_, + const string &attr_, + string &attrvalue_) + { + FuseFunc fusefunc; + + fusefunc = FuseFunc::find(attr_); + if(fusefunc != FuseFunc::invalid) + attrvalue_ = (std::string)*config_.policies[(FuseFunc::Enum::Type)*fusefunc]; + } + + static + void + getxattr_controlfile_category_policy(const Config &config_, + const string &attr_, + string &attrvalue_) + { + Category cat; + + cat = Category::find(attr_); + if(cat != Category::invalid) + { + vector policies; + for(int i = FuseFunc::Enum::BEGIN; i < FuseFunc::Enum::END; i++) + { + if(cat == (Category::Enum::Type)*FuseFunc::fusefuncs[i]) + policies.push_back(*config_.policies[i]); + } + + std::sort(policies.begin(),policies.end()); + policies.erase(std::unique(policies.begin(),policies.end()), + policies.end()); + attrvalue_ = str::join(policies,','); + } + } + + static + void + getxattr_controlfile_srcmounts(const Config &config_, + string &attrvalue_) + { + attrvalue_ = config_.branches.to_string(); + } + + static + void + getxattr_controlfile_branches(const Config &config_, + string &attrvalue_) + { + attrvalue_ = config_.branches.to_string(true); + } + + static + void + getxattr_controlfile_uint64_t(const uint64_t uint_, + string &attrvalue_) + { + std::ostringstream os; + + os << uint_; + + attrvalue_ = os.str(); + } + + static + void + getxattr_controlfile_time_t(const time_t time, + string &attrvalue) + { + std::ostringstream os; + + os << time; + + attrvalue = os.str(); + } + + static + void + getxattr_controlfile_bool(const bool boolvalue, + string &attrvalue) + { + attrvalue = (boolvalue ? "true" : "false"); + } + + static + void + getxattr_controlfile_errno(const int errno_, + string &attrvalue) + { + switch(errno_) + { + case 0: + attrvalue = "passthrough"; + break; + case ENOATTR: + attrvalue = "noattr"; + break; + case ENOSYS: + attrvalue = "nosys"; + break; + default: + attrvalue = "ERROR"; + break; + } + } + + static + void + getxattr_controlfile_statfs(const Config::StatFS::Enum enum_, + string &attrvalue_) + { + switch(enum_) + { + case Config::StatFS::BASE: + attrvalue_ = "base"; + break; + case Config::StatFS::FULL: + attrvalue_ = "full"; + break; + default: + attrvalue_ = "ERROR"; + break; + } + } + + static + void + getxattr_controlfile_statfsignore(const Config::StatFSIgnore::Enum enum_, + string &attrvalue_) + { + switch(enum_) + { + case Config::StatFSIgnore::NONE: + attrvalue_ = "none"; + break; + case Config::StatFSIgnore::RO: + attrvalue_ = "ro"; + break; + case Config::StatFSIgnore::NC: + attrvalue_ = "nc"; + break; + default: + attrvalue_ = "ERROR"; + break; + } + } + + static + void + getxattr_controlfile_policies(const Config &config, + string &attrvalue) + { + size_t i = Policy::Enum::begin(); + + attrvalue = (string)Policy::policies[i]; + for(i++; i < Policy::Enum::end(); i++) + attrvalue += ',' + (string)Policy::policies[i]; + } + + static + void + getxattr_controlfile_version(string &attrvalue) + { + attrvalue = MERGERFS_VERSION; + if(attrvalue.empty()) + attrvalue = "unknown_possible_problem_with_build"; + } + + static + void + getxattr_pid(string &attrvalue) + { + int pid; + char buf[32]; + + pid = getpid(); + snprintf(buf,sizeof(buf),"%d",pid); + + attrvalue = buf; + } + + static + int + getxattr_controlfile(const Config &config, + const char *attrname, + char *buf, + const size_t count) + { + size_t len; + string attrvalue; + vector attr; + + str::split(attr,attrname,'.'); + if((attr[0] != "user") || (attr[1] != "mergerfs")) + return -ENOATTR; + + switch(attr.size()) + { + case 3: + if(attr[2] == "srcmounts") + l::getxattr_controlfile_srcmounts(config,attrvalue); + else if(attr[2] == "branches") + l::getxattr_controlfile_branches(config,attrvalue); + else if(attr[2] == "minfreespace") + l::getxattr_controlfile_uint64_t(config.minfreespace,attrvalue); + else if(attr[2] == "moveonenospc") + l::getxattr_controlfile_bool(config.moveonenospc,attrvalue); + else if(attr[2] == "dropcacheonclose") + l::getxattr_controlfile_bool(config.dropcacheonclose,attrvalue); + else if(attr[2] == "symlinkify") + l::getxattr_controlfile_bool(config.symlinkify,attrvalue); + else if(attr[2] == "symlinkify_timeout") + l::getxattr_controlfile_time_t(config.symlinkify_timeout,attrvalue); + else if(attr[2] == "nullrw") + l::getxattr_controlfile_bool(config.nullrw,attrvalue); + else if(attr[2] == "ignorepponrename") + l::getxattr_controlfile_bool(config.ignorepponrename,attrvalue); + else if(attr[2] == "security_capability") + l::getxattr_controlfile_bool(config.security_capability,attrvalue); + else if(attr[2] == "xattr") + l::getxattr_controlfile_errno(config.xattr,attrvalue); + else if(attr[2] == "link_cow") + l::getxattr_controlfile_bool(config.link_cow,attrvalue); + else if(attr[2] == "statfs") + l::getxattr_controlfile_statfs(config.statfs,attrvalue); + else if(attr[2] == "statfs_ignore") + l::getxattr_controlfile_statfsignore(config.statfs_ignore,attrvalue); + else if(attr[2] == "policies") + l::getxattr_controlfile_policies(config,attrvalue); + else if(attr[2] == "version") + l::getxattr_controlfile_version(attrvalue); + else if(attr[2] == "pid") + l::getxattr_pid(attrvalue); + else if(attr[2] == "direct_io") + l::getxattr_controlfile_bool(config.direct_io,attrvalue); + break; + + case 4: + if(attr[2] == "category") + l::getxattr_controlfile_category_policy(config,attr[3],attrvalue); + else if(attr[2] == "func") + l::getxattr_controlfile_fusefunc_policy(config,attr[3],attrvalue); + else if((attr[2] == "cache") && (attr[3] == "open")) + l::getxattr_controlfile_uint64_t(config.open_cache.timeout,attrvalue); + else if((attr[2] == "cache") && (attr[3] == "statfs")) + l::getxattr_controlfile_uint64_t(fs::statvfs_cache_timeout(),attrvalue); + break; + } + + if(attrvalue.empty()) + return -ENOATTR; + + len = attrvalue.size(); + + if(count == 0) + return len; + + if(count < len) + return -ERANGE; + + memcpy(buf,attrvalue.c_str(),len); + + return (int)len; + } + + 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 &branches_, + const char *fusepath, + char *buf, + const size_t count) + { + string concated; + vector paths; + vector 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) + { + vector attr; + + str::split(attr,attrname,'.'); + + 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(Policy::Func::Search searchFunc, + const Branches &branches_, + const size_t minfreespace, + const char *fusepath, + const char *attrname, + char *buf, + const size_t count) + { + int rv; + string fullpath; + vector basepaths; + + rv = searchFunc(branches_,fusepath,minfreespace,basepaths); + if(rv == -1) + return -errno; + + fullpath = fs::path::make(basepaths[0],fusepath); + + if(str::isprefix(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 +{ + int + getxattr(const char *fusepath, + const char *attrname, + char *buf, + size_t count) + { + const fuse_context *fc = fuse_get_context(); + const Config &config = Config::get(fc); + + if(fusepath == config.controlfile) + return l::getxattr_controlfile(config, + attrname, + buf, + count); + + if((config.security_capability == false) && + l::is_attrname_security_capability(attrname)) + return -ENOATTR; + + if(config.xattr) + return -config.xattr; + + const ugid::Set ugid(fc->uid,fc->gid); + const rwlock::ReadGuard readlock(&config.branches_lock); + + return l::getxattr(config.getxattr, + config.branches, + config.minfreespace, + fusepath, + attrname, + buf, + count); + } +} diff --git a/src/chown.hpp b/src/fuse_getxattr.hpp similarity index 84% rename from src/chown.hpp rename to src/fuse_getxattr.hpp index 4b56c31b..854e26e8 100644 --- a/src/chown.hpp +++ b/src/fuse_getxattr.hpp @@ -16,13 +16,11 @@ #pragma once -namespace mergerfs +namespace FUSE { - namespace fuse - { - int - chown(const char *fusepath, - uid_t uid, - gid_t gid); - } + int + getxattr(const char *fusepath_, + const char *attrname_, + char *buf_, + size_t count_); } diff --git a/src/init.cpp b/src/fuse_init.cpp similarity index 70% rename from src/init.cpp rename to src/fuse_init.cpp index 525e450d..ea3935e5 100644 --- a/src/init.cpp +++ b/src/fuse_init.cpp @@ -14,27 +14,24 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include - #include "config.hpp" #include "ugid.hpp" -namespace mergerfs +#include + +namespace FUSE { - namespace fuse + void * + init(fuse_conn_info *conn_) { - void * - init(fuse_conn_info *conn) - { - ugid::init(); + ugid::init(); - conn->want |= FUSE_CAP_ASYNC_READ; - conn->want |= FUSE_CAP_ATOMIC_O_TRUNC; - conn->want |= FUSE_CAP_BIG_WRITES; - conn->want |= FUSE_CAP_DONT_MASK; - conn->want |= FUSE_CAP_IOCTL_DIR; + conn_->want |= FUSE_CAP_ASYNC_READ; + conn_->want |= FUSE_CAP_ATOMIC_O_TRUNC; + conn_->want |= FUSE_CAP_BIG_WRITES; + conn_->want |= FUSE_CAP_DONT_MASK; + conn_->want |= FUSE_CAP_IOCTL_DIR; - return &Config::get_writable(); - } + return &Config::get_writable(); } } diff --git a/src/init.hpp b/src/fuse_init.hpp similarity index 90% rename from src/init.hpp rename to src/fuse_init.hpp index 64bc0cc3..ea8f0d39 100644 --- a/src/init.hpp +++ b/src/fuse_init.hpp @@ -16,11 +16,10 @@ #pragma once -namespace mergerfs +#include + +namespace FUSE { - namespace fuse - { - void * - init(fuse_conn_info *conn); - } + void * + init(fuse_conn_info *conn_); } diff --git a/src/ioctl.cpp b/src/fuse_ioctl.cpp similarity index 76% rename from src/ioctl.cpp rename to src/fuse_ioctl.cpp index 8985dd13..084a7b14 100644 --- a/src/ioctl.cpp +++ b/src/fuse_ioctl.cpp @@ -34,9 +34,8 @@ using std::string; using std::vector; -using namespace mergerfs; -namespace local +namespace l { static int @@ -59,7 +58,7 @@ namespace local { FileInfo *fi = reinterpret_cast(ffi_->fh); - return local::ioctl(fi->fd,cmd_,data_); + return l::ioctl(fi->fd,cmd_,data_); } @@ -85,14 +84,14 @@ namespace local if(rv == -1) return -errno; - fs::path::make(basepaths[0],fusepath_,fullpath); + fullpath = fs::path::make(basepaths[0],fusepath_); const int flags = O_RDONLY | O_NOATIME | O_NONBLOCK; fd = fs::open(fullpath,flags); if(fd == -1) return -errno; - rv = local::ioctl(fd,cmd_,data_); + rv = l::ioctl(fd,cmd_,data_); fs::close(fd); @@ -111,31 +110,29 @@ namespace local const ugid::Set ugid(fc->uid,fc->gid); const rwlock::ReadGuard readlock(&config.branches_lock); - return local::ioctl_dir_base(config.open, - config.branches, - config.minfreespace, - di->fusepath.c_str(), - cmd_, - data_); + return l::ioctl_dir_base(config.open, + config.branches, + config.minfreespace, + di->fusepath.c_str(), + cmd_, + data_); } } -namespace mergerfs +namespace FUSE { - namespace fuse + int + ioctl(const char *fusepath_, + int cmd_, + void *arg_, + fuse_file_info *ffi_, + unsigned int flags_, + void *data_) { - int - ioctl(const char *fusepath_, - int cmd_, - void *arg_, - fuse_file_info *ffi_, - unsigned int flags_, - void *data_) - { - if(flags_ & FUSE_IOCTL_DIR) - return local::ioctl_dir(ffi_,cmd_,data_); - - return local::ioctl_file(ffi_,cmd_,data_); - } + if(flags_ & FUSE_IOCTL_DIR) + return l::ioctl_dir(ffi_,cmd_,data_); + + + return l::ioctl_file(ffi_,cmd_,data_); } } diff --git a/src/fsync.hpp b/src/fuse_ioctl.hpp similarity index 79% rename from src/fsync.hpp rename to src/fuse_ioctl.hpp index b59e85e3..ec540cb8 100644 --- a/src/fsync.hpp +++ b/src/fuse_ioctl.hpp @@ -18,13 +18,13 @@ #include -namespace mergerfs +namespace FUSE { - namespace fuse - { - int - fsync(const char *fusepath, - int isdatasync, - fuse_file_info *fi); - } + int + ioctl(const char *fusepath_, + int cmd_, + void *arg_, + fuse_file_info *ffi_, + unsigned int flags_, + void *data_); } diff --git a/src/fuse_link.cpp b/src/fuse_link.cpp new file mode 100644 index 00000000..9117975f --- /dev/null +++ b/src/fuse_link.cpp @@ -0,0 +1,249 @@ +/* + Copyright (c) 2016, Antonio SJ Musumeci + + 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 "config.hpp" +#include "errno.hpp" +#include "fs_base_link.hpp" +#include "fs_clonepath.hpp" +#include "fs_path.hpp" +#include "rv.hpp" +#include "rwlock.hpp" +#include "ugid.hpp" + +#include + +#include +#include + +using std::string; +using std::vector; + +namespace l +{ + static + int + link_create_path_core(const string &oldbasepath_, + const string &newbasepath_, + const char *oldfusepath_, + const char *newfusepath_, + const int error_) + { + int rv; + string oldfullpath; + string newfullpath; + + oldfullpath = fs::path::make(&oldbasepath_,oldfusepath_); + newfullpath = fs::path::make(&oldbasepath_,newfusepath_); + + rv = fs::link(oldfullpath,newfullpath); + + return error::calc(rv,error_,errno); + } + + static + int + link_create_path_loop(const vector &oldbasepaths_, + const string &newbasepath_, + const char *oldfusepath_, + const char *newfusepath_, + const string &newfusedirpath_) + { + int rv; + int error; + + error = -1; + for(size_t i = 0, ei = oldbasepaths_.size(); i != ei; i++) + { + rv = fs::clonepath_as_root(newbasepath_,*oldbasepaths_[i],newfusedirpath_); + if(rv == -1) + error = error::calc(rv,error,errno); + else + error = l::link_create_path_core(*oldbasepaths_[i],newbasepath_, + oldfusepath_,newfusepath_, + error); + } + + return -error; + } + + static + int + link_create_path(Policy::Func::Search searchFunc_, + Policy::Func::Action actionFunc_, + const Branches &branches_, + const uint64_t minfreespace_, + const char *oldfusepath_, + const char *newfusepath_) + { + int rv; + string newfusedirpath; + vector oldbasepaths; + vector newbasepaths; + + rv = actionFunc_(branches_,oldfusepath_,minfreespace_,oldbasepaths); + if(rv == -1) + return -errno; + + newfusedirpath = fs::path::dirname(newfusepath_); + + rv = searchFunc_(branches_,newfusedirpath,minfreespace_,newbasepaths); + if(rv == -1) + return -errno; + + return l::link_create_path_loop(oldbasepaths,*newbasepaths[0], + oldfusepath_,newfusepath_, + newfusedirpath); + } + + static + int + clonepath_if_would_create(Policy::Func::Search searchFunc_, + Policy::Func::Create createFunc_, + const Branches &branches_, + const uint64_t minfreespace_, + const string &oldbasepath_, + const char *oldfusepath_, + const char *newfusepath_) + { + int rv; + string newfusedirpath; + vector newbasepath; + + newfusedirpath = fs::path::dirname(newfusepath_); + + rv = createFunc_(branches_,newfusedirpath,minfreespace_,newbasepath); + if(rv == -1) + return -1; + + if(oldbasepath_ != *newbasepath[0]) + return (errno=EXDEV,-1); + + rv = searchFunc_(branches_,newfusedirpath,minfreespace_,newbasepath); + if(rv == -1) + return -1; + + return fs::clonepath_as_root(*newbasepath[0],oldbasepath_,newfusedirpath); + } + + static + int + link_preserve_path_core(Policy::Func::Search searchFunc_, + Policy::Func::Create createFunc_, + const Branches &branches_, + const uint64_t minfreespace_, + const string &oldbasepath_, + const char *oldfusepath_, + const char *newfusepath_, + const int error_) + { + int rv; + string oldfullpath; + string newfullpath; + + oldfullpath = fs::path::make(&oldbasepath_,oldfusepath_); + newfullpath = fs::path::make(&oldbasepath_,newfusepath_); + + rv = fs::link(oldfullpath,newfullpath); + if((rv == -1) && (errno == ENOENT)) + { + rv = l::clonepath_if_would_create(searchFunc_,createFunc_, + branches_,minfreespace_, + oldbasepath_, + oldfusepath_,newfusepath_); + if(rv != -1) + rv = fs::link(oldfullpath,newfullpath); + } + + return error::calc(rv,error_,errno); + } + + static + int + link_preserve_path_loop(Policy::Func::Search searchFunc_, + Policy::Func::Create createFunc_, + const Branches &branches_, + const uint64_t minfreespace_, + const char *oldfusepath_, + const char *newfusepath_, + const vector &oldbasepaths_) + { + int error; + + error = -1; + for(size_t i = 0, ei = oldbasepaths_.size(); i != ei; i++) + { + error = l::link_preserve_path_core(searchFunc_,createFunc_, + branches_,minfreespace_, + *oldbasepaths_[i], + oldfusepath_,newfusepath_, + error); + } + + return -error; + } + + static + int + link_preserve_path(Policy::Func::Search searchFunc_, + Policy::Func::Action actionFunc_, + Policy::Func::Create createFunc_, + const Branches &branches_, + const uint64_t minfreespace_, + const char *oldfusepath_, + const char *newfusepath_) + { + int rv; + vector oldbasepaths; + + rv = actionFunc_(branches_,oldfusepath_,minfreespace_,oldbasepaths); + if(rv == -1) + return -errno; + + return l::link_preserve_path_loop(searchFunc_,createFunc_, + branches_,minfreespace_, + oldfusepath_,newfusepath_, + oldbasepaths); + } +} + +namespace FUSE +{ + int + link(const char *from_, + const char *to_) + { + const fuse_context *fc = fuse_get_context(); + const Config &config = Config::get(fc); + const ugid::Set ugid(fc->uid,fc->gid); + const rwlock::ReadGuard readlock(&config.branches_lock); + + if(config.create->path_preserving() && !config.ignorepponrename) + return l::link_preserve_path(config.getattr, + config.link, + config.create, + config.branches, + config.minfreespace, + from_, + to_); + + return l::link_create_path(config.link, + config.create, + config.branches, + config.minfreespace, + from_, + to_); + } +} diff --git a/src/fuse_link.hpp b/src/fuse_link.hpp new file mode 100644 index 00000000..843b752d --- /dev/null +++ b/src/fuse_link.hpp @@ -0,0 +1,24 @@ +/* + Copyright (c) 2016, Antonio SJ Musumeci + + 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 + +namespace FUSE +{ + int + link(const char *from_, + const char *to_); +} diff --git a/src/fuse_listxattr.cpp b/src/fuse_listxattr.cpp new file mode 100644 index 00000000..795b79ff --- /dev/null +++ b/src/fuse_listxattr.cpp @@ -0,0 +1,146 @@ +/* + Copyright (c) 2018, Antonio SJ Musumeci + + 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 "buildvector.hpp" +#include "category.hpp" +#include "config.hpp" +#include "errno.hpp" +#include "fs_base_listxattr.hpp" +#include "fs_path.hpp" +#include "rwlock.hpp" +#include "ugid.hpp" +#include "xattr.hpp" + +#include + +#include +#include + +#include + +using std::string; +using std::vector; + +namespace l +{ + static + int + listxattr_controlfile(char *list_, + const size_t size_) + { + string xattrs; + const vector strs = + buildvector + ("user.mergerfs.branches") + ("user.mergerfs.cache.open") + ("user.mergerfs.cache.statfs") + ("user.mergerfs.direct_io") + ("user.mergerfs.dropcacheonclose") + ("user.mergerfs.ignorepponrename") + ("user.mergerfs.link_cow") + ("user.mergerfs.minfreespace") + ("user.mergerfs.moveonenospc") + ("user.mergerfs.nullrw") + ("user.mergerfs.pid") + ("user.mergerfs.policies") + ("user.mergerfs.security_capability") + ("user.mergerfs.srcmounts") + ("user.mergerfs.statfs") + ("user.mergerfs.statfs_ignore") + ("user.mergerfs.symlinkify") + ("user.mergerfs.symlinkify_timeout") + ("user.mergerfs.version") + ("user.mergerfs.xattr") + ; + + xattrs.reserve(1024); + for(size_t i = 0; i < strs.size(); i++) + xattrs += (strs[i] + '\0'); + for(size_t i = Category::Enum::BEGIN; i < Category::Enum::END; i++) + xattrs += ("user.mergerfs.category." + (std::string)*Category::categories[i] + '\0'); + for(size_t i = FuseFunc::Enum::BEGIN; i < FuseFunc::Enum::END; i++) + xattrs += ("user.mergerfs.func." + (std::string)*FuseFunc::fusefuncs[i] + '\0'); + + if(size_ == 0) + return xattrs.size(); + + if(size_ < xattrs.size()) + return -ERANGE; + + memcpy(list_,xattrs.c_str(),xattrs.size()); + + return xattrs.size(); + } + + static + int + listxattr(Policy::Func::Search searchFunc_, + const Branches &branches_, + const uint64_t minfreespace_, + const char *fusepath_, + char *list_, + const size_t size_) + { + int rv; + string fullpath; + vector basepaths; + + rv = searchFunc_(branches_,fusepath_,minfreespace_,basepaths); + if(rv == -1) + return -errno; + + fullpath = fs::path::make(basepaths[0],fusepath_); + + rv = fs::llistxattr(fullpath,list_,size_); + + return ((rv == -1) ? -errno : rv); + } +} + +namespace FUSE +{ + int + listxattr(const char *fusepath_, + char *list_, + size_t size_) + { + const fuse_context *fc = fuse_get_context(); + const Config &config = Config::get(fc); + + if(fusepath_ == config.controlfile) + return l::listxattr_controlfile(list_,size_); + + switch(config.xattr) + { + case 0: + break; + case ENOATTR: + return 0; + default: + return -config.xattr; + } + + const ugid::Set ugid(fc->uid,fc->gid); + const rwlock::ReadGuard readlock(&config.branches_lock); + + return l::listxattr(config.listxattr, + config.branches, + config.minfreespace, + fusepath_, + list_, + size_); + } +} diff --git a/src/fuse_listxattr.hpp b/src/fuse_listxattr.hpp new file mode 100644 index 00000000..3ce0aec8 --- /dev/null +++ b/src/fuse_listxattr.hpp @@ -0,0 +1,25 @@ +/* + Copyright (c) 2016, Antonio SJ Musumeci + + 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 + +namespace FUSE +{ + int + listxattr(const char *fusepath_, + char *buf_, + size_t count_); +} diff --git a/src/fuse_mkdir.cpp b/src/fuse_mkdir.cpp new file mode 100644 index 00000000..2a7c8dd9 --- /dev/null +++ b/src/fuse_mkdir.cpp @@ -0,0 +1,149 @@ +/* + Copyright (c) 2016, Antonio SJ Musumeci + + 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 + +#include +#include + +#include "config.hpp" +#include "errno.hpp" +#include "fs_acl.hpp" +#include "fs_base_mkdir.hpp" +#include "fs_clonepath.hpp" +#include "fs_path.hpp" +#include "rv.hpp" +#include "rwlock.hpp" +#include "ugid.hpp" + +using std::string; +using std::vector; + +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 vector &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(Policy::Func::Search searchFunc_, + Policy::Func::Create createFunc_, + const Branches &branches_, + const uint64_t minfreespace_, + const char *fusepath_, + const mode_t mode_, + const mode_t umask_) + { + int rv; + string fusedirpath; + vector createpaths; + vector existingpaths; + + fusedirpath = fs::path::dirname(fusepath_); + + rv = searchFunc_(branches_,fusedirpath,minfreespace_,existingpaths); + if(rv == -1) + return -errno; + + rv = createFunc_(branches_,fusedirpath,minfreespace_,createpaths); + if(rv == -1) + return -errno; + + return l::mkdir_loop(*existingpaths[0], + createpaths, + fusepath_, + fusedirpath, + mode_, + umask_); + } +} + +namespace FUSE +{ + int + mkdir(const char *fusepath_, + mode_t mode_) + { + const fuse_context *fc = fuse_get_context(); + const Config &config = Config::get(fc); + const ugid::Set ugid(fc->uid,fc->gid); + const rwlock::ReadGuard readlock(&config.branches_lock); + + return l::mkdir(config.getattr, + config.mkdir, + config.branches, + config.minfreespace, + fusepath_, + mode_, + fc->umask); + } +} diff --git a/src/fuse_mkdir.hpp b/src/fuse_mkdir.hpp new file mode 100644 index 00000000..4b8ee8a9 --- /dev/null +++ b/src/fuse_mkdir.hpp @@ -0,0 +1,24 @@ +/* + Copyright (c) 2016, Antonio SJ Musumeci + + 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 + +namespace FUSE +{ + int + mkdir(const char *fusepath_, + mode_t mode_); +} diff --git a/src/fuse_mknod.cpp b/src/fuse_mknod.cpp new file mode 100644 index 00000000..14a30a45 --- /dev/null +++ b/src/fuse_mknod.cpp @@ -0,0 +1,151 @@ +/* + Copyright (c) 2016, Antonio SJ Musumeci + + 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 "config.hpp" +#include "errno.hpp" +#include "fs_acl.hpp" +#include "fs_base_mknod.hpp" +#include "fs_clonepath.hpp" +#include "fs_path.hpp" +#include "rv.hpp" +#include "rwlock.hpp" +#include "ugid.hpp" + +#include + +#include +#include + +using std::string; +using std::vector; + +namespace l +{ + static + inline + int + mknod_core(const string &fullpath_, + mode_t mode_, + const mode_t umask_, + const dev_t dev_) + { + if(!fs::acl::dir_has_defaults(fullpath_)) + mode_ &= ~umask_; + + return fs::mknod(fullpath_,mode_,dev_); + } + + static + int + mknod_loop_core(const string &createpath_, + const char *fusepath_, + const mode_t mode_, + const mode_t umask_, + const dev_t dev_, + const int error_) + { + int rv; + string fullpath; + + fullpath = fs::path::make(&createpath_,fusepath_); + + rv = l::mknod_core(fullpath,mode_,umask_,dev_); + + return error::calc(rv,error_,errno); + } + + static + int + mknod_loop(const string &existingpath_, + const vector &createpaths_, + const char *fusepath_, + const string &fusedirpath_, + const mode_t mode_, + const mode_t umask_, + const dev_t dev_) + { + 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::mknod_loop_core(*createpaths_[i], + fusepath_, + mode_,umask_,dev_,error); + } + + return -error; + } + + static + int + mknod(Policy::Func::Search searchFunc_, + Policy::Func::Create createFunc_, + const Branches &branches_, + const uint64_t minfreespace_, + const char *fusepath_, + const mode_t mode_, + const mode_t umask_, + const dev_t dev_) + { + int rv; + string fusedirpath; + vector createpaths; + vector existingpaths; + + fusedirpath = fs::path::dirname(fusepath_); + + rv = searchFunc_(branches_,fusedirpath,minfreespace_,existingpaths); + if(rv == -1) + return -errno; + + rv = createFunc_(branches_,fusedirpath,minfreespace_,createpaths); + if(rv == -1) + return -errno; + + return l::mknod_loop(*existingpaths[0],createpaths, + fusepath_,fusedirpath, + mode_,umask_,dev_); + } +} + +namespace FUSE +{ + int + mknod(const char *fusepath_, + mode_t mode_, + dev_t rdev_) + { + const fuse_context *fc = fuse_get_context(); + const Config &config = Config::get(fc); + const ugid::Set ugid(fc->uid,fc->gid); + const rwlock::ReadGuard readlock(&config.branches_lock); + + return l::mknod(config.getattr, + config.mknod, + config.branches, + config.minfreespace, + fusepath_, + mode_, + fc->umask, + rdev_); + } +} diff --git a/src/fuse_mknod.hpp b/src/fuse_mknod.hpp new file mode 100644 index 00000000..aba67b5a --- /dev/null +++ b/src/fuse_mknod.hpp @@ -0,0 +1,26 @@ + +/* + Copyright (c) 2016, Antonio SJ Musumeci + + 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 + +namespace FUSE +{ + int + mknod(const char *fusepath_, + mode_t mode_, + dev_t rdev_); +} diff --git a/src/open.cpp b/src/fuse_open.cpp similarity index 70% rename from src/open.cpp rename to src/fuse_open.cpp index 61d5d2df..6bf0326c 100644 --- a/src/open.cpp +++ b/src/fuse_open.cpp @@ -32,7 +32,7 @@ using std::string; using std::vector; -namespace local +namespace l { static int @@ -45,7 +45,7 @@ namespace local int fd; string fullpath; - fs::path::make(basepath_,fusepath_,&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()); @@ -77,32 +77,29 @@ namespace local if(rv == -1) return -errno; - return local::open_core(basepath,fusepath_,flags_,link_cow_,fh_); + return l::open_core(basepath,fusepath_,flags_,link_cow_,fh_); } } -namespace mergerfs +namespace FUSE { - namespace fuse + int + open(const char *fusepath_, + fuse_file_info *ffi_) { - int - open(const char *fusepath_, - fuse_file_info *ffi_) - { - const fuse_context *fc = fuse_get_context(); - const Config &config = Config::get(fc); - const ugid::Set ugid(fc->uid,fc->gid); - const rwlock::ReadGuard readlock(&config.branches_lock); - - ffi_->direct_io = config.direct_io; - return local::open(config.open, - config.open_cache, - config.branches, - config.minfreespace, - fusepath_, - ffi_->flags, - config.link_cow, - &ffi_->fh); - } + const fuse_context *fc = fuse_get_context(); + const Config &config = Config::get(fc); + const ugid::Set ugid(fc->uid,fc->gid); + const rwlock::ReadGuard readlock(&config.branches_lock); + + ffi_->direct_io = config.direct_io; + return l::open(config.open, + config.open_cache, + config.branches, + config.minfreespace, + fusepath_, + ffi_->flags, + config.link_cow, + &ffi_->fh); } } diff --git a/src/fuse_open.hpp b/src/fuse_open.hpp new file mode 100644 index 00000000..3a8c1662 --- /dev/null +++ b/src/fuse_open.hpp @@ -0,0 +1,26 @@ +/* + Copyright (c) 2016, Antonio SJ Musumeci + + 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 + +namespace FUSE +{ + int + open(const char *fusepath_, + fuse_file_info *ffi_); +} diff --git a/src/opendir.hpp b/src/fuse_opendir.cpp similarity index 80% rename from src/opendir.hpp rename to src/fuse_opendir.cpp index 1d0e884e..721ce085 100644 --- a/src/opendir.hpp +++ b/src/fuse_opendir.cpp @@ -14,18 +14,18 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#pragma once +#include "dirinfo.hpp" #include -#include - -namespace mergerfs +namespace FUSE { - namespace fuse + int + opendir(const char *fusepath_, + fuse_file_info *ffi_) { - int - opendir(const char *fusepath, - fuse_file_info *ffi); + ffi_->fh = reinterpret_cast(new DirInfo(fusepath_)); + + return 0; } } diff --git a/src/rename.hpp b/src/fuse_opendir.hpp similarity index 88% rename from src/rename.hpp rename to src/fuse_opendir.hpp index f8cc0718..aedb2204 100644 --- a/src/rename.hpp +++ b/src/fuse_opendir.hpp @@ -16,12 +16,11 @@ #pragma once -namespace mergerfs +#include + +namespace FUSE { - namespace fuse - { - int - rename(const char *from, - const char *to); - } + int + opendir(const char *fusepath_, + fuse_file_info *ffi_); } diff --git a/src/read.cpp b/src/fuse_read.cpp similarity index 68% rename from src/read.cpp rename to src/fuse_read.cpp index 668f92d9..68296888 100644 --- a/src/read.cpp +++ b/src/fuse_read.cpp @@ -20,7 +20,7 @@ #include -namespace local +namespace l { static inline @@ -59,35 +59,32 @@ namespace local } } -namespace mergerfs +namespace FUSE { - namespace fuse + int + read(const char *fusepath_, + char *buf_, + size_t count_, + off_t offset_, + fuse_file_info *ffi_) { - int - read(const char *fusepath_, - char *buf_, - size_t count_, - off_t offset_, - fuse_file_info *ffi_) - { - FileInfo *fi; + FileInfo *fi; - fi = reinterpret_cast(ffi_->fh); + fi = reinterpret_cast(ffi_->fh); - if(ffi_->direct_io) - return local::read_direct_io(fi->fd,buf_,count_,offset_); - return local::read_regular(fi->fd,buf_,count_,offset_); - } + if(ffi_->direct_io) + return l::read_direct_io(fi->fd,buf_,count_,offset_); + return l::read_regular(fi->fd,buf_,count_,offset_); + } - int - read_null(const char *fusepath_, - char *buf_, - size_t count_, - off_t offset_, - fuse_file_info *ffi_) + int + read_null(const char *fusepath_, + char *buf_, + size_t count_, + off_t offset_, + fuse_file_info *ffi_) - { - return count_; - } + { + return count_; } } diff --git a/src/read_buf.hpp b/src/fuse_read.hpp similarity index 69% rename from src/read_buf.hpp rename to src/fuse_read.hpp index 46c0a55c..0fa146c1 100644 --- a/src/read_buf.hpp +++ b/src/fuse_read.hpp @@ -18,17 +18,19 @@ #include -#include - -namespace mergerfs +namespace FUSE { - namespace fuse - { - int - read_buf(const char *fusepath, - struct fuse_bufvec **buf, - size_t size, - off_t offset, - fuse_file_info *fi); - } + int + read(const char *fusepath_, + char *buf_, + size_t count_, + off_t offset_, + fuse_file_info *ffi_); + + int + read_null(const char *fusepath_, + char *buf_, + size_t count_, + off_t offset_, + fuse_file_info *ffi_); } diff --git a/src/read_buf.cpp b/src/fuse_read_buf.cpp similarity index 52% rename from src/read_buf.cpp rename to src/fuse_read_buf.cpp index 5024d6c2..c726fc4f 100644 --- a/src/read_buf.cpp +++ b/src/fuse_read_buf.cpp @@ -14,57 +14,57 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "errno.hpp" +#include "fileinfo.hpp" + #include #include #include -#include "errno.hpp" -#include "fileinfo.hpp" - typedef struct fuse_bufvec fuse_bufvec; -static -int -_read_buf(const int fd, - fuse_bufvec **bufp, - const size_t size, - const off_t offset) +namespace l { - fuse_bufvec *src; + static + int + read_buf(const int fd_, + fuse_bufvec **bufp_, + const size_t size_, + const off_t offset_) + { + fuse_bufvec *src; - src = (fuse_bufvec*)malloc(sizeof(fuse_bufvec)); - if(src == NULL) - return -ENOMEM; + src = (fuse_bufvec*)malloc(sizeof(fuse_bufvec)); + if(src == NULL) + return -ENOMEM; - *src = FUSE_BUFVEC_INIT(size); + *src = FUSE_BUFVEC_INIT(size_); - src->buf->flags = (fuse_buf_flags)(FUSE_BUF_IS_FD|FUSE_BUF_FD_SEEK|FUSE_BUF_FD_RETRY); - src->buf->fd = fd; - src->buf->pos = offset; + src->buf->flags = (fuse_buf_flags)(FUSE_BUF_IS_FD|FUSE_BUF_FD_SEEK|FUSE_BUF_FD_RETRY); + src->buf->fd = fd_; + src->buf->pos = offset_; - *bufp = src; + *bufp_ = src; - return 0; + return 0; + } } -namespace mergerfs +namespace FUSE { - namespace fuse + int + read_buf(const char *fusepath_, + fuse_bufvec **bufp_, + size_t size_, + off_t offset_, + fuse_file_info *ffi_) { - int - read_buf(const char *fusepath, - fuse_bufvec **bufp, - size_t size, - off_t offset, - fuse_file_info *ffi) - { - FileInfo *fi = reinterpret_cast(ffi->fh); + FileInfo *fi = reinterpret_cast(ffi_->fh); - return _read_buf(fi->fd, - bufp, - size, - offset); - } + return l::read_buf(fi->fd, + bufp_, + size_, + offset_); } } diff --git a/src/fuse_read_buf.hpp b/src/fuse_read_buf.hpp new file mode 100644 index 00000000..1faeb891 --- /dev/null +++ b/src/fuse_read_buf.hpp @@ -0,0 +1,31 @@ +/* + Copyright (c) 2016, Antonio SJ Musumeci + + 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 + +#include + +namespace FUSE +{ + int + read_buf(const char *fusepath_, + struct fuse_bufvec **buf_, + size_t size_, + off_t offset_, + fuse_file_info *ffi_); +} diff --git a/src/fuse_readdir.cpp b/src/fuse_readdir.cpp new file mode 100644 index 00000000..da72964d --- /dev/null +++ b/src/fuse_readdir.cpp @@ -0,0 +1,118 @@ +/* + Copyright (c) 2019, Antonio SJ Musumeci + + 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. +*/ + +#define _DEFAULT_SOURCE + +#include "config.hpp" +#include "dirinfo.hpp" +#include "errno.hpp" +#include "fs_base_closedir.hpp" +#include "fs_base_dirfd.hpp" +#include "fs_base_opendir.hpp" +#include "fs_base_readdir.hpp" +#include "fs_base_stat.hpp" +#include "fs_devid.hpp" +#include "fs_inode.hpp" +#include "fs_path.hpp" +#include "hashset.hpp" +#include "rwlock.hpp" +#include "ugid.hpp" + +#include + +#include +#include + +using std::string; +using std::vector; + +#define NO_OFFSET 0 + +namespace l +{ + static + int + readdir(const Branches &branches_, + const char *dirname_, + void *buf_, + const fuse_fill_dir_t filler_) + { + HashSet names; + string basepath; + struct stat st = {0}; + + for(size_t i = 0, ei = branches_.size(); i != ei; i++) + { + int rv; + int dirfd; + DIR *dh; + + basepath = fs::path::make(&branches_[i].path,dirname_); + + dh = fs::opendir(basepath); + if(!dh) + continue; + + dirfd = fs::dirfd(dh); + st.st_dev = fs::devid(dirfd); + if(st.st_dev == (dev_t)-1) + st.st_dev = i; + + rv = 0; + for(struct dirent *de = fs::readdir(dh); de && !rv; de = fs::readdir(dh)) + { + rv = names.put(de->d_name); + if(rv == 0) + continue; + + st.st_ino = de->d_ino; + st.st_mode = DTTOIF(de->d_type); + + fs::inode::recompute(&st); + + rv = filler_(buf_,de->d_name,&st,NO_OFFSET); + if(rv) + return (fs::closedir(dh),-ENOMEM); + } + + fs::closedir(dh); + } + + return 0; + } +} + +namespace FUSE +{ + int + readdir(const char *fusepath_, + void *buf_, + fuse_fill_dir_t filler_, + off_t offset_, + fuse_file_info *ffi_) + { + DirInfo *di = reinterpret_cast(ffi_->fh); + const fuse_context *fc = fuse_get_context(); + const Config &config = Config::get(fc); + const ugid::Set ugid(fc->uid,fc->gid); + const rwlock::ReadGuard readlock(&config.branches_lock); + + return l::readdir(config.branches, + di->fusepath.c_str(), + buf_, + filler_); + } +} diff --git a/src/fgetattr.hpp b/src/fuse_readdir.hpp similarity index 80% rename from src/fgetattr.hpp rename to src/fuse_readdir.hpp index 1fc6b7e4..ec820595 100644 --- a/src/fgetattr.hpp +++ b/src/fuse_readdir.hpp @@ -16,17 +16,18 @@ #pragma once -#include +#include + #include +#include #include -namespace mergerfs +namespace FUSE { - namespace fuse - { - int - fgetattr(const char *fusepath, - struct stat *st, - fuse_file_info *fileinfo); - } + int + readdir(const char *fusepath_, + void *buf_, + fuse_fill_dir_t filler_, + off_t offset_, + fuse_file_info *ffi_); } diff --git a/src/fuse_readlink.cpp b/src/fuse_readlink.cpp new file mode 100644 index 00000000..47c6be6c --- /dev/null +++ b/src/fuse_readlink.cpp @@ -0,0 +1,138 @@ +/* + Copyright (c) 2016, Antonio SJ Musumeci + + 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 "config.hpp" +#include "errno.hpp" +#include "fs_base_readlink.hpp" +#include "fs_base_stat.hpp" +#include "fs_path.hpp" +#include "rwlock.hpp" +#include "symlinkify.hpp" +#include "ugid.hpp" + +#include + +#include + +using std::string; +using std::vector; + +namespace l +{ + static + int + readlink_core_standard(const string &fullpath_, + char *buf_, + const size_t size_) + + { + int rv; + + rv = fs::readlink(fullpath_,buf_,size_); + if(rv == -1) + return -errno; + + buf_[rv] = '\0'; + + return 0; + } + + static + int + readlink_core_symlinkify(const string &fullpath_, + char *buf_, + const size_t size_, + const time_t symlinkify_timeout_) + { + int rv; + struct stat st; + + rv = fs::lstat(fullpath_,&st); + if(rv == -1) + return -errno; + + if(!symlinkify::can_be_symlink(st,symlinkify_timeout_)) + return l::readlink_core_standard(fullpath_,buf_,size_); + + strncpy(buf_,fullpath_.c_str(),size_); + + return 0; + } + + static + int + readlink_core(const string *basepath_, + const char *fusepath_, + char *buf_, + const size_t size_, + const bool symlinkify_, + const time_t symlinkify_timeout_) + { + string fullpath; + + fullpath = fs::path::make(basepath_,fusepath_); + + if(symlinkify_) + return l::readlink_core_symlinkify(fullpath,buf_,size_,symlinkify_timeout_); + + return l::readlink_core_standard(fullpath,buf_,size_); + } + + static + int + readlink(Policy::Func::Search searchFunc_, + const Branches &branches_, + const uint64_t minfreespace_, + const char *fusepath_, + char *buf_, + const size_t size_, + const bool symlinkify_, + const time_t symlinkify_timeout_) + { + int rv; + vector basepaths; + + rv = searchFunc_(branches_,fusepath_,minfreespace_,basepaths); + if(rv == -1) + return -errno; + + return l::readlink_core(basepaths[0],fusepath_,buf_,size_, + symlinkify_,symlinkify_timeout_); + } +} + +namespace FUSE +{ + int + readlink(const char *fusepath_, + char *buf_, + size_t size_) + { + const fuse_context *fc = fuse_get_context(); + const Config &config = Config::get(fc); + const ugid::Set ugid(fc->uid,fc->gid); + const rwlock::ReadGuard readlock(&config.branches_lock); + + return l::readlink(config.readlink, + config.branches, + config.minfreespace, + fusepath_, + buf_, + size_, + config.symlinkify, + config.symlinkify_timeout); + } +} diff --git a/src/access.hpp b/src/fuse_readlink.hpp similarity index 87% rename from src/access.hpp rename to src/fuse_readlink.hpp index 64e568b6..336bd613 100644 --- a/src/access.hpp +++ b/src/fuse_readlink.hpp @@ -16,12 +16,10 @@ #pragma once -namespace mergerfs +namespace FUSE { - namespace fuse - { - int - access(const char *fusepath, - int mask); - } + int + readlink(const char *fusepath_, + char *buf_, + size_t size_); } diff --git a/src/release.cpp b/src/fuse_release.cpp similarity index 77% rename from src/release.cpp rename to src/fuse_release.cpp index f68030b0..336c61d9 100644 --- a/src/release.cpp +++ b/src/fuse_release.cpp @@ -24,7 +24,7 @@ #include -namespace local +namespace l { static int @@ -47,21 +47,18 @@ namespace local } } -namespace mergerfs +namespace FUSE { - namespace fuse + int + release(const char *fusepath_, + fuse_file_info *ffi_) { - int - release(const char *fusepath_, - fuse_file_info *ffi_) - { - const Config &config = Config::get(); - FileInfo *fi = reinterpret_cast(ffi_->fh); + const Config &config = Config::get(); + FileInfo *fi = reinterpret_cast(ffi_->fh); - if(config.open_cache.timeout) - config.open_cache.cleanup(10); + if(config.open_cache.timeout) + config.open_cache.cleanup(10); - return local::release(fi,config.dropcacheonclose); - } + return l::release(fi,config.dropcacheonclose); } } diff --git a/src/fuse_release.hpp b/src/fuse_release.hpp new file mode 100644 index 00000000..b871c8f0 --- /dev/null +++ b/src/fuse_release.hpp @@ -0,0 +1,26 @@ +/* + Copyright (c) 2016, Antonio SJ Musumeci + + 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 + +namespace FUSE +{ + int + release(const char *fusepath_, + fuse_file_info *ffi_); +} diff --git a/src/releasedir.cpp b/src/fuse_releasedir.cpp similarity index 79% rename from src/releasedir.cpp rename to src/fuse_releasedir.cpp index 8c437de8..7782db71 100644 --- a/src/releasedir.cpp +++ b/src/fuse_releasedir.cpp @@ -19,7 +19,7 @@ #include -namespace local +namespace l { static int @@ -31,17 +31,14 @@ namespace local } } -namespace mergerfs +namespace FUSE { - namespace fuse + int + releasedir(const char *fusepath_, + fuse_file_info *ffi_) { - int - releasedir(const char *fusepath_, - fuse_file_info *ffi_) - { - DirInfo *di = reinterpret_cast(ffi_->fh); - - return local::releasedir(di); - } + DirInfo *di = reinterpret_cast(ffi_->fh); + + return l::releasedir(di); } } diff --git a/src/flush.hpp b/src/fuse_releasedir.hpp similarity index 87% rename from src/flush.hpp rename to src/fuse_releasedir.hpp index 84d37ead..ab21aa0b 100644 --- a/src/flush.hpp +++ b/src/fuse_releasedir.hpp @@ -16,12 +16,11 @@ #pragma once -namespace mergerfs +#include + +namespace FUSE { - namespace fuse - { - int - flush(const char *path, - fuse_file_info *fi); - } + int + releasedir(const char *fusepath_, + fuse_file_info *ffi_); } diff --git a/src/fuse_removexattr.cpp b/src/fuse_removexattr.cpp new file mode 100644 index 00000000..d080f0a9 --- /dev/null +++ b/src/fuse_removexattr.cpp @@ -0,0 +1,112 @@ +/* + Copyright (c) 2016, Antonio SJ Musumeci + + 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 "config.hpp" +#include "errno.hpp" +#include "fs_base_removexattr.hpp" +#include "fs_path.hpp" +#include "rv.hpp" +#include "rwlock.hpp" +#include "ugid.hpp" + +#include + +#include +#include + +using std::string; +using std::vector; + +namespace l +{ + static + int + removexattr_loop_core(const string *basepath_, + const char *fusepath_, + const char *attrname_, + const int error_) + { + int rv; + string fullpath; + + fullpath = fs::path::make(basepath_,fusepath_); + + rv = fs::lremovexattr(fullpath,attrname_); + + return error::calc(rv,error_,errno); + } + + static + int + removexattr_loop(const vector &basepaths_, + const char *fusepath_, + const char *attrname_) + { + int error; + + error = -1; + + for(size_t i = 0, ei = basepaths_.size(); i != ei; i++) + { + error = l::removexattr_loop_core(basepaths_[i],fusepath_,attrname_,error); + } + + return -error; + } + + static + int + removexattr(Policy::Func::Action actionFunc_, + const Branches &branches_, + const uint64_t minfreespace_, + const char *fusepath_, + const char *attrname_) + { + int rv; + vector basepaths; + + rv = actionFunc_(branches_,fusepath_,minfreespace_,basepaths); + if(rv == -1) + return -errno; + + return l::removexattr_loop(basepaths,fusepath_,attrname_); + } +} + +namespace FUSE +{ + int + removexattr(const char *fusepath_, + const char *attrname_) + { + const fuse_context *fc = fuse_get_context(); + const Config &config = Config::get(fc); + + if(fusepath_ == config.controlfile) + return -ENOATTR; + if(config.xattr) + return -config.xattr; + + const ugid::Set ugid(fc->uid,fc->gid); + const rwlock::ReadGuard readlock(&config.branches_lock); + + return l::removexattr(config.removexattr, + config.branches, + config.minfreespace, + fusepath_, + attrname_); + } +} diff --git a/src/fuse_removexattr.hpp b/src/fuse_removexattr.hpp new file mode 100644 index 00000000..3d0c13e2 --- /dev/null +++ b/src/fuse_removexattr.hpp @@ -0,0 +1,24 @@ +/* + Copyright (c) 2016, Antonio SJ Musumeci + + 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 + +namespace FUSE +{ + int + removexattr(const char *fusepath_, + const char *attrname_); +} diff --git a/src/rename.cpp b/src/fuse_rename.cpp similarity index 83% rename from src/rename.cpp rename to src/fuse_rename.cpp index 53df9eda..02b174f4 100644 --- a/src/rename.cpp +++ b/src/fuse_rename.cpp @@ -32,7 +32,6 @@ using std::string; using std::vector; using std::set; -using namespace mergerfs; static bool @@ -78,8 +77,8 @@ _rename_create_path_core(const vector &oldbasepaths, rv = fs::clonepath_as_root(newbasepath,oldbasepath,newfusedirpath); if(rv != -1) { - fs::path::make(&oldbasepath,oldfusepath,oldfullpath); - fs::path::make(&oldbasepath,newfusepath,newfullpath); + oldfullpath = fs::path::make(oldbasepath,oldfusepath); + newfullpath = fs::path::make(oldbasepath,newfusepath); rv = fs::rename(oldfullpath,newfullpath); } @@ -90,7 +89,7 @@ _rename_create_path_core(const vector &oldbasepaths, } else { - fs::path::make(&oldbasepath,newfusepath,newfullpath); + newfullpath = fs::path::make(oldbasepath,newfusepath); tounlink.push_back(newfullpath); } @@ -204,14 +203,14 @@ _rename_preserve_path_core(Policy::Func::Search searchFunc, bool ismember; string newfullpath; - fs::path::make(&oldbasepath,newfusepath,newfullpath); + newfullpath = fs::path::make(oldbasepath,newfusepath); ismember = member(oldbasepaths,oldbasepath); if(ismember) { string oldfullpath; - fs::path::make(&oldbasepath,oldfusepath,oldfullpath); + oldfullpath = fs::path::make(oldbasepath,oldfusepath); rv = fs::rename(oldfullpath,newfullpath); if((rv == -1) && (errno == ENOENT)) @@ -270,36 +269,33 @@ _rename_preserve_path(Policy::Func::Search searchFunc, return -error; } -namespace mergerfs +namespace FUSE { - namespace fuse + int + rename(const char *oldpath, + const char *newpath) { - int - rename(const char *oldpath, - const char *newpath) - { - const fuse_context *fc = fuse_get_context(); - const Config &config = Config::get(fc); - const ugid::Set ugid(fc->uid,fc->gid); - const rwlock::ReadGuard readlock(&config.branches_lock); - - config.open_cache.erase(oldpath); - - if(config.create->path_preserving() && !config.ignorepponrename) - return _rename_preserve_path(config.getattr, - config.rename, - config.create, - config.branches, - config.minfreespace, - oldpath, - newpath); - - return _rename_create_path(config.getattr, - config.rename, - config.branches, - config.minfreespace, - oldpath, - newpath); - } + const fuse_context *fc = fuse_get_context(); + const Config &config = Config::get(fc); + const ugid::Set ugid(fc->uid,fc->gid); + const rwlock::ReadGuard readlock(&config.branches_lock); + + config.open_cache.erase(oldpath); + + if(config.create->path_preserving() && !config.ignorepponrename) + return _rename_preserve_path(config.getattr, + config.rename, + config.create, + config.branches, + config.minfreespace, + oldpath, + newpath); + + return _rename_create_path(config.getattr, + config.rename, + config.branches, + config.minfreespace, + oldpath, + newpath); } } diff --git a/src/fuse_rename.hpp b/src/fuse_rename.hpp new file mode 100644 index 00000000..9f26b018 --- /dev/null +++ b/src/fuse_rename.hpp @@ -0,0 +1,24 @@ +/* + Copyright (c) 2016, Antonio SJ Musumeci + + 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 + +namespace FUSE +{ + int + rename(const char *from_, + const char *to_); +} diff --git a/src/fuse_rmdir.cpp b/src/fuse_rmdir.cpp new file mode 100644 index 00000000..22895d4d --- /dev/null +++ b/src/fuse_rmdir.cpp @@ -0,0 +1,102 @@ +/* + Copyright (c) 2016, Antonio SJ Musumeci + + 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 "config.hpp" +#include "errno.hpp" +#include "fs_base_rmdir.hpp" +#include "fs_path.hpp" +#include "rv.hpp" +#include "rwlock.hpp" +#include "ugid.hpp" + +#include + +#include + +#include + +using std::string; +using std::vector; + +namespace l +{ + static + int + rmdir_loop_core(const string *basepath_, + const char *fusepath_, + const int error_) + { + int rv; + string fullpath; + + fullpath = fs::path::make(basepath_,fusepath_); + + rv = fs::rmdir(fullpath); + + return error::calc(rv,error_,errno); + } + + + static + int + rmdir_loop(const vector &basepaths_, + const char *fusepath_) + { + int error; + + error = -1; + for(size_t i = 0, ei = basepaths_.size(); i != ei; i++) + { + error = l::rmdir_loop_core(basepaths_[i],fusepath_,error); + } + + return -error; + } + + static + int + rmdir(Policy::Func::Action actionFunc_, + const Branches &branches_, + const uint64_t minfreespace_, + const char *fusepath_) + { + int rv; + vector basepaths; + + rv = actionFunc_(branches_,fusepath_,minfreespace_,basepaths); + if(rv == -1) + return -errno; + + return l::rmdir_loop(basepaths,fusepath_); + } +} + +namespace FUSE +{ + int + rmdir(const char *fusepath_) + { + const fuse_context *fc = fuse_get_context(); + const Config &config = Config::get(fc); + const ugid::Set ugid(fc->uid,fc->gid); + const rwlock::ReadGuard readguard(&config.branches_lock); + + return l::rmdir(config.rmdir, + config.branches, + config.minfreespace, + fusepath_); + } +} diff --git a/src/fuse_rmdir.hpp b/src/fuse_rmdir.hpp new file mode 100644 index 00000000..58e6813c --- /dev/null +++ b/src/fuse_rmdir.hpp @@ -0,0 +1,23 @@ +/* + Copyright (c) 2016, Antonio SJ Musumeci + + 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 + +namespace FUSE +{ + int + rmdir(const char *fusepath_); +} diff --git a/src/fuse_setxattr.cpp b/src/fuse_setxattr.cpp new file mode 100644 index 00000000..5a6bde49 --- /dev/null +++ b/src/fuse_setxattr.cpp @@ -0,0 +1,480 @@ +/* + Copyright (c) 2018, Antonio SJ Musumeci + + 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 "config.hpp" +#include "errno.hpp" +#include "fs_base_setxattr.hpp" +#include "fs_glob.hpp" +#include "fs_path.hpp" +#include "fs_statvfs_cache.hpp" +#include "num.hpp" +#include "rv.hpp" +#include "rwlock.hpp" +#include "str.hpp" +#include "ugid.hpp" + +#include + +#include +#include +#include + +#include + +static const char SECURITY_CAPABILITY[] = "security.capability"; + +using std::string; +using std::vector; + +namespace l +{ + static + bool + is_attrname_security_capability(const char *attrname_) + { + return (strcmp(attrname_,SECURITY_CAPABILITY) == 0); + } + + static + void + split_attrval(const string &attrval, + string &instruction, + string &values) + { + size_t offset; + + offset = attrval.find_first_of('/'); + instruction = attrval.substr(0,offset); + if(offset != string::npos) + values = attrval.substr(offset); + } + + static + int + setxattr_srcmounts(const string &attrval, + const int flags, + Branches &branches_, + pthread_rwlock_t &branches_lock) + { + const rwlock::WriteGuard wrg(&branches_lock); + + string instruction; + string values; + + if((flags & XATTR_CREATE) == XATTR_CREATE) + return -EEXIST; + + l::split_attrval(attrval,instruction,values); + + if(instruction == "+") + branches_.add_end(values); + else if(instruction == "+<") + branches_.add_begin(values); + else if(instruction == "+>") + branches_.add_end(values); + else if(instruction == "-") + branches_.erase_fnmatch(values); + else if(instruction == "-<") + branches_.erase_begin(); + else if(instruction == "->") + branches_.erase_end(); + else if(instruction == "=") + branches_.set(values); + else if(instruction.empty()) + branches_.set(values); + else + return -EINVAL; + + return 0; + } + + static + int + setxattr_uint64_t(const string &attrval, + const int flags, + uint64_t &uint) + { + int rv; + + if((flags & XATTR_CREATE) == XATTR_CREATE) + return -EEXIST; + + rv = num::to_uint64_t(attrval,uint); + if(rv == -1) + return -EINVAL; + + return 0; + } + + static + int + setxattr_time_t(const string &attrval, + const int flags, + time_t &time) + { + int rv; + + if((flags & XATTR_CREATE) == XATTR_CREATE) + return -EEXIST; + + rv = num::to_time_t(attrval,time); + if(rv == -1) + return -EINVAL; + + return 0; + } + + static + int + setxattr_bool(const string &attrval, + const int flags, + bool &value) + { + if((flags & XATTR_CREATE) == XATTR_CREATE) + return -EEXIST; + + if(attrval == "false") + value = false; + else if(attrval == "true") + value = true; + else + return -EINVAL; + + return 0; + } + + static + int + setxattr_xattr(const string &attrval_, + const int flags_, + int xattr_) + { + if((flags_ & XATTR_CREATE) == XATTR_CREATE) + return -EEXIST; + + if(attrval_ == "passthrough") + xattr_ = 0; + else if(attrval_ == "noattr") + xattr_ = ENOATTR; + else if(attrval_ == "nosys") + xattr_ = ENOSYS; + else + return -EINVAL; + + return 0; + } + + static + int + setxattr_statfs(const string &attrval_, + const int flags_, + Config::StatFS::Enum &enum_) + { + if((flags_ & XATTR_CREATE) == XATTR_CREATE) + return -EEXIST; + + if(attrval_ == "base") + enum_ = Config::StatFS::BASE; + else if(attrval_ == "full") + enum_ = Config::StatFS::FULL; + else + return -EINVAL; + + return 0; + } + + static + int + setxattr_statfsignore(const string &attrval_, + const int flags_, + Config::StatFSIgnore::Enum &enum_) + { + if((flags_ & XATTR_CREATE) == XATTR_CREATE) + return -EEXIST; + + if(attrval_ == "none") + enum_ = Config::StatFSIgnore::NONE; + else if(attrval_ == "ro") + enum_ = Config::StatFSIgnore::RO; + else if(attrval_ == "nc") + enum_ = Config::StatFSIgnore::NC; + else + return -EINVAL; + + return 0; + } + + static + int + setxattr_controlfile_func_policy(Config &config, + const string &funcname, + const string &attrval, + const int flags) + { + int rv; + + if((flags & XATTR_CREATE) == XATTR_CREATE) + return -EEXIST; + + if(funcname == "open") + config.open_cache.clear(); + + rv = config.set_func_policy(funcname,attrval); + if(rv == -1) + return -errno; + + return 0; + } + + static + int + setxattr_controlfile_category_policy(Config &config, + const string &categoryname, + const string &attrval, + const int flags) + { + int rv; + + if((flags & XATTR_CREATE) == XATTR_CREATE) + return -EEXIST; + + if(categoryname == "search") + config.open_cache.clear(); + + rv = config.set_category_policy(categoryname,attrval); + if(rv == -1) + return -errno; + + return 0; + } + + static + int + setxattr_statfs_timeout(const string &attrval_, + const int flags_) + { + int rv; + uint64_t timeout; + + rv = l::setxattr_uint64_t(attrval_,flags_,timeout); + if(rv >= 0) + fs::statvfs_cache_timeout(timeout); + + return rv; + } + + static + int + setxattr_controlfile(Config &config, + const string &attrname, + const string &attrval, + const int flags) + { + vector attr; + + str::split(attr,attrname,'.'); + + switch(attr.size()) + { + case 3: + if(attr[2] == "srcmounts") + return l::setxattr_srcmounts(attrval, + flags, + config.branches, + config.branches_lock); + else if(attr[2] == "branches") + return l::setxattr_srcmounts(attrval, + flags, + config.branches, + config.branches_lock); + else if(attr[2] == "minfreespace") + return l::setxattr_uint64_t(attrval, + flags, + config.minfreespace); + else if(attr[2] == "moveonenospc") + return l::setxattr_bool(attrval, + flags, + config.moveonenospc); + else if(attr[2] == "dropcacheonclose") + return l::setxattr_bool(attrval, + flags, + config.dropcacheonclose); + else if(attr[2] == "symlinkify") + return l::setxattr_bool(attrval, + flags, + config.symlinkify); + else if(attr[2] == "symlinkify_timeout") + return l::setxattr_time_t(attrval, + flags, + config.symlinkify_timeout); + else if(attr[2] == "ignorepponrename") + return l::setxattr_bool(attrval, + flags, + config.ignorepponrename); + else if(attr[2] == "security_capability") + return l::setxattr_bool(attrval, + flags, + config.security_capability); + else if(attr[2] == "xattr") + return l::setxattr_xattr(attrval, + flags, + config.xattr); + else if(attr[2] == "link_cow") + return l::setxattr_bool(attrval, + flags, + config.link_cow); + else if(attr[2] == "statfs") + return l::setxattr_statfs(attrval, + flags, + config.statfs); + else if(attr[2] == "statfs_ignore") + return l::setxattr_statfsignore(attrval, + flags, + config.statfs_ignore); + else if(attr[2] == "direct_io") + return l::setxattr_bool(attrval, + flags, + config.direct_io); + break; + + case 4: + if(attr[2] == "category") + return l::setxattr_controlfile_category_policy(config, + attr[3], + attrval, + flags); + else if(attr[2] == "func") + return l::setxattr_controlfile_func_policy(config, + attr[3], + attrval, + flags); + else if((attr[2] == "cache") && (attr[3] == "open")) + return l::setxattr_uint64_t(attrval, + flags, + config.open_cache.timeout); + else if((attr[2] == "cache") && (attr[3] == "statfs")) + return l::setxattr_statfs_timeout(attrval,flags); + break; + + default: + break; + } + + return -EINVAL; + } + + static + int + setxattr_loop_core(const string *basepath, + const char *fusepath, + const char *attrname, + const char *attrval, + const size_t attrvalsize, + const int flags, + const int error) + { + int rv; + string fullpath; + + fullpath = fs::path::make(basepath,fusepath); + + rv = fs::lsetxattr(fullpath,attrname,attrval,attrvalsize,flags); + + return error::calc(rv,error,errno); + } + + static + int + setxattr_loop(const vector &basepaths, + const char *fusepath, + const char *attrname, + const char *attrval, + const size_t attrvalsize, + const int flags) + { + int error; + + error = -1; + for(size_t i = 0, ei = basepaths.size(); i != ei; i++) + { + error = l::setxattr_loop_core(basepaths[i],fusepath, + attrname,attrval,attrvalsize,flags, + error); + } + + return -error; + } + + static + int + setxattr(Policy::Func::Action actionFunc, + const Branches &branches_, + const uint64_t minfreespace, + const char *fusepath, + const char *attrname, + const char *attrval, + const size_t attrvalsize, + const int flags) + { + int rv; + vector basepaths; + + rv = actionFunc(branches_,fusepath,minfreespace,basepaths); + if(rv == -1) + return -errno; + + return l::setxattr_loop(basepaths,fusepath,attrname,attrval,attrvalsize,flags); + } +} + +namespace FUSE +{ + int + setxattr(const char *fusepath, + const char *attrname, + const char *attrval, + size_t attrvalsize, + int flags) + { + const fuse_context *fc = fuse_get_context(); + const Config &config = Config::get(fc); + + if(fusepath == config.controlfile) + return l::setxattr_controlfile(Config::get_writable(), + attrname, + string(attrval,attrvalsize), + flags); + + if((config.security_capability == false) && + l::is_attrname_security_capability(attrname)) + return -ENOATTR; + + if(config.xattr) + return -config.xattr; + + const ugid::Set ugid(fc->uid,fc->gid); + const rwlock::ReadGuard readlock(&config.branches_lock); + + return l::setxattr(config.setxattr, + config.branches, + config.minfreespace, + fusepath, + attrname, + attrval, + attrvalsize, + flags); + } +} diff --git a/src/fuse_setxattr.hpp b/src/fuse_setxattr.hpp new file mode 100644 index 00000000..d0cbc243 --- /dev/null +++ b/src/fuse_setxattr.hpp @@ -0,0 +1,27 @@ +/* + Copyright (c) 2016, Antonio SJ Musumeci + + 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 + +namespace FUSE +{ + int + setxattr(const char *fusepath_, + const char *attrname_, + const char *attrval_, + size_t attrvalsize_, + int flags_); +} diff --git a/src/fuse_statfs.cpp b/src/fuse_statfs.cpp new file mode 100644 index 00000000..a5757956 --- /dev/null +++ b/src/fuse_statfs.cpp @@ -0,0 +1,167 @@ +/* + Copyright (c) 2018, Antonio SJ Musumeci + + 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 "config.hpp" +#include "errno.hpp" +#include "fs_base_stat.hpp" +#include "fs_base_statvfs.hpp" +#include "fs_path.hpp" +#include "rwlock.hpp" +#include "statvfs_util.hpp" +#include "ugid.hpp" + +#include + +#include +#include +#include +#include +#include + +using std::string; +using std::map; +using std::vector; +typedef Config::StatFS StatFS; +typedef Config::StatFSIgnore StatFSIgnore; + +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::Enum ignore_, + const Branch *branch_, + const bool readonly_) + { + return ((((ignore_ == StatFSIgnore::RO) || readonly_) && + (branch_->ro_or_nc())) || + ((ignore_ == StatFSIgnore::NC) && (branch_->nc()))); + } + + static + int + statfs(const Branches &branches_, + const char *fusepath_, + const StatFS::Enum mode_, + const StatFSIgnore::Enum 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 fsstats; + + min_bsize = std::numeric_limits::max(); + min_frsize = std::numeric_limits::max(); + min_namemax = std::numeric_limits::max(); + for(size_t i = 0, ei = branches_.size(); i < ei; i++) + { + fullpath = ((mode_ == StatFS::FULL) ? + fs::path::make(&branches_[i].path,fusepath_) : + branches_[i].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_,&branches_[i],StatVFS::readonly(stvfs))) + { + stvfs.f_bavail = 0; + stvfs.f_favail = 0; + } + + fsstats.insert(std::make_pair(st.st_dev,stvfs)); + } + + map::iterator iter = fsstats.begin(); + map::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 +{ + int + statfs(const char *fusepath_, + struct statvfs *st_) + { + const fuse_context *fc = fuse_get_context(); + const Config &config = Config::get(fc); + const ugid::Set ugid(fc->uid,fc->gid); + const rwlock::ReadGuard readlock(&config.branches_lock); + + return l::statfs(config.branches, + fusepath_, + config.statfs, + config.statfs_ignore, + st_); + } +} diff --git a/src/fuse_statfs.hpp b/src/fuse_statfs.hpp new file mode 100644 index 00000000..816c297d --- /dev/null +++ b/src/fuse_statfs.hpp @@ -0,0 +1,26 @@ +/* + Copyright (c) 2016, Antonio SJ Musumeci + + 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 + +namespace FUSE +{ + int + statfs(const char *fusepath_, + struct statvfs *fsstat_); +} diff --git a/src/fuse_symlink.cpp b/src/fuse_symlink.cpp new file mode 100644 index 00000000..4a452bf2 --- /dev/null +++ b/src/fuse_symlink.cpp @@ -0,0 +1,129 @@ +/* + Copyright (c) 2016, Antonio SJ Musumeci + + 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 "config.hpp" +#include "errno.hpp" +#include "fs_base_symlink.hpp" +#include "fs_clonepath.hpp" +#include "fs_path.hpp" +#include "rv.hpp" +#include "rwlock.hpp" +#include "ugid.hpp" + +#include + +#include + +#include +#include + +using std::string; +using std::vector; + +namespace l +{ + static + int + symlink_loop_core(const string &newbasepath_, + const char *oldpath_, + const char *newpath_, + const int error_) + { + int rv; + string fullnewpath; + + fullnewpath = fs::path::make(&newbasepath_,newpath_); + + rv = fs::symlink(oldpath_,fullnewpath); + + return error::calc(rv,error_,errno); + } + + static + int + symlink_loop(const string &existingpath_, + const vector newbasepaths_, + const char *oldpath_, + const char *newpath_, + const string &newdirpath_) + { + 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], + oldpath_, + newpath_, + error); + } + + return -error; + } + + static + int + symlink(Policy::Func::Search searchFunc_, + Policy::Func::Create createFunc_, + const Branches &branches_, + const uint64_t minfreespace_, + const char *oldpath_, + const char *newpath_) + { + int rv; + string newdirpath; + vector newbasepaths; + vector existingpaths; + + newdirpath = fs::path::dirname(newpath_); + + rv = searchFunc_(branches_,newdirpath,minfreespace_,existingpaths); + if(rv == -1) + return -errno; + + rv = createFunc_(branches_,newdirpath,minfreespace_,newbasepaths); + if(rv == -1) + return -errno; + + return l::symlink_loop(*existingpaths[0],newbasepaths, + oldpath_,newpath_,newdirpath); + } +} + +namespace FUSE +{ + int + symlink(const char *oldpath_, + const char *newpath_) + { + const fuse_context *fc = fuse_get_context(); + const Config &config = Config::get(fc); + const ugid::Set ugid(fc->uid,fc->gid); + const rwlock::ReadGuard readlock(&config.branches_lock); + + return l::symlink(config.getattr, + config.symlink, + config.branches, + config.minfreespace, + oldpath_, + newpath_); + } +} diff --git a/src/fuse_symlink.hpp b/src/fuse_symlink.hpp new file mode 100644 index 00000000..c598cd22 --- /dev/null +++ b/src/fuse_symlink.hpp @@ -0,0 +1,24 @@ +/* + Copyright (c) 2016, Antonio SJ Musumeci + + 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 + +namespace FUSE +{ + int + symlink(const char *oldpath_, + const char *newpath_); +} diff --git a/src/fuse_truncate.cpp b/src/fuse_truncate.cpp new file mode 100644 index 00000000..48039934 --- /dev/null +++ b/src/fuse_truncate.cpp @@ -0,0 +1,108 @@ +/* + Copyright (c) 2016, Antonio SJ Musumeci + + 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 "config.hpp" +#include "errno.hpp" +#include "fs_base_truncate.hpp" +#include "fs_path.hpp" +#include "rv.hpp" +#include "rwlock.hpp" +#include "ugid.hpp" + +#include + +#include +#include + +#include +#include + +using std::string; +using std::vector; + +namespace l +{ + static + int + truncate_loop_core(const string *basepath_, + const char *fusepath_, + const off_t size_, + const int error_) + { + int rv; + string fullpath; + + fullpath = fs::path::make(basepath_,fusepath_); + + rv = fs::truncate(fullpath,size_); + + return error::calc(rv,error_,errno); + } + + static + int + truncate_loop(const vector &basepaths_, + const char *fusepath_, + const off_t size_) + { + int error; + + error = -1; + for(size_t i = 0, ei = basepaths_.size(); i != ei; i++) + { + error = l::truncate_loop_core(basepaths_[i],fusepath_,size_,error); + } + + return -error; + } + + static + int + truncate(Policy::Func::Action actionFunc_, + const Branches &branches_, + const uint64_t minfreespace_, + const char *fusepath_, + const off_t size_) + { + int rv; + vector basepaths; + + rv = actionFunc_(branches_,fusepath_,minfreespace_,basepaths); + if(rv == -1) + return -errno; + + return l::truncate_loop(basepaths,fusepath_,size_); + } +} + +namespace FUSE +{ + int + truncate(const char *fusepath_, + off_t size_) + { + const fuse_context *fc = fuse_get_context(); + const Config &config = Config::get(fc); + const ugid::Set ugid(fc->uid,fc->gid); + const rwlock::ReadGuard readlock(&config.branches_lock); + + return l::truncate(config.truncate, + config.branches, + config.minfreespace, + fusepath_, + size_); + } +} diff --git a/src/fuse_truncate.hpp b/src/fuse_truncate.hpp new file mode 100644 index 00000000..8c2e6d0c --- /dev/null +++ b/src/fuse_truncate.hpp @@ -0,0 +1,26 @@ +/* + Copyright (c) 2016, Antonio SJ Musumeci + + 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 + +namespace FUSE +{ + int + truncate(const char *fusepath_, + off_t size_); +} diff --git a/src/unlink.cpp b/src/fuse_unlink.cpp similarity index 72% rename from src/unlink.cpp rename to src/fuse_unlink.cpp index 3b682509..0a2d0ea4 100644 --- a/src/unlink.cpp +++ b/src/fuse_unlink.cpp @@ -32,7 +32,7 @@ using std::string; using std::vector; -namespace local +namespace l { static int @@ -43,7 +43,7 @@ namespace local int rv; string fullpath; - fs::path::make(basepath_,fusepath_,fullpath); + fullpath = fs::path::make(basepath_,fusepath_); rv = fs::unlink(fullpath); @@ -60,7 +60,7 @@ namespace local error = -1; for(size_t i = 0, ei = basepaths_.size(); i != ei; i++) { - error = local::unlink_loop_core(basepaths_[i],fusepath_,error); + error = l::unlink_loop_core(basepaths_[i],fusepath_,error); } return -error; @@ -80,28 +80,25 @@ namespace local if(rv == -1) return -errno; - return local::unlink_loop(basepaths,fusepath_); + return l::unlink_loop(basepaths,fusepath_); } } -namespace mergerfs +namespace FUSE { - namespace fuse + int + unlink(const char *fusepath_) { - int - unlink(const char *fusepath_) - { - const fuse_context *fc = fuse_get_context(); - const Config &config = Config::get(fc); - const ugid::Set ugid(fc->uid,fc->gid); - const rwlock::ReadGuard readlock(&config.branches_lock); - - config.open_cache.erase(fusepath_); - - return local::unlink(config.unlink, - config.branches, - config.minfreespace, - fusepath_); - } + const fuse_context *fc = fuse_get_context(); + const Config &config = Config::get(fc); + const ugid::Set ugid(fc->uid,fc->gid); + const rwlock::ReadGuard readlock(&config.branches_lock); + + config.open_cache.erase(fusepath_); + + return l::unlink(config.unlink, + config.branches, + config.minfreespace, + fusepath_); } } diff --git a/src/fuse_unlink.hpp b/src/fuse_unlink.hpp new file mode 100644 index 00000000..60260882 --- /dev/null +++ b/src/fuse_unlink.hpp @@ -0,0 +1,23 @@ +/* + Copyright (c) 2016, Antonio SJ Musumeci + + 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 + +namespace FUSE +{ + int + unlink(const char *fusepath_); +} diff --git a/src/fuse_utimens.cpp b/src/fuse_utimens.cpp new file mode 100644 index 00000000..77454043 --- /dev/null +++ b/src/fuse_utimens.cpp @@ -0,0 +1,106 @@ +/* + Copyright (c) 2016, Antonio SJ Musumeci + + 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 "config.hpp" +#include "errno.hpp" +#include "fs_base_utime.hpp" +#include "fs_path.hpp" +#include "rv.hpp" +#include "rwlock.hpp" +#include "ugid.hpp" +#include + +#include +#include + +#include + +using std::string; +using std::vector; + +namespace l +{ + static + int + utimens_loop_core(const string *basepath_, + const char *fusepath_, + const timespec ts_[2], + const int error_) + { + int rv; + string fullpath; + + fullpath = fs::path::make(basepath_,fusepath_); + + rv = fs::lutime(fullpath,ts_); + + return error::calc(rv,error_,errno); + } + + static + int + utimens_loop(const vector &basepaths_, + const char *fusepath_, + const timespec ts_[2]) + { + int error; + + error = -1; + for(size_t i = 0, ei = basepaths_.size(); i != ei; i++) + { + error = l::utimens_loop_core(basepaths_[i],fusepath_,ts_,error); + } + + return -error; + } + + static + int + utimens(Policy::Func::Action actionFunc_, + const Branches &branches_, + const uint64_t minfreespace_, + const char *fusepath_, + const timespec ts_[2]) + { + int rv; + vector basepaths; + + rv = actionFunc_(branches_,fusepath_,minfreespace_,basepaths); + if(rv == -1) + return -errno; + + return l::utimens_loop(basepaths,fusepath_,ts_); + } +} + +namespace FUSE +{ + int + utimens(const char *fusepath_, + const timespec ts_[2]) + { + const fuse_context *fc = fuse_get_context(); + const Config &config = Config::get(fc); + const ugid::Set ugid(fc->uid,fc->gid); + const rwlock::ReadGuard readlock(&config.branches_lock); + + return l::utimens(config.utimens, + config.branches, + config.minfreespace, + fusepath_, + ts_); + } +} diff --git a/src/chmod.hpp b/src/fuse_utimens.hpp similarity index 87% rename from src/chmod.hpp rename to src/fuse_utimens.hpp index e413abe3..6a122c7b 100644 --- a/src/chmod.hpp +++ b/src/fuse_utimens.hpp @@ -16,12 +16,11 @@ #pragma once -namespace mergerfs +#include + +namespace FUSE { - namespace fuse - { - int - chmod(const char *fusepath, - mode_t mode); - } + int + utimens(const char *fusepath_, + const timespec ts_[2]); } diff --git a/src/write.cpp b/src/fuse_write.cpp similarity index 79% rename from src/write.cpp rename to src/fuse_write.cpp index 512da185..7ca49dd2 100644 --- a/src/write.cpp +++ b/src/fuse_write.cpp @@ -22,18 +22,17 @@ #include "rwlock.hpp" #include "ugid.hpp" -#include - #include #include -using namespace mergerfs; +#include + using std::string; using std::vector; typedef int (*WriteFunc)(const int,const void*,const size_t,const off_t); -namespace local +namespace l { static bool @@ -91,7 +90,7 @@ namespace local fi = reinterpret_cast(ffi_->fh); rv = func_(fi->fd,buf_,count_,offset_); - if(local::out_of_space(-rv)) + if(l::out_of_space(-rv)) { const fuse_context *fc = fuse_get_context(); const Config &config = Config::get(fc); @@ -115,34 +114,32 @@ namespace local return rv; } } -namespace mergerfs + +namespace FUSE { - namespace fuse + int + write(const char *fusepath_, + const char *buf_, + size_t count_, + off_t offset_, + fuse_file_info *ffi_) { - int - write(const char *fusepath_, - const char *buf_, - size_t count_, - off_t offset_, - fuse_file_info *ffi_) - { - WriteFunc wf; - - wf = ((ffi_->direct_io) ? - local::write_direct_io : - local::write_regular); - - return local::write(wf,buf_,count_,offset_,ffi_); - } - - int - write_null(const char *fusepath_, - const char *buf_, - size_t count_, - off_t offset_, - fuse_file_info *ffi_) - { - return count_; - } + WriteFunc wf; + + wf = ((ffi_->direct_io) ? + l::write_direct_io : + l::write_regular); + + return l::write(wf,buf_,count_,offset_,ffi_); + } + + int + write_null(const char *fusepath_, + const char *buf_, + size_t count_, + off_t offset_, + fuse_file_info *ffi_) + { + return count_; } } diff --git a/src/fuse_write.hpp b/src/fuse_write.hpp new file mode 100644 index 00000000..9bc62c7e --- /dev/null +++ b/src/fuse_write.hpp @@ -0,0 +1,36 @@ +/* + Copyright (c) 2016, Antonio SJ Musumeci + + 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 + +namespace FUSE +{ + int + write(const char *fusepath_, + const char *buf_, + size_t count_, + off_t offset_, + fuse_file_info *ffi_); + + int + write_null(const char *fusepath_, + const char *buf_, + size_t count_, + off_t offset_, + fuse_file_info *ffi_); +} diff --git a/src/fuse_write_buf.cpp b/src/fuse_write_buf.cpp new file mode 100644 index 00000000..8b220eae --- /dev/null +++ b/src/fuse_write_buf.cpp @@ -0,0 +1,112 @@ +/* + Copyright (c) 2016, Antonio SJ Musumeci + + 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 "config.hpp" +#include "errno.hpp" +#include "fileinfo.hpp" +#include "fs_movefile.hpp" +#include "fuse_write.hpp" +#include "policy.hpp" +#include "rwlock.hpp" +#include "ugid.hpp" + +#include + +#include +#include + +#include +#include + +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); + } +} + +namespace FUSE +{ + int + write_buf(const char *fusepath_, + fuse_bufvec *src_, + off_t offset_, + fuse_file_info *ffi_) + { + int rv; + FileInfo *fi = reinterpret_cast(ffi_->fh); + + rv = l::write_buf(fi->fd,src_,offset_); + if(l::out_of_space(-rv)) + { + const fuse_context *fc = fuse_get_context(); + const Config &config = Config::get(fc); + + if(config.moveonenospc) + { + size_t extra; + vector paths; + const ugid::Set ugid(0,0); + const rwlock::ReadGuard readlock(&config.branches_lock); + + config.branches.to_paths(paths); + + extra = fuse_buf_size(src_); + rv = fs::movefile(paths,fi->fusepath,extra,fi->fd); + if(rv == -1) + return -ENOSPC; + + rv = l::write_buf(fi->fd,src_,offset_); + } + } + + return rv; + } + + int + write_buf_null(const char *fusepath_, + fuse_bufvec *src_, + off_t offset_, + fuse_file_info *ffi_) + { + return src_->buf[0].size; + } +} diff --git a/src/readdir.hpp b/src/fuse_write_buf.hpp similarity index 69% rename from src/readdir.hpp rename to src/fuse_write_buf.hpp index f6e3e153..54c23750 100644 --- a/src/readdir.hpp +++ b/src/fuse_write_buf.hpp @@ -16,24 +16,21 @@ #pragma once -#include -#include - #include #include -#include -#include -namespace mergerfs +namespace FUSE { - namespace fuse - { - int - readdir(const char *fusepath, - void *buf, - fuse_fill_dir_t filler, - off_t offset, - fuse_file_info *fi); - } + int + write_buf(const char *fusepath_, + struct fuse_bufvec *buf_, + off_t offset_, + fuse_file_info *ffi_); + + int + write_buf_null(const char *fusepath_, + struct fuse_bufvec *buf_, + off_t offset_, + fuse_file_info *ffi_); } diff --git a/src/fusefunc.cpp b/src/fusefunc.cpp index 7b3b3cd9..52984dc2 100644 --- a/src/fusefunc.cpp +++ b/src/fusefunc.cpp @@ -23,75 +23,73 @@ #define FUSEFUNC(X,Y) FuseFunc(FuseFunc::Enum::X,#X,Category::Enum::Y) -namespace mergerfs -{ - const std::vector FuseFunc::_fusefuncs_ = - buildvector - (FUSEFUNC(invalid,invalid)) - (FUSEFUNC(access,search)) - (FUSEFUNC(chmod,action)) - (FUSEFUNC(chown,action)) - (FUSEFUNC(create,create)) - (FUSEFUNC(getattr,search)) - (FUSEFUNC(getxattr,search)) - (FUSEFUNC(link,action)) - (FUSEFUNC(listxattr,search)) - (FUSEFUNC(mkdir,create)) - (FUSEFUNC(mknod,create)) - (FUSEFUNC(open,search)) - (FUSEFUNC(readlink,search)) - (FUSEFUNC(removexattr,action)) - (FUSEFUNC(rename,action)) - (FUSEFUNC(rmdir,action)) - (FUSEFUNC(setxattr,action)) - (FUSEFUNC(symlink,create)) - (FUSEFUNC(truncate,action)) - (FUSEFUNC(unlink,action)) - (FUSEFUNC(utimens,action)) - ; +const std::vector FuseFunc::_fusefuncs_ = + buildvector + (FUSEFUNC(invalid,invalid)) + (FUSEFUNC(access,search)) + (FUSEFUNC(chmod,action)) + (FUSEFUNC(chown,action)) + (FUSEFUNC(create,create)) + (FUSEFUNC(getattr,search)) + (FUSEFUNC(getxattr,search)) + (FUSEFUNC(link,action)) + (FUSEFUNC(listxattr,search)) + (FUSEFUNC(mkdir,create)) + (FUSEFUNC(mknod,create)) + (FUSEFUNC(open,search)) + (FUSEFUNC(readlink,search)) + (FUSEFUNC(removexattr,action)) + (FUSEFUNC(rename,action)) + (FUSEFUNC(rmdir,action)) + (FUSEFUNC(setxattr,action)) + (FUSEFUNC(symlink,create)) + (FUSEFUNC(truncate,action)) + (FUSEFUNC(unlink,action)) + (FUSEFUNC(utimens,action)) + ; - const FuseFunc * const FuseFunc::fusefuncs = &_fusefuncs_[1]; +const FuseFunc * const FuseFunc::fusefuncs = &_fusefuncs_[1]; - const FuseFunc &FuseFunc::invalid = FuseFunc::fusefuncs[FuseFunc::Enum::invalid]; - const FuseFunc &FuseFunc::access = FuseFunc::fusefuncs[FuseFunc::Enum::access]; - const FuseFunc &FuseFunc::chmod = FuseFunc::fusefuncs[FuseFunc::Enum::chmod]; - const FuseFunc &FuseFunc::chown = FuseFunc::fusefuncs[FuseFunc::Enum::chown]; - const FuseFunc &FuseFunc::create = FuseFunc::fusefuncs[FuseFunc::Enum::create]; - const FuseFunc &FuseFunc::getattr = FuseFunc::fusefuncs[FuseFunc::Enum::getattr]; - const FuseFunc &FuseFunc::getxattr = FuseFunc::fusefuncs[FuseFunc::Enum::getxattr]; - const FuseFunc &FuseFunc::link = FuseFunc::fusefuncs[FuseFunc::Enum::link]; - const FuseFunc &FuseFunc::listxattr = FuseFunc::fusefuncs[FuseFunc::Enum::listxattr]; - const FuseFunc &FuseFunc::mkdir = FuseFunc::fusefuncs[FuseFunc::Enum::mkdir]; - const FuseFunc &FuseFunc::mknod = FuseFunc::fusefuncs[FuseFunc::Enum::mknod]; - const FuseFunc &FuseFunc::open = FuseFunc::fusefuncs[FuseFunc::Enum::open]; - const FuseFunc &FuseFunc::readlink = FuseFunc::fusefuncs[FuseFunc::Enum::readlink]; - const FuseFunc &FuseFunc::removexattr = FuseFunc::fusefuncs[FuseFunc::Enum::removexattr]; - const FuseFunc &FuseFunc::rmdir = FuseFunc::fusefuncs[FuseFunc::Enum::rmdir]; - const FuseFunc &FuseFunc::setxattr = FuseFunc::fusefuncs[FuseFunc::Enum::setxattr]; - const FuseFunc &FuseFunc::symlink = FuseFunc::fusefuncs[FuseFunc::Enum::symlink]; - const FuseFunc &FuseFunc::truncate = FuseFunc::fusefuncs[FuseFunc::Enum::truncate]; - const FuseFunc &FuseFunc::unlink = FuseFunc::fusefuncs[FuseFunc::Enum::unlink]; - const FuseFunc &FuseFunc::utimens = FuseFunc::fusefuncs[FuseFunc::Enum::utimens]; +const FuseFunc &FuseFunc::invalid = FuseFunc::fusefuncs[FuseFunc::Enum::invalid]; +const FuseFunc &FuseFunc::access = FuseFunc::fusefuncs[FuseFunc::Enum::access]; +const FuseFunc &FuseFunc::chmod = FuseFunc::fusefuncs[FuseFunc::Enum::chmod]; +const FuseFunc &FuseFunc::chown = FuseFunc::fusefuncs[FuseFunc::Enum::chown]; +const FuseFunc &FuseFunc::create = FuseFunc::fusefuncs[FuseFunc::Enum::create]; +const FuseFunc &FuseFunc::getattr = FuseFunc::fusefuncs[FuseFunc::Enum::getattr]; +const FuseFunc &FuseFunc::getxattr = FuseFunc::fusefuncs[FuseFunc::Enum::getxattr]; +const FuseFunc &FuseFunc::link = FuseFunc::fusefuncs[FuseFunc::Enum::link]; +const FuseFunc &FuseFunc::listxattr = FuseFunc::fusefuncs[FuseFunc::Enum::listxattr]; +const FuseFunc &FuseFunc::mkdir = FuseFunc::fusefuncs[FuseFunc::Enum::mkdir]; +const FuseFunc &FuseFunc::mknod = FuseFunc::fusefuncs[FuseFunc::Enum::mknod]; +const FuseFunc &FuseFunc::open = FuseFunc::fusefuncs[FuseFunc::Enum::open]; +const FuseFunc &FuseFunc::readlink = FuseFunc::fusefuncs[FuseFunc::Enum::readlink]; +const FuseFunc &FuseFunc::removexattr = FuseFunc::fusefuncs[FuseFunc::Enum::removexattr]; +const FuseFunc &FuseFunc::rmdir = FuseFunc::fusefuncs[FuseFunc::Enum::rmdir]; +const FuseFunc &FuseFunc::setxattr = FuseFunc::fusefuncs[FuseFunc::Enum::setxattr]; +const FuseFunc &FuseFunc::symlink = FuseFunc::fusefuncs[FuseFunc::Enum::symlink]; +const FuseFunc &FuseFunc::truncate = FuseFunc::fusefuncs[FuseFunc::Enum::truncate]; +const FuseFunc &FuseFunc::unlink = FuseFunc::fusefuncs[FuseFunc::Enum::unlink]; +const FuseFunc &FuseFunc::utimens = FuseFunc::fusefuncs[FuseFunc::Enum::utimens]; - const FuseFunc& - FuseFunc::find(const std::string &str) - { - for(int i = Enum::BEGIN; i != Enum::END; ++i) - { - if(fusefuncs[i] == str) - return fusefuncs[i]; - } +const +FuseFunc& +FuseFunc::find(const std::string &str) +{ + for(int i = Enum::BEGIN; i != Enum::END; ++i) + { + if(fusefuncs[i] == str) + return fusefuncs[i]; + } - return invalid; - } + return invalid; +} - const FuseFunc& - FuseFunc::find(const FuseFunc::Enum::Type i) - { - if(i >= FuseFunc::Enum::BEGIN && - i < FuseFunc::Enum::END) - return fusefuncs[i]; +const +FuseFunc& +FuseFunc::find(const FuseFunc::Enum::Type i) +{ + if((i >= FuseFunc::Enum::BEGIN) && (i < FuseFunc::Enum::END)) + return fusefuncs[i]; - return invalid; - } + return invalid; } diff --git a/src/fusefunc.hpp b/src/fusefunc.hpp index d6190e48..067ef11c 100644 --- a/src/fusefunc.hpp +++ b/src/fusefunc.hpp @@ -16,113 +16,110 @@ #pragma once +#include "category.hpp" + #include #include -#include "category.hpp" - -namespace mergerfs +class FuseFunc { - class FuseFunc +public: + struct Enum { - public: - struct Enum - { - enum Type - { - invalid = -1, - BEGIN = 0, - access = BEGIN, - chmod, - chown, - create, - getattr, - getxattr, - link, - listxattr, - mkdir, - mknod, - open, - readlink, - removexattr, - rename, - rmdir, - setxattr, - symlink, - truncate, - unlink, - utimens, - END - }; - }; - - private: - Enum::Type _enum; - std::string _str; - Category::Enum::Type _category; - - public: - FuseFunc() - : _enum(invalid), - _str(invalid), - _category(Category::Enum::invalid) - { - } - - FuseFunc(const Enum::Type enum_, - const std::string &str_, - const Category::Enum::Type category_) - : _enum(enum_), - _str(str_), - _category(category_) - { - } - - public: - operator const Enum::Type() const { return _enum; } - operator const std::string&() const { return _str; } - operator const Category::Enum::Type() const { return _category; } - operator const FuseFunc*() const { return this; } - - bool operator==(const std::string &str_) const - { return _str == str_; } - - bool operator==(const Enum::Type enum_) const - { return _enum == enum_; } - - bool operator!=(const FuseFunc &r) const - { return _enum != r._enum; } - - bool operator<(const FuseFunc &r) const - { return _enum < r._enum; } - - public: - static const FuseFunc &find(const std::string&); - static const FuseFunc &find(const Enum::Type); - - public: - static const std::vector _fusefuncs_; - static const FuseFunc * const fusefuncs; - static const FuseFunc &invalid; - static const FuseFunc &access; - static const FuseFunc &chmod; - static const FuseFunc &chown; - static const FuseFunc &create; - static const FuseFunc &getattr; - static const FuseFunc &getxattr; - static const FuseFunc &link; - static const FuseFunc &listxattr; - static const FuseFunc &mkdir; - static const FuseFunc &mknod; - static const FuseFunc &open; - static const FuseFunc &readlink; - static const FuseFunc &removexattr; - static const FuseFunc &rename; - static const FuseFunc &rmdir; - static const FuseFunc &setxattr; - static const FuseFunc &symlink; - static const FuseFunc &truncate; - static const FuseFunc &unlink; - static const FuseFunc &utimens; + enum Type + { + invalid = -1, + BEGIN = 0, + access = BEGIN, + chmod, + chown, + create, + getattr, + getxattr, + link, + listxattr, + mkdir, + mknod, + open, + readlink, + removexattr, + rename, + rmdir, + setxattr, + symlink, + truncate, + unlink, + utimens, + END + }; }; -} + +private: + Enum::Type _enum; + std::string _str; + Category::Enum::Type _category; + +public: + FuseFunc() + : _enum(invalid), + _str(invalid), + _category(Category::Enum::invalid) + { + } + + FuseFunc(const Enum::Type enum_, + const std::string &str_, + const Category::Enum::Type category_) + : _enum(enum_), + _str(str_), + _category(category_) + { + } + +public: + operator const Enum::Type() const { return _enum; } + operator const std::string&() const { return _str; } + operator const Category::Enum::Type() const { return _category; } + operator const FuseFunc*() const { return this; } + + bool operator==(const std::string &str_) const + { return _str == str_; } + + bool operator==(const Enum::Type enum_) const + { return _enum == enum_; } + + bool operator!=(const FuseFunc &r) const + { return _enum != r._enum; } + + bool operator<(const FuseFunc &r) const + { return _enum < r._enum; } + +public: + static const FuseFunc &find(const std::string&); + static const FuseFunc &find(const Enum::Type); + +public: + static const std::vector _fusefuncs_; + static const FuseFunc * const fusefuncs; + static const FuseFunc &invalid; + static const FuseFunc &access; + static const FuseFunc &chmod; + static const FuseFunc &chown; + static const FuseFunc &create; + static const FuseFunc &getattr; + static const FuseFunc &getxattr; + static const FuseFunc &link; + static const FuseFunc &listxattr; + static const FuseFunc &mkdir; + static const FuseFunc &mknod; + static const FuseFunc &open; + static const FuseFunc &readlink; + static const FuseFunc &removexattr; + static const FuseFunc &rename; + static const FuseFunc &rmdir; + static const FuseFunc &setxattr; + static const FuseFunc &symlink; + static const FuseFunc &truncate; + static const FuseFunc &unlink; + static const FuseFunc &utimens; +}; diff --git a/src/getattr.cpp b/src/getattr.cpp deleted file mode 100644 index 6b8c9d13..00000000 --- a/src/getattr.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* - Copyright (c) 2016, Antonio SJ Musumeci - - 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 - -#include -#include - -#include "config.hpp" -#include "errno.hpp" -#include "fs_base_stat.hpp" -#include "fs_inode.hpp" -#include "fs_path.hpp" -#include "rwlock.hpp" -#include "symlinkify.hpp" -#include "ugid.hpp" - -using std::string; -using std::vector; - -static -int -_getattr_controlfile(struct stat &st) -{ - static const uid_t uid = ::getuid(); - static const gid_t gid = ::getgid(); - static const time_t now = ::time(NULL); - - st.st_dev = 0; - st.st_ino = fs::inode::MAGIC; - st.st_mode = (S_IFREG|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH); - st.st_nlink = 1; - st.st_uid = uid; - st.st_gid = gid; - st.st_rdev = 0; - st.st_size = 0; - st.st_blksize = 512; - st.st_blocks = 0; - st.st_atime = now; - st.st_mtime = now; - st.st_ctime = now; - - return 0; -} - -static -int -_getattr(Policy::Func::Search searchFunc, - const Branches &branches_, - const uint64_t minfreespace, - const char *fusepath, - struct stat &st, - const bool symlinkify, - const time_t symlinkify_timeout) -{ - int rv; - string fullpath; - vector basepaths; - - rv = searchFunc(branches_,fusepath,minfreespace,basepaths); - if(rv == -1) - return -errno; - - fs::path::make(basepaths[0],fusepath,fullpath); - - rv = fs::lstat(fullpath,st); - if(rv == -1) - return -errno; - - if(symlinkify && symlinkify::can_be_symlink(st,symlinkify_timeout)) - st.st_mode = symlinkify::convert(st.st_mode); - - fs::inode::recompute(st); - - return 0; -} - -namespace mergerfs -{ - namespace fuse - { - int - getattr(const char *fusepath, - struct stat *st) - { - const fuse_context *fc = fuse_get_context(); - const Config &config = Config::get(fc); - - if(fusepath == config.controlfile) - return _getattr_controlfile(*st); - - const ugid::Set ugid(fc->uid,fc->gid); - const rwlock::ReadGuard readlock(&config.branches_lock); - - return _getattr(config.getattr, - config.branches, - config.minfreespace, - fusepath, - *st, - config.symlinkify, - config.symlinkify_timeout); - } - } -} diff --git a/src/getxattr.cpp b/src/getxattr.cpp deleted file mode 100644 index b0365668..00000000 --- a/src/getxattr.cpp +++ /dev/null @@ -1,464 +0,0 @@ -/* - Copyright (c) 2018, Antonio SJ Musumeci - - 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 "config.hpp" -#include "errno.hpp" -#include "fs_base_getxattr.hpp" -#include "fs_path.hpp" -#include "fs_statvfs_cache.hpp" -#include "rwlock.hpp" -#include "str.hpp" -#include "ugid.hpp" -#include "version.hpp" - -#include - -#include -#include -#include -#include -#include - -#include -#include - -static const char SECURITY_CAPABILITY[] = "security.capability"; - -using std::string; -using std::vector; -using std::set; -using namespace mergerfs; - -static -bool -_is_attrname_security_capability(const char *attrname_) -{ - 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 -void -_getxattr_controlfile_fusefunc_policy(const Config &config, - const string &attr, - string &attrvalue) -{ - FuseFunc fusefunc; - - fusefunc = FuseFunc::find(attr); - if(fusefunc != FuseFunc::invalid) - attrvalue = (std::string)*config.policies[(FuseFunc::Enum::Type)*fusefunc]; -} - -static -void -_getxattr_controlfile_category_policy(const Config &config, - const string &attr, - string &attrvalue) -{ - Category cat; - - cat = Category::find(attr); - if(cat != Category::invalid) - { - vector policies; - for(int i = FuseFunc::Enum::BEGIN; i < FuseFunc::Enum::END; i++) - { - if(cat == (Category::Enum::Type)*FuseFunc::fusefuncs[i]) - policies.push_back(*config.policies[i]); - } - - std::sort(policies.begin(),policies.end()); - policies.erase(std::unique(policies.begin(),policies.end()), - policies.end()); - attrvalue = str::join(policies,','); - } -} - -static -void -_getxattr_controlfile_srcmounts(const Config &config, - string &attrvalue) -{ - attrvalue = config.branches.to_string(); -} - -static -void -_getxattr_controlfile_branches(const Config &config, - string &attrvalue) -{ - attrvalue = config.branches.to_string(true); -} - -static -void -_getxattr_controlfile_uint64_t(const uint64_t uint, - string &attrvalue) -{ - std::ostringstream os; - - os << uint; - - attrvalue = os.str(); -} - -static -void -_getxattr_controlfile_time_t(const time_t time, - string &attrvalue) -{ - std::ostringstream os; - - os << time; - - attrvalue = os.str(); -} - -static -void -_getxattr_controlfile_bool(const bool boolvalue, - string &attrvalue) -{ - attrvalue = (boolvalue ? "true" : "false"); -} - -static -void -_getxattr_controlfile_errno(const int errno_, - string &attrvalue) -{ - switch(errno_) - { - case 0: - attrvalue = "passthrough"; - break; - case ENOATTR: - attrvalue = "noattr"; - break; - case ENOSYS: - attrvalue = "nosys"; - break; - default: - attrvalue = "ERROR"; - break; - } -} - -static -void -_getxattr_controlfile_statfs(const Config::StatFS::Enum enum_, - string &attrvalue_) -{ - switch(enum_) - { - case Config::StatFS::BASE: - attrvalue_ = "base"; - break; - case Config::StatFS::FULL: - attrvalue_ = "full"; - break; - default: - attrvalue_ = "ERROR"; - break; - } -} - -static -void -_getxattr_controlfile_statfsignore(const Config::StatFSIgnore::Enum enum_, - string &attrvalue_) -{ - switch(enum_) - { - case Config::StatFSIgnore::NONE: - attrvalue_ = "none"; - break; - case Config::StatFSIgnore::RO: - attrvalue_ = "ro"; - break; - case Config::StatFSIgnore::NC: - attrvalue_ = "nc"; - break; - default: - attrvalue_ = "ERROR"; - break; - } -} - -static -void -_getxattr_controlfile_policies(const Config &config, - string &attrvalue) -{ - size_t i = Policy::Enum::begin(); - - attrvalue = (string)Policy::policies[i]; - for(i++; i < Policy::Enum::end(); i++) - attrvalue += ',' + (string)Policy::policies[i]; -} - -static -void -_getxattr_controlfile_version(string &attrvalue) -{ - attrvalue = MERGERFS_VERSION; - if(attrvalue.empty()) - attrvalue = "unknown_possible_problem_with_build"; -} - -static -void -_getxattr_pid(string &attrvalue) -{ - int pid; - char buf[32]; - - pid = getpid(); - snprintf(buf,sizeof(buf),"%d",pid); - - attrvalue = buf; -} - -static -int -_getxattr_controlfile(const Config &config, - const char *attrname, - char *buf, - const size_t count) -{ - size_t len; - string attrvalue; - vector attr; - - str::split(attr,attrname,'.'); - if((attr[0] != "user") || (attr[1] != "mergerfs")) - return -ENOATTR; - - switch(attr.size()) - { - case 3: - if(attr[2] == "srcmounts") - _getxattr_controlfile_srcmounts(config,attrvalue); - else if(attr[2] == "branches") - _getxattr_controlfile_branches(config,attrvalue); - else if(attr[2] == "minfreespace") - _getxattr_controlfile_uint64_t(config.minfreespace,attrvalue); - else if(attr[2] == "moveonenospc") - _getxattr_controlfile_bool(config.moveonenospc,attrvalue); - else if(attr[2] == "dropcacheonclose") - _getxattr_controlfile_bool(config.dropcacheonclose,attrvalue); - else if(attr[2] == "symlinkify") - _getxattr_controlfile_bool(config.symlinkify,attrvalue); - else if(attr[2] == "symlinkify_timeout") - _getxattr_controlfile_time_t(config.symlinkify_timeout,attrvalue); - else if(attr[2] == "nullrw") - _getxattr_controlfile_bool(config.nullrw,attrvalue); - else if(attr[2] == "ignorepponrename") - _getxattr_controlfile_bool(config.ignorepponrename,attrvalue); - else if(attr[2] == "security_capability") - _getxattr_controlfile_bool(config.security_capability,attrvalue); - else if(attr[2] == "xattr") - _getxattr_controlfile_errno(config.xattr,attrvalue); - else if(attr[2] == "link_cow") - _getxattr_controlfile_bool(config.link_cow,attrvalue); - else if(attr[2] == "statfs") - _getxattr_controlfile_statfs(config.statfs,attrvalue); - else if(attr[2] == "statfs_ignore") - _getxattr_controlfile_statfsignore(config.statfs_ignore,attrvalue); - else if(attr[2] == "policies") - _getxattr_controlfile_policies(config,attrvalue); - else if(attr[2] == "version") - _getxattr_controlfile_version(attrvalue); - else if(attr[2] == "pid") - _getxattr_pid(attrvalue); - else if(attr[2] == "direct_io") - _getxattr_controlfile_bool(config.direct_io,attrvalue); - break; - - case 4: - if(attr[2] == "category") - _getxattr_controlfile_category_policy(config,attr[3],attrvalue); - else if(attr[2] == "func") - _getxattr_controlfile_fusefunc_policy(config,attr[3],attrvalue); - else if((attr[2] == "cache") && (attr[3] == "open")) - _getxattr_controlfile_uint64_t(config.open_cache.timeout,attrvalue); - else if((attr[2] == "cache") && (attr[3] == "statfs")) - _getxattr_controlfile_uint64_t(fs::statvfs_cache_timeout(),attrvalue); - break; - } - - if(attrvalue.empty()) - return -ENOATTR; - - len = attrvalue.size(); - - if(count == 0) - return len; - - if(count < len) - return -ERANGE; - - memcpy(buf,attrvalue.c_str(),len); - - return (int)len; -} - -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 &branches_, - const char *fusepath, - char *buf, - const size_t count) -{ - string concated; - vector paths; - vector branches; - - branches_.to_paths(branches); - - fs::findallfiles(branches,fusepath,paths); - - concated = str::join(paths,'\0'); - - return _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) -{ - vector attr; - - str::split(attr,attrname,'.'); - - if(attr[2] == "basepath") - return _getxattr_from_string(buf,count,basepath); - else if(attr[2] == "relpath") - return _getxattr_from_string(buf,count,fusepath); - else if(attr[2] == "fullpath") - return _getxattr_from_string(buf,count,fullpath); - else if(attr[2] == "allpaths") - return _getxattr_user_mergerfs_allpaths(branches_,fusepath,buf,count); - - return -ENOATTR; -} - -static -int -_getxattr(Policy::Func::Search searchFunc, - const Branches &branches_, - const size_t minfreespace, - const char *fusepath, - const char *attrname, - char *buf, - const size_t count) -{ - int rv; - string fullpath; - vector basepaths; - - rv = searchFunc(branches_,fusepath,minfreespace,basepaths); - if(rv == -1) - return -errno; - - fs::path::make(basepaths[0],fusepath,fullpath); - - if(str::isprefix(attrname,"user.mergerfs.")) - rv = _getxattr_user_mergerfs(*basepaths[0],fusepath,fullpath,branches_,attrname,buf,count); - else - rv = _lgetxattr(fullpath,attrname,buf,count); - - return rv; -} - -namespace mergerfs -{ - namespace fuse - { - int - getxattr(const char *fusepath, - const char *attrname, - char *buf, - size_t count) - { - const fuse_context *fc = fuse_get_context(); - const Config &config = Config::get(fc); - - if(fusepath == config.controlfile) - return _getxattr_controlfile(config, - attrname, - buf, - count); - - if((config.security_capability == false) && - _is_attrname_security_capability(attrname)) - return -ENOATTR; - - if(config.xattr) - return -config.xattr; - - const ugid::Set ugid(fc->uid,fc->gid); - const rwlock::ReadGuard readlock(&config.branches_lock); - - return _getxattr(config.getxattr, - config.branches, - config.minfreespace, - fusepath, - attrname, - buf, - count); - } - } -} diff --git a/src/getxattr.hpp b/src/getxattr.hpp deleted file mode 100644 index 2752e51d..00000000 --- a/src/getxattr.hpp +++ /dev/null @@ -1,29 +0,0 @@ -/* - Copyright (c) 2016, Antonio SJ Musumeci - - 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 - -namespace mergerfs -{ - namespace fuse - { - int - getxattr(const char *fusepath, - const char *attrname, - char *buf, - size_t count); - } -} diff --git a/src/ioctl.hpp b/src/ioctl.hpp deleted file mode 100644 index 78cc6506..00000000 --- a/src/ioctl.hpp +++ /dev/null @@ -1,33 +0,0 @@ -/* - Copyright (c) 2016, Antonio SJ Musumeci - - 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 - -namespace mergerfs -{ - namespace fuse - { - int - ioctl(const char *fusepath, - int cmd, - void *arg, - fuse_file_info *fi, - unsigned int flags, - void *data); - } -} diff --git a/src/link.cpp b/src/link.cpp deleted file mode 100644 index 3adb21fe..00000000 --- a/src/link.cpp +++ /dev/null @@ -1,250 +0,0 @@ -/* - Copyright (c) 2016, Antonio SJ Musumeci - - 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 - -#include -#include - -#include "config.hpp" -#include "errno.hpp" -#include "fs_base_link.hpp" -#include "fs_clonepath.hpp" -#include "fs_path.hpp" -#include "rv.hpp" -#include "rwlock.hpp" -#include "ugid.hpp" - -using std::string; -using std::vector; -using namespace mergerfs; - -static -int -_link_create_path_core(const string &oldbasepath, - const string &newbasepath, - const char *oldfusepath, - const char *newfusepath, - const int error) -{ - int rv; - string oldfullpath; - string newfullpath; - - fs::path::make(&oldbasepath,oldfusepath,oldfullpath); - fs::path::make(&oldbasepath,newfusepath,newfullpath); - - rv = fs::link(oldfullpath,newfullpath); - - return error::calc(rv,error,errno); -} - -static -int -_link_create_path_loop(const vector &oldbasepaths, - const string &newbasepath, - const char *oldfusepath, - const char *newfusepath, - const string &newfusedirpath) -{ - int rv; - int error; - - error = -1; - for(size_t i = 0, ei = oldbasepaths.size(); i != ei; i++) - { - rv = fs::clonepath_as_root(newbasepath,*oldbasepaths[i],newfusedirpath); - if(rv == -1) - error = error::calc(rv,error,errno); - else - error = _link_create_path_core(*oldbasepaths[i],newbasepath, - oldfusepath,newfusepath, - error); - } - - return -error; -} - -static -int -_link_create_path(Policy::Func::Search searchFunc, - Policy::Func::Action actionFunc, - const Branches &branches_, - const uint64_t minfreespace, - const char *oldfusepath, - const char *newfusepath) -{ - int rv; - string newfusedirpath; - vector oldbasepaths; - vector newbasepaths; - - rv = actionFunc(branches_,oldfusepath,minfreespace,oldbasepaths); - if(rv == -1) - return -errno; - - newfusedirpath = fs::path::dirname(newfusepath); - - rv = searchFunc(branches_,newfusedirpath,minfreespace,newbasepaths); - if(rv == -1) - return -errno; - - return _link_create_path_loop(oldbasepaths,*newbasepaths[0], - oldfusepath,newfusepath, - newfusedirpath); -} - -static -int -_clonepath_if_would_create(Policy::Func::Search searchFunc, - Policy::Func::Create createFunc, - const Branches &branches_, - const uint64_t minfreespace, - const string &oldbasepath, - const char *oldfusepath, - const char *newfusepath) -{ - int rv; - string newfusedirpath; - vector newbasepath; - - newfusedirpath = fs::path::dirname(newfusepath); - - rv = createFunc(branches_,newfusedirpath,minfreespace,newbasepath); - if(rv == -1) - return -1; - - if(oldbasepath != *newbasepath[0]) - return (errno=EXDEV,-1); - - rv = searchFunc(branches_,newfusedirpath,minfreespace,newbasepath); - if(rv == -1) - return -1; - - return fs::clonepath_as_root(*newbasepath[0],oldbasepath,newfusedirpath); -} - -static -int -_link_preserve_path_core(Policy::Func::Search searchFunc, - Policy::Func::Create createFunc, - const Branches &branches_, - const uint64_t minfreespace, - const string &oldbasepath, - const char *oldfusepath, - const char *newfusepath, - const int error) -{ - int rv; - string oldfullpath; - string newfullpath; - - fs::path::make(&oldbasepath,oldfusepath,oldfullpath); - fs::path::make(&oldbasepath,newfusepath,newfullpath); - - rv = fs::link(oldfullpath,newfullpath); - if((rv == -1) && (errno == ENOENT)) - { - rv = _clonepath_if_would_create(searchFunc,createFunc, - branches_,minfreespace, - oldbasepath, - oldfusepath,newfusepath); - if(rv != -1) - rv = fs::link(oldfullpath,newfullpath); - } - - return error::calc(rv,error,errno); -} - -static -int -_link_preserve_path_loop(Policy::Func::Search searchFunc, - Policy::Func::Create createFunc, - const Branches &branches_, - const uint64_t minfreespace, - const char *oldfusepath, - const char *newfusepath, - const vector &oldbasepaths) -{ - int error; - - error = -1; - for(size_t i = 0, ei = oldbasepaths.size(); i != ei; i++) - { - error = _link_preserve_path_core(searchFunc,createFunc, - branches_,minfreespace, - *oldbasepaths[i], - oldfusepath,newfusepath, - error); - } - - return -error; -} - -static -int -_link_preserve_path(Policy::Func::Search searchFunc, - Policy::Func::Action actionFunc, - Policy::Func::Create createFunc, - const Branches &branches_, - const uint64_t minfreespace, - const char *oldfusepath, - const char *newfusepath) -{ - int rv; - vector oldbasepaths; - - rv = actionFunc(branches_,oldfusepath,minfreespace,oldbasepaths); - if(rv == -1) - return -errno; - - return _link_preserve_path_loop(searchFunc,createFunc, - branches_,minfreespace, - oldfusepath,newfusepath, - oldbasepaths); -} - -namespace mergerfs -{ - namespace fuse - { - int - link(const char *from, - const char *to) - { - const fuse_context *fc = fuse_get_context(); - const Config &config = Config::get(fc); - const ugid::Set ugid(fc->uid,fc->gid); - const rwlock::ReadGuard readlock(&config.branches_lock); - - if(config.create->path_preserving() && !config.ignorepponrename) - return _link_preserve_path(config.getattr, - config.link, - config.create, - config.branches, - config.minfreespace, - from, - to); - - return _link_create_path(config.link, - config.create, - config.branches, - config.minfreespace, - from, - to); - } - } -} diff --git a/src/listxattr.cpp b/src/listxattr.cpp deleted file mode 100644 index d89949b0..00000000 --- a/src/listxattr.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/* - Copyright (c) 2018, Antonio SJ Musumeci - - 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 - -#include -#include - -#include - -#include "buildvector.hpp" -#include "category.hpp" -#include "config.hpp" -#include "errno.hpp" -#include "fs_base_listxattr.hpp" -#include "fs_path.hpp" -#include "rwlock.hpp" -#include "ugid.hpp" -#include "xattr.hpp" - -using std::string; -using std::vector; -using namespace mergerfs; - -static -int -_listxattr_controlfile(char *list, - const size_t size) -{ - string xattrs; - const vector strs = - buildvector - ("user.mergerfs.branches") - ("user.mergerfs.cache.open") - ("user.mergerfs.cache.statfs") - ("user.mergerfs.direct_io") - ("user.mergerfs.dropcacheonclose") - ("user.mergerfs.ignorepponrename") - ("user.mergerfs.link_cow") - ("user.mergerfs.minfreespace") - ("user.mergerfs.moveonenospc") - ("user.mergerfs.nullrw") - ("user.mergerfs.pid") - ("user.mergerfs.policies") - ("user.mergerfs.security_capability") - ("user.mergerfs.srcmounts") - ("user.mergerfs.statfs") - ("user.mergerfs.statfs_ignore") - ("user.mergerfs.symlinkify") - ("user.mergerfs.symlinkify_timeout") - ("user.mergerfs.version") - ("user.mergerfs.xattr") - ; - - xattrs.reserve(1024); - for(size_t i = 0; i < strs.size(); i++) - xattrs += (strs[i] + '\0'); - for(size_t i = Category::Enum::BEGIN; i < Category::Enum::END; i++) - xattrs += ("user.mergerfs.category." + (std::string)*Category::categories[i] + '\0'); - for(size_t i = FuseFunc::Enum::BEGIN; i < FuseFunc::Enum::END; i++) - xattrs += ("user.mergerfs.func." + (std::string)*FuseFunc::fusefuncs[i] + '\0'); - - if(size == 0) - return xattrs.size(); - - if(size < xattrs.size()) - return -ERANGE; - - memcpy(list,xattrs.c_str(),xattrs.size()); - - return xattrs.size(); -} - -static -int -_listxattr(Policy::Func::Search searchFunc, - const Branches &branches_, - const uint64_t minfreespace, - const char *fusepath, - char *list, - const size_t size) -{ - int rv; - string fullpath; - vector basepaths; - - rv = searchFunc(branches_,fusepath,minfreespace,basepaths); - if(rv == -1) - return -errno; - - fs::path::make(basepaths[0],fusepath,fullpath); - - rv = fs::llistxattr(fullpath,list,size); - - return ((rv == -1) ? -errno : rv); -} - -namespace mergerfs -{ - namespace fuse - { - int - listxattr(const char *fusepath, - char *list, - size_t size) - { - const fuse_context *fc = fuse_get_context(); - const Config &config = Config::get(fc); - - if(fusepath == config.controlfile) - return _listxattr_controlfile(list,size); - - switch(config.xattr) - { - case 0: - break; - case ENOATTR: - return 0; - default: - return -config.xattr; - } - - const ugid::Set ugid(fc->uid,fc->gid); - const rwlock::ReadGuard readlock(&config.branches_lock); - - return _listxattr(config.listxattr, - config.branches, - config.minfreespace, - fusepath, - list, - size); - } - } -} diff --git a/src/listxattr.hpp b/src/listxattr.hpp deleted file mode 100644 index 58c9156b..00000000 --- a/src/listxattr.hpp +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (c) 2016, Antonio SJ Musumeci - - 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 - -namespace mergerfs -{ - namespace fuse - { - int - listxattr(const char *fusepath, - char *buf, - size_t count); - } -} diff --git a/src/mergerfs.cpp b/src/mergerfs.cpp index 80a64a58..657b3610 100644 --- a/src/mergerfs.cpp +++ b/src/mergerfs.cpp @@ -14,58 +14,59 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "fs_path.hpp" +#include "mergerfs.hpp" +#include "option_parser.hpp" +#include "resources.hpp" + +#include "fuse_access.hpp" +#include "fuse_chmod.hpp" +#include "fuse_chown.hpp" +#include "fuse_create.hpp" +#include "fuse_destroy.hpp" +#include "fuse_fallocate.hpp" +#include "fuse_fgetattr.hpp" +#include "fuse_flock.hpp" +#include "fuse_flush.hpp" +#include "fuse_fsync.hpp" +#include "fuse_fsyncdir.hpp" +#include "fuse_ftruncate.hpp" +#include "fuse_getattr.hpp" +#include "fuse_getxattr.hpp" +#include "fuse_init.hpp" +#include "fuse_ioctl.hpp" +#include "fuse_link.hpp" +#include "fuse_listxattr.hpp" +#include "fuse_mkdir.hpp" +#include "fuse_mknod.hpp" +#include "fuse_open.hpp" +#include "fuse_opendir.hpp" +#include "fuse_read.hpp" +#include "fuse_read_buf.hpp" +#include "fuse_readdir.hpp" +#include "fuse_readlink.hpp" +#include "fuse_release.hpp" +#include "fuse_releasedir.hpp" +#include "fuse_removexattr.hpp" +#include "fuse_rename.hpp" +#include "fuse_rmdir.hpp" +#include "fuse_setxattr.hpp" +#include "fuse_statfs.hpp" +#include "fuse_symlink.hpp" +#include "fuse_truncate.hpp" +#include "fuse_unlink.hpp" +#include "fuse_utimens.hpp" +#include "fuse_write.hpp" +#include "fuse_write_buf.hpp" + #include -#include #include #include -#include "fs_path.hpp" -#include "mergerfs.hpp" -#include "option_parser.hpp" -#include "resources.hpp" +#include -#include "access.hpp" -#include "chmod.hpp" -#include "chown.hpp" -#include "create.hpp" -#include "destroy.hpp" -#include "fallocate.hpp" -#include "fgetattr.hpp" -#include "flock.hpp" -#include "flush.hpp" -#include "fsync.hpp" -#include "fsyncdir.hpp" -#include "ftruncate.hpp" -#include "getattr.hpp" -#include "getxattr.hpp" -#include "init.hpp" -#include "ioctl.hpp" -#include "link.hpp" -#include "listxattr.hpp" -#include "mkdir.hpp" -#include "mknod.hpp" -#include "open.hpp" -#include "opendir.hpp" -#include "read.hpp" -#include "read_buf.hpp" -#include "readdir.hpp" -#include "readlink.hpp" -#include "release.hpp" -#include "releasedir.hpp" -#include "removexattr.hpp" -#include "rename.hpp" -#include "rmdir.hpp" -#include "setxattr.hpp" -#include "statfs.hpp" -#include "symlink.hpp" -#include "truncate.hpp" -#include "unlink.hpp" -#include "utimens.hpp" -#include "write.hpp" -#include "write_buf.hpp" - -namespace local +namespace l { static void @@ -76,58 +77,58 @@ namespace local ops.flag_nopath = true; ops.flag_utime_omit_ok = true; - ops.access = mergerfs::fuse::access; + ops.access = FUSE::access; ops.bmap = NULL; - ops.chmod = mergerfs::fuse::chmod; - ops.chown = mergerfs::fuse::chown; - ops.create = mergerfs::fuse::create; - ops.destroy = mergerfs::fuse::destroy; - ops.fallocate = mergerfs::fuse::fallocate; - ops.fgetattr = mergerfs::fuse::fgetattr; - ops.flock = mergerfs::fuse::flock; - ops.flush = mergerfs::fuse::flush; - ops.fsync = mergerfs::fuse::fsync; - ops.fsyncdir = mergerfs::fuse::fsyncdir; - ops.ftruncate = mergerfs::fuse::ftruncate; - ops.getattr = mergerfs::fuse::getattr; + ops.chmod = FUSE::chmod; + ops.chown = FUSE::chown; + ops.create = FUSE::create; + ops.destroy = FUSE::destroy; + ops.fallocate = FUSE::fallocate; + ops.fgetattr = FUSE::fgetattr; + ops.flock = FUSE::flock; + ops.flush = FUSE::flush; + ops.fsync = FUSE::fsync; + ops.fsyncdir = FUSE::fsyncdir; + ops.ftruncate = FUSE::ftruncate; + ops.getattr = FUSE::getattr; ops.getdir = NULL; /* deprecated; use readdir */ - ops.getxattr = mergerfs::fuse::getxattr; - ops.init = mergerfs::fuse::init; - ops.ioctl = mergerfs::fuse::ioctl; - ops.link = mergerfs::fuse::link; - ops.listxattr = mergerfs::fuse::listxattr; + ops.getxattr = FUSE::getxattr; + ops.init = FUSE::init; + ops.ioctl = FUSE::ioctl; + ops.link = FUSE::link; + ops.listxattr = FUSE::listxattr; ops.lock = NULL; - ops.mkdir = mergerfs::fuse::mkdir; - ops.mknod = mergerfs::fuse::mknod; - ops.open = mergerfs::fuse::open; - ops.opendir = mergerfs::fuse::opendir; + ops.mkdir = FUSE::mkdir; + ops.mknod = FUSE::mknod; + ops.open = FUSE::open; + ops.opendir = FUSE::opendir; ops.poll = NULL; ops.read = (nullrw ? - mergerfs::fuse::read_null : - mergerfs::fuse::read); + FUSE::read_null : + FUSE::read); ops.read_buf = (nullrw ? NULL : - mergerfs::fuse::read_buf); - ops.readdir = mergerfs::fuse::readdir; - ops.readlink = mergerfs::fuse::readlink; - ops.release = mergerfs::fuse::release; - ops.releasedir = mergerfs::fuse::releasedir; - ops.removexattr = mergerfs::fuse::removexattr; - ops.rename = mergerfs::fuse::rename; - ops.rmdir = mergerfs::fuse::rmdir; - ops.setxattr = mergerfs::fuse::setxattr; - ops.statfs = mergerfs::fuse::statfs; - ops.symlink = mergerfs::fuse::symlink; - ops.truncate = mergerfs::fuse::truncate; - ops.unlink = mergerfs::fuse::unlink; + FUSE::read_buf); + ops.readdir = FUSE::readdir; + ops.readlink = FUSE::readlink; + ops.release = FUSE::release; + ops.releasedir = FUSE::releasedir; + ops.removexattr = FUSE::removexattr; + ops.rename = FUSE::rename; + ops.rmdir = FUSE::rmdir; + ops.setxattr = FUSE::setxattr; + ops.statfs = FUSE::statfs; + ops.symlink = FUSE::symlink; + ops.truncate = FUSE::truncate; + ops.unlink = FUSE::unlink; ops.utime = NULL; /* deprecated; use utimens() */ - ops.utimens = mergerfs::fuse::utimens; + ops.utimens = FUSE::utimens; ops.write = (nullrw ? - mergerfs::fuse::write_null : - mergerfs::fuse::write); + FUSE::write_null : + FUSE::write); ops.write_buf = (nullrw ? - mergerfs::fuse::write_buf_null : - mergerfs::fuse::write_buf); + FUSE::write_buf_null : + FUSE::write_buf); return; } @@ -139,31 +140,28 @@ namespace local const int prio = -10; std::srand(time(NULL)); - mergerfs::resources::reset_umask(); - mergerfs::resources::maxout_rlimit_nofile(); - mergerfs::resources::maxout_rlimit_fsize(); - mergerfs::resources::setpriority(prio); + resources::reset_umask(); + resources::maxout_rlimit_nofile(); + resources::maxout_rlimit_fsize(); + resources::setpriority(prio); } -} -namespace mergerfs -{ int - main(const int argc, - char **argv) + main(const int argc_, + char **argv_) { fuse_args args; fuse_operations ops = {0}; Config config; - args.argc = argc; - args.argv = argv; + args.argc = argc_; + args.argv = argv_; args.allocated = 0; - mergerfs::options::parse(args,config); + options::parse(args,config); - local::setup_resources(); - local::get_fuse_operations(ops,config.nullrw); + l::setup_resources(); + l::get_fuse_operations(ops,config.nullrw); return fuse_main(args.argc, args.argv, @@ -176,5 +174,5 @@ int main(int argc, char **argv) { - return mergerfs::main(argc,argv); + return l::main(argc,argv); } diff --git a/src/mkdir.cpp b/src/mkdir.cpp deleted file mode 100644 index 3b2170f2..00000000 --- a/src/mkdir.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/* - Copyright (c) 2016, Antonio SJ Musumeci - - 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 - -#include -#include - -#include "config.hpp" -#include "errno.hpp" -#include "fs_acl.hpp" -#include "fs_base_mkdir.hpp" -#include "fs_clonepath.hpp" -#include "fs_path.hpp" -#include "rv.hpp" -#include "rwlock.hpp" -#include "ugid.hpp" - -using std::string; -using std::vector; -using namespace mergerfs; - -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; - - fs::path::make(&createpath,fusepath,fullpath); - - rv = _mkdir_core(fullpath,mode,umask); - - return error::calc(rv,error,errno); -} - -static -int -_mkdir_loop(const string &existingpath, - const vector &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 = _mkdir_loop_core(*createpaths[i], - fusepath, - mode,umask,error); - } - - return -error; -} - -static -int -_mkdir(Policy::Func::Search searchFunc, - Policy::Func::Create createFunc, - const Branches &branches_, - const uint64_t minfreespace, - const char *fusepath, - const mode_t mode, - const mode_t umask) -{ - int rv; - string fusedirpath; - vector createpaths; - vector existingpaths; - - fusedirpath = fs::path::dirname(fusepath); - - rv = searchFunc(branches_,fusedirpath,minfreespace,existingpaths); - if(rv == -1) - return -errno; - - rv = createFunc(branches_,fusedirpath,minfreespace,createpaths); - if(rv == -1) - return -errno; - - return _mkdir_loop(*existingpaths[0],createpaths, - fusepath,fusedirpath,mode,umask); -} - -namespace mergerfs -{ - namespace fuse - { - int - mkdir(const char *fusepath, - mode_t mode) - { - const fuse_context *fc = fuse_get_context(); - const Config &config = Config::get(fc); - const ugid::Set ugid(fc->uid,fc->gid); - const rwlock::ReadGuard readlock(&config.branches_lock); - - return _mkdir(config.getattr, - config.mkdir, - config.branches, - config.minfreespace, - fusepath, - mode, - fc->umask); - } - } -} diff --git a/src/mkdir.hpp b/src/mkdir.hpp deleted file mode 100644 index 4837e400..00000000 --- a/src/mkdir.hpp +++ /dev/null @@ -1,27 +0,0 @@ -/* - Copyright (c) 2016, Antonio SJ Musumeci - - 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 - -namespace mergerfs -{ - namespace fuse - { - int - mkdir(const char *fusepath, - mode_t mode); - } -} diff --git a/src/mknod.cpp b/src/mknod.cpp deleted file mode 100644 index 829f7a0a..00000000 --- a/src/mknod.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* - Copyright (c) 2016, Antonio SJ Musumeci - - 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 - -#include -#include - -#include "config.hpp" -#include "errno.hpp" -#include "fs_acl.hpp" -#include "fs_base_mknod.hpp" -#include "fs_clonepath.hpp" -#include "fs_path.hpp" -#include "rv.hpp" -#include "rwlock.hpp" -#include "ugid.hpp" - -using std::string; -using std::vector; -using namespace mergerfs; - -static -inline -int -_mknod_core(const string &fullpath, - mode_t mode, - const mode_t umask, - const dev_t dev) -{ - if(!fs::acl::dir_has_defaults(fullpath)) - mode &= ~umask; - - return fs::mknod(fullpath,mode,dev); -} - -static -int -_mknod_loop_core(const string &createpath, - const char *fusepath, - const mode_t mode, - const mode_t umask, - const dev_t dev, - const int error) -{ - int rv; - string fullpath; - - fs::path::make(&createpath,fusepath,fullpath); - - rv = _mknod_core(fullpath,mode,umask,dev); - - return error::calc(rv,error,errno); -} - -static -int -_mknod_loop(const string &existingpath, - const vector &createpaths, - const char *fusepath, - const string &fusedirpath, - const mode_t mode, - const mode_t umask, - const dev_t dev) -{ - 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 = _mknod_loop_core(*createpaths[i], - fusepath, - mode,umask,dev,error); - } - - return -error; -} - -static -int -_mknod(Policy::Func::Search searchFunc, - Policy::Func::Create createFunc, - const Branches &branches_, - const uint64_t minfreespace, - const char *fusepath, - const mode_t mode, - const mode_t umask, - const dev_t dev) -{ - int rv; - string fusedirpath; - vector createpaths; - vector existingpaths; - - fusedirpath = fs::path::dirname(fusepath); - - rv = searchFunc(branches_,fusedirpath,minfreespace,existingpaths); - if(rv == -1) - return -errno; - - rv = createFunc(branches_,fusedirpath,minfreespace,createpaths); - if(rv == -1) - return -errno; - - return _mknod_loop(*existingpaths[0],createpaths, - fusepath,fusedirpath, - mode,umask,dev); -} - -namespace mergerfs -{ - namespace fuse - { - int - mknod(const char *fusepath, - mode_t mode, - dev_t rdev) - { - const fuse_context *fc = fuse_get_context(); - const Config &config = Config::get(fc); - const ugid::Set ugid(fc->uid,fc->gid); - const rwlock::ReadGuard readlock(&config.branches_lock); - - return _mknod(config.getattr, - config.mknod, - config.branches, - config.minfreespace, - fusepath, - mode, - fc->umask, - rdev); - } - } -} diff --git a/src/mknod.hpp b/src/mknod.hpp deleted file mode 100644 index cc7237ff..00000000 --- a/src/mknod.hpp +++ /dev/null @@ -1,29 +0,0 @@ - -/* - Copyright (c) 2016, Antonio SJ Musumeci - - 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 - -namespace mergerfs -{ - namespace fuse - { - int - mknod(const char *fusepath, - mode_t mode, - dev_t rdev); - } -} diff --git a/src/opendir.cpp b/src/opendir.cpp deleted file mode 100644 index d9d02ee6..00000000 --- a/src/opendir.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* - Copyright (c) 2016, Antonio SJ Musumeci - - 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 "dirinfo.hpp" - -#include - -namespace mergerfs -{ - namespace fuse - { - int - opendir(const char *fusepath_, - fuse_file_info *ffi_) - { - ffi_->fh = reinterpret_cast(new DirInfo(fusepath_)); - - return 0; - } - } -} diff --git a/src/option_parser.cpp b/src/option_parser.cpp index c496bf8e..eb2296a9 100644 --- a/src/option_parser.cpp +++ b/src/option_parser.cpp @@ -39,7 +39,6 @@ using std::string; using std::vector; -using namespace mergerfs; enum { @@ -454,33 +453,29 @@ option_processor(void *data, return rv; } -namespace mergerfs +namespace options { - namespace options + void + parse(fuse_args &args, + Config &config) { - void - parse(fuse_args &args, - Config &config) - { - const struct fuse_opt opts[] = - { - FUSE_OPT_KEY("-h",MERGERFS_OPT_HELP), - FUSE_OPT_KEY("--help",MERGERFS_OPT_HELP), - FUSE_OPT_KEY("-v",MERGERFS_OPT_VERSION), - FUSE_OPT_KEY("-V",MERGERFS_OPT_VERSION), - FUSE_OPT_KEY("--version",MERGERFS_OPT_VERSION), - {NULL,-1U,0} - }; - - - fuse_opt_parse(&args, - &config, - opts, - ::option_processor); - - set_default_options(args); - set_fsname(args,config.branches); - set_subtype(args); - } + const struct fuse_opt opts[] = + { + FUSE_OPT_KEY("-h",MERGERFS_OPT_HELP), + FUSE_OPT_KEY("--help",MERGERFS_OPT_HELP), + FUSE_OPT_KEY("-v",MERGERFS_OPT_VERSION), + FUSE_OPT_KEY("-V",MERGERFS_OPT_VERSION), + FUSE_OPT_KEY("--version",MERGERFS_OPT_VERSION), + {NULL,-1U,0} + }; + + fuse_opt_parse(&args, + &config, + opts, + ::option_processor); + + set_default_options(args); + set_fsname(args,config.branches); + set_subtype(args); } } diff --git a/src/option_parser.hpp b/src/option_parser.hpp index a76bb227..28c582a4 100644 --- a/src/option_parser.hpp +++ b/src/option_parser.hpp @@ -16,16 +16,13 @@ #pragma once -#include - #include "config.hpp" -namespace mergerfs +#include + +namespace options { - namespace options - { - void - parse(fuse_args &args, - Config &config); - } + void + parse(fuse_args &args, + Config &config); } diff --git a/src/policy_cache.cpp b/src/policy_cache.cpp index 55764275..6dbab69e 100644 --- a/src/policy_cache.cpp +++ b/src/policy_cache.cpp @@ -13,7 +13,7 @@ using std::vector; static const uint64_t DEFAULT_TIMEOUT = 0; -namespace local +namespace l { static uint64_t @@ -62,7 +62,7 @@ PolicyCache::cleanup(const int prob_) if(rand() % prob_) return; - now = local::get_time(); + now = l::get_time(); pthread_mutex_lock(&_lock); @@ -103,7 +103,7 @@ PolicyCache::operator()(Policy::Func::Search &func_, if(timeout == 0) return func_(branches_,fusepath_,minfreespace_,branch_); - now = local::get_time(); + now = l::get_time(); pthread_mutex_lock(&_lock); v = &_cache[fusepath_]; diff --git a/src/policy_newest.cpp b/src/policy_newest.cpp index f4f8a249..3151bd1d 100644 --- a/src/policy_newest.cpp +++ b/src/policy_newest.cpp @@ -56,7 +56,7 @@ namespace newest { branch = &branches_[i]; - if(!fs::exists(branch->path,fusepath,st)) + if(!fs::exists(branch->path,fusepath,&st)) error_and_continue(error,ENOENT); if(branch->ro_or_nc()) error_and_continue(error,EROFS); @@ -103,7 +103,7 @@ namespace newest { branch = &branches_[i]; - if(!fs::exists(branch->path,fusepath,st)) + if(!fs::exists(branch->path,fusepath,&st)) error_and_continue(error,ENOENT); if(branch->ro()) error_and_continue(error,EROFS); @@ -144,7 +144,7 @@ namespace newest { branch = &branches_[i]; - if(!fs::exists(branch->path,fusepath,st)) + if(!fs::exists(branch->path,fusepath,&st)) continue; if(st.st_mtime < newest) continue; diff --git a/src/read.hpp b/src/read.hpp deleted file mode 100644 index 0a2cf7f9..00000000 --- a/src/read.hpp +++ /dev/null @@ -1,44 +0,0 @@ -/* - Copyright (c) 2016, Antonio SJ Musumeci - - 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 - -namespace mergerfs -{ - namespace fuse - { - int - read(const char *fusepath, - char *buf, - size_t count, - off_t offset, - fuse_file_info *fi); - - int - read_direct_io(const char *fusepath, - char *buf, - size_t count, - off_t offset, - fuse_file_info *fi); - - int - read_null(const char *fusepath, - char *buf, - size_t count, - off_t offset, - fuse_file_info *fi); - } -} diff --git a/src/readdir.cpp b/src/readdir.cpp deleted file mode 100644 index 29ad9411..00000000 --- a/src/readdir.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/* - Copyright (c) 2016, Antonio SJ Musumeci - - 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. -*/ - -#define _DEFAULT_SOURCE - -#include - -#include -#include - -#include "config.hpp" -#include "dirinfo.hpp" -#include "errno.hpp" -#include "fs_base_closedir.hpp" -#include "fs_base_dirfd.hpp" -#include "fs_base_opendir.hpp" -#include "fs_base_readdir.hpp" -#include "fs_base_stat.hpp" -#include "fs_devid.hpp" -#include "fs_inode.hpp" -#include "fs_path.hpp" -#include "hashset.hpp" -#include "readdir.hpp" -#include "rwlock.hpp" -#include "ugid.hpp" - -using std::string; -using std::vector; - -#define NO_OFFSET 0 - -static -int -_readdir(const Branches &branches_, - const char *dirname, - void *buf, - const fuse_fill_dir_t filler) -{ - HashSet names; - string basepath; - struct stat st = {0}; - - for(size_t i = 0, ei = branches_.size(); i != ei; i++) - { - int rv; - int dirfd; - DIR *dh; - - basepath = fs::path::make(&branches_[i].path,dirname); - - dh = fs::opendir(basepath); - if(!dh) - continue; - - dirfd = fs::dirfd(dh); - st.st_dev = fs::devid(dirfd); - if(st.st_dev == (dev_t)-1) - st.st_dev = i; - - rv = 0; - for(struct dirent *de = fs::readdir(dh); de && !rv; de = fs::readdir(dh)) - { - rv = names.put(de->d_name); - if(rv == 0) - continue; - - st.st_ino = de->d_ino; - st.st_mode = DTTOIF(de->d_type); - - fs::inode::recompute(st); - - rv = filler(buf,de->d_name,&st,NO_OFFSET); - if(rv) - return (fs::closedir(dh),-ENOMEM); - } - - fs::closedir(dh); - } - - return 0; -} - -namespace mergerfs -{ - namespace fuse - { - int - readdir(const char *fusepath, - void *buf, - fuse_fill_dir_t filler, - off_t offset, - fuse_file_info *ffi) - { - DirInfo *di = reinterpret_cast(ffi->fh); - const fuse_context *fc = fuse_get_context(); - const Config &config = Config::get(fc); - const ugid::Set ugid(fc->uid,fc->gid); - const rwlock::ReadGuard readlock(&config.branches_lock); - - return ::_readdir(config.branches, - di->fusepath.c_str(), - buf, - filler); - } - } -} diff --git a/src/readlink.cpp b/src/readlink.cpp deleted file mode 100644 index 42ae3007..00000000 --- a/src/readlink.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/* - Copyright (c) 2016, Antonio SJ Musumeci - - 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 - -#include - -#include "config.hpp" -#include "errno.hpp" -#include "fs_base_readlink.hpp" -#include "fs_base_stat.hpp" -#include "fs_path.hpp" -#include "rwlock.hpp" -#include "symlinkify.hpp" -#include "ugid.hpp" - -using std::string; -using std::vector; - -static -int -_readlink_core_standard(const string &fullpath, - char *buf, - const size_t size) - -{ - int rv; - - rv = fs::readlink(fullpath,buf,size); - if(rv == -1) - return -errno; - - buf[rv] = '\0'; - - return 0; -} - -static -int -_readlink_core_symlinkify(const string &fullpath, - char *buf, - const size_t size, - const time_t symlinkify_timeout) -{ - int rv; - struct stat st; - - rv = fs::stat(fullpath,st); - if(rv == -1) - return -errno; - - if(!symlinkify::can_be_symlink(st,symlinkify_timeout)) - return _readlink_core_standard(fullpath,buf,size); - - strncpy(buf,fullpath.c_str(),size); - - return 0; -} - -static -int -_readlink_core(const string *basepath, - const char *fusepath, - char *buf, - const size_t size, - const bool symlinkify, - const time_t symlinkify_timeout) -{ - string fullpath; - - fs::path::make(basepath,fusepath,fullpath); - - if(symlinkify) - return _readlink_core_symlinkify(fullpath,buf,size,symlinkify_timeout); - - return _readlink_core_standard(fullpath,buf,size); -} - -static -int -_readlink(Policy::Func::Search searchFunc, - const Branches &branches_, - const uint64_t minfreespace, - const char *fusepath, - char *buf, - const size_t size, - const bool symlinkify, - const time_t symlinkify_timeout) -{ - int rv; - vector basepaths; - - rv = searchFunc(branches_,fusepath,minfreespace,basepaths); - if(rv == -1) - return -errno; - - return _readlink_core(basepaths[0],fusepath,buf,size, - symlinkify,symlinkify_timeout); -} - -namespace mergerfs -{ - namespace fuse - { - int - readlink(const char *fusepath, - char *buf, - size_t size) - { - const fuse_context *fc = fuse_get_context(); - const Config &config = Config::get(fc); - const ugid::Set ugid(fc->uid,fc->gid); - const rwlock::ReadGuard readlock(&config.branches_lock); - - return _readlink(config.readlink, - config.branches, - config.minfreespace, - fusepath, - buf, - size, - config.symlinkify, - config.symlinkify_timeout); - } - } -} diff --git a/src/readlink.hpp b/src/readlink.hpp deleted file mode 100644 index e36bac71..00000000 --- a/src/readlink.hpp +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (c) 2016, Antonio SJ Musumeci - - 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 - -namespace mergerfs -{ - namespace fuse - { - int - readlink(const char *fusepath, - char *buf, - size_t size); - } -} diff --git a/src/release.hpp b/src/release.hpp deleted file mode 100644 index a74ba121..00000000 --- a/src/release.hpp +++ /dev/null @@ -1,27 +0,0 @@ -/* - Copyright (c) 2016, Antonio SJ Musumeci - - 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 - -namespace mergerfs -{ - namespace fuse - { - int - release(const char *fusepath, - fuse_file_info *fi); - } -} diff --git a/src/removexattr.cpp b/src/removexattr.cpp deleted file mode 100644 index 31561973..00000000 --- a/src/removexattr.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - Copyright (c) 2016, Antonio SJ Musumeci - - 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 - -#include -#include - -#include "config.hpp" -#include "errno.hpp" -#include "fs_base_removexattr.hpp" -#include "fs_path.hpp" -#include "rv.hpp" -#include "rwlock.hpp" -#include "ugid.hpp" - -using std::string; -using std::vector; - -static -int -_removexattr_loop_core(const string *basepath, - const char *fusepath, - const char *attrname, - const int error) -{ - int rv; - string fullpath; - - fs::path::make(basepath,fusepath,fullpath); - - rv = fs::lremovexattr(fullpath,attrname); - - return error::calc(rv,error,errno); -} - -static -int -_removexattr_loop(const vector &basepaths, - const char *fusepath, - const char *attrname) -{ - int error; - - error = -1; - - for(size_t i = 0, ei = basepaths.size(); i != ei; i++) - { - error = _removexattr_loop_core(basepaths[i],fusepath,attrname,error); - } - - return -error; -} - -static -int -_removexattr(Policy::Func::Action actionFunc, - const Branches &branches_, - const uint64_t minfreespace, - const char *fusepath, - const char *attrname) -{ - int rv; - vector basepaths; - - rv = actionFunc(branches_,fusepath,minfreespace,basepaths); - if(rv == -1) - return -errno; - - return _removexattr_loop(basepaths,fusepath,attrname); -} - -namespace mergerfs -{ - namespace fuse - { - int - removexattr(const char *fusepath, - const char *attrname) - { - const fuse_context *fc = fuse_get_context(); - const Config &config = Config::get(fc); - - if(fusepath == config.controlfile) - return -ENOATTR; - if(config.xattr) - return -config.xattr; - - const ugid::Set ugid(fc->uid,fc->gid); - const rwlock::ReadGuard readlock(&config.branches_lock); - - return _removexattr(config.removexattr, - config.branches, - config.minfreespace, - fusepath, - attrname); - } - } -} diff --git a/src/removexattr.hpp b/src/removexattr.hpp deleted file mode 100644 index 38e970e2..00000000 --- a/src/removexattr.hpp +++ /dev/null @@ -1,27 +0,0 @@ -/* - Copyright (c) 2016, Antonio SJ Musumeci - - 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 - -namespace mergerfs -{ - namespace fuse - { - int - removexattr(const char *fusepath, - const char *attrname); - } -} diff --git a/src/resources.cpp b/src/resources.cpp index 4af7b912..734b25a4 100644 --- a/src/resources.cpp +++ b/src/resources.cpp @@ -20,63 +20,60 @@ #include #include -namespace mergerfs +namespace resources { - namespace resources + int + reset_umask(void) { - int - reset_umask(void) - { - umask(0); - return 0; - } + umask(0); + return 0; + } - int - maxout_rlimit(const int resource) - { - int rv; - struct rlimit rlim; + int + maxout_rlimit(const int resource) + { + int rv; + struct rlimit rlim; - rlim.rlim_cur = RLIM_INFINITY; - rlim.rlim_max = RLIM_INFINITY; - rv = ::setrlimit(resource,&rlim); - if(rv == 0) - return 0; + rlim.rlim_cur = RLIM_INFINITY; + rlim.rlim_max = RLIM_INFINITY; + rv = ::setrlimit(resource,&rlim); + if(rv == 0) + return 0; - rv = ::getrlimit(resource,&rlim); - if(rv == -1) - return -1; + rv = ::getrlimit(resource,&rlim); + if(rv == -1) + return -1; - rv = 0; - rlim.rlim_cur = rlim.rlim_max; - while(rv == 0) - { - rv = ::setrlimit(resource,&rlim); - rlim.rlim_max *= 2; - rlim.rlim_cur = rlim.rlim_max; - } + rv = 0; + rlim.rlim_cur = rlim.rlim_max; + while(rv == 0) + { + rv = ::setrlimit(resource,&rlim); + rlim.rlim_max *= 2; + rlim.rlim_cur = rlim.rlim_max; + } - return rv; - } + return rv; + } - int - maxout_rlimit_nofile(void) - { - return maxout_rlimit(RLIMIT_NOFILE); - } + int + maxout_rlimit_nofile(void) + { + return maxout_rlimit(RLIMIT_NOFILE); + } - int - maxout_rlimit_fsize(void) - { - return maxout_rlimit(RLIMIT_FSIZE); - } + int + maxout_rlimit_fsize(void) + { + return maxout_rlimit(RLIMIT_FSIZE); + } - int - setpriority(const int prio) - { - const int SELF = 0; + int + setpriority(const int prio) + { + const int SELF = 0; - return ::setpriority(PRIO_PROCESS,SELF,prio); - } + return ::setpriority(PRIO_PROCESS,SELF,prio); } } diff --git a/src/resources.hpp b/src/resources.hpp index 160802c8..faafaeff 100644 --- a/src/resources.hpp +++ b/src/resources.hpp @@ -16,14 +16,11 @@ #pragma once -namespace mergerfs +namespace resources { - namespace resources - { - int reset_umask(void); - int maxout_rlimit(const int resource); - int maxout_rlimit_nofile(void); - int maxout_rlimit_fsize(void); - int setpriority(const int prio); - } + int reset_umask(void); + int maxout_rlimit(const int resource_); + int maxout_rlimit_nofile(void); + int maxout_rlimit_fsize(void); + int setpriority(const int prio_); } diff --git a/src/rmdir.cpp b/src/rmdir.cpp deleted file mode 100644 index 923e9b15..00000000 --- a/src/rmdir.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - Copyright (c) 2016, Antonio SJ Musumeci - - 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 - -#include - -#include - -#include "config.hpp" -#include "errno.hpp" -#include "fs_base_rmdir.hpp" -#include "fs_path.hpp" -#include "rv.hpp" -#include "rwlock.hpp" -#include "ugid.hpp" - -using std::string; -using std::vector; - -static -int -_rmdir_loop_core(const string *basepath, - const char *fusepath, - const int error) -{ - int rv; - string fullpath; - - fs::path::make(basepath,fusepath,fullpath); - - rv = fs::rmdir(fullpath); - - return error::calc(rv,error,errno); -} - - -static -int -_rmdir_loop(const vector &basepaths, - const char *fusepath) -{ - int error; - - error = -1; - for(size_t i = 0, ei = basepaths.size(); i != ei; i++) - { - error = _rmdir_loop_core(basepaths[i],fusepath,error); - } - - return -error; -} - -static -int -_rmdir(Policy::Func::Action actionFunc, - const Branches &branches_, - const uint64_t minfreespace, - const char *fusepath) -{ - int rv; - vector basepaths; - - rv = actionFunc(branches_,fusepath,minfreespace,basepaths); - if(rv == -1) - return -errno; - - return _rmdir_loop(basepaths,fusepath); -} - -namespace mergerfs -{ - namespace fuse - { - int - rmdir(const char *fusepath) - { - const fuse_context *fc = fuse_get_context(); - const Config &config = Config::get(fc); - const ugid::Set ugid(fc->uid,fc->gid); - const rwlock::ReadGuard readguard(&config.branches_lock); - - return _rmdir(config.rmdir, - config.branches, - config.minfreespace, - fusepath); - } - } -} diff --git a/src/rwlock.hpp b/src/rwlock.hpp index 54aeee2b..a810ed22 100644 --- a/src/rwlock.hpp +++ b/src/rwlock.hpp @@ -18,50 +18,47 @@ #include -namespace mergerfs +namespace rwlock { - namespace rwlock + class ReadGuard { - class ReadGuard + public: + ReadGuard(pthread_rwlock_t *lock_) + : _lock(lock_) { - public: - ReadGuard(pthread_rwlock_t *lock) - { - _lock = lock; - pthread_rwlock_rdlock(_lock); - } + pthread_rwlock_rdlock(_lock); + } - ~ReadGuard() - { - pthread_rwlock_unlock(_lock); - } + ~ReadGuard() + { + pthread_rwlock_unlock(_lock); + } - private: - ReadGuard(); + private: + ReadGuard(); - private: - pthread_rwlock_t *_lock; - }; + private: + pthread_rwlock_t *_lock; + }; - class WriteGuard + class WriteGuard + { + public: + WriteGuard(pthread_rwlock_t *lock_) + : _lock(lock_) { - public: - WriteGuard(pthread_rwlock_t *lock) - { - _lock = lock; - pthread_rwlock_wrlock(_lock); - } + pthread_rwlock_wrlock(_lock); + } - ~WriteGuard() - { - pthread_rwlock_unlock(_lock); - } + ~WriteGuard() + { + pthread_rwlock_unlock(_lock); + } - private: - WriteGuard(); + private: + WriteGuard(); - private: - pthread_rwlock_t *_lock; - }; - } + private: + pthread_rwlock_t *_lock; + }; } diff --git a/src/setxattr.cpp b/src/setxattr.cpp deleted file mode 100644 index c27963e7..00000000 --- a/src/setxattr.cpp +++ /dev/null @@ -1,482 +0,0 @@ -/* - Copyright (c) 2018, Antonio SJ Musumeci - - 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 "config.hpp" -#include "errno.hpp" -#include "fs_base_setxattr.hpp" -#include "fs_glob.hpp" -#include "fs_path.hpp" -#include "fs_statvfs_cache.hpp" -#include "num.hpp" -#include "rv.hpp" -#include "rwlock.hpp" -#include "str.hpp" -#include "ugid.hpp" - -#include - -#include -#include -#include - -#include - -static const char SECURITY_CAPABILITY[] = "security.capability"; - -using std::string; -using std::vector; -using mergerfs::FuseFunc; -using namespace mergerfs; - -static -bool -_is_attrname_security_capability(const char *attrname_) -{ - return (strcmp(attrname_,SECURITY_CAPABILITY) == 0); -} - -static -void -_split_attrval(const string &attrval, - string &instruction, - string &values) -{ - size_t offset; - - offset = attrval.find_first_of('/'); - instruction = attrval.substr(0,offset); - if(offset != string::npos) - values = attrval.substr(offset); -} - -static -int -_setxattr_srcmounts(const string &attrval, - const int flags, - Branches &branches_, - pthread_rwlock_t &branches_lock) -{ - const rwlock::WriteGuard wrg(&branches_lock); - - string instruction; - string values; - - if((flags & XATTR_CREATE) == XATTR_CREATE) - return -EEXIST; - - _split_attrval(attrval,instruction,values); - - if(instruction == "+") - branches_.add_end(values); - else if(instruction == "+<") - branches_.add_begin(values); - else if(instruction == "+>") - branches_.add_end(values); - else if(instruction == "-") - branches_.erase_fnmatch(values); - else if(instruction == "-<") - branches_.erase_begin(); - else if(instruction == "->") - branches_.erase_end(); - else if(instruction == "=") - branches_.set(values); - else if(instruction.empty()) - branches_.set(values); - else - return -EINVAL; - - return 0; -} - -static -int -_setxattr_uint64_t(const string &attrval, - const int flags, - uint64_t &uint) -{ - int rv; - - if((flags & XATTR_CREATE) == XATTR_CREATE) - return -EEXIST; - - rv = num::to_uint64_t(attrval,uint); - if(rv == -1) - return -EINVAL; - - return 0; -} - -static -int -_setxattr_time_t(const string &attrval, - const int flags, - time_t &time) -{ - int rv; - - if((flags & XATTR_CREATE) == XATTR_CREATE) - return -EEXIST; - - rv = num::to_time_t(attrval,time); - if(rv == -1) - return -EINVAL; - - return 0; -} - -static -int -_setxattr_bool(const string &attrval, - const int flags, - bool &value) -{ - if((flags & XATTR_CREATE) == XATTR_CREATE) - return -EEXIST; - - if(attrval == "false") - value = false; - else if(attrval == "true") - value = true; - else - return -EINVAL; - - return 0; -} - -static -int -_setxattr_xattr(const string &attrval_, - const int flags_, - int xattr_) -{ - if((flags_ & XATTR_CREATE) == XATTR_CREATE) - return -EEXIST; - - if(attrval_ == "passthrough") - xattr_ = 0; - else if(attrval_ == "noattr") - xattr_ = ENOATTR; - else if(attrval_ == "nosys") - xattr_ = ENOSYS; - else - return -EINVAL; - - return 0; -} - -static -int -_setxattr_statfs(const string &attrval_, - const int flags_, - Config::StatFS::Enum &enum_) -{ - if((flags_ & XATTR_CREATE) == XATTR_CREATE) - return -EEXIST; - - if(attrval_ == "base") - enum_ = Config::StatFS::BASE; - else if(attrval_ == "full") - enum_ = Config::StatFS::FULL; - else - return -EINVAL; - - return 0; -} - -static -int -_setxattr_statfsignore(const string &attrval_, - const int flags_, - Config::StatFSIgnore::Enum &enum_) -{ - if((flags_ & XATTR_CREATE) == XATTR_CREATE) - return -EEXIST; - - if(attrval_ == "none") - enum_ = Config::StatFSIgnore::NONE; - else if(attrval_ == "ro") - enum_ = Config::StatFSIgnore::RO; - else if(attrval_ == "nc") - enum_ = Config::StatFSIgnore::NC; - else - return -EINVAL; - - return 0; -} - -static -int -_setxattr_controlfile_func_policy(Config &config, - const string &funcname, - const string &attrval, - const int flags) -{ - int rv; - - if((flags & XATTR_CREATE) == XATTR_CREATE) - return -EEXIST; - - if(funcname == "open") - config.open_cache.clear(); - - rv = config.set_func_policy(funcname,attrval); - if(rv == -1) - return -errno; - - return 0; -} - -static -int -_setxattr_controlfile_category_policy(Config &config, - const string &categoryname, - const string &attrval, - const int flags) -{ - int rv; - - if((flags & XATTR_CREATE) == XATTR_CREATE) - return -EEXIST; - - if(categoryname == "search") - config.open_cache.clear(); - - rv = config.set_category_policy(categoryname,attrval); - if(rv == -1) - return -errno; - - return 0; -} - -static -int -_setxattr_statfs_timeout(const string &attrval_, - const int flags_) -{ - int rv; - uint64_t timeout; - - rv = _setxattr_uint64_t(attrval_,flags_,timeout); - if(rv >= 0) - fs::statvfs_cache_timeout(timeout); - - return rv; -} - -static -int -_setxattr_controlfile(Config &config, - const string &attrname, - const string &attrval, - const int flags) -{ - vector attr; - - str::split(attr,attrname,'.'); - - switch(attr.size()) - { - case 3: - if(attr[2] == "srcmounts") - return _setxattr_srcmounts(attrval, - flags, - config.branches, - config.branches_lock); - else if(attr[2] == "branches") - return _setxattr_srcmounts(attrval, - flags, - config.branches, - config.branches_lock); - else if(attr[2] == "minfreespace") - return _setxattr_uint64_t(attrval, - flags, - config.minfreespace); - else if(attr[2] == "moveonenospc") - return _setxattr_bool(attrval, - flags, - config.moveonenospc); - else if(attr[2] == "dropcacheonclose") - return _setxattr_bool(attrval, - flags, - config.dropcacheonclose); - else if(attr[2] == "symlinkify") - return _setxattr_bool(attrval, - flags, - config.symlinkify); - else if(attr[2] == "symlinkify_timeout") - return _setxattr_time_t(attrval, - flags, - config.symlinkify_timeout); - else if(attr[2] == "ignorepponrename") - return _setxattr_bool(attrval, - flags, - config.ignorepponrename); - else if(attr[2] == "security_capability") - return _setxattr_bool(attrval, - flags, - config.security_capability); - else if(attr[2] == "xattr") - return _setxattr_xattr(attrval, - flags, - config.xattr); - else if(attr[2] == "link_cow") - return _setxattr_bool(attrval, - flags, - config.link_cow); - else if(attr[2] == "statfs") - return _setxattr_statfs(attrval, - flags, - config.statfs); - else if(attr[2] == "statfs_ignore") - return _setxattr_statfsignore(attrval, - flags, - config.statfs_ignore); - else if(attr[2] == "direct_io") - return _setxattr_bool(attrval, - flags, - config.direct_io); - break; - - case 4: - if(attr[2] == "category") - return _setxattr_controlfile_category_policy(config, - attr[3], - attrval, - flags); - else if(attr[2] == "func") - return _setxattr_controlfile_func_policy(config, - attr[3], - attrval, - flags); - else if((attr[2] == "cache") && (attr[3] == "open")) - return _setxattr_uint64_t(attrval, - flags, - config.open_cache.timeout); - else if((attr[2] == "cache") && (attr[3] == "statfs")) - return _setxattr_statfs_timeout(attrval,flags); - break; - - default: - break; - } - - return -EINVAL; -} - -static -int -_setxattr_loop_core(const string *basepath, - const char *fusepath, - const char *attrname, - const char *attrval, - const size_t attrvalsize, - const int flags, - const int error) -{ - int rv; - string fullpath; - - fs::path::make(basepath,fusepath,fullpath); - - rv = fs::lsetxattr(fullpath,attrname,attrval,attrvalsize,flags); - - return error::calc(rv,error,errno); -} - -static -int -_setxattr_loop(const vector &basepaths, - const char *fusepath, - const char *attrname, - const char *attrval, - const size_t attrvalsize, - const int flags) -{ - int error; - - error = -1; - for(size_t i = 0, ei = basepaths.size(); i != ei; i++) - { - error = _setxattr_loop_core(basepaths[i],fusepath, - attrname,attrval,attrvalsize,flags, - error); - } - - return -error; -} - -static -int -_setxattr(Policy::Func::Action actionFunc, - const Branches &branches_, - const uint64_t minfreespace, - const char *fusepath, - const char *attrname, - const char *attrval, - const size_t attrvalsize, - const int flags) -{ - int rv; - vector basepaths; - - rv = actionFunc(branches_,fusepath,minfreespace,basepaths); - if(rv == -1) - return -errno; - - return _setxattr_loop(basepaths,fusepath,attrname,attrval,attrvalsize,flags); -} - -namespace mergerfs -{ - namespace fuse - { - int - setxattr(const char *fusepath, - const char *attrname, - const char *attrval, - size_t attrvalsize, - int flags) - { - const fuse_context *fc = fuse_get_context(); - const Config &config = Config::get(fc); - - if(fusepath == config.controlfile) - return _setxattr_controlfile(Config::get_writable(), - attrname, - string(attrval,attrvalsize), - flags); - - if((config.security_capability == false) && - _is_attrname_security_capability(attrname)) - return -ENOATTR; - - if(config.xattr) - return -config.xattr; - - const ugid::Set ugid(fc->uid,fc->gid); - const rwlock::ReadGuard readlock(&config.branches_lock); - - return _setxattr(config.setxattr, - config.branches, - config.minfreespace, - fusepath, - attrname, - attrval, - attrvalsize, - flags); - } - } -} diff --git a/src/setxattr.hpp b/src/setxattr.hpp deleted file mode 100644 index e1d44901..00000000 --- a/src/setxattr.hpp +++ /dev/null @@ -1,30 +0,0 @@ -/* - Copyright (c) 2016, Antonio SJ Musumeci - - 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 - -namespace mergerfs -{ - namespace fuse - { - int - setxattr(const char *fusepath, - const char *attrname, - const char *attrval, - size_t attrvalsize, - int flags); - } -} diff --git a/src/statfs.cpp b/src/statfs.cpp deleted file mode 100644 index ce414d5d..00000000 --- a/src/statfs.cpp +++ /dev/null @@ -1,168 +0,0 @@ -/* - Copyright (c) 2018, Antonio SJ Musumeci - - 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 "config.hpp" -#include "errno.hpp" -#include "fs_base_stat.hpp" -#include "fs_base_statvfs.hpp" -#include "fs_path.hpp" -#include "rwlock.hpp" -#include "statvfs_util.hpp" -#include "ugid.hpp" - -#include - -#include -#include -#include -#include -#include - -using std::string; -using std::map; -using std::vector; -using mergerfs::Config; -typedef Config::StatFS StatFS; -typedef Config::StatFSIgnore StatFSIgnore; - -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::Enum ignore_, - const Branch *branch_, - const bool readonly_) -{ - return ((((ignore_ == StatFSIgnore::RO) || readonly_) && - (branch_->ro_or_nc())) || - ((ignore_ == StatFSIgnore::NC) && (branch_->nc()))); -} - -static -int -_statfs(const Branches &branches_, - const char *fusepath, - const StatFS::Enum mode, - const StatFSIgnore::Enum 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 fsstats; - - min_bsize = std::numeric_limits::max(); - min_frsize = std::numeric_limits::max(); - min_namemax = std::numeric_limits::max(); - for(size_t i = 0, ei = branches_.size(); i < ei; i++) - { - fullpath = ((mode == StatFS::FULL) ? - fs::path::make(&branches_[i].path,fusepath) : - branches_[i].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(_should_ignore(ignore,&branches_[i],StatVFS::readonly(stvfs))) - { - stvfs.f_bavail = 0; - stvfs.f_favail = 0; - } - - fsstats.insert(std::make_pair(st.st_dev,stvfs)); - } - - map::iterator iter = fsstats.begin(); - map::iterator enditer = fsstats.end(); - if(iter != enditer) - { - fsstat = iter->second; - _normalize_statvfs(&fsstat,min_bsize,min_frsize,min_namemax); - - for(++iter; iter != enditer; ++iter) - { - _normalize_statvfs(&iter->second,min_bsize,min_frsize,min_namemax); - _merge_statvfs(&fsstat,&iter->second); - } - } - - return 0; -} - -namespace mergerfs -{ - namespace fuse - { - int - statfs(const char *fusepath, - struct statvfs *stat) - { - const fuse_context *fc = fuse_get_context(); - const Config &config = Config::get(fc); - const ugid::Set ugid(fc->uid,fc->gid); - const rwlock::ReadGuard readlock(&config.branches_lock); - - return _statfs(config.branches, - fusepath, - config.statfs, - config.statfs_ignore, - *stat); - } - } -} diff --git a/src/statfs.hpp b/src/statfs.hpp deleted file mode 100644 index 4377ad2c..00000000 --- a/src/statfs.hpp +++ /dev/null @@ -1,27 +0,0 @@ -/* - Copyright (c) 2016, Antonio SJ Musumeci - - 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 - -namespace mergerfs -{ - namespace fuse - { - int - statfs(const char *fusepath, - struct statvfs *fsstat); - } -} diff --git a/src/symlink.cpp b/src/symlink.cpp deleted file mode 100644 index 604cf1d8..00000000 --- a/src/symlink.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/* - Copyright (c) 2016, Antonio SJ Musumeci - - 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 - -#include -#include - -#include - -#include "config.hpp" -#include "errno.hpp" -#include "fs_base_symlink.hpp" -#include "fs_clonepath.hpp" -#include "fs_path.hpp" -#include "rv.hpp" -#include "rwlock.hpp" -#include "ugid.hpp" - -using std::string; -using std::vector; -using namespace mergerfs; - -static -int -_symlink_loop_core(const string &newbasepath, - const char *oldpath, - const char *newpath, - const int error) -{ - int rv; - string fullnewpath; - - fs::path::make(&newbasepath,newpath,fullnewpath); - - rv = fs::symlink(oldpath,fullnewpath); - - return error::calc(rv,error,errno); -} - -static -int -_symlink_loop(const string &existingpath, - const vector newbasepaths, - const char *oldpath, - const char *newpath, - const string &newdirpath) -{ - 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 = _symlink_loop_core(*newbasepaths[i], - oldpath, - newpath, - error); - } - - return -error; -} - -static -int -_symlink(Policy::Func::Search searchFunc, - Policy::Func::Create createFunc, - const Branches &branches_, - const uint64_t minfreespace, - const char *oldpath, - const char *newpath) -{ - int rv; - string newdirpath; - vector newbasepaths; - vector existingpaths; - - newdirpath = fs::path::dirname(newpath); - - rv = searchFunc(branches_,newdirpath,minfreespace,existingpaths); - if(rv == -1) - return -errno; - - rv = createFunc(branches_,newdirpath,minfreespace,newbasepaths); - if(rv == -1) - return -errno; - - return _symlink_loop(*existingpaths[0],newbasepaths, - oldpath,newpath,newdirpath); -} - -namespace mergerfs -{ - namespace fuse - { - int - symlink(const char *oldpath, - const char *newpath) - { - const fuse_context *fc = fuse_get_context(); - const Config &config = Config::get(fc); - const ugid::Set ugid(fc->uid,fc->gid); - const rwlock::ReadGuard readlock(&config.branches_lock); - - return _symlink(config.getattr, - config.symlink, - config.branches, - config.minfreespace, - oldpath, - newpath); - } - } -} diff --git a/src/symlink.hpp b/src/symlink.hpp deleted file mode 100644 index 47f7cafc..00000000 --- a/src/symlink.hpp +++ /dev/null @@ -1,27 +0,0 @@ -/* - Copyright (c) 2016, Antonio SJ Musumeci - - 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 - -namespace mergerfs -{ - namespace fuse - { - int - symlink(const char *oldpath, - const char *newpath); - } -} diff --git a/src/truncate.cpp b/src/truncate.cpp deleted file mode 100644 index 70e71400..00000000 --- a/src/truncate.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/* - Copyright (c) 2016, Antonio SJ Musumeci - - 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 - -#include -#include - -#include -#include - -#include "config.hpp" -#include "errno.hpp" -#include "fs_base_truncate.hpp" -#include "fs_path.hpp" -#include "rv.hpp" -#include "rwlock.hpp" -#include "ugid.hpp" - -using std::string; -using std::vector; - -static -int -_truncate_loop_core(const string *basepath, - const char *fusepath, - const off_t size, - const int error) -{ - int rv; - string fullpath; - - fs::path::make(basepath,fusepath,fullpath); - - rv = fs::truncate(fullpath,size); - - return error::calc(rv,error,errno); -} - -static -int -_truncate_loop(const vector &basepaths, - const char *fusepath, - const off_t size) -{ - int error; - - error = -1; - for(size_t i = 0, ei = basepaths.size(); i != ei; i++) - { - error = _truncate_loop_core(basepaths[i],fusepath,size,error); - } - - return -error; -} - -static -int -_truncate(Policy::Func::Action actionFunc, - const Branches &branches_, - const uint64_t minfreespace, - const char *fusepath, - const off_t size) -{ - int rv; - vector basepaths; - - rv = actionFunc(branches_,fusepath,minfreespace,basepaths); - if(rv == -1) - return -errno; - - return _truncate_loop(basepaths,fusepath,size); -} - -namespace mergerfs -{ - namespace fuse - { - int - truncate(const char *fusepath, - off_t size) - { - const fuse_context *fc = fuse_get_context(); - const Config &config = Config::get(fc); - const ugid::Set ugid(fc->uid,fc->gid); - const rwlock::ReadGuard readlock(&config.branches_lock); - - return _truncate(config.truncate, - config.branches, - config.minfreespace, - fusepath, - size); - } - } -} diff --git a/src/utimens.cpp b/src/utimens.cpp deleted file mode 100644 index b678428f..00000000 --- a/src/utimens.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - Copyright (c) 2016, Antonio SJ Musumeci - - 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 - -#include - -#include -#include - -#include "config.hpp" -#include "errno.hpp" -#include "fs_base_utime.hpp" -#include "fs_path.hpp" -#include "rv.hpp" -#include "rwlock.hpp" -#include "ugid.hpp" - -using std::string; -using std::vector; - -static -int -_utimens_loop_core(const string *basepath, - const char *fusepath, - const timespec ts[2], - const int error) -{ - int rv; - string fullpath; - - fs::path::make(basepath,fusepath,fullpath); - - rv = fs::lutime(fullpath,ts); - - return error::calc(rv,error,errno); -} - -static -int -_utimens_loop(const vector &basepaths, - const char *fusepath, - const timespec ts[2]) -{ - int error; - - error = -1; - for(size_t i = 0, ei = basepaths.size(); i != ei; i++) - { - error = _utimens_loop_core(basepaths[i],fusepath,ts,error); - } - - return -error; -} - -static -int -_utimens(Policy::Func::Action actionFunc, - const Branches &branches_, - const uint64_t minfreespace, - const char *fusepath, - const timespec ts[2]) -{ - int rv; - vector basepaths; - - rv = actionFunc(branches_,fusepath,minfreespace,basepaths); - if(rv == -1) - return -errno; - - return _utimens_loop(basepaths,fusepath,ts); -} - -namespace mergerfs -{ - namespace fuse - { - int - utimens(const char *fusepath, - const timespec ts[2]) - { - const fuse_context *fc = fuse_get_context(); - const Config &config = Config::get(fc); - const ugid::Set ugid(fc->uid,fc->gid); - const rwlock::ReadGuard readlock(&config.branches_lock); - - return _utimens(config.utimens, - config.branches, - config.minfreespace, - fusepath, - ts); - } - } -} diff --git a/src/utimens.hpp b/src/utimens.hpp deleted file mode 100644 index 8d3b2af6..00000000 --- a/src/utimens.hpp +++ /dev/null @@ -1,27 +0,0 @@ -/* - Copyright (c) 2016, Antonio SJ Musumeci - - 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 - -namespace mergerfs -{ - namespace fuse - { - int - utimens(const char *fusepath, - const timespec ts[2]); - } -} diff --git a/src/write.hpp b/src/write.hpp deleted file mode 100644 index a2399b61..00000000 --- a/src/write.hpp +++ /dev/null @@ -1,44 +0,0 @@ -/* - Copyright (c) 2016, Antonio SJ Musumeci - - 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 - -namespace mergerfs -{ - namespace fuse - { - int - write(const char *fusepath, - const char *buf, - size_t count, - off_t offset, - fuse_file_info *fi); - - int - write_direct_io(const char *fusepath, - const char *buf, - size_t count, - off_t offset, - fuse_file_info *fi); - - int - write_null(const char *fusepath, - const char *buf, - size_t count, - off_t offset, - fuse_file_info *fi); - } -} diff --git a/src/write_buf.cpp b/src/write_buf.cpp deleted file mode 100644 index 8d2e94cc..00000000 --- a/src/write_buf.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/* - Copyright (c) 2016, Antonio SJ Musumeci - - 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 "config.hpp" -#include "errno.hpp" -#include "fileinfo.hpp" -#include "fs_movefile.hpp" -#include "policy.hpp" -#include "rwlock.hpp" -#include "ugid.hpp" -#include "write.hpp" - -#include - -#include -#include - -#include -#include - -using std::string; -using std::vector; -using namespace mergerfs; - -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); -} - -namespace mergerfs -{ - namespace fuse - { - int - write_buf(const char *fusepath, - fuse_bufvec *src, - off_t offset, - fuse_file_info *ffi) - { - int rv; - FileInfo *fi = reinterpret_cast(ffi->fh); - - rv = _write_buf(fi->fd,*src,offset); - if(_out_of_space(-rv)) - { - const fuse_context *fc = fuse_get_context(); - const Config &config = Config::get(fc); - - if(config.moveonenospc) - { - size_t extra; - vector paths; - const ugid::Set ugid(0,0); - const rwlock::ReadGuard readlock(&config.branches_lock); - - config.branches.to_paths(paths); - - extra = fuse_buf_size(src); - rv = fs::movefile(paths,fi->fusepath,extra,fi->fd); - if(rv == -1) - return -ENOSPC; - - rv = _write_buf(fi->fd,*src,offset); - } - } - - return rv; - } - - int - write_buf_null(const char *fusepath, - fuse_bufvec *src, - off_t offset, - fuse_file_info *ffi) - { - return src->buf[0].size; - } - } -} diff --git a/src/write_buf.hpp b/src/write_buf.hpp deleted file mode 100644 index e9872523..00000000 --- a/src/write_buf.hpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - Copyright (c) 2016, Antonio SJ Musumeci - - 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 - -#include - -namespace mergerfs -{ - namespace fuse - { - int - write_buf(const char *fusepath, - struct fuse_bufvec *buf, - off_t offset, - fuse_file_info *fi); - - int - write_buf_null(const char *fusepath, - struct fuse_bufvec *buf, - off_t offset, - fuse_file_info *fi); - } -}