mirror of https://github.com/trapexit/mergerfs.git
trapexit
6 years ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
178 changed files with 5070 additions and 5225 deletions
-
1src/buildvector.hpp
-
105src/chmod.cpp
-
111src/chown.cpp
-
23src/config.cpp
-
29src/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
-
18src/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
-
20src/fuse_access.cpp
-
8src/fuse_access.hpp
-
105src/fuse_chmod.cpp
-
8src/fuse_chmod.hpp
-
110src/fuse_chown.cpp
-
10src/fuse_chown.hpp
-
16src/fuse_create.cpp
-
12src/fuse_create.hpp
-
5src/fuse_destroy.cpp
-
5src/fuse_destroy.hpp
-
46src/fuse_fallocate.cpp
-
27src/fuse_fallocate.hpp
-
35src/fuse_fgetattr.cpp
-
12src/fuse_fgetattr.hpp
-
32src/fuse_flock.cpp
-
10src/fuse_flock.hpp
-
28src/fuse_flush.cpp
-
26src/fuse_flush.hpp
-
40src/fuse_fsync.cpp
-
10src/fuse_fsync.hpp
-
34src/fuse_fsyncdir.cpp
-
11src/fuse_fsyncdir.hpp
-
32src/fuse_ftruncate.cpp
-
12src/fuse_ftruncate.hpp
-
117src/fuse_getattr.cpp
-
9src/fuse_getattr.hpp
-
467src/fuse_getxattr.cpp
-
12src/fuse_getxattr.hpp
-
21src/fuse_init.cpp
-
9src/fuse_init.hpp
-
21src/fuse_ioctl.cpp
-
14src/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
-
13src/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