|
|
@ -14,11 +14,6 @@ |
|
|
|
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 "fileinfo.hpp"
|
|
|
@ -29,81 +24,92 @@ |
|
|
|
#include "rwlock.hpp"
|
|
|
|
#include "ugid.hpp"
|
|
|
|
|
|
|
|
#include <fuse.h>
|
|
|
|
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
using std::string; |
|
|
|
using std::vector; |
|
|
|
using namespace mergerfs; |
|
|
|
|
|
|
|
static |
|
|
|
int |
|
|
|
_create_core(const string &fullpath, |
|
|
|
mode_t mode, |
|
|
|
const mode_t umask, |
|
|
|
const int flags) |
|
|
|
namespace local |
|
|
|
{ |
|
|
|
if(!fs::acl::dir_has_defaults(fullpath)) |
|
|
|
mode &= ~umask; |
|
|
|
|
|
|
|
return fs::open(fullpath,flags,mode); |
|
|
|
} |
|
|
|
|
|
|
|
static |
|
|
|
int |
|
|
|
_create_core(const string &createpath, |
|
|
|
const char *fusepath, |
|
|
|
const mode_t mode, |
|
|
|
const mode_t umask, |
|
|
|
const int flags, |
|
|
|
uint64_t &fh) |
|
|
|
{ |
|
|
|
int rv; |
|
|
|
string fullpath; |
|
|
|
|
|
|
|
fs::path::make(&createpath,fusepath,fullpath); |
|
|
|
|
|
|
|
rv = _create_core(fullpath,mode,umask,flags); |
|
|
|
if(rv == -1) |
|
|
|
return -errno; |
|
|
|
|
|
|
|
fh = reinterpret_cast<uint64_t>(new FileInfo(rv,fusepath)); |
|
|
|
static |
|
|
|
int |
|
|
|
create_core(const string &fullpath_, |
|
|
|
mode_t mode_, |
|
|
|
const mode_t umask_, |
|
|
|
const int flags_) |
|
|
|
{ |
|
|
|
if(!fs::acl::dir_has_defaults(fullpath_)) |
|
|
|
mode_ &= ~umask_; |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
return fs::open(fullpath_,flags_,mode_); |
|
|
|
} |
|
|
|
|
|
|
|
static |
|
|
|
int |
|
|
|
_create(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 int flags, |
|
|
|
uint64_t &fh) |
|
|
|
{ |
|
|
|
int rv; |
|
|
|
string fullpath; |
|
|
|
string fusedirpath; |
|
|
|
vector<const string*> createpaths; |
|
|
|
vector<const string*> existingpaths; |
|
|
|
static |
|
|
|
int |
|
|
|
create_core(const string &createpath_, |
|
|
|
const char *fusepath_, |
|
|
|
const mode_t mode_, |
|
|
|
const mode_t umask_, |
|
|
|
const int flags_, |
|
|
|
uint64_t *fh_) |
|
|
|
{ |
|
|
|
int rv; |
|
|
|
string fullpath; |
|
|
|
|
|
|
|
fusedirpath = fs::path::dirname(fusepath); |
|
|
|
fs::path::make(&createpath_,fusepath_,fullpath); |
|
|
|
|
|
|
|
rv = searchFunc(branches_,fusedirpath,minfreespace,existingpaths); |
|
|
|
if(rv == -1) |
|
|
|
return -errno; |
|
|
|
rv = local::create_core(fullpath,mode_,umask_,flags_); |
|
|
|
if(rv == -1) |
|
|
|
return -errno; |
|
|
|
|
|
|
|
rv = createFunc(branches_,fusedirpath,minfreespace,createpaths); |
|
|
|
if(rv == -1) |
|
|
|
return -errno; |
|
|
|
*fh_ = reinterpret_cast<uint64_t>(new FileInfo(rv,fusepath_)); |
|
|
|
|
|
|
|
rv = fs::clonepath_as_root(*existingpaths[0],*createpaths[0],fusedirpath); |
|
|
|
if(rv == -1) |
|
|
|
return -errno; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
return _create_core(*createpaths[0], |
|
|
|
fusepath, |
|
|
|
mode,umask,flags,fh); |
|
|
|
static |
|
|
|
int |
|
|
|
create(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 int flags_, |
|
|
|
uint64_t *fh_) |
|
|
|
{ |
|
|
|
int rv; |
|
|
|
string fullpath; |
|
|
|
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; |
|
|
|
|
|
|
|
rv = fs::clonepath_as_root(*existingpaths[0],*createpaths[0],fusedirpath); |
|
|
|
if(rv == -1) |
|
|
|
return -errno; |
|
|
|
|
|
|
|
return local::create_core(*createpaths[0], |
|
|
|
fusepath_, |
|
|
|
mode_, |
|
|
|
umask_, |
|
|
|
flags_, |
|
|
|
fh_); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
namespace mergerfs |
|
|
@ -111,24 +117,25 @@ namespace mergerfs |
|
|
|
namespace fuse |
|
|
|
{ |
|
|
|
int |
|
|
|
create(const char *fusepath, |
|
|
|
mode_t mode, |
|
|
|
fuse_file_info *ffi) |
|
|
|
create(const char *fusepath_, |
|
|
|
mode_t mode_, |
|
|
|
fuse_file_info *ffi_) |
|
|
|
{ |
|
|
|
const fuse_context *fc = fuse_get_context(); |
|
|
|
const Config &config = Config::get(fc); |
|
|
|
const ugid::Set ugid(fc->uid,fc->gid); |
|
|
|
const rwlock::ReadGuard readlock(&config.branches_lock); |
|
|
|
|
|
|
|
return _create(config.getattr, |
|
|
|
config.create, |
|
|
|
config.branches, |
|
|
|
config.minfreespace, |
|
|
|
fusepath, |
|
|
|
mode, |
|
|
|
fc->umask, |
|
|
|
ffi->flags, |
|
|
|
ffi->fh); |
|
|
|
ffi_->direct_io = config.direct_io; |
|
|
|
return local::create(config.getattr, |
|
|
|
config.create, |
|
|
|
config.branches, |
|
|
|
config.minfreespace, |
|
|
|
fusepath_, |
|
|
|
mode_, |
|
|
|
fc->umask, |
|
|
|
ffi_->flags, |
|
|
|
&ffi_->fh); |
|
|
|
} |
|
|
|
} |
|
|
|
} |