You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

224 lines
10 KiB

  1. # Technical Behavior and Limitations
  2. ## Do hardlinks work?
  3. Yes. There is no option to enable or disable links. They are
  4. fundimentally supported in compatible situations. That said the inode
  5. of a file is not necessarily indicitive of two file names linking to
  6. the same underlying data. See also the option `inodecalc` for how
  7. inode values are calculated.
  8. What mergerfs does not do is fake hard links across branches. Read the
  9. section [rename & link](../config/rename_and_link.md) for how it
  10. works.
  11. Remember that hardlinks will **NOT** work across devices. That
  12. includes between the original filesystem and a mergerfs pool, between
  13. two separate pools of the same underlying filesystems, or bind mounts
  14. of paths within the mergerfs pool. The latter is common when using
  15. Docker or Podman. Multiple volumes (bind mounts) to the same
  16. underlying filesystem are considered different devices. There is no
  17. way to link or rename between them. You should mount in the highest
  18. directory in the mergerfs pool that includes all the paths you need if
  19. you want links and rename to work.
  20. ## How does mergerfs handle moving and copying of files?
  21. This is a _very_ common mistaken assumption regarding how filesystems
  22. work. There is no such thing as "move" or "copy." These concepts are
  23. high level behaviors made up of numerous independent steps and _not_
  24. individual filesystem functions.
  25. A "move" can include a "copy" so lets describe copy first.
  26. When an application copies a file from "source" to "destination" it
  27. can do so in a number of ways but the basics are the following.
  28. 1. `open` the source file.
  29. 2. `create` the destination file.
  30. 3. `read` a chunk of data from source and `write` to
  31. destination. Continue till it runs out of data to copy.
  32. 4. Copy file metadata (`stat`) such as ownership (`chown`),
  33. permissions (`chmod`), timestamps (`utimes`), extended attributes
  34. (`getxattr`, `setxattr`), etc.
  35. 5. `close` source and destination files.
  36. "move" is typically a `rename(src,dst)` and if that errors with
  37. `EXDEV` (meaning the source and destination are on different
  38. filesystems) the application will "copy" the file as described above
  39. and then it removes (`unlink`) the source.
  40. The `rename(src,dst)`, `open(src)`, `create(dst)`, data copying,
  41. metadata copying, `unlink(src)`, etc. are entirely distinct and
  42. separate events. There is really no practical way to know that what is
  43. ultimately occurring is the "copying" of a file or what the source
  44. file would be. Since the source is not known there is no way to know
  45. how large a created file is destined to become. This is why it is
  46. impossible for mergerfs to choose the branch for a `create` based on
  47. file size. The only context provided when a file is created, besides
  48. the name, is the permissions, if it is to be read and/or written, and
  49. some low level settings for the operating system.
  50. All of this means that mergerfs can not make decisions when a file is
  51. created based on file size or the source of the data. That information
  52. is simply not available. At best mergerfs could respond to files
  53. reaching a certain size when writing data, a file is closed, or
  54. renamed.
  55. Related: if a user wished to have mergerfs perform certain activities
  56. based on the name of a file it is common and even best practice for a
  57. program to write to a temporary file first and then rename to its
  58. final destination. That temporary file name will typically be random
  59. and have no indication of the type of file being written. At best
  60. something could be done on rename.
  61. ## Does FICLONE or FICLONERANGE work?
  62. Unfortunately not. FUSE, the technology mergerfs is based on, does not
  63. support the `clone_file_range` feature needed for it to work. mergerfs
  64. won't even know such a request is made. The kernel will simply return
  65. an error back to the application making the request.
  66. Should FUSE gain the ability mergerfs will be updated to support it.
  67. ## Why do I get an "out of space" / "no space left on device" / ENOSPC error even though there appears to be lots of space available?
  68. First make sure you've read the sections above about policies, path
  69. preservation, branch filtering, and the options `minfreespace`,
  70. `moveonenospc`, `statfs`, and `statfs_ignore`.
  71. mergerfs is simply presenting a union of the content within multiple
  72. branches. The reported free space is an aggregate of space available
  73. within the pool (behavior modified by `statfs` and
  74. `statfs_ignore`). It does not represent a contiguous space. In the
  75. same way that read-only filesystems, those with quotas, or reserved
  76. space report the full theoretical space available.
  77. Due to path preservation, branch tagging, read-only status, and
  78. `minfreespace` settings it is perfectly valid that `ENOSPC` / "out of
  79. space" / "no space left on device" be returned. It is doing what was
  80. asked of it: filtering possible branches due to those settings. Only
  81. one error can be returned and if one of the reasons for filtering a
  82. branch was `minfreespace` then it will be returned as
  83. such. `moveonenospc` is only relevant to writing a file which is too
  84. large for the filesystem it's currently on.
  85. It is also possible that the filesystem selected has run out of
  86. inodes. Use `df -i` to list the total and available inodes per
  87. filesystem.
  88. If you don't care about path preservation then simply change the
  89. `create` policy to one which isn't. `mfs` is probably what most are
  90. looking for. The reason it's not default is because it was originally
  91. set to `epmfs` and changing it now would change people's setup. Such a
  92. setting change will likely occur in mergerfs 3.
  93. ## Why does the total available space in mergerfs not equal outside?
  94. Are you using ext2/3/4? With reserve for root? mergerfs uses available
  95. space for statfs calculations. If you've reserved space for root then
  96. it won't show up.
  97. You can remove the reserve by running: `tune2fs -m 0 <device>`
  98. ## I notice massive slowdowns of writes when enabling cache.files.
  99. When file caching is enabled in any form (`cache.files!=off`) it will
  100. issue `getxattr` requests for `security.capability` prior to _every
  101. single write_. This will usually result in performance degradation,
  102. especially when using a network filesystem (such as NFS or SMB.)
  103. Unfortunately at this moment, the kernel is not caching the response.
  104. To work around this situation mergerfs offers a few solutions.
  105. 1. Set `security_capability=false`. It will short circuit any call and
  106. return `ENOATTR`. This still means though that mergerfs will
  107. receive the request before every write but at least it doesn't get
  108. passed through to the underlying filesystem.
  109. 2. Set `xattr=noattr`. Same as above but applies to _all_ calls to
  110. getxattr. Not just `security.capability`. This will not be cached
  111. by the kernel either but mergerfs' runtime config system will still
  112. function.
  113. 3. Set `xattr=nosys`. Results in mergerfs returning `ENOSYS` which
  114. _will_ be cached by the kernel. No future xattr calls will be
  115. forwarded to mergerfs. The downside is that also means the xattr
  116. based config and query functionality won't work either.
  117. 4. Disable file caching. If you aren't using applications which use
  118. `mmap` it's probably simpler to just disable it altogether. The
  119. kernel won't send the requests when caching is disabled.
  120. ## Why use FUSE? Why not a kernel based solution?
  121. As with any solution to a problem, there are advantages and
  122. disadvantages to each one.
  123. A FUSE based solution has all the downsides of FUSE:
  124. - Higher IO latency due to the trips in and out of kernel space
  125. - Higher general overhead due to trips in and out of kernel space
  126. - Double caching when using page caching
  127. - Misc limitations due to FUSE's design
  128. But FUSE also has a lot of upsides:
  129. - Easier to offer a cross platform solution
  130. - Easier forward and backward compatibility
  131. - Easier updates for users
  132. - Easier and faster release cadence
  133. - Allows more flexibility in design and features
  134. - Overall easier to write, secure, and maintain
  135. - Much lower barrier to entry (getting code into the kernel takes a
  136. lot of time and effort initially)
  137. ## Is my OS's libfuse needed for mergerfs to work?
  138. No. Normally `mount.fuse` is needed to get mergerfs (or any FUSE
  139. filesystem to mount using the `mount` command but in vendoring the
  140. libfuse library the `mount.fuse` app has been renamed to
  141. `mount.mergerfs` meaning the filesystem type in `fstab` can simply be
  142. `mergerfs`. That said there should be no harm in having it installed
  143. and continuing to using `fuse.mergerfs` as the type in `/etc/fstab`.
  144. If `mergerfs` doesn't work as a type it could be due to how the
  145. `mount.mergerfs` tool was installed. Must be in `/sbin/` with proper
  146. permissions.
  147. ## Why was splice support removed?
  148. After a lot of testing over the years, splicing always appeared to
  149. at best, provide equivalent performance, and in some cases, worse
  150. performance. Splice is not supported on other platforms forcing a
  151. traditional read/write fallback to be provided. The splice code was
  152. removed to simplify the codebase.
  153. ## How does mergerfs handle credentials?
  154. mergerfs is a multithreaded application in order to handle requests
  155. from the kernel concurrently. Each FUSE message has a header with
  156. certain details about the request include the process ID (pid) of the
  157. requestion application, the process' effective user id (uid), and
  158. group id (gid). To ensure proper POSIX filesystem behavior and
  159. security mergerfs must change its identity to match that of the
  160. requester when performing the core filesystem function on the
  161. underlying filesystem. On most Unix/POSIX based system a process and
  162. all its threads are under the same uid and gid. However, on Linux each
  163. thread may have its own credentials. This allows mergerfs to be
  164. multithreaded and for each thread to change to the credentials
  165. (seteuid,setegid) as required by the incoming message it is
  166. handling. However, on FreeBSD this is not possible at the moment
  167. (though there has been
  168. [discussions](https://wiki.freebsd.org/Per-Thread%20Credentials) and
  169. as such must change the credentials of the whole application when
  170. actioning messages. mergerfs does optimize this behavior by only
  171. changing credentials and locking the thread to do so if the process is
  172. currently not the same as what is necessary by the incoming request.