Skip to content

mergerfs pool — /mnt/storage, the union every container sees

disk1:disk2:disk3 pooled by mergerfs 2.33.5. This is the only path containers, Samba, rsnapshot and the backup scripts use. The individual /mnt/diskN mounts exist for SnapRAID and for humans.

Why this shape

One namespace over three independent ext4 disks so a single disk failure costs a slice, not the whole library, and each disk remains readable on its own. category.create=mfs spreads new files by most-free-space; that is also why cross-disk hardlinks fail and the *arrs copy instead (item 16).

Shape

fstab line (installed 2026-09-03 14:08, backup /etc/fstab.bak.2026-09-03-item13):

/mnt/disk1:/mnt/disk2:/mnt/disk3 /mnt/storage fuse.mergerfs allow_other,use_ino,cache.files=partial,dropcacheonclose=true,category.create=mfs,moveonenospc=true,minfreespace=50G,posix_acl=true,fsname=mergerfs,nonempty,nosuid,nodev,noatime,x-systemd.requires=/mnt/disk1,x-systemd.requires=/mnt/disk2,x-systemd.requires=/mnt/disk3 0 0

Version-specific facts that were wrong in the original plan — do not "clean up": - use_ino is required on 2.33.5: it enables inodecalc; 49 hardlink groups and *arr hardlink detection depend on both names reporting one inode. (It becomes a hard mount failure only on ≥ 2.40.) - nonempty is still enforced on this version. Keep it. - epmfs was rejected: no fallback (ENOSPC), and 53 % of tv/, 18 % of movies/ folders exist on exactly one branch. - x-systemd.requires ×3 fixes a real boot race: the old unit had no dependency on the branches; had the pool won, Docker's create_host_path would have written media onto the NVMe under the mountpoint.

Consumers that must stop before an unmount: 15 compose services + samba-nas (docker-run). Sequence used 09-03: prove options on a 2nd instance at /mnt/storage-test → stop consumers → fuser clean → umountls -A gate (0 entries) → mountdaemon-reload → validate xattr/inode/write → start in dependency order. Pool was down 20 s.

Connected to

If you change this

  • Hits: every container with a /mnt/storage bind (gluetun/qbittorrent, plex, jellyfin, *arrs, immich-server, tdarr, filebrowser, glances, samba-nas) · docker-backup.sh and precious-sync.sh (both refuse to run if it is not a mountpoint — good) · rsnapshot (backup /mnt/storage/…) · mnt-storage.mount unit options (run daemon-reload).
  • Does not hit: SnapRAID (reads /mnt/diskN directly) · the rescue USB · Pi-hole, NPM, wg-easy, homer, uptime-kuma (no media binds).

Surfaces

Surface Role
findmnt /mnt/storage live options; mnt-storage.mount Requires/After all three branches
df -h /mnt/storage ~11 TB, 44 % used

See

  • Source: /etc/fstab · systemctl cat mnt-storage.mount