Skip to content

Commit

Permalink
revert removal of 'all' policy and relevant behavior. closes #54
Browse files Browse the repository at this point in the history
  • Loading branch information
trapexit committed Mar 6, 2015
1 parent a359c88 commit c022741
Show file tree
Hide file tree
Showing 28 changed files with 451 additions and 222 deletions.
68 changes: 48 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,41 @@ In /etc/fstab it'd look like the following:

Filesystem calls are broken up into 3 categories: action, create, search. There are also some calls which have no policy attached due to state being kept between calls. These categories can be assigned a policy which dictates how [mergerfs](http://github.com/trapexit/mergerfs) behaves. Any policy can be assigned to a category though some aren't terribly practical. For instance: rand (Random) may be useful for **create** but could lead to very odd behavior if used for **search**.

#### Functional classifications ####
| Class | FUSE calls |
|-------|------------|
| action | chmod, chown, link, removexattr, rename, rmdir, setxattr, truncate, unlink, utimens |
| search | access, getattr, getxattr, listxattr, open, readlink, symlink |
| create | create, mkdir, mknod |
| N/A | fallocate, fgetattr, fsync, ftruncate, ioctl, read, readdir, statfs, symlink, write, release |
#### Functional classifications ####
| FUSE Function | Class |
|-------------|---------|
| access | search |
| chmod | action |
| chown | action |
| create | create |
| fallocate | N/A |
| fgetattr | N/A |
| fsync | N/A |
| ftruncate | N/A |
| getattr | search |
| getxattr | search |
| ioctl | N/A* |
| link | action |
| listxattr | search |
| mkdir | create |
| mknod | create |
| open | search |
| read | N/A |
| readdir | N/A |
| readlink | search |
| release | N/A |
| removexattr | action |
| rename | action |
| rmdir | action |
| setxattr | action |
| statfs | N/A |
| symlink | create |
| truncate | action |
| unlink | action |
| utimens | action |
| write | N/A |

`ioctl` behaves differently if its acting on a directory. It'll use the `getattr` policy to find and open the directory before issuing the `ioctl`. In other cases where something may be searched (to confirm a directory exists across all source mounts) then `getattr` will be used.

#### Policy descriptions ####
| Policy | Description |
Expand All @@ -69,7 +97,7 @@ Filesystem calls are broken up into 3 categories: action, create, search. There

#### readdir ####

[readdir](http://linux.die.net/man/3/readdir) is very different from most functions in this realm. It certainly could have it's own set of policies to tweak its behavior. At this time it provides a simple `first found` merging of directories and file found. That is: only the first file or directory found for a directory is returned.
[readdir](http://linux.die.net/man/3/readdir) is very different from most functions in this realm. It certainly could have it's own set of policies to tweak its behavior. At this time it provides a simple `first found` merging of directories and file found. That is: only the first file or directory found for a directory is returned. Given how FUSE works though the data representing the returned entry comes from `getattr`.

It could be extended to offer the ability to see all files found. Perhaps concatinating `#` and a number to the name. But to really be useful you'd need to be able to access them which would complicate file lookup.

Expand Down Expand Up @@ -133,29 +161,29 @@ Even if xattrs are disabled the [{list,get,set}xattrs](http://linux.die.net/man/
```
[trapexit:/tmp/mount] $ xattr -l .mergerfs
user.mergerfs.srcmounts: /tmp/a:/tmp/b
user.mergerfs.category.action: ff
user.mergerfs.category.action: all
user.mergerfs.category.create: epmfs
user.mergerfs.category.search: ff
user.mergerfs.func.access: ff
user.mergerfs.func.chmod: ff
user.mergerfs.func.chown: ff
user.mergerfs.func.chmod: all
user.mergerfs.func.chown: all
user.mergerfs.func.create: epmfs
user.mergerfs.func.getattr: ff
user.mergerfs.func.getxattr: ff
user.mergerfs.func.link: ff
user.mergerfs.func.link: all
user.mergerfs.func.listxattr: ff
user.mergerfs.func.mkdir: epmfs
user.mergerfs.func.mknod: epmfs
user.mergerfs.func.open: ff
user.mergerfs.func.readlink: ff
user.mergerfs.func.removexattr: ff
user.mergerfs.func.rename: ff
user.mergerfs.func.rmdir: ff
user.mergerfs.func.setxattr: ff
user.mergerfs.func.symlink: ff
user.mergerfs.func.truncate: ff
user.mergerfs.func.unlink: ff
user.mergerfs.func.utimens: ff
user.mergerfs.func.removexattr: all
user.mergerfs.func.rename: all
user.mergerfs.func.rmdir: all
user.mergerfs.func.setxattr: all
user.mergerfs.func.symlink: epmfs
user.mergerfs.func.truncate: all
user.mergerfs.func.unlink: all
user.mergerfs.func.utimens: all
[trapexit:/tmp/mount] $ xattr -p user.mergerfs.category.search .mergerfs
ff
Expand Down
8 changes: 4 additions & 4 deletions src/access.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,19 +45,19 @@ using mergerfs::Policy;

static
int
_access(const fs::SearchFunc searchFunc,
_access(const fs::find::Func searchFunc,
const vector<string> &srcmounts,
const string &fusepath,
const int mask)
{
int rv;
fs::Path path;
fs::Paths paths;

rv = searchFunc(srcmounts,fusepath,path);
rv = searchFunc(srcmounts,fusepath,paths,1);
if(rv == -1)
return -errno;

rv = ::eaccess(path.full.c_str(),mask);
rv = ::eaccess(paths[0].full.c_str(),mask);

return ((rv == -1) ? -errno : 0);
}
Expand Down
18 changes: 13 additions & 5 deletions src/chmod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,21 +39,29 @@ using mergerfs::Policy;

static
int
_chmod(const fs::SearchFunc searchFunc,
_chmod(const fs::find::Func actionFunc,
const vector<string> &srcmounts,
const string &fusepath,
const mode_t mode)
{
int rv;
fs::Path path;
int error;
fs::Paths paths;

rv = searchFunc(srcmounts,fusepath,path);
rv = actionFunc(srcmounts,fusepath,paths,-1);
if(rv == -1)
return -errno;

rv = ::chmod(path.full.c_str(),mode);
error = 0;
for(fs::Paths::const_iterator
i = paths.begin(), ei = paths.end(); i != ei; ++i)
{
rv = ::chmod(i->full.c_str(),mode);
if(rv == -1)
error = errno;
}

return ((rv == -1) ? -errno : 0);
return -error;
}

namespace mergerfs
Expand Down
18 changes: 13 additions & 5 deletions src/chown.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,22 +40,30 @@ using mergerfs::Policy;

static
int
_chown(const fs::SearchFunc searchFunc,
_chown(const fs::find::Func actionFunc,
const vector<string> &srcmounts,
const string &fusepath,
const uid_t uid,
const gid_t gid)
{
int rv;
fs::Path path;
int error;
fs::Paths paths;

rv = searchFunc(srcmounts,fusepath,path);
rv = actionFunc(srcmounts,fusepath,paths,-1);
if(rv == -1)
return -errno;

rv = ::lchown(path.full.c_str(),uid,gid);
error = 0;
for(fs::Paths::const_iterator
i = paths.begin(), ei = paths.end(); i != ei; ++i)
{
rv = ::lchown(i->full.c_str(),uid,gid);
if(rv == -1)
error = errno;
}

return ((rv == -1) ? -errno : 0);
return -error;
}

namespace mergerfs
Expand Down
2 changes: 1 addition & 1 deletion src/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ namespace mergerfs
{
pthread_rwlock_init(&srcmountslock,NULL);

setpolicy(Category::Enum::action,Policy::Enum::ff);
setpolicy(Category::Enum::action,Policy::Enum::all);
setpolicy(Category::Enum::create,Policy::Enum::epmfs);
setpolicy(Category::Enum::search,Policy::Enum::ff);
}
Expand Down
20 changes: 10 additions & 10 deletions src/create.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ using mergerfs::Policy;

static
int
_create(const fs::SearchFunc searchFunc,
const fs::SearchFunc createPathFunc,
_create(const fs::find::Func searchFunc,
const fs::find::Func createFunc,
const vector<string> &srcmounts,
const string &fusepath,
const mode_t mode,
Expand All @@ -57,25 +57,25 @@ _create(const fs::SearchFunc searchFunc,
int rv;
string path;
string dirname;
fs::Path createpath;
fs::Path existingpath;
fs::Paths createpath;
fs::Paths existingpath;

dirname = fs::dirname(fusepath);
rv = searchFunc(srcmounts,dirname,existingpath);
rv = searchFunc(srcmounts,dirname,existingpath,1);
if(rv == -1)
return -errno;

rv = createPathFunc(srcmounts,dirname,createpath);
rv = createFunc(srcmounts,dirname,createpath,1);
if(rv == -1)
return -errno;

if(createpath.base != existingpath.base)
if(createpath[0].base != existingpath[0].base)
{
const mergerfs::ugid::SetResetGuard ugid(0,0);
fs::clonepath(existingpath.base,createpath.base,dirname);
fs::clonepath(existingpath[0].base,createpath[0].base,dirname);
}

path = fs::make_path(createpath.base,fusepath);
path = fs::make_path(createpath[0].base,fusepath);

fd = ::open(path.c_str(),flags,mode);
if(fd == -1)
Expand All @@ -100,7 +100,7 @@ namespace mergerfs
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);

return _create(*config.create,
return _create(*config.getattr,
*config.create,
config.srcmounts,
fusepath,
Expand Down
Loading

0 comments on commit c022741

Please sign in to comment.