a featureful union filesystem https://trapexit.github.io/mergerfs/
Find a file
Antonio S. Musumeci c43a14f269 thread_pool: close TOCTOU in set_threads by reading _remove_count under lock
set_threads read _threads.size() under _threads_mutex then read
_remove_count outside the lock.  Between the two reads a worker could
claim a _remove_count decrement and erase itself from _threads via
_remove_self, causing set_threads to double-count that shrink: once
from the reduced _threads.size() (had the lock been re-acquired) and
once from the stale _remove_count that was already claimed.  This
could cause a spurious over-shrink and a -EINVAL return even though
the pool was at the target size.

Move the _remove_count load inside the _threads_mutex scope so both
values are read atomically with respect to worker self-removal.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 17:29:07 -04:00
.github Update submitting bug reports, improve collect-info (#1598) 2025-12-06 13:55:14 -06:00
buildtools Detect OS for release-sample make target 2026-04-08 20:48:02 -05:00
debian Build improvements (#1501) 2025-08-04 23:39:52 -05:00
man Fix manpage links for 2.41.0-rc3 (#1555) 2025-10-29 12:07:49 -05:00
mkdocs Update docs on limiting drive spinup 2026-04-06 14:01:20 -05:00
src Misc updates and fixes 2026-04-04 02:46:24 -05:00
tests thread_pool: store scaling config by value 2026-04-10 16:23:08 -04:00
tools tools/preload: include correct extended attribute headers on FreeBSD (#1590) 2025-11-25 12:09:41 -06:00
vendored thread_pool: close TOCTOU in set_threads by reading _remove_count under lock 2026-04-10 17:29:07 -04:00
.gitignore Build improvements (#1501) 2025-08-04 23:39:52 -05:00
DEPENDENCIES Update vendored/nonstd to latest and fix API usage 2026-03-02 01:09:16 -05:00
LICENSE Update copyright headers 2026-03-02 01:09:16 -05:00
Makefile Detect OS for release-sample make target 2026-04-08 20:48:02 -05:00
mergerfs.spec Build improvements (#1501) 2025-08-04 23:39:52 -05:00
README.md Fix some links in docs (#1582) 2025-11-18 08:35:27 -06:00

mergerfs - a featureful union filesystem

mergerfs is a FUSE based union filesystem geared towards simplifying storage and management of files across numerous commodity storage devices. It is similar to mhddfs, unionfs, aufs, DrivePool, etc.

Features

  • Logically combine numerous filesystems/paths into a single mount point (JBOFS: Just a Bunch of FileSystems)
  • Combine paths of the same or different filesystems
  • Ability to add or remove filesystems/paths without impacting the rest of the data
  • Unaffected by individual filesystem failure
  • Configurable file selection and creation placement
  • File IO passthrough for near native IO performance (where supported)
  • Works with filesystems of any size
  • Works with filesystems of almost any type
  • Ignore read-only filesystems when creating files
  • Hard links
  • Hard link copy-on-write / CoW
  • Runtime configurable
  • Support for extended attributes (xattrs)
  • Support for file attributes (chattr)
  • Support for POSIX ACLs

Non-features

  • Read/write overlay on top of read-only filesystem like OverlayFS
  • File whiteout
  • RAID like parity calculation (see SnapRAID)
  • Redundancy
  • Splitting of files across branches

How it works

mergerfs logically merges multiple filesystem paths together. Not block devices, not filesystem mounts, just paths. It acts as a proxy to the underlying filesystem paths. Combining the behaviors of some functions and being a selector for others.

When the contents of a directory are requested mergerfs combines the list of files from each directory, deduplicating entries, and returns that list.

When a file or directory is created a policy is first run to determine which branch will be selected for the creation.

For functions which change attributes or remove the file the behavior may be applied to all instances found.

The way in which mergerfs behaves is controlled by the config/options/settings. More specifically by policies.

Visualization

A         +      B        =       C
/disk1           /disk2           /merged
|                |                |
+-- /dir1        +-- /dir1        +-- /dir1
|   |            |   |            |   |
|   +-- file1    |   |            |   +-- file1
|                |   +-- file2    |   +-- file2
|                |   +-- file3    |   +-- file3
|                |                |
+-- /dir2        |                +-- /dir2
|   |            |                |   |
|   +-- file4    |                |   +-- file4
|                |                |
|                +-- /dir3        +-- /dir3
|                |   |            |   |
|                |   +-- file5    |   +-- file5
|                |                |
+-- file6        |                +-- file6
+-- file7        +-- file7        +-- file7

QuickStart

https://trapexit.github.io/mergerfs/latest/quickstart/

Documentation

https://trapexit.github.io/mergerfs

Support

https://trapexit.github.io/mergerfs/latest/support/

Sponsorship and Donations

https://github.com/trapexit/support

Development and support of a project like mergerfs requires a significant amount of time and effort. The software is released under the very liberal ISC license and is therefore free to use for personal or commercial uses.

If you are a non-commercial user and find mergerfs and its support valuable and would like to support the project financially it would be very much appreciated.

If you are using mergerfs commercially please consider sponsoring the project to ensure it continues to be maintained and receive updates. If custom features are needed feel free to contact me directly.