Merge pull request #575 from trapexit/cleanup

general code cleanup
This commit is contained in:
trapexit 2019-01-31 23:50:40 -05:00 committed by GitHub
commit cfd5d31338
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
178 changed files with 5100 additions and 5255 deletions

View File

@ -17,6 +17,7 @@
#pragma once
#include <algorithm>
#include <vector>
template<typename V, bool SORT = false>
class buildvector

View File

@ -1,105 +0,0 @@
/*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <fuse.h>
#include <string>
#include <vector>
#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<const string*> &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<const string*> 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);
}
}
}

View File

@ -1,111 +0,0 @@
/*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <fuse.h>
#include <string>
#include <vector>
#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<const string*> &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<const string*> 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);
}
}
}

View File

@ -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);
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;
}
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;
}

View File

@ -23,115 +23,112 @@
#include <fuse.h>
#include <stdint.h>
#include <sys/stat.h>
#include <string>
#include <vector>
namespace mergerfs
#include <stdint.h>
#include <sys/stat.h>
class Config
{
class Config
public:
struct StatFS
{
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
{
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));
}
};

View File

@ -1,30 +0,0 @@
/*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
namespace mergerfs
{
namespace fuse
{
int
fallocate(const char *fusepath,
int mode,
off_t offset,
off_t len,
fuse_file_info *fi);
}
}

View File

@ -1,28 +0,0 @@
/*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
namespace mergerfs
{
namespace fuse
{
int
flock(const char *fusepath,
fuse_file_info *ffi,
int op);
}
}

View File

@ -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;

View File

@ -27,22 +27,22 @@ namespace fs
using std::string;
using std::vector;
void findallfiles(const vector<string> &basepaths,
const char *fusepath,
vector<string> &paths);
void findallfiles(const vector<string> &basepaths_,
const char *fusepath_,
vector<string> &paths_);
int findonfs(const vector<string> &basepaths,
const string &fusepath,
const int fd,
string &basepath);
int findonfs(const vector<string> &basepaths_,
const string &fusepath_,
const int fd_,
string &basepath_);
void realpathize(vector<string> &strs);
void realpathize(vector<string> &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<string> &srcs,
const uint64_t minfreespace,
string &path);
};
int mfs(const vector<string> &srcs_,
const uint64_t minfreespace_,
string &path_);
}

View File

@ -25,6 +25,6 @@ namespace fs
namespace acl
{
bool
dir_has_defaults(const std::string &fullpath);
dir_has_defaults(const std::string &fullpath_);
}
}

View File

@ -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_);
}
}

View File

@ -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);
}
}

View File

@ -18,10 +18,10 @@
#pragma once
#include <sys/stat.h>
#include "fs_base_stat.hpp"
#include <sys/stat.h>
#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);
}

View File

@ -18,94 +18,94 @@
#pragma once
#include "fs_base_stat.hpp"
#include <string>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#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);
}

View File

@ -25,8 +25,8 @@ namespace fs
static
inline
int
close(const int fd)
close(const int fd_)
{
return ::close(fd);
return ::close(fd_);
}
}

View File

@ -26,8 +26,8 @@ namespace fs
static
inline
int
closedir(DIR *dirp)
closedir(DIR *dirp_)
{
return ::closedir(dirp);
return ::closedir(dirp_);
}
}

View File

@ -26,8 +26,8 @@ namespace fs
static
inline
int
dirfd(DIR *dirp)
dirfd(DIR *dirp_)
{
return ::dirfd(dirp);
return ::dirfd(dirp_);
}
}

View File

@ -25,8 +25,8 @@ namespace fs
static
inline
int
dup(const int fd)
dup(const int fd_)
{
return ::dup(fd);
return ::dup(fd_);
}
}

View File

@ -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);
}

View File

@ -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_);
}

View File

@ -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_);
}
}

View File

@ -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

View File

@ -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_);
}
}

View File

@ -18,10 +18,12 @@
#pragma once
#include <sys/time.h>
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]);
}

View File

@ -21,10 +21,10 @@
#include "errno.hpp"
#include "xattr.hpp"
#include <sys/types.h>
#include <string>
#include <sys/types.h>
namespace fs
{
static

View File

@ -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());
}
}

View File

@ -21,10 +21,10 @@
#include "errno.hpp"
#include "xattr.hpp"
#include <sys/types.h>
#include <string>
#include <sys/types.h>
namespace fs
{
static

View File

@ -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_);
}
}

View File

@ -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_);
}
}

View File

@ -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_);
}
}

View File

@ -18,29 +18,29 @@
#pragma once
#include <string>
#include <stdlib.h>
#include <string.h>
#include <string>
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;
}

View File

@ -18,12 +18,12 @@
#pragma once
#include <string>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string>
namespace fs
{
static

View File

@ -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());
}
}

View File

@ -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_);
}
}

View File

@ -25,8 +25,8 @@ namespace fs
static
inline
struct dirent *
readdir(DIR *dirp)
readdir(DIR *dirp_)
{
return ::readdir(dirp);
return ::readdir(dirp_);
}
}

View File

@ -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_);
}
}

View File

@ -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);
}
}

View File

@ -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());
}
}

View File

@ -18,21 +18,21 @@
#pragma once
#include <sys/types.h>
#include "errno.hpp"
#include "xattr.hpp"
#include <sys/types.h>
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

View File

@ -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());
}
}

View File

@ -21,10 +21,10 @@
#include "errno.hpp"
#include "xattr.hpp"
#include <sys/types.h>
#include <string>
#include <sys/types.h>
namespace fs
{
static

View File

@ -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
}
}

View File

@ -22,10 +22,10 @@
#include "fs_base_close.hpp"
#include "fs_base_open.hpp"
#include <sys/statvfs.h>
#include <string>
#include <sys/statvfs.h>
#ifndef O_PATH
# define O_PATH 0
#endif

View File

@ -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());
}
}

View File

@ -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_);
}
}

View File

@ -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);
}
}

View File

@ -18,15 +18,15 @@
#pragma once
#include "fs_base_futimesat.hpp"
#include "fs_base_stat.hpp"
#include <string>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/time.h>
#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);
}
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);
}
}

View File

@ -19,10 +19,7 @@
namespace fs
{
using std::string;
using std::vector;
void
glob(const string &pattern_,
vector<string> &strs_);
glob(const std::string &pattern_,
std::vector<std::string> &strs_);
}

View File

@ -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);
}
}
}

View File

@ -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;

View File

@ -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_)
const char *suffix_)
{
*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)
{
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_);
}
}
};

View File

@ -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);

View File

@ -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<const string*> 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<const string*> 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);
}
}
}

View File

@ -16,11 +16,9 @@
#pragma once
namespace mergerfs
namespace FUSE
{
namespace fuse
{
int
rmdir(const char *fusepath);
}
int
access(const char *fusepath_,
int mask_);
}

105
src/fuse_chmod.cpp Normal file
View File

@ -0,0 +1,105 @@
/*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config.hpp"
#include "errno.hpp"
#include "fs_base_chmod.hpp"
#include "fs_path.hpp"
#include "rv.hpp"
#include "rwlock.hpp"
#include "ugid.hpp"
#include <fuse.h>
#include <string>
#include <vector>
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<const string*> &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<const string*> 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_);
}
}

View File

@ -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_);
}

110
src/fuse_chown.cpp Normal file
View File

@ -0,0 +1,110 @@
/*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config.hpp"
#include "errno.hpp"
#include "fs_base_chown.hpp"
#include "fs_path.hpp"
#include "rv.hpp"
#include "rwlock.hpp"
#include "ugid.hpp"
#include <fuse.h>
#include <string>
#include <vector>
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<const string*> &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<const string*> 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_);
}
}

View File

@ -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_);
}

View File

@ -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);
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);
}
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);
}
}

View File

@ -16,14 +16,14 @@
#pragma once
#include <fuse.h>
#include <sys/types.h>
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_);
}

View File

@ -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 *)
{
}
}
}

View File

@ -16,11 +16,8 @@
#pragma once
namespace mergerfs
namespace FUSE
{
namespace fuse
{
void
destroy(void *);
}
void
destroy(void *);
}

View File

@ -14,43 +14,43 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <fuse.h>
#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 <fuse.h>
namespace l
{
int rv;
rv = fs::fallocate(fd,mode,offset,len);
return ((rv == -1) ? -errno : 0);
}
namespace mergerfs
{
namespace fuse
static
int
fallocate(const int fd_,
const int mode_,
const off_t offset_,
const off_t len_)
{
int
fallocate(const char *fusepath,
int mode,
off_t offset,
off_t len,
fuse_file_info *ffi)
{
FileInfo *fi = reinterpret_cast<FileInfo*>(ffi->fh);
int rv;
return _fallocate(fi->fd,
mode,
offset,
len);
}
rv = fs::fallocate(fd_,mode_,offset_,len_);
return ((rv == -1) ? -errno : 0);
}
}
namespace FUSE
{
int
fallocate(const char *fusepath_,
int mode_,
off_t offset_,
off_t len_,
fuse_file_info *ffi_)
{
FileInfo *fi = reinterpret_cast<FileInfo*>(ffi_->fh);
return l::fallocate(fi->fd,
mode_,
offset_,
len_);
}
}

27
src/fuse_fallocate.hpp Normal file
View File

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

View File

@ -14,41 +14,42 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <fuse.h>
#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 <fuse.h>
namespace l
{
int rv;
rv = fs::fstat(fd,st);
if(rv == -1)
return -errno;
fs::inode::recompute(st);
return 0;
}
namespace mergerfs
{
namespace fuse
static
int
fgetattr(const int fd_,
struct stat *st_)
{
int
fgetattr(const char *fusepath,
struct stat *st,
fuse_file_info *ffi)
{
FileInfo *fi = reinterpret_cast<FileInfo*>(ffi->fh);
int rv;
return ::_fgetattr(fi->fd,*st);
}
rv = fs::fstat(fd_,st_);
if(rv == -1)
return -errno;
fs::inode::recompute(st_);
return 0;
}
}
namespace FUSE
{
int
fgetattr(const char *fusepath_,
struct stat *st_,
fuse_file_info *ffi_)
{
FileInfo *fi = reinterpret_cast<FileInfo*>(ffi_->fh);
return l::fgetattr(fi->fd,st_);
}
}

View File

@ -18,16 +18,14 @@
#include <fuse.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
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_);
}

View File

@ -14,36 +14,36 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <fuse.h>
#include "errno.hpp"
#include "fileinfo.hpp"
#include "fs_base_flock.hpp"
static
int
_flock(const int fd,
const int operation)
#include <fuse.h>
namespace l
{
int rv;
rv = fs::flock(fd,operation);
return ((rv == -1) ? -errno : 0);
}
namespace mergerfs
{
namespace fuse
static
int
flock(const int fd_,
const int operation_)
{
int
flock(const char *fusepath,
fuse_file_info *ffi,
int op)
{
FileInfo* fi = reinterpret_cast<FileInfo*>(ffi->fh);
int rv;
return _flock(fi->fd,op);
}
rv = fs::flock(fd_,operation_);
return ((rv == -1) ? -errno : 0);
}
}
namespace FUSE
{
int
flock(const char *fusepath_,
fuse_file_info *ffi_,
int op_)
{
FileInfo* fi = reinterpret_cast<FileInfo*>(ffi_->fh);
return l::flock(fi->fd,op_);
}
}

View File

@ -18,12 +18,10 @@
#include <fuse.h>
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_);
}

View File

@ -14,39 +14,39 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <fuse.h>
#include "errno.hpp"
#include "fileinfo.hpp"
#include "fs_base_close.hpp"
#include "fs_base_dup.hpp"
static
int
_flush(const int fd)
#include <fuse.h>
namespace l
{
int rv;
rv = fs::dup(fd);
if(rv == -1)
errno = EIO;
else
rv = fs::close(rv);
return ((rv == -1) ? -errno : 0);
}
namespace mergerfs
{
namespace fuse
static
int
flush(const int fd_)
{
int
flush(const char *fusepath,
fuse_file_info *ffi)
{
FileInfo *fi = reinterpret_cast<FileInfo*>(ffi->fh);
int rv;
return ::_flush(fi->fd);
}
rv = fs::dup(fd_);
if(rv == -1)
errno = EIO;
else
rv = fs::close(rv);
return ((rv == -1) ? -errno : 0);
}
}
namespace FUSE
{
int
flush(const char *fusepath_,
fuse_file_info *ffi_)
{
FileInfo *fi = reinterpret_cast<FileInfo*>(ffi_->fh);
return l::flush(fi->fd);
}
}

26
src/fuse_flush.hpp Normal file
View File

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

View File

@ -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 <fuse.h>
#include <string>
#include <vector>
#include "errno.hpp"
#include "fileinfo.hpp"
#include "fs_base_fsync.hpp"
static
int
_fsync(const int fd,
const int isdatasync)
namespace l
{
int rv;
rv = (isdatasync ?
fs::fdatasync(fd) :
fs::fsync(fd));
return ((rv == -1) ? -errno : 0);
}
namespace mergerfs
{
namespace fuse
static
int
fsync(const int fd_,
const int isdatasync_)
{
int
fsync(const char *fusepath,
int isdatasync,
fuse_file_info *ffi)
{
FileInfo *fi = reinterpret_cast<FileInfo*>(ffi->fh);
int rv;
return ::_fsync(fi->fd,isdatasync);
}
rv = (isdatasync_ ?
fs::fdatasync(fd_) :
fs::fsync(fd_));
return ((rv == -1) ? -errno : 0);
}
}
namespace FUSE
{
int
fsync(const char *fusepath_,
int isdatasync_,
fuse_file_info *ffi_)
{
FileInfo *fi = reinterpret_cast<FileInfo*>(ffi_->fh);
return l::fsync(fi->fd,isdatasync_);
}
}

View File

@ -18,12 +18,10 @@
#include <fuse.h>
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_);
}

View File

@ -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 <fuse.h>
#include <string>
#include <vector>
#include "errno.hpp"
#include "dirinfo.hpp"
#include "fs_base_fsync.hpp"
static
int
_fsyncdir(const DirInfo *di,
const int isdatasync)
namespace l
{
int rv;
rv = -1;
errno = ENOSYS;
return ((rv == -1) ? -errno : 0);
}
namespace mergerfs
{
namespace fuse
static
int
fsyncdir(const DirInfo *di_,
const int isdatasync_)
{
int
fsyncdir(const char *fusepath,
int isdatasync,
fuse_file_info *ffi)
{
DirInfo *di = reinterpret_cast<DirInfo*>(ffi->fh);
int rv;
return ::_fsyncdir(di,isdatasync);
}
rv = -1;
errno = ENOSYS;
return ((rv == -1) ? -errno : 0);
}
}
namespace FUSE
{
int
fsyncdir(const char *fusepath_,
int isdatasync_,
fuse_file_info *ffi_)
{
DirInfo *di = reinterpret_cast<DirInfo*>(ffi_->fh);
return l::fsyncdir(di,isdatasync_);
}
}

View File

@ -18,13 +18,10 @@
#include <fuse.h>
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_);
}

View File

@ -14,36 +14,36 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <fuse.h>
#include "errno.hpp"
#include "fileinfo.hpp"
#include "fs_base_ftruncate.hpp"
static
int
_ftruncate(const int fd,
const off_t size)
#include <fuse.h>
namespace l
{
int rv;
rv = fs::ftruncate(fd,size);
return ((rv == -1) ? -errno : 0);
}
namespace mergerfs
{
namespace fuse
static
int
ftruncate(const int fd_,
const off_t size_)
{
int
ftruncate(const char *fusepath,
off_t size,
fuse_file_info *ffi)
{
FileInfo *fi = reinterpret_cast<FileInfo*>(ffi->fh);
int rv;
return ::_ftruncate(fi->fd,size);
}
rv = fs::ftruncate(fd_,size_);
return ((rv == -1) ? -errno : 0);
}
}
namespace FUSE
{
int
ftruncate(const char *fusepath_,
off_t size_,
fuse_file_info *ffi_)
{
FileInfo *fi = reinterpret_cast<FileInfo*>(ffi_->fh);
return l::ftruncate(fi->fd,size_);
}
}

View File

@ -19,14 +19,12 @@
#include <fuse.h>
#include <sys/types.h>
#include <unistd.h>
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_);
}

117
src/fuse_getattr.cpp Normal file
View File

@ -0,0 +1,117 @@
/*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "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 <fuse.h>
#include <string>
#include <vector>
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<const string*> 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);
}
}

View File

@ -20,12 +20,9 @@
#include <sys/stat.h>
#include <unistd.h>
namespace mergerfs
namespace FUSE
{
namespace fuse
{
int
getattr(const char *fusepath,
struct stat *buf);
}
int
getattr(const char *fusepath_,
struct stat *buf_);
}

467
src/fuse_getxattr.cpp Normal file
View File

@ -0,0 +1,467 @@
/*
Copyright (c) 2018, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "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 <fuse.h>
#include <algorithm>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include <stdio.h>
#include <string.h>
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<string> 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<string> 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<string> paths;
vector<string> 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<string> 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<const string*> 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);
}
}

View File

@ -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_);
}

View File

@ -14,27 +14,24 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <fuse.h>
#include "config.hpp"
#include "ugid.hpp"
namespace mergerfs
#include <fuse.h>
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();
}
}

View File

@ -16,11 +16,10 @@
#pragma once
namespace mergerfs
#include <fuse.h>
namespace FUSE
{
namespace fuse
{
void *
init(fuse_conn_info *conn);
}
void *
init(fuse_conn_info *conn_);
}

View File

@ -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<FileInfo*>(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_);
if(flags_ & FUSE_IOCTL_DIR)
return l::ioctl_dir(ffi_,cmd_,data_);
return local::ioctl_file(ffi_,cmd_,data_);
}
return l::ioctl_file(ffi_,cmd_,data_);
}
}

View File

@ -18,13 +18,13 @@
#include <fuse.h>
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_);
}

249
src/fuse_link.cpp Normal file
View File

@ -0,0 +1,249 @@
/*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "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 <fuse.h>
#include <string>
#include <vector>
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<const string*> &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<const string*> oldbasepaths;
vector<const string*> 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<const string*> 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<const string*> &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<const string*> 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_);
}
}

24
src/fuse_link.hpp Normal file
View File

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

146
src/fuse_listxattr.cpp Normal file
View File

@ -0,0 +1,146 @@
/*
Copyright (c) 2018, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "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 <fuse.h>
#include <string>
#include <vector>
#include <string.h>
using std::string;
using std::vector;
namespace l
{
static
int
listxattr_controlfile(char *list_,
const size_t size_)
{
string xattrs;
const vector<string> strs =
buildvector<string>
("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<const string*> 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_);
}
}

25
src/fuse_listxattr.hpp Normal file
View File

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

149
src/fuse_mkdir.cpp Normal file
View File

@ -0,0 +1,149 @@
/*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <fuse.h>
#include <string>
#include <vector>
#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<const string*> &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<const string*> createpaths;
vector<const string*> 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);
}
}

24
src/fuse_mkdir.hpp Normal file
View File

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

151
src/fuse_mknod.cpp Normal file
View File

@ -0,0 +1,151 @@
/*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "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 <fuse.h>
#include <string>
#include <vector>
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<const string*> &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<const string*> createpaths;
vector<const string*> 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_);
}
}

26
src/fuse_mknod.hpp Normal file
View File

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

View File

@ -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);
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);
}
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);
}
}

26
src/fuse_open.hpp Normal file
View File

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

Some files were not shown because too many files have changed in this diff Show More