mirror of
https://github.com/trapexit/mergerfs.git
synced 2025-01-21 20:17:47 +08:00
Merge pull request #47 from trapexit/getxattr_all
add user.mergerfs.allpaths and user.mergerfs.relpath to getxattr
This commit is contained in:
commit
f3f5a18ef5
11
README.md
11
README.md
|
@ -148,8 +148,10 @@ For **user.mergerfs.srcmounts** there are several instructions available for man
|
|||
|
||||
While they won't show up when using [listxattr](http://linux.die.net/man/2/listxattr) mergerfs offers a number of special xattrs to query information about the files served. To access the values you will need to issue a [getxattr](http://linux.die.net/man/2/getxattr) for one of the following:
|
||||
|
||||
* user.mergerfs.basepath : gives you the base mount point for the file given the current search policy
|
||||
* user.mergerfs.fullpath : gives you the full path of the original file given the search policy
|
||||
* user.mergerfs.basepath: the base mount point for the file given the current search policy
|
||||
* user.mergerfs.relpath: the relative path of the file from the perspective of the mount point
|
||||
* user.mergerfs.fullpath: the full path of the original file given the search policy
|
||||
* user.mergerfs.allpaths: a NUL ('\0') separated list of full paths to all files found
|
||||
|
||||
```
|
||||
[trapexit:/tmp/mount] $ ls
|
||||
|
@ -158,4 +160,9 @@ A B C
|
|||
/mnt/a/full/path/to/A
|
||||
[trapexit:/tmp/mount] $ xattr -p user.mergerfs.basepath A
|
||||
/mnt/a
|
||||
[trapexit:/tmp/mount] $ xattr -p user.mergerfs.relpath A
|
||||
/full/path/to/A
|
||||
[trapexit:/tmp/mount] $ xattr -p user.mergerfs.allpaths A | tr '\0' '\n'
|
||||
/mnt/a/full/path/to/A
|
||||
/mnt/b/full/path/to/A
|
||||
```
|
||||
|
|
21
src/fs.cpp
21
src/fs.cpp
|
@ -162,6 +162,27 @@ namespace fs
|
|||
fusepath);
|
||||
}
|
||||
|
||||
void
|
||||
findallfiles(const vector<string> &srcmounts,
|
||||
const string &fusepath,
|
||||
vector<string> &paths)
|
||||
{
|
||||
for(vector<string>::const_iterator
|
||||
iter = srcmounts.begin(), eiter = srcmounts.end();
|
||||
iter != eiter;
|
||||
++iter)
|
||||
{
|
||||
int rv;
|
||||
string fullpath;
|
||||
struct stat st;
|
||||
|
||||
fullpath = fs::make_path(*iter,fusepath);
|
||||
rv = ::lstat(fullpath.c_str(),&st);
|
||||
if(rv == 0)
|
||||
paths.push_back(fullpath);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
listxattr(const string &path,
|
||||
vector<char> &attrs)
|
||||
|
|
|
@ -64,6 +64,10 @@ namespace fs
|
|||
bool path_exists(const vector<string> &srcmounts,
|
||||
const string &fusepath);
|
||||
|
||||
void findallfiles(const vector<string> &srcmounts,
|
||||
const string &fusepath,
|
||||
vector<string> &paths);
|
||||
|
||||
int clonepath(const string &srcfrom,
|
||||
const string &srcto,
|
||||
const string &relative);
|
||||
|
|
|
@ -94,6 +94,46 @@ _getxattr_from_string(char *destbuf,
|
|||
return srcbufsize;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_getxattr_user_mergerfs_allpaths(const vector<string> &srcmounts,
|
||||
const string &fusepath,
|
||||
char *buf,
|
||||
const size_t count)
|
||||
{
|
||||
string concated;
|
||||
vector<string> paths;
|
||||
|
||||
fs::findallfiles(srcmounts,fusepath,paths);
|
||||
|
||||
concated = str::join(paths,'\0');
|
||||
|
||||
return ::_getxattr_from_string(buf,count,concated);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_getxattr_user_mergerfs(const fs::Path &path,
|
||||
const vector<string> &srcmounts,
|
||||
const string &fusepath,
|
||||
const char *attrname,
|
||||
char *buf,
|
||||
const size_t count)
|
||||
{
|
||||
const char *attrbasename = &attrname[sizeof("user.mergerfs")];
|
||||
|
||||
if(!strcmp(attrbasename,"basepath"))
|
||||
return ::_getxattr_from_string(buf,count,path.base);
|
||||
else if(!strcmp(attrbasename,"fullpath"))
|
||||
return ::_getxattr_from_string(buf,count,path.full);
|
||||
else if(!strcmp(attrbasename,"relpath"))
|
||||
return ::_getxattr_from_string(buf,count,fusepath);
|
||||
else if(!strcmp(attrbasename,"allpaths"))
|
||||
return ::_getxattr_user_mergerfs_allpaths(srcmounts,fusepath,buf,count);
|
||||
|
||||
return (errno=ENOATTR,-1);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
_getxattr(const fs::SearchFunc searchFunc,
|
||||
|
@ -111,11 +151,10 @@ _getxattr(const fs::SearchFunc searchFunc,
|
|||
if(rv == -1)
|
||||
return -errno;
|
||||
|
||||
if(!strcmp(attrname,"user.mergerfs.basepath"))
|
||||
rv = ::_getxattr_from_string(buf,count,path.base);
|
||||
else if(!strcmp(attrname,"user.mergerfs.fullpath"))
|
||||
rv = ::_getxattr_from_string(buf,count,path.full);
|
||||
else
|
||||
if(!strncmp("user.mergerfs.",attrname,sizeof("user.mergerfs.")-1))
|
||||
rv = _getxattr_user_mergerfs(path,srcmounts,fusepath,attrname,buf,count);
|
||||
|
||||
if(rv == -1 && errno == ENOATTR)
|
||||
rv = ::lgetxattr(path.full.c_str(),attrname,buf,count);
|
||||
|
||||
return ((rv == -1) ? -errno : rv);
|
||||
|
|
Loading…
Reference in New Issue
Block a user