Browse Source

Merge pull request #621 from trapexit/posix-acl

add support for POSIX ACLs
pull/622/head
trapexit 5 years ago
committed by GitHub
parent
commit
af1c0d78e8
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 25
      README.md
  2. 2
      libfuse/Makefile
  3. 2
      libfuse/include/fuse_common.h
  4. 4
      libfuse/lib/fuse_lowlevel.c
  5. 33
      man/mergerfs.1
  6. 13
      src/config.cpp
  7. 1
      src/config.hpp
  8. 2
      src/fuse_getxattr.cpp
  9. 23
      src/fuse_init.cpp
  10. 1
      src/fuse_listxattr.cpp
  11. 3
      src/option_parser.cpp

25
README.md

@ -1,6 +1,6 @@
% mergerfs(1) mergerfs user manual
% Antonio SJ Musumeci <trapexit@spawn.link>
% 2019-05-12
% 2019-05-18
# NAME
@ -31,6 +31,7 @@ mergerfs -o&lt;options&gt; &lt;branches&gt; &lt;mountpoint&gt;
* Handles pool of read-only and read/write drives
* Can turn read-only files into symlinks to underlying file
* Hard link copy-on-write / CoW
* supports POSIX ACLs
# How it works
@ -80,6 +81,7 @@ mergerfs does **not** support the copy-on-write (CoW) behavior found in **aufs**
* **link_cow=true|false**: When enabled if a regular file is opened which has a link count > 1 it will copy the file to a temporary file and rename over the original. Breaking the link and providing a basic copy-on-write function similar to cow-shell. (default: false)
* **statfs=base|full**: Controls how statfs works. 'base' means it will always use all branches in statfs calculations. 'full' is in effect path preserving and only includes drives where the path exists. (default: base)
* **statfs_ignore=none|ro|nc**: 'ro' will cause statfs calculations to ignore available space for branches mounted or tagged as 'read-only' or 'no create'. 'nc' will ignore available space for branches tagged as 'no create'. (default: none)
* **posix_acl=true|false:** enable POSIX ACL support (if supported by kernel and underlying filesystem). (default: false)
* **threads=num**: number of threads to use in multithreaded mode. When set to zero (the default) it will attempt to discover and use the number of logical cores. If the lookup fails it will fall back to using 4. If the thread count is set negative it will look up the number of cores then divide by the absolute value. ie. threads=-2 on an 8 core machine will result in 8 / 2 = 4 threads. There will always be at least 1 thread. NOTE: higher number of threads increases parallelism but usually decreases throughput. (default: number of cores) *NOTE2:* the option is unavailable when built with system libfuse.
* **fsname=name**: sets the name of the filesystem as seen in **mount**, **df**, etc. Defaults to a list of the source paths concatenated together with the longest common prefix removed.
* **func.&lt;func&gt;=&lt;policy&gt;**: sets the specific FUSE function's policy. See below for the list of value types. Example: **func.getattr=newest**
@ -964,15 +966,20 @@ For non-Linux systems mergerfs uses a read-write lock and changes credentials on
# PERFORMANCE TWEAKING
* try adding (or removing) `direct_io`
* try adding (or removing) `auto_cache`
* try adding (or removing) `kernel_cache`
* try adding (or removing) `splice_move`, `splice_read`, and `splice_write`
* try increasing cache timeouts `cache.attr`, `cache.entry`, `cache.negative_entry`
* try changing the number of worker threads
* try disabling `security_capability` or `xattr`
NOTE: be sure to read about these features before changing them
* add (or remove) `direct_io`
* add (or remove) `auto_cache`
* add (or remove) `kernel_cache`
* add (or remove) `splice_move`, `splice_read`, and `splice_write`
* increase cache timeouts `cache.attr`, `cache.entry`, `cache.negative_entry`
* enable `cache.open` and/or `cache.statfs`
* change the number opf worker threads
* disable `security_capability` and/or `xattr`
* disable `posix_acl`
* test theoretical performance using `nullrw` or mounting a ram disk
* use `symlinkify` if your data is largely static and you need native speed reads
* use `symlinkify` if your data is largely static
* use tiered cache drives
* use lvm and lvm cache to place a SSD in front of your HDDs (howto coming)

2
libfuse/Makefile

@ -1,4 +1,4 @@
VERSION = "2.9.7-mergerfs_2.26.0"
VERSION = "2.9.7-mergerfs_2.27.0"
OPT = -O2
ifeq ($(DEBUG),1)

2
libfuse/include/fuse_common.h

@ -112,6 +112,8 @@ struct fuse_file_info {
#define FUSE_CAP_SPLICE_READ (1 << 9)
#define FUSE_CAP_FLOCK_LOCKS (1 << 10)
#define FUSE_CAP_IOCTL_DIR (1 << 11)
#define FUSE_CAP_POSIX_ACL (1 << 19)
/**
* Ioctl flags

4
libfuse/lib/fuse_lowlevel.c

@ -1795,6 +1795,8 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
f->conn.capable |= FUSE_CAP_DONT_MASK;
if (arg->flags & FUSE_FLOCK_LOCKS)
f->conn.capable |= FUSE_CAP_FLOCK_LOCKS;
if (arg->flags & FUSE_POSIX_ACL)
f->conn.capable |= FUSE_CAP_POSIX_ACL;
} else {
f->conn.async_read = 0;
f->conn.max_readahead = 0;
@ -1861,6 +1863,8 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
outarg.flags |= FUSE_DONT_MASK;
if (f->conn.want & FUSE_CAP_FLOCK_LOCKS)
outarg.flags |= FUSE_FLOCK_LOCKS;
if (f->conn.want & FUSE_CAP_POSIX_ACL)
outarg.flags |= FUSE_POSIX_ACL;
outarg.max_readahead = f->conn.max_readahead;
outarg.max_write = f->conn.max_write;
if (f->conn.proto_minor >= 13) {

33
man/mergerfs.1

@ -1,7 +1,7 @@
.\"t
.\" Automatically generated by Pandoc 1.19.2.4
.\"
.TH "mergerfs" "1" "2019\-05\-12" "mergerfs user manual" ""
.TH "mergerfs" "1" "2019\-05\-18" "mergerfs user manual" ""
.hy
.SH NAME
.PP
@ -41,6 +41,8 @@ Handles pool of read\-only and read/write drives
Can turn read\-only files into symlinks to underlying file
.IP \[bu] 2
Hard link copy\-on\-write / CoW
.IP \[bu] 2
supports POSIX ACLs
.SH How it works
.PP
mergerfs logically merges multiple paths together.
@ -175,6 +177,10 @@ calculations to ignore available space for branches mounted or tagged as
create\[aq].
(default: none)
.IP \[bu] 2
\f[B]posix_acl=true|false:\f[] enable POSIX ACL support (if supported by
kernel and underlying filesystem).
(default: false)
.IP \[bu] 2
\f[B]threads=num\f[]: number of threads to use in multithreaded mode.
When set to zero (the default) it will attempt to discover and use the
number of logical cores.
@ -1925,28 +1931,35 @@ be used so threads trying to change credentials don\[aq]t starve.
This isn\[aq]t the best solution but should work reasonably well
assuming there are few users.
.SH PERFORMANCE TWEAKING
.PP
NOTE: be sure to read about these features before changing them
.IP \[bu] 2
try adding (or removing) \f[C]direct_io\f[]
add (or remove) \f[C]direct_io\f[]
.IP \[bu] 2
try adding (or removing) \f[C]auto_cache\f[]
add (or remove) \f[C]auto_cache\f[]
.IP \[bu] 2
try adding (or removing) \f[C]kernel_cache\f[]
add (or remove) \f[C]kernel_cache\f[]
.IP \[bu] 2
try adding (or removing) \f[C]splice_move\f[], \f[C]splice_read\f[], and
add (or remove) \f[C]splice_move\f[], \f[C]splice_read\f[], and
\f[C]splice_write\f[]
.IP \[bu] 2
try increasing cache timeouts \f[C]cache.attr\f[], \f[C]cache.entry\f[],
increase cache timeouts \f[C]cache.attr\f[], \f[C]cache.entry\f[],
\f[C]cache.negative_entry\f[]
.IP \[bu] 2
try changing the number of worker threads
enable \f[C]cache.open\f[] and/or \f[C]cache.statfs\f[]
.IP \[bu] 2
try disabling \f[C]security_capability\f[] or \f[C]xattr\f[]
change the number opf worker threads
.IP \[bu] 2
disable \f[C]security_capability\f[] and/or \f[C]xattr\f[]
.IP \[bu] 2
disable \f[C]posix_acl\f[]
.IP \[bu] 2
test theoretical performance using \f[C]nullrw\f[] or mounting a ram
disk
.IP \[bu] 2
use \f[C]symlinkify\f[] if your data is largely static and you need
native speed reads
use \f[C]symlinkify\f[] if your data is largely static
.IP \[bu] 2
use tiered cache drives
.IP \[bu] 2
use lvm and lvm cache to place a SSD in front of your HDDs (howto
coming)

13
src/config.cpp

@ -14,17 +14,17 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <string>
#include <vector>
#include <unistd.h>
#include <sys/stat.h>
#include "config.hpp"
#include "errno.hpp"
#include "fs.hpp"
#include "rwlock.hpp"
#include <unistd.h>
#include <sys/stat.h>
#include <string>
#include <vector>
#define MINFREESPACE_DEFAULT (4294967295ULL)
#define POLICYINIT(X) X(policies[FuseFunc::Enum::X])
@ -48,6 +48,7 @@ Config::Config()
xattr(0),
statfs(StatFS::BASE),
statfs_ignore(StatFSIgnore::NONE),
posix_acl(false),
POLICYINIT(access),
POLICYINIT(chmod),
POLICYINIT(chown),

1
src/config.hpp

@ -78,6 +78,7 @@ public:
int xattr;
StatFS::Enum statfs;
StatFSIgnore::Enum statfs_ignore;
bool posix_acl;
public:
const Policy *policies[FuseFunc::Enum::END];

2
src/fuse_getxattr.cpp

@ -346,6 +346,8 @@ namespace l
l::getxattr_controlfile_pid(attrvalue);
else if(attr[2] == "direct_io")
l::getxattr_controlfile_bool(config.direct_io,attrvalue);
else if(attr[2] == "posix_acl")
l::getxattr_controlfile_bool(config.posix_acl,attrvalue);
break;
case 4:

23
src/fuse_init.cpp

@ -19,6 +19,17 @@
#include <fuse.h>
namespace l
{
void
want_if_capable(fuse_conn_info *conn_,
const int flag_)
{
if(conn_->capable & flag_)
conn_->want |= flag_;
}
}
namespace FUSE
{
void *
@ -26,11 +37,13 @@ namespace FUSE
{
ugid::init();
conn_->want |= FUSE_CAP_ASYNC_READ;
conn_->want |= FUSE_CAP_ATOMIC_O_TRUNC;
conn_->want |= FUSE_CAP_BIG_WRITES;
conn_->want |= FUSE_CAP_DONT_MASK;
conn_->want |= FUSE_CAP_IOCTL_DIR;
l::want_if_capable(conn_,FUSE_CAP_ASYNC_READ);
l::want_if_capable(conn_,FUSE_CAP_ATOMIC_O_TRUNC);
l::want_if_capable(conn_,FUSE_CAP_BIG_WRITES);
l::want_if_capable(conn_,FUSE_CAP_DONT_MASK);
l::want_if_capable(conn_,FUSE_CAP_IOCTL_DIR);
if(Config::get().posix_acl)
l::want_if_capable(conn_,FUSE_CAP_POSIX_ACL);
return &Config::get_writable();
}

1
src/fuse_listxattr.cpp

@ -59,6 +59,7 @@ namespace l
("user.mergerfs.nullrw")
("user.mergerfs.pid")
("user.mergerfs.policies")
("user.mergerfs.posix_acl")
("user.mergerfs.security_capability")
("user.mergerfs.srcmounts")
("user.mergerfs.statfs")

3
src/option_parser.cpp

@ -305,6 +305,8 @@ parse_and_process_kv_arg(Config &config,
rv = parse_and_process_statfsignore(value,config.statfs_ignore);
else if(key == "fsname")
rv = parse_and_process(value,config.fsname);
else if(key == "posix_acl")
rv = parse_and_process(value,config.posix_acl);
}
if(rv == -1)
@ -433,6 +435,7 @@ usage(void)
" as 'read only' or 'no create'. 'nc' will ignore\n"
" available space for branches tagged as\n"
" 'no create'. default = none\n"
" -o posix_acl=<bool> enable POSIX ACL support\n"
<< std::endl;
}

Loading…
Cancel
Save