mirror of https://github.com/trapexit/mergerfs.git
Browse Source
add tagging branches RW/RO/NW
add tagging branches RW/RO/NW
This allows users to tag a branch as readonly or not for writing regardless of how the filesystem is mounted. Should simplify deployments and offer more flexibility.pull/527/head
Antonio SJ Musumeci
6 years ago
57 changed files with 1669 additions and 1293 deletions
-
64README.md
-
113man/mergerfs.1
-
8src/access.cpp
-
216src/branch.cpp
-
55src/branch.hpp
-
8src/chmod.cpp
-
8src/chown.cpp
-
8src/config.cpp
-
5src/config.hpp
-
10src/create.cpp
-
14src/fs.cpp
-
4src/fs.hpp
-
17src/fs_glob.cpp
-
4src/fs_glob.hpp
-
18src/fs_info.cpp
-
5src/fs_info.hpp
-
8src/getattr.cpp
-
39src/getxattr.cpp
-
8src/ioctl.cpp
-
32src/link.cpp
-
9src/listxattr.cpp
-
10src/mkdir.cpp
-
10src/mknod.cpp
-
8src/open.cpp
-
30src/option_parser.cpp
-
37src/policy.hpp
-
94src/policy_all.cpp
-
153src/policy_epall.cpp
-
165src/policy_epff.cpp
-
235src/policy_eplfs.cpp
-
235src/policy_eplus.cpp
-
235src/policy_epmfs.cpp
-
4src/policy_eprand.cpp
-
2src/policy_erofs.cpp
-
51src/policy_error.hpp
-
100src/policy_ff.cpp
-
2src/policy_invalid.cpp
-
146src/policy_lfs.cpp
-
145src/policy_lus.cpp
-
141src/policy_mfs.cpp
-
200src/policy_newest.cpp
-
4src/policy_rand.cpp
-
10src/readdir.cpp
-
8src/readlink.cpp
-
8src/removexattr.cpp
-
40src/rename.cpp
-
8src/rmdir.cpp
-
117src/setxattr.cpp
-
18src/statfs.cpp
-
12src/str.cpp
-
4src/str.hpp
-
10src/symlink.cpp
-
8src/truncate.cpp
-
8src/unlink.cpp
-
8src/utimens.cpp
-
18src/write.cpp
-
25src/write_buf.cpp
@ -0,0 +1,216 @@ |
|||||
|
/*
|
||||
|
ISC License |
||||
|
|
||||
|
Copyright (c) 2018, Antonio SJ Musumeci <trapexit@spawn.link> |
||||
|
|
||||
|
Permission to use, copy, modify, and/or distribute this software for any |
||||
|
purpose with or without fee is hereby granted, provided that the above |
||||
|
copyright notice and this permission notice appear in all copies. |
||||
|
|
||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
||||
|
*/ |
||||
|
|
||||
|
#include "branch.hpp"
|
||||
|
#include "fs.hpp"
|
||||
|
#include "fs_glob.hpp"
|
||||
|
#include "str.hpp"
|
||||
|
|
||||
|
#include <fnmatch.h>
|
||||
|
|
||||
|
#include <string>
|
||||
|
|
||||
|
using std::string; |
||||
|
using std::vector; |
||||
|
|
||||
|
bool |
||||
|
Branch::ro(void) const |
||||
|
{ |
||||
|
return (mode == Branch::RO); |
||||
|
} |
||||
|
|
||||
|
bool |
||||
|
Branch::ro_or_nw(void) const |
||||
|
{ |
||||
|
return ((mode == Branch::RO) || |
||||
|
(mode == Branch::NW)); |
||||
|
} |
||||
|
|
||||
|
string |
||||
|
Branches::to_string(const bool mode_) const |
||||
|
{ |
||||
|
string tmp; |
||||
|
|
||||
|
for(size_t i = 0; i < size(); i++) |
||||
|
{ |
||||
|
const Branch &branch = (*this)[i]; |
||||
|
|
||||
|
tmp += branch.path; |
||||
|
|
||||
|
if(mode_) |
||||
|
{ |
||||
|
tmp += '='; |
||||
|
switch(branch.mode) |
||||
|
{ |
||||
|
default: |
||||
|
case Branch::RW: |
||||
|
tmp += "RW"; |
||||
|
break; |
||||
|
case Branch::RO: |
||||
|
tmp += "RO"; |
||||
|
break; |
||||
|
case Branch::NW: |
||||
|
tmp += "NW"; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
tmp += ':'; |
||||
|
} |
||||
|
|
||||
|
if(*tmp.rbegin() == ':') |
||||
|
tmp.erase(tmp.size() - 1); |
||||
|
|
||||
|
return tmp; |
||||
|
} |
||||
|
|
||||
|
void |
||||
|
Branches::to_paths(vector<string> &vec_) const |
||||
|
{ |
||||
|
for(size_t i = 0; i < size(); i++) |
||||
|
{ |
||||
|
const Branch &branch = (*this)[i]; |
||||
|
|
||||
|
vec_.push_back(branch.path); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
static |
||||
|
void |
||||
|
parse(const string &str_, |
||||
|
Branches &branches_) |
||||
|
{ |
||||
|
string str; |
||||
|
Branch branch; |
||||
|
vector<string> globbed; |
||||
|
|
||||
|
str = str_; |
||||
|
branch.mode = Branch::INVALID; |
||||
|
if(str::ends_with(str,"=RO")) |
||||
|
branch.mode = Branch::RO; |
||||
|
else if(str::ends_with(str,"=RW")) |
||||
|
branch.mode = Branch::RW; |
||||
|
else if(str::ends_with(str,"=NW")) |
||||
|
branch.mode = Branch::NW; |
||||
|
|
||||
|
if(branch.mode != Branch::INVALID) |
||||
|
str.resize(str.size() - 3); |
||||
|
else |
||||
|
branch.mode = Branch::RW; |
||||
|
|
||||
|
fs::glob(str,globbed); |
||||
|
fs::realpathize(globbed); |
||||
|
for(size_t i = 0; i < globbed.size(); i++) |
||||
|
{ |
||||
|
branch.path = globbed[i]; |
||||
|
branches_.push_back(branch); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void |
||||
|
Branches::set(const std::string &str_) |
||||
|
{ |
||||
|
vector<string> paths; |
||||
|
|
||||
|
clear(); |
||||
|
|
||||
|
str::split(paths,str_,':'); |
||||
|
|
||||
|
for(size_t i = 0; i < paths.size(); i++) |
||||
|
{ |
||||
|
Branches branches; |
||||
|
|
||||
|
parse(paths[i],branches); |
||||
|
|
||||
|
insert(end(), |
||||
|
branches.begin(), |
||||
|
branches.end()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void |
||||
|
Branches::add_begin(const std::string &str_) |
||||
|
{ |
||||
|
vector<string> paths; |
||||
|
|
||||
|
str::split(paths,str_,':'); |
||||
|
|
||||
|
for(size_t i = 0; i < paths.size(); i++) |
||||
|
{ |
||||
|
Branches branches; |
||||
|
|
||||
|
parse(paths[i],branches); |
||||
|
|
||||
|
insert(begin(), |
||||
|
branches.begin(), |
||||
|
branches.end()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void |
||||
|
Branches::add_end(const std::string &str_) |
||||
|
{ |
||||
|
vector<string> paths; |
||||
|
|
||||
|
str::split(paths,str_,':'); |
||||
|
|
||||
|
for(size_t i = 0; i < paths.size(); i++) |
||||
|
{ |
||||
|
Branches branches; |
||||
|
|
||||
|
parse(paths[i],branches); |
||||
|
|
||||
|
insert(end(), |
||||
|
branches.begin(), |
||||
|
branches.end()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void |
||||
|
Branches::erase_begin(void) |
||||
|
{ |
||||
|
erase(begin()); |
||||
|
} |
||||
|
|
||||
|
void |
||||
|
Branches::erase_end(void) |
||||
|
{ |
||||
|
pop_back(); |
||||
|
} |
||||
|
|
||||
|
void |
||||
|
Branches::erase_fnmatch(const std::string &str_) |
||||
|
{ |
||||
|
vector<string> patterns; |
||||
|
|
||||
|
str::split(patterns,str_,':'); |
||||
|
|
||||
|
for(iterator i = begin(); i != end();) |
||||
|
{ |
||||
|
int match = FNM_NOMATCH; |
||||
|
|
||||
|
for(vector<string>::const_iterator pi = patterns.begin(); |
||||
|
pi != patterns.end() && match != 0; |
||||
|
++pi) |
||||
|
{ |
||||
|
match = ::fnmatch(pi->c_str(),i->path.c_str(),0); |
||||
|
} |
||||
|
|
||||
|
i = ((match == 0) ? erase(i) : (i+1)); |
||||
|
} |
||||
|
} |
@ -0,0 +1,55 @@ |
|||||
|
/*
|
||||
|
ISC License |
||||
|
|
||||
|
Copyright (c) 2018, Antonio SJ Musumeci <trapexit@spawn.link> |
||||
|
|
||||
|
Permission to use, copy, modify, and/or distribute this software for any |
||||
|
purpose with or without fee is hereby granted, provided that the above |
||||
|
copyright notice and this permission notice appear in all copies. |
||||
|
|
||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
||||
|
*/ |
||||
|
|
||||
|
#pragma once
|
||||
|
|
||||
|
#include <string>
|
||||
|
#include <vector>
|
||||
|
|
||||
|
struct Branch |
||||
|
{ |
||||
|
enum Mode |
||||
|
{ |
||||
|
INVALID, |
||||
|
RO, |
||||
|
RW, |
||||
|
NW |
||||
|
}; |
||||
|
|
||||
|
Mode mode; |
||||
|
std::string path; |
||||
|
|
||||
|
bool ro(void) const; |
||||
|
bool ro_or_nw(void) const; |
||||
|
}; |
||||
|
|
||||
|
class Branches : public std::vector<Branch> |
||||
|
{ |
||||
|
public: |
||||
|
std::string to_string(const bool mode_ = false) const; |
||||
|
|
||||
|
void to_paths(std::vector<std::string> &vec_) const; |
||||
|
|
||||
|
public: |
||||
|
void set(const std::string &str_); |
||||
|
void add_begin(const std::string &str_); |
||||
|
void add_end(const std::string &str_); |
||||
|
void erase_begin(void); |
||||
|
void erase_end(void); |
||||
|
void erase_fnmatch(const std::string &str_); |
||||
|
}; |
@ -0,0 +1,51 @@ |
|||||
|
/*
|
||||
|
ISC License |
||||
|
|
||||
|
Copyright (c) 2018, Antonio SJ Musumeci <trapexit@spawn.link> |
||||
|
|
||||
|
Permission to use, copy, modify, and/or distribute this software for any |
||||
|
purpose with or without fee is hereby granted, provided that the above |
||||
|
copyright notice and this permission notice appear in all copies. |
||||
|
|
||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
||||
|
*/ |
||||
|
|
||||
|
#pragma once
|
||||
|
|
||||
|
#define error_and_continue(CUR,ERR) \
|
||||
|
{ \ |
||||
|
policy::calc_error(CUR,ERR); \ |
||||
|
continue; \ |
||||
|
} |
||||
|
|
||||
|
namespace policy |
||||
|
{ |
||||
|
static |
||||
|
inline |
||||
|
void |
||||
|
calc_error(int &cur_, |
||||
|
int err_) |
||||
|
{ |
||||
|
switch(cur_) |
||||
|
{ |
||||
|
default: |
||||
|
case ENOENT: |
||||
|
cur_ = err_; |
||||
|
break; |
||||
|
case ENOSPC: |
||||
|
if(err_ != ENOENT) |
||||
|
cur_ = err_; |
||||
|
break; |
||||
|
case EROFS: |
||||
|
if((err_ != ENOENT) && (err_ != ENOSPC)) |
||||
|
cur_ = err_; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue