Browse Source

match cli options to xattrs

pull/60/head
Antonio SJ Musumeci 10 years ago
parent
commit
08366a35be
  1. 6
      README.md
  2. 48
      src/config.cpp
  3. 6
      src/config.hpp
  4. 33
      src/option_parser.cpp
  5. 42
      src/setxattr.cpp

6
README.md

@ -20,11 +20,11 @@ Why create mergerfs when those exist? mhddfs isn't really maintained or flexible
###options### ###options###
All [FUSE](http://fuse.sourceforge.net) functions which have a category (see below) are option keys. The syntax being `<func>=<policy>`.
All [FUSE](http://fuse.sourceforge.net) functions which have a category (see below) are option keys. The syntax being `func.<func>=<policy>`.
To set all function policies in a category use `category.&lt;category&gt;=&lt;policy&gt;` such as `category.create=mfs`.
To set all function policies in a category use `category.<category>=<policy>` such as `category.create=mfs`.
They are evaluated in the order listed so if the options are `rmdir=rand,category.action=ff` the `action` category setting will override the `rmdir` setting.
They are evaluated in the order listed so if the options are `func.rmdir=rand,category.action=ff` the `action` category setting will override the `rmdir` setting.
###srcpoints### ###srcpoints###

48
src/config.cpp

@ -27,6 +27,7 @@
#include <unistd.h> #include <unistd.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <errno.h>
#include "config.hpp" #include "config.hpp"
#include "rwlock.hpp" #include "rwlock.hpp"
@ -69,22 +70,53 @@ namespace mergerfs
{ {
pthread_rwlock_init(&srcmountslock,NULL); pthread_rwlock_init(&srcmountslock,NULL);
setpolicy(Category::Enum::action,Policy::Enum::all);
setpolicy(Category::Enum::create,Policy::Enum::epmfs);
setpolicy(Category::Enum::search,Policy::Enum::ff);
set_category_policy("action","all");
set_category_policy("create","epmfs");
set_category_policy("search","ff");
} }
void
Config::setpolicy(const Category::Enum::Type category,
const Policy::Enum::Type policy_)
int
Config::set_func_policy(const string &fusefunc_,
const string &policy_)
{ {
const Policy *policy = Policy::find(policy_);
const Policy *policy;
const FuseFunc *fusefunc;
fusefunc = FuseFunc::find(fusefunc_);
if(fusefunc == FuseFunc::invalid)
return (errno=ENODATA,-1);
policy = Policy::find(policy_);
if(policy == Policy::invalid)
return (errno=EINVAL,-1);
policies[(FuseFunc::Enum::Type)*fusefunc] = policy;
return 0;
}
int
Config::set_category_policy(const string &category_,
const string &policy_)
{
const Policy *policy;
const Category *category;
category = Category::find(category_);
if(category == Category::invalid)
return (errno=ENODATA,-1);
policy = Policy::find(policy_);
if(policy == Policy::invalid)
return (errno=EINVAL,-1);
for(int i = 0; i < FuseFunc::Enum::END; i++) for(int i = 0; i < FuseFunc::Enum::END; i++)
{ {
if(FuseFunc::fusefuncs[i] == category)
if(FuseFunc::fusefuncs[i] == (Category::Enum::Type)*category)
policies[(FuseFunc::Enum::Type)FuseFunc::fusefuncs[i]] = policy; policies[(FuseFunc::Enum::Type)FuseFunc::fusefuncs[i]] = policy;
} }
return 0;
} }
const Config& const Config&

6
src/config.hpp

@ -45,8 +45,10 @@ namespace mergerfs
Config(); Config();
public: public:
void setpolicy(const Category::Enum::Type category,
const Policy::Enum::Type policy);
int set_func_policy(const std::string &fusefunc_,
const std::string &policy_);
int set_category_policy(const std::string &category,
const std::string &policy);
public: public:
std::string destmount; std::string destmount;

33
src/option_parser.cpp

@ -41,6 +41,31 @@ using std::string;
using std::vector; using std::vector;
using namespace mergerfs; using namespace mergerfs;
static
int
parse_and_process_kv_arg(config::Config &config,
const std::string &key,
const std::string &value)
{
int rv;
std::vector<std::string> keypart;
str::split(keypart,key,'.');
if(keypart.size() != 2)
return 1;
rv = 0;
if(keypart[0] == "func")
rv = config.set_func_policy(keypart[1],value);
else if(keypart[0] == "category")
rv = config.set_category_policy(keypart[1],value);
if(rv == -1)
rv = 1;
return rv;
}
static static
int int
process_opt(config::Config &config, process_opt(config::Config &config,
@ -53,13 +78,7 @@ process_opt(config::Config &config,
switch(argvalue.size()) switch(argvalue.size())
{ {
case 2: case 2:
{
FuseFunc fusefunc = FuseFunc::find(argvalue[0]);
if(fusefunc != FuseFunc::invalid)
config.policies[(FuseFunc::Enum::Type)*fusefunc] = Policy::find(argvalue[1]);
else
rv = 1;
}
rv = parse_and_process_kv_arg(config,argvalue[0],argvalue[1]);
break; break;
default: default:

42
src/setxattr.cpp

@ -167,27 +167,19 @@ _setxattr_srcmounts(vector<string> &srcmounts,
static static
int int
_setxattr_controlfile_func_policy(const Policy *policies[],
const char *funcname,
const string &attrval,
const int flags)
_setxattr_controlfile_func_policy(config::Config &config,
const char *funcname,
const string &attrval,
const int flags)
{ {
const FuseFunc *fusefunc;
const Policy *policy;
fusefunc = FuseFunc::find(funcname);
if(fusefunc == FuseFunc::invalid)
return -ENOATTR;
int rv;
if((flags & XATTR_CREATE) == XATTR_CREATE) if((flags & XATTR_CREATE) == XATTR_CREATE)
return -EEXIST; return -EEXIST;
policy = Policy::find(attrval);
if((policy == Policy::invalid) &&
(attrval != "invalid"))
return -EINVAL;
policies[(FuseFunc::Enum::Type)*fusefunc] = policy;
rv = config.set_func_policy(funcname,attrval);
if(rv == -1)
return -errno;
return 0; return 0;
} }
@ -199,22 +191,14 @@ _setxattr_controlfile_category_policy(config::Config &config,
const string &attrval, const string &attrval,
const int flags) const int flags)
{ {
const Category *category;
const Policy *policy;
category = Category::find(categoryname);
if(category == Category::invalid)
return -ENOATTR;
int rv;
if((flags & XATTR_CREATE) == XATTR_CREATE) if((flags & XATTR_CREATE) == XATTR_CREATE)
return -EEXIST; return -EEXIST;
policy = Policy::find(attrval);
if((policy == Policy::invalid) &&
(attrval != "invalid"))
return -EINVAL;
config.setpolicy(*category,*policy);
rv = config.set_category_policy(categoryname,attrval);
if(rv == -1)
return -errno;
return 0; return 0;
} }
@ -246,7 +230,7 @@ _setxattr_controlfile(config::Config &config,
attrval, attrval,
flags); flags);
else if(!strncmp("func.",attrbasename,sizeof("func.")-1)) else if(!strncmp("func.",attrbasename,sizeof("func.")-1))
return _setxattr_controlfile_func_policy(config.policies,
return _setxattr_controlfile_func_policy(config,
&attrbasename[sizeof("func.")-1], &attrbasename[sizeof("func.")-1],
attrval, attrval,
flags); flags);

Loading…
Cancel
Save