Browse Source

remove statfs policy

pull/36/head
Antonio SJ Musumeci 11 years ago
parent
commit
16fe0cf90c
  1. 40
      README.md
  2. 3
      src/config.cpp
  3. 2
      src/getxattr.cpp
  4. 4
      src/option_parser.cpp
  5. 49
      src/policy.cpp
  6. 35
      src/policy.hpp
  7. 9
      src/setxattr.cpp
  8. 28
      src/statfs.cpp
  9. 6
      src/write.cpp

40
README.md

@ -10,20 +10,19 @@ Why create mergerfs when those exist? mhddfs isn't really maintained or flexible
Policies
========
Filesystem calls are broken up into 5 classes of policies: search, action, create, statfs, and none.
Filesystem calls are broken up into 4 categories of policies: search, action, create, and none.
Below shows each policy class, the FUSE calls they impact, and the policy names.
####Policy classifications####
#### Policy classifications ####
| Class | FUSE calls | Policies |
|-------|------------|----------|
| search | access, getattr, getxattr, listxattr, open, readlink | First Found (ff), First Found w/ Permission (ffwp), Newest (newest) |
| action | chmod, link, removexattr, rmdir, setxattr, truncate, unlink, utimens | First Found (ff), First Found w/ Permission (ffwp), Newest (newest), All Found (all) |
| create | create, mkdir, mknod | Existing Path (ep), Most Free Space (mfs), Existing Path Most Free Space (epmfs), Random (rand) |
| statfs | statfs | Sum Used Max Free (sumf), Sum Used Sum Free (susf) |
| none | fallocate, fsync, ftruncate, ioctl, read, readdir, rename, symlink, write, release | |
| none | fallocate, fsync, ftruncate, ioctl, read, readdir, rename, statfs, symlink, write, release | |
####Descriptions####
#### Descriptions ####
| Class/Policy | Description |
|--------------|-------------|
| search/ff | Given the order the paths were provided at mount time act on the first one found (regardless if stat would return EACCES). |
@ -37,8 +36,10 @@ Below shows each policy class, the FUSE calls they impact, and the policy names.
| create/mfs | Assuming the path is found to exist (ENOENT would not be returned) use the drive with the most free space available. |
| create/epmfs | If the path exists in multiple locations use the one with the most free space. Otherwise fall back to mfs. |
| create/rand | Pick a destination at random. Again the dirname of the full path must exist somewhere. |
| statfs/sumf | When reporting the size of the filesystem it will show the sum of all used but the available space will be reported as the max available across the filesystems mounted. |
| statfs/susf | As above but will report the sum of available space. Since the largest usable space is that of the filesystem with the most usable space this option is deceptive. |
#### statvfs ####
Since we aren't trying to stripe data across drives the free space of the mountpoint is just that of the source mount with the most free space at the moment.
**NOTE:** create is really a search for existence and then create. The 'search' policy applies to the first part. If the [dirname](http://linux.die.net/man/3/dirname) of the full path is not found to exist [ENOENT](http://linux.die.net/man/3/errno) is returned.
@ -46,7 +47,7 @@ Usage
=====
```
$ mergerfs -o create=epmfs,search=ff,action=ff,statfs=sumf <mountpoint> <dir0>:<dir1>:<dir2>
$ mergerfs -o create=epmfs,search=ff,action=ff <mountpoint> <dir0>:<dir1>:<dir2>
```
| Option | Values | Default |
@ -54,7 +55,6 @@ $ mergerfs -o create=epmfs,search=ff,action=ff,statfs=sumf <mountpoint> <dir0>:<
| search | ff, ffwp, newest | ff |
| action | ff, ffwp, newest, all | ff |
| create | ep, mfs, epmfs, rand | epmfs |
| statfs | sumf, susf | sumf |
Building
========
@ -72,6 +72,7 @@ make WITHOUT_XATTR=1 - to build program without xattrs functionality
Runtime Settings
================
#### /.mergerfs pseudo file ####
```
<mountpoint>/.mergerfs
```
@ -85,7 +86,6 @@ Reading the file will result in a newline delimited list of current settings as
action=ff
create=epmfs
search=ff
statfs=sumf
```
Writing to the file is buffered and waits till a newline to process. Meaning echo works well.
@ -96,7 +96,25 @@ Writing to the file is buffered and waits till a newline to process. Meaning ech
action=ff
create=epmfs
search=newest
statfs=sumf
```
*NOTE:* offset is not supported and ignored in both read and write. There is also a safety check which limits buffered + incoming length to a max of 1024 bytes.
#### xattrs ####
If xattrs has been enabled you can also use [{list,get,set}xattrs](http://linux.die.net/man/2/listxattr) on the pseudo file **.mergerfs** to modify the policies. The keys are **mergerfs.action**, **mergerfs.create**, and **mergerfs.search**.
```
[trapexit:/tmp/mount] $ attr -l .mergerfs
Attribute "mergerfs.action" has a 3 byte value for .mergerfs
Attribute "mergerfs.create" has a 6 byte value for .mergerfs
Attribute "mergerfs.search" has a 3 byte value for .mergerfs
[trapexit:/tmp/mount] $ attr -g mergerfs.action .mergerfs
Attribute "mergerfs.action" had a 3 byte value for .mergerfs:
ff
[trapexit:/tmp/mount] 1 $ attr -s mergerfs.action -V ffwp .mergerfs
Attribute "mergerfs.action" set to a 3 byte value for .mergerfs:
ffwp
```

3
src/config.cpp

@ -63,8 +63,7 @@ namespace mergerfs
ss << "action=" << policy.action.str() << std::endl
<< "create=" << policy.create.str() << std::endl
<< "search=" << policy.search.str() << std::endl
<< "statfs=" << policy.statfs.str() << std::endl;
<< "search=" << policy.search.str() << std::endl;
return ss.str();
}

2
src/getxattr.cpp

@ -56,8 +56,6 @@ _getxattr_controlfile(const Policy &policy,
attrvalue = policy.create.str();
else if(attrname == "user.mergerfs.search")
attrvalue = policy.search.str();
else if(attrname == "user.mergerfs.statfs")
attrvalue = policy.statfs.str();
if(attrvalue.empty())
return -ENOATTR;

4
src/option_parser.cpp

@ -68,9 +68,7 @@ process_opt(config::Config &config,
switch(argvalue.size())
{
case 2:
if(argvalue[0] == "statfs")
policy.statfs.fromString(argvalue[1]);
else if(argvalue[0] == "create")
if(argvalue[0] == "create")
policy.create.fromString(argvalue[1]);
else if(argvalue[0] == "search")
policy.search.fromString(argvalue[1]);

49
src/policy.cpp

@ -254,53 +254,4 @@ namespace mergerfs
return NULL;
}
}
Policy::StatFS::StatFS(const Policy::StatFS::Type value)
{
*this = value;
}
Policy::StatFS&
Policy::StatFS::operator=(Policy::StatFS::Type value)
{
_str = toString(value);
_value = fromString(_str);
return *this;
}
Policy::StatFS&
Policy::StatFS::operator=(const std::string str)
{
_value = fromString(str);
_str = toString(_value);
return *this;
}
Policy::StatFS::Type
Policy::StatFS::fromString(const std::string str)
{
if(str == "susf")
return Policy::StatFS::SumUsedSumFree;
else if(str == "sumf")
return Policy::StatFS::SumUsedMaxFree;
return Policy::StatFS::Invalid;
}
std::string
Policy::StatFS::toString(const Policy::StatFS::Type value)
{
switch(value)
{
case Policy::StatFS::SumUsedSumFree:
return "susf";
case Policy::StatFS::SumUsedMaxFree:
return "sumf";
case Policy::StatFS::Invalid:
default:
return "invalid";
}
}
}

35
src/policy.hpp

@ -36,45 +36,12 @@ namespace mergerfs
public:
enum Type
{
STATFS,
ACTION,
CREATE,
SEARCH
};
public:
class StatFS
{
public:
enum Type
{
Invalid = -1,
SumUsedSumFree,
SumUsedMaxFree,
Max
};
StatFS(Type _value);
public:
operator Type() const { return _value; }
operator std::string() const { return _str; }
std::string str() const { return _str; }
StatFS& operator=(const Type);
StatFS& operator=(const std::string);
static Type fromString(const std::string);
static std::string toString(const Type);
private:
StatFS();
private:
Type _value;
std::string _str;
};
class Create
{
public:
@ -190,14 +157,12 @@ namespace mergerfs
public:
Policy() :
statfs(StatFS::SumUsedMaxFree),
create(Create::ExistingPathMostFreeSpace),
search(Search::FirstFound),
action(Action::FirstFound)
{}
public:
StatFS statfs;
Create create;
Search search;
Action action;

9
src/setxattr.cpp

@ -75,15 +75,6 @@ _setxattr_controlfile(config::Config &config,
else
return -ENOSPC;
}
else if(attrname == "user.mergerfs.statfs")
{
if((flags & XATTR_CREATE) == XATTR_CREATE)
return -EEXIST;
if(Policy::StatFS::fromString(attrval) != -1)
config.policy.statfs = attrval;
else
return -ENOSPC;
}
else
{
return -ENOATTR;

28
src/statfs.cpp

@ -68,24 +68,12 @@ _normalize_statvfs(struct statvfs *fsstat,
static
void
_merge_statvfs(struct statvfs * const out,
const struct statvfs * const in,
const Policy::StatFS policy)
const struct statvfs * const in)
{
switch(policy)
if(out->f_bfree < in->f_bfree)
{
case Policy::StatFS::SumUsedMaxFree:
if(out->f_bfree < in->f_bfree)
{
out->f_bfree = in->f_bfree;
out->f_bavail = in->f_bavail;
}
break;
default:
case Policy::StatFS::SumUsedSumFree:
out->f_bfree += in->f_bfree;
out->f_bavail += in->f_bavail;
break;
out->f_bfree = in->f_bfree;
out->f_bavail = in->f_bavail;
}
out->f_ffree += in->f_ffree;
@ -96,8 +84,7 @@ _merge_statvfs(struct statvfs * const out,
static
int
_statfs(const Policy::StatFS policy,
const vector<string> &srcmounts,
_statfs(const vector<string> &srcmounts,
struct statvfs &fsstat)
{
unsigned long min_bsize = ULONG_MAX;
@ -134,7 +121,7 @@ _statfs(const Policy::StatFS policy,
for(;fsstatiter != endfsstatiter;++fsstatiter)
{
_normalize_statvfs(&fsstatiter->second,min_bsize,min_frsize,min_namemax);
_merge_statvfs(&fsstat,&fsstatiter->second,policy);
_merge_statvfs(&fsstat,&fsstatiter->second);
}
}
@ -152,8 +139,7 @@ namespace mergerfs
const ugid::SetResetGuard uid;
const config::Config &config = config::get();
return _statfs(config.policy.statfs,
config.srcmounts,
return _statfs(config.srcmounts,
*stat);
}
}

6
src/write.cpp

@ -68,12 +68,6 @@ _process_kv(Config &config,
if(rv == 0)
config.policy.create = value;
}
else if(key == "statfs")
{
rv = (Policy::StatFS::fromString(value) != -1) ? 0 : -EINVAL;
if(rv == 0)
config.policy.statfs = value;
}
else
{
rv = -EINVAL;

Loading…
Cancel
Save