mirror of https://github.com/trapexit/mergerfs.git
Antonio SJ Musumeci
6 years ago
178 changed files with 5070 additions and 5225 deletions
-
1src/buildvector.hpp
-
105src/chmod.cpp
-
111src/chown.cpp
-
177src/config.cpp
-
209src/config.hpp
-
30src/fallocate.hpp
-
28src/flock.hpp
-
8src/fs.cpp
-
30src/fs.hpp
-
2src/fs_acl.hpp
-
10src/fs_attr.hpp
-
24src/fs_base_access.hpp
-
42src/fs_base_chmod.hpp
-
70src/fs_base_chown.hpp
-
4src/fs_base_close.hpp
-
4src/fs_base_closedir.hpp
-
4src/fs_base_dirfd.hpp
-
4src/fs_base_dup.hpp
-
18src/fs_base_fadvise.hpp
-
8src/fs_base_fallocate.hpp
-
6src/fs_base_flock.hpp
-
8src/fs_base_fsync.hpp
-
6src/fs_base_ftruncate.hpp
-
8src/fs_base_futimesat.hpp
-
4src/fs_base_getxattr.hpp
-
7src/fs_base_link.hpp
-
4src/fs_base_listxattr.hpp
-
8src/fs_base_lseek.hpp
-
6src/fs_base_mkdir.hpp
-
8src/fs_base_mknod.hpp
-
14src/fs_base_mkstemp.hpp
-
4src/fs_base_open.hpp
-
4src/fs_base_opendir.hpp
-
18src/fs_base_read.hpp
-
4src/fs_base_readdir.hpp
-
8src/fs_base_readlink.hpp
-
10src/fs_base_realpath.hpp
-
12src/fs_base_remove.hpp
-
10src/fs_base_removexattr.hpp
-
12src/fs_base_rmdir.hpp
-
4src/fs_base_setxattr.hpp
-
57src/fs_base_stat.hpp
-
4src/fs_base_statvfs.hpp
-
24src/fs_base_symlink.hpp
-
15src/fs_base_truncate.hpp
-
26src/fs_base_utime.hpp
-
132src/fs_base_utime_generic.hpp
-
2src/fs_clonefile.cpp
-
22src/fs_clonepath.cpp
-
2src/fs_copyfile.cpp
-
2src/fs_cow.cpp
-
4src/fs_devid.hpp
-
8src/fs_exists.hpp
-
7src/fs_glob.hpp
-
15src/fs_inode.hpp
-
2src/fs_movefile.cpp
-
41src/fs_path.hpp
-
4src/fs_statvfs_cache.cpp
-
56src/fuse_access.cpp
-
10src/fuse_access.hpp
-
105src/fuse_chmod.cpp
-
10src/fuse_chmod.hpp
-
110src/fuse_chown.cpp
-
12src/fuse_chown.hpp
-
62src/fuse_create.cpp
-
14src/fuse_create.hpp
-
9src/fuse_destroy.cpp
-
9src/fuse_destroy.hpp
-
54src/fuse_fallocate.cpp
-
27src/fuse_fallocate.hpp
-
47src/fuse_fgetattr.cpp
-
14src/fuse_fgetattr.hpp
-
40src/fuse_flock.cpp
-
12src/fuse_flock.hpp
-
44src/fuse_flush.cpp
-
26src/fuse_flush.hpp
-
48src/fuse_fsync.cpp
-
12src/fuse_fsync.hpp
-
46src/fuse_fsyncdir.cpp
-
13src/fuse_fsyncdir.hpp
-
40src/fuse_ftruncate.cpp
-
14src/fuse_ftruncate.hpp
-
117src/fuse_getattr.cpp
-
11src/fuse_getattr.hpp
-
467src/fuse_getxattr.cpp
-
14src/fuse_getxattr.hpp
-
27src/fuse_init.cpp
-
11src/fuse_init.hpp
-
49src/fuse_ioctl.cpp
-
16src/fuse_ioctl.hpp
-
249src/fuse_link.cpp
-
24src/fuse_link.hpp
-
146src/fuse_listxattr.cpp
-
25src/fuse_listxattr.hpp
-
149src/fuse_mkdir.cpp
-
24src/fuse_mkdir.hpp
-
151src/fuse_mknod.cpp
-
26src/fuse_mknod.hpp
-
45src/fuse_open.cpp
-
26src/fuse_open.hpp
@ -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); |
|
||||
} |
|
||||
} |
|
||||
} |
|
@ -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); |
|
||||
} |
|
||||
} |
|
||||
} |
|
@ -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); |
|
||||
} |
|
||||
} |
|
@ -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); |
|
||||
} |
|
||||
} |
|
@ -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_); |
||||
|
} |
||||
|
} |
@ -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_); |
||||
|
} |
||||
|
} |
@ -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_); |
||||
|
} |
@ -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_); |
||||
|
} |
@ -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); |
||||
|
} |
||||
|
} |
@ -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); |
||||
|
} |
||||
|
} |
@ -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_); |
||||
|
} |
||||
|
} |
@ -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_); |
||||
|
} |
@ -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_); |
||||
|
} |
||||
|
} |
@ -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_); |
||||
|
} |
@ -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); |
||||
|
} |
||||
|
} |
@ -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_); |
||||
|
} |
@ -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_); |
||||
|
} |
||||
|
} |
@ -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_); |
||||
|
} |
@ -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 changed in this diff
Write
Preview
Loading…
Cancel
Save
Reference in new issue