From 08366a35be56f34b3819d9c66cd2dba89be5dad2 Mon Sep 17 00:00:00 2001 From: Antonio SJ Musumeci Date: Tue, 10 Mar 2015 18:42:59 -0400 Subject: [PATCH] match cli options to xattrs --- README.md | 6 +++--- src/config.cpp | 48 +++++++++++++++++++++++++++++++++++-------- src/config.hpp | 6 ++++-- src/option_parser.cpp | 33 ++++++++++++++++++++++------- src/setxattr.cpp | 42 ++++++++++++------------------------- 5 files changed, 86 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index c9132829..58e9a4ee 100644 --- a/README.md +++ b/README.md @@ -20,11 +20,11 @@ Why create mergerfs when those exist? mhddfs isn't really maintained or flexible ###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.=`. -To set all function policies in a category use `category.<category>=<policy>` such as `category.create=mfs`. +To set all function policies in a category use `category.=` 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### diff --git a/src/config.cpp b/src/config.cpp index 3cf4fe93..88c967ee 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -27,6 +27,7 @@ #include #include +#include #include "config.hpp" #include "rwlock.hpp" @@ -69,22 +70,53 @@ namespace mergerfs { 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++) { - if(FuseFunc::fusefuncs[i] == category) + if(FuseFunc::fusefuncs[i] == (Category::Enum::Type)*category) policies[(FuseFunc::Enum::Type)FuseFunc::fusefuncs[i]] = policy; } + + return 0; } const Config& diff --git a/src/config.hpp b/src/config.hpp index 2c544b4f..f673dc5a 100644 --- a/src/config.hpp +++ b/src/config.hpp @@ -45,8 +45,10 @@ namespace mergerfs Config(); 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: std::string destmount; diff --git a/src/option_parser.cpp b/src/option_parser.cpp index 9d83b5d7..12d66b36 100644 --- a/src/option_parser.cpp +++ b/src/option_parser.cpp @@ -41,6 +41,31 @@ using std::string; using std::vector; 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 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 int process_opt(config::Config &config, @@ -53,13 +78,7 @@ process_opt(config::Config &config, switch(argvalue.size()) { 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; default: diff --git a/src/setxattr.cpp b/src/setxattr.cpp index a9d913ce..b7a452d2 100644 --- a/src/setxattr.cpp +++ b/src/setxattr.cpp @@ -167,27 +167,19 @@ _setxattr_srcmounts(vector &srcmounts, static 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) 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; } @@ -199,22 +191,14 @@ _setxattr_controlfile_category_policy(config::Config &config, const string &attrval, 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) 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; } @@ -246,7 +230,7 @@ _setxattr_controlfile(config::Config &config, attrval, flags); 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], attrval, flags);