Fundamentals 6 min read

Debugging "directory not empty" errors from os.RemoveAll on a custom FUSE filesystem

This article details the investigation of a "directory not empty" failure when using Go's os.RemoveAll on a self‑built FUSE‑based distributed filesystem, describing the kernel readdir offset issue, the debugging steps taken, and the final fix applied.

360 Smart Cloud
360 Smart Cloud
360 Smart Cloud
Debugging "directory not empty" errors from os.RemoveAll on a custom FUSE filesystem

Background : A Go program compiled for a custom distributed filesystem mounted via FUSE failed when calling os.RemoveAll(dir) on a non‑empty directory, reporting "directory not empty".

Investigation Process : The team examined the FUSE client implementation, noting that FUSE operates as a user‑space filesystem framework. They reproduced the issue by creating a directory with 300 files and running the removal script, which consistently triggered the error.

Root Cause : The kernel, during a readdir operation, received an interrupt signal and resent the request from the previous offset to /dev/fuse. The client incorrectly discarded the partially returned data, causing subsequent reads to fail because the expected offset data was missing. This manifested as incomplete unlink operations and the "directory not empty" error.

Detailed Trace : The kernel invokes sys_getdents64, which leads to iterate_dir in VFS, then to fuse_readdir. The response is copied to user space via dir_emit. At a certain point, signal_pending(current) returned -4, interrupting processing and forcing a retry from the original offset, exposing the bug.

Fix : After confirming the signal handling was normal, the team corrected the distributed filesystem logic to properly handle interrupted readdir calls and ensure all files are unlinked before removing the directory. The issue was resolved.

Kernel Module Build Commands :

make CONFIG_FUSE_FS=m M=fs/fuse</code>
<code>yes | cp fs/fuse/fuse.ko /usr/lib/modules/4.18.0_80.7.1.el8_0_bch_v1.0/kernel/fs/fuse/</code>
<code>umount /mnt</code>
<code>umount /sys/fs/fuse/connections/</code>
<code>rmmod fuse</code>
<code>insmod /usr/lib/modules/4.18.0_80.7.1.el8_0_bch_v1.0/kernel/fs/fuse/fuse.ko

Ftrace Debugging Commands :

cd /sys/kernel/debug/tracing</code>
<code>echo 0 > tracing_on</code>
<code>echo > trace</code>
<code>echo syscalls:* > set_event</code>
<code>echo raw_syscalls:* >> set_event</code>
<code>echo ${pid} >> set_event_pid</code>
<code>echo 1 > tracing_on</code>
<code># run the program</code>
<code>cat trace

The experience shared aims to help others encountering similar FUSE‑related filesystem issues.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

debuggingkernelGoFUSEFilesystemos.RemoveAll
360 Smart Cloud
Written by

360 Smart Cloud

Official service account of 360 Smart Cloud, dedicated to building a high-quality, secure, highly available, convenient, and stable one‑stop cloud service platform.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.