Browse Source

README: misc updates and tweaks

pull/858/head
Antonio SJ Musumeci 4 years ago
parent
commit
e9e17baf5e
  1. 114
      README.md
  2. 219
      man/mergerfs.1

114
README.md

@ -31,7 +31,7 @@ mergerfs -o<options> <branches> <mountpoint>
* Handles pool of read-only and read/write drives * Handles pool of read-only and read/write drives
* Can turn read-only files into symlinks to underlying file * Can turn read-only files into symlinks to underlying file
* Hard link copy-on-write / CoW * Hard link copy-on-write / CoW
* supports POSIX ACLs
* Support for POSIX ACLs
# HOW IT WORKS # HOW IT WORKS
@ -59,7 +59,7 @@ A + B = C
+-- file6 +-- file6
``` ```
mergerfs does **not** support the copy-on-write (CoW) behavior found in **aufs** and **overlayfs**. You can **not** mount a read-only filesystem and write to it. However, mergerfs will ignore read-only drives when creating new files so you can mix read-write and read-only drives. It also does **not** split data across drives. It is not RAID0 / striping. It is simply a union.
mergerfs does **NOT** support the copy-on-write (CoW) or whiteout behaviors found in **aufs** and **overlayfs**. You can **not** mount a read-only filesystem and write to it. However, mergerfs will ignore read-only drives when creating new files so you can mix read-write and read-only drives. It also does **NOT** split data across drives. It is not RAID0 / striping. It is simply a union of other filesystems.
# TERMINOLOGY # TERMINOLOGY
@ -67,9 +67,9 @@ mergerfs does **not** support the copy-on-write (CoW) behavior found in **aufs**
* branch: A base path used in the pool. * branch: A base path used in the pool.
* pool: The mergerfs mount. The union of the branches. * pool: The mergerfs mount. The union of the branches.
* relative path: The path in the pool relative to the branch and mount. * relative path: The path in the pool relative to the branch and mount.
* function: A filesystem call (open, unlink, create, getattr, rmdir, etc.)
* category: A collection of functions based on basic behavior (action, create, search).
* policy: The algorithm used to select a file when performing a function. * policy: The algorithm used to select a file when performing a function.
* function: A filesystem call (open, unlink, create, getattr, etc.)
* category: A collection of functions (action, create, search).
* path preservation: Aspect of some policies which includes checking the path for which a file would be created. * path preservation: Aspect of some policies which includes checking the path for which a file would be created.
@ -77,22 +77,25 @@ mergerfs does **not** support the copy-on-write (CoW) behavior found in **aufs**
If you don't already know that you have a special use case then just start with one of the following option sets. If you don't already know that you have a special use case then just start with one of the following option sets.
#### You don't need `mmap`
#### You need `mmap` (used by rtorrent and many sqlite3 base software)
`allow_other,use_ino,cache.files=partial,dropcacheonclose=true,category.create=mfs`
`use_ino,cache.files=off,dropcacheonclose=true,allow_other,category.create=mfs`
#### You don't need `mmap`
#### You do need `mmap` (used by rtorrent and some other programs)
`allow_other,use_ino,cache.files=off,dropcacheonclose=true,category.create=mfs`
`use_ino,cache.files=partial,dropcacheonclose=true,allow_other,category.create=mfs`
See the mergerfs [wiki for real world deployments](https://github.com/trapexit/mergerfs/wiki/Real-World-Deployments) for comparisons / ideas. See the mergerfs [wiki for real world deployments](https://github.com/trapexit/mergerfs/wiki/Real-World-Deployments) for comparisons / ideas.
# OPTIONS # OPTIONS
These options are the same regardless you use them with the `mergerfs` commandline program, used in fstab, or in a config file.
### mount options ### mount options
* **config**: Path to a config file. Same arguments as below in key=val format.
* **config**: Path to a config file. Same arguments as below in key=val / ini style format.
* **branches**: Colon delimited list of branches. * **branches**: Colon delimited list of branches.
* **allow_other**: A libfuse option which allows users besides the one which ran mergerfs to see the filesystem. This is required for most use-cases. * **allow_other**: A libfuse option which allows users besides the one which ran mergerfs to see the filesystem. This is required for most use-cases.
* **minfreespace=SIZE**: The minimum space value used for creation policies. Can be overridden by branch specific option. Understands 'K', 'M', and 'G' to represent kilobyte, megabyte, and gigabyte respectively. (default: 4G) * **minfreespace=SIZE**: The minimum space value used for creation policies. Can be overridden by branch specific option. Understands 'K', 'M', and 'G' to represent kilobyte, megabyte, and gigabyte respectively. (default: 4G)
@ -101,7 +104,7 @@ See the mergerfs [wiki for real world deployments](https://github.com/trapexit/m
* **inodecalc=passthrough|path-hash|devino-hash|hybrid-hash**: Selects the inode calculation algorithm. (default: hybrid-hash) * **inodecalc=passthrough|path-hash|devino-hash|hybrid-hash**: Selects the inode calculation algorithm. (default: hybrid-hash)
* **dropcacheonclose=BOOL**: When a file is requested to be closed call `posix_fadvise` on it first to instruct the kernel that we no longer need the data and it can drop its cache. Recommended when **cache.files=partial|full|auto-full** to limit double caching. (default: false) * **dropcacheonclose=BOOL**: When a file is requested to be closed call `posix_fadvise` on it first to instruct the kernel that we no longer need the data and it can drop its cache. Recommended when **cache.files=partial|full|auto-full** to limit double caching. (default: false)
* **symlinkify=BOOL**: When enabled and a file is not writable and its mtime or ctime is older than **symlinkify_timeout** files will be reported as symlinks to the original files. Please read more below before using. (default: false) * **symlinkify=BOOL**: When enabled and a file is not writable and its mtime or ctime is older than **symlinkify_timeout** files will be reported as symlinks to the original files. Please read more below before using. (default: false)
* **symlinkify_timeout=INT**: Time to wait, in seconds, to activate the **symlinkify** behavior. (default: 3600)
* **symlinkify_timeout=UINT**: Time to wait, in seconds, to activate the **symlinkify** behavior. (default: 3600)
* **nullrw=BOOL**: Turns reads and writes into no-ops. The request will succeed but do nothing. Useful for benchmarking mergerfs. (default: false) * **nullrw=BOOL**: Turns reads and writes into no-ops. The request will succeed but do nothing. Useful for benchmarking mergerfs. (default: false)
* **ignorepponrename=BOOL**: Ignore path preserving on rename. Typically rename and link act differently depending on the policy of `create` (read below). Enabling this will cause rename and link to always use the non-path preserving behavior. This means files, when renamed or linked, will stay on the same drive. (default: false) * **ignorepponrename=BOOL**: Ignore path preserving on rename. Typically rename and link act differently depending on the policy of `create` (read below). Enabling this will cause rename and link to always use the non-path preserving behavior. This means files, when renamed or linked, will stay on the same drive. (default: false)
* **security_capability=BOOL**: If false return ENOATTR when xattr security.capability is queried. (default: true) * **security_capability=BOOL**: If false return ENOATTR when xattr security.capability is queried. (default: true)
@ -112,16 +115,18 @@ See the mergerfs [wiki for real world deployments](https://github.com/trapexit/m
* **nfsopenhack=off|git|all**: A workaround for exporting mergerfs over NFS where there are issues with creating files for write while setting the mode to read-only. (default: off) * **nfsopenhack=off|git|all**: A workaround for exporting mergerfs over NFS where there are issues with creating files for write while setting the mode to read-only. (default: off)
* **posix_acl=BOOL**: Enable POSIX ACL support (if supported by kernel and underlying filesystem). (default: false) * **posix_acl=BOOL**: Enable POSIX ACL support (if supported by kernel and underlying filesystem). (default: false)
* **async_read=BOOL**: Perform reads asynchronously. If disabled or unavailable the kernel will ensure there is at most one pending read request per file handle and will attempt to order requests by offset. (default: true) * **async_read=BOOL**: Perform reads asynchronously. If disabled or unavailable the kernel will ensure there is at most one pending read request per file handle and will attempt to order requests by offset. (default: true)
* **fuse_msg_size=INT**: Set the max number of pages per FUSE message. Only available on Linux >= 4.20 and ignored otherwise. (min: 1; max: 256; default: 256)
* **fuse_msg_size=UINT**: Set the max number of pages per FUSE message. Only available on Linux >= 4.20 and ignored otherwise. (min: 1; max: 256; default: 256)
* **threads=INT**: Number of threads to use in multithreaded mode. When set to zero 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: 0) * **threads=INT**: Number of threads to use in multithreaded mode. When set to zero 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: 0)
* **fsname=STR**: 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. * **fsname=STR**: 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.FUNC=POLICY**: Sets the specific FUSE function's policy. See below for the list of value types. Example: **func.getattr=newest** * **func.FUNC=POLICY**: Sets the specific FUSE function's policy. See below for the list of value types. Example: **func.getattr=newest**
* **category.CATEGORY=POLICY**: Sets policy of all FUSE functions in the provided category. See POLICIES section for defaults. Example: **category.create=mfs**
* **cache.open=INT**: 'open' policy cache timeout in seconds. (default: 0)
* **cache.statfs=INT**: 'statfs' cache timeout in seconds. (default: 0)
* **cache.attr=INT**: File attribute cache timeout in seconds. (default: 1)
* **cache.entry=INT**: File name lookup cache timeout in seconds. (default: 1)
* **cache.negative_entry=INT**: Negative file name lookup cache timeout in seconds. (default: 0)
* **category.action=POLICY**: Sets policy of all FUSE functions in the action category. (default: epall)
* **category.create=POLICY**: Sets policy of all FUSE functions in the create category. (default: epmfs)
* **category.search=POLICY**: Sets policy of all FUSE functions in the search category. (default: ff)
* **cache.open=UINT**: 'open' policy cache timeout in seconds. (default: 0)
* **cache.statfs=UINT**: 'statfs' cache timeout in seconds. (default: 0)
* **cache.attr=UINT**: File attribute cache timeout in seconds. (default: 1)
* **cache.entry=UINT**: File name lookup cache timeout in seconds. (default: 1)
* **cache.negative_entry=UINT**: Negative file name lookup cache timeout in seconds. (default: 0)
* **cache.files=libfuse|off|partial|full|auto-full**: File page caching mode (default: libfuse) * **cache.files=libfuse|off|partial|full|auto-full**: File page caching mode (default: libfuse)
* **cache.writeback=BOOL**: Enable kernel writeback caching (default: false) * **cache.writeback=BOOL**: Enable kernel writeback caching (default: false)
* **cache.symlinks=BOOL**: Cache symlinks (if supported by kernel) (default: false) * **cache.symlinks=BOOL**: Cache symlinks (if supported by kernel) (default: false)
@ -139,17 +144,18 @@ See the mergerfs [wiki for real world deployments](https://github.com/trapexit/m
#### Value Types #### Value Types
* BOOL = 'true' | 'false' * BOOL = 'true' | 'false'
* INT = [0,MAX_INT]
* INT = [MIN_INT,MAX_INT]
* UINT = [0,MAX_INT]
* SIZE = 'NNM'; NN = INT, M = 'K' | 'M' | 'G' | 'T' * SIZE = 'NNM'; NN = INT, M = 'K' | 'M' | 'G' | 'T'
* STR = string * STR = string
* FUNC = FUSE function
* CATEGORY = FUSE function category
* FUNC = filesystem function
* CATEGORY = function category
* POLICY = mergerfs function policy * POLICY = mergerfs function policy
### branches ### branches
The 'branches' (formerly 'srcmounts') argument is a colon (':') delimited list of paths to be pooled together. It does not matter if the paths are on the same or different drives nor does it matter the filesystem (within reason). Used and available space will not be duplicated for paths on the same device and any features which aren't supported by the underlying filesystem (such as file attributes or extended attributes) will return the appropriate errors.
The 'branches' argument is a colon (':') delimited list of paths to be pooled together. It does not matter if the paths are on the same or different drives nor does it matter the filesystem (within reason). Used and available space will not be duplicated for paths on the same device and any features which aren't supported by the underlying filesystem (such as file attributes or extended attributes) will return the appropriate errors.
Branches currently have two options which can be set. A type which impacts whether or not the branch is included in a policy calculation and a individual minfreespace value. The values are set by prepending an `=` at the end of a branch designation and using commas as delimiters. Example: /mnt/drive=RW,1234 Branches currently have two options which can be set. A type which impacts whether or not the branch is included in a policy calculation and a individual minfreespace value. The values are set by prepending an `=` at the end of a branch designation and using commas as delimiters. Example: /mnt/drive=RW,1234
@ -270,16 +276,18 @@ This hack addresses the issue where the creation of a file with a read-only mode
Even though it's a more niche situation this hack breaks normal security and behavior and as such is `off` by default. If set to `git` it will only perform the hack when the path in question includes `/.git/`. `all` will result it it applying anytime a readonly file which is empty is opened for writing. Even though it's a more niche situation this hack breaks normal security and behavior and as such is `off` by default. If set to `git` it will only perform the hack when the path in question includes `/.git/`. `all` will result it it applying anytime a readonly file which is empty is opened for writing.
# FUNCTIONS / POLICIES / CATEGORIES
# FUNCTIONS, CATEGORIES and POLICIES
The POSIX filesystem API is made up of a number of functions. **creat**, **stat**, **chown**, etc. For ease of configuration in mergerfs most of the core functions are grouped into 3 categories: **action**, **create**, and **search**. These functions and categories can be assigned a policy which dictates which underlying branch/file/directory is chosen when performing that behavior. Any policy can be assigned to a function or category though some may not be very useful in practice. For instance: **rand** (random) may be useful for file creation (create) but could lead to very odd behavior if used for `chmod` if there were more than one copy of the file.
The POSIX filesystem API is made up of a number of functions. **creat**, **stat**, **chown**, etc. For ease of configuration in mergerfs most of the core functions are grouped into 3 categories: **action**, **create**, and **search**. These functions and categories can be assigned a policy which dictates which branch is chosen when performing that function.
Some functions, listed in the category `N/A` below, can not be assigned the normal policies. All functions which work on file handles use the handle which was acquired by `open` or `create`. `readdir` has no real need for a policy given the purpose is merely to return a list of entries in a directory. `statfs`'s behavior can be modified via other options. That said many times the current FUSE kernel driver will not always provide the file handle when a client calls `fgetattr`, `fchown`, `fchmod`, `futimens`, `ftruncate`, etc. This means it will call the regular, path based, versions.
Some functions, listed in the category `N/A` below, can not be assigned the normal policies. These functions work with file handles, rather than file paths, which were created by `open` or `create`. That said many times the current FUSE kernel driver will not always provide the file handle when a client calls `fgetattr`, `fchown`, `fchmod`, `futimens`, `ftruncate`, etc. This means it will call the regular, path based, versions. `readdir` has no real need for a policy given the purpose is merely to return a list of entries in a directory. `statfs`'s behavior can be modified via other options.
When using policies which are based on a branch's available space the base path provided is used. Not the full path to the file in question. Meaning that sub mounts won't be considered in the space calculations. The reason is that it doesn't really work for non-path preserving policies and can lead to non-obvious behaviors.
When using policies which are based on a branch's available space the base path provided is used. Not the full path to the file in question. Meaning that mounts in the branch won't be considered in the space calculations. The reason is that it doesn't really work for non-path preserving policies and can lead to non-obvious behaviors.
NOTE: While any policy can be assigned to a function or category though some may not be very useful in practice. For instance: **rand** (random) may be useful for file creation (create) but could lead to very odd behavior if used for `chmod` if there were more than one copy of the file.
#### Functions and their Category classifications
### Functions and their Category classifications
| Category | FUSE Functions | | Category | FUSE Functions |
|----------|-------------------------------------------------------------------------------------| |----------|-------------------------------------------------------------------------------------|
@ -288,7 +296,27 @@ When using policies which are based on a branch's available space the base path
| search | access, getattr, getxattr, ioctl (directories), listxattr, open, readlink | | search | access, getattr, getxattr, ioctl (directories), listxattr, open, readlink |
| N/A | fchmod, fchown, futimens, ftruncate, fallocate, fgetattr, fsync, ioctl (files), read, readdir, release, statfs, write, copy_file_range | | N/A | fchmod, fchown, futimens, ftruncate, fallocate, fgetattr, fsync, ioctl (files), read, readdir, release, statfs, write, copy_file_range |
In cases where something may be searched (to confirm a directory exists across all source mounts) **getattr** will be used.
In cases where something may be searched for (such as a path to clone) **getattr** will usually be used.
### Policies
A policy is the algorithm used to choose a branch or branches for a function to work on. Think of them as ways to filter and sort branches.
Any function in the `create` category will clone the relative path if needed. Some other functions (`rename`,`link`,`ioctl`) have special requirements or behaviors which you can read more about below.
#### Filtering
Policies basically search branches and create a list of files / paths for functions to work on. The policy is responsible for filtering and sorting the branches. Filters include **minfreespace**, whether or not a branch is mounted read-only, and the branch tagging (RO,NC,RW). These filters are applied across all policies unless otherwise noted.
* No **search** function policies filter.
* All **action** function policies filter out branches which are mounted **read-only** or tagged as **RO (read-only)**.
* All **create** function policies filter out branches which are mounted **read-only**, tagged **RO (read-only)** or **NC (no create)**, or has available space less than `minfreespace`.
Policies may have their own additional filtering such as those that require existing paths to be present.
If all branches are filtered an error will be returned. Typically **EROFS** (read-only filesystem) or **ENOSPC** (no space left on device) depending on the most recent reason for filtering a branch. **ENOENT** will be returned if no elegible branch is found.
#### Path Preservation #### Path Preservation
@ -304,20 +332,9 @@ When using non-path preserving policies paths will be cloned to target drives as
With the `msp` or `most shared path` policies they are defined as `path preserving` for the purpose of controlling `link` and `rename`'s behaviors since `ignorepponrename` is available to disable that behavior. In mergerfs v3.0 the path preserving behavior of rename and link will likely be separated from the policy all together. With the `msp` or `most shared path` policies they are defined as `path preserving` for the purpose of controlling `link` and `rename`'s behaviors since `ignorepponrename` is available to disable that behavior. In mergerfs v3.0 the path preserving behavior of rename and link will likely be separated from the policy all together.
#### Filters
Policies basically search branches and create a list of files / paths for functions to work on. The policy is responsible for filtering and sorting. Filters include **minfreespace**, whether or not a branch is mounted read-only, and the branch tagging (RO,NC,RW). The policy defines the sorting but filtering is mostly uniform as described below.
* No **search** policies filter.
* All **action** policies will filter out branches which are mounted **read-only** or tagged as **RO (read-only)**.
* All **create** policies will filter out branches which are mounted **read-only**, tagged **RO (read-only)** or **NC (no create)**, or has available space less than `minfreespace`.
If all branches are filtered an error will be returned. Typically **EROFS** (read-only filesystem) or **ENOSPC** (no space left on device) depending on the most recent reason for filtering a branch.
#### Policy descriptions #### Policy descriptions
Because of the nature of the behavior the policies act differently depending on the function it is used with (based on the category).
A policy's behavior differs, as mentioned above, based on the function it is used with. Sometimes it really might not make sense to even offer certain policies because they are literally the same as others but it makes things a bit more uniform. In mergerfs 3.0 this might change.
| Policy | Description | | Policy | Description |
@ -360,19 +377,6 @@ Because of the nature of the behavior the policies act differently depending on
When `ioctl` is used with an open file then it will use the file handle which was created at the original `open` call. However, when using `ioctl` with a directory mergerfs will use the `open` policy to find the directory to act on. When `ioctl` is used with an open file then it will use the file handle which was created at the original `open` call. However, when using `ioctl` with a directory mergerfs will use the `open` policy to find the directory to act on.
#### unlink
In FUSE there is an opaque "file handle" which is created by `open`, `create`, or `opendir`, passed to the kernel, and then is passed back to the FUSE userland application by the kernel. Unfortunately, the FUSE kernel driver does not always send the file handle when it theoretically could/should. This complicates certain behaviors / workflows particularly in the high level API. As a result mergerfs is currently doing a few hacky things.
libfuse2 and libfuse3, when using the high level API, will rename names to `.fuse_hiddenXXXXXX` if the file is open when unlinked or renamed over. It does this so the file is still available when a request referencing the now missing file is made. This file however keeps a `rmdir` from succeeding and can be picked up by software reading directories.
The change mergerfs has done is that if a file is open when an unlink or rename happens it will open the file and keep it open till closed by all those who opened it prior. When a request comes in referencing that file and it doesn't include a file handle it will instead use the file handle created at unlink/rename time.
This won't result in technically proper behavior but close enough for many usecases.
The plan is to rewrite mergerfs to use the low level API so these invasive libfuse changes are no longer necessary.
#### rename & link #### #### rename & link ####
**NOTE:** If you're receiving errors from software when files are moved / renamed / linked then you should consider changing the create policy to one which is **not** path preserving, enabling `ignorepponrename`, or contacting the author of the offending software and requesting that `EXDEV` (cross device / improper link) be properly handled. **NOTE:** If you're receiving errors from software when files are moved / renamed / linked then you should consider changing the create policy to one which is **not** path preserving, enabling `ignorepponrename`, or contacting the author of the offending software and requesting that `EXDEV` (cross device / improper link) be properly handled.
@ -473,7 +477,7 @@ $ wget https://github.com/trapexit/mergerfs/releases/download/<ver>/mergerfs-<ve
$ cd mergerfs $ cd mergerfs
$ sudo tools/install-build-pkgs $ sudo tools/install-build-pkgs
$ make deb $ make deb
$ sudo dpkg -i ../mergerfs_version_arch.deb
$ sudo dpkg -i ../mergerfs_<version>_<arch>.deb
``` ```
#### RHEL / CentOS /Fedora #### RHEL / CentOS /Fedora
@ -664,7 +668,6 @@ A B C
* mergerfs.dup: Ensure there are at least N copies of a file across the pool * mergerfs.dup: Ensure there are at least N copies of a file across the pool
* mergerfs.balance: Rebalance files across drives by moving them from the most filled to the least filled * mergerfs.balance: Rebalance files across drives by moving them from the most filled to the least filled
* mergerfs.consolidate: move files within a single mergerfs directory to the drive with most free space * mergerfs.consolidate: move files within a single mergerfs directory to the drive with most free space
* mergerfs.mktrash: Creates FreeDesktop.org Trash specification compatible directories on a mergerfs mount
* https://github.com/trapexit/scorch * https://github.com/trapexit/scorch
* scorch: A tool to help discover silent corruption of files and keep track of files * scorch: A tool to help discover silent corruption of files and keep track of files
* https://github.com/trapexit/bbf * https://github.com/trapexit/bbf
@ -869,6 +872,8 @@ $ dd if=/mnt/mergerfs/1GB.file of=/dev/null bs=1M count=1024 iflag=nocache conv=
# TIPS / NOTES # TIPS / NOTES
* This document is very literal and thorough. Unless there is a bug things work as described. If a suspected feature isn't mentioned it doesn't exist.
* Ensure you're using the latest version. Few distros have the latest version.
* **use_ino** will only work when used with mergerfs 2.18.0 and above. * **use_ino** will only work when used with mergerfs 2.18.0 and above.
* Run mergerfs as `root` (with **allow_other**) unless you're merging paths which are owned by the same user otherwise strange permission issues may arise. * Run mergerfs as `root` (with **allow_other**) unless you're merging paths which are owned by the same user otherwise strange permission issues may arise.
* https://github.com/trapexit/backup-and-recovery-howtos : A set of guides / howtos on creating a data storage system, backing it up, maintaining it, and recovering from failure. * https://github.com/trapexit/backup-and-recovery-howtos : A set of guides / howtos on creating a data storage system, backing it up, maintaining it, and recovering from failure.
@ -885,6 +890,7 @@ $ dd if=/mnt/mergerfs/1GB.file of=/dev/null bs=1M count=1024 iflag=nocache conv=
[https://github.com/trapexit/mergerfs/wiki/Kernel-Issues-&-Bugs](https://github.com/trapexit/mergerfs/wiki/Kernel-Issues-&-Bugs) [https://github.com/trapexit/mergerfs/wiki/Kernel-Issues-&-Bugs](https://github.com/trapexit/mergerfs/wiki/Kernel-Issues-&-Bugs)
#### directory mtime is not being updated #### directory mtime is not being updated
Remember that the default policy for `getattr` is `ff`. The information for the first directory found will be returned. If it wasn't the directory which had been updated then it will appear outdated. Remember that the default policy for `getattr` is `ff`. The information for the first directory found will be returned. If it wasn't the directory which had been updated then it will appear outdated.

219
man/mergerfs.1

@ -42,7 +42,7 @@ Can turn read\-only files into symlinks to underlying file
.IP \[bu] 2 .IP \[bu] 2
Hard link copy\-on\-write / CoW Hard link copy\-on\-write / CoW
.IP \[bu] 2 .IP \[bu] 2
supports POSIX ACLs
Support for POSIX ACLs
.SH HOW IT WORKS .SH HOW IT WORKS
.PP .PP
mergerfs logically merges multiple paths together. mergerfs logically merges multiple paths together.
@ -74,14 +74,14 @@ A\ \ \ \ \ \ \ \ \ +\ \ \ \ \ \ B\ \ \ \ \ \ \ \ =\ \ \ \ \ \ \ C
\f[] \f[]
.fi .fi
.PP .PP
mergerfs does \f[B]not\f[] support the copy\-on\-write (CoW) behavior
found in \f[B]aufs\f[] and \f[B]overlayfs\f[].
mergerfs does \f[B]NOT\f[] support the copy\-on\-write (CoW) or whiteout
behaviors found in \f[B]aufs\f[] and \f[B]overlayfs\f[].
You can \f[B]not\f[] mount a read\-only filesystem and write to it. You can \f[B]not\f[] mount a read\-only filesystem and write to it.
However, mergerfs will ignore read\-only drives when creating new files However, mergerfs will ignore read\-only drives when creating new files
so you can mix read\-write and read\-only drives. so you can mix read\-write and read\-only drives.
It also does \f[B]not\f[] split data across drives.
It also does \f[B]NOT\f[] split data across drives.
It is not RAID0 / striping. It is not RAID0 / striping.
It is simply a union.
It is simply a union of other filesystems.
.SH TERMINOLOGY .SH TERMINOLOGY
.IP \[bu] 2 .IP \[bu] 2
branch: A base path used in the pool. branch: A base path used in the pool.
@ -91,11 +91,12 @@ The union of the branches.
.IP \[bu] 2 .IP \[bu] 2
relative path: The path in the pool relative to the branch and mount. relative path: The path in the pool relative to the branch and mount.
.IP \[bu] 2 .IP \[bu] 2
policy: The algorithm used to select a file when performing a function.
function: A filesystem call (open, unlink, create, getattr, rmdir, etc.)
.IP \[bu] 2 .IP \[bu] 2
function: A filesystem call (open, unlink, create, getattr, etc.)
category: A collection of functions based on basic behavior (action,
create, search).
.IP \[bu] 2 .IP \[bu] 2
category: A collection of functions (action, create, search).
policy: The algorithm used to select a file when performing a function.
.IP \[bu] 2 .IP \[bu] 2
path preservation: Aspect of some policies which includes checking the path preservation: Aspect of some policies which includes checking the
path for which a file would be created. path for which a file would be created.
@ -103,21 +104,26 @@ path for which a file would be created.
.PP .PP
If you don\[aq]t already know that you have a special use case then just If you don\[aq]t already know that you have a special use case then just
start with one of the following option sets. start with one of the following option sets.
.SS You don\[aq]t need \f[C]mmap\f[]
.SS You need \f[C]mmap\f[] (used by rtorrent and many sqlite3 base
software)
.PP .PP
\f[C]use_ino,cache.files=off,dropcacheonclose=true,allow_other,category.create=mfs\f[]
.SS You do need \f[C]mmap\f[] (used by rtorrent and some other programs)
\f[C]allow_other,use_ino,cache.files=partial,dropcacheonclose=true,category.create=mfs\f[]
.SS You don\[aq]t need \f[C]mmap\f[]
.PP .PP
\f[C]use_ino,cache.files=partial,dropcacheonclose=true,allow_other,category.create=mfs\f[]
\f[C]allow_other,use_ino,cache.files=off,dropcacheonclose=true,category.create=mfs\f[]
.PP .PP
See the mergerfs wiki for real world See the mergerfs wiki for real world
deployments (https://github.com/trapexit/mergerfs/wiki/Real-World-Deployments) deployments (https://github.com/trapexit/mergerfs/wiki/Real-World-Deployments)
for comparisons / ideas. for comparisons / ideas.
.SH OPTIONS .SH OPTIONS
.PP
These options are the same regardless you use them with the
\f[C]mergerfs\f[] commandline program, used in fstab, or in a config
file.
.SS mount options .SS mount options
.IP \[bu] 2 .IP \[bu] 2
\f[B]config\f[]: Path to a config file. \f[B]config\f[]: Path to a config file.
Same arguments as below in key=val format.
Same arguments as below in key=val / ini style format.
.IP \[bu] 2 .IP \[bu] 2
\f[B]branches\f[]: Colon delimited list of branches. \f[B]branches\f[]: Colon delimited list of branches.
.IP \[bu] 2 .IP \[bu] 2
@ -163,7 +169,7 @@ be reported as symlinks to the original files.
Please read more below before using. Please read more below before using.
(default: false) (default: false)
.IP \[bu] 2 .IP \[bu] 2
\f[B]symlinkify_timeout=INT\f[]: Time to wait, in seconds, to activate
\f[B]symlinkify_timeout=UINT\f[]: Time to wait, in seconds, to activate
the \f[B]symlinkify\f[] behavior. the \f[B]symlinkify\f[] behavior.
(default: 3600) (default: 3600)
.IP \[bu] 2 .IP \[bu] 2
@ -227,7 +233,7 @@ pending read request per file handle and will attempt to order requests
by offset. by offset.
(default: true) (default: true)
.IP \[bu] 2 .IP \[bu] 2
\f[B]fuse_msg_size=INT\f[]: Set the max number of pages per FUSE
\f[B]fuse_msg_size=UINT\f[]: Set the max number of pages per FUSE
message. message.
Only available on Linux >= 4.20 and ignored otherwise. Only available on Linux >= 4.20 and ignored otherwise.
(min: 1; max: 256; default: 256) (min: 1; max: 256; default: 256)
@ -254,24 +260,32 @@ longest common prefix removed.
See below for the list of value types. See below for the list of value types.
Example: \f[B]func.getattr=newest\f[] Example: \f[B]func.getattr=newest\f[]
.IP \[bu] 2 .IP \[bu] 2
\f[B]category.CATEGORY=POLICY\f[]: Sets policy of all FUSE functions in
the provided category.
See POLICIES section for defaults.
Example: \f[B]category.create=mfs\f[]
\f[B]category.action=POLICY\f[]: Sets policy of all FUSE functions in
the action category.
(default: epall)
.IP \[bu] 2
\f[B]category.create=POLICY\f[]: Sets policy of all FUSE functions in
the create category.
(default: epmfs)
.IP \[bu] 2 .IP \[bu] 2
\f[B]cache.open=INT\f[]: \[aq]open\[aq] policy cache timeout in seconds.
\f[B]category.search=POLICY\f[]: Sets policy of all FUSE functions in
the search category.
(default: ff)
.IP \[bu] 2
\f[B]cache.open=UINT\f[]: \[aq]open\[aq] policy cache timeout in
seconds.
(default: 0) (default: 0)
.IP \[bu] 2 .IP \[bu] 2
\f[B]cache.statfs=INT\f[]: \[aq]statfs\[aq] cache timeout in seconds.
\f[B]cache.statfs=UINT\f[]: \[aq]statfs\[aq] cache timeout in seconds.
(default: 0) (default: 0)
.IP \[bu] 2 .IP \[bu] 2
\f[B]cache.attr=INT\f[]: File attribute cache timeout in seconds.
\f[B]cache.attr=UINT\f[]: File attribute cache timeout in seconds.
(default: 1) (default: 1)
.IP \[bu] 2 .IP \[bu] 2
\f[B]cache.entry=INT\f[]: File name lookup cache timeout in seconds.
\f[B]cache.entry=UINT\f[]: File name lookup cache timeout in seconds.
(default: 1) (default: 1)
.IP \[bu] 2 .IP \[bu] 2
\f[B]cache.negative_entry=INT\f[]: Negative file name lookup cache
\f[B]cache.negative_entry=UINT\f[]: Negative file name lookup cache
timeout in seconds. timeout in seconds.
(default: 0) (default: 0)
.IP \[bu] 2 .IP \[bu] 2
@ -315,22 +329,24 @@ setting.
.IP \[bu] 2 .IP \[bu] 2
BOOL = \[aq]true\[aq] | \[aq]false\[aq] BOOL = \[aq]true\[aq] | \[aq]false\[aq]
.IP \[bu] 2 .IP \[bu] 2
INT = [0,MAX_INT]
INT = [MIN_INT,MAX_INT]
.IP \[bu] 2
UINT = [0,MAX_INT]
.IP \[bu] 2 .IP \[bu] 2
SIZE = \[aq]NNM\[aq]; NN = INT, M = \[aq]K\[aq] | \[aq]M\[aq] | SIZE = \[aq]NNM\[aq]; NN = INT, M = \[aq]K\[aq] | \[aq]M\[aq] |
\[aq]G\[aq] | \[aq]T\[aq] \[aq]G\[aq] | \[aq]T\[aq]
.IP \[bu] 2 .IP \[bu] 2
STR = string STR = string
.IP \[bu] 2 .IP \[bu] 2
FUNC = FUSE function
FUNC = filesystem function
.IP \[bu] 2 .IP \[bu] 2
CATEGORY = FUSE function category
CATEGORY = function category
.IP \[bu] 2 .IP \[bu] 2
POLICY = mergerfs function policy POLICY = mergerfs function policy
.SS branches .SS branches
.PP .PP
The \[aq]branches\[aq] (formerly \[aq]srcmounts\[aq]) argument is a
colon (\[aq]:\[aq]) delimited list of paths to be pooled together.
The \[aq]branches\[aq] argument is a colon (\[aq]:\[aq]) delimited list
of paths to be pooled together.
It does not matter if the paths are on the same or different drives nor It does not matter if the paths are on the same or different drives nor
does it matter the filesystem (within reason). does it matter the filesystem (within reason).
Used and available space will not be duplicated for paths on the same Used and available space will not be duplicated for paths on the same
@ -613,7 +629,7 @@ If set to \f[C]git\f[] it will only perform the hack when the path in
question includes \f[C]/.git/\f[]. question includes \f[C]/.git/\f[].
\f[C]all\f[] will result it it applying anytime a readonly file which is \f[C]all\f[] will result it it applying anytime a readonly file which is
empty is opened for writing. empty is opened for writing.
.SH FUNCTIONS / POLICIES / CATEGORIES
.SH FUNCTIONS, CATEGORIES and POLICIES
.PP .PP
The POSIX filesystem API is made up of a number of functions. The POSIX filesystem API is made up of a number of functions.
\f[B]creat\f[], \f[B]stat\f[], \f[B]chown\f[], etc. \f[B]creat\f[], \f[B]stat\f[], \f[B]chown\f[], etc.
@ -621,34 +637,34 @@ For ease of configuration in mergerfs most of the core functions are
grouped into 3 categories: \f[B]action\f[], \f[B]create\f[], and grouped into 3 categories: \f[B]action\f[], \f[B]create\f[], and
\f[B]search\f[]. \f[B]search\f[].
These functions and categories can be assigned a policy which dictates These functions and categories can be assigned a policy which dictates
which underlying branch/file/directory is chosen when performing that
behavior.
Any policy can be assigned to a function or category though some may not
be very useful in practice.
For instance: \f[B]rand\f[] (random) may be useful for file creation
(create) but could lead to very odd behavior if used for \f[C]chmod\f[]
if there were more than one copy of the file.
which branch is chosen when performing that function.
.PP .PP
Some functions, listed in the category \f[C]N/A\f[] below, can not be Some functions, listed in the category \f[C]N/A\f[] below, can not be
assigned the normal policies. assigned the normal policies.
All functions which work on file handles use the handle which was
acquired by \f[C]open\f[] or \f[C]create\f[].
\f[C]readdir\f[] has no real need for a policy given the purpose is
merely to return a list of entries in a directory.
\f[C]statfs\f[]\[aq]s behavior can be modified via other options.
These functions work with file handles, rather than file paths, which
were created by \f[C]open\f[] or \f[C]create\f[].
That said many times the current FUSE kernel driver will not always That said many times the current FUSE kernel driver will not always
provide the file handle when a client calls \f[C]fgetattr\f[], provide the file handle when a client calls \f[C]fgetattr\f[],
\f[C]fchown\f[], \f[C]fchmod\f[], \f[C]futimens\f[], \f[C]ftruncate\f[], \f[C]fchown\f[], \f[C]fchmod\f[], \f[C]futimens\f[], \f[C]ftruncate\f[],
etc. etc.
This means it will call the regular, path based, versions. This means it will call the regular, path based, versions.
\f[C]readdir\f[] has no real need for a policy given the purpose is
merely to return a list of entries in a directory.
\f[C]statfs\f[]\[aq]s behavior can be modified via other options.
.PP .PP
When using policies which are based on a branch\[aq]s available space When using policies which are based on a branch\[aq]s available space
the base path provided is used. the base path provided is used.
Not the full path to the file in question. Not the full path to the file in question.
Meaning that sub mounts won\[aq]t be considered in the space
Meaning that mounts in the branch won\[aq]t be considered in the space
calculations. calculations.
The reason is that it doesn\[aq]t really work for non\-path preserving The reason is that it doesn\[aq]t really work for non\-path preserving
policies and can lead to non\-obvious behaviors. policies and can lead to non\-obvious behaviors.
.PP
NOTE: While any policy can be assigned to a function or category though
some may not be very useful in practice.
For instance: \f[B]rand\f[] (random) may be useful for file creation
(create) but could lead to very odd behavior if used for \f[C]chmod\f[]
if there were more than one copy of the file.
.SS Functions and their Category classifications .SS Functions and their Category classifications
.PP .PP
.TS .TS
@ -685,8 +701,44 @@ fchmod, fchown, futimens, ftruncate, fallocate, fgetattr, fsync, ioctl
T} T}
.TE .TE
.PP .PP
In cases where something may be searched (to confirm a directory exists
across all source mounts) \f[B]getattr\f[] will be used.
In cases where something may be searched for (such as a path to clone)
\f[B]getattr\f[] will usually be used.
.SS Policies
.PP
A policy is the algorithm used to choose a branch or branches for a
function to work on.
Think of them as ways to filter and sort branches.
.PP
Any function in the \f[C]create\f[] category will clone the relative
path if needed.
Some other functions (\f[C]rename\f[],\f[C]link\f[],\f[C]ioctl\f[]) have
special requirements or behaviors which you can read more about below.
.SS Filtering
.PP
Policies basically search branches and create a list of files / paths
for functions to work on.
The policy is responsible for filtering and sorting the branches.
Filters include \f[B]minfreespace\f[], whether or not a branch is
mounted read\-only, and the branch tagging (RO,NC,RW).
These filters are applied across all policies unless otherwise noted.
.IP \[bu] 2
No \f[B]search\f[] function policies filter.
.IP \[bu] 2
All \f[B]action\f[] function policies filter out branches which are
mounted \f[B]read\-only\f[] or tagged as \f[B]RO (read\-only)\f[].
.IP \[bu] 2
All \f[B]create\f[] function policies filter out branches which are
mounted \f[B]read\-only\f[], tagged \f[B]RO (read\-only)\f[] or \f[B]NC
(no create)\f[], or has available space less than \f[C]minfreespace\f[].
.PP
Policies may have their own additional filtering such as those that
require existing paths to be present.
.PP
If all branches are filtered an error will be returned.
Typically \f[B]EROFS\f[] (read\-only filesystem) or \f[B]ENOSPC\f[] (no
space left on device) depending on the most recent reason for filtering
a branch.
\f[B]ENOENT\f[] will be returned if no elegible branch is found.
.SS Path Preservation .SS Path Preservation
.PP .PP
Policies, as described below, are of two basic types. Policies, as described below, are of two basic types.
@ -709,33 +761,14 @@ defined as \f[C]path\ preserving\f[] for the purpose of controlling
\f[C]ignorepponrename\f[] is available to disable that behavior. \f[C]ignorepponrename\f[] is available to disable that behavior.
In mergerfs v3.0 the path preserving behavior of rename and link will In mergerfs v3.0 the path preserving behavior of rename and link will
likely be separated from the policy all together. likely be separated from the policy all together.
.SS Filters
.PP
Policies basically search branches and create a list of files / paths
for functions to work on.
The policy is responsible for filtering and sorting.
Filters include \f[B]minfreespace\f[], whether or not a branch is
mounted read\-only, and the branch tagging (RO,NC,RW).
The policy defines the sorting but filtering is mostly uniform as
described below.
.IP \[bu] 2
No \f[B]search\f[] policies filter.
.IP \[bu] 2
All \f[B]action\f[] policies will filter out branches which are mounted
\f[B]read\-only\f[] or tagged as \f[B]RO (read\-only)\f[].
.IP \[bu] 2
All \f[B]create\f[] policies will filter out branches which are mounted
\f[B]read\-only\f[], tagged \f[B]RO (read\-only)\f[] or \f[B]NC (no
create)\f[], or has available space less than \f[C]minfreespace\f[].
.PP
If all branches are filtered an error will be returned.
Typically \f[B]EROFS\f[] (read\-only filesystem) or \f[B]ENOSPC\f[] (no
space left on device) depending on the most recent reason for filtering
a branch.
.SS Policy descriptions .SS Policy descriptions
.PP .PP
Because of the nature of the behavior the policies act differently
depending on the function it is used with (based on the category).
A policy\[aq]s behavior differs, as mentioned above, based on the
function it is used with.
Sometimes it really might not make sense to even offer certain policies
because they are literally the same as others but it makes things a bit
more uniform.
In mergerfs 3.0 this might change.
.PP .PP
.TS .TS
tab(@); tab(@);
@ -930,38 +963,6 @@ When \f[C]ioctl\f[] is used with an open file then it will use the file
handle which was created at the original \f[C]open\f[] call. handle which was created at the original \f[C]open\f[] call.
However, when using \f[C]ioctl\f[] with a directory mergerfs will use However, when using \f[C]ioctl\f[] with a directory mergerfs will use
the \f[C]open\f[] policy to find the directory to act on. the \f[C]open\f[] policy to find the directory to act on.
.SS unlink
.PP
In FUSE there is an opaque "file handle" which is created by
\f[C]open\f[], \f[C]create\f[], or \f[C]opendir\f[], passed to the
kernel, and then is passed back to the FUSE userland application by the
kernel.
Unfortunately, the FUSE kernel driver does not always send the file
handle when it theoretically could/should.
This complicates certain behaviors / workflows particularly in the high
level API.
As a result mergerfs is currently doing a few hacky things.
.PP
libfuse2 and libfuse3, when using the high level API, will rename names
to \f[C]\&.fuse_hiddenXXXXXX\f[] if the file is open when unlinked or
renamed over.
It does this so the file is still available when a request referencing
the now missing file is made.
This file however keeps a \f[C]rmdir\f[] from succeeding and can be
picked up by software reading directories.
.PP
The change mergerfs has done is that if a file is open when an unlink or
rename happens it will open the file and keep it open till closed by all
those who opened it prior.
When a request comes in referencing that file and it doesn\[aq]t include
a file handle it will instead use the file handle created at
unlink/rename time.
.PP
This won\[aq]t result in technically proper behavior but close enough
for many usecases.
.PP
The plan is to rewrite mergerfs to use the low level API so these
invasive libfuse changes are no longer necessary.
.SS rename & link .SS rename & link
.PP .PP
\f[B]NOTE:\f[] If you\[aq]re receiving errors from software when files \f[B]NOTE:\f[] If you\[aq]re receiving errors from software when files
@ -1152,7 +1153,7 @@ $\ wget\ https://github.com/trapexit/mergerfs/releases/download/<ver>/mergerfs\-
$\ cd\ mergerfs $\ cd\ mergerfs
$\ sudo\ tools/install\-build\-pkgs $\ sudo\ tools/install\-build\-pkgs
$\ make\ deb $\ make\ deb
$\ sudo\ dpkg\ \-i\ ../mergerfs_version_arch.deb
$\ sudo\ dpkg\ \-i\ ../mergerfs_<version>_<arch>.deb
\f[] \f[]
.fi .fi
.SS RHEL / CentOS /Fedora .SS RHEL / CentOS /Fedora
@ -1449,9 +1450,6 @@ most filled to the least filled
mergerfs.consolidate: move files within a single mergerfs directory to mergerfs.consolidate: move files within a single mergerfs directory to
the drive with most free space the drive with most free space
.IP \[bu] 2 .IP \[bu] 2
mergerfs.mktrash: Creates FreeDesktop.org Trash specification compatible
directories on a mergerfs mount
.IP \[bu] 2
https://github.com/trapexit/scorch https://github.com/trapexit/scorch
.IP \[bu] 2 .IP \[bu] 2
scorch: A tool to help discover silent corruption of files and keep scorch: A tool to help discover silent corruption of files and keep
@ -1741,7 +1739,7 @@ do
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ head\ \-n\ 1\ |\ \\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ head\ \-n\ 1\ |\ \\
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ cut\ \-d\[aq]\ \[aq]\ \-f2\-) \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ cut\ \-d\[aq]\ \[aq]\ \-f2\-)
\ \ \ \ test\ \-n\ "${FILE}" \ \ \ \ test\ \-n\ "${FILE}"
\ \ \ \ rsync\ \-axqHAXWES\ \-\-preallocate\ \-\-remove\-source\-files\ "${CACHE}/./${FILE}"\ "${BACKING}/"
\ \ \ \ rsync\ \-axqHAXWESR\ \-\-preallocate\ \-\-remove\-source\-files\ "${CACHE}/./${FILE}"\ "${BACKING}/"
done done
\f[] \f[]
.fi .fi
@ -1893,6 +1891,13 @@ $\ dd\ if=/mnt/mergerfs/1GB.file\ of=/dev/null\ bs=1M\ count=1024\ iflag=nocache
.fi .fi
.SH TIPS / NOTES .SH TIPS / NOTES
.IP \[bu] 2 .IP \[bu] 2
This document is very literal and thorough.
Unless there is a bug things work as described.
If a suspected feature isn\[aq]t mentioned it doesn\[aq]t exist.
.IP \[bu] 2
Ensure you\[aq]re using the latest version.
Few distros have the latest version.
.IP \[bu] 2
\f[B]use_ino\f[] will only work when used with mergerfs 2.18.0 and \f[B]use_ino\f[] will only work when used with mergerfs 2.18.0 and
above. above.
.IP \[bu] 2 .IP \[bu] 2

Loading…
Cancel
Save