From 41b40b94fa6961329164a373b951c1b070a274c9 Mon Sep 17 00:00:00 2001 From: trapexit Date: Fri, 19 Sep 2025 20:20:28 -0400 Subject: [PATCH] Misc docs updates (#1524) --- .../config/functions_categories_policies.md | 12 +- .../faq/technical_behavior_and_limitations.md | 111 ++++++++++++++---- mkdocs/docs/index.md | 1 + mkdocs/docs/quickstart.md | 8 +- mkdocs/docs/remote_filesystems.md | 17 +++ mkdocs/docs/support.md | 1 + 6 files changed, 122 insertions(+), 28 deletions(-) diff --git a/mkdocs/docs/config/functions_categories_policies.md b/mkdocs/docs/config/functions_categories_policies.md index b7f7e4f1..0a99c64e 100644 --- a/mkdocs/docs/config/functions_categories_policies.md +++ b/mkdocs/docs/config/functions_categories_policies.md @@ -5,7 +5,9 @@ The POSIX filesystem API is made up of a number of functions. `creat`, 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. +function. IE. When an application requests that a file or directory is +created how should mergerfs decide which branch to choose to attempt +the create? That is the policy. Some functions, listed in the category `N/A` below, can not be assigned the normal policies because they are directly related to a @@ -44,9 +46,9 @@ branch base path provided is used. Not the full path to the file or directory in question. Meaning that mounts within the branch will not be considered in the space calculations. -NOTE: While any policy can be assigned to a function or category, some -may not be very useful in practice. For instance: `rand` (random) may -be useful for file creation but could lead to very odd behavior if +**NOTE:** While any policy can be assigned to a function or category, +some may not be very useful in practice. For instance: `rand` (random) +may be useful for file creation but could lead to very odd behavior if used for `chmod` if there were more than one copy of the file. Unless users find this flexibility useful it will likely be removed in the future. @@ -69,7 +71,7 @@ whether or not a branch is mounted read-only, and the branch mode [minfreespace](minfreespace.md). Policies may have their own additional filtering such as those that -require existing paths to be present. +require relative 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 diff --git a/mkdocs/docs/faq/technical_behavior_and_limitations.md b/mkdocs/docs/faq/technical_behavior_and_limitations.md index 136aaa0d..3e88ce85 100644 --- a/mkdocs/docs/faq/technical_behavior_and_limitations.md +++ b/mkdocs/docs/faq/technical_behavior_and_limitations.md @@ -1,26 +1,71 @@ # Technical Behavior and Limitations -## Do hardlinks work? - -Yes. There is no option to enable or disable links (or renames.) They -are fundamentally supported in compatible situations. That said the -inode of a file is not necessarily indicative of two file names -linking to the same underlying data. See also the option `inodecalc` -for how inode values are calculated. - -What mergerfs does not do is fake hard links across branches. Read the -section [rename & link](../config/rename_and_link.md) for how it -works. - -Remember that hardlinks will **NOT** work across devices. That -includes between the original filesystem and a mergerfs pool, between -two separate pools of the same underlying filesystems, or bind mounts -of paths within the mergerfs pool. The latter is common when using -Docker or Podman. Multiple volumes (bind mounts) to the same -underlying filesystem are considered different devices. There is no -way to link or rename between them. You should mount in the highest -directory in the mergerfs pool that includes all the paths you need if -you want links and rename to work. +## Do hard links work? + +Yes. [links](https://en.wikipedia.org/wiki/Hard_link) (otherwise known +as hard links) are fundamentally supported by mergerfs. There is no +option to enable or disable links. All comments elswhere claiming they +do not work are related to the setup of the user's system. + +See the [Intro to Filesystems](../intro_to_filesystems.md) page for more +details on what a `link` is. + +A limitation of a `link` is that it **must** reference a file/inode +within the same filesystem or device. When a request is made to the +operating system to `link` (or `rename`) a file to a target location +the OS will first check if the source and target are the same +filesystem / device. If not it will return the error `EXDEV` meaning +that the request is not able to be made due to the result being "cross +device". + +What catches many users off guard is that this "cross device" check is +not very deep or involved. Even the same filesystem bind mounted to +another location will typically be considered a different device. So +when mergerfs is creating a union of other filesystems there is no way +to link or rename from one of the underlying branches into +mergerfs. They are different filesystems even if logically they seem +related or the same. And similarly it is impossible for mergerfs to +truly make a link between two branches which are not in fact the same +mounted filesystem. + +This is relevant to mergerfs users because bind mounts are very common +when using container runtimes such as Docker, Podman, or +Kubernetes. When you add a volume or mount to your container that is +in fact a bind mount of that path. Meaning if you were to add +`/mnt/mergerfs/downloads` and `/mnt/mergerfs/movies` as separate +mounts into your container any request to link between the two +locations within the container will fail with the `EXDEV` error even +though it will work perfectly fine on the host. If you wish for `link` +and `rename` to work you **MUST** mount into the container a point in +the directory structure above what you wish to use. In this case +`/mnt/mergerfs`. + +Another situation where people will hit unexpected `EXDEV` errors is +when they use a policy which makes file creation decisions based on +existing paths. If the source of a `link` or `rename` is on branch A +but the target directory is on branch B, given the whole point of the +policy is to strictly enforce behavior based on what branches already +exist, it must return `EXDEV`. Doing otherwise would fundamentally +break the purpose of the policy. Read [rename & +link](../config/rename_and_link.md) for more details on how mergerfs +handles those two functions. + +When in doubt it is trivial to test `link`: + +```shell +$ cd /mnt/mergerfs/ +$ touch foo +$ ln -v foo bar +'bar' => 'foo' +$ stat foo bar | grep Inode +Device: 0,173 Inode: 123456 Links: 2 +Device: 0,173 Inode: 123456 Links: 2 +``` + +For the more technical: within mergerfs the inode of a file is not +necessarily indicative of two file names linking to the same +underlying data. For more details as to why that is see the docs on +[inodecalc](../config/inodecalc.md). ## Do reflink, FICLONE, or FICLONERANGE work? @@ -213,3 +258,27 @@ Requires that enabled (the default.) If there are any usage issues contact the [author](../support.md). + + +## What happens if a branch filesystem blocks? + +POSIX filesystem calls unfortunately are entirely synchronous. If the +underlying filesystem mergerfs is interacting with freezes up or +blocks then the thread issuing the request will block same as any +other piece of software. If enough threads block then mergerfs will +block. There are no timeouts or ways to truly work around this +situation. If mergerfs spawned new threads it is very likely they too +would end up blocked. + + +## What information does mergerfs have when making decisions? + +Every incoming request contains: + +* The `tid` or `pid` of the calling thread/process +* The `uid` and `gid` of the calling thread/process +* The `umask` of the calling thread/process +* The arguments of the filesystem call in question + +Naturally the mergerfs config as well as anything queriable from the +operating system or filesystems are also available. diff --git a/mkdocs/docs/index.md b/mkdocs/docs/index.md index 1242ec3c..f9940188 100644 --- a/mkdocs/docs/index.md +++ b/mkdocs/docs/index.md @@ -23,6 +23,7 @@ commodity storage devices. It is similar to [**mhddfs**, **unionfs**, * Works with filesystems of [almost any type](faq/compatibility_and_integration.md#what-filesystems-can-be-used-as-branches) * Ignore read-only filesystems when creating files +* [Hard links](faq/technical_behavior_and_limitations.md#do-hard-links-work) * Hard link [copy-on-write / CoW](config/link_cow.md) * [Runtime configurable](runtime_interface.md) * Support for extended attributes (xattrs) diff --git a/mkdocs/docs/quickstart.md b/mkdocs/docs/quickstart.md index 1254c352..50e2738c 100644 --- a/mkdocs/docs/quickstart.md +++ b/mkdocs/docs/quickstart.md @@ -133,7 +133,9 @@ ExecStart=/usr/bin/mergerfs \ -o dropcacheonclose=false \ /mnt/hdd0:/mnt/hdd1 \ /media -ExecStop=/bin/fusermount -uz /media +ExecStop=/usr/bin/umount /media +# Or if you need fusermount +# ExecStop=/usr/bin/mergerfs-fusermount -u /media Restart=on-failure [Install] @@ -197,7 +199,9 @@ ExecStart=/usr/bin/mergerfs \ -o dropcacheonclose=false \ /mnt/hdd0:/mnt/hdd1 \ /media -ExecStop=/bin/fusermount -uz /media +ExecStop=/usr/bin/umount /media +# Or if you need fusermount +# ExecStop=/usr/bin/mergerfs-fusermount -u /media Restart=on-failure [Install] diff --git a/mkdocs/docs/remote_filesystems.md b/mkdocs/docs/remote_filesystems.md index b0ac63fc..6ed9b1ee 100644 --- a/mkdocs/docs/remote_filesystems.md +++ b/mkdocs/docs/remote_filesystems.md @@ -49,6 +49,23 @@ NFS export settings: running mergerfs as a non-root user, there is no guarantee that mergerfs will be able to do what it needs to manage the underlying filesystem. +* `softerr` or `soft`: A perhaps questionable choice but if NFS + freezes up because the backend dies or the network goes down the + default `hard` mount would cause mergerfs to block the same as any + other software. By setting `softerr` or `soft` the NFS client will + timeout eventually and return an error. +* `softreval`: NFS client will serve up cached data after `retrans` + attempts to revalidate the data. Helps with intermitent network + issues. +* `timeo=150`: Timeout till retrying request. +* `retrans=3`: Number of retrying a request. +* `rsize=131072`: Read size. +* `wsize=131072`: Write size. + +`no_root_squash` is necessary but the others are just suggestions and +you may want to alter based on your use case. The risk of using `hard` +and other more strict behavior options is that should NFS completely +lock up it will impact mergerfs negatively. ### NFS exporting mergerfs diff --git a/mkdocs/docs/support.md b/mkdocs/docs/support.md index 9776acb0..89645888 100644 --- a/mkdocs/docs/support.md +++ b/mkdocs/docs/support.md @@ -47,6 +47,7 @@ directly.](mailto:support@spawn.link)** programs: `ln`, `mv`, `cp`, `ls`, `dd`, etc. With the most simple mergerfs setup possible. + ### Contact / Issue submission * github.com: [https://github.com/trapexit/mergerfs/issues](https://github.com/trapexit/mergerfs/issues)