diff --git a/README.md b/README.md index 55eceb53..cae9745a 100644 --- a/README.md +++ b/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 :: +$ mergerfs -o create=epmfs,search=ff,action=ff :: ``` | Option | Values | Default | @@ -54,7 +55,6 @@ $ mergerfs -o create=epmfs,search=ff,action=ff,statfs=sumf :< | 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 #### ``` /.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 +``` diff --git a/src/config.cpp b/src/config.cpp index 0815a045..e9543092 100644 --- a/src/config.cpp +++ b/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(); } diff --git a/src/getxattr.cpp b/src/getxattr.cpp index 155cd9ef..eed257cc 100644 --- a/src/getxattr.cpp +++ b/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; diff --git a/src/option_parser.cpp b/src/option_parser.cpp index 8c3b0a1b..17b9fb1d 100644 --- a/src/option_parser.cpp +++ b/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]); diff --git a/src/policy.cpp b/src/policy.cpp index 51d509dc..7955fc9c 100644 --- a/src/policy.cpp +++ b/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"; - } - } } diff --git a/src/policy.hpp b/src/policy.hpp index bb84317d..5497a70c 100644 --- a/src/policy.hpp +++ b/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; diff --git a/src/setxattr.cpp b/src/setxattr.cpp index 0fb53190..f8f9fd61 100644 --- a/src/setxattr.cpp +++ b/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; diff --git a/src/statfs.cpp b/src/statfs.cpp index 336193b5..87220d53 100644 --- a/src/statfs.cpp +++ b/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 &srcmounts, +_statfs(const vector &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); } } diff --git a/src/write.cpp b/src/write.cpp index d0b27cb3..5de17dd4 100644 --- a/src/write.cpp +++ b/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;