Mergerfs is a FUSE based union filesystem that allows pooling of mount points or other directories into a single virtual directory. While it does consume significant CPU resources and somewhat limit maximum throughput it works well otherwise and is easy to set up. It still offer sufficient performance for a home server use. It is very similar to other union file systems such as MHDDFS.
Install with packer.
packer -S mergerfs
Setup Mergerfs Mount Points
Create a directory that will be used as a mount point for the virtual pool.
sudo mkdir /mnt/merger
In the case where mergerfs fails to mount at boot time or gets unmounted for any reason the mount point is still accessible. This means that any application will still see a volume but instead of the pooled volume it will be a directory on the underlying file system. This means that data can be written to this directory potentially filling the system drive. This unwanted behaviour can be prevented by allowing only root access and setting the immutable attribute on the mount point.
Set the mount point ownership to root user and group.
sudo chown root:root /mnt/merger
Set the mount point permissions to allow full access to the owner and group.
sudo chmod 770 /mnt/merger
Set immutable flag on the mount point to prevent accidental changes to ownership or permissions.
sudo chattr +i /mnt/merger
When set the immutable flag will prevent changing permissions or ownership by anyone including root user. The flag can be removed with
-i option as superuser.
Mount Mergerfs manually
Mount the volume with desired options.
sudo mergerfs -o defaults,allow_other,direct_io,use_ino,fsname=mergerfs,minfreespace=50G,func.getattr=newest /mnt/disk\* /mnt/merger
The defaults option sets several recommended option at once. To allow access to users other than the one that mounted mergerfs volume use
allow_other option. Enabling
direct_io disables caching which can improve write speeds at the cost of read speed reduction. It is also generally recommended to enable
use_ino option so that hard linked files share the same inode value. By default the name of the volume will appear as a list of source paths concatenated together with longest common prefix removed, to change this to something more readable
fsname option is used.
Optionally set a minimum limit to prevent a physical hard drive from filling up beyond a certain point. Minimum limit value can be specified in megabytes M, kilobytes K or gigabytes G with
minfreespace option. If omitted the the default value of
4G will be used. This means the limit can be set to a very low value to spread data on all drives. If you want directories to fill up before moving on to the next drive the default of
4GB is sufficient to prevent severe performance loss. For optimal performance it’s a good idea to leave 5% to 10% of the storage device free.
Kodi, Plex, Subsonic and other applications can use modified date attribute to speed up scanning. This attribute can be inconsistent on a mergerfs volume. This can be worked around in at least some of the applications. A catch all fix is to use
funct.getattr=newest option which will show the directory with the most recent mdate attribute. Note that this option can cause drives to spin up more often.
Mount Mergerfs with fstab
Open the file systems table file.
sudo nano /etc/fstab
Add the mount command at the end of the file.
/mnt/disk* /mnt/merger fuse.mergerfs defaults,allow_other,direct_io,use_ino,fsname=mergerfs,minfreespace=50G,func.getattr=newest 0 0
Mount the fstab entry.
sudo mount /mnt/merger
Optionally all entries in can be mounted with
-a option instead of the specific mount.
Mount Mergerfs with Systemd
The advantage of mounting with systemd service is that it is much easier to remember systemd start command than it is to remember the full mhddfs mount command. It is also a good practice to mount mergerfs after physical disks in fstab have been mounted. Mergerfs package does not come with a systemd script by default so a custom script needs to be created.
Create the mount script.
sudo nano /etc/systemd/system/mnt-merger.mount
Note that the name of the systemd mount file has to match the
Where = field. Slashes ( / ) in the path are replaced by dashes ( – ). So
mnt-merger. Non matching name will result in a failed start of the script with error “Where= setting doesn’t match unit name. Refusing.“.
Copy the script and save.
[Unit] Description = Mount mergerfs volume Requires = mnt-disk1.mount Requires = mnt-disk2.mount Requires = mnt-disk3.mount Requires = mnt-disk4.mount Requires = mnt-disk5.mount Requires = mnt-disk6.mount Requires = mnt-disk7.mount Requires = mnt-disk8.mount After = mnt-disk1.mount After = mnt-disk2.mount After = mnt-diks3.mount After = mnt-diks4.mount After = mnt-diks5.mount After = mnt-diks6.mount After = mnt-diks7.mount After = mnt-diks8.mount After = mnt-diks9.mount After = mnt-diks10.mount [Mount] What = /mnt/disk* Where = /mnt/merger Type = fuse.mergerfs Options = defaults,allow_other,direct_io,use_ino,fsname=mergerfs,minfreespace=50G,func.getattr=newest [Install] WantedBy = multi-user.target
Start the service.
sudo systemctl start mnt-merger.mount
Enable the service to run on boot.
sudo systemctl enable mnt-merger.mount