Browse Source

Merge pull request #47 from trapexit/getxattr_all

add user.mergerfs.allpaths and user.mergerfs.relpath to getxattr
pull/49/head 1.7.0
Antonio SJ Musumeci 10 years ago
parent
commit
f3f5a18ef5
  1. 11
      README.md
  2. 21
      src/fs.cpp
  3. 4
      src/fs.hpp
  4. 49
      src/getxattr.cpp

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: 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 [trapexit:/tmp/mount] $ ls
@ -158,4 +160,9 @@ A B C
/mnt/a/full/path/to/A /mnt/a/full/path/to/A
[trapexit:/tmp/mount] $ xattr -p user.mergerfs.basepath A [trapexit:/tmp/mount] $ xattr -p user.mergerfs.basepath A
/mnt/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

@ -162,6 +162,27 @@ namespace fs
fusepath); 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 int
listxattr(const string &path, listxattr(const string &path,
vector<char> &attrs) vector<char> &attrs)

4
src/fs.hpp

@ -64,6 +64,10 @@ namespace fs
bool path_exists(const vector<string> &srcmounts, bool path_exists(const vector<string> &srcmounts,
const string &fusepath); const string &fusepath);
void findallfiles(const vector<string> &srcmounts,
const string &fusepath,
vector<string> &paths);
int clonepath(const string &srcfrom, int clonepath(const string &srcfrom,
const string &srcto, const string &srcto,
const string &relative); const string &relative);

49
src/getxattr.cpp

@ -94,6 +94,46 @@ _getxattr_from_string(char *destbuf,
return srcbufsize; 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 static
int int
_getxattr(const fs::SearchFunc searchFunc, _getxattr(const fs::SearchFunc searchFunc,
@ -111,11 +151,10 @@ _getxattr(const fs::SearchFunc searchFunc,
if(rv == -1) if(rv == -1)
return -errno; 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); rv = ::lgetxattr(path.full.c_str(),attrname,buf,count);
return ((rv == -1) ? -errno : rv); return ((rv == -1) ? -errno : rv);

Loading…
Cancel
Save