Skip to content

FUSE open() on filename containing backslash deadlocks indefinitely in invalidate_inode_pages2 #660

Description

@firestaerter3

Summary

Files whose name contains a backslash character (\, 0x5C) cause the FUSE open() syscall to deadlock indefinitely in the kernel page cache layer. The mount stays "healthy" from a small-block read perspective, but any process that attempts to open() these files (Plex Media Scanner, ffprobe, etc.) ends up in uninterruptible D state and can only be cleared by rebooting the host/LXC.

We hit this four times in 26 hours before tracing it to backslash-in-path. Surfaces a lot like #647 ("multi-segment sequential reads deadlock") but the trigger and the surviving kernel stack are different, and rolling back to the dev_20260529-0315 build that #647's reporter confirmed good did not fix it on our deployment.

Symptoms

  • ls, stat, directory listing on the mount: all fine.
  • open() on an affected file: never returns. Process state = DN, wchan = folio_wait_bit_common.
  • altmount's own health-check (2% segment sample) reports the file as healthy.
  • altmount's streaming_failure_count for the file stays at 0 because the read never reaches userspace.
  • The wedge is not consumer-driven: any subsequent open() on the same inode also blocks, even from a fresh process.
  • Recovery: only by rebooting the host. docker stop on the consumer cannot reap a D-state process; the kernel folio stays locked.

Kernel stack (live D-state process captured pre-reboot)

[<0>] folio_wait_bit_common+0x136/0x330
[<0>] __folio_lock+0x17/0x30
[<0>] invalidate_inode_pages2_range+0x1b2/0x440
[<0>] invalidate_inode_pages2+0x17/0x30
[<0>] fuse_open_common+0x1c3/0x210
[<0>] fuse_open+0x10/0x20
[<0>] do_dentry_open+0x21d/0x570
[<0>] vfs_open+0x33/0x50
[<0>] path_openat+0xb1c/0x1190
[<0>] do_filp_open+0xaf/0x170
[<0>] do_sys_openat2+0xb3/0xe0
[<0>] __x64_sys_open+0x6e/0xa0

The same stack reproduces across all wedged processes (we counted 8 in one cascade, each on a different file, all with \ in the path).

Reproducer

Some NZB releases contain Windows-style backslashes inside their RAR-extracted directory structure. After altmount unpacks them, the virtual paths look like:

/mnt/altmount/complete/movies/<Release.Name>/Subdir name\Filename.mkv
                                                       ^
                                       single literal backslash inside the filename

To reproduce:

  1. Locate any altmount-served file whose name contains \ (we have ~78 of these across 38 release-dirs in our deployment).
  2. From any client that mounts the altmount FUSE (rclone-mount sidecar, in our case): run ffprobe, dd, or any binary that does open(2) on the file.
  3. The process enters DN state and never returns. kill -9 does not free it.
  4. cat /proc/<pid>/stack shows the trace above.

Example paths

Three patterns we see in the wedge-triggering files (release-group names removed for brevity):

/mnt/altmount/complete/movies/<release>/<X>\<X>.mkv
/mnt/altmount/complete/movies/<release>/<hex>\<hex>\<filename>.mkv
/mnt/altmount/complete/movies/<release>/<dir-name>.mkv\<dir-name>.mkv

The third pattern (last path component being <name>.mkv\<name>.mkv, literally) makes me suspect the WebDAV path resolver and the FUSE page-cache layer disagree about whether they are looking at one file or a directory plus file.

Multiple release groups are involved, so it is not a single-uploader issue. It looks more like a class of older scene archives that were packed on Windows with backslashes inside their internal directory structure, and the structure survives through RAR extraction into altmount's virtual filesystem.

What we have ruled out

Workaround we deployed

Two layers:

  1. Quarantine on disk. Move the offending release-dirs out of the Sonarr/Radarr scan paths into a sibling quarantine directory. Plex/Radarr mark the items as unavailable on the next scan and stop launching --analyze on them. Load returns to baseline within minutes.
  2. Radarr custom format. Added a custom format matching \\ in release titles, scored -10000, applied to the relevant quality profiles with minFormatScore=0. Prevents the next import from putting these releases back into the library.

Both are workarounds. The actual fix belongs in altmount's path-handling layer somewhere between RAR extraction, WebDAV path emission, and FUSE response. A backslash in a filename is technically legal on Linux, but altmount could either normalize it on extraction (replace \ with / and split, or with _) or reject the file with a clean EIO at open() time instead of hanging the kernel folio.

Environment

  • altmount image: ghcr.io/javi11/altmount:dev_20260529-0315 (also reproduces on pinned-20260513)
  • rclone-mount sidecar: rclone/rclone:latest, --vfs-cache-mode=full, --timeout=2m, --vfs-read-chunk-streams=4
  • Host: LXC on Proxmox PVE, Linux 6.8.12-16-pve, x86_64
  • Docker with userns-remap, cap_add: SYS_ADMIN, /dev/fuse
  • Three NNTP providers

Happy to provide

  • Full snapshot tarball (dmesg, ps auxf, kernel-stack dump for all D-state procs, altmount.log tail). ~450 KB.
  • Specific paths for clean repro (the release-dirs survive in our quarantine if you want to inspect over WebDAV).
  • The Radarr custom format JSON and the daily scan script we deployed as defense layers.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions