Skip to content

Commit

Permalink
Merge pull request #47 from trapexit/getxattr_all
Browse files Browse the repository at this point in the history
add user.mergerfs.allpaths and user.mergerfs.relpath to getxattr
  • Loading branch information
trapexit committed Feb 7, 2015
2 parents dbe630c + d30cae2 commit f3f5a18
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 7 deletions.
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 changes: 21 additions & 0 deletions src/fs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 4 additions & 0 deletions src/fs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
49 changes: 44 additions & 5 deletions src/getxattr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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);
Expand Down

0 comments on commit f3f5a18

Please sign in to comment.