Skip to content

Segfault: Race condition in concurrent cache operations with high thread counts #1468

Description

@TylerMills

Describe the bug

MergerFS v2.40.2 experienced a segmentation fault during heavy I/O operations from SABnzbd (Usenet downloader). The segfault caused the MergerFS mount to become unresponsive with "Transport endpoint is not connected" errors, which then caused all Docker containers using the mount to fail.

Please be sure to use latest release of mergerfs to ensure the issue still exists. Not your distro's latest but the latest official release.

Using mergerfs v2.40.2 (latest official release as of March 1, 2024)

To Reproduce

Steps to reproduce the behavior:

  1. MergerFS mount configured with 4 branches (1 SSD cache + 1 ZFS pool + 2 NFS shares)
  2. Heavy concurrent write operations via SABnzbd downloading multiple large files simultaneously
  3. Cache SSD was at 73% capacity with ~68GB of incomplete downloads
  4. After approximately 30-60 minutes of heavy downloading, MergerFS segfaulted

MergerFS mount configuration from /etc/fstab:

/mnt/cluster-cache-1:/mnt/cluster-c:/mnt/cluster-a:/mnt/cluster-b /mnt/storage-cluster fuse.mergerfs allow_other,use_ino,cache.files=full,dropcacheonclose=true,category.create=ff,minfreespace=16G,uid=1000,gid=1000,cache.writeback=true,cache.statfs=60,cache.attr=60,cache.entry=60,cache.negative_entry=60,cache.symlinks=true,cache.readdir=true,parallel-direct-writes=true,read-thread-count=16,process-thread-count=16,readahead=1024,security_capability=false,posix_acl=false,async_read=false,_netdev,nonempty,x-systemd.automount,noauto,nofail,x-systemd.requires-mounts-for=/mnt/cluster-cache-1,x-systemd.requires-mounts-for=/mnt/cluster-a,x-systemd.requires-mounts-for=/mnt/cluster-b,x-systemd.requires-mounts-for=/mnt/cluster-c 0 0

Expected behavior

MergerFS should handle high concurrent I/O operations without crashing, even under heavy load from applications like SABnzbd.

System information:

  • OS, kernel version:
Linux home-server 6.11.0-25-generic #25~24.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue Apr 15 17:20:50 UTC 2 x86_64 x86_64 x86_64 GNU/Linux
  • mergerfs version:
mergerfs v2.40.2
  • mergerfs settings:

    • Branches: /mnt/cluster-cache-1:/mnt/cluster-c:/mnt/cluster-a:/mnt/cluster-b
    • Create policy: ff (fill first)
    • Min free space: 16G
    • Cache settings: cache.files=full, cache.writeback=true, various cache timeouts set to 60
    • Thread counts: read-thread-count=16, process-thread-count=16
    • Other: parallel-direct-writes=true, readahead=1024
  • List of drives, filesystems, & sizes:

Filesystem                                Size  Used Avail Use% Mounted on
/dev/nvme0n1p3                            1.8T  1.3T  472G  73% /mnt/cluster-cache-1
cluster-c                                 130T  2.1T  128T   2% /mnt/cluster-c
67.2xx.xxx.xxx:/var/nfs/shared/cluster_a   88T  1.1T   87T   2% /mnt/cluster-a
67.2xx.xxx.xx:/var/nfs/shared/cluster_b   88T   59T   29T  68% /mnt/cluster-b

Filesystem types:

  • /mnt/cluster-cache-1: ext4 on NVMe SSD
  • /mnt/cluster-c: ZFS pool (10x HDD RAIDZ)
  • /mnt/cluster-a & /mnt/cluster-b: NFS v3 shares from Ubiquiti UNAS Pro

Crash Information:

Kernel log showing segfault:

[Fri May 23 00:22:56 2025] fuse.process[726341]: segfault at 762726058079 ip 000063e52d992140 sp 00007620cb7eb408 error 4 in mergerfs[73140,63e52d92d000+7c000] likely on CPU 25 (core 41, socket 0)
[Fri May 23 02:12:25 2025] fuse.process[791721]: segfault at 79904d7c2c61 ip 00005f2109fef140 sp 00007998633ec408 error 4 in mergerfs[73140,5f2109f8a000+7c000] likely on CPU 25 (core 41, socket 0)

Signal from crash dump: 11 (SIGSEGV)

Command line at crash:

mergerfs /mnt/cluster-cache-1:/mnt/cluster-c:/mnt/cluster-a:/mnt/cluster-b /mnt/storage-cluster -o rw,allow_other,use_ino,cache.files=full,dropcacheonclose=true,category.create=ff,minfreespace=64G,uid=1000,gid=1000,cache.writeback=true,cache.statfs=60,cache.attr=60,cache.entry=60,cache.negative_entry=60,cache.symlinks=true,cache.readdir=true,parallel-direct-writes=true,read-thread-count=16,process-thread-count=16,readahead=1024,security_capability=false,posix_acl=false,async_read=false,nonempty,dev,suid

Additional context

  • The crash occurred during heavy write operations from SABnzbd downloading multiple large files
  • A cache mover container (ghcr.io/monstermuffin/mergerfs-cache-mover) was configured to run every 30 minutes but had exited earlier
  • The system had been running for several days without issues before this crash
  • After the crash, attempts to remount MergerFS failed with "Transport endpoint is not connected" errors
  • A full crash dump is available at /var/crash/_usr_bin_mergerfs.0.crash (101MB)
  • The crash appears to consistently happen on CPU 25 (core 41, socket 0)

The timing suggests the crash may be related to high concurrent I/O operations, possibly a race condition when handling multiple write operations across different backend filesystems (local SSD, ZFS, and NFS).

Crash Dump Analysis

Analysis of the core dump reveals:

  1. Memory Corruption Evidence:

    • Register values show corrupted pointers: rax=0xaac1296ebc486919, rbx/rcx/rdi=0xee091b86ee1d6979
    • These values appear to be garbage data indicating memory corruption
    • The instruction pointer (rip=0x63e52d992140) was at a valid code location in mergerfs
  2. Thread State at Crash (34 threads total):

    • Multiple threads performing posix_fadvise64 with POSIX_FADV_DONTNEED (advise=4) on various file descriptors
    • Several threads reading from fd=4 (likely the FUSE device) with 1MB buffers
    • One thread performing fdatasync on fd=135
    • One thread performing pwrite64
    • Process was in "D" state (disk sleep) with 34 threads, using ~89MB RSS
  3. Concurrent I/O Pattern:

    • Many threads simultaneously calling posix_fadvise to drop cache pages
    • This suggests aggressive cache management under memory pressure
    • The combination of high thread counts and cache operations likely triggered a race condition
  4. GDB Stack Traces (abbreviated):

    Thread 1 (crashed): #0  0x000063e52d992140 in ?? ()
    Thread 25: #0  __GI_fdatasync (fd=135)
    Thread 24: #0  __libc_pwrite64 (fd=72, count=3593)
    Threads 23-14,12-5: #0  __GI___libc_read (fd=4, nbytes=1052672)
    Threads 34-26,13: #0  __GI___posix_fadvise64_l64 (advise=4)
    

Likely Root Cause:
The crash appears to be a race condition in the cache management code when multiple threads simultaneously attempt to drop cache pages (posix_fadvise with DONTNEED) under heavy I/O load. The combination of:

  • High thread counts (16 read + 16 process threads)
  • Aggressive caching (cache.files=full, cache.writeback=true)
  • parallel-direct-writes=true
  • dropcacheonclose=true

Creates conditions where memory structures can be corrupted during concurrent cache operations.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions