mirror of
https://github.com/trapexit/mergerfs.git
synced 2026-10-26 02:48:59 -04:00
Start using std::filesystem::path for fusepath (#1522)
This commit is contained in:
parent
f64ff9ca1e
commit
8c649d33ee
139 changed files with 1711 additions and 1663 deletions
|
|
@ -833,13 +833,21 @@ unlock_path(struct fuse *f,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Throughout this file all calls to the op.func() callbacks will be
|
||||||
|
'&fusepath[1]' because the current path generation always prefixes a
|
||||||
|
'/' for each path but we need a relative path for usage with
|
||||||
|
`openat()` functions and would rather do that here than in the
|
||||||
|
called function.
|
||||||
|
*/
|
||||||
|
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
try_get_path(struct fuse *f,
|
try_get_path(struct fuse *f,
|
||||||
uint64_t nodeid,
|
uint64_t nodeid,
|
||||||
const char *name,
|
const char *name,
|
||||||
char **path,
|
char **path,
|
||||||
node_t **wnodep,
|
node_t **wnodep,
|
||||||
bool need_lock)
|
bool need_lock)
|
||||||
{
|
{
|
||||||
unsigned bufsize = 256;
|
unsigned bufsize = 256;
|
||||||
|
|
@ -1395,7 +1403,7 @@ int
|
||||||
lookup_path(struct fuse *f,
|
lookup_path(struct fuse *f,
|
||||||
uint64_t nodeid,
|
uint64_t nodeid,
|
||||||
const char *name,
|
const char *name,
|
||||||
const char *path,
|
const char *fusepath,
|
||||||
struct fuse_entry_param *e,
|
struct fuse_entry_param *e,
|
||||||
fuse_file_info_t *fi)
|
fuse_file_info_t *fi)
|
||||||
{
|
{
|
||||||
|
|
@ -1404,7 +1412,7 @@ lookup_path(struct fuse *f,
|
||||||
memset(e,0,sizeof(struct fuse_entry_param));
|
memset(e,0,sizeof(struct fuse_entry_param));
|
||||||
|
|
||||||
rv = ((fi == NULL) ?
|
rv = ((fi == NULL) ?
|
||||||
f->fs->op.getattr(path,&e->attr,&e->timeout) :
|
f->fs->op.getattr(&fusepath[1],&e->attr,&e->timeout) :
|
||||||
f->fs->op.fgetattr(fi->fh,&e->attr,&e->timeout));
|
f->fs->op.fgetattr(fi->fh,&e->attr,&e->timeout));
|
||||||
|
|
||||||
if(rv)
|
if(rv)
|
||||||
|
|
@ -1556,7 +1564,7 @@ fuse_lib_lookup(fuse_req_t req,
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
uint64_t nodeid;
|
uint64_t nodeid;
|
||||||
char *path;
|
char *fusepath;
|
||||||
const char *name;
|
const char *name;
|
||||||
struct fuse *f;
|
struct fuse *f;
|
||||||
node_t *dot = NULL;
|
node_t *dot = NULL;
|
||||||
|
|
@ -1597,16 +1605,16 @@ fuse_lib_lookup(fuse_req_t req,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = get_path_name(f,nodeid,name,&path);
|
err = get_path_name(f,nodeid,name,&fusepath);
|
||||||
if(!err)
|
if(!err)
|
||||||
{
|
{
|
||||||
err = lookup_path(f,nodeid,name,path,&e,NULL);
|
err = lookup_path(f,nodeid,name,fusepath,&e,NULL);
|
||||||
if(err == -ENOENT)
|
if(err == -ENOENT)
|
||||||
{
|
{
|
||||||
e.ino = 0;
|
e.ino = 0;
|
||||||
err = 0;
|
err = 0;
|
||||||
}
|
}
|
||||||
free_path(f,nodeid,path);
|
free_path(f,nodeid,fusepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dot)
|
if(dot)
|
||||||
|
|
@ -1673,7 +1681,7 @@ fuse_lib_getattr(fuse_req_t req,
|
||||||
struct fuse_in_header *hdr_)
|
struct fuse_in_header *hdr_)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
char *path;
|
char *fusepath;
|
||||||
uint64_t fh;
|
uint64_t fh;
|
||||||
struct fuse *f;
|
struct fuse *f;
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
|
|
@ -1691,21 +1699,21 @@ fuse_lib_getattr(fuse_req_t req,
|
||||||
memset(&buf,0,sizeof(buf));
|
memset(&buf,0,sizeof(buf));
|
||||||
|
|
||||||
err = 0;
|
err = 0;
|
||||||
path = NULL;
|
fusepath = NULL;
|
||||||
if(fh == 0)
|
if(fh == 0)
|
||||||
{
|
{
|
||||||
err = get_path(f,hdr_->nodeid,&path);
|
err = get_path(f,hdr_->nodeid,&fusepath);
|
||||||
if(err == -ESTALE) // unlinked but open
|
if(err == -ESTALE) // unlinked but open
|
||||||
err = 0;
|
err = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!err)
|
if(!err)
|
||||||
{
|
{
|
||||||
err = ((path != NULL) ?
|
err = ((fusepath != NULL) ?
|
||||||
f->fs->op.getattr(path,&buf,&timeout) :
|
f->fs->op.getattr(&fusepath[1],&buf,&timeout) :
|
||||||
f->fs->op.fgetattr(fh,&buf,&timeout));
|
f->fs->op.fgetattr(fh,&buf,&timeout));
|
||||||
|
|
||||||
free_path(f,hdr_->nodeid,path);
|
free_path(f,hdr_->nodeid,fusepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!err)
|
if(!err)
|
||||||
|
|
@ -1743,7 +1751,7 @@ fuse_lib_statx_path(fuse_req_t req_,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = f_->fs->op.statx(fusepath,
|
err = f_->fs->op.statx(&fusepath[1],
|
||||||
inarg_->sx_flags,
|
inarg_->sx_flags,
|
||||||
inarg_->sx_mask,
|
inarg_->sx_mask,
|
||||||
&st,
|
&st,
|
||||||
|
|
@ -1804,7 +1812,7 @@ fuse_lib_setattr(fuse_req_t req,
|
||||||
uint64_t fh;
|
uint64_t fh;
|
||||||
struct fuse *f = req_fuse_prepare(req);
|
struct fuse *f = req_fuse_prepare(req);
|
||||||
struct stat stbuf = {0};
|
struct stat stbuf = {0};
|
||||||
char *path;
|
char *fusepath;
|
||||||
int err;
|
int err;
|
||||||
fuse_timeouts_t timeout;
|
fuse_timeouts_t timeout;
|
||||||
struct fuse_setattr_in *arg;
|
struct fuse_setattr_in *arg;
|
||||||
|
|
@ -1816,10 +1824,10 @@ fuse_lib_setattr(fuse_req_t req,
|
||||||
fh = arg->fh;
|
fh = arg->fh;
|
||||||
|
|
||||||
err = 0;
|
err = 0;
|
||||||
path = NULL;
|
fusepath = NULL;
|
||||||
if(fh == 0)
|
if(fh == 0)
|
||||||
{
|
{
|
||||||
err = get_path(f,hdr_->nodeid,&path);
|
err = get_path(f,hdr_->nodeid,&fusepath);
|
||||||
if(err == -ESTALE)
|
if(err == -ESTALE)
|
||||||
err = 0;
|
err = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -1828,8 +1836,8 @@ fuse_lib_setattr(fuse_req_t req,
|
||||||
{
|
{
|
||||||
err = 0;
|
err = 0;
|
||||||
if(!err && (arg->valid & FATTR_MODE))
|
if(!err && (arg->valid & FATTR_MODE))
|
||||||
err = ((path != NULL) ?
|
err = ((fusepath != NULL) ?
|
||||||
f->fs->op.chmod(path,arg->mode) :
|
f->fs->op.chmod(&fusepath[1],arg->mode) :
|
||||||
f->fs->op.fchmod(fh,arg->mode));
|
f->fs->op.fchmod(fh,arg->mode));
|
||||||
|
|
||||||
if(!err && (arg->valid & (FATTR_UID | FATTR_GID)))
|
if(!err && (arg->valid & (FATTR_UID | FATTR_GID)))
|
||||||
|
|
@ -1837,14 +1845,14 @@ fuse_lib_setattr(fuse_req_t req,
|
||||||
uid_t uid = ((arg->valid & FATTR_UID) ? arg->uid : (uid_t)-1);
|
uid_t uid = ((arg->valid & FATTR_UID) ? arg->uid : (uid_t)-1);
|
||||||
gid_t gid = ((arg->valid & FATTR_GID) ? arg->gid : (gid_t)-1);
|
gid_t gid = ((arg->valid & FATTR_GID) ? arg->gid : (gid_t)-1);
|
||||||
|
|
||||||
err = ((path != NULL) ?
|
err = ((fusepath != NULL) ?
|
||||||
f->fs->op.chown(path,uid,gid) :
|
f->fs->op.chown(&fusepath[1],uid,gid) :
|
||||||
f->fs->op.fchown(fh,uid,gid));
|
f->fs->op.fchown(fh,uid,gid));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!err && (arg->valid & FATTR_SIZE))
|
if(!err && (arg->valid & FATTR_SIZE))
|
||||||
err = ((path != NULL) ?
|
err = ((fusepath != NULL) ?
|
||||||
f->fs->op.truncate(path,arg->size) :
|
f->fs->op.truncate(&fusepath[1],arg->size) :
|
||||||
f->fs->op.ftruncate(fh,arg->size));
|
f->fs->op.ftruncate(fh,arg->size));
|
||||||
|
|
||||||
if(!err && (arg->valid & (FATTR_ATIME | FATTR_MTIME)))
|
if(!err && (arg->valid & (FATTR_ATIME | FATTR_MTIME)))
|
||||||
|
|
@ -1866,8 +1874,8 @@ fuse_lib_setattr(fuse_req_t req,
|
||||||
else if(arg->valid & FATTR_MTIME)
|
else if(arg->valid & FATTR_MTIME)
|
||||||
tv[1] = (struct timespec){ static_cast<time_t>(arg->mtime), arg->mtimensec };
|
tv[1] = (struct timespec){ static_cast<time_t>(arg->mtime), arg->mtimensec };
|
||||||
|
|
||||||
err = ((path != NULL) ?
|
err = ((fusepath != NULL) ?
|
||||||
f->fs->op.utimens(path,tv) :
|
f->fs->op.utimens(&fusepath[1],tv) :
|
||||||
f->fs->op.futimens(fh,tv));
|
f->fs->op.futimens(fh,tv));
|
||||||
}
|
}
|
||||||
else if(!err && ((arg->valid & (FATTR_ATIME|FATTR_MTIME)) == (FATTR_ATIME|FATTR_MTIME)))
|
else if(!err && ((arg->valid & (FATTR_ATIME|FATTR_MTIME)) == (FATTR_ATIME|FATTR_MTIME)))
|
||||||
|
|
@ -1877,17 +1885,17 @@ fuse_lib_setattr(fuse_req_t req,
|
||||||
tv[0].tv_nsec = arg->atimensec;
|
tv[0].tv_nsec = arg->atimensec;
|
||||||
tv[1].tv_sec = arg->mtime;
|
tv[1].tv_sec = arg->mtime;
|
||||||
tv[1].tv_nsec = arg->mtimensec;
|
tv[1].tv_nsec = arg->mtimensec;
|
||||||
err = ((path != NULL) ?
|
err = ((fusepath != NULL) ?
|
||||||
f->fs->op.utimens(path,tv) :
|
f->fs->op.utimens(&fusepath[1],tv) :
|
||||||
f->fs->op.futimens(fh,tv));
|
f->fs->op.futimens(fh,tv));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!err)
|
if(!err)
|
||||||
err = ((path != NULL) ?
|
err = ((fusepath != NULL) ?
|
||||||
f->fs->op.getattr(path,&stbuf,&timeout) :
|
f->fs->op.getattr(&fusepath[1],&stbuf,&timeout) :
|
||||||
f->fs->op.fgetattr(fh,&stbuf,&timeout));
|
f->fs->op.fgetattr(fh,&stbuf,&timeout));
|
||||||
|
|
||||||
free_path(f,hdr_->nodeid,path);
|
free_path(f,hdr_->nodeid,fusepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!err)
|
if(!err)
|
||||||
|
|
@ -1910,7 +1918,7 @@ fuse_lib_access(fuse_req_t req,
|
||||||
struct fuse_in_header *hdr_)
|
struct fuse_in_header *hdr_)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
char *path;
|
char *fusepath;
|
||||||
struct fuse *f;
|
struct fuse *f;
|
||||||
struct fuse_access_in *arg;
|
struct fuse_access_in *arg;
|
||||||
|
|
||||||
|
|
@ -1918,11 +1926,11 @@ fuse_lib_access(fuse_req_t req,
|
||||||
|
|
||||||
f = req_fuse_prepare(req);
|
f = req_fuse_prepare(req);
|
||||||
|
|
||||||
err = get_path(f,hdr_->nodeid,&path);
|
err = get_path(f,hdr_->nodeid,&fusepath);
|
||||||
if(!err)
|
if(!err)
|
||||||
{
|
{
|
||||||
err = f->fs->op.access(path,arg->mask);
|
err = f->fs->op.access(&fusepath[1],arg->mask);
|
||||||
free_path(f,hdr_->nodeid,path);
|
free_path(f,hdr_->nodeid,fusepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
fuse_reply_err(req,err);
|
fuse_reply_err(req,err);
|
||||||
|
|
@ -1934,17 +1942,17 @@ fuse_lib_readlink(fuse_req_t req,
|
||||||
struct fuse_in_header *hdr_)
|
struct fuse_in_header *hdr_)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
char *path;
|
char *fusepath;
|
||||||
struct fuse *f;
|
struct fuse *f;
|
||||||
char linkname[PATH_MAX + 1];
|
char linkname[PATH_MAX + 1];
|
||||||
|
|
||||||
f = req_fuse_prepare(req);
|
f = req_fuse_prepare(req);
|
||||||
|
|
||||||
err = get_path(f,hdr_->nodeid,&path);
|
err = get_path(f,hdr_->nodeid,&fusepath);
|
||||||
if(!err)
|
if(!err)
|
||||||
{
|
{
|
||||||
err = f->fs->op.readlink(path,linkname,sizeof(linkname));
|
err = f->fs->op.readlink(&fusepath[1],linkname,sizeof(linkname));
|
||||||
free_path(f,hdr_->nodeid,path);
|
free_path(f,hdr_->nodeid,fusepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!err)
|
if(!err)
|
||||||
|
|
@ -1964,7 +1972,7 @@ fuse_lib_mknod(fuse_req_t req,
|
||||||
struct fuse_in_header *hdr_)
|
struct fuse_in_header *hdr_)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
char *path;
|
char *fusepath;
|
||||||
struct fuse *f;
|
struct fuse *f;
|
||||||
const char* name;
|
const char* name;
|
||||||
struct fuse_entry_param e;
|
struct fuse_entry_param e;
|
||||||
|
|
@ -1979,7 +1987,7 @@ fuse_lib_mknod(fuse_req_t req,
|
||||||
|
|
||||||
f = req_fuse_prepare(req);
|
f = req_fuse_prepare(req);
|
||||||
|
|
||||||
err = get_path_name(f,hdr_->nodeid,name,&path);
|
err = get_path_name(f,hdr_->nodeid,name,&fusepath);
|
||||||
if(!err)
|
if(!err)
|
||||||
{
|
{
|
||||||
err = -ENOSYS;
|
err = -ENOSYS;
|
||||||
|
|
@ -1989,22 +1997,22 @@ fuse_lib_mknod(fuse_req_t req,
|
||||||
|
|
||||||
memset(&fi,0,sizeof(fi));
|
memset(&fi,0,sizeof(fi));
|
||||||
fi.flags = O_CREAT | O_EXCL | O_WRONLY;
|
fi.flags = O_CREAT | O_EXCL | O_WRONLY;
|
||||||
err = f->fs->op.create(path,arg->mode,&fi);
|
err = f->fs->op.create(&fusepath[1],arg->mode,&fi);
|
||||||
if(!err)
|
if(!err)
|
||||||
{
|
{
|
||||||
err = lookup_path(f,hdr_->nodeid,name,path,&e,&fi);
|
err = lookup_path(f,hdr_->nodeid,name,fusepath,&e,&fi);
|
||||||
f->fs->op.release(&fi);
|
f->fs->op.release(&fi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(err == -ENOSYS)
|
if(err == -ENOSYS)
|
||||||
{
|
{
|
||||||
err = f->fs->op.mknod(path,arg->mode,arg->rdev);
|
err = f->fs->op.mknod(&fusepath[1],arg->mode,arg->rdev);
|
||||||
if(!err)
|
if(!err)
|
||||||
err = lookup_path(f,hdr_->nodeid,name,path,&e,NULL);
|
err = lookup_path(f,hdr_->nodeid,name,fusepath,&e,NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
free_path(f,hdr_->nodeid,path);
|
free_path(f,hdr_->nodeid,fusepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
reply_entry(req,&e,err);
|
reply_entry(req,&e,err);
|
||||||
|
|
@ -2016,7 +2024,7 @@ fuse_lib_mkdir(fuse_req_t req,
|
||||||
struct fuse_in_header *hdr_)
|
struct fuse_in_header *hdr_)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
char *path;
|
char *fusepath;
|
||||||
struct fuse *f;
|
struct fuse *f;
|
||||||
const char *name;
|
const char *name;
|
||||||
struct fuse_entry_param e;
|
struct fuse_entry_param e;
|
||||||
|
|
@ -2029,13 +2037,13 @@ fuse_lib_mkdir(fuse_req_t req,
|
||||||
|
|
||||||
f = req_fuse_prepare(req);
|
f = req_fuse_prepare(req);
|
||||||
|
|
||||||
err = get_path_name(f,hdr_->nodeid,name,&path);
|
err = get_path_name(f,hdr_->nodeid,name,&fusepath);
|
||||||
if(!err)
|
if(!err)
|
||||||
{
|
{
|
||||||
err = f->fs->op.mkdir(path,arg->mode);
|
err = f->fs->op.mkdir(&fusepath[1],arg->mode);
|
||||||
if(!err)
|
if(!err)
|
||||||
err = lookup_path(f,hdr_->nodeid,name,path,&e,NULL);
|
err = lookup_path(f,hdr_->nodeid,name,fusepath,&e,NULL);
|
||||||
free_path(f,hdr_->nodeid,path);
|
free_path(f,hdr_->nodeid,fusepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
reply_entry(req,&e,err);
|
reply_entry(req,&e,err);
|
||||||
|
|
@ -2047,7 +2055,7 @@ fuse_lib_unlink(fuse_req_t req,
|
||||||
struct fuse_in_header *hdr_)
|
struct fuse_in_header *hdr_)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
char *path;
|
char *fusepath;
|
||||||
struct fuse *f;
|
struct fuse *f;
|
||||||
const char *name;
|
const char *name;
|
||||||
node_t *wnode;
|
node_t *wnode;
|
||||||
|
|
@ -2055,18 +2063,18 @@ fuse_lib_unlink(fuse_req_t req,
|
||||||
name = (const char*)PARAM(hdr_);
|
name = (const char*)PARAM(hdr_);
|
||||||
|
|
||||||
f = req_fuse_prepare(req);
|
f = req_fuse_prepare(req);
|
||||||
err = get_path_wrlock(f,hdr_->nodeid,name,&path,&wnode);
|
err = get_path_wrlock(f,hdr_->nodeid,name,&fusepath,&wnode);
|
||||||
|
|
||||||
if(!err)
|
if(!err)
|
||||||
{
|
{
|
||||||
if(node_open(wnode))
|
if(node_open(wnode))
|
||||||
fuse_get_context()->nodeid = wnode->nodeid;
|
fuse_get_context()->nodeid = wnode->nodeid;
|
||||||
|
|
||||||
err = f->fs->op.unlink(path);
|
err = f->fs->op.unlink(&fusepath[1]);
|
||||||
if(!err)
|
if(!err)
|
||||||
remove_node(f,hdr_->nodeid,name);
|
remove_node(f,hdr_->nodeid,name);
|
||||||
|
|
||||||
free_path_wrlock(f,hdr_->nodeid,wnode,path);
|
free_path_wrlock(f,hdr_->nodeid,wnode,fusepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
fuse_reply_err(req,err);
|
fuse_reply_err(req,err);
|
||||||
|
|
@ -2078,7 +2086,7 @@ fuse_lib_rmdir(fuse_req_t req,
|
||||||
struct fuse_in_header *hdr_)
|
struct fuse_in_header *hdr_)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
char *path;
|
char *fusepath;
|
||||||
struct fuse *f;
|
struct fuse *f;
|
||||||
const char *name;
|
const char *name;
|
||||||
node_t *wnode;
|
node_t *wnode;
|
||||||
|
|
@ -2087,13 +2095,13 @@ fuse_lib_rmdir(fuse_req_t req,
|
||||||
|
|
||||||
f = req_fuse_prepare(req);
|
f = req_fuse_prepare(req);
|
||||||
|
|
||||||
err = get_path_wrlock(f,hdr_->nodeid,name,&path,&wnode);
|
err = get_path_wrlock(f,hdr_->nodeid,name,&fusepath,&wnode);
|
||||||
if(!err)
|
if(!err)
|
||||||
{
|
{
|
||||||
err = f->fs->op.rmdir(path);
|
err = f->fs->op.rmdir(&fusepath[1]);
|
||||||
if(!err)
|
if(!err)
|
||||||
remove_node(f,hdr_->nodeid,name);
|
remove_node(f,hdr_->nodeid,name);
|
||||||
free_path_wrlock(f,hdr_->nodeid,wnode,path);
|
free_path_wrlock(f,hdr_->nodeid,wnode,fusepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
fuse_reply_err(req,err);
|
fuse_reply_err(req,err);
|
||||||
|
|
@ -2105,7 +2113,7 @@ fuse_lib_symlink(fuse_req_t req_,
|
||||||
struct fuse_in_header *hdr_)
|
struct fuse_in_header *hdr_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
char *path;
|
char *fusepath;
|
||||||
struct fuse *f;
|
struct fuse *f;
|
||||||
const char *name;
|
const char *name;
|
||||||
const char *linkname;
|
const char *linkname;
|
||||||
|
|
@ -2116,13 +2124,13 @@ fuse_lib_symlink(fuse_req_t req_,
|
||||||
|
|
||||||
f = req_fuse_prepare(req_);
|
f = req_fuse_prepare(req_);
|
||||||
|
|
||||||
rv = get_path_name(f,hdr_->nodeid,name,&path);
|
rv = get_path_name(f,hdr_->nodeid,name,&fusepath);
|
||||||
if(rv == 0)
|
if(rv == 0)
|
||||||
{
|
{
|
||||||
rv = f->fs->op.symlink(linkname,path,&e.attr,&e.timeout);
|
rv = f->fs->op.symlink(linkname,&fusepath[1],&e.attr,&e.timeout);
|
||||||
if(rv == 0)
|
if(rv == 0)
|
||||||
rv = set_path_info(f,hdr_->nodeid,name,&e);
|
rv = set_path_info(f,hdr_->nodeid,name,&e);
|
||||||
free_path(f,hdr_->nodeid,path);
|
free_path(f,hdr_->nodeid,fusepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
reply_entry(req_,&e,rv);
|
reply_entry(req_,&e,rv);
|
||||||
|
|
@ -2148,12 +2156,19 @@ fuse_lib_rename(fuse_req_t req,
|
||||||
newname = (oldname + strlen(oldname) + 1);
|
newname = (oldname + strlen(oldname) + 1);
|
||||||
|
|
||||||
f = req_fuse_prepare(req);
|
f = req_fuse_prepare(req);
|
||||||
err = get_path2(f,hdr_->nodeid,oldname,arg->newdir,newname,
|
err = get_path2(f,
|
||||||
&oldpath,&newpath,&wnode1,&wnode2);
|
hdr_->nodeid,
|
||||||
|
oldname,
|
||||||
|
arg->newdir,
|
||||||
|
newname,
|
||||||
|
&oldpath,
|
||||||
|
&newpath,
|
||||||
|
&wnode1,
|
||||||
|
&wnode2);
|
||||||
|
|
||||||
if(!err)
|
if(!err)
|
||||||
{
|
{
|
||||||
err = f->fs->op.rename(oldpath,newpath);
|
err = f->fs->op.rename(&oldpath[1],&newpath[1]);
|
||||||
if(!err)
|
if(!err)
|
||||||
err = rename_node(f,hdr_->nodeid,oldname,arg->newdir,newname);
|
err = rename_node(f,hdr_->nodeid,oldname,arg->newdir,newname);
|
||||||
|
|
||||||
|
|
@ -2200,12 +2215,17 @@ fuse_lib_link(fuse_req_t req,
|
||||||
f = req_fuse_prepare(req);
|
f = req_fuse_prepare(req);
|
||||||
|
|
||||||
rv = get_path2(f,
|
rv = get_path2(f,
|
||||||
arg->oldnodeid,NULL,
|
arg->oldnodeid,
|
||||||
hdr_->nodeid,newname,
|
NULL,
|
||||||
&oldpath,&newpath,NULL,NULL);
|
hdr_->nodeid,
|
||||||
|
newname,
|
||||||
|
&oldpath,
|
||||||
|
&newpath,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
if(!rv)
|
if(!rv)
|
||||||
{
|
{
|
||||||
rv = f->fs->op.link(oldpath,newpath,&e.attr,&e.timeout);
|
rv = f->fs->op.link(&oldpath[1],&newpath[1],&e.attr,&e.timeout);
|
||||||
if(rv == 0)
|
if(rv == 0)
|
||||||
rv = set_path_info(f,hdr_->nodeid,newname,&e);
|
rv = set_path_info(f,hdr_->nodeid,newname,&e);
|
||||||
free_path2(f,arg->oldnodeid,hdr_->nodeid,NULL,NULL,oldpath,newpath);
|
free_path2(f,arg->oldnodeid,hdr_->nodeid,NULL,NULL,oldpath,newpath);
|
||||||
|
|
@ -2239,7 +2259,7 @@ fuse_lib_create(fuse_req_t req,
|
||||||
struct fuse_in_header *hdr_)
|
struct fuse_in_header *hdr_)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
char *path;
|
char *fusepath;
|
||||||
struct fuse *f;
|
struct fuse *f;
|
||||||
const char *name;
|
const char *name;
|
||||||
uint64_t new_nodeid;
|
uint64_t new_nodeid;
|
||||||
|
|
@ -2267,13 +2287,13 @@ fuse_lib_create(fuse_req_t req,
|
||||||
fuse_get_context()->nodeid = new_nodeid;
|
fuse_get_context()->nodeid = new_nodeid;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = get_path_name(f,hdr_->nodeid,name,&path);
|
err = get_path_name(f,hdr_->nodeid,name,&fusepath);
|
||||||
if(!err)
|
if(!err)
|
||||||
{
|
{
|
||||||
err = f->fs->op.create(path,arg->mode,&ffi);
|
err = f->fs->op.create(&fusepath[1],arg->mode,&ffi);
|
||||||
if(!err)
|
if(!err)
|
||||||
{
|
{
|
||||||
err = lookup_path(f,hdr_->nodeid,name,path,&e,&ffi);
|
err = lookup_path(f,hdr_->nodeid,name,fusepath,&e,&ffi);
|
||||||
if(err)
|
if(err)
|
||||||
{
|
{
|
||||||
f->fs->op.release(&ffi);
|
f->fs->op.release(&ffi);
|
||||||
|
|
@ -2307,7 +2327,7 @@ fuse_lib_create(fuse_req_t req,
|
||||||
fuse_reply_err(req,err);
|
fuse_reply_err(req,err);
|
||||||
}
|
}
|
||||||
|
|
||||||
free_path(f,hdr_->nodeid,path);
|
free_path(f,hdr_->nodeid,fusepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
|
@ -2352,7 +2372,7 @@ fuse_lib_open(fuse_req_t req,
|
||||||
struct fuse_in_header *hdr_)
|
struct fuse_in_header *hdr_)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
char *path;
|
char *fusepath;
|
||||||
struct fuse *f;
|
struct fuse *f;
|
||||||
fuse_file_info_t ffi = {0};
|
fuse_file_info_t ffi = {0};
|
||||||
struct fuse_open_in *arg;
|
struct fuse_open_in *arg;
|
||||||
|
|
@ -2363,14 +2383,14 @@ fuse_lib_open(fuse_req_t req,
|
||||||
|
|
||||||
f = req_fuse_prepare(req);
|
f = req_fuse_prepare(req);
|
||||||
|
|
||||||
err = get_path(f,hdr_->nodeid,&path);
|
err = get_path(f,hdr_->nodeid,&fusepath);
|
||||||
if(!err)
|
if(!err)
|
||||||
{
|
{
|
||||||
err = f->fs->op.open(path,&ffi);
|
err = f->fs->op.open(&fusepath[1],&ffi);
|
||||||
if(!err)
|
if(!err)
|
||||||
{
|
{
|
||||||
if(ffi.auto_cache && (ffi.passthrough == false))
|
if(ffi.auto_cache && (ffi.passthrough == false))
|
||||||
open_auto_cache(f,hdr_->nodeid,path,&ffi);
|
open_auto_cache(f,hdr_->nodeid,fusepath,&ffi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2388,7 +2408,7 @@ fuse_lib_open(fuse_req_t req,
|
||||||
fuse_reply_err(req,err);
|
fuse_reply_err(req,err);
|
||||||
}
|
}
|
||||||
|
|
||||||
free_path(f,hdr_->nodeid,path);
|
free_path(f,hdr_->nodeid,fusepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
|
@ -2496,7 +2516,7 @@ fuse_lib_opendir(fuse_req_t req,
|
||||||
struct fuse_in_header *hdr_)
|
struct fuse_in_header *hdr_)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
char *path;
|
char *fusepath;
|
||||||
struct fuse_dh *dh;
|
struct fuse_dh *dh;
|
||||||
fuse_file_info_t llffi = {0};
|
fuse_file_info_t llffi = {0};
|
||||||
fuse_file_info_t ffi = {0};
|
fuse_file_info_t ffi = {0};
|
||||||
|
|
@ -2521,10 +2541,10 @@ fuse_lib_opendir(fuse_req_t req,
|
||||||
llffi.fh = (uintptr_t)dh;
|
llffi.fh = (uintptr_t)dh;
|
||||||
ffi.flags = llffi.flags;
|
ffi.flags = llffi.flags;
|
||||||
|
|
||||||
err = get_path(f,hdr_->nodeid,&path);
|
err = get_path(f,hdr_->nodeid,&fusepath);
|
||||||
if(!err)
|
if(!err)
|
||||||
{
|
{
|
||||||
err = f->fs->op.opendir(path,&ffi);
|
err = f->fs->op.opendir(&fusepath[1],&ffi);
|
||||||
dh->fh = ffi.fh;
|
dh->fh = ffi.fh;
|
||||||
llffi.keep_cache = ffi.keep_cache;
|
llffi.keep_cache = ffi.keep_cache;
|
||||||
llffi.cache_readdir = ffi.cache_readdir;
|
llffi.cache_readdir = ffi.cache_readdir;
|
||||||
|
|
@ -2548,7 +2568,7 @@ fuse_lib_opendir(fuse_req_t req,
|
||||||
free(dh);
|
free(dh);
|
||||||
}
|
}
|
||||||
|
|
||||||
free_path(f,hdr_->nodeid,path);
|
free_path(f,hdr_->nodeid,fusepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
|
@ -2557,7 +2577,7 @@ readdir_buf_size(fuse_dirents_t *d_,
|
||||||
size_t size_,
|
size_t size_,
|
||||||
off_t off_)
|
off_t off_)
|
||||||
{
|
{
|
||||||
if(off_ >= kv_size(d_->offs))
|
if((size_t)off_ >= kv_size(d_->offs))
|
||||||
return 0;
|
return 0;
|
||||||
if((kv_A(d_->offs,off_) + size_) > kv_size(d_->data))
|
if((kv_A(d_->offs,off_) + size_) > kv_size(d_->data))
|
||||||
return (kv_size(d_->data) - kv_A(d_->offs,off_));
|
return (kv_size(d_->data) - kv_A(d_->offs,off_));
|
||||||
|
|
@ -2723,19 +2743,20 @@ fuse_lib_statfs(fuse_req_t req,
|
||||||
struct fuse_in_header *hdr_)
|
struct fuse_in_header *hdr_)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
char *path = NULL;
|
char *fusepath;
|
||||||
struct fuse *f;
|
struct fuse *f;
|
||||||
struct statvfs buf = {0};
|
struct statvfs buf = {0};
|
||||||
|
|
||||||
f = req_fuse_prepare(req);
|
f = req_fuse_prepare(req);
|
||||||
|
|
||||||
|
fusepath = NULL;
|
||||||
if(hdr_->nodeid)
|
if(hdr_->nodeid)
|
||||||
err = get_path(f,hdr_->nodeid,&path);
|
err = get_path(f,hdr_->nodeid,&fusepath);
|
||||||
|
|
||||||
if(!err)
|
if(!err)
|
||||||
{
|
{
|
||||||
err = f->fs->op.statfs(path ? path : "/",&buf);
|
err = f->fs->op.statfs(fusepath ? &fusepath[1] : "",&buf);
|
||||||
free_path(f,hdr_->nodeid,path);
|
free_path(f,hdr_->nodeid,fusepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!err)
|
if(!err)
|
||||||
|
|
@ -2750,7 +2771,7 @@ fuse_lib_setxattr(fuse_req_t req,
|
||||||
struct fuse_in_header *hdr_)
|
struct fuse_in_header *hdr_)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
char *path;
|
char *fusepath;
|
||||||
const char *name;
|
const char *name;
|
||||||
const char *value;
|
const char *value;
|
||||||
struct fuse *f;
|
struct fuse *f;
|
||||||
|
|
@ -2766,11 +2787,11 @@ fuse_lib_setxattr(fuse_req_t req,
|
||||||
|
|
||||||
f = req_fuse_prepare(req);
|
f = req_fuse_prepare(req);
|
||||||
|
|
||||||
err = get_path(f,hdr_->nodeid,&path);
|
err = get_path(f,hdr_->nodeid,&fusepath);
|
||||||
if(!err)
|
if(!err)
|
||||||
{
|
{
|
||||||
err = f->fs->op.setxattr(path,name,value,arg->size,arg->flags);
|
err = f->fs->op.setxattr(&fusepath[1],name,value,arg->size,arg->flags);
|
||||||
free_path(f,hdr_->nodeid,path);
|
free_path(f,hdr_->nodeid,fusepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
fuse_reply_err(req,err);
|
fuse_reply_err(req,err);
|
||||||
|
|
@ -2786,14 +2807,14 @@ common_getxattr(struct fuse *f,
|
||||||
size_t size)
|
size_t size)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
char *path;
|
char *fusepath;
|
||||||
|
|
||||||
err = get_path(f,ino,&path);
|
err = get_path(f,ino,&fusepath);
|
||||||
if(!err)
|
if(!err)
|
||||||
{
|
{
|
||||||
err = f->fs->op.getxattr(path,name,value,size);
|
err = f->fs->op.getxattr(&fusepath[1],name,value,size);
|
||||||
|
|
||||||
free_path(f,ino,path);
|
free_path(f,ino,fusepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
|
@ -2848,14 +2869,14 @@ common_listxattr(struct fuse *f,
|
||||||
char *list,
|
char *list,
|
||||||
size_t size)
|
size_t size)
|
||||||
{
|
{
|
||||||
char *path;
|
|
||||||
int err;
|
int err;
|
||||||
|
char *fusepath;
|
||||||
|
|
||||||
err = get_path(f,ino,&path);
|
err = get_path(f,ino,&fusepath);
|
||||||
if(!err)
|
if(!err)
|
||||||
{
|
{
|
||||||
err = f->fs->op.listxattr(path,list,size);
|
err = f->fs->op.listxattr(&fusepath[1],list,size);
|
||||||
free_path(f,ino,path);
|
free_path(f,ino,fusepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
|
@ -2906,7 +2927,7 @@ fuse_lib_removexattr(fuse_req_t req,
|
||||||
const struct fuse_in_header *hdr_)
|
const struct fuse_in_header *hdr_)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
char *path;
|
char *fusepath;
|
||||||
const char *name;
|
const char *name;
|
||||||
struct fuse *f;
|
struct fuse *f;
|
||||||
|
|
||||||
|
|
@ -2914,11 +2935,11 @@ fuse_lib_removexattr(fuse_req_t req,
|
||||||
|
|
||||||
f = req_fuse_prepare(req);
|
f = req_fuse_prepare(req);
|
||||||
|
|
||||||
err = get_path(f,hdr_->nodeid,&path);
|
err = get_path(f,hdr_->nodeid,&fusepath);
|
||||||
if(!err)
|
if(!err)
|
||||||
{
|
{
|
||||||
err = f->fs->op.removexattr(path,name);
|
err = f->fs->op.removexattr(&fusepath[1],name);
|
||||||
free_path(f,hdr_->nodeid,path);
|
free_path(f,hdr_->nodeid,fusepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
fuse_reply_err(req,err);
|
fuse_reply_err(req,err);
|
||||||
|
|
@ -2988,7 +3009,7 @@ fuse_lib_tmpfile(fuse_req_t req_,
|
||||||
const struct fuse_in_header *hdr_)
|
const struct fuse_in_header *hdr_)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
char *path;
|
char *fusepath;
|
||||||
struct fuse *f;
|
struct fuse *f;
|
||||||
const char *name;
|
const char *name;
|
||||||
fuse_file_info_t ffi = {0};
|
fuse_file_info_t ffi = {0};
|
||||||
|
|
@ -3007,13 +3028,13 @@ fuse_lib_tmpfile(fuse_req_t req_,
|
||||||
|
|
||||||
f = req_fuse_prepare(req_);
|
f = req_fuse_prepare(req_);
|
||||||
|
|
||||||
err = get_path_name(f,hdr_->nodeid,name,&path);
|
err = get_path_name(f,hdr_->nodeid,name,&fusepath);
|
||||||
if(!err)
|
if(!err)
|
||||||
{
|
{
|
||||||
err = f->fs->op.tmpfile(path,arg->mode,&ffi);
|
err = f->fs->op.tmpfile(&fusepath[1],arg->mode,&ffi);
|
||||||
if(!err)
|
if(!err)
|
||||||
{
|
{
|
||||||
err = lookup_path(f,hdr_->nodeid,name,path,&e,&ffi);
|
err = lookup_path(f,hdr_->nodeid,name,fusepath,&e,&ffi);
|
||||||
if(err)
|
if(err)
|
||||||
{
|
{
|
||||||
f->fs->op.release(&ffi);
|
f->fs->op.release(&ffi);
|
||||||
|
|
@ -3046,7 +3067,7 @@ fuse_lib_tmpfile(fuse_req_t req_,
|
||||||
fuse_reply_err(req_,err);
|
fuse_reply_err(req_,err);
|
||||||
}
|
}
|
||||||
|
|
||||||
free_path(f,hdr_->nodeid,path);
|
free_path(f,hdr_->nodeid,fusepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
|
@ -3404,7 +3425,7 @@ fuse_lib_bmap(fuse_req_t req,
|
||||||
const struct fuse_in_header *hdr_)
|
const struct fuse_in_header *hdr_)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
char *path;
|
char *fusepath;
|
||||||
struct fuse *f;
|
struct fuse *f;
|
||||||
uint64_t block;
|
uint64_t block;
|
||||||
const struct fuse_bmap_in *arg;
|
const struct fuse_bmap_in *arg;
|
||||||
|
|
@ -3414,11 +3435,11 @@ fuse_lib_bmap(fuse_req_t req,
|
||||||
|
|
||||||
f = req_fuse_prepare(req);
|
f = req_fuse_prepare(req);
|
||||||
|
|
||||||
err = get_path(f,hdr_->nodeid,&path);
|
err = get_path(f,hdr_->nodeid,&fusepath);
|
||||||
if(!err)
|
if(!err)
|
||||||
{
|
{
|
||||||
err = f->fs->op.bmap(path,arg->blocksize,&block);
|
err = f->fs->op.bmap(&fusepath[1],arg->blocksize,&block);
|
||||||
free_path(f,hdr_->nodeid,path);
|
free_path(f,hdr_->nodeid,fusepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!err)
|
if(!err)
|
||||||
|
|
|
||||||
|
|
@ -391,10 +391,10 @@ Branches::Impl::to_paths(StrVec &paths_) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fs::PathVector
|
std::vector<fs::path>
|
||||||
Branches::Impl::to_paths() const
|
Branches::Impl::to_paths() const
|
||||||
{
|
{
|
||||||
fs::PathVector vp;
|
std::vector<fs::path> vp;
|
||||||
|
|
||||||
for(const auto &branch : *this)
|
for(const auto &branch : *this)
|
||||||
vp.emplace_back(branch.path);
|
vp.emplace_back(branch.path);
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "branch.hpp"
|
#include "branch.hpp"
|
||||||
#include "fs_pathvector.hpp"
|
#include "fs_path.hpp"
|
||||||
#include "strvec.hpp"
|
#include "strvec.hpp"
|
||||||
#include "tofrom_string.hpp"
|
#include "tofrom_string.hpp"
|
||||||
|
|
||||||
|
|
@ -52,7 +52,7 @@ public:
|
||||||
public:
|
public:
|
||||||
const u64 &minfreespace(void) const;
|
const u64 &minfreespace(void) const;
|
||||||
void to_paths(StrVec &strvec) const;
|
void to_paths(StrVec &strvec) const;
|
||||||
fs::PathVector to_paths() const;
|
std::vector<fs::path> to_paths() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Impl& operator=(Impl &impl_);
|
Impl& operator=(Impl &impl_);
|
||||||
|
|
|
||||||
|
|
@ -18,12 +18,13 @@
|
||||||
#include "ef.hpp"
|
#include "ef.hpp"
|
||||||
#include "errno.hpp"
|
#include "errno.hpp"
|
||||||
#include "from_string.hpp"
|
#include "from_string.hpp"
|
||||||
|
#include "fs_path.hpp"
|
||||||
|
#include "nonstd/string.hpp"
|
||||||
#include "num.hpp"
|
#include "num.hpp"
|
||||||
#include "rwlock.hpp"
|
#include "rwlock.hpp"
|
||||||
#include "str.hpp"
|
#include "str.hpp"
|
||||||
#include "to_string.hpp"
|
#include "to_string.hpp"
|
||||||
#include "version.hpp"
|
#include "version.hpp"
|
||||||
#include "nonstd/string.hpp"
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
@ -428,15 +429,15 @@ Config::finish_initializing()
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Config::is_rootdir(const char *fusepath_)
|
Config::is_rootdir(const fs::path &fusepath_)
|
||||||
{
|
{
|
||||||
return str::eq(fusepath_,"/");
|
return fusepath_.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Config::is_ctrl_file(const char *fusepath_)
|
Config::is_ctrl_file(const fs::path &fusepath_)
|
||||||
{
|
{
|
||||||
return str::eq(fusepath_,"/.mergerfs");
|
return (fusepath_ == ".mergerfs");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@
|
||||||
#include "config_xattr.hpp"
|
#include "config_xattr.hpp"
|
||||||
#include "enum.hpp"
|
#include "enum.hpp"
|
||||||
#include "errno.hpp"
|
#include "errno.hpp"
|
||||||
|
#include "fs_path.hpp"
|
||||||
#include "funcs.hpp"
|
#include "funcs.hpp"
|
||||||
#include "fuse_readdir.hpp"
|
#include "fuse_readdir.hpp"
|
||||||
#include "policy.hpp"
|
#include "policy.hpp"
|
||||||
|
|
@ -46,7 +47,6 @@
|
||||||
#include "fuse.h"
|
#include "fuse.h"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <filesystem>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
@ -59,7 +59,7 @@ typedef ToFromWrapper<uint64_t> ConfigUINT64;
|
||||||
typedef ToFromWrapper<int64_t> ConfigS64;
|
typedef ToFromWrapper<int64_t> ConfigS64;
|
||||||
typedef ToFromWrapper<int> ConfigINT;
|
typedef ToFromWrapper<int> ConfigINT;
|
||||||
typedef ToFromWrapper<std::string> ConfigSTR;
|
typedef ToFromWrapper<std::string> ConfigSTR;
|
||||||
typedef ToFromWrapper<std::filesystem::path> ConfigPath;
|
typedef ToFromWrapper<fs::path> ConfigPath;
|
||||||
typedef std::map<std::string,ToFromString*> Str2TFStrMap;
|
typedef std::map<std::string,ToFromString*> Str2TFStrMap;
|
||||||
|
|
||||||
extern const std::string CONTROLFILE;
|
extern const std::string CONTROLFILE;
|
||||||
|
|
@ -173,8 +173,8 @@ public:
|
||||||
int from_file(const std::string &filepath, ErrVec *errs);
|
int from_file(const std::string &filepath, ErrVec *errs);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static bool is_rootdir(const char *fusepath);
|
static bool is_rootdir(const fs::path &fusepath);
|
||||||
static bool is_ctrl_file(const char *fusepath);
|
static bool is_ctrl_file(const fs::path &fusepath);
|
||||||
static bool is_mergerfs_xattr(const char *attrname);
|
static bool is_mergerfs_xattr(const char *attrname);
|
||||||
static bool is_cmd_xattr(const std::string_view &attrname);
|
static bool is_cmd_xattr(const std::string_view &attrname);
|
||||||
static std::string prune_ctrl_xattr(const std::string &s);
|
static std::string prune_ctrl_xattr(const std::string &s);
|
||||||
|
|
|
||||||
|
|
@ -34,5 +34,5 @@ InodeCalc::to_string(void) const
|
||||||
int
|
int
|
||||||
InodeCalc::from_string(const std::string_view s_)
|
InodeCalc::from_string(const std::string_view s_)
|
||||||
{
|
{
|
||||||
return fs::inode::set_algo(s_);
|
return fs::inode::set_algo(std::string{s_});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,14 +18,32 @@
|
||||||
|
|
||||||
#include "fh.hpp"
|
#include "fh.hpp"
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
|
|
||||||
class DirInfo : public FH
|
class DirInfo : public FH
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DirInfo(const char *fusepath_)
|
static DirInfo *from_fh(const uint64_t fh);
|
||||||
|
|
||||||
|
public:
|
||||||
|
uint64_t to_fh() const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
DirInfo(const fs::path &fusepath_)
|
||||||
: FH(fusepath_)
|
: FH(fusepath_)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline
|
||||||
|
uint64_t
|
||||||
|
DirInfo::to_fh() const
|
||||||
|
{
|
||||||
|
return reinterpret_cast<uint64_t>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
DirInfo*
|
||||||
|
DirInfo::from_fh(const uint64_t fh_)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<DirInfo*>(fh_);
|
||||||
|
}
|
||||||
|
|
|
||||||
13
src/fh.hpp
13
src/fh.hpp
|
|
@ -16,23 +16,18 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include "fs_path.hpp"
|
||||||
|
|
||||||
|
|
||||||
class FH
|
class FH
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FH(const std::string fusepath_)
|
FH(const fs::path &fusepath_)
|
||||||
: fusepath(std::move(fusepath_))
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
FH(const char *fusepath_)
|
|
||||||
: fusepath(fusepath_)
|
: fusepath(fusepath_)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::string fusepath;
|
fs::path fusepath;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,10 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "fh.hpp"
|
|
||||||
#include "branch.hpp"
|
#include "branch.hpp"
|
||||||
|
#include "fh.hpp"
|
||||||
|
#include "fs_path.hpp"
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#include "int_types.h"
|
#include "int_types.h"
|
||||||
|
|
@ -28,24 +28,27 @@
|
||||||
class FileInfo : public FH
|
class FileInfo : public FH
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FileInfo(const int fd_,
|
static FileInfo *from_fh(const uint64_t fh);
|
||||||
const Branch &branch_,
|
|
||||||
const char *fusepath_,
|
public:
|
||||||
const bool direct_io_)
|
FileInfo(const int fd_,
|
||||||
|
const Branch *branch_,
|
||||||
|
const fs::path &fusepath_,
|
||||||
|
const bool direct_io_)
|
||||||
: FH(fusepath_),
|
: FH(fusepath_),
|
||||||
fd(fd_),
|
fd(fd_),
|
||||||
branch(branch_),
|
branch(*branch_),
|
||||||
direct_io(direct_io_)
|
direct_io(direct_io_)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
FileInfo(const int fd_,
|
FileInfo(const int fd_,
|
||||||
const Branch *branch_,
|
const Branch &branch_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
const bool direct_io_)
|
const bool direct_io_)
|
||||||
: FH(fusepath_),
|
: FH(fusepath_),
|
||||||
fd(fd_),
|
fd(fd_),
|
||||||
branch(*branch_),
|
branch(branch_),
|
||||||
direct_io(direct_io_)
|
direct_io(direct_io_)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -58,9 +61,26 @@ public:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
uint64_t to_fh() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int fd;
|
int fd;
|
||||||
Branch branch;
|
Branch branch;
|
||||||
u32 direct_io:1;
|
u32 direct_io:1;
|
||||||
std::mutex mutex;
|
std::mutex mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline
|
||||||
|
uint64_t
|
||||||
|
FileInfo::to_fh() const
|
||||||
|
{
|
||||||
|
return reinterpret_cast<uint64_t>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
FileInfo*
|
||||||
|
FileInfo::from_fh(const uintptr_t fh_)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<FileInfo*>(fh_);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -187,7 +187,7 @@ str::from(const std::string_view value_,
|
||||||
|
|
||||||
int
|
int
|
||||||
str::from(const std::string_view value_,
|
str::from(const std::string_view value_,
|
||||||
std::filesystem::path *path_)
|
fs::path *path_)
|
||||||
{
|
{
|
||||||
*path_ = value_;
|
*path_ = value_;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,9 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "fs_path.hpp"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <filesystem>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
|
||||||
|
|
@ -32,5 +33,5 @@ namespace str
|
||||||
int from(const std::string_view, int64_t *);
|
int from(const std::string_view, int64_t *);
|
||||||
int from(const std::string_view, std::string *);
|
int from(const std::string_view, std::string *);
|
||||||
int from(const std::string_view, const std::string *);
|
int from(const std::string_view, const std::string *);
|
||||||
int from(const std::string_view, std::filesystem::path *);
|
int from(const std::string_view, fs::path *);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,18 +21,18 @@
|
||||||
#include "fs_lgetxattr.hpp"
|
#include "fs_lgetxattr.hpp"
|
||||||
#include "fs_path.hpp"
|
#include "fs_path.hpp"
|
||||||
|
|
||||||
#include <string>
|
#include <filesystem>
|
||||||
|
|
||||||
constexpr const char POSIX_ACL_DEFAULT_XATTR[] = "system.posix_acl_default";
|
constexpr const char POSIX_ACL_DEFAULT_XATTR[] = "system.posix_acl_default";
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
fs::acl::dir_has_defaults(const std::string &fullpath_)
|
fs::acl::dir_has_defaults(const fs::path &fullpath_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
std::string dirpath;
|
fs::path dirpath;
|
||||||
|
|
||||||
dirpath = fs::path::dirname(fullpath_);
|
dirpath = fullpath_.parent_path();
|
||||||
|
|
||||||
rv = fs::lgetxattr(dirpath,POSIX_ACL_DEFAULT_XATTR,NULL,0);
|
rv = fs::lgetxattr(dirpath,POSIX_ACL_DEFAULT_XATTR,NULL,0);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include "fs_path.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace fs
|
namespace fs
|
||||||
|
|
@ -26,6 +26,6 @@ namespace fs
|
||||||
namespace acl
|
namespace acl
|
||||||
{
|
{
|
||||||
bool
|
bool
|
||||||
dir_has_defaults(const std::string &fullpath);
|
dir_has_defaults(const fs::path &fullpath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,10 +27,6 @@
|
||||||
#include "fs_xattr.hpp"
|
#include "fs_xattr.hpp"
|
||||||
#include "ugid.hpp"
|
#include "ugid.hpp"
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
using std::string;
|
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
bool
|
bool
|
||||||
|
|
@ -56,36 +52,36 @@ _ignorable_error(const int err_)
|
||||||
possible. Optionally ignore errors on metadata copies.
|
possible. Optionally ignore errors on metadata copies.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
fs::clonepath(const string &srcpath_,
|
fs::clonepath(const fs::path &srcpath_,
|
||||||
const string &dstpath_,
|
const fs::path &dstpath_,
|
||||||
const char *relpath_,
|
const fs::path &relpath_,
|
||||||
const bool return_metadata_errors_)
|
const bool return_metadata_errors_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
string dstpath;
|
fs::path dstpath;
|
||||||
string srcpath;
|
fs::path srcpath;
|
||||||
string dirname;
|
fs::path dirname;
|
||||||
|
|
||||||
if((relpath_ == NULL) || (relpath_[0] == '\0'))
|
if(relpath_.empty())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
dirname = fs::path::dirname(relpath_);
|
dirname = relpath_.parent_path();
|
||||||
if(dirname != "/")
|
if(!dirname.empty())
|
||||||
{
|
{
|
||||||
rv = fs::clonepath(srcpath_,dstpath_,dirname,return_metadata_errors_);
|
rv = fs::clonepath(srcpath_,dstpath_,dirname,return_metadata_errors_);
|
||||||
if(rv < 0)
|
if(rv < 0)
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
srcpath = fs::path::make(srcpath_,relpath_);
|
srcpath = srcpath_ / relpath_;
|
||||||
rv = fs::lstat(srcpath,&st);
|
rv = fs::lstat(srcpath,&st);
|
||||||
if(rv < 0)
|
if(rv < 0)
|
||||||
return rv;
|
return rv;
|
||||||
else if(!S_ISDIR(st.st_mode))
|
else if(!S_ISDIR(st.st_mode))
|
||||||
return -ENOTDIR;
|
return -ENOTDIR;
|
||||||
|
|
||||||
dstpath = fs::path::make(dstpath_,relpath_);
|
dstpath = dstpath_ / relpath_;
|
||||||
rv = fs::mkdir(dstpath,st.st_mode);
|
rv = fs::mkdir(dstpath,st.st_mode);
|
||||||
if(rv < 0)
|
if(rv < 0)
|
||||||
return ((rv == -EEXIST) ? 0 : rv);
|
return ((rv == -EEXIST) ? 0 : rv);
|
||||||
|
|
@ -112,24 +108,12 @@ fs::clonepath(const string &srcpath_,
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fs::clonepath(const string &srcpath_,
|
fs::clonepath_as_root(const fs::path &srcpath_,
|
||||||
const string &dstpath_,
|
const fs::path &dstpath_,
|
||||||
const string &relpath_,
|
const fs::path &relpath_,
|
||||||
const bool return_metadata_errors_)
|
const bool return_metadata_errors_)
|
||||||
{
|
{
|
||||||
return fs::clonepath(srcpath_,
|
if(relpath_.empty())
|
||||||
dstpath_,
|
|
||||||
relpath_.c_str(),
|
|
||||||
return_metadata_errors_);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
fs::clonepath_as_root(const string &srcpath_,
|
|
||||||
const string &dstpath_,
|
|
||||||
const char *relpath_,
|
|
||||||
const bool return_metadata_errors_)
|
|
||||||
{
|
|
||||||
if((relpath_ == NULL) || (relpath_[0] == '\0'))
|
|
||||||
return 0;
|
return 0;
|
||||||
if(srcpath_ == dstpath_)
|
if(srcpath_ == dstpath_)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -141,15 +125,3 @@ fs::clonepath_as_root(const string &srcpath_,
|
||||||
relpath_,
|
relpath_,
|
||||||
return_metadata_errors_);
|
return_metadata_errors_);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
fs::clonepath_as_root(const string &srcpath_,
|
|
||||||
const string &dstpath_,
|
|
||||||
const string &relpath_,
|
|
||||||
const bool return_metadata_errors_)
|
|
||||||
{
|
|
||||||
return fs::clonepath_as_root(srcpath_,
|
|
||||||
dstpath_,
|
|
||||||
relpath_.c_str(),
|
|
||||||
return_metadata_errors_);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -16,26 +16,18 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include "fs_path.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace fs
|
namespace fs
|
||||||
{
|
{
|
||||||
int clonepath(const std::string &srcpath,
|
int clonepath(const fs::path &srcpath,
|
||||||
const std::string &dstpath,
|
const fs::path &dstpath,
|
||||||
const char *relpath,
|
const fs::path &relpath,
|
||||||
const bool return_metadata_errors = false);
|
const bool return_metadata_errors = false);
|
||||||
int clonepath(const std::string &srcpath,
|
|
||||||
const std::string &dstpath,
|
|
||||||
const std::string &relpath,
|
|
||||||
const bool return_metadata_errors = false);
|
|
||||||
|
|
||||||
int clonepath_as_root(const std::string &srcpath,
|
int clonepath_as_root(const fs::path &srcpath,
|
||||||
const std::string &dstpath,
|
const fs::path &dstpath,
|
||||||
const char *relpath,
|
const fs::path &relpath,
|
||||||
const bool return_metadata_errors = false);
|
const bool return_metadata_errors = false);
|
||||||
int clonepath_as_root(const std::string &srcpath,
|
|
||||||
const std::string &dstpath,
|
|
||||||
const std::string &relpath,
|
|
||||||
const bool return_metadata_errors = false);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
#include "fs_futimens.hpp"
|
#include "fs_futimens.hpp"
|
||||||
#include "fs_mktemp.hpp"
|
#include "fs_mktemp.hpp"
|
||||||
#include "fs_open.hpp"
|
#include "fs_open.hpp"
|
||||||
|
#include "fs_path.hpp"
|
||||||
#include "fs_rename.hpp"
|
#include "fs_rename.hpp"
|
||||||
#include "fs_unlink.hpp"
|
#include "fs_unlink.hpp"
|
||||||
#include "fs_xattr.hpp"
|
#include "fs_xattr.hpp"
|
||||||
|
|
@ -96,9 +97,9 @@ fs::copyfile(const int src_fd_,
|
||||||
// * Does not handle non-regular files.
|
// * Does not handle non-regular files.
|
||||||
|
|
||||||
s64
|
s64
|
||||||
fs::copyfile(const int src_fd_,
|
fs::copyfile(const int src_fd_,
|
||||||
const std::filesystem::path &dst_filepath_,
|
const fs::path &dst_filepath_,
|
||||||
const fs::CopyFileFlags &flags_)
|
const fs::CopyFileFlags &flags_)
|
||||||
{
|
{
|
||||||
s64 rv;
|
s64 rv;
|
||||||
int dst_fd;
|
int dst_fd;
|
||||||
|
|
@ -164,9 +165,9 @@ fs::copyfile(const int src_fd_,
|
||||||
}
|
}
|
||||||
|
|
||||||
s64
|
s64
|
||||||
fs::copyfile(const std::filesystem::path &src_filepath_,
|
fs::copyfile(const fs::path &src_filepath_,
|
||||||
const std::filesystem::path &dst_filepath_,
|
const fs::path &dst_filepath_,
|
||||||
const fs::CopyFileFlags &flags_)
|
const fs::CopyFileFlags &flags_)
|
||||||
{
|
{
|
||||||
int src_fd;
|
int src_fd;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "int_types.h"
|
#include "int_types.h"
|
||||||
|
#include "fs_path.hpp"
|
||||||
#include <filesystem>
|
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
|
@ -22,12 +21,12 @@ namespace fs
|
||||||
const int dst_fd);
|
const int dst_fd);
|
||||||
|
|
||||||
s64
|
s64
|
||||||
copyfile(const int src_fd,
|
copyfile(const int src_fd,
|
||||||
const std::filesystem::path &dst_filepath,
|
const fs::path &dst_filepath,
|
||||||
const CopyFileFlags &flags);
|
const CopyFileFlags &flags);
|
||||||
|
|
||||||
s64
|
s64
|
||||||
copyfile(const std::filesystem::path &src_filepath,
|
copyfile(const fs::path &src_filepath,
|
||||||
const std::filesystem::path &dst_filepath,
|
const fs::path &dst_filepath,
|
||||||
const CopyFileFlags &flags);
|
const CopyFileFlags &flags);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,8 +53,8 @@ fs::cow::is_eligible(const int flags_,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
fs::cow::is_eligible(const char *fullpath_,
|
fs::cow::is_eligible(const fs::path &fullpath_,
|
||||||
const int flags_)
|
const int flags_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
@ -70,7 +70,7 @@ fs::cow::is_eligible(const char *fullpath_,
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fs::cow::break_link(const char *src_filepath_)
|
fs::cow::break_link(const fs::path &src_filepath_)
|
||||||
{
|
{
|
||||||
return fs::copyfile(src_filepath_,
|
return fs::copyfile(src_filepath_,
|
||||||
src_filepath_,
|
src_filepath_,
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "fs_path.hpp"
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
|
@ -30,8 +32,8 @@ namespace fs
|
||||||
bool is_eligible(const struct stat &st);
|
bool is_eligible(const struct stat &st);
|
||||||
bool is_eligible(const int flags, const struct stat &st);
|
bool is_eligible(const int flags, const struct stat &st);
|
||||||
|
|
||||||
bool is_eligible(const char *fullpath, const int flags);
|
bool is_eligible(const fs::path &fullpath, const int flags);
|
||||||
|
|
||||||
int break_link(const char *fullpath);
|
int break_link(const fs::path &fullpath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,4 +40,13 @@ namespace fs
|
||||||
{
|
{
|
||||||
return fs::eaccess(path_.c_str(),mode_);
|
return fs::eaccess(path_.c_str(),mode_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
int
|
||||||
|
eaccess(const fs::path &path_,
|
||||||
|
const int mode_)
|
||||||
|
{
|
||||||
|
return fs::eaccess(path_.c_str(),mode_);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,16 +21,14 @@
|
||||||
#include "fs_lstat.hpp"
|
#include "fs_lstat.hpp"
|
||||||
#include "fs_path.hpp"
|
#include "fs_path.hpp"
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
|
|
||||||
namespace fs
|
namespace fs
|
||||||
{
|
{
|
||||||
static
|
static
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
exists(const std::string &path_,
|
exists(const fs::path &path_,
|
||||||
struct stat *st_)
|
struct stat *st_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
|
|
@ -42,7 +40,7 @@ namespace fs
|
||||||
static
|
static
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
exists(const std::string &path_)
|
exists(const fs::path &path_)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
|
|
@ -52,26 +50,13 @@ namespace fs
|
||||||
static
|
static
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
exists(const std::string &basepath_,
|
exists(const fs::path &basepath_,
|
||||||
const std::string &relpath_)
|
const char *relpath_,
|
||||||
|
struct stat *st_)
|
||||||
{
|
{
|
||||||
std::string fullpath;
|
fs::path fullpath;
|
||||||
|
|
||||||
fullpath = fs::path::make(basepath_,relpath_);
|
fullpath = basepath_ / relpath_;
|
||||||
|
|
||||||
return fs::exists(fullpath);
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
inline
|
|
||||||
bool
|
|
||||||
exists(const std::string &basepath_,
|
|
||||||
const char *relpath_,
|
|
||||||
struct stat *st_)
|
|
||||||
{
|
|
||||||
std::string fullpath;
|
|
||||||
|
|
||||||
fullpath = fs::path::make(basepath_,relpath_);
|
|
||||||
|
|
||||||
return fs::exists(fullpath,st_);
|
return fs::exists(fullpath,st_);
|
||||||
}
|
}
|
||||||
|
|
@ -79,8 +64,33 @@ namespace fs
|
||||||
static
|
static
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
exists(const std::string &basepath_,
|
exists(const fs::path &basepath_,
|
||||||
const char *relpath_)
|
const fs::path &relpath_,
|
||||||
|
struct stat *st_)
|
||||||
|
{
|
||||||
|
fs::path fullpath;
|
||||||
|
|
||||||
|
fullpath = basepath_ / relpath_;
|
||||||
|
|
||||||
|
return fs::exists(fullpath,st_);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
bool
|
||||||
|
exists(const fs::path &basepath_,
|
||||||
|
const char *relpath_)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
return fs::exists(basepath_,relpath_,&st);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
bool
|
||||||
|
exists(const fs::path &basepath_,
|
||||||
|
const fs::path &relpath_)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "fs_path.hpp"
|
||||||
#include "to_neg_errno.hpp"
|
#include "to_neg_errno.hpp"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
@ -38,7 +39,10 @@ namespace fs
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
rv = ::faccessat(dirfd_,path_,mode_,flags_);
|
rv = ::faccessat(dirfd_,
|
||||||
|
path_,
|
||||||
|
mode_,
|
||||||
|
flags_);
|
||||||
|
|
||||||
return ::to_neg_errno(rv);
|
return ::to_neg_errno(rv);
|
||||||
}
|
}
|
||||||
|
|
@ -51,6 +55,23 @@ namespace fs
|
||||||
const int mode_,
|
const int mode_,
|
||||||
const int flags_)
|
const int flags_)
|
||||||
{
|
{
|
||||||
return fs::faccessat(dirfd_,path_.c_str(),mode_,flags_);
|
return fs::faccessat(dirfd_,
|
||||||
|
path_.c_str(),
|
||||||
|
mode_,
|
||||||
|
flags_);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
int
|
||||||
|
faccessat(const int dirfd_,
|
||||||
|
const fs::path &path_,
|
||||||
|
const int mode_,
|
||||||
|
const int flags_)
|
||||||
|
{
|
||||||
|
return fs::faccessat(dirfd_,
|
||||||
|
path_.c_str(),
|
||||||
|
mode_,
|
||||||
|
flags_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,11 @@
|
||||||
|
|
||||||
#include "fs_fchmodat.hpp"
|
#include "fs_fchmodat.hpp"
|
||||||
|
|
||||||
|
#include "fs_path.hpp"
|
||||||
#include "to_neg_errno.hpp"
|
#include "to_neg_errno.hpp"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
|
@ -38,7 +41,10 @@ namespace fs
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
rv = ::fchmodat(dirfd_,pathname_,mode_,flags_);
|
rv = ::fchmodat(dirfd_,
|
||||||
|
pathname_,
|
||||||
|
mode_,
|
||||||
|
flags_);
|
||||||
|
|
||||||
return ::to_neg_errno(rv);
|
return ::to_neg_errno(rv);
|
||||||
}
|
}
|
||||||
|
|
@ -51,6 +57,23 @@ namespace fs
|
||||||
const mode_t mode_,
|
const mode_t mode_,
|
||||||
const int flags_)
|
const int flags_)
|
||||||
{
|
{
|
||||||
return fs::fchmodat(dirfd_,pathname_.c_str(),mode_,flags_);
|
return fs::fchmodat(dirfd_,
|
||||||
|
pathname_.c_str(),
|
||||||
|
mode_,
|
||||||
|
flags_);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
int
|
||||||
|
fchmodat(const int dirfd_,
|
||||||
|
const fs::path &pathname_,
|
||||||
|
const mode_t mode_,
|
||||||
|
const int flags_)
|
||||||
|
{
|
||||||
|
return fs::fchmodat(dirfd_,
|
||||||
|
pathname_.c_str(),
|
||||||
|
mode_,
|
||||||
|
flags_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
#include "to_neg_errno.hpp"
|
#include "to_neg_errno.hpp"
|
||||||
#include "xattr.hpp"
|
#include "xattr.hpp"
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
|
||||||
|
|
@ -27,14 +27,14 @@
|
||||||
|
|
||||||
void
|
void
|
||||||
fs::findallfiles(const std::vector<std::string> &basepaths_,
|
fs::findallfiles(const std::vector<std::string> &basepaths_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
std::vector<std::string> *paths_)
|
std::vector<std::string> *paths_)
|
||||||
{
|
{
|
||||||
std::string fullpath;
|
fs::path fullpath;
|
||||||
|
|
||||||
for(const auto &basepath : basepaths_)
|
for(const auto &basepath : basepaths_)
|
||||||
{
|
{
|
||||||
fullpath = fs::path::make(basepath,fusepath_);
|
fullpath = basepath / fusepath_;
|
||||||
|
|
||||||
if(!fs::exists(fullpath))
|
if(!fs::exists(fullpath))
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "strvec.hpp"
|
#include "fs_path.hpp"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
namespace fs
|
namespace fs
|
||||||
{
|
{
|
||||||
void
|
void
|
||||||
findallfiles(const StrVec &basepaths,
|
findallfiles(const std::vector<std::string> &basepaths,
|
||||||
const char *fusepath,
|
const fs::path &fusepath,
|
||||||
StrVec *paths);
|
std::vector<std::string> *paths);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,14 +30,14 @@
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_findonfs(const Branches::Ptr &branches_,
|
_findonfs(const Branches::Ptr &branches_,
|
||||||
const std::string &fusepath_,
|
const fs::path &fusepath_,
|
||||||
const int fd_,
|
const int fd_,
|
||||||
std::string *basepath_)
|
std::string *basepath_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
dev_t dev;
|
dev_t dev;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
std::string fullpath;
|
fs::path fullpath;
|
||||||
|
|
||||||
rv = fs::fstat(fd_,&st);
|
rv = fs::fstat(fd_,&st);
|
||||||
if(rv < 0)
|
if(rv < 0)
|
||||||
|
|
@ -46,7 +46,7 @@ _findonfs(const Branches::Ptr &branches_,
|
||||||
dev = st.st_dev;
|
dev = st.st_dev;
|
||||||
for(const auto &branch : *branches_)
|
for(const auto &branch : *branches_)
|
||||||
{
|
{
|
||||||
fullpath = fs::path::make(branch.path,fusepath_);
|
fullpath = branch.path / fusepath_;
|
||||||
|
|
||||||
rv = fs::lstat(fullpath,&st);
|
rv = fs::lstat(fullpath,&st);
|
||||||
if(rv < 0)
|
if(rv < 0)
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "fs_path.hpp"
|
||||||
#include "to_neg_errno.hpp"
|
#include "to_neg_errno.hpp"
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
@ -43,6 +44,20 @@ namespace fs
|
||||||
return ::to_neg_errno(rv);
|
return ::to_neg_errno(rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
int
|
||||||
|
fstatat(const int dirfd_,
|
||||||
|
const fs::path &pathname_,
|
||||||
|
struct stat *statbuf_,
|
||||||
|
const int flags_)
|
||||||
|
{
|
||||||
|
return fs::fstatat(dirfd_,
|
||||||
|
pathname_.c_str(),
|
||||||
|
statbuf_,
|
||||||
|
flags_);
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
inline
|
inline
|
||||||
int
|
int
|
||||||
|
|
@ -55,4 +70,17 @@ namespace fs
|
||||||
statbuf_,
|
statbuf_,
|
||||||
AT_SYMLINK_NOFOLLOW);
|
AT_SYMLINK_NOFOLLOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
int
|
||||||
|
fstatat_nofollow(const int dirfd_,
|
||||||
|
const fs::path &pathname_,
|
||||||
|
struct stat *statbuf_)
|
||||||
|
{
|
||||||
|
return fs::fstatat(dirfd_,
|
||||||
|
pathname_,
|
||||||
|
statbuf_,
|
||||||
|
AT_SYMLINK_NOFOLLOW);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,13 +26,13 @@
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
typedef uint64_t (*inodefunc_t)(const std::string_view,
|
typedef uint64_t (*inodefunc_t)(const std::string &,
|
||||||
const std::string_view,
|
const std::string &,
|
||||||
const mode_t,
|
const mode_t,
|
||||||
const ino_t);
|
const ino_t);
|
||||||
|
|
||||||
static uint64_t _hybrid_hash(const std::string_view,
|
static uint64_t _hybrid_hash(const std::string &,
|
||||||
const std::string_view,
|
const std::string &,
|
||||||
const mode_t,
|
const mode_t,
|
||||||
const ino_t);
|
const ino_t);
|
||||||
|
|
||||||
|
|
@ -51,8 +51,8 @@ _h64_to_h32(uint64_t h_)
|
||||||
|
|
||||||
static
|
static
|
||||||
uint64_t
|
uint64_t
|
||||||
_passthrough(const std::string_view branch_path_,
|
_passthrough(const std::string &branch_path_,
|
||||||
const std::string_view fusepath_,
|
const std::string &fusepath_,
|
||||||
const mode_t mode_,
|
const mode_t mode_,
|
||||||
const ino_t ino_)
|
const ino_t ino_)
|
||||||
{
|
{
|
||||||
|
|
@ -61,8 +61,8 @@ _passthrough(const std::string_view branch_path_,
|
||||||
|
|
||||||
static
|
static
|
||||||
uint64_t
|
uint64_t
|
||||||
_path_hash(const std::string_view branch_path_,
|
_path_hash(const std::string &branch_path_,
|
||||||
const std::string_view fusepath_,
|
const std::string &fusepath_,
|
||||||
const mode_t mode_,
|
const mode_t mode_,
|
||||||
const ino_t ino_)
|
const ino_t ino_)
|
||||||
{
|
{
|
||||||
|
|
@ -75,8 +75,8 @@ _path_hash(const std::string_view branch_path_,
|
||||||
|
|
||||||
static
|
static
|
||||||
uint64_t
|
uint64_t
|
||||||
_path_hash32(const std::string_view branch_path_,
|
_path_hash32(const std::string &branch_path_,
|
||||||
const std::string_view fusepath_,
|
const std::string &fusepath_,
|
||||||
const mode_t mode_,
|
const mode_t mode_,
|
||||||
const ino_t ino_)
|
const ino_t ino_)
|
||||||
{
|
{
|
||||||
|
|
@ -92,8 +92,8 @@ _path_hash32(const std::string_view branch_path_,
|
||||||
|
|
||||||
static
|
static
|
||||||
uint64_t
|
uint64_t
|
||||||
_devino_hash(const std::string_view branch_path_,
|
_devino_hash(const std::string &branch_path_,
|
||||||
const std::string_view fusepath_,
|
const std::string &fusepath_,
|
||||||
const mode_t mode_,
|
const mode_t mode_,
|
||||||
const ino_t ino_)
|
const ino_t ino_)
|
||||||
{
|
{
|
||||||
|
|
@ -107,8 +107,8 @@ _devino_hash(const std::string_view branch_path_,
|
||||||
|
|
||||||
static
|
static
|
||||||
uint64_t
|
uint64_t
|
||||||
_devino_hash32(const std::string_view branch_path_,
|
_devino_hash32(const std::string &branch_path_,
|
||||||
const std::string_view fusepath_,
|
const std::string &fusepath_,
|
||||||
const mode_t mode_,
|
const mode_t mode_,
|
||||||
const ino_t ino_)
|
const ino_t ino_)
|
||||||
{
|
{
|
||||||
|
|
@ -124,8 +124,8 @@ _devino_hash32(const std::string_view branch_path_,
|
||||||
|
|
||||||
static
|
static
|
||||||
uint64_t
|
uint64_t
|
||||||
_hybrid_hash(const std::string_view branch_path_,
|
_hybrid_hash(const std::string &branch_path_,
|
||||||
const std::string_view fusepath_,
|
const std::string &fusepath_,
|
||||||
const mode_t mode_,
|
const mode_t mode_,
|
||||||
const ino_t ino_)
|
const ino_t ino_)
|
||||||
{
|
{
|
||||||
|
|
@ -136,8 +136,8 @@ _hybrid_hash(const std::string_view branch_path_,
|
||||||
|
|
||||||
static
|
static
|
||||||
uint64_t
|
uint64_t
|
||||||
_hybrid_hash32(const std::string_view branch_path_,
|
_hybrid_hash32(const std::string &branch_path_,
|
||||||
const std::string_view fusepath_,
|
const std::string &fusepath_,
|
||||||
const mode_t mode_,
|
const mode_t mode_,
|
||||||
const ino_t ino_)
|
const ino_t ino_)
|
||||||
{
|
{
|
||||||
|
|
@ -147,7 +147,7 @@ _hybrid_hash32(const std::string_view branch_path_,
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fs::inode::set_algo(const std::string_view algo_)
|
fs::inode::set_algo(const std::string &algo_)
|
||||||
{
|
{
|
||||||
if(algo_ == "passthrough")
|
if(algo_ == "passthrough")
|
||||||
g_func = ::_passthrough;
|
g_func = ::_passthrough;
|
||||||
|
|
@ -191,18 +191,18 @@ fs::inode::get_algo(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t
|
uint64_t
|
||||||
fs::inode::calc(const std::string_view branch_path_,
|
fs::inode::calc(const std::string &branch_path_,
|
||||||
const std::string_view fusepath_,
|
const std::string &fusepath_,
|
||||||
const mode_t mode_,
|
const mode_t mode_,
|
||||||
const ino_t ino_)
|
const ino_t ino_)
|
||||||
{
|
{
|
||||||
return g_func(branch_path_,fusepath_,mode_,ino_);
|
return g_func(branch_path_,fusepath_,mode_,ino_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fs::inode::calc(const std::string_view branch_path_,
|
fs::inode::calc(const std::string &branch_path_,
|
||||||
const std::string_view fusepath_,
|
const std::string &fusepath_,
|
||||||
struct stat *st_)
|
struct stat *st_)
|
||||||
{
|
{
|
||||||
st_->st_ino = calc(branch_path_,
|
st_->st_ino = calc(branch_path_,
|
||||||
fusepath_,
|
fusepath_,
|
||||||
|
|
@ -211,9 +211,9 @@ fs::inode::calc(const std::string_view branch_path_,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fs::inode::calc(const std::string_view branch_path_,
|
fs::inode::calc(const std::string &branch_path_,
|
||||||
const std::string_view fusepath_,
|
const std::string &fusepath_,
|
||||||
struct fuse_statx *st_)
|
struct fuse_statx *st_)
|
||||||
{
|
{
|
||||||
st_->ino = calc(branch_path_,
|
st_->ino = calc(branch_path_,
|
||||||
fusepath_,
|
fusepath_,
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
|
@ -31,19 +30,19 @@ namespace fs
|
||||||
{
|
{
|
||||||
namespace inode
|
namespace inode
|
||||||
{
|
{
|
||||||
int set_algo(const std::string_view s);
|
int set_algo(const std::string &s);
|
||||||
std::string get_algo(void);
|
std::string get_algo(void);
|
||||||
|
|
||||||
uint64_t calc(const std::string_view basepath,
|
uint64_t calc(const std::string &basepath,
|
||||||
const std::string_view fusepath,
|
const std::string &fusepath,
|
||||||
const mode_t mode,
|
const mode_t mode,
|
||||||
const ino_t ino);
|
const ino_t ino);
|
||||||
|
|
||||||
void calc(const std::string_view basepath,
|
void calc(const std::string &basepath,
|
||||||
const std::string_view fusepath,
|
const std::string &fusepath,
|
||||||
struct stat *st);
|
struct stat *st);
|
||||||
void calc(const std::string_view basepath,
|
void calc(const std::string &basepath,
|
||||||
const std::string_view fusepath,
|
const std::string &fusepath,
|
||||||
struct fuse_statx *st);
|
struct fuse_statx *st);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,13 +20,12 @@
|
||||||
|
|
||||||
#include "fs_close.hpp"
|
#include "fs_close.hpp"
|
||||||
#include "fs_mktemp.hpp"
|
#include "fs_mktemp.hpp"
|
||||||
|
#include "fs_path.hpp"
|
||||||
#include "fs_statvfs.hpp"
|
#include "fs_statvfs.hpp"
|
||||||
#include "fs_unlink.hpp"
|
#include "fs_unlink.hpp"
|
||||||
#include "statvfs_util.hpp"
|
#include "statvfs_util.hpp"
|
||||||
#include "ugid.hpp"
|
#include "ugid.hpp"
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -35,7 +34,7 @@ namespace fs
|
||||||
static
|
static
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
is_mounted_rofs(const std::string path_)
|
is_mounted_rofs(const fs::path &path_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
struct statvfs st;
|
struct statvfs st;
|
||||||
|
|
@ -48,7 +47,7 @@ namespace fs
|
||||||
static
|
static
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
is_rofs(std::string path_)
|
is_rofs(const fs::path &path_)
|
||||||
{
|
{
|
||||||
ugid::SetRootGuard const ugid;
|
ugid::SetRootGuard const ugid;
|
||||||
|
|
||||||
|
|
@ -68,7 +67,7 @@ namespace fs
|
||||||
static
|
static
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
is_rofs_but_not_mounted_ro(const std::string path_)
|
is_rofs_but_not_mounted_ro(const fs::path &path_)
|
||||||
{
|
{
|
||||||
if(fs::is_mounted_rofs(path_))
|
if(fs::is_mounted_rofs(path_))
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,8 @@ namespace fs
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
rv = ::mkdir(path_,mode_);
|
rv = ::mkdir(path_,
|
||||||
|
mode_);
|
||||||
|
|
||||||
return ::to_neg_errno(rv);
|
return ::to_neg_errno(rv);
|
||||||
}
|
}
|
||||||
|
|
@ -49,15 +50,17 @@ namespace fs
|
||||||
mkdir(const std::string &path_,
|
mkdir(const std::string &path_,
|
||||||
const mode_t mode_)
|
const mode_t mode_)
|
||||||
{
|
{
|
||||||
return fs::mkdir(path_.c_str(),mode_);
|
return fs::mkdir(path_.c_str(),
|
||||||
|
mode_);
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
inline
|
inline
|
||||||
int
|
int
|
||||||
mkdir(const fs::Path &path_,
|
mkdir(const fs::path &path_,
|
||||||
const mode_t mode_)
|
const mode_t mode_)
|
||||||
{
|
{
|
||||||
return fs::mkdir(path_.c_str(),mode_);
|
return fs::mkdir(path_.c_str(),
|
||||||
|
mode_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <filesystem>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
|
|
@ -37,45 +38,40 @@
|
||||||
static char const CHARS[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
static char const CHARS[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||||
static size_t const CHARS_SIZE = (sizeof(CHARS) - 1);
|
static size_t const CHARS_SIZE = (sizeof(CHARS) - 1);
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
std::string
|
fs::path
|
||||||
_generate_tmp_path(const std::string &dirpath_,
|
_generate_tmp_path(const fs::path &dirpath_,
|
||||||
const std::string &filename_)
|
const std::string &src_filename_)
|
||||||
{
|
{
|
||||||
long name_max;
|
long name_max;
|
||||||
size_t substr_len;
|
size_t substr_len;
|
||||||
fs::Path path;
|
std::string tmp_filename;
|
||||||
std::string filename;
|
|
||||||
|
|
||||||
name_max = ::pathconf(dirpath_.c_str(),_PC_NAME_MAX);
|
name_max = ::pathconf(dirpath_.c_str(),_PC_NAME_MAX);
|
||||||
if(name_max == -1)
|
if(name_max == -1)
|
||||||
name_max = NAME_MAX;
|
name_max = NAME_MAX;
|
||||||
|
|
||||||
substr_len = std::min(filename_.size(),
|
substr_len = std::min(src_filename_.size(),
|
||||||
(size_t)(name_max - PAD_LEN - 2ULL));
|
(size_t)(name_max - PAD_LEN - 2ULL));
|
||||||
|
|
||||||
filename = '.';
|
tmp_filename = '.';
|
||||||
filename += filename_.substr(0,substr_len);
|
tmp_filename += src_filename_.substr(0,substr_len);
|
||||||
filename += '_';
|
tmp_filename += '_';
|
||||||
for(size_t i = 0; i < PAD_LEN; i++)
|
for(size_t i = 0; i < PAD_LEN; i++)
|
||||||
filename += CHARS[RND::rand64(CHARS_SIZE)];
|
tmp_filename += CHARS[RND::rand64(CHARS_SIZE)];
|
||||||
|
|
||||||
path = dirpath_;
|
return dirpath_ / tmp_filename;
|
||||||
path /= filename;
|
|
||||||
|
|
||||||
return path.string();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<int,std::string>
|
std::tuple<int,fs::path>
|
||||||
fs::mktemp_in_dir(const std::string &dirpath_,
|
fs::mktemp_in_dir(const fs::path &dirpath_,
|
||||||
const std::string &filename_,
|
const fs::path &filename_,
|
||||||
const int flags_)
|
const int flags_)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
int count;
|
int count;
|
||||||
int flags;
|
int flags;
|
||||||
std::string tmp_filepath;
|
fs::path tmp_filepath;
|
||||||
|
|
||||||
count = MAX_ATTEMPTS;
|
count = MAX_ATTEMPTS;
|
||||||
flags = (flags_ | O_EXCL | O_CREAT);
|
flags = (flags_ | O_EXCL | O_CREAT);
|
||||||
|
|
@ -87,21 +83,19 @@ fs::mktemp_in_dir(const std::string &dirpath_,
|
||||||
if(fd == -EEXIST)
|
if(fd == -EEXIST)
|
||||||
continue;
|
continue;
|
||||||
if(fd < 0)
|
if(fd < 0)
|
||||||
return std::make_tuple(fd,std::string());
|
return std::make_tuple(fd,fs::path());
|
||||||
|
|
||||||
return std::make_tuple(fd,tmp_filepath);
|
return std::make_tuple(fd,tmp_filepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::make_tuple(-EEXIST,std::string());
|
return std::make_tuple(-EEXIST,fs::path());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<int,std::string>
|
std::tuple<int,fs::path>
|
||||||
fs::mktemp(const std::string &filepath_,
|
fs::mktemp(const fs::path &filepath_,
|
||||||
const int flags_)
|
const int flags_)
|
||||||
{
|
{
|
||||||
fs::Path filepath{filepath_};
|
return fs::mktemp_in_dir(filepath_.parent_path(),
|
||||||
|
filepath_.filename(),
|
||||||
return fs::mktemp_in_dir(filepath.parent_path(),
|
|
||||||
filepath.filename(),
|
|
||||||
flags_);
|
flags_);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,18 +18,20 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "fs_path.hpp"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
namespace fs
|
namespace fs
|
||||||
{
|
{
|
||||||
|
|
||||||
std::tuple<int,std::string>
|
std::tuple<int,fs::path>
|
||||||
mktemp_in_dir(const std::string &dirpath,
|
mktemp_in_dir(const fs::path &dirpath,
|
||||||
const std::string &filename,
|
const fs::path &filename,
|
||||||
int const flags);
|
int const flags);
|
||||||
|
|
||||||
std::tuple<int,std::string>
|
std::tuple<int,fs::path>
|
||||||
mktemp(const std::string &filepath,
|
mktemp(const fs::path &filepath,
|
||||||
const int flags);
|
const int flags);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ namespace fs
|
||||||
{
|
{
|
||||||
struct Mount
|
struct Mount
|
||||||
{
|
{
|
||||||
fs::Path dir;
|
fs::path dir;
|
||||||
std::string fsname;
|
std::string fsname;
|
||||||
std::string type;
|
std::string type;
|
||||||
std::string opts;
|
std::string opts;
|
||||||
|
|
|
||||||
|
|
@ -62,23 +62,23 @@ static
|
||||||
int
|
int
|
||||||
_movefile_and_open(const Policy::Create &createFunc_,
|
_movefile_and_open(const Policy::Create &createFunc_,
|
||||||
const Branches::Ptr &branches_,
|
const Branches::Ptr &branches_,
|
||||||
const std::string &branchpath_,
|
const fs::path &branchpath_,
|
||||||
const std::string &fusepath_,
|
const fs::path &fusepath_,
|
||||||
int origfd_)
|
int origfd_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
int dstfd_flags;
|
int dstfd_flags;
|
||||||
int origfd_flags;
|
int origfd_flags;
|
||||||
s64 src_size;
|
s64 src_size;
|
||||||
std::string fusedir;
|
fs::path fusedir;
|
||||||
std::string src_branch;
|
fs::path src_branch;
|
||||||
std::string src_filepath;
|
fs::path src_filepath;
|
||||||
std::string dst_filepath;
|
fs::path dst_filepath;
|
||||||
std::vector<Branch*> dst_branch;
|
std::vector<Branch*> dst_branch;
|
||||||
|
|
||||||
src_branch = branchpath_;
|
src_branch = branchpath_;
|
||||||
|
|
||||||
rv = createFunc_(branches_,fusepath_.c_str(),dst_branch);
|
rv = createFunc_(branches_,fusepath_,dst_branch);
|
||||||
if(rv < 0)
|
if(rv < 0)
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
|
|
@ -93,14 +93,14 @@ _movefile_and_open(const Policy::Create &createFunc_,
|
||||||
if(fs::has_space(dst_branch[0]->path,src_size) == false)
|
if(fs::has_space(dst_branch[0]->path,src_size) == false)
|
||||||
return -ENOSPC;
|
return -ENOSPC;
|
||||||
|
|
||||||
fusedir = fs::path::dirname(fusepath_);
|
fusedir = fusepath_.parent_path();
|
||||||
|
|
||||||
rv = fs::clonepath(src_branch,dst_branch[0]->path,fusedir);
|
rv = fs::clonepath(src_branch,dst_branch[0]->path,fusedir);
|
||||||
if(rv < 0)
|
if(rv < 0)
|
||||||
return -ENOSPC;
|
return -ENOSPC;
|
||||||
|
|
||||||
src_filepath = fs::path::make(src_branch,fusepath_);
|
src_filepath = src_branch / fusepath_;
|
||||||
dst_filepath = fs::path::make(dst_branch[0]->path,fusepath_);
|
dst_filepath = dst_branch[0]->path / fusepath_;
|
||||||
|
|
||||||
rv = fs::copyfile(src_filepath,dst_filepath,{.cleanup_failure = true});
|
rv = fs::copyfile(src_filepath,dst_filepath,{.cleanup_failure = true});
|
||||||
if(rv < 0)
|
if(rv < 0)
|
||||||
|
|
@ -119,8 +119,8 @@ _movefile_and_open(const Policy::Create &createFunc_,
|
||||||
int
|
int
|
||||||
fs::movefile_and_open(const Policy::Create &policy_,
|
fs::movefile_and_open(const Policy::Create &policy_,
|
||||||
const Branches::Ptr &branches_,
|
const Branches::Ptr &branches_,
|
||||||
const std::string &branchpath_,
|
const fs::path &branchpath_,
|
||||||
const std::string &fusepath_,
|
const fs::path &fusepath_,
|
||||||
const int origfd_)
|
const int origfd_)
|
||||||
{
|
{
|
||||||
return ::_movefile_and_open(policy_,
|
return ::_movefile_and_open(policy_,
|
||||||
|
|
@ -133,8 +133,8 @@ fs::movefile_and_open(const Policy::Create &policy_,
|
||||||
int
|
int
|
||||||
fs::movefile_and_open_as_root(const Policy::Create &policy_,
|
fs::movefile_and_open_as_root(const Policy::Create &policy_,
|
||||||
const Branches::Ptr &branches_,
|
const Branches::Ptr &branches_,
|
||||||
const std::string &branchpath_,
|
const fs::path &branchpath_,
|
||||||
const std::string &fusepath_,
|
const fs::path &fusepath_,
|
||||||
const int origfd_)
|
const int origfd_)
|
||||||
{
|
{
|
||||||
const ugid::Set ugid(0,0);
|
const ugid::Set ugid(0,0);
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "branches.hpp"
|
#include "branches.hpp"
|
||||||
|
#include "fs_path.hpp"
|
||||||
#include "policy.hpp"
|
#include "policy.hpp"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
@ -27,14 +28,14 @@ namespace fs
|
||||||
int
|
int
|
||||||
movefile_and_open(const Policy::Create &policy,
|
movefile_and_open(const Policy::Create &policy,
|
||||||
const Branches::Ptr &branches_,
|
const Branches::Ptr &branches_,
|
||||||
const std::string &branchpath,
|
const fs::path &branchpath,
|
||||||
const std::string &fusepath,
|
const fs::path &fusepath,
|
||||||
const int origfd);
|
const int origfd);
|
||||||
|
|
||||||
int
|
int
|
||||||
movefile_and_open_as_root(const Policy::Create &policy,
|
movefile_and_open_as_root(const Policy::Create &policy,
|
||||||
const Branches::Ptr &branches_,
|
const Branches::Ptr &branches_,
|
||||||
const std::string &branchpath,
|
const fs::path &branchpath,
|
||||||
const std::string &fusepath,
|
const fs::path &fusepath,
|
||||||
int origfd);
|
int origfd);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,9 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "fs_path.hpp"
|
||||||
#include "to_neg_errno.hpp"
|
#include "to_neg_errno.hpp"
|
||||||
|
|
||||||
#include <filesystem>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
@ -61,10 +61,10 @@ namespace fs
|
||||||
static
|
static
|
||||||
inline
|
inline
|
||||||
int
|
int
|
||||||
openat(const int dirfd_,
|
openat(const int dirfd_,
|
||||||
const std::filesystem::path &pathname_,
|
const fs::path &pathname_,
|
||||||
const int flags_,
|
const int flags_,
|
||||||
const mode_t mode_ = 0)
|
const mode_t mode_ = 0)
|
||||||
{
|
{
|
||||||
return fs::openat(dirfd_,
|
return fs::openat(dirfd_,
|
||||||
pathname_.c_str(),
|
pathname_.c_str(),
|
||||||
|
|
|
||||||
|
|
@ -15,45 +15,3 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "fs_path.hpp"
|
#include "fs_path.hpp"
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
using std::string;
|
|
||||||
|
|
||||||
|
|
||||||
string
|
|
||||||
fs::path::dirname(const char *path_)
|
|
||||||
{
|
|
||||||
string path(path_);
|
|
||||||
|
|
||||||
return fs::path::dirname(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
string
|
|
||||||
fs::path::dirname(const string &path_)
|
|
||||||
{
|
|
||||||
std::size_t i;
|
|
||||||
|
|
||||||
i = path_.size() - 1;
|
|
||||||
while((i > 0) && (path_[i] == '/'))
|
|
||||||
i--;
|
|
||||||
|
|
||||||
while((i > 0) && (path_[i] != '/'))
|
|
||||||
i--;
|
|
||||||
|
|
||||||
while((i > 0) && (path_[i] == '/'))
|
|
||||||
i--;
|
|
||||||
|
|
||||||
return path_.substr(0,i+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
string
|
|
||||||
fs::path::basename(const string &path_)
|
|
||||||
{
|
|
||||||
return path_.substr(path_.find_last_of('/')+1);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -16,74 +16,10 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
|
|
||||||
namespace fs
|
namespace fs
|
||||||
{
|
{
|
||||||
typedef std::filesystem::path Path;
|
using path = std::filesystem::path;
|
||||||
|
|
||||||
namespace path
|
|
||||||
{
|
|
||||||
std::string dirname(const char *path);
|
|
||||||
std::string dirname(const std::string &path);
|
|
||||||
|
|
||||||
std::string basename(const std::string &path);
|
|
||||||
|
|
||||||
static
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
append(std::string &base_,
|
|
||||||
const char *suffix_)
|
|
||||||
{
|
|
||||||
base_ += suffix_;
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
append(std::string &base_,
|
|
||||||
const std::string &suffix_)
|
|
||||||
{
|
|
||||||
base_ += suffix_;
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
inline
|
|
||||||
std::string
|
|
||||||
make(const char *base_,
|
|
||||||
const char *suffix_)
|
|
||||||
{
|
|
||||||
char back;
|
|
||||||
std::string path(base_);
|
|
||||||
|
|
||||||
back = *path.rbegin();
|
|
||||||
if((back != '/') && (suffix_[0] != '/'))
|
|
||||||
path.push_back('/');
|
|
||||||
path += suffix_;
|
|
||||||
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
inline
|
|
||||||
std::string
|
|
||||||
make(const std::string &base_,
|
|
||||||
const char *suffix_)
|
|
||||||
{
|
|
||||||
return (base_ + suffix_);
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
inline
|
|
||||||
std::string
|
|
||||||
make(const std::string &base_,
|
|
||||||
const std::string &suffix_)
|
|
||||||
{
|
|
||||||
return (base_ + suffix_);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "fs_path.hpp"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace fs
|
|
||||||
{
|
|
||||||
typedef std::vector<fs::Path> PathVector;
|
|
||||||
}
|
|
||||||
|
|
@ -30,22 +30,17 @@
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
|
|
||||||
namespace fs
|
|
||||||
{
|
|
||||||
typedef std::set<fs::Path> PathSet;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr std::chrono::milliseconds SLEEP_DURATION = std::chrono::milliseconds(333);
|
constexpr std::chrono::milliseconds SLEEP_DURATION = std::chrono::milliseconds(333);
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
bool
|
bool
|
||||||
_branch_is_mounted(const struct stat &src_st_,
|
_branch_is_mounted(const struct stat &src_st_,
|
||||||
const fs::Path &branch_path_)
|
const fs::path &branch_path_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
fs::Path filepath;
|
fs::path filepath;
|
||||||
|
|
||||||
rv = fs::lgetxattr(branch_path_,"user.mergerfs.branch",NULL,0);
|
rv = fs::lgetxattr(branch_path_,"user.mergerfs.branch",NULL,0);
|
||||||
if(rv >= 0)
|
if(rv >= 0)
|
||||||
|
|
@ -74,13 +69,13 @@ _branch_is_mounted(const struct stat &src_st_,
|
||||||
|
|
||||||
static
|
static
|
||||||
void
|
void
|
||||||
_check_mounted(const struct stat &src_st_,
|
_check_mounted(const struct stat &src_st_,
|
||||||
const fs::PathSet &tgt_paths_,
|
const std::set<fs::path> &tgt_paths_,
|
||||||
fs::PathVector *successes_,
|
std::vector<fs::path> *successes_,
|
||||||
fs::PathVector *failures_)
|
std::vector<fs::path> *failures_)
|
||||||
{
|
{
|
||||||
fs::PathVector &successes = *successes_;
|
std::vector<fs::path> &successes = *successes_;
|
||||||
fs::PathVector &failures = *failures_;
|
std::vector<fs::path> &failures = *failures_;
|
||||||
|
|
||||||
for(auto const &tgt_path : tgt_paths_)
|
for(auto const &tgt_path : tgt_paths_)
|
||||||
{
|
{
|
||||||
|
|
@ -97,13 +92,13 @@ _check_mounted(const struct stat &src_st_,
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_wait_for_mount(const struct stat &src_st_,
|
_wait_for_mount(const struct stat &src_st_,
|
||||||
const fs::PathVector &tgt_paths_,
|
const std::vector<fs::path> &tgt_paths_,
|
||||||
const std::chrono::milliseconds &timeout_)
|
const std::chrono::milliseconds &timeout_)
|
||||||
{
|
{
|
||||||
bool first_loop;
|
bool first_loop;
|
||||||
fs::PathVector successes;
|
std::vector<fs::path> successes;
|
||||||
fs::PathVector failures;
|
std::vector<fs::path> failures;
|
||||||
fs::PathSet tgt_paths;
|
std::set<fs::path> tgt_paths;
|
||||||
std::chrono::time_point<std::chrono::steady_clock> now;
|
std::chrono::time_point<std::chrono::steady_clock> now;
|
||||||
std::chrono::time_point<std::chrono::steady_clock> deadline;
|
std::chrono::time_point<std::chrono::steady_clock> deadline;
|
||||||
|
|
||||||
|
|
@ -146,8 +141,8 @@ _wait_for_mount(const struct stat &src_st_,
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fs::wait_for_mount(const fs::Path &src_path_,
|
fs::wait_for_mount(const fs::path &src_path_,
|
||||||
const fs::PathVector &tgt_paths_,
|
const std::vector<fs::path> &tgt_paths_,
|
||||||
const std::chrono::milliseconds &timeout_)
|
const std::chrono::milliseconds &timeout_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "fs_pathvector.hpp"
|
#include "fs_path.hpp"
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
namespace fs
|
namespace fs
|
||||||
{
|
{
|
||||||
int
|
int
|
||||||
wait_for_mount(const fs::Path &srcpath,
|
wait_for_mount(const fs::path &srcpath,
|
||||||
const fs::PathVector &tgtpaths,
|
const std::vector<fs::path> &tgtpaths,
|
||||||
const std::chrono::milliseconds &timeout);
|
const std::chrono::milliseconds &timeout);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "fuse_access.hpp"
|
||||||
|
|
||||||
#include "config.hpp"
|
#include "config.hpp"
|
||||||
#include "errno.hpp"
|
#include "errno.hpp"
|
||||||
#include "fs_eaccess.hpp"
|
#include "fs_eaccess.hpp"
|
||||||
|
|
@ -23,48 +25,40 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
using std::string;
|
|
||||||
using std::vector;
|
|
||||||
|
|
||||||
|
static
|
||||||
namespace l
|
int
|
||||||
|
_access(const Policy::Search &searchFunc_,
|
||||||
|
const Branches &branches_,
|
||||||
|
const fs::path &fusepath_,
|
||||||
|
const int mask_)
|
||||||
{
|
{
|
||||||
static
|
int rv;
|
||||||
int
|
StrVec basepaths;
|
||||||
access(const Policy::Search &searchFunc_,
|
fs::path fullpath;
|
||||||
const Branches &branches_,
|
std::vector<Branch*> branches;
|
||||||
const char *fusepath_,
|
|
||||||
const int mask_)
|
|
||||||
{
|
|
||||||
int rv;
|
|
||||||
string fullpath;
|
|
||||||
StrVec basepaths;
|
|
||||||
std::vector<Branch*> branches;
|
|
||||||
|
|
||||||
rv = searchFunc_(branches_,fusepath_,branches);
|
|
||||||
if(rv < 0)
|
|
||||||
return rv;
|
|
||||||
|
|
||||||
fullpath = fs::path::make(branches[0]->path,fusepath_);
|
|
||||||
|
|
||||||
rv = fs::eaccess(fullpath,mask_);
|
|
||||||
|
|
||||||
|
rv = searchFunc_(branches_,fusepath_,branches);
|
||||||
|
if(rv < 0)
|
||||||
return rv;
|
return rv;
|
||||||
}
|
|
||||||
|
fullpath = branches[0]->path / fusepath_;
|
||||||
|
|
||||||
|
rv = fs::eaccess(fullpath,mask_);
|
||||||
|
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace FUSE
|
int
|
||||||
|
FUSE::access(const char *fusepath_,
|
||||||
|
int mask_)
|
||||||
{
|
{
|
||||||
int
|
const fs::path fusepath{fusepath_};
|
||||||
access(const char *fusepath_,
|
const fuse_context *fc = fuse_get_context();
|
||||||
int mask_)
|
const ugid::Set ugid(fc->uid,fc->gid);
|
||||||
{
|
|
||||||
const fuse_context *fc = fuse_get_context();
|
|
||||||
const ugid::Set ugid(fc->uid,fc->gid);
|
|
||||||
|
|
||||||
return l::access(cfg.func.access.policy,
|
return ::_access(cfg.func.access.policy,
|
||||||
cfg.branches,
|
cfg.branches,
|
||||||
fusepath_,
|
fusepath,
|
||||||
mask_);
|
mask_);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "fuse_bmap.hpp"
|
||||||
|
|
||||||
#include "errno.hpp"
|
#include "errno.hpp"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
@ -23,17 +25,14 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
|
||||||
namespace FUSE
|
int
|
||||||
|
FUSE::bmap(const char *fusepath_,
|
||||||
|
size_t blocksize_,
|
||||||
|
uint64_t *idx_)
|
||||||
{
|
{
|
||||||
int
|
(void)fusepath_;
|
||||||
bmap(const char *fusepath_,
|
(void)blocksize_;
|
||||||
size_t blocksize_,
|
(void)idx_;
|
||||||
uint64_t *idx_)
|
|
||||||
{
|
|
||||||
(void)fusepath_;
|
|
||||||
(void)blocksize_;
|
|
||||||
(void)idx_;
|
|
||||||
|
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "fuse_chmod.hpp"
|
||||||
|
|
||||||
#include "config.hpp"
|
#include "config.hpp"
|
||||||
#include "errno.hpp"
|
#include "errno.hpp"
|
||||||
#include "fs_lchmod.hpp"
|
#include "fs_lchmod.hpp"
|
||||||
|
|
@ -23,96 +25,90 @@
|
||||||
|
|
||||||
#include "fuse.h"
|
#include "fuse.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
|
static
|
||||||
namespace l
|
void
|
||||||
|
_chmod_loop_core(const std::string &basepath_,
|
||||||
|
const fs::path &fusepath_,
|
||||||
|
const mode_t mode_,
|
||||||
|
PolicyRV *prv_)
|
||||||
{
|
{
|
||||||
static
|
fs::path fullpath;
|
||||||
void
|
|
||||||
chmod_loop_core(const std::string &basepath_,
|
|
||||||
const char *fusepath_,
|
|
||||||
const mode_t mode_,
|
|
||||||
PolicyRV *prv_)
|
|
||||||
{
|
|
||||||
std::string fullpath;
|
|
||||||
|
|
||||||
fullpath = fs::path::make(basepath_,fusepath_);
|
fullpath = basepath_ / fusepath_;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
fs::lchmod(fullpath,mode_);
|
fs::lchmod(fullpath,mode_);
|
||||||
|
|
||||||
prv_->insert(errno,basepath_);
|
prv_->insert(errno,basepath_);
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void
|
void
|
||||||
chmod_loop(const std::vector<Branch*> &branches_,
|
_chmod_loop(const std::vector<Branch*> &branches_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
const mode_t mode_,
|
const mode_t mode_,
|
||||||
PolicyRV *prv_)
|
PolicyRV *prv_)
|
||||||
{
|
{
|
||||||
for(auto &branch : branches_)
|
for(auto &branch : branches_)
|
||||||
{
|
{
|
||||||
l::chmod_loop_core(branch->path,fusepath_,mode_,prv_);
|
::_chmod_loop_core(branch->path,fusepath_,mode_,prv_);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
int
|
|
||||||
chmod(const Policy::Action &actionFunc_,
|
|
||||||
const Policy::Search &searchFunc_,
|
|
||||||
const Branches &branches_,
|
|
||||||
const char *fusepath_,
|
|
||||||
const mode_t mode_)
|
|
||||||
{
|
|
||||||
int rv;
|
|
||||||
PolicyRV prv;
|
|
||||||
std::vector<Branch*> branches;
|
|
||||||
|
|
||||||
rv = actionFunc_(branches_,fusepath_,branches);
|
|
||||||
if(rv < 0)
|
|
||||||
return rv;
|
|
||||||
|
|
||||||
l::chmod_loop(branches,fusepath_,mode_,&prv);
|
|
||||||
if(prv.errors.empty())
|
|
||||||
return 0;
|
|
||||||
if(prv.successes.empty())
|
|
||||||
return prv.errors[0].rv;
|
|
||||||
|
|
||||||
branches.clear();
|
|
||||||
rv = searchFunc_(branches_,fusepath_,branches);
|
|
||||||
if(rv < 0)
|
|
||||||
return rv;
|
|
||||||
|
|
||||||
return prv.get_error(branches[0]->path);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_chmod(const char *fusepath_,
|
_chmod(const Policy::Action &actionFunc_,
|
||||||
const mode_t mode_)
|
const Policy::Search &searchFunc_,
|
||||||
|
const Branches &branches_,
|
||||||
|
const fs::path &fusepath_,
|
||||||
|
const mode_t mode_)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
PolicyRV prv;
|
||||||
|
std::vector<Branch*> branches;
|
||||||
|
|
||||||
|
rv = actionFunc_(branches_,fusepath_,branches);
|
||||||
|
if(rv < 0)
|
||||||
|
return rv;
|
||||||
|
|
||||||
|
::_chmod_loop(branches,fusepath_,mode_,&prv);
|
||||||
|
if(prv.errors.empty())
|
||||||
|
return 0;
|
||||||
|
if(prv.successes.empty())
|
||||||
|
return prv.errors[0].rv;
|
||||||
|
|
||||||
|
branches.clear();
|
||||||
|
rv = searchFunc_(branches_,fusepath_,branches);
|
||||||
|
if(rv < 0)
|
||||||
|
return rv;
|
||||||
|
|
||||||
|
return prv.get_error(branches[0]->path);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int
|
||||||
|
_chmod(const fs::path &fusepath_,
|
||||||
|
const mode_t mode_)
|
||||||
{
|
{
|
||||||
const fuse_context *fc = fuse_get_context();
|
const fuse_context *fc = fuse_get_context();
|
||||||
const ugid::Set ugid(fc->uid,fc->gid);
|
const ugid::Set ugid(fc->uid,fc->gid);
|
||||||
|
|
||||||
return l::chmod(cfg.func.chmod.policy,
|
return ::_chmod(cfg.func.chmod.policy,
|
||||||
cfg.func.getattr.policy,
|
cfg.func.getattr.policy,
|
||||||
cfg.branches,
|
cfg.branches,
|
||||||
fusepath_,
|
fusepath_,
|
||||||
mode_);
|
mode_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
namespace FUSE
|
FUSE::chmod(const char *fusepath_,
|
||||||
|
mode_t mode_)
|
||||||
{
|
{
|
||||||
int
|
const fs::path fusepath{fusepath_};
|
||||||
chmod(const char *fusepath_,
|
|
||||||
mode_t mode_)
|
return ::_chmod(fusepath,mode_);
|
||||||
{
|
|
||||||
return ::_chmod(fusepath_,mode_);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
|
||||||
namespace FUSE
|
namespace FUSE
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "fuse_chown.hpp"
|
||||||
|
|
||||||
#include "config.hpp"
|
#include "config.hpp"
|
||||||
#include "errno.hpp"
|
#include "errno.hpp"
|
||||||
#include "fs_lchown.hpp"
|
#include "fs_lchown.hpp"
|
||||||
|
|
@ -27,87 +29,83 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
namespace l
|
static
|
||||||
|
void
|
||||||
|
_chown_loop_core(const fs::path &basepath_,
|
||||||
|
const fs::path &fusepath_,
|
||||||
|
const uid_t uid_,
|
||||||
|
const gid_t gid_,
|
||||||
|
PolicyRV *prv_)
|
||||||
{
|
{
|
||||||
static
|
fs::path fullpath;
|
||||||
void
|
|
||||||
chown_loop_core(const std::string &basepath_,
|
|
||||||
const char *fusepath_,
|
|
||||||
const uid_t uid_,
|
|
||||||
const gid_t gid_,
|
|
||||||
PolicyRV *prv_)
|
|
||||||
{
|
|
||||||
std::string fullpath;
|
|
||||||
|
|
||||||
fullpath = fs::path::make(basepath_,fusepath_);
|
fullpath = basepath_ / fusepath_;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
fs::lchown(fullpath,uid_,gid_);
|
fs::lchown(fullpath,uid_,gid_);
|
||||||
|
|
||||||
prv_->insert(errno,basepath_);
|
prv_->insert(errno,basepath_);
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
void
|
|
||||||
chown_loop(const std::vector<Branch*> &branches_,
|
|
||||||
const char *fusepath_,
|
|
||||||
const uid_t uid_,
|
|
||||||
const gid_t gid_,
|
|
||||||
PolicyRV *prv_)
|
|
||||||
{
|
|
||||||
for(auto &branch : branches_)
|
|
||||||
{
|
|
||||||
l::chown_loop_core(branch->path,fusepath_,uid_,gid_,prv_);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
int
|
|
||||||
chown(const Policy::Action &actionFunc_,
|
|
||||||
const Policy::Search &searchFunc_,
|
|
||||||
const Branches &branches_,
|
|
||||||
const char *fusepath_,
|
|
||||||
const uid_t uid_,
|
|
||||||
const gid_t gid_)
|
|
||||||
{
|
|
||||||
int rv;
|
|
||||||
PolicyRV prv;
|
|
||||||
std::vector<Branch*> branches;
|
|
||||||
|
|
||||||
rv = actionFunc_(branches_,fusepath_,branches);
|
|
||||||
if(rv < 0)
|
|
||||||
return rv;
|
|
||||||
|
|
||||||
l::chown_loop(branches,fusepath_,uid_,gid_,&prv);
|
|
||||||
if(prv.errors.empty())
|
|
||||||
return 0;
|
|
||||||
if(prv.successes.empty())
|
|
||||||
return prv.errors[0].rv;
|
|
||||||
|
|
||||||
branches.clear();
|
|
||||||
rv = searchFunc_(branches_,fusepath_,branches);
|
|
||||||
if(rv < 0)
|
|
||||||
return rv;
|
|
||||||
|
|
||||||
return prv.get_error(branches[0]->path);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace FUSE
|
static
|
||||||
|
void
|
||||||
|
_chown_loop(const std::vector<Branch*> &branches_,
|
||||||
|
const fs::path &fusepath_,
|
||||||
|
const uid_t uid_,
|
||||||
|
const gid_t gid_,
|
||||||
|
PolicyRV *prv_)
|
||||||
{
|
{
|
||||||
int
|
for(const auto &branch : branches_)
|
||||||
chown(const char *fusepath_,
|
{
|
||||||
uid_t uid_,
|
::_chown_loop_core(branch->path,fusepath_,uid_,gid_,prv_);
|
||||||
gid_t gid_)
|
}
|
||||||
{
|
}
|
||||||
const fuse_context *fc = fuse_get_context();
|
|
||||||
const ugid::Set ugid(fc->uid,fc->gid);
|
static
|
||||||
|
int
|
||||||
return l::chown(cfg.func.chown.policy,
|
_chown(const Policy::Action &actionFunc_,
|
||||||
cfg.func.getattr.policy,
|
const Policy::Search &searchFunc_,
|
||||||
cfg.branches,
|
const Branches &branches_,
|
||||||
fusepath_,
|
const fs::path &fusepath_,
|
||||||
uid_,
|
const uid_t uid_,
|
||||||
gid_);
|
const gid_t gid_)
|
||||||
}
|
{
|
||||||
|
int rv;
|
||||||
|
PolicyRV prv;
|
||||||
|
std::vector<Branch*> branches;
|
||||||
|
|
||||||
|
rv = actionFunc_(branches_,fusepath_,branches);
|
||||||
|
if(rv < 0)
|
||||||
|
return rv;
|
||||||
|
|
||||||
|
::_chown_loop(branches,fusepath_,uid_,gid_,&prv);
|
||||||
|
|
||||||
|
if(prv.errors.empty())
|
||||||
|
return 0;
|
||||||
|
if(prv.successes.empty())
|
||||||
|
return prv.errors[0].rv;
|
||||||
|
|
||||||
|
branches.clear();
|
||||||
|
rv = searchFunc_(branches_,fusepath_,branches);
|
||||||
|
if(rv < 0)
|
||||||
|
return rv;
|
||||||
|
|
||||||
|
return prv.get_error(branches[0]->path);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
FUSE::chown(const char *fusepath_,
|
||||||
|
uid_t uid_,
|
||||||
|
gid_t gid_)
|
||||||
|
{
|
||||||
|
const fs::path fusepath{fusepath_};
|
||||||
|
const fuse_context *fc = fuse_get_context();
|
||||||
|
const ugid::Set ugid(fc->uid,fc->gid);
|
||||||
|
|
||||||
|
return ::_chown(cfg.func.chown.policy,
|
||||||
|
cfg.func.getattr.policy,
|
||||||
|
cfg.branches,
|
||||||
|
fusepath,
|
||||||
|
uid_,
|
||||||
|
gid_);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
namespace FUSE
|
namespace FUSE
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "fuse_copy_file_range.hpp"
|
||||||
|
|
||||||
#include "errno.hpp"
|
#include "errno.hpp"
|
||||||
#include "fileinfo.hpp"
|
#include "fileinfo.hpp"
|
||||||
#include "fs_copy_file_range.hpp"
|
#include "fs_copy_file_range.hpp"
|
||||||
|
|
@ -23,48 +25,42 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
namespace l
|
static
|
||||||
|
ssize_t
|
||||||
|
_copy_file_range(const int fd_in_,
|
||||||
|
off_t offset_in_,
|
||||||
|
const int fd_out_,
|
||||||
|
off_t offset_out_,
|
||||||
|
size_t size_,
|
||||||
|
int flags_)
|
||||||
{
|
{
|
||||||
static
|
ssize_t rv;
|
||||||
ssize_t
|
|
||||||
copy_file_range(const int fd_in_,
|
|
||||||
off_t offset_in_,
|
|
||||||
const int fd_out_,
|
|
||||||
off_t offset_out_,
|
|
||||||
size_t size_,
|
|
||||||
int flags_)
|
|
||||||
{
|
|
||||||
ssize_t rv;
|
|
||||||
|
|
||||||
rv = fs::copy_file_range(fd_in_,
|
rv = fs::copy_file_range(fd_in_,
|
||||||
&offset_in_,
|
&offset_in_,
|
||||||
fd_out_,
|
fd_out_,
|
||||||
&offset_out_,
|
&offset_out_,
|
||||||
size_,
|
size_,
|
||||||
flags_);
|
flags_);
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace FUSE
|
ssize_t
|
||||||
|
FUSE::copy_file_range(const fuse_file_info_t *ffi_in_,
|
||||||
|
off_t offset_in_,
|
||||||
|
const fuse_file_info_t *ffi_out_,
|
||||||
|
off_t offset_out_,
|
||||||
|
size_t size_,
|
||||||
|
int flags_)
|
||||||
{
|
{
|
||||||
ssize_t
|
FileInfo *fi_in = FileInfo::from_fh(ffi_in_->fh);
|
||||||
copy_file_range(const fuse_file_info_t *ffi_in_,
|
FileInfo *fi_out = FileInfo::from_fh(ffi_out_->fh);
|
||||||
off_t offset_in_,
|
|
||||||
const fuse_file_info_t *ffi_out_,
|
|
||||||
off_t offset_out_,
|
|
||||||
size_t size_,
|
|
||||||
int flags_)
|
|
||||||
{
|
|
||||||
FileInfo *fi_in = reinterpret_cast<FileInfo*>(ffi_in_->fh);
|
|
||||||
FileInfo *fi_out = reinterpret_cast<FileInfo*>(ffi_out_->fh);
|
|
||||||
|
|
||||||
return l::copy_file_range(fi_in->fd,
|
return ::_copy_file_range(fi_in->fd,
|
||||||
offset_in_,
|
offset_in_,
|
||||||
fi_out->fd,
|
fi_out->fd,
|
||||||
offset_out_,
|
offset_out_,
|
||||||
size_,
|
size_,
|
||||||
flags_);
|
flags_);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,18 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "fuse.h"
|
||||||
|
|
||||||
|
#ifndef _GNU_SOURCE
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#endif
|
||||||
|
#ifndef _FILE_OFFSET_BITS
|
||||||
|
#define _FILE_OFFSET_BITS 64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "fuse.h"
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
namespace FUSE
|
namespace FUSE
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,11 @@
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "state.hpp"
|
#include "fuse_create.hpp"
|
||||||
|
|
||||||
|
#include "state.hpp"
|
||||||
#include "config.hpp"
|
#include "config.hpp"
|
||||||
|
|
||||||
#include "errno.hpp"
|
#include "errno.hpp"
|
||||||
#include "fileinfo.hpp"
|
#include "fileinfo.hpp"
|
||||||
#include "fs_acl.hpp"
|
#include "fs_acl.hpp"
|
||||||
|
|
@ -25,6 +27,7 @@
|
||||||
#include "fs_path.hpp"
|
#include "fs_path.hpp"
|
||||||
#include "fuse_passthrough.hpp"
|
#include "fuse_passthrough.hpp"
|
||||||
#include "procfs.hpp"
|
#include "procfs.hpp"
|
||||||
|
#include "syslog.hpp"
|
||||||
#include "ugid.hpp"
|
#include "ugid.hpp"
|
||||||
|
|
||||||
#include "fuse.h"
|
#include "fuse.h"
|
||||||
|
|
@ -32,7 +35,6 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The kernel expects being able to issue read requests when running
|
The kernel expects being able to issue read requests when running
|
||||||
with writeback caching enabled so we must change O_WRONLY to
|
with writeback caching enabled so we must change O_WRONLY to
|
||||||
|
|
@ -135,10 +137,10 @@ _config_to_ffi_flags(Config &cfg_,
|
||||||
|
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_create_core(const std::string &fullpath_,
|
_create_core(const fs::path &fullpath_,
|
||||||
mode_t mode_,
|
mode_t mode_,
|
||||||
const mode_t umask_,
|
const mode_t umask_,
|
||||||
const int flags_)
|
const int flags_)
|
||||||
{
|
{
|
||||||
if(!fs::acl::dir_has_defaults(fullpath_))
|
if(!fs::acl::dir_has_defaults(fullpath_))
|
||||||
mode_ &= ~umask_;
|
mode_ &= ~umask_;
|
||||||
|
|
@ -149,24 +151,24 @@ _create_core(const std::string &fullpath_,
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_create_core(const Branch *branch_,
|
_create_core(const Branch *branch_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
fuse_file_info_t *ffi_,
|
fuse_file_info_t *ffi_,
|
||||||
const mode_t mode_,
|
const mode_t mode_,
|
||||||
const mode_t umask_)
|
const mode_t umask_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
FileInfo *fi;
|
FileInfo *fi;
|
||||||
std::string fullpath;
|
fs::path fullpath;
|
||||||
|
|
||||||
fullpath = fs::path::make(branch_->path,fusepath_);
|
fullpath = branch_->path / fusepath_;
|
||||||
|
|
||||||
rv = ::_create_core(fullpath,mode_,umask_,ffi_->flags);
|
rv = ::_create_core(fullpath,mode_,umask_,ffi_->flags);
|
||||||
if(rv < 0)
|
if(rv < 0)
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
fi = new FileInfo(rv,branch_,fusepath_,ffi_->direct_io);
|
fi = new FileInfo(rv,*branch_,fusepath_,ffi_->direct_io);
|
||||||
|
|
||||||
ffi_->fh = reinterpret_cast<uint64_t>(fi);
|
ffi_->fh = fi->to_fh();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -176,18 +178,18 @@ int
|
||||||
_create(const Policy::Search &searchFunc_,
|
_create(const Policy::Search &searchFunc_,
|
||||||
const Policy::Create &createFunc_,
|
const Policy::Create &createFunc_,
|
||||||
const Branches &branches_,
|
const Branches &branches_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
fuse_file_info_t *ffi_,
|
fuse_file_info_t *ffi_,
|
||||||
const mode_t mode_,
|
const mode_t mode_,
|
||||||
const mode_t umask_)
|
const mode_t umask_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
std::string fullpath;
|
fs::path fullpath;
|
||||||
std::string fusedirpath;
|
fs::path fusedirpath;
|
||||||
std::vector<Branch*> createpaths;
|
std::vector<Branch*> createpaths;
|
||||||
std::vector<Branch*> existingpaths;
|
std::vector<Branch*> existingpaths;
|
||||||
|
|
||||||
fusedirpath = fs::path::dirname(fusepath_);
|
fusedirpath = fusepath_.parent_path();
|
||||||
|
|
||||||
rv = searchFunc_(branches_,fusedirpath,existingpaths);
|
rv = searchFunc_(branches_,fusedirpath,existingpaths);
|
||||||
if(rv < 0)
|
if(rv < 0)
|
||||||
|
|
@ -222,7 +224,7 @@ _(const PassthroughEnum e_,
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_create_for_insert_lambda(const fuse_context *fc_,
|
_create_for_insert_lambda(const fuse_context *fc_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
const mode_t mode_,
|
const mode_t mode_,
|
||||||
fuse_file_info_t *ffi_,
|
fuse_file_info_t *ffi_,
|
||||||
State::OpenFile *of_)
|
State::OpenFile *of_)
|
||||||
|
|
@ -259,7 +261,7 @@ _create_for_insert_lambda(const fuse_context *fc_,
|
||||||
if(rv < 0)
|
if(rv < 0)
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
fi = reinterpret_cast<FileInfo*>(ffi_->fh);
|
fi = FileInfo::from_fh(ffi_->fh);
|
||||||
|
|
||||||
of_->ref_count = 1;
|
of_->ref_count = 1;
|
||||||
of_->fi = fi;
|
of_->fi = fi;
|
||||||
|
|
@ -289,10 +291,9 @@ _create_for_insert_lambda(const fuse_context *fc_,
|
||||||
|
|
||||||
static
|
static
|
||||||
inline
|
inline
|
||||||
constexpr
|
|
||||||
auto
|
auto
|
||||||
_create_insert_lambda(const fuse_context *fc_,
|
_create_insert_lambda(const fuse_context *fc_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
const mode_t mode_,
|
const mode_t mode_,
|
||||||
fuse_file_info_t *ffi_,
|
fuse_file_info_t *ffi_,
|
||||||
int *_rv_)
|
int *_rv_)
|
||||||
|
|
@ -311,14 +312,14 @@ _create_insert_lambda(const fuse_context *fc_,
|
||||||
// This function should never be called?
|
// This function should never be called?
|
||||||
static
|
static
|
||||||
inline
|
inline
|
||||||
constexpr
|
|
||||||
auto
|
auto
|
||||||
_create_update_lambda()
|
_create_update_lambda()
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
[=](auto &val_)
|
[](const auto &val_)
|
||||||
{
|
{
|
||||||
fmt::println(stderr,"THIS SHOULD NOT HAPPEN");
|
fmt::println(stderr,"CREATE_UPDATE_LAMBDA: THIS SHOULD NOT HAPPEN");
|
||||||
|
SysLog::crit("CREATE_UPDATE_LAMBDA: THIS SHOULD NOT HAPPEN");
|
||||||
abort();
|
abort();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -326,7 +327,7 @@ _create_update_lambda()
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_create(const fuse_context *fc_,
|
_create(const fuse_context *fc_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
mode_t mode_,
|
mode_t mode_,
|
||||||
fuse_file_info_t *ffi_)
|
fuse_file_info_t *ffi_)
|
||||||
{
|
{
|
||||||
|
|
@ -343,7 +344,7 @@ _create(const fuse_context *fc_,
|
||||||
// ref_count is default (0).
|
// ref_count is default (0).
|
||||||
if(rv < 0)
|
if(rv < 0)
|
||||||
of.erase_if(fc_->nodeid,
|
of.erase_if(fc_->nodeid,
|
||||||
[](auto &val_)
|
[](const auto &val_)
|
||||||
{
|
{
|
||||||
return (val_.second.ref_count <= 0);
|
return (val_.second.ref_count <= 0);
|
||||||
});
|
});
|
||||||
|
|
@ -351,15 +352,13 @@ _create(const fuse_context *fc_,
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace FUSE
|
int
|
||||||
|
FUSE::create(const char *fusepath_,
|
||||||
|
mode_t mode_,
|
||||||
|
fuse_file_info_t *ffi_)
|
||||||
{
|
{
|
||||||
int
|
const fs::path fusepath{fusepath_};
|
||||||
create(const char *fusepath_,
|
const fuse_context *fc = fuse_get_context();
|
||||||
mode_t mode_,
|
|
||||||
fuse_file_info_t *ffi_)
|
|
||||||
{
|
|
||||||
const fuse_context *fc = fuse_get_context();
|
|
||||||
|
|
||||||
return ::_create(fc,fusepath_,mode_,ffi_);
|
return ::_create(fc,fusepath,mode_,ffi_);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,10 @@
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace FUSE
|
#include "fuse_destroy.hpp"
|
||||||
{
|
|
||||||
void
|
void
|
||||||
destroy(void)
|
FUSE::destroy(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
#include "fuse_fallocate.hpp"
|
#include "fuse_fallocate.hpp"
|
||||||
|
|
||||||
|
#include "state.hpp"
|
||||||
|
|
||||||
#include "errno.hpp"
|
#include "errno.hpp"
|
||||||
#include "fileinfo.hpp"
|
#include "fileinfo.hpp"
|
||||||
#include "fs_fallocate.hpp"
|
#include "fs_fallocate.hpp"
|
||||||
|
|
@ -43,7 +45,23 @@ FUSE::fallocate(const uint64_t fh_,
|
||||||
off_t offset_,
|
off_t offset_,
|
||||||
off_t len_)
|
off_t len_)
|
||||||
{
|
{
|
||||||
FileInfo *fi = reinterpret_cast<FileInfo*>(fh_);
|
uint64_t fh;
|
||||||
|
const fuse_context *fc = fuse_get_context();
|
||||||
|
|
||||||
|
fh = fh_;
|
||||||
|
if(fh == 0)
|
||||||
|
{
|
||||||
|
state.open_files.cvisit(fc->nodeid,
|
||||||
|
[&](auto &val_)
|
||||||
|
{
|
||||||
|
fh = val_.second.fi->to_fh();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fh == 0)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
FileInfo *fi = FileInfo::from_fh(fh);
|
||||||
|
|
||||||
return ::_fallocate(fi->fd,
|
return ::_fallocate(fi->fd,
|
||||||
mode_,
|
mode_,
|
||||||
|
|
|
||||||
|
|
@ -49,14 +49,14 @@ FUSE::fchmod(const uint64_t fh_,
|
||||||
state.open_files.cvisit(fc->nodeid,
|
state.open_files.cvisit(fc->nodeid,
|
||||||
[&](auto &val_)
|
[&](auto &val_)
|
||||||
{
|
{
|
||||||
fh = reinterpret_cast<uint64_t>(val_.second.fi);
|
fh = val_.second.fi->to_fh();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fh == 0)
|
if(fh == 0)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
FileInfo *fi = reinterpret_cast<FileInfo*>(fh);
|
FileInfo *fi = FileInfo::from_fh(fh);
|
||||||
|
|
||||||
return ::_fchmod(fi->fd,mode_);
|
return ::_fchmod(fi->fd,mode_);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,14 +53,14 @@ FUSE::fchown(const uint64_t fh_,
|
||||||
state.open_files.cvisit(fc->nodeid,
|
state.open_files.cvisit(fc->nodeid,
|
||||||
[&](auto &val_)
|
[&](auto &val_)
|
||||||
{
|
{
|
||||||
fh = reinterpret_cast<uint64_t>(val_.second.fi);
|
fh = val_.second.fi->to_fh();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fh == 0)
|
if(fh == 0)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
FileInfo *fi = reinterpret_cast<FileInfo*>(fh);
|
FileInfo *fi = FileInfo::from_fh(fh);
|
||||||
|
|
||||||
return ::_fchown(fi->fd,uid_,gid_);
|
return ::_fchown(fi->fd,uid_,gid_);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ FUSE::fgetattr(const uint64_t fh_,
|
||||||
state.open_files.cvisit(fc->nodeid,
|
state.open_files.cvisit(fc->nodeid,
|
||||||
[&](const auto &val_)
|
[&](const auto &val_)
|
||||||
{
|
{
|
||||||
fh = reinterpret_cast<uint64_t>(val_.second.fi);
|
fh = val_.second.fi->to_fh();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -70,7 +70,7 @@ FUSE::fgetattr(const uint64_t fh_,
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileInfo *fi = reinterpret_cast<FileInfo*>(fh);
|
FileInfo *fi = FileInfo::from_fh(fh);
|
||||||
|
|
||||||
rv = ::_fgetattr(fi,st_);
|
rv = ::_fgetattr(fi,st_);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
#include "errno.hpp"
|
#include "errno.hpp"
|
||||||
#include "fileinfo.hpp"
|
#include "fileinfo.hpp"
|
||||||
#include "fs_flock.hpp"
|
#include "fs_flock.hpp"
|
||||||
|
#include "state.hpp"
|
||||||
|
|
||||||
#include "fuse.h"
|
#include "fuse.h"
|
||||||
|
|
||||||
|
|
@ -39,7 +40,23 @@ int
|
||||||
FUSE::flock(const fuse_file_info_t *ffi_,
|
FUSE::flock(const fuse_file_info_t *ffi_,
|
||||||
int op_)
|
int op_)
|
||||||
{
|
{
|
||||||
FileInfo* fi = reinterpret_cast<FileInfo*>(ffi_->fh);
|
uint64_t fh;
|
||||||
|
const fuse_context *fc = fuse_get_context();
|
||||||
|
|
||||||
|
fh = ffi_->fh;
|
||||||
|
if(fh == 0)
|
||||||
|
{
|
||||||
|
state.open_files.cvisit(fc->nodeid,
|
||||||
|
[&](const auto &val_)
|
||||||
|
{
|
||||||
|
fh = val_.second.fi->to_fh();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fh == 0)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
FileInfo* fi = FileInfo::from_fh(fh);
|
||||||
|
|
||||||
return ::_flock(fi->fd,op_);
|
return ::_flock(fi->fd,op_);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ _flush(const int fd_)
|
||||||
int
|
int
|
||||||
FUSE::flush(const fuse_file_info_t *ffi_)
|
FUSE::flush(const fuse_file_info_t *ffi_)
|
||||||
{
|
{
|
||||||
FileInfo *fi = reinterpret_cast<FileInfo*>(ffi_->fh);
|
FileInfo *fi = FileInfo::from_fh(ffi_->fh);
|
||||||
|
|
||||||
return ::_flush(fi->fd);
|
return ::_flush(fi->fd);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ int
|
||||||
FUSE::fsync(const uint64_t fh_,
|
FUSE::fsync(const uint64_t fh_,
|
||||||
int isdatasync_)
|
int isdatasync_)
|
||||||
{
|
{
|
||||||
FileInfo *fi = reinterpret_cast<FileInfo*>(fh_);
|
FileInfo *fi = FileInfo::from_fh(fh_);
|
||||||
|
|
||||||
return ::_fsync(fi->fd,isdatasync_);
|
return ::_fsync(fi->fd,isdatasync_);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ int
|
||||||
FUSE::fsyncdir(const fuse_file_info_t *ffi_,
|
FUSE::fsyncdir(const fuse_file_info_t *ffi_,
|
||||||
int isdatasync_)
|
int isdatasync_)
|
||||||
{
|
{
|
||||||
DirInfo *di = reinterpret_cast<DirInfo*>(ffi_->fh);
|
DirInfo *di = DirInfo::from_fh(ffi_->fh);
|
||||||
|
|
||||||
return ::_fsyncdir(di,isdatasync_);
|
return ::_fsyncdir(di,isdatasync_);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,11 +49,11 @@ FUSE::ftruncate(const uint64_t fh_,
|
||||||
state.open_files.cvisit(fc->nodeid,
|
state.open_files.cvisit(fc->nodeid,
|
||||||
[&](auto &val_)
|
[&](auto &val_)
|
||||||
{
|
{
|
||||||
fh = reinterpret_cast<uint64_t>(val_.second.fi);
|
fh = val_.second.fi->to_fh();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
FileInfo *fi = reinterpret_cast<FileInfo*>(fh);
|
FileInfo *fi = FileInfo::from_fh(fh);
|
||||||
|
|
||||||
return ::_ftruncate(fi->fd,size_);
|
return ::_ftruncate(fi->fd,size_);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -51,11 +51,11 @@ FUSE::futimens(const uint64_t fh_,
|
||||||
state.open_files.cvisit(fc->nodeid,
|
state.open_files.cvisit(fc->nodeid,
|
||||||
[&](const auto &val_)
|
[&](const auto &val_)
|
||||||
{
|
{
|
||||||
fh = reinterpret_cast<uint64_t>(val_.second.fi);
|
fh = val_.second.fi->to_fh();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
FileInfo *fi = reinterpret_cast<FileInfo*>(fh);
|
FileInfo *fi = FileInfo::from_fh(fh);
|
||||||
|
|
||||||
return ::_futimens(fi->fd,ts_);
|
return ::_futimens(fi->fd,ts_);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,13 +33,11 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
using std::string;
|
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
void
|
void
|
||||||
_set_stat_if_leads_to_dir(const std::string &path_,
|
_set_stat_if_leads_to_dir(const fs::path &path_,
|
||||||
struct stat *st_)
|
struct stat *st_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
@ -56,8 +54,8 @@ _set_stat_if_leads_to_dir(const std::string &path_,
|
||||||
|
|
||||||
static
|
static
|
||||||
void
|
void
|
||||||
_set_stat_if_leads_to_reg(const std::string &path_,
|
_set_stat_if_leads_to_reg(const fs::path &path_,
|
||||||
struct stat *st_)
|
struct stat *st_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
@ -122,21 +120,21 @@ static
|
||||||
int
|
int
|
||||||
_getattr(const Policy::Search &searchFunc_,
|
_getattr(const Policy::Search &searchFunc_,
|
||||||
const Branches &branches_,
|
const Branches &branches_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
struct stat *st_,
|
struct stat *st_,
|
||||||
const bool symlinkify_,
|
const bool symlinkify_,
|
||||||
const time_t symlinkify_timeout_,
|
const time_t symlinkify_timeout_,
|
||||||
FollowSymlinks followsymlinks_)
|
FollowSymlinks followsymlinks_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
string fullpath;
|
fs::path fullpath;
|
||||||
std::vector<Branch*> branches;
|
std::vector<Branch*> branches;
|
||||||
|
|
||||||
rv = searchFunc_(branches_,fusepath_,branches);
|
rv = searchFunc_(branches_,fusepath_,branches);
|
||||||
if(rv < 0)
|
if(rv < 0)
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
fullpath = fs::path::make(branches[0]->path,fusepath_);
|
fullpath = branches[0]->path / fusepath_;
|
||||||
|
|
||||||
switch(followsymlinks_)
|
switch(followsymlinks_)
|
||||||
{
|
{
|
||||||
|
|
@ -166,13 +164,15 @@ _getattr(const Policy::Search &searchFunc_,
|
||||||
if(symlinkify_ && symlinkify::can_be_symlink(*st_,symlinkify_timeout_))
|
if(symlinkify_ && symlinkify::can_be_symlink(*st_,symlinkify_timeout_))
|
||||||
symlinkify::convert(fullpath,st_);
|
symlinkify::convert(fullpath,st_);
|
||||||
|
|
||||||
fs::inode::calc(branches[0]->path,fusepath_,st_);
|
fs::inode::calc(branches[0]->path,
|
||||||
|
fusepath_,
|
||||||
|
st_);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
_getattr(const char *fusepath_,
|
_getattr(const fs::path &fusepath_,
|
||||||
struct stat *st_,
|
struct stat *st_,
|
||||||
fuse_timeouts_t *timeout_)
|
fuse_timeouts_t *timeout_)
|
||||||
{
|
{
|
||||||
|
|
@ -202,6 +202,16 @@ int
|
||||||
FUSE::getattr(const char *fusepath_,
|
FUSE::getattr(const char *fusepath_,
|
||||||
struct stat *st_,
|
struct stat *st_,
|
||||||
fuse_timeouts_t *timeout_)
|
fuse_timeouts_t *timeout_)
|
||||||
|
{
|
||||||
|
const fs::path fusepath{fusepath_};
|
||||||
|
|
||||||
|
return FUSE::getattr(fusepath,st_,timeout_);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
FUSE::getattr(const fs::path &fusepath_,
|
||||||
|
struct stat *st_,
|
||||||
|
fuse_timeouts_t *timeout_)
|
||||||
{
|
{
|
||||||
if(Config::is_ctrl_file(fusepath_))
|
if(Config::is_ctrl_file(fusepath_))
|
||||||
return ::_getattr_controlfile(st_);
|
return ::_getattr_controlfile(st_);
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@
|
||||||
|
|
||||||
#include "fuse.h"
|
#include "fuse.h"
|
||||||
|
|
||||||
|
#include "fs_path.hpp"
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
@ -29,4 +31,10 @@ namespace FUSE
|
||||||
getattr(const char *fusepath,
|
getattr(const char *fusepath,
|
||||||
struct stat *buf,
|
struct stat *buf,
|
||||||
fuse_timeouts_t *timeout);
|
fuse_timeouts_t *timeout);
|
||||||
|
|
||||||
|
int
|
||||||
|
getattr(const fs::path &fusepath,
|
||||||
|
struct stat *buf,
|
||||||
|
fuse_timeouts_t *timeout);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,11 +29,11 @@
|
||||||
#include "fuse.h"
|
#include "fuse.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cstring>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
static const char SECURITY_CAPABILITY[] = "security.capability";
|
static const char SECURITY_CAPABILITY[] = "security.capability";
|
||||||
|
|
||||||
|
|
@ -97,7 +97,7 @@ _getxattr_from_string(char *destbuf_,
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_getxattr_user_mergerfs_allpaths(const Branches::Ptr &branches_,
|
_getxattr_user_mergerfs_allpaths(const Branches::Ptr &branches_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
char *buf_,
|
char *buf_,
|
||||||
const size_t count_)
|
const size_t count_)
|
||||||
{
|
{
|
||||||
|
|
@ -116,13 +116,13 @@ _getxattr_user_mergerfs_allpaths(const Branches::Ptr &branches_,
|
||||||
|
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_getxattr_user_mergerfs(const std::string &basepath_,
|
_getxattr_user_mergerfs(const fs::path &basepath_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
const std::string &fullpath_,
|
const fs::path &fullpath_,
|
||||||
const Branches &branches_,
|
const Branches &branches_,
|
||||||
const char *attrname_,
|
const char *attrname_,
|
||||||
char *buf_,
|
char *buf_,
|
||||||
const size_t count_)
|
const size_t count_)
|
||||||
{
|
{
|
||||||
std::string key;
|
std::string key;
|
||||||
|
|
||||||
|
|
@ -144,20 +144,20 @@ static
|
||||||
int
|
int
|
||||||
_getxattr(const Policy::Search &searchFunc_,
|
_getxattr(const Policy::Search &searchFunc_,
|
||||||
const Branches &branches_,
|
const Branches &branches_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
const char *attrname_,
|
const char *attrname_,
|
||||||
char *buf_,
|
char *buf_,
|
||||||
const size_t count_)
|
const size_t count_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
std::string fullpath;
|
fs::path fullpath;
|
||||||
std::vector<Branch*> branches;
|
std::vector<Branch*> branches;
|
||||||
|
|
||||||
rv = searchFunc_(branches_,fusepath_,branches);
|
rv = searchFunc_(branches_,fusepath_,branches);
|
||||||
if(rv < 0)
|
if(rv < 0)
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
fullpath = fs::path::make(branches[0]->path,fusepath_);
|
fullpath = branches[0]->path / fusepath_;
|
||||||
|
|
||||||
if(Config::is_mergerfs_xattr(attrname_))
|
if(Config::is_mergerfs_xattr(attrname_))
|
||||||
return ::_getxattr_user_mergerfs(branches[0]->path,
|
return ::_getxattr_user_mergerfs(branches[0]->path,
|
||||||
|
|
@ -177,7 +177,9 @@ FUSE::getxattr(const char *fusepath_,
|
||||||
char *attrvalue_,
|
char *attrvalue_,
|
||||||
size_t attrvalue_size_)
|
size_t attrvalue_size_)
|
||||||
{
|
{
|
||||||
if(Config::is_ctrl_file(fusepath_))
|
const fs::path fusepath{fusepath_};
|
||||||
|
|
||||||
|
if(Config::is_ctrl_file(fusepath))
|
||||||
return ::_getxattr_ctrl_file(cfg,
|
return ::_getxattr_ctrl_file(cfg,
|
||||||
attrname_,
|
attrname_,
|
||||||
attrvalue_,
|
attrvalue_,
|
||||||
|
|
@ -195,7 +197,7 @@ FUSE::getxattr(const char *fusepath_,
|
||||||
|
|
||||||
return ::_getxattr(cfg.func.getxattr.policy,
|
return ::_getxattr(cfg.func.getxattr.policy,
|
||||||
cfg.branches,
|
cfg.branches,
|
||||||
fusepath_,
|
fusepath,
|
||||||
attrname_,
|
attrname_,
|
||||||
attrvalue_,
|
attrvalue_,
|
||||||
attrvalue_size_);
|
attrvalue_size_);
|
||||||
|
|
|
||||||
|
|
@ -143,8 +143,8 @@ _want_if_capable_max_pages(fuse_conn_info *conn_,
|
||||||
|
|
||||||
static
|
static
|
||||||
void
|
void
|
||||||
_readahead(const fs::Path path_,
|
_readahead(const fs::path &path_,
|
||||||
const int readahead_)
|
const int readahead_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,7 @@ _ioctl_file(const fuse_file_info_t *ffi_,
|
||||||
void *data_,
|
void *data_,
|
||||||
uint32_t *out_bufsz_)
|
uint32_t *out_bufsz_)
|
||||||
{
|
{
|
||||||
FileInfo *fi = reinterpret_cast<FileInfo*>(ffi_->fh);
|
FileInfo *fi = FileInfo::from_fh(ffi_->fh);
|
||||||
const fuse_context *fc = fuse_get_context();
|
const fuse_context *fc = fuse_get_context();
|
||||||
const ugid::Set ugid(fc->uid,fc->gid);
|
const ugid::Set ugid(fc->uid,fc->gid);
|
||||||
|
|
||||||
|
|
@ -127,21 +127,21 @@ static
|
||||||
int
|
int
|
||||||
_ioctl_dir_base(const Policy::Search &searchFunc_,
|
_ioctl_dir_base(const Policy::Search &searchFunc_,
|
||||||
const Branches &branches_,
|
const Branches &branches_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
const uint32_t cmd_,
|
const uint32_t cmd_,
|
||||||
void *data_,
|
void *data_,
|
||||||
uint32_t *out_bufsz_)
|
uint32_t *out_bufsz_)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
int rv;
|
int rv;
|
||||||
std::string fullpath;
|
fs::path fullpath;
|
||||||
std::vector<Branch*> branches;
|
std::vector<Branch*> branches;
|
||||||
|
|
||||||
rv = searchFunc_(branches_,fusepath_,branches);
|
rv = searchFunc_(branches_,fusepath_,branches);
|
||||||
if(rv < 0)
|
if(rv < 0)
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
fullpath = fs::path::make(branches[0]->path,fusepath_);
|
fullpath = branches[0]->path / fusepath_;
|
||||||
|
|
||||||
fd = fs::open(fullpath,O_RDONLY|O_NOATIME|O_NONBLOCK);
|
fd = fs::open(fullpath,O_RDONLY|O_NOATIME|O_NONBLOCK);
|
||||||
if(fd < 0)
|
if(fd < 0)
|
||||||
|
|
@ -161,7 +161,7 @@ _ioctl_dir(const fuse_file_info_t *ffi_,
|
||||||
void *data_,
|
void *data_,
|
||||||
uint32_t *out_bufsz_)
|
uint32_t *out_bufsz_)
|
||||||
{
|
{
|
||||||
DirInfo *di = reinterpret_cast<DirInfo*>(ffi_->fh);
|
DirInfo *di = DirInfo::from_fh(ffi_->fh);
|
||||||
const fuse_context *fc = fuse_get_context();
|
const fuse_context *fc = fuse_get_context();
|
||||||
const ugid::Set ugid(fc->uid,fc->gid);
|
const ugid::Set ugid(fc->uid,fc->gid);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,6 @@
|
||||||
|
|
||||||
#include "fuse.h"
|
#include "fuse.h"
|
||||||
|
|
||||||
#include <filesystem>
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
@ -38,20 +37,20 @@ static
|
||||||
int
|
int
|
||||||
_link_create_path_loop(const std::vector<Branch*> &oldbranches_,
|
_link_create_path_loop(const std::vector<Branch*> &oldbranches_,
|
||||||
const Branch *newbranch_,
|
const Branch *newbranch_,
|
||||||
const char *oldfusepath_,
|
const fs::path &oldfusepath_,
|
||||||
const char *newfusepath_,
|
const fs::path &newfusepath_,
|
||||||
const std::string &newfusedirpath_)
|
const fs::path &newfusedirpath_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
int err;
|
int err;
|
||||||
std::string oldfullpath;
|
fs::path oldfullpath;
|
||||||
std::string newfullpath;
|
fs::path newfullpath;
|
||||||
|
|
||||||
err = -ENOENT;
|
err = -ENOENT;
|
||||||
for(const auto &oldbranch : oldbranches_)
|
for(const auto &oldbranch : oldbranches_)
|
||||||
{
|
{
|
||||||
oldfullpath = fs::path::make(oldbranch->path,oldfusepath_);
|
oldfullpath = oldbranch->path / oldfusepath_;
|
||||||
newfullpath = fs::path::make(oldbranch->path,newfusepath_);
|
newfullpath = oldbranch->path / newfusepath_;
|
||||||
|
|
||||||
rv = fs::link(oldfullpath,newfullpath);
|
rv = fs::link(oldfullpath,newfullpath);
|
||||||
if(rv == -ENOENT)
|
if(rv == -ENOENT)
|
||||||
|
|
@ -73,11 +72,11 @@ int
|
||||||
_link_create_path(const Policy::Search &searchFunc_,
|
_link_create_path(const Policy::Search &searchFunc_,
|
||||||
const Policy::Action &actionFunc_,
|
const Policy::Action &actionFunc_,
|
||||||
const Branches &ibranches_,
|
const Branches &ibranches_,
|
||||||
const char *oldfusepath_,
|
const fs::path &oldfusepath_,
|
||||||
const char *newfusepath_)
|
const fs::path &newfusepath_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
std::string newfusedirpath;
|
fs::path newfusedirpath;
|
||||||
std::vector<Branch*> oldbranches;
|
std::vector<Branch*> oldbranches;
|
||||||
std::vector<Branch*> newbranches;
|
std::vector<Branch*> newbranches;
|
||||||
|
|
||||||
|
|
@ -85,7 +84,7 @@ _link_create_path(const Policy::Search &searchFunc_,
|
||||||
if(rv < 0)
|
if(rv < 0)
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
newfusedirpath = fs::path::dirname(newfusepath_);
|
newfusedirpath = newfusepath_.parent_path();
|
||||||
|
|
||||||
rv = searchFunc_(ibranches_,newfusedirpath,newbranches);
|
rv = searchFunc_(ibranches_,newfusedirpath,newbranches);
|
||||||
if(rv < 0)
|
if(rv < 0)
|
||||||
|
|
@ -98,17 +97,17 @@ _link_create_path(const Policy::Search &searchFunc_,
|
||||||
|
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_link_preserve_path_core(const std::string &oldbasepath_,
|
_link_preserve_path_core(const fs::path &oldbasepath_,
|
||||||
const char *oldfusepath_,
|
const fs::path &oldfusepath_,
|
||||||
const char *newfusepath_,
|
const fs::path &newfusepath_,
|
||||||
struct stat *st_)
|
struct stat *st_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
std::string oldfullpath;
|
fs::path oldfullpath;
|
||||||
std::string newfullpath;
|
fs::path newfullpath;
|
||||||
|
|
||||||
oldfullpath = fs::path::make(oldbasepath_,oldfusepath_);
|
oldfullpath = oldbasepath_ / oldfusepath_;
|
||||||
newfullpath = fs::path::make(oldbasepath_,newfusepath_);
|
newfullpath = oldbasepath_ / newfusepath_;
|
||||||
|
|
||||||
rv = fs::link(oldfullpath,newfullpath);
|
rv = fs::link(oldfullpath,newfullpath);
|
||||||
if(rv == -ENOENT)
|
if(rv == -ENOENT)
|
||||||
|
|
@ -122,8 +121,8 @@ _link_preserve_path_core(const std::string &oldbasepath_,
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_link_preserve_path_loop(const std::vector<Branch*> &oldbranches_,
|
_link_preserve_path_loop(const std::vector<Branch*> &oldbranches_,
|
||||||
const char *oldfusepath_,
|
const fs::path &oldfusepath_,
|
||||||
const char *newfusepath_,
|
const fs::path &newfusepath_,
|
||||||
struct stat *st_)
|
struct stat *st_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
|
@ -147,8 +146,8 @@ static
|
||||||
int
|
int
|
||||||
_link_preserve_path(const Policy::Action &actionFunc_,
|
_link_preserve_path(const Policy::Action &actionFunc_,
|
||||||
const Branches &branches_,
|
const Branches &branches_,
|
||||||
const char *oldfusepath_,
|
const fs::path &oldfusepath_,
|
||||||
const char *newfusepath_,
|
const fs::path &newfusepath_,
|
||||||
struct stat *st_)
|
struct stat *st_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
|
@ -166,10 +165,10 @@ _link_preserve_path(const Policy::Action &actionFunc_,
|
||||||
|
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_link(Config &cfg_,
|
_link(Config &cfg_,
|
||||||
const char *oldpath_,
|
const fs::path &oldpath_,
|
||||||
const char *newpath_,
|
const fs::path &newpath_,
|
||||||
struct stat *st_)
|
struct stat *st_)
|
||||||
{
|
{
|
||||||
if(cfg_.func.create.policy.path_preserving() && !cfg_.ignorepponrename)
|
if(cfg_.func.create.policy.path_preserving() && !cfg_.ignorepponrename)
|
||||||
return ::_link_preserve_path(cfg_.func.link.policy,
|
return ::_link_preserve_path(cfg_.func.link.policy,
|
||||||
|
|
@ -188,8 +187,8 @@ _link(Config &cfg_,
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_link(Config &cfg_,
|
_link(Config &cfg_,
|
||||||
const char *oldpath_,
|
const fs::path &oldpath_,
|
||||||
const char *newpath_,
|
const fs::path &newpath_,
|
||||||
struct stat *st_,
|
struct stat *st_,
|
||||||
fuse_timeouts_t *timeouts_)
|
fuse_timeouts_t *timeouts_)
|
||||||
{
|
{
|
||||||
|
|
@ -204,18 +203,18 @@ _link(Config &cfg_,
|
||||||
|
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_link_exdev_rel_symlink(const char *oldpath_,
|
_link_exdev_rel_symlink(const fs::path &oldpath_,
|
||||||
const char *newpath_,
|
const fs::path &newpath_,
|
||||||
struct stat *st_,
|
struct stat *st_,
|
||||||
fuse_timeouts_t *timeouts_)
|
fuse_timeouts_t *timeouts_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
fs::Path target(oldpath_);
|
fs::path target(oldpath_);
|
||||||
fs::Path linkpath(newpath_);
|
fs::path linkpath(newpath_);
|
||||||
|
|
||||||
target = target.lexically_relative(linkpath.parent_path());
|
target = target.lexically_relative(linkpath.parent_path());
|
||||||
|
|
||||||
rv = FUSE::symlink(target.c_str(),linkpath.c_str());
|
rv = FUSE::symlink(target.c_str(),linkpath);
|
||||||
if(rv == 0)
|
if(rv == 0)
|
||||||
rv = FUSE::getattr(oldpath_,st_,timeouts_);
|
rv = FUSE::getattr(oldpath_,st_,timeouts_);
|
||||||
|
|
||||||
|
|
@ -230,20 +229,20 @@ static
|
||||||
int
|
int
|
||||||
_link_exdev_abs_base_symlink(const Policy::Search &openPolicy_,
|
_link_exdev_abs_base_symlink(const Policy::Search &openPolicy_,
|
||||||
const Branches::Ptr &ibranches_,
|
const Branches::Ptr &ibranches_,
|
||||||
const char *oldpath_,
|
const fs::path &oldpath_,
|
||||||
const char *newpath_,
|
const fs::path &newpath_,
|
||||||
struct stat *st_,
|
struct stat *st_,
|
||||||
fuse_timeouts_t *timeouts_)
|
fuse_timeouts_t *timeouts_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
std::string target;
|
fs::path target;
|
||||||
std::vector<Branch*> obranches;
|
std::vector<Branch*> obranches;
|
||||||
|
|
||||||
rv = openPolicy_(ibranches_,oldpath_,obranches);
|
rv = openPolicy_(ibranches_,oldpath_,obranches);
|
||||||
if(rv < 0)
|
if(rv < 0)
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
target = fs::path::make(obranches[0]->path,oldpath_);
|
target = obranches[0]->path / oldpath_;
|
||||||
|
|
||||||
rv = FUSE::symlink(target.c_str(),newpath_);
|
rv = FUSE::symlink(target.c_str(),newpath_);
|
||||||
if(rv == 0)
|
if(rv == 0)
|
||||||
|
|
@ -258,17 +257,17 @@ _link_exdev_abs_base_symlink(const Policy::Search &openPolicy_,
|
||||||
|
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_link_exdev_abs_pool_symlink(const fs::Path mount_,
|
_link_exdev_abs_pool_symlink(const fs::path &mount_,
|
||||||
const char *oldpath_,
|
const fs::path &oldpath_,
|
||||||
const char *newpath_,
|
const fs::path &newpath_,
|
||||||
struct stat *st_,
|
struct stat *st_,
|
||||||
fuse_timeouts_t *timeouts_)
|
fuse_timeouts_t *timeouts_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
StrVec basepaths;
|
StrVec basepaths;
|
||||||
std::string target;
|
fs::path target;
|
||||||
|
|
||||||
target = fs::path::make(mount_,oldpath_);
|
target = mount_ / oldpath_;
|
||||||
|
|
||||||
rv = FUSE::symlink(target.c_str(),newpath_);
|
rv = FUSE::symlink(target.c_str(),newpath_);
|
||||||
if(rv == 0)
|
if(rv == 0)
|
||||||
|
|
@ -284,8 +283,8 @@ _link_exdev_abs_pool_symlink(const fs::Path mount_,
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_link_exdev(Config &cfg_,
|
_link_exdev(Config &cfg_,
|
||||||
const char *oldpath_,
|
const fs::path &oldpath_,
|
||||||
const char *newpath_,
|
const fs::path &newpath_,
|
||||||
struct stat *st_,
|
struct stat *st_,
|
||||||
fuse_timeouts_t *timeouts_)
|
fuse_timeouts_t *timeouts_)
|
||||||
{
|
{
|
||||||
|
|
@ -323,12 +322,14 @@ FUSE::link(const char *oldpath_,
|
||||||
fuse_timeouts_t *timeouts_)
|
fuse_timeouts_t *timeouts_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
const fs::path oldpath{oldpath_};
|
||||||
|
const fs::path newpath{newpath_};
|
||||||
const fuse_context *fc = fuse_get_context();
|
const fuse_context *fc = fuse_get_context();
|
||||||
const ugid::Set ugid(fc->uid,fc->gid);
|
const ugid::Set ugid(fc->uid,fc->gid);
|
||||||
|
|
||||||
rv = ::_link(cfg,oldpath_,newpath_,st_,timeouts_);
|
rv = ::_link(cfg,oldpath,newpath,st_,timeouts_);
|
||||||
if(rv == -EXDEV)
|
if(rv == -EXDEV)
|
||||||
rv = ::_link_exdev(cfg,oldpath_,newpath_,st_,timeouts_);
|
rv = ::_link_exdev(cfg,oldpath,newpath,st_,timeouts_);
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,18 +24,19 @@
|
||||||
|
|
||||||
#include "fuse.h"
|
#include "fuse.h"
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
ssize_t
|
ssize_t
|
||||||
_listxattr_size(const std::vector<Branch*> &branches_,
|
_listxattr_size(const std::vector<Branch*> &branches_,
|
||||||
const char *fusepath_)
|
const fs::path &fusepath_)
|
||||||
{
|
{
|
||||||
ssize_t size;
|
ssize_t size;
|
||||||
std::string fullpath;
|
fs::path fullpath;
|
||||||
|
|
||||||
if(branches_.empty())
|
if(branches_.empty())
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
@ -45,7 +46,7 @@ _listxattr_size(const std::vector<Branch*> &branches_,
|
||||||
{
|
{
|
||||||
ssize_t rv;
|
ssize_t rv;
|
||||||
|
|
||||||
fullpath = fs::path::make(branch->path,fusepath_);
|
fullpath = branch->path / fusepath_;
|
||||||
|
|
||||||
rv = fs::llistxattr(fullpath,NULL,0);
|
rv = fs::llistxattr(fullpath,NULL,0);
|
||||||
if(rv < 0)
|
if(rv < 0)
|
||||||
|
|
@ -60,13 +61,13 @@ _listxattr_size(const std::vector<Branch*> &branches_,
|
||||||
static
|
static
|
||||||
ssize_t
|
ssize_t
|
||||||
_listxattr(const std::vector<Branch*> &branches_,
|
_listxattr(const std::vector<Branch*> &branches_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
char *list_,
|
char *list_,
|
||||||
size_t size_)
|
size_t size_)
|
||||||
{
|
{
|
||||||
ssize_t rv;
|
ssize_t rv;
|
||||||
ssize_t size;
|
ssize_t size;
|
||||||
std::string fullpath;
|
fs::path fullpath;
|
||||||
std::optional<ssize_t> err;
|
std::optional<ssize_t> err;
|
||||||
|
|
||||||
if(size_ == 0)
|
if(size_ == 0)
|
||||||
|
|
@ -76,7 +77,7 @@ _listxattr(const std::vector<Branch*> &branches_,
|
||||||
err = -ENOENT;
|
err = -ENOENT;
|
||||||
for(const auto branch : branches_)
|
for(const auto branch : branches_)
|
||||||
{
|
{
|
||||||
fullpath = fs::path::make(branch->path,fusepath_);
|
fullpath = branch->path / fusepath_;
|
||||||
|
|
||||||
rv = fs::llistxattr(fullpath,list_,size_);
|
rv = fs::llistxattr(fullpath,list_,size_);
|
||||||
if(rv == -ERANGE)
|
if(rv == -ERANGE)
|
||||||
|
|
@ -104,12 +105,11 @@ static
|
||||||
int
|
int
|
||||||
_listxattr(const Policy::Search &searchFunc_,
|
_listxattr(const Policy::Search &searchFunc_,
|
||||||
const Branches &ibranches_,
|
const Branches &ibranches_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
char *list_,
|
char *list_,
|
||||||
const size_t size_)
|
const size_t size_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
std::string fullpath;
|
|
||||||
std::vector<Branch*> obranches;
|
std::vector<Branch*> obranches;
|
||||||
|
|
||||||
rv = searchFunc_(ibranches_,fusepath_,obranches);
|
rv = searchFunc_(ibranches_,fusepath_,obranches);
|
||||||
|
|
@ -127,7 +127,9 @@ FUSE::listxattr(const char *fusepath_,
|
||||||
char *list_,
|
char *list_,
|
||||||
size_t size_)
|
size_t size_)
|
||||||
{
|
{
|
||||||
if(Config::is_ctrl_file(fusepath_))
|
const fs::path fusepath{fusepath_};
|
||||||
|
|
||||||
|
if(Config::is_ctrl_file(fusepath))
|
||||||
return cfg.keys_listxattr(list_,size_);
|
return cfg.keys_listxattr(list_,size_);
|
||||||
|
|
||||||
switch(cfg.xattr)
|
switch(cfg.xattr)
|
||||||
|
|
@ -145,7 +147,7 @@ FUSE::listxattr(const char *fusepath_,
|
||||||
|
|
||||||
return ::_listxattr(cfg.func.listxattr.policy,
|
return ::_listxattr(cfg.func.listxattr.policy,
|
||||||
cfg.branches,
|
cfg.branches,
|
||||||
fusepath_,
|
fusepath,
|
||||||
list_,
|
list_,
|
||||||
size_);
|
size_);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,18 +16,17 @@
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "fuse_lock.hpp"
|
||||||
|
|
||||||
#include "errno.hpp"
|
#include "errno.hpp"
|
||||||
|
|
||||||
#include "fuse.h"
|
#include "fuse.h"
|
||||||
|
|
||||||
|
|
||||||
namespace FUSE
|
int
|
||||||
|
FUSE::lock(const fuse_file_info_t *ffi,
|
||||||
|
int cmd,
|
||||||
|
struct flock *flock)
|
||||||
{
|
{
|
||||||
int
|
return -ENOSYS;
|
||||||
lock(const fuse_file_info_t *ffi,
|
|
||||||
int cmd,
|
|
||||||
struct flock *flock)
|
|
||||||
{
|
|
||||||
return -ENOSYS;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,9 +33,9 @@
|
||||||
|
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_mkdir_core(const std::string &fullpath_,
|
_mkdir_core(const fs::path &fullpath_,
|
||||||
mode_t mode_,
|
mode_t mode_,
|
||||||
const mode_t umask_)
|
const mode_t umask_)
|
||||||
{
|
{
|
||||||
if(!fs::acl::dir_has_defaults(fullpath_))
|
if(!fs::acl::dir_has_defaults(fullpath_))
|
||||||
mode_ &= ~umask_;
|
mode_ &= ~umask_;
|
||||||
|
|
@ -45,15 +45,15 @@ _mkdir_core(const std::string &fullpath_,
|
||||||
|
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_mkdir_loop_core(const std::string &createpath_,
|
_mkdir_loop_core(const fs::path &createpath_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
const mode_t mode_,
|
const mode_t mode_,
|
||||||
const mode_t umask_)
|
const mode_t umask_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
std::string fullpath;
|
fs::path fullpath;
|
||||||
|
|
||||||
fullpath = fs::path::make(createpath_,fusepath_);
|
fullpath = createpath_ / fusepath_;
|
||||||
|
|
||||||
rv = ::_mkdir_core(fullpath,mode_,umask_);
|
rv = ::_mkdir_core(fullpath,mode_,umask_);
|
||||||
|
|
||||||
|
|
@ -64,8 +64,8 @@ static
|
||||||
int
|
int
|
||||||
_mkdir_loop(const Branch *existingbranch_,
|
_mkdir_loop(const Branch *existingbranch_,
|
||||||
const std::vector<Branch*> &createbranches_,
|
const std::vector<Branch*> &createbranches_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
const std::string &fusedirpath_,
|
const fs::path &fusedirpath_,
|
||||||
const mode_t mode_,
|
const mode_t mode_,
|
||||||
const mode_t umask_)
|
const mode_t umask_)
|
||||||
{
|
{
|
||||||
|
|
@ -97,16 +97,16 @@ int
|
||||||
_mkdir(const Policy::Search &getattrPolicy_,
|
_mkdir(const Policy::Search &getattrPolicy_,
|
||||||
const Policy::Create &mkdirPolicy_,
|
const Policy::Create &mkdirPolicy_,
|
||||||
const Branches &branches_,
|
const Branches &branches_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
const mode_t mode_,
|
const mode_t mode_,
|
||||||
const mode_t umask_)
|
const mode_t umask_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
std::string fusedirpath;
|
fs::path fusedirpath;
|
||||||
std::vector<Branch*> createbranches;
|
std::vector<Branch*> createbranches;
|
||||||
std::vector<Branch*> existingbranches;
|
std::vector<Branch*> existingbranches;
|
||||||
|
|
||||||
fusedirpath = fs::path::dirname(fusepath_);
|
fusedirpath = fusepath_.parent_path();
|
||||||
|
|
||||||
rv = getattrPolicy_(branches_,fusedirpath,existingbranches);
|
rv = getattrPolicy_(branches_,fusedirpath,existingbranches);
|
||||||
if(rv < 0)
|
if(rv < 0)
|
||||||
|
|
@ -129,13 +129,14 @@ FUSE::mkdir(const char *fusepath_,
|
||||||
mode_t mode_)
|
mode_t mode_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
const fs::path fusepath{fusepath_};
|
||||||
const fuse_context *fc = fuse_get_context();
|
const fuse_context *fc = fuse_get_context();
|
||||||
const ugid::Set ugid(fc->uid,fc->gid);
|
const ugid::Set ugid(fc->uid,fc->gid);
|
||||||
|
|
||||||
rv = ::_mkdir(cfg.func.getattr.policy,
|
rv = ::_mkdir(cfg.func.getattr.policy,
|
||||||
cfg.func.mkdir.policy,
|
cfg.func.mkdir.policy,
|
||||||
cfg.branches,
|
cfg.branches,
|
||||||
fusepath_,
|
fusepath,
|
||||||
mode_,
|
mode_,
|
||||||
fc->umask);
|
fc->umask);
|
||||||
if(rv == -EROFS)
|
if(rv == -EROFS)
|
||||||
|
|
@ -144,7 +145,7 @@ FUSE::mkdir(const char *fusepath_,
|
||||||
rv = ::_mkdir(cfg.func.getattr.policy,
|
rv = ::_mkdir(cfg.func.getattr.policy,
|
||||||
cfg.func.mkdir.policy,
|
cfg.func.mkdir.policy,
|
||||||
cfg.branches,
|
cfg.branches,
|
||||||
fusepath_,
|
fusepath,
|
||||||
mode_,
|
mode_,
|
||||||
fc->umask);
|
fc->umask);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,10 +34,10 @@
|
||||||
static
|
static
|
||||||
inline
|
inline
|
||||||
int
|
int
|
||||||
_mknod_core(const std::string &fullpath_,
|
_mknod_core(const fs::path &fullpath_,
|
||||||
mode_t mode_,
|
mode_t mode_,
|
||||||
const mode_t umask_,
|
const mode_t umask_,
|
||||||
const dev_t dev_)
|
const dev_t dev_)
|
||||||
{
|
{
|
||||||
if(!fs::acl::dir_has_defaults(fullpath_))
|
if(!fs::acl::dir_has_defaults(fullpath_))
|
||||||
mode_ &= ~umask_;
|
mode_ &= ~umask_;
|
||||||
|
|
@ -47,16 +47,16 @@ _mknod_core(const std::string &fullpath_,
|
||||||
|
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_mknod_loop_core(const std::string &createbranch_,
|
_mknod_loop_core(const fs::path &createbranch_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
const mode_t mode_,
|
const mode_t mode_,
|
||||||
const mode_t umask_,
|
const mode_t umask_,
|
||||||
const dev_t dev_)
|
const dev_t dev_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
std::string fullpath;
|
fs::path fullpath;
|
||||||
|
|
||||||
fullpath = fs::path::make(createbranch_,fusepath_);
|
fullpath = createbranch_ / fusepath_;
|
||||||
|
|
||||||
rv = ::_mknod_core(fullpath,mode_,umask_,dev_);
|
rv = ::_mknod_core(fullpath,mode_,umask_,dev_);
|
||||||
|
|
||||||
|
|
@ -65,10 +65,10 @@ _mknod_loop_core(const std::string &createbranch_,
|
||||||
|
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_mknod_loop(const std::string &existingbranch_,
|
_mknod_loop(const fs::path &existingbranch_,
|
||||||
const std::vector<Branch*> &createbranches_,
|
const std::vector<Branch*> &createbranches_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
const std::string &fusedirpath_,
|
const fs::path &fusedirpath_,
|
||||||
const mode_t mode_,
|
const mode_t mode_,
|
||||||
const mode_t umask_,
|
const mode_t umask_,
|
||||||
const dev_t dev_)
|
const dev_t dev_)
|
||||||
|
|
@ -102,17 +102,17 @@ int
|
||||||
_mknod(const Policy::Search &searchFunc_,
|
_mknod(const Policy::Search &searchFunc_,
|
||||||
const Policy::Create &createFunc_,
|
const Policy::Create &createFunc_,
|
||||||
const Branches &branches_,
|
const Branches &branches_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
const mode_t mode_,
|
const mode_t mode_,
|
||||||
const mode_t umask_,
|
const mode_t umask_,
|
||||||
const dev_t dev_)
|
const dev_t dev_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
std::string fusedirpath;
|
fs::path fusedirpath;
|
||||||
std::vector<Branch*> createbranches;
|
std::vector<Branch*> createbranches;
|
||||||
std::vector<Branch*> existingbranches;
|
std::vector<Branch*> existingbranches;
|
||||||
|
|
||||||
fusedirpath = fs::path::dirname(fusepath_);
|
fusedirpath = fusepath_.parent_path();
|
||||||
|
|
||||||
rv = searchFunc_(branches_,fusedirpath,existingbranches);
|
rv = searchFunc_(branches_,fusedirpath,existingbranches);
|
||||||
if(rv < 0)
|
if(rv < 0)
|
||||||
|
|
@ -137,13 +137,14 @@ FUSE::mknod(const char *fusepath_,
|
||||||
dev_t rdev_)
|
dev_t rdev_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
const fs::path fusepath{fusepath_};
|
||||||
const fuse_context *fc = fuse_get_context();
|
const fuse_context *fc = fuse_get_context();
|
||||||
const ugid::Set ugid(fc->uid,fc->gid);
|
const ugid::Set ugid(fc->uid,fc->gid);
|
||||||
|
|
||||||
rv = ::_mknod(cfg.func.getattr.policy,
|
rv = ::_mknod(cfg.func.getattr.policy,
|
||||||
cfg.func.mknod.policy,
|
cfg.func.mknod.policy,
|
||||||
cfg.branches,
|
cfg.branches,
|
||||||
fusepath_,
|
fusepath,
|
||||||
mode_,
|
mode_,
|
||||||
fc->umask,
|
fc->umask,
|
||||||
rdev_);
|
rdev_);
|
||||||
|
|
@ -153,7 +154,7 @@ FUSE::mknod(const char *fusepath_,
|
||||||
rv = ::_mknod(cfg.func.getattr.policy,
|
rv = ::_mknod(cfg.func.getattr.policy,
|
||||||
cfg.func.mknod.policy,
|
cfg.func.mknod.policy,
|
||||||
cfg.branches,
|
cfg.branches,
|
||||||
fusepath_,
|
fusepath,
|
||||||
mode_,
|
mode_,
|
||||||
fc->umask,
|
fc->umask,
|
||||||
rdev_);
|
rdev_);
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
bool
|
bool
|
||||||
_rdonly(const int flags_)
|
_rdonly(const int flags_)
|
||||||
|
|
@ -49,8 +50,8 @@ _rdonly(const int flags_)
|
||||||
|
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_lchmod_and_open_if_not_writable_and_empty(const std::string &fullpath_,
|
_lchmod_and_open_if_not_writable_and_empty(const fs::path &fullpath_,
|
||||||
const int flags_)
|
const int flags_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
@ -77,7 +78,7 @@ _lchmod_and_open_if_not_writable_and_empty(const std::string &fullpath_,
|
||||||
|
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_nfsopenhack(const std::string &fullpath_,
|
_nfsopenhack(const fs::path &fullpath_,
|
||||||
const int flags_,
|
const int flags_,
|
||||||
const NFSOpenHack nfsopenhack_)
|
const NFSOpenHack nfsopenhack_)
|
||||||
{
|
{
|
||||||
|
|
@ -89,7 +90,7 @@ _nfsopenhack(const std::string &fullpath_,
|
||||||
case NFSOpenHack::ENUM::GIT:
|
case NFSOpenHack::ENUM::GIT:
|
||||||
if(::_rdonly(flags_))
|
if(::_rdonly(flags_))
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
if(fullpath_.find("/.git/") == std::string::npos)
|
if(fullpath_.string().find("/.git/") == std::string::npos)
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
return ::_lchmod_and_open_if_not_writable_and_empty(fullpath_,flags_);
|
return ::_lchmod_and_open_if_not_writable_and_empty(fullpath_,flags_);
|
||||||
case NFSOpenHack::ENUM::ALL:
|
case NFSOpenHack::ENUM::ALL:
|
||||||
|
|
@ -194,9 +195,9 @@ _config_to_ffi_flags(Config &cfg_,
|
||||||
|
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_open_path(const std::string &filepath_,
|
_open_path(const fs::path &filepath_,
|
||||||
const Branch *branch_,
|
const Branch *branch_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
fuse_file_info_t *ffi_,
|
fuse_file_info_t *ffi_,
|
||||||
const NFSOpenHack nfsopenhack_)
|
const NFSOpenHack nfsopenhack_)
|
||||||
{
|
{
|
||||||
|
|
@ -211,7 +212,7 @@ _open_path(const std::string &filepath_,
|
||||||
|
|
||||||
fi = new FileInfo(fd,branch_,fusepath_,ffi_->direct_io);
|
fi = new FileInfo(fd,branch_,fusepath_,ffi_->direct_io);
|
||||||
|
|
||||||
ffi_->fh = reinterpret_cast<uint64_t>(fi);
|
ffi_->fh = fi->to_fh();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -220,7 +221,7 @@ static
|
||||||
int
|
int
|
||||||
_open_fd(const int fd_,
|
_open_fd(const int fd_,
|
||||||
const Branch *branch_,
|
const Branch *branch_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
fuse_file_info_t *ffi_)
|
fuse_file_info_t *ffi_)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
|
|
@ -232,7 +233,7 @@ _open_fd(const int fd_,
|
||||||
|
|
||||||
fi = new FileInfo(fd,branch_,fusepath_,ffi_->direct_io);
|
fi = new FileInfo(fd,branch_,fusepath_,ffi_->direct_io);
|
||||||
|
|
||||||
ffi_->fh = reinterpret_cast<uint64_t>(fi);
|
ffi_->fh = fi->to_fh();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -241,23 +242,23 @@ static
|
||||||
int
|
int
|
||||||
_open(const Policy::Search &searchFunc_,
|
_open(const Policy::Search &searchFunc_,
|
||||||
const Branches &ibranches_,
|
const Branches &ibranches_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
fuse_file_info_t *ffi_,
|
fuse_file_info_t *ffi_,
|
||||||
const bool link_cow_,
|
const bool link_cow_,
|
||||||
const NFSOpenHack nfsopenhack_)
|
const NFSOpenHack nfsopenhack_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
std::string filepath;
|
fs::path filepath;
|
||||||
std::vector<Branch*> obranches;
|
std::vector<Branch*> obranches;
|
||||||
|
|
||||||
rv = searchFunc_(ibranches_,fusepath_,obranches);
|
rv = searchFunc_(ibranches_,fusepath_,obranches);
|
||||||
if(rv < 0)
|
if(rv < 0)
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
filepath = fs::path::make(obranches[0]->path,fusepath_);
|
filepath = obranches[0]->path / fusepath_;
|
||||||
|
|
||||||
if(link_cow_ && fs::cow::is_eligible(filepath.c_str(),ffi_->flags))
|
if(link_cow_ && fs::cow::is_eligible(filepath,ffi_->flags))
|
||||||
fs::cow::break_link(filepath.c_str());
|
fs::cow::break_link(filepath);
|
||||||
|
|
||||||
rv = ::_open_path(filepath,
|
rv = ::_open_path(filepath,
|
||||||
obranches[0],
|
obranches[0],
|
||||||
|
|
@ -280,7 +281,7 @@ _(const PassthroughEnum e_,
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_open_for_insert_lambda(const fuse_context *fc_,
|
_open_for_insert_lambda(const fuse_context *fc_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
fuse_file_info_t *ffi_,
|
fuse_file_info_t *ffi_,
|
||||||
State::OpenFile *of_)
|
State::OpenFile *of_)
|
||||||
{
|
{
|
||||||
|
|
@ -306,7 +307,7 @@ _open_for_insert_lambda(const fuse_context *fc_,
|
||||||
if(rv < 0)
|
if(rv < 0)
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
fi = reinterpret_cast<FileInfo*>(ffi_->fh);
|
fi = FileInfo::from_fh(ffi_->fh);
|
||||||
|
|
||||||
of_->ref_count = 1;
|
of_->ref_count = 1;
|
||||||
of_->fi = fi;
|
of_->fi = fi;
|
||||||
|
|
@ -337,7 +338,7 @@ _open_for_insert_lambda(const fuse_context *fc_,
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_open_for_update_lambda(const fuse_context *fc_,
|
_open_for_update_lambda(const fuse_context *fc_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
fuse_file_info_t *ffi_,
|
fuse_file_info_t *ffi_,
|
||||||
State::OpenFile *of_)
|
State::OpenFile *of_)
|
||||||
{
|
{
|
||||||
|
|
@ -373,10 +374,9 @@ _open_for_update_lambda(const fuse_context *fc_,
|
||||||
|
|
||||||
static
|
static
|
||||||
inline
|
inline
|
||||||
constexpr
|
|
||||||
auto
|
auto
|
||||||
_open_insert_lambda(const fuse_context *fc_,
|
_open_insert_lambda(const fuse_context *fc_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
fuse_file_info_t *ffi_,
|
fuse_file_info_t *ffi_,
|
||||||
int *rv_)
|
int *rv_)
|
||||||
{
|
{
|
||||||
|
|
@ -392,10 +392,9 @@ _open_insert_lambda(const fuse_context *fc_,
|
||||||
|
|
||||||
static
|
static
|
||||||
inline
|
inline
|
||||||
constexpr
|
|
||||||
auto
|
auto
|
||||||
_open_update_lambda(const fuse_context *fc_,
|
_open_update_lambda(const fuse_context *fc_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
fuse_file_info_t *ffi_,
|
fuse_file_info_t *ffi_,
|
||||||
int *rv_)
|
int *rv_)
|
||||||
{
|
{
|
||||||
|
|
@ -424,7 +423,7 @@ _open_update_lambda(const fuse_context *fc_,
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_open(const fuse_context *fc_,
|
_open(const fuse_context *fc_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
fuse_file_info_t *ffi_)
|
fuse_file_info_t *ffi_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
|
@ -449,14 +448,12 @@ _open(const fuse_context *fc_,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace FUSE
|
int
|
||||||
|
FUSE::open(const char *fusepath_,
|
||||||
|
fuse_file_info_t *ffi_)
|
||||||
{
|
{
|
||||||
int
|
const fs::path fusepath{fusepath_};
|
||||||
open(const char *fusepath_,
|
const fuse_context *fc = fuse_get_context();
|
||||||
fuse_file_info_t *ffi_)
|
|
||||||
{
|
|
||||||
const fuse_context *fc = fuse_get_context();
|
|
||||||
|
|
||||||
return ::_open(fc,fusepath_,ffi_);
|
return ::_open(fc,fusepath,ffi_);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,11 @@ int
|
||||||
FUSE::opendir(const char *fusepath_,
|
FUSE::opendir(const char *fusepath_,
|
||||||
fuse_file_info_t *ffi_)
|
fuse_file_info_t *ffi_)
|
||||||
{
|
{
|
||||||
ffi_->fh = reinterpret_cast<uint64_t>(new DirInfo(fusepath_));
|
DirInfo *di;
|
||||||
|
|
||||||
|
di = new DirInfo(fusepath_);
|
||||||
|
|
||||||
|
ffi_->fh = di->to_fh();
|
||||||
|
|
||||||
ffi_->noflush = true;
|
ffi_->noflush = true;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,22 +16,21 @@
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "fuse_poll.hpp"
|
||||||
|
|
||||||
#include "errno.hpp"
|
#include "errno.hpp"
|
||||||
|
|
||||||
#include "fuse.h"
|
#include "fuse.h"
|
||||||
|
|
||||||
|
|
||||||
namespace FUSE
|
int
|
||||||
|
FUSE::poll(const fuse_file_info_t *ffi_,
|
||||||
|
fuse_pollhandle_t *ph_,
|
||||||
|
unsigned *reventsp_)
|
||||||
{
|
{
|
||||||
int
|
(void)ffi_;
|
||||||
poll(const fuse_file_info_t *ffi_,
|
(void)ph_;
|
||||||
fuse_pollhandle_t *ph_,
|
(void)reventsp_;
|
||||||
unsigned *reventsp_)
|
|
||||||
{
|
|
||||||
(void)ffi_;
|
|
||||||
(void)ph_;
|
|
||||||
(void)reventsp_;
|
|
||||||
|
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ FUSE::read(const fuse_file_info_t *ffi_,
|
||||||
size_t size_,
|
size_t size_,
|
||||||
off_t offset_)
|
off_t offset_)
|
||||||
{
|
{
|
||||||
FileInfo *fi = reinterpret_cast<FileInfo*>(ffi_->fh);
|
FileInfo *fi = FileInfo::from_fh(ffi_->fh);
|
||||||
|
|
||||||
if(fi->direct_io)
|
if(fi->direct_io)
|
||||||
return ::_read_direct_io(fi->fd,buf_,size_,offset_);
|
return ::_read_direct_io(fi->fd,buf_,size_,offset_);
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ _handle_ENOENT(const fuse_file_info_t *ffi_,
|
||||||
fuse_dirents_t *buf_)
|
fuse_dirents_t *buf_)
|
||||||
{
|
{
|
||||||
dirent de;
|
dirent de;
|
||||||
DirInfo *di = reinterpret_cast<DirInfo*>(ffi_->fh);
|
DirInfo *di = DirInfo::from_fh(ffi_->fh);
|
||||||
|
|
||||||
if(di->fusepath != "/")
|
if(di->fusepath != "/")
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,8 @@
|
||||||
|
|
||||||
#include "int_types.h"
|
#include "int_types.h"
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
#define MAX_ENTRIES_PER_LOOP 64
|
#define MAX_ENTRIES_PER_LOOP 64
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -63,153 +65,152 @@ _dirent_exact_namelen(const struct dirent *d_)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace l
|
struct Error
|
||||||
{
|
{
|
||||||
struct Error
|
private:
|
||||||
|
int _err;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Error()
|
||||||
|
: _err(ENOENT)
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
int _err;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Error()
|
|
||||||
: _err(ENOENT)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
operator int()
|
|
||||||
{
|
|
||||||
return _err;
|
|
||||||
}
|
|
||||||
|
|
||||||
Error&
|
|
||||||
operator=(int v_)
|
|
||||||
{
|
|
||||||
if(_err != 0)
|
|
||||||
_err = v_;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static
|
|
||||||
inline
|
|
||||||
int
|
|
||||||
readdir(const std::string &branch_path_,
|
|
||||||
const std::string &rel_dirpath_,
|
|
||||||
HashSet &names_,
|
|
||||||
fuse_dirents_t *buf_,
|
|
||||||
std::mutex &mutex_)
|
|
||||||
{
|
|
||||||
int rv;
|
|
||||||
DIR *dir;
|
|
||||||
std::string rel_filepath;
|
|
||||||
std::string abs_dirpath;
|
|
||||||
|
|
||||||
abs_dirpath = fs::path::make(branch_path_,rel_dirpath_);
|
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
dir = fs::opendir(abs_dirpath);
|
|
||||||
if(dir == NULL)
|
|
||||||
return errno;
|
|
||||||
|
|
||||||
DEFER{ fs::closedir(dir); };
|
|
||||||
|
|
||||||
// The default buffer size in glibc is 32KB. 64 is based on a
|
|
||||||
// guess of an average size of 512B per entry. This is to limit
|
|
||||||
// contention on the lock when needing to request more data from
|
|
||||||
// the kernel. This could be handled better by using getdents but
|
|
||||||
// due to the differences between Linux and FreeBSD a more
|
|
||||||
// complicated abstraction needs to be created to handle them to
|
|
||||||
// make it easier to use across the codebase.
|
|
||||||
// * https://man7.org/linux/man-pages/man2/getdents.2.html
|
|
||||||
// * https://man.freebsd.org/cgi/man.cgi?query=getdents
|
|
||||||
while(true)
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lk(mutex_);
|
|
||||||
for(int i = 0; i < MAX_ENTRIES_PER_LOOP; i++)
|
|
||||||
{
|
|
||||||
dirent *de;
|
|
||||||
u64 namelen;
|
|
||||||
|
|
||||||
de = fs::readdir(dir);
|
|
||||||
if(de == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
namelen = ::_dirent_exact_namelen(de);
|
|
||||||
|
|
||||||
rv = names_.put(de->d_name,namelen);
|
|
||||||
if(rv == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
rel_filepath = fs::path::make(rel_dirpath_,de->d_name);
|
|
||||||
de->d_ino = fs::inode::calc(branch_path_,
|
|
||||||
rel_filepath,
|
|
||||||
DTTOIF(de->d_type),
|
|
||||||
de->d_ino);
|
|
||||||
|
|
||||||
rv = fuse_dirents_add(buf_,de,namelen);
|
|
||||||
if(rv >= 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
return ENOMEM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
operator int()
|
||||||
inline
|
|
||||||
int
|
|
||||||
concurrent_readdir(ThreadPool &tp_,
|
|
||||||
const Branches::Ptr &branches_,
|
|
||||||
const std::string &rel_dirpath_,
|
|
||||||
fuse_dirents_t *buf_,
|
|
||||||
const uid_t uid_,
|
|
||||||
const gid_t gid_)
|
|
||||||
{
|
{
|
||||||
HashSet names;
|
return _err;
|
||||||
std::mutex mutex;
|
|
||||||
std::vector<std::future<int>> futures;
|
|
||||||
|
|
||||||
fuse_dirents_reset(buf_);
|
|
||||||
futures.reserve(branches_->size());
|
|
||||||
|
|
||||||
for(const auto &branch : *branches_)
|
|
||||||
{
|
|
||||||
auto func =
|
|
||||||
[&,buf_,uid_,gid_]()
|
|
||||||
{
|
|
||||||
const ugid::Set ugid(uid_,gid_);
|
|
||||||
|
|
||||||
return l::readdir(branch.path,
|
|
||||||
rel_dirpath_,
|
|
||||||
names,
|
|
||||||
buf_,
|
|
||||||
mutex);
|
|
||||||
};
|
|
||||||
|
|
||||||
auto rv = tp_.enqueue_task(std::move(func));
|
|
||||||
|
|
||||||
futures.emplace_back(std::move(rv));
|
|
||||||
}
|
|
||||||
|
|
||||||
Error error;
|
|
||||||
for(auto &future : futures)
|
|
||||||
error = future.get();
|
|
||||||
|
|
||||||
return -error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Error&
|
||||||
|
operator=(int v_)
|
||||||
|
{
|
||||||
|
if(_err != 0)
|
||||||
|
_err = v_;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
int
|
||||||
|
_readdir(const fs::path &branch_path_,
|
||||||
|
const fs::path &rel_dirpath_,
|
||||||
|
HashSet &names_,
|
||||||
|
fuse_dirents_t *buf_,
|
||||||
|
std::mutex &mutex_)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
DIR *dir;
|
||||||
|
fs::path rel_filepath;
|
||||||
|
fs::path abs_dirpath;
|
||||||
|
|
||||||
|
abs_dirpath = branch_path_ / rel_dirpath_;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
dir = fs::opendir(abs_dirpath);
|
||||||
|
if(dir == NULL)
|
||||||
|
return errno;
|
||||||
|
|
||||||
|
DEFER{ fs::closedir(dir); };
|
||||||
|
|
||||||
|
// The default buffer size in glibc is 32KB. 64 is based on a
|
||||||
|
// guess of an average size of 512B per entry. This is to limit
|
||||||
|
// contention on the lock when needing to request more data from
|
||||||
|
// the kernel. This could be handled better by using getdents but
|
||||||
|
// due to the differences between Linux and FreeBSD a more
|
||||||
|
// complicated abstraction needs to be created to handle them to
|
||||||
|
// make it easier to use across the codebase.
|
||||||
|
// * https://man7.org/linux/man-pages/man2/getdents.2.html
|
||||||
|
// * https://man.freebsd.org/cgi/man.cgi?query=getdents
|
||||||
|
rel_filepath = rel_dirpath_ / "dummy";
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lk(mutex_);
|
||||||
|
for(int i = 0; i < MAX_ENTRIES_PER_LOOP; i++)
|
||||||
|
{
|
||||||
|
dirent *de;
|
||||||
|
u64 namelen;
|
||||||
|
|
||||||
|
de = fs::readdir(dir);
|
||||||
|
if(de == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
namelen = ::_dirent_exact_namelen(de);
|
||||||
|
|
||||||
|
rv = names_.put(de->d_name,namelen);
|
||||||
|
if(rv == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
rel_filepath.replace_filename(de->d_name);
|
||||||
|
|
||||||
|
de->d_ino = fs::inode::calc(branch_path_,
|
||||||
|
rel_filepath,
|
||||||
|
DTTOIF(de->d_type),
|
||||||
|
de->d_ino);
|
||||||
|
|
||||||
|
rv = fuse_dirents_add(buf_,de,namelen);
|
||||||
|
if(rv >= 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
int
|
||||||
|
_concurrent_readdir(ThreadPool &tp_,
|
||||||
|
const Branches::Ptr &branches_,
|
||||||
|
const fs::path &rel_dirpath_,
|
||||||
|
fuse_dirents_t *buf_,
|
||||||
|
const uid_t uid_,
|
||||||
|
const gid_t gid_)
|
||||||
|
{
|
||||||
|
HashSet names;
|
||||||
|
std::mutex mutex;
|
||||||
|
std::vector<std::future<int>> futures;
|
||||||
|
|
||||||
|
fuse_dirents_reset(buf_);
|
||||||
|
futures.reserve(branches_->size());
|
||||||
|
|
||||||
|
for(const auto &branch : *branches_)
|
||||||
|
{
|
||||||
|
auto func =
|
||||||
|
[&,buf_,uid_,gid_]()
|
||||||
|
{
|
||||||
|
const ugid::Set ugid(uid_,gid_);
|
||||||
|
|
||||||
|
return ::_readdir(branch.path,
|
||||||
|
rel_dirpath_,
|
||||||
|
names,
|
||||||
|
buf_,
|
||||||
|
mutex);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto rv = tp_.enqueue_task(std::move(func));
|
||||||
|
|
||||||
|
futures.emplace_back(std::move(rv));
|
||||||
|
}
|
||||||
|
|
||||||
|
Error error;
|
||||||
|
for(auto &future : futures)
|
||||||
|
error = future.get();
|
||||||
|
|
||||||
|
return -error;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
FUSE::ReadDirCOR::operator()(const fuse_file_info_t *ffi_,
|
FUSE::ReadDirCOR::operator()(const fuse_file_info_t *ffi_,
|
||||||
fuse_dirents_t *buf_)
|
fuse_dirents_t *buf_)
|
||||||
{
|
{
|
||||||
DirInfo *di = reinterpret_cast<DirInfo*>(ffi_->fh);
|
DirInfo *di = DirInfo::from_fh(ffi_->fh);
|
||||||
const fuse_context *fc = fuse_get_context();
|
const fuse_context *fc = fuse_get_context();
|
||||||
|
|
||||||
return l::concurrent_readdir(_tp,
|
return ::_concurrent_readdir(_tp,
|
||||||
cfg.branches,
|
cfg.branches,
|
||||||
di->fusepath,
|
di->fusepath,
|
||||||
buf_,
|
buf_,
|
||||||
|
|
|
||||||
|
|
@ -45,175 +45,173 @@ FUSE::ReadDirCOSR::~ReadDirCOSR()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace l
|
struct DirRV
|
||||||
{
|
{
|
||||||
struct DirRV
|
const std::string *branch_path;
|
||||||
|
DIR *dir;
|
||||||
|
int err;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Error
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
int _err;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Error()
|
||||||
|
: _err(ENOENT)
|
||||||
{
|
{
|
||||||
const std::string *branch_path;
|
|
||||||
DIR *dir;
|
|
||||||
int err;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Error
|
}
|
||||||
|
|
||||||
|
operator int()
|
||||||
{
|
{
|
||||||
private:
|
return _err;
|
||||||
int _err;
|
}
|
||||||
|
|
||||||
public:
|
Error&
|
||||||
Error()
|
operator=(int const v_)
|
||||||
: _err(ENOENT)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
operator int()
|
|
||||||
{
|
|
||||||
return _err;
|
|
||||||
}
|
|
||||||
|
|
||||||
Error&
|
|
||||||
operator=(int const v_)
|
|
||||||
{
|
|
||||||
if(_err != 0)
|
|
||||||
_err = v_;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static
|
|
||||||
uint64_t
|
|
||||||
dirent_exact_namelen(const struct dirent *d_)
|
|
||||||
{
|
{
|
||||||
|
if(_err != 0)
|
||||||
|
_err = v_;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static
|
||||||
|
uint64_t
|
||||||
|
_dirent_exact_namelen(const struct dirent *d_)
|
||||||
|
{
|
||||||
#ifdef _D_EXACT_NAMLEN
|
#ifdef _D_EXACT_NAMLEN
|
||||||
return _D_EXACT_NAMLEN(d_);
|
return _D_EXACT_NAMLEN(d_);
|
||||||
#elif defined _DIRENT_HAVE_D_NAMLEN
|
#elif defined _DIRENT_HAVE_D_NAMLEN
|
||||||
return d_->d_namlen;
|
return d_->d_namlen;
|
||||||
#else
|
#else
|
||||||
return strlen(d_->d_name);
|
return strlen(d_->d_name);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
inline
|
inline
|
||||||
std::vector<std::future<DirRV>>
|
std::vector<std::future<DirRV>>
|
||||||
opendir(ThreadPool &tp_,
|
_opendir(ThreadPool &tp_,
|
||||||
const Branches::Ptr &branches_,
|
const Branches::Ptr &branches_,
|
||||||
const std::string &rel_dirpath_,
|
const fs::path &rel_dirpath_,
|
||||||
uid_t const uid_,
|
uid_t const uid_,
|
||||||
gid_t const gid_)
|
gid_t const gid_)
|
||||||
{
|
{
|
||||||
std::vector<std::future<DirRV>> futures;
|
std::vector<std::future<DirRV>> futures;
|
||||||
|
|
||||||
futures.reserve(branches_->size());
|
futures.reserve(branches_->size());
|
||||||
|
|
||||||
for(const auto &branch : *branches_)
|
for(const auto &branch : *branches_)
|
||||||
{
|
{
|
||||||
auto func =
|
auto func =
|
||||||
[&branch,&rel_dirpath_,uid_,gid_]()
|
[&branch,&rel_dirpath_,uid_,gid_]()
|
||||||
{
|
{
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
std::string abs_dirpath;
|
fs::path abs_dirpath;
|
||||||
const ugid::Set ugid(uid_,gid_);
|
const ugid::Set ugid(uid_,gid_);
|
||||||
|
|
||||||
abs_dirpath = fs::path::make(branch.path,rel_dirpath_);
|
abs_dirpath = branch.path / rel_dirpath_;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
dir = fs::opendir(abs_dirpath);
|
dir = fs::opendir(abs_dirpath);
|
||||||
|
|
||||||
return DirRV{&branch.path,dir,errno};
|
return DirRV{&branch.path,dir,errno};
|
||||||
};
|
};
|
||||||
|
|
||||||
auto rv = tp_.enqueue_task(std::move(func));
|
auto rv = tp_.enqueue_task(std::move(func));
|
||||||
|
|
||||||
futures.emplace_back(std::move(rv));
|
futures.emplace_back(std::move(rv));
|
||||||
}
|
}
|
||||||
|
|
||||||
return futures;
|
return futures;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
inline
|
inline
|
||||||
int
|
int
|
||||||
readdir(std::vector<std::future<DirRV>> &dh_futures_,
|
_readdir(std::vector<std::future<DirRV>> &dh_futures_,
|
||||||
const std::string &rel_dirpath_,
|
const fs::path &rel_dirpath_,
|
||||||
fuse_dirents_t *buf_)
|
fuse_dirents_t *buf_)
|
||||||
{
|
{
|
||||||
Error error;
|
Error error;
|
||||||
HashSet names;
|
HashSet names;
|
||||||
std::string rel_filepath;
|
fs::path rel_filepath;
|
||||||
|
|
||||||
for(auto &dh_future : dh_futures_)
|
rel_filepath = rel_dirpath_ / "dummy";
|
||||||
{
|
for(auto &dh_future : dh_futures_)
|
||||||
int rv;
|
{
|
||||||
DirRV dirrv;
|
int rv;
|
||||||
|
DirRV dirrv;
|
||||||
|
|
||||||
dirrv = dh_future.get();
|
dirrv = dh_future.get();
|
||||||
|
|
||||||
error = dirrv.err;
|
error = dirrv.err;
|
||||||
if(dirrv.dir == NULL)
|
if(dirrv.dir == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
DEFER { fs::closedir(dirrv.dir); };
|
DEFER { fs::closedir(dirrv.dir); };
|
||||||
|
|
||||||
rv = 0;
|
rv = 0;
|
||||||
for(dirent *de = fs::readdir(dirrv.dir); de && !rv; de = fs::readdir(dirrv.dir))
|
for(dirent *de = fs::readdir(dirrv.dir); de && !rv; de = fs::readdir(dirrv.dir))
|
||||||
{
|
{
|
||||||
std::uint64_t namelen;
|
std::uint64_t namelen;
|
||||||
|
|
||||||
namelen = l::dirent_exact_namelen(de);
|
namelen = ::_dirent_exact_namelen(de);
|
||||||
|
|
||||||
rv = names.put(de->d_name,namelen);
|
rv = names.put(de->d_name,namelen);
|
||||||
if(rv == 0)
|
if(rv == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
rel_filepath = fs::path::make(rel_dirpath_,de->d_name);
|
rel_filepath.replace_filename(de->d_name);
|
||||||
de->d_ino = fs::inode::calc(*dirrv.branch_path,
|
de->d_ino = fs::inode::calc(*dirrv.branch_path,
|
||||||
rel_filepath,
|
rel_filepath,
|
||||||
DTTOIF(de->d_type),
|
DTTOIF(de->d_type),
|
||||||
de->d_ino);
|
de->d_ino);
|
||||||
|
|
||||||
rv = fuse_dirents_add(buf_,de,namelen);
|
rv = fuse_dirents_add(buf_,de,namelen);
|
||||||
if(rv == 0)
|
if(rv == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
error = ENOMEM;
|
error = ENOMEM;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return -error;
|
return -error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
inline
|
inline
|
||||||
int
|
int
|
||||||
readdir(ThreadPool &tp_,
|
_readdir(ThreadPool &tp_,
|
||||||
const Branches::Ptr &branches_,
|
const Branches::Ptr &branches_,
|
||||||
const std::string &rel_dirpath_,
|
const fs::path &rel_dirpath_,
|
||||||
fuse_dirents_t *buf_,
|
fuse_dirents_t *buf_,
|
||||||
uid_t const uid_,
|
uid_t const uid_,
|
||||||
gid_t const gid_)
|
gid_t const gid_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
std::vector<std::future<DirRV>> futures;
|
std::vector<std::future<DirRV>> futures;
|
||||||
|
|
||||||
fuse_dirents_reset(buf_);
|
fuse_dirents_reset(buf_);
|
||||||
|
|
||||||
futures = l::opendir(tp_,branches_,rel_dirpath_,uid_,gid_);
|
futures = ::_opendir(tp_,branches_,rel_dirpath_,uid_,gid_);
|
||||||
rv = l::readdir(futures,rel_dirpath_,buf_);
|
rv = ::_readdir(futures,rel_dirpath_,buf_);
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
FUSE::ReadDirCOSR::operator()(fuse_file_info_t const *ffi_,
|
FUSE::ReadDirCOSR::operator()(fuse_file_info_t const *ffi_,
|
||||||
fuse_dirents_t *buf_)
|
fuse_dirents_t *buf_)
|
||||||
{
|
{
|
||||||
DirInfo *di = reinterpret_cast<DirInfo*>(ffi_->fh);
|
DirInfo *di = DirInfo::from_fh(ffi_->fh);
|
||||||
const fuse_context *fc = fuse_get_context();
|
const fuse_context *fc = fuse_get_context();
|
||||||
|
|
||||||
return l::readdir(_tp,
|
return ::_readdir(_tp,
|
||||||
cfg.branches,
|
cfg.branches,
|
||||||
di->fusepath,
|
di->fusepath,
|
||||||
buf_,
|
buf_,
|
||||||
|
|
|
||||||
|
|
@ -56,22 +56,23 @@ _dirent_exact_namelen(const struct dirent *d_)
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_readdir(const Branches::Ptr &branches_,
|
_readdir(const Branches::Ptr &branches_,
|
||||||
const std::string &rel_dirpath_,
|
const fs::path &rel_dirpath_,
|
||||||
fuse_dirents_t *buf_)
|
fuse_dirents_t *buf_)
|
||||||
{
|
{
|
||||||
Err err;
|
Err err;
|
||||||
HashSet names;
|
HashSet names;
|
||||||
std::string rel_filepath;
|
fs::path rel_filepath;
|
||||||
std::string abs_dirpath;
|
fs::path abs_dirpath;
|
||||||
|
|
||||||
fuse_dirents_reset(buf_);
|
fuse_dirents_reset(buf_);
|
||||||
|
|
||||||
|
rel_filepath = rel_dirpath_ / "dummy";
|
||||||
for(const auto &branch : *branches_)
|
for(const auto &branch : *branches_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
DIR *dh;
|
DIR *dh;
|
||||||
|
|
||||||
abs_dirpath = fs::path::make(branch.path,rel_dirpath_);
|
abs_dirpath = branch.path / rel_dirpath_;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
dh = fs::opendir(abs_dirpath);
|
dh = fs::opendir(abs_dirpath);
|
||||||
|
|
@ -92,7 +93,7 @@ _readdir(const Branches::Ptr &branches_,
|
||||||
if(rv == 0)
|
if(rv == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
rel_filepath = fs::path::make(rel_dirpath_,de->d_name);
|
rel_filepath.replace_filename(de->d_name);
|
||||||
de->d_ino = fs::inode::calc(branch.path,
|
de->d_ino = fs::inode::calc(branch.path,
|
||||||
rel_filepath,
|
rel_filepath,
|
||||||
DTTOIF(de->d_type),
|
DTTOIF(de->d_type),
|
||||||
|
|
@ -111,7 +112,7 @@ int
|
||||||
FUSE::ReadDirSeq::operator()(fuse_file_info_t const *ffi_,
|
FUSE::ReadDirSeq::operator()(fuse_file_info_t const *ffi_,
|
||||||
fuse_dirents_t *buf_)
|
fuse_dirents_t *buf_)
|
||||||
{
|
{
|
||||||
DirInfo *di = reinterpret_cast<DirInfo*>(ffi_->fh);
|
DirInfo *di = DirInfo::from_fh(ffi_->fh);
|
||||||
const fuse_context *fc = fuse_get_context();
|
const fuse_context *fc = fuse_get_context();
|
||||||
const ugid::Set ugid(fc->uid,fc->gid);
|
const ugid::Set ugid(fc->uid,fc->gid);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,16 +26,14 @@
|
||||||
|
|
||||||
#include "fuse.h"
|
#include "fuse.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <cstring>
|
||||||
|
|
||||||
using std::string;
|
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_readlink_core_standard(const string &fullpath_,
|
_readlink_core_standard(const fs::path &fullpath_,
|
||||||
char *buf_,
|
char *buf_,
|
||||||
const size_t size_)
|
const size_t size_)
|
||||||
|
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
|
@ -51,10 +49,10 @@ _readlink_core_standard(const string &fullpath_,
|
||||||
|
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_readlink_core_symlinkify(const string &fullpath_,
|
_readlink_core_symlinkify(const fs::path &fullpath_,
|
||||||
char *buf_,
|
char *buf_,
|
||||||
const size_t size_,
|
const size_t size_,
|
||||||
const time_t symlinkify_timeout_)
|
const time_t symlinkify_timeout_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
@ -73,16 +71,16 @@ _readlink_core_symlinkify(const string &fullpath_,
|
||||||
|
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_readlink_core(const string &basepath_,
|
_readlink_core(const fs::path &basepath_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
char *buf_,
|
char *buf_,
|
||||||
const size_t size_,
|
const size_t size_,
|
||||||
const bool symlinkify_,
|
const bool symlinkify_,
|
||||||
const time_t symlinkify_timeout_)
|
const time_t symlinkify_timeout_)
|
||||||
{
|
{
|
||||||
string fullpath;
|
fs::path fullpath;
|
||||||
|
|
||||||
fullpath = fs::path::make(basepath_,fusepath_);
|
fullpath = basepath_ / fusepath_;
|
||||||
|
|
||||||
if(symlinkify_)
|
if(symlinkify_)
|
||||||
return ::_readlink_core_symlinkify(fullpath,buf_,size_,symlinkify_timeout_);
|
return ::_readlink_core_symlinkify(fullpath,buf_,size_,symlinkify_timeout_);
|
||||||
|
|
@ -94,7 +92,7 @@ static
|
||||||
int
|
int
|
||||||
_readlink(const Policy::Search &searchFunc_,
|
_readlink(const Policy::Search &searchFunc_,
|
||||||
const Branches &ibranches_,
|
const Branches &ibranches_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
char *buf_,
|
char *buf_,
|
||||||
const size_t size_,
|
const size_t size_,
|
||||||
const bool symlinkify_,
|
const bool symlinkify_,
|
||||||
|
|
@ -121,12 +119,13 @@ FUSE::readlink(const char *fusepath_,
|
||||||
char *buf_,
|
char *buf_,
|
||||||
size_t size_)
|
size_t size_)
|
||||||
{
|
{
|
||||||
|
const fs::path fusepath{fusepath_};
|
||||||
const fuse_context *fc = fuse_get_context();
|
const fuse_context *fc = fuse_get_context();
|
||||||
const ugid::Set ugid(fc->uid,fc->gid);
|
const ugid::Set ugid(fc->uid,fc->gid);
|
||||||
|
|
||||||
return ::_readlink(cfg.func.readlink.policy,
|
return ::_readlink(cfg.func.readlink.policy,
|
||||||
cfg.branches,
|
cfg.branches,
|
||||||
fusepath_,
|
fusepath,
|
||||||
buf_,
|
buf_,
|
||||||
size_,
|
size_,
|
||||||
cfg.symlinkify,
|
cfg.symlinkify,
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ int
|
||||||
_release(const fuse_context *fc_,
|
_release(const fuse_context *fc_,
|
||||||
const fuse_file_info_t *ffi_)
|
const fuse_file_info_t *ffi_)
|
||||||
{
|
{
|
||||||
FileInfo *fi = reinterpret_cast<FileInfo*>(ffi_->fh);
|
FileInfo *fi = FileInfo::from_fh(ffi_->fh);
|
||||||
|
|
||||||
return ::_release(fc_,fi,cfg.dropcacheonclose);
|
return ::_release(fc_,fi,cfg.dropcacheonclose);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ _releasedir(DirInfo *di_)
|
||||||
int
|
int
|
||||||
FUSE::releasedir(const fuse_file_info_t *ffi_)
|
FUSE::releasedir(const fuse_file_info_t *ffi_)
|
||||||
{
|
{
|
||||||
DirInfo *di = reinterpret_cast<DirInfo*>(ffi_->fh);
|
DirInfo *di = DirInfo::from_fh(ffi_->fh);
|
||||||
|
|
||||||
return ::_releasedir(di);
|
return ::_releasedir(di);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,23 +25,19 @@
|
||||||
|
|
||||||
#include "fuse.h"
|
#include "fuse.h"
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
using std::string;
|
|
||||||
using std::vector;
|
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
void
|
void
|
||||||
_removexattr_loop_core(const string &basepath_,
|
_removexattr_loop_core(const fs::path &basepath_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
const char *attrname_,
|
const char *attrname_,
|
||||||
PolicyRV *prv_)
|
PolicyRV *prv_)
|
||||||
{
|
{
|
||||||
string fullpath;
|
fs::path fullpath;
|
||||||
|
|
||||||
fullpath = fs::path::make(basepath_,fusepath_);
|
fullpath = basepath_ / fusepath_;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
fs::lremovexattr(fullpath,attrname_);
|
fs::lremovexattr(fullpath,attrname_);
|
||||||
|
|
@ -52,7 +48,7 @@ _removexattr_loop_core(const string &basepath_,
|
||||||
static
|
static
|
||||||
void
|
void
|
||||||
_removexattr_loop(const std::vector<Branch*> &branches_,
|
_removexattr_loop(const std::vector<Branch*> &branches_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
const char *attrname_,
|
const char *attrname_,
|
||||||
PolicyRV *prv_)
|
PolicyRV *prv_)
|
||||||
{
|
{
|
||||||
|
|
@ -67,7 +63,7 @@ int
|
||||||
_removexattr(const Policy::Action &actionFunc_,
|
_removexattr(const Policy::Action &actionFunc_,
|
||||||
const Policy::Search &searchFunc_,
|
const Policy::Search &searchFunc_,
|
||||||
const Branches &ibranches_,
|
const Branches &ibranches_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
const char *attrname_)
|
const char *attrname_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
|
@ -96,7 +92,9 @@ int
|
||||||
FUSE::removexattr(const char *fusepath_,
|
FUSE::removexattr(const char *fusepath_,
|
||||||
const char *attrname_)
|
const char *attrname_)
|
||||||
{
|
{
|
||||||
if(Config::is_ctrl_file(fusepath_))
|
const fs::path fusepath{fusepath_};
|
||||||
|
|
||||||
|
if(Config::is_ctrl_file(fusepath))
|
||||||
return -ENOATTR;
|
return -ENOATTR;
|
||||||
|
|
||||||
if(cfg.xattr.to_int())
|
if(cfg.xattr.to_int())
|
||||||
|
|
@ -108,6 +106,6 @@ FUSE::removexattr(const char *fusepath_,
|
||||||
return ::_removexattr(cfg.func.removexattr.policy,
|
return ::_removexattr(cfg.func.removexattr.policy,
|
||||||
cfg.func.getxattr.policy,
|
cfg.func.getxattr.policy,
|
||||||
cfg.branches,
|
cfg.branches,
|
||||||
fusepath_,
|
fusepath,
|
||||||
attrname_);
|
attrname_);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,12 +31,10 @@
|
||||||
#include "ugid.hpp"
|
#include "ugid.hpp"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <filesystem>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace stdfs = std::filesystem;
|
|
||||||
|
|
||||||
static
|
static
|
||||||
bool
|
bool
|
||||||
|
|
@ -70,19 +68,19 @@ _remove(const StrVec &toremove_)
|
||||||
|
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_rename_create_path(const Policy::Search &searchPolicy_,
|
_rename_create_path(const Policy::Search &searchPolicy_,
|
||||||
const Policy::Action &actionPolicy_,
|
const Policy::Action &actionPolicy_,
|
||||||
const Branches::Ptr &branches_,
|
const Branches::Ptr &branches_,
|
||||||
const stdfs::path &oldfusepath_,
|
const fs::path &oldfusepath_,
|
||||||
const stdfs::path &newfusepath_)
|
const fs::path &newfusepath_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
Err err;
|
Err err;
|
||||||
StrVec toremove;
|
StrVec toremove;
|
||||||
std::vector<Branch*> newbranches;
|
std::vector<Branch*> newbranches;
|
||||||
std::vector<Branch*> oldbranches;
|
std::vector<Branch*> oldbranches;
|
||||||
stdfs::path oldfullpath;
|
fs::path oldfullpath;
|
||||||
stdfs::path newfullpath;
|
fs::path newfullpath;
|
||||||
|
|
||||||
rv = actionPolicy_(branches_,oldfusepath_,oldbranches);
|
rv = actionPolicy_(branches_,oldfusepath_,oldbranches);
|
||||||
if(rv < 0)
|
if(rv < 0)
|
||||||
|
|
@ -129,17 +127,17 @@ _rename_create_path(const Policy::Search &searchPolicy_,
|
||||||
|
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_rename_preserve_path(const Policy::Action &actionPolicy_,
|
_rename_preserve_path(const Policy::Action &actionPolicy_,
|
||||||
const Branches::Ptr &branches_,
|
const Branches::Ptr &branches_,
|
||||||
const stdfs::path &oldfusepath_,
|
const fs::path &oldfusepath_,
|
||||||
const stdfs::path &newfusepath_)
|
const fs::path &newfusepath_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
bool success;
|
bool success;
|
||||||
StrVec toremove;
|
StrVec toremove;
|
||||||
std::vector<Branch*> oldbranches;
|
std::vector<Branch*> oldbranches;
|
||||||
stdfs::path oldfullpath;
|
fs::path oldfullpath;
|
||||||
stdfs::path newfullpath;
|
fs::path newfullpath;
|
||||||
|
|
||||||
rv = actionPolicy_(branches_,oldfusepath_,oldbranches);
|
rv = actionPolicy_(branches_,oldfusepath_,oldbranches);
|
||||||
if(rv < 0)
|
if(rv < 0)
|
||||||
|
|
@ -181,11 +179,11 @@ _rename_preserve_path(const Policy::Action &actionPolicy_,
|
||||||
|
|
||||||
static
|
static
|
||||||
void
|
void
|
||||||
_rename_exdev_rename_back(const std::vector<Branch*> &branches_,
|
_rename_exdev_rename_back(const std::vector<Branch*> &branches_,
|
||||||
const stdfs::path &oldfusepath_)
|
const fs::path &oldfusepath_)
|
||||||
{
|
{
|
||||||
stdfs::path oldpath;
|
fs::path oldpath;
|
||||||
stdfs::path newpath;
|
fs::path newpath;
|
||||||
|
|
||||||
for(auto &branch : branches_)
|
for(auto &branch : branches_)
|
||||||
{
|
{
|
||||||
|
|
@ -202,14 +200,14 @@ _rename_exdev_rename_back(const std::vector<Branch*> &branches_,
|
||||||
|
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_rename_exdev_rename_target(const Policy::Action &actionPolicy_,
|
_rename_exdev_rename_target(const Policy::Action &actionPolicy_,
|
||||||
const Branches::Ptr &ibranches_,
|
const Branches::Ptr &ibranches_,
|
||||||
const stdfs::path &oldfusepath_,
|
const fs::path &oldfusepath_,
|
||||||
std::vector<Branch*> &obranches_)
|
std::vector<Branch*> &obranches_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
stdfs::path clonesrc;
|
fs::path clonesrc;
|
||||||
stdfs::path clonetgt;
|
fs::path clonetgt;
|
||||||
|
|
||||||
rv = actionPolicy_(ibranches_,oldfusepath_,obranches_);
|
rv = actionPolicy_(ibranches_,oldfusepath_,obranches_);
|
||||||
if(rv < 0)
|
if(rv < 0)
|
||||||
|
|
@ -250,14 +248,14 @@ _rename_exdev_rename_target(const Policy::Action &actionPolicy_,
|
||||||
|
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_rename_exdev_rel_symlink(const Policy::Action &actionPolicy_,
|
_rename_exdev_rel_symlink(const Policy::Action &actionPolicy_,
|
||||||
const Branches::Ptr &branches_,
|
const Branches::Ptr &branches_,
|
||||||
const stdfs::path &oldfusepath_,
|
const fs::path &oldfusepath_,
|
||||||
const stdfs::path &newfusepath_)
|
const fs::path &newfusepath_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
stdfs::path target;
|
fs::path target;
|
||||||
stdfs::path linkpath;
|
fs::path linkpath;
|
||||||
std::vector<Branch*> branches;
|
std::vector<Branch*> branches;
|
||||||
|
|
||||||
rv = ::_rename_exdev_rename_target(actionPolicy_,branches_,oldfusepath_,branches);
|
rv = ::_rename_exdev_rename_target(actionPolicy_,branches_,oldfusepath_,branches);
|
||||||
|
|
@ -269,7 +267,7 @@ _rename_exdev_rel_symlink(const Policy::Action &actionPolicy_,
|
||||||
target += oldfusepath_;
|
target += oldfusepath_;
|
||||||
target = target.lexically_relative(linkpath.parent_path());
|
target = target.lexically_relative(linkpath.parent_path());
|
||||||
|
|
||||||
rv = FUSE::symlink(target.c_str(),linkpath.c_str());
|
rv = FUSE::symlink(target.c_str(),linkpath);
|
||||||
if(rv < 0)
|
if(rv < 0)
|
||||||
::_rename_exdev_rename_back(branches,oldfusepath_);
|
::_rename_exdev_rename_back(branches,oldfusepath_);
|
||||||
|
|
||||||
|
|
@ -278,15 +276,15 @@ _rename_exdev_rel_symlink(const Policy::Action &actionPolicy_,
|
||||||
|
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_rename_exdev_abs_symlink(const Policy::Action &actionPolicy_,
|
_rename_exdev_abs_symlink(const Policy::Action &actionPolicy_,
|
||||||
const Branches::Ptr &branches_,
|
const Branches::Ptr &branches_,
|
||||||
const stdfs::path &mount_,
|
const fs::path &mount_,
|
||||||
const stdfs::path &oldfusepath_,
|
const fs::path &oldfusepath_,
|
||||||
const stdfs::path &newfusepath_)
|
const fs::path &newfusepath_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
stdfs::path target;
|
fs::path target;
|
||||||
stdfs::path linkpath;
|
fs::path linkpath;
|
||||||
std::vector<Branch*> branches;
|
std::vector<Branch*> branches;
|
||||||
|
|
||||||
rv = ::_rename_exdev_rename_target(actionPolicy_,branches_,oldfusepath_,branches);
|
rv = ::_rename_exdev_rename_target(actionPolicy_,branches_,oldfusepath_,branches);
|
||||||
|
|
@ -298,7 +296,7 @@ _rename_exdev_abs_symlink(const Policy::Action &actionPolicy_,
|
||||||
target /= ".mergerfs_rename_exdev";
|
target /= ".mergerfs_rename_exdev";
|
||||||
target += oldfusepath_;
|
target += oldfusepath_;
|
||||||
|
|
||||||
rv = FUSE::symlink(target.c_str(),linkpath.c_str());
|
rv = FUSE::symlink(target.c_str(),linkpath);
|
||||||
if(rv < 0)
|
if(rv < 0)
|
||||||
::_rename_exdev_rename_back(branches,oldfusepath_);
|
::_rename_exdev_rename_back(branches,oldfusepath_);
|
||||||
|
|
||||||
|
|
@ -307,9 +305,9 @@ _rename_exdev_abs_symlink(const Policy::Action &actionPolicy_,
|
||||||
|
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_rename_exdev(Config &cfg_,
|
_rename_exdev(Config &cfg_,
|
||||||
const stdfs::path &oldfusepath_,
|
const fs::path &oldfusepath_,
|
||||||
const stdfs::path &newfusepath_)
|
const fs::path &newfusepath_)
|
||||||
{
|
{
|
||||||
switch(cfg_.rename_exdev)
|
switch(cfg_.rename_exdev)
|
||||||
{
|
{
|
||||||
|
|
@ -333,9 +331,9 @@ _rename_exdev(Config &cfg_,
|
||||||
|
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_rename(Config &cfg_,
|
_rename(Config &cfg_,
|
||||||
const stdfs::path &oldpath_,
|
const fs::path &oldpath_,
|
||||||
const stdfs::path &newpath_)
|
const fs::path &newpath_)
|
||||||
{
|
{
|
||||||
if(cfg_.func.create.policy.path_preserving() && !cfg_.ignorepponrename)
|
if(cfg_.func.create.policy.path_preserving() && !cfg_.ignorepponrename)
|
||||||
return ::_rename_preserve_path(cfg_.func.rename.policy,
|
return ::_rename_preserve_path(cfg_.func.rename.policy,
|
||||||
|
|
@ -355,8 +353,8 @@ FUSE::rename(const char *oldfusepath_,
|
||||||
const char *newfusepath_)
|
const char *newfusepath_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
stdfs::path oldfusepath(oldfusepath_);
|
const fs::path oldfusepath{oldfusepath_};
|
||||||
stdfs::path newfusepath(newfusepath_);
|
const fs::path newfusepath{newfusepath_};
|
||||||
const fuse_context *fc = fuse_get_context();
|
const fuse_context *fc = fuse_get_context();
|
||||||
const ugid::Set ugid(fc->uid,fc->gid);
|
const ugid::Set ugid(fc->uid,fc->gid);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,9 +30,6 @@
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
using std::string;
|
|
||||||
using std::vector;
|
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
|
|
@ -45,14 +42,14 @@ _should_unlink(int rv_,
|
||||||
|
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_rmdir_core(const string &basepath_,
|
_rmdir_core(const fs::path &basepath_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
const FollowSymlinks followsymlinks_)
|
const FollowSymlinks followsymlinks_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
string fullpath;
|
fs::path fullpath;
|
||||||
|
|
||||||
fullpath = fs::path::make(basepath_,fusepath_);
|
fullpath = basepath_ / fusepath_;
|
||||||
|
|
||||||
rv = fs::rmdir(fullpath);
|
rv = fs::rmdir(fullpath);
|
||||||
if(::_should_unlink(rv,followsymlinks_))
|
if(::_should_unlink(rv,followsymlinks_))
|
||||||
|
|
@ -64,7 +61,7 @@ _rmdir_core(const string &basepath_,
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_rmdir_loop(const std::vector<Branch*> &branches_,
|
_rmdir_loop(const std::vector<Branch*> &branches_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
const FollowSymlinks followsymlinks_)
|
const FollowSymlinks followsymlinks_)
|
||||||
{
|
{
|
||||||
Err err;
|
Err err;
|
||||||
|
|
@ -82,7 +79,7 @@ int
|
||||||
_rmdir(const Policy::Action &actionFunc_,
|
_rmdir(const Policy::Action &actionFunc_,
|
||||||
const Branches &branches_,
|
const Branches &branches_,
|
||||||
const FollowSymlinks followsymlinks_,
|
const FollowSymlinks followsymlinks_,
|
||||||
const char *fusepath_)
|
const fs::path &fusepath_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
std::vector<Branch*> branches;
|
std::vector<Branch*> branches;
|
||||||
|
|
@ -97,11 +94,12 @@ _rmdir(const Policy::Action &actionFunc_,
|
||||||
int
|
int
|
||||||
FUSE::rmdir(const char *fusepath_)
|
FUSE::rmdir(const char *fusepath_)
|
||||||
{
|
{
|
||||||
|
const fs::path fusepath{fusepath_};
|
||||||
const fuse_context *fc = fuse_get_context();
|
const fuse_context *fc = fuse_get_context();
|
||||||
const ugid::Set ugid(fc->uid,fc->gid);
|
const ugid::Set ugid(fc->uid,fc->gid);
|
||||||
|
|
||||||
return ::_rmdir(cfg.func.rmdir.policy,
|
return ::_rmdir(cfg.func.rmdir.policy,
|
||||||
cfg.branches,
|
cfg.branches,
|
||||||
cfg.follow_symlinks,
|
cfg.follow_symlinks,
|
||||||
fusepath_);
|
fusepath);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,11 +31,10 @@
|
||||||
|
|
||||||
#include "fuse.h"
|
#include "fuse.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
static const char SECURITY_CAPABILITY[] = "security.capability";
|
static const char SECURITY_CAPABILITY[] = "security.capability";
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -107,17 +106,17 @@ _setxattr_ctrl_file(const char *attrname_,
|
||||||
|
|
||||||
static
|
static
|
||||||
void
|
void
|
||||||
_setxattr_loop_core(const std::string &basepath_,
|
_setxattr_loop_core(const fs::path &basepath_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
const char *attrname_,
|
const char *attrname_,
|
||||||
const char *attrval_,
|
const char *attrval_,
|
||||||
const size_t attrvalsize_,
|
const size_t attrvalsize_,
|
||||||
const int flags_,
|
const int flags_,
|
||||||
PolicyRV *prv_)
|
PolicyRV *prv_)
|
||||||
{
|
{
|
||||||
std::string fullpath;
|
fs::path fullpath;
|
||||||
|
|
||||||
fullpath = fs::path::make(basepath_,fusepath_);
|
fullpath = basepath_ / fusepath_;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
fs::lsetxattr(fullpath,attrname_,attrval_,attrvalsize_,flags_);
|
fs::lsetxattr(fullpath,attrname_,attrval_,attrvalsize_,flags_);
|
||||||
|
|
@ -128,7 +127,7 @@ _setxattr_loop_core(const std::string &basepath_,
|
||||||
static
|
static
|
||||||
void
|
void
|
||||||
_setxattr_loop(const std::vector<Branch*> &branches_,
|
_setxattr_loop(const std::vector<Branch*> &branches_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
const char *attrname_,
|
const char *attrname_,
|
||||||
const char *attrval_,
|
const char *attrval_,
|
||||||
const size_t attrvalsize_,
|
const size_t attrvalsize_,
|
||||||
|
|
@ -151,7 +150,7 @@ int
|
||||||
_setxattr(const Policy::Action &setxattrPolicy_,
|
_setxattr(const Policy::Action &setxattrPolicy_,
|
||||||
const Policy::Search &getxattrPolicy_,
|
const Policy::Search &getxattrPolicy_,
|
||||||
const Branches &branches_,
|
const Branches &branches_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
const char *attrname_,
|
const char *attrname_,
|
||||||
const char *attrval_,
|
const char *attrval_,
|
||||||
const size_t attrvalsize_,
|
const size_t attrvalsize_,
|
||||||
|
|
@ -181,11 +180,11 @@ _setxattr(const Policy::Action &setxattrPolicy_,
|
||||||
|
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_setxattr(const char *fusepath_,
|
_setxattr(const fs::path &fusepath_,
|
||||||
const char *attrname_,
|
const char *attrname_,
|
||||||
const char *attrval_,
|
const char *attrval_,
|
||||||
size_t attrvalsize_,
|
size_t attrvalsize_,
|
||||||
int flags_)
|
int flags_)
|
||||||
{
|
{
|
||||||
if((cfg.security_capability == false) &&
|
if((cfg.security_capability == false) &&
|
||||||
::_is_attrname_security_capability(attrname_))
|
::_is_attrname_security_capability(attrname_))
|
||||||
|
|
@ -215,11 +214,13 @@ FUSE::setxattr(const char *fusepath_,
|
||||||
size_t attrvalsize_,
|
size_t attrvalsize_,
|
||||||
int flags_)
|
int flags_)
|
||||||
{
|
{
|
||||||
if(Config::is_ctrl_file(fusepath_))
|
const fs::path fusepath{fusepath_};
|
||||||
|
|
||||||
|
if(Config::is_ctrl_file(fusepath))
|
||||||
return ::_setxattr_ctrl_file(attrname_,
|
return ::_setxattr_ctrl_file(attrname_,
|
||||||
attrval_,
|
attrval_,
|
||||||
attrvalsize_,
|
attrvalsize_,
|
||||||
flags_);
|
flags_);
|
||||||
|
|
||||||
return ::_setxattr(fusepath_,attrname_,attrval_,attrvalsize_,flags_);
|
return ::_setxattr(fusepath,attrname_,attrval_,attrvalsize_,flags_);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,16 +26,12 @@
|
||||||
|
|
||||||
#include "fuse.h"
|
#include "fuse.h"
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
using std::string;
|
|
||||||
using std::map;
|
|
||||||
using std::vector;
|
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
void
|
void
|
||||||
|
|
@ -80,28 +76,29 @@ _should_ignore(const StatFSIgnore ignore_,
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_statfs(const Branches::Ptr &branches_,
|
_statfs(const Branches::Ptr &branches_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
const StatFS mode_,
|
const StatFS mode_,
|
||||||
const StatFSIgnore ignore_,
|
const StatFSIgnore ignore_,
|
||||||
struct statvfs *fsstat_)
|
struct statvfs *fsstat_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
string fullpath;
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
struct statvfs stvfs;
|
struct statvfs stvfs;
|
||||||
unsigned long min_bsize;
|
unsigned long min_bsize;
|
||||||
unsigned long min_frsize;
|
unsigned long min_frsize;
|
||||||
unsigned long min_namemax;
|
unsigned long min_namemax;
|
||||||
map<dev_t,struct statvfs> fsstats;
|
std::map<dev_t,struct statvfs> fsstats;
|
||||||
|
fs::path fullpath;
|
||||||
|
|
||||||
min_bsize = std::numeric_limits<unsigned long>::max();
|
min_bsize = std::numeric_limits<unsigned long>::max();
|
||||||
min_frsize = std::numeric_limits<unsigned long>::max();
|
min_frsize = std::numeric_limits<unsigned long>::max();
|
||||||
min_namemax = std::numeric_limits<unsigned long>::max();
|
min_namemax = std::numeric_limits<unsigned long>::max();
|
||||||
for(const auto &branch : *branches_)
|
for(const auto &branch : *branches_)
|
||||||
{
|
{
|
||||||
fullpath = ((mode_ == StatFS::ENUM::FULL) ?
|
if(mode_ == StatFS::ENUM::FULL)
|
||||||
fs::path::make(branch.path,fusepath_) :
|
fullpath = branch.path / fusepath_;
|
||||||
branch.path);
|
else
|
||||||
|
fullpath = branch.path;
|
||||||
|
|
||||||
rv = fs::lstat(fullpath,&st);
|
rv = fs::lstat(fullpath,&st);
|
||||||
if(rv < 0)
|
if(rv < 0)
|
||||||
|
|
@ -127,8 +124,8 @@ _statfs(const Branches::Ptr &branches_,
|
||||||
fsstats.insert(std::make_pair(st.st_dev,stvfs));
|
fsstats.insert(std::make_pair(st.st_dev,stvfs));
|
||||||
}
|
}
|
||||||
|
|
||||||
map<dev_t,struct statvfs>::iterator iter = fsstats.begin();
|
std::map<dev_t,struct statvfs>::iterator iter = fsstats.begin();
|
||||||
map<dev_t,struct statvfs>::iterator enditer = fsstats.end();
|
std::map<dev_t,struct statvfs>::iterator enditer = fsstats.end();
|
||||||
if(iter != enditer)
|
if(iter != enditer)
|
||||||
{
|
{
|
||||||
*fsstat_ = iter->second;
|
*fsstat_ = iter->second;
|
||||||
|
|
@ -148,11 +145,12 @@ int
|
||||||
FUSE::statfs(const char *fusepath_,
|
FUSE::statfs(const char *fusepath_,
|
||||||
struct statvfs *st_)
|
struct statvfs *st_)
|
||||||
{
|
{
|
||||||
|
const fs::path fusepath{fusepath_};
|
||||||
const fuse_context *fc = fuse_get_context();
|
const fuse_context *fc = fuse_get_context();
|
||||||
const ugid::Set ugid(fc->uid,fc->gid);
|
const ugid::Set ugid(fc->uid,fc->gid);
|
||||||
|
|
||||||
return ::_statfs(cfg.branches,
|
return ::_statfs(cfg.branches,
|
||||||
fusepath_,
|
fusepath,
|
||||||
cfg.statfs,
|
cfg.statfs,
|
||||||
cfg.statfs_ignore,
|
cfg.statfs_ignore,
|
||||||
st_);
|
st_);
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
#include "fs_inode.hpp"
|
#include "fs_inode.hpp"
|
||||||
#include "fs_path.hpp"
|
#include "fs_path.hpp"
|
||||||
#include "fs_statx.hpp"
|
#include "fs_statx.hpp"
|
||||||
|
#include "state.hpp"
|
||||||
#include "str.hpp"
|
#include "str.hpp"
|
||||||
#include "symlinkify.hpp"
|
#include "symlinkify.hpp"
|
||||||
#include "ugid.hpp"
|
#include "ugid.hpp"
|
||||||
|
|
@ -38,7 +39,7 @@
|
||||||
|
|
||||||
static
|
static
|
||||||
void
|
void
|
||||||
_set_stat_if_leads_to_dir(const std::string &path_,
|
_set_stat_if_leads_to_dir(const fs::path &path_,
|
||||||
struct fuse_statx *st_)
|
struct fuse_statx *st_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
|
@ -56,7 +57,7 @@ _set_stat_if_leads_to_dir(const std::string &path_,
|
||||||
|
|
||||||
static
|
static
|
||||||
void
|
void
|
||||||
_set_stat_if_leads_to_reg(const std::string &path_,
|
_set_stat_if_leads_to_reg(const fs::path &path_,
|
||||||
struct fuse_statx *st_)
|
struct fuse_statx *st_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
|
@ -116,7 +117,7 @@ static
|
||||||
int
|
int
|
||||||
_statx(const Policy::Search &searchFunc_,
|
_statx(const Policy::Search &searchFunc_,
|
||||||
const Branches &branches_,
|
const Branches &branches_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
const uint32_t flags_,
|
const uint32_t flags_,
|
||||||
const uint32_t mask_,
|
const uint32_t mask_,
|
||||||
struct fuse_statx *st_,
|
struct fuse_statx *st_,
|
||||||
|
|
@ -125,14 +126,14 @@ _statx(const Policy::Search &searchFunc_,
|
||||||
FollowSymlinks followsymlinks_)
|
FollowSymlinks followsymlinks_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
std::string fullpath;
|
fs::path fullpath;
|
||||||
std::vector<Branch*> branches;
|
std::vector<Branch*> branches;
|
||||||
|
|
||||||
rv = searchFunc_(branches_,fusepath_,branches);
|
rv = searchFunc_(branches_,fusepath_,branches);
|
||||||
if(rv < 0)
|
if(rv < 0)
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
fullpath = fs::path::make(branches[0]->path,fusepath_);
|
fullpath = branches[0]->path / fusepath_;
|
||||||
|
|
||||||
switch(followsymlinks_)
|
switch(followsymlinks_)
|
||||||
{
|
{
|
||||||
|
|
@ -162,14 +163,16 @@ _statx(const Policy::Search &searchFunc_,
|
||||||
if(symlinkify_ && symlinkify::can_be_symlink(*st_,symlinkify_timeout_))
|
if(symlinkify_ && symlinkify::can_be_symlink(*st_,symlinkify_timeout_))
|
||||||
symlinkify::convert(fullpath,st_);
|
symlinkify::convert(fullpath,st_);
|
||||||
|
|
||||||
fs::inode::calc(branches[0]->path,fusepath_,st_);
|
fs::inode::calc(branches[0]->path,
|
||||||
|
fusepath_,
|
||||||
|
st_);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_statx(const char *fusepath_,
|
_statx(const fs::path &fusepath_,
|
||||||
const uint32_t flags_,
|
const uint32_t flags_,
|
||||||
const uint32_t mask_,
|
const uint32_t mask_,
|
||||||
struct fuse_statx *st_,
|
struct fuse_statx *st_,
|
||||||
|
|
@ -206,10 +209,12 @@ FUSE::statx(const char *fusepath_,
|
||||||
struct fuse_statx *st_,
|
struct fuse_statx *st_,
|
||||||
fuse_timeouts_t *timeout_)
|
fuse_timeouts_t *timeout_)
|
||||||
{
|
{
|
||||||
if(Config::is_ctrl_file(fusepath_))
|
const fs::path fusepath{fusepath_};
|
||||||
|
|
||||||
|
if(Config::is_ctrl_file(fusepath))
|
||||||
return ::_statx_controlfile(st_);
|
return ::_statx_controlfile(st_);
|
||||||
|
|
||||||
return ::_statx(fusepath_,
|
return ::_statx(fusepath,
|
||||||
flags_|AT_STATX_DONT_SYNC,
|
flags_|AT_STATX_DONT_SYNC,
|
||||||
mask_,
|
mask_,
|
||||||
st_,
|
st_,
|
||||||
|
|
@ -223,9 +228,25 @@ FUSE::statx_fh(const uint64_t fh_,
|
||||||
struct fuse_statx *st_,
|
struct fuse_statx *st_,
|
||||||
fuse_timeouts_t *timeout_)
|
fuse_timeouts_t *timeout_)
|
||||||
{
|
{
|
||||||
FileInfo *fi = reinterpret_cast<FileInfo*>(fh_);
|
uint64_t fh;
|
||||||
|
const fuse_context *fc = fuse_get_context();
|
||||||
|
|
||||||
return ::_statx(fi->fusepath.c_str(),
|
fh = fh_;
|
||||||
|
if(fh == 0)
|
||||||
|
{
|
||||||
|
state.open_files.cvisit(fc->nodeid,
|
||||||
|
[&](auto &val_)
|
||||||
|
{
|
||||||
|
fh = val_.second.fi->to_fh();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fh == 0)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
FileInfo *fi = FileInfo::from_fh(fh);
|
||||||
|
|
||||||
|
return ::_statx(fi->fusepath,
|
||||||
flags_|AT_STATX_DONT_SYNC,
|
flags_|AT_STATX_DONT_SYNC,
|
||||||
mask_,
|
mask_,
|
||||||
st_,
|
st_,
|
||||||
|
|
|
||||||
|
|
@ -29,32 +29,30 @@
|
||||||
|
|
||||||
#include "fuse.h"
|
#include "fuse.h"
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
using std::string;
|
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_symlink_loop_core(const std::string &newbranch_,
|
_symlink_loop_core(const fs::path &newbranch_,
|
||||||
const char *target_,
|
const char *target_,
|
||||||
const char *linkpath_,
|
const fs::path &linkpath_,
|
||||||
struct stat *st_)
|
struct stat *st_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
string fullnewpath;
|
fs::path fullnewpath;
|
||||||
|
|
||||||
fullnewpath = fs::path::make(newbranch_,linkpath_);
|
fullnewpath = newbranch_ / linkpath_;
|
||||||
|
|
||||||
rv = fs::symlink(target_,fullnewpath);
|
rv = fs::symlink(target_,fullnewpath);
|
||||||
if((rv >= 0) && (st_ != NULL) && (st_->st_ino == 0))
|
if((rv >= 0) && (st_ != NULL) && (st_->st_ino == 0))
|
||||||
{
|
{
|
||||||
fs::lstat(fullnewpath,st_);
|
fs::lstat(fullnewpath,st_);
|
||||||
if(st_->st_ino != 0)
|
if(st_->st_ino != 0)
|
||||||
fs::inode::calc(newbranch_,linkpath_,st_);
|
fs::inode::calc(newbranch_,
|
||||||
|
linkpath_,
|
||||||
|
st_);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
|
|
@ -62,11 +60,11 @@ _symlink_loop_core(const std::string &newbranch_,
|
||||||
|
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_symlink_loop(const std::string &existingbranch_,
|
_symlink_loop(const fs::path &existingbranch_,
|
||||||
const std::vector<Branch*> &newbranches_,
|
const std::vector<Branch*> &newbranches_,
|
||||||
const char *target_,
|
const char *target_,
|
||||||
const char *linkpath_,
|
const fs::path &linkpath_,
|
||||||
const std::string &newdirpath_,
|
const fs::path &newdirpath_,
|
||||||
struct stat *st_)
|
struct stat *st_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
|
@ -95,15 +93,15 @@ _symlink(const Policy::Search &searchFunc_,
|
||||||
const Policy::Create &createFunc_,
|
const Policy::Create &createFunc_,
|
||||||
const Branches &branches_,
|
const Branches &branches_,
|
||||||
const char *target_,
|
const char *target_,
|
||||||
const char *linkpath_,
|
const fs::path &linkpath_,
|
||||||
struct stat *st_)
|
struct stat *st_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
string newdirpath;
|
fs::path newdirpath;
|
||||||
std::vector<Branch*> newbranches;
|
std::vector<Branch*> newbranches;
|
||||||
std::vector<Branch*> existingbranches;
|
std::vector<Branch*> existingbranches;
|
||||||
|
|
||||||
newdirpath = fs::path::dirname(linkpath_);
|
newdirpath = linkpath_.parent_path();
|
||||||
|
|
||||||
rv = searchFunc_(branches_,newdirpath,existingbranches);
|
rv = searchFunc_(branches_,newdirpath,existingbranches);
|
||||||
if(rv < 0)
|
if(rv < 0)
|
||||||
|
|
@ -126,9 +124,23 @@ FUSE::symlink(const char *target_,
|
||||||
const char *linkpath_,
|
const char *linkpath_,
|
||||||
struct stat *st_,
|
struct stat *st_,
|
||||||
fuse_timeouts_t *timeouts_)
|
fuse_timeouts_t *timeouts_)
|
||||||
|
{
|
||||||
|
const fs::path linkpath{linkpath_};
|
||||||
|
|
||||||
|
return FUSE::symlink(target_,
|
||||||
|
linkpath,
|
||||||
|
st_,
|
||||||
|
timeouts_);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
FUSE::symlink(const char *target_,
|
||||||
|
const fs::path &linkpath_,
|
||||||
|
struct stat *st_,
|
||||||
|
fuse_timeouts_t *timeouts_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
const fuse_context *fc = fuse_get_context();
|
const fuse_context *fc = fuse_get_context();
|
||||||
const ugid::Set ugid(fc->uid,fc->gid);
|
const ugid::Set ugid(fc->uid,fc->gid);
|
||||||
|
|
||||||
rv = ::_symlink(cfg.func.getattr.policy,
|
rv = ::_symlink(cfg.func.getattr.policy,
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,10 @@
|
||||||
|
|
||||||
#include "fuse.h"
|
#include "fuse.h"
|
||||||
|
|
||||||
|
#include "fs_path.hpp"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
namespace FUSE
|
namespace FUSE
|
||||||
|
|
@ -27,4 +31,11 @@ namespace FUSE
|
||||||
const char *linkpath,
|
const char *linkpath,
|
||||||
struct stat *st = NULL,
|
struct stat *st = NULL,
|
||||||
fuse_timeouts_t *timeouts = NULL);
|
fuse_timeouts_t *timeouts = NULL);
|
||||||
|
|
||||||
|
int
|
||||||
|
symlink(const char *target,
|
||||||
|
const fs::path &linkpath,
|
||||||
|
struct stat *st = NULL,
|
||||||
|
fuse_timeouts_t *timeouts = NULL);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,25 +25,21 @@
|
||||||
|
|
||||||
#include "fuse.h"
|
#include "fuse.h"
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
using std::string;
|
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
void
|
void
|
||||||
_truncate_loop_core(const string &basepath_,
|
_truncate_loop_core(const fs::path &basepath_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
const off_t size_,
|
const off_t size_,
|
||||||
PolicyRV *prv_)
|
PolicyRV *prv_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
string fullpath;
|
fs::path fullpath;
|
||||||
|
|
||||||
fullpath = fs::path::make(basepath_,fusepath_);
|
fullpath = basepath_ / fusepath_;
|
||||||
|
|
||||||
rv = fs::truncate(fullpath,size_);
|
rv = fs::truncate(fullpath,size_);
|
||||||
|
|
||||||
|
|
@ -53,7 +49,7 @@ _truncate_loop_core(const string &basepath_,
|
||||||
static
|
static
|
||||||
void
|
void
|
||||||
_truncate_loop(const std::vector<Branch*> &branches_,
|
_truncate_loop(const std::vector<Branch*> &branches_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
const off_t size_,
|
const off_t size_,
|
||||||
PolicyRV *prv_)
|
PolicyRV *prv_)
|
||||||
{
|
{
|
||||||
|
|
@ -68,7 +64,7 @@ int
|
||||||
_truncate(const Policy::Action &actionFunc_,
|
_truncate(const Policy::Action &actionFunc_,
|
||||||
const Policy::Search &searchFunc_,
|
const Policy::Search &searchFunc_,
|
||||||
const Branches &branches_,
|
const Branches &branches_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
const off_t size_)
|
const off_t size_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
|
@ -97,12 +93,13 @@ int
|
||||||
FUSE::truncate(const char *fusepath_,
|
FUSE::truncate(const char *fusepath_,
|
||||||
off_t size_)
|
off_t size_)
|
||||||
{
|
{
|
||||||
|
const fs::path fusepath{fusepath_};
|
||||||
const fuse_context *fc = fuse_get_context();
|
const fuse_context *fc = fuse_get_context();
|
||||||
const ugid::Set ugid(fc->uid,fc->gid);
|
const ugid::Set ugid(fc->uid,fc->gid);
|
||||||
|
|
||||||
return ::_truncate(cfg.func.truncate.policy,
|
return ::_truncate(cfg.func.truncate.policy,
|
||||||
cfg.func.getattr.policy,
|
cfg.func.getattr.policy,
|
||||||
cfg.branches,
|
cfg.branches,
|
||||||
fusepath_,
|
fusepath,
|
||||||
size_);
|
size_);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@
|
||||||
|
|
||||||
#include "fuse.h"
|
#include "fuse.h"
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
@ -34,14 +33,14 @@
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
_unlink_loop(const std::vector<Branch*> &branches_,
|
_unlink_loop(const std::vector<Branch*> &branches_,
|
||||||
const char *fusepath_)
|
const fs::path &fusepath_)
|
||||||
{
|
{
|
||||||
Err err;
|
Err err;
|
||||||
std::string fullpath;
|
fs::path fullpath;
|
||||||
|
|
||||||
for(const auto &branch : branches_)
|
for(const auto &branch : branches_)
|
||||||
{
|
{
|
||||||
fullpath = fs::path::make(branch->path,fusepath_);
|
fullpath = branch->path / fusepath_;
|
||||||
|
|
||||||
err = fs::unlink(fullpath);
|
err = fs::unlink(fullpath);
|
||||||
}
|
}
|
||||||
|
|
@ -53,7 +52,7 @@ static
|
||||||
int
|
int
|
||||||
_unlink(const Policy::Action &unlinkPolicy_,
|
_unlink(const Policy::Action &unlinkPolicy_,
|
||||||
const Branches &branches_,
|
const Branches &branches_,
|
||||||
const char *fusepath_)
|
const fs::path &fusepath_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
std::vector<Branch*> branches;
|
std::vector<Branch*> branches;
|
||||||
|
|
@ -68,10 +67,11 @@ _unlink(const Policy::Action &unlinkPolicy_,
|
||||||
int
|
int
|
||||||
FUSE::unlink(const char *fusepath_)
|
FUSE::unlink(const char *fusepath_)
|
||||||
{
|
{
|
||||||
|
const fs::path fusepath{fusepath_};
|
||||||
const fuse_context *fc = fuse_get_context();
|
const fuse_context *fc = fuse_get_context();
|
||||||
const ugid::Set ugid(fc->uid,fc->gid);
|
const ugid::Set ugid(fc->uid,fc->gid);
|
||||||
|
|
||||||
return ::_unlink(cfg.func.unlink.policy,
|
return ::_unlink(cfg.func.unlink.policy,
|
||||||
cfg.branches,
|
cfg.branches,
|
||||||
fusepath_);
|
fusepath);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,24 +25,20 @@
|
||||||
|
|
||||||
#include "fuse.h"
|
#include "fuse.h"
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
using std::string;
|
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
void
|
void
|
||||||
_utimens_loop_core(const string &basepath_,
|
_utimens_loop_core(const fs::path &basepath_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
const timespec ts_[2],
|
const timespec ts_[2],
|
||||||
PolicyRV *prv_)
|
PolicyRV *prv_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
string fullpath;
|
fs::path fullpath;
|
||||||
|
|
||||||
fullpath = fs::path::make(basepath_,fusepath_);
|
fullpath = basepath_ / fusepath_;
|
||||||
|
|
||||||
rv = fs::lutimens(fullpath,ts_);
|
rv = fs::lutimens(fullpath,ts_);
|
||||||
|
|
||||||
|
|
@ -52,7 +48,7 @@ _utimens_loop_core(const string &basepath_,
|
||||||
static
|
static
|
||||||
void
|
void
|
||||||
_utimens_loop(const std::vector<Branch*> &branches_,
|
_utimens_loop(const std::vector<Branch*> &branches_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
const timespec ts_[2],
|
const timespec ts_[2],
|
||||||
PolicyRV *prv_)
|
PolicyRV *prv_)
|
||||||
{
|
{
|
||||||
|
|
@ -67,7 +63,7 @@ int
|
||||||
_utimens(const Policy::Action &utimensPolicy_,
|
_utimens(const Policy::Action &utimensPolicy_,
|
||||||
const Policy::Search &getattrPolicy_,
|
const Policy::Search &getattrPolicy_,
|
||||||
const Branches &branches_,
|
const Branches &branches_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
const timespec ts_[2])
|
const timespec ts_[2])
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
|
@ -96,12 +92,13 @@ int
|
||||||
FUSE::utimens(const char *fusepath_,
|
FUSE::utimens(const char *fusepath_,
|
||||||
const timespec ts_[2])
|
const timespec ts_[2])
|
||||||
{
|
{
|
||||||
|
const fs::path fusepath{fusepath_};
|
||||||
const fuse_context *fc = fuse_get_context();
|
const fuse_context *fc = fuse_get_context();
|
||||||
const ugid::Set ugid(fc->uid,fc->gid);
|
const ugid::Set ugid(fc->uid,fc->gid);
|
||||||
|
|
||||||
return ::_utimens(cfg.func.utimens.policy,
|
return ::_utimens(cfg.func.utimens.policy,
|
||||||
cfg.func.getattr.policy,
|
cfg.func.getattr.policy,
|
||||||
cfg.branches,
|
cfg.branches,
|
||||||
fusepath_,
|
fusepath,
|
||||||
ts_);
|
ts_);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -162,7 +162,7 @@ _write(const fuse_file_info_t *ffi_,
|
||||||
{
|
{
|
||||||
FileInfo *fi;
|
FileInfo *fi;
|
||||||
|
|
||||||
fi = reinterpret_cast<FileInfo*>(ffi_->fh);
|
fi = FileInfo::from_fh(ffi_->fh);
|
||||||
|
|
||||||
// Concurrent writes can only happen if:
|
// Concurrent writes can only happen if:
|
||||||
// 1) writeback-cache is enabled and using page caching
|
// 1) writeback-cache is enabled and using page caching
|
||||||
|
|
|
||||||
|
|
@ -87,10 +87,9 @@
|
||||||
|
|
||||||
#include <csignal>
|
#include <csignal>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
|
|
||||||
namespace l
|
namespace l
|
||||||
{
|
{
|
||||||
|
|
@ -192,7 +191,7 @@ namespace l
|
||||||
wait_for_mount(const Config &cfg_)
|
wait_for_mount(const Config &cfg_)
|
||||||
{
|
{
|
||||||
int failures;
|
int failures;
|
||||||
fs::PathVector paths;
|
std::vector<fs::path> paths;
|
||||||
std::chrono::milliseconds timeout;
|
std::chrono::milliseconds timeout;
|
||||||
|
|
||||||
paths = cfg_.branches->to_paths();
|
paths = cfg_.branches->to_paths();
|
||||||
|
|
@ -232,7 +231,7 @@ namespace l
|
||||||
|
|
||||||
static
|
static
|
||||||
void
|
void
|
||||||
lazy_umount(const fs::Path target_)
|
lazy_umount(const fs::path &target_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
#include "errno.hpp"
|
#include "errno.hpp"
|
||||||
#include "fmt/core.h"
|
#include "fmt/core.h"
|
||||||
#include "fs_glob.hpp"
|
#include "fs_glob.hpp"
|
||||||
|
#include "fs_path.hpp"
|
||||||
#include "fs_statvfs_cache.hpp"
|
#include "fs_statvfs_cache.hpp"
|
||||||
#include "hw_cpu.hpp"
|
#include "hw_cpu.hpp"
|
||||||
#include "num.hpp"
|
#include "num.hpp"
|
||||||
|
|
@ -33,7 +34,6 @@
|
||||||
#include "fuse_config.hpp"
|
#include "fuse_config.hpp"
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <filesystem>
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
@ -47,9 +47,6 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
using std::string;
|
|
||||||
using std::vector;
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
MERGERFS_OPT_HELP,
|
MERGERFS_OPT_HELP,
|
||||||
|
|
@ -97,7 +94,7 @@ _set_fsname(Config &cfg_,
|
||||||
{
|
{
|
||||||
if(cfg_.fsname->empty())
|
if(cfg_.fsname->empty())
|
||||||
{
|
{
|
||||||
vector<string> paths;
|
std::vector<std::string> paths;
|
||||||
|
|
||||||
cfg_.branches->to_paths(paths);
|
cfg_.branches->to_paths(paths);
|
||||||
|
|
||||||
|
|
@ -225,7 +222,7 @@ _process_branches(Config &cfg_,
|
||||||
const char *arg_)
|
const char *arg_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
string arg;
|
std::string arg;
|
||||||
|
|
||||||
arg = arg_;
|
arg = arg_;
|
||||||
rv = cfg_.set_raw("branches",arg);
|
rv = cfg_.set_raw("branches",arg);
|
||||||
|
|
@ -242,7 +239,7 @@ _process_mount(Config &cfg_,
|
||||||
const char *arg_)
|
const char *arg_)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
string arg;
|
std::string arg;
|
||||||
|
|
||||||
arg = arg_;
|
arg = arg_;
|
||||||
rv = cfg_.set_raw("mount",arg);
|
rv = cfg_.set_raw("mount",arg);
|
||||||
|
|
@ -347,8 +344,8 @@ void
|
||||||
_check_for_mount_loop(Config &cfg_,
|
_check_for_mount_loop(Config &cfg_,
|
||||||
Config::ErrVec *errs_)
|
Config::ErrVec *errs_)
|
||||||
{
|
{
|
||||||
fs::Path mount;
|
fs::path mount;
|
||||||
fs::PathVector branches;
|
std::vector<fs::path> branches;
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
|
|
||||||
mount = *cfg_.mountpoint;
|
mount = *cfg_.mountpoint;
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#include "branches.hpp"
|
#include "branches.hpp"
|
||||||
#include "strvec.hpp"
|
#include "strvec.hpp"
|
||||||
|
#include "fs_path.hpp"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
@ -37,7 +38,7 @@ namespace Policy
|
||||||
public:
|
public:
|
||||||
std::string name;
|
std::string name;
|
||||||
virtual int operator()(const Branches::Ptr&,
|
virtual int operator()(const Branches::Ptr&,
|
||||||
const char*,
|
const fs::path&,
|
||||||
std::vector<Branch*>&) const = 0;
|
std::vector<Branch*>&) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -63,21 +64,13 @@ namespace Policy
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
operator()(const Branches::Ptr &branches_,
|
operator()(const Branches::Ptr &branches_,
|
||||||
const char *fusepath_,
|
const std::filesystem::path &fusepath_,
|
||||||
std::vector<Branch*> &output_) const
|
std::vector<Branch*> &output_) const
|
||||||
{
|
{
|
||||||
return (*impl)(branches_,fusepath_,output_);
|
return (*impl)(branches_,fusepath_,output_);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
operator()(const Branches::Ptr &branches_,
|
|
||||||
const std::string &fusepath_,
|
|
||||||
std::vector<Branch*> &output_) const
|
|
||||||
{
|
|
||||||
return (*impl)(branches_,fusepath_.c_str(),output_);
|
|
||||||
}
|
|
||||||
|
|
||||||
operator bool() const
|
operator bool() const
|
||||||
{
|
{
|
||||||
return (bool)impl;
|
return (bool)impl;
|
||||||
|
|
@ -99,7 +92,7 @@ namespace Policy
|
||||||
std::string name;
|
std::string name;
|
||||||
virtual bool path_preserving(void) const = 0;
|
virtual bool path_preserving(void) const = 0;
|
||||||
virtual int operator()(const Branches::Ptr&,
|
virtual int operator()(const Branches::Ptr&,
|
||||||
const char*,
|
const std::filesystem::path&,
|
||||||
std::vector<Branch*>&) const = 0;
|
std::vector<Branch*>&) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -131,21 +124,13 @@ namespace Policy
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
operator()(const Branches::Ptr &branches_,
|
operator()(const Branches::Ptr &branches_,
|
||||||
const char *fusepath_,
|
const std::filesystem::path &fusepath_,
|
||||||
std::vector<Branch*> &output_) const
|
std::vector<Branch*> &output_) const
|
||||||
{
|
{
|
||||||
return (*impl)(branches_,fusepath_,output_);
|
return (*impl)(branches_,fusepath_,output_);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
operator()(const Branches::Ptr &branches_,
|
|
||||||
const std::string &fusepath_,
|
|
||||||
std::vector<Branch*> &output_) const
|
|
||||||
{
|
|
||||||
return (*impl)(branches_,fusepath_.c_str(),output_);
|
|
||||||
}
|
|
||||||
|
|
||||||
operator bool() const
|
operator bool() const
|
||||||
{
|
{
|
||||||
return (bool)impl;
|
return (bool)impl;
|
||||||
|
|
@ -166,7 +151,7 @@ namespace Policy
|
||||||
public:
|
public:
|
||||||
std::string name;
|
std::string name;
|
||||||
virtual int operator()(const Branches::Ptr&,
|
virtual int operator()(const Branches::Ptr&,
|
||||||
const char*,
|
const std::filesystem::path&,
|
||||||
std::vector<Branch*>&) const = 0;
|
std::vector<Branch*>&) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -193,20 +178,12 @@ namespace Policy
|
||||||
|
|
||||||
int
|
int
|
||||||
operator()(const Branches::Ptr &branches_,
|
operator()(const Branches::Ptr &branches_,
|
||||||
const char *fusepath_,
|
const std::filesystem::path &fusepath_,
|
||||||
std::vector<Branch*> &output_) const
|
std::vector<Branch*> &output_) const
|
||||||
{
|
{
|
||||||
return (*impl)(branches_,fusepath_,output_);
|
return (*impl)(branches_,fusepath_,output_);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
operator()(const Branches::Ptr &branches_,
|
|
||||||
const std::string &fusepath_,
|
|
||||||
std::vector<Branch*> &output_) const
|
|
||||||
{
|
|
||||||
return (*impl)(branches_,fusepath_.c_str(),output_);
|
|
||||||
}
|
|
||||||
|
|
||||||
operator bool() const
|
operator bool() const
|
||||||
{
|
{
|
||||||
return (bool)impl;
|
return (bool)impl;
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ _create(const Branches::Ptr &ibranches_,
|
||||||
|
|
||||||
int
|
int
|
||||||
Policy::All::Action::operator()(const Branches::Ptr &ibranches_,
|
Policy::All::Action::operator()(const Branches::Ptr &ibranches_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
std::vector<Branch*> &obranches_) const
|
std::vector<Branch*> &obranches_) const
|
||||||
{
|
{
|
||||||
return Policies::Action::epall(ibranches_,fusepath_,obranches_);
|
return Policies::Action::epall(ibranches_,fusepath_,obranches_);
|
||||||
|
|
@ -70,7 +70,7 @@ Policy::All::Action::operator()(const Branches::Ptr &ibranches_,
|
||||||
|
|
||||||
int
|
int
|
||||||
Policy::All::Create::operator()(const Branches::Ptr &ibranches_,
|
Policy::All::Create::operator()(const Branches::Ptr &ibranches_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
std::vector<Branch*> &obranches_) const
|
std::vector<Branch*> &obranches_) const
|
||||||
{
|
{
|
||||||
return ::_create(ibranches_,obranches_);
|
return ::_create(ibranches_,obranches_);
|
||||||
|
|
@ -78,7 +78,7 @@ Policy::All::Create::operator()(const Branches::Ptr &ibranches_,
|
||||||
|
|
||||||
int
|
int
|
||||||
Policy::All::Search::operator()(const Branches::Ptr &ibranches_,
|
Policy::All::Search::operator()(const Branches::Ptr &ibranches_,
|
||||||
const char *fusepath_,
|
const fs::path &fusepath_,
|
||||||
std::vector<Branch*> &obranches_) const
|
std::vector<Branch*> &obranches_) const
|
||||||
{
|
{
|
||||||
return Policies::Search::epall(ibranches_,fusepath_,obranches_);
|
return Policies::Search::epall(ibranches_,fusepath_,obranches_);
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue