rm -rf Behaviour in WSL: What Actually Happens
Running rm -rf inside WSL does not behave the same as running it on a native Linux filesystem, and the differences range from subtle performance characteristics to genuinely consequential deletion failures that leave files in ambiguous states across the Windows–Linux boundary. This technical note documents the specific observed behaviours when rm -rf operates on WSL's internal ext4 filesystem, on DrvFs-mounted Windows drives, and on paths that cross the boundary between the two — based on direct testing across WSL 1 and WSL 2 on multiple Windows builds. The coverage includes permission model interactions, the difference between VolFs and DrvFs deletion semantics, the specific edge cases where files appear deleted from one side but persist on the other, and the safety practices that prevent data loss in a dual-filesystem environment. This note sits within the tech notes section and connects to the LXSS and lxrun documentation on WSL internals and the Linux on Windows topic hub.
The two filesystems you are actually using
WSL operates across two fundamentally different filesystem layers. The Linux-native filesystem (ext4 on WSL 2, or VolFs on WSL 1) stores files inside the WSL environment with full Linux permission semantics. The Windows filesystem is accessible through DrvFs mounts at /mnt/c, /mnt/d, etc. When you run rm -rf, the behaviour depends entirely on which filesystem the target path resides on — and the differences are significant enough that the same command can succeed completely, fail silently, or produce a partially-deleted state depending on the path.
ext4 / VolFs: the Linux-native side
On WSL 2, the Linux distribution's root filesystem is a real ext4 filesystem stored inside a VHDX (Virtual Hard Disk) file on the Windows side. Inside that filesystem, rm -rf behaves identically to native Linux. File permissions are real Linux permissions. Inode operations work as expected. The unlink() and rmdir() system calls operate against a real Linux kernel (WSL 2 runs an actual Linux kernel in a lightweight VM). There are no translation layers, no permission mapping quirks, and no cross-platform edge cases.
On WSL 1 (the original LXSS architecture), the Linux filesystem — called VolFs — stored files on NTFS with Linux metadata encoded in NTFS extended attributes. rm -rf on VolFs paths worked correctly from the Linux side but had a specific fragility: if the files had been touched by Windows tools (which could strip the extended attributes), the deletion might encounter permission errors that did not correspond to the visible Linux permission bits.
DrvFs: the Windows filesystem layer
DrvFs is the filesystem driver that makes Windows drives accessible inside WSL as /mnt/c, /mnt/d, and so on. When rm -rf targets a path under /mnt/c, the operation must cross the boundary between Linux filesystem semantics and Windows NTFS semantics. This is where the interesting behaviour lives.
When rm -rf targets a directory on DrvFs (e.g., /mnt/c/Users/name/project), the operation translates Linux unlink() and rmdir() calls into Windows file deletion operations through the 9P protocol (WSL 2) or the LXSS translation layer (WSL 1). Files that are open by Windows processes — including files held open by indexing services, antivirus scanners, OneDrive sync, or Windows Search — cannot be deleted and produce Permission denied or Device or resource busy errors. The -f flag suppresses the error messages but does not force the deletion. The result is a partially-deleted directory tree where some files are gone and others remain.
Permission handling across the boundary
The permission model mismatch between Linux and Windows is the root cause of most unexpected rm -rf behaviour on DrvFs paths.
How DrvFs maps permissions
DrvFs presents Windows files to WSL with synthesised Linux permission bits. The mapping is configurable through /etc/wsl.conf or mount options, but the defaults are:
Files: -rwxrwxrwx (0777)
Directories: drwxrwxrwx (0777)
Owner: the WSL user's UID
Group: the WSL user's GID
This means rm -rf sees everything as writable and owned by the current user. The Linux permission check passes unconditionally. The actual access control happens at the Windows level, when the translated file operation hits NTFS ACLs. If the Windows user associated with the WSL session has permission to delete the file (according to NTFS), the deletion succeeds. If not — because the file is owned by a different Windows user, because it is in a protected system directory, or because a Windows process has it locked — the operation fails regardless of what the Linux permission bits show.
Seeing rwxrwxrwx permissions on a DrvFs file does not mean you can delete it. The Linux permission display is a synthetic representation. The actual permission enforcement happens at the NTFS layer, which ls -la does not show. This is the single most confusing aspect of rm -rf on DrvFs: the permissions say yes, but the filesystem says no. The error message you receive — typically Permission denied — makes it look like a Linux permission problem when it is actually a Windows ACL or file-locking problem.
The metadata mount option
WSL 2 supports a metadata mount option for DrvFs that stores real Linux permission bits as NTFS extended attributes:
[automount]
options = "metadata,umask=022,fmask=133"
With metadata enabled, files created from WSL on DrvFs get actual Linux permission bits stored alongside them. This changes the rm -rf behaviour because the Linux permission check now evaluates real permission data rather than the synthetic 0777. A file created with chmod 444 from WSL will resist deletion with rm (prompting for confirmation) — though rm -f still bypasses the prompt, and the actual deletion still depends on NTFS ACLs.
The specific edge cases
Files locked by Windows processes
The most common cause of partial rm -rf failures on DrvFs:
Running rm -rf on a project directory under /mnt/c while Visual Studio Code, Windows Defender, or OneDrive has files in that directory open results in a mix of deleted and surviving files. The command exits with status 0 (success) because -f suppresses errors, but a subsequent ls reveals files that were not deleted. The surviving files are those that were locked by Windows processes at the moment of the deletion attempt. Repeating the rm -rf after closing the interfering process deletes the remaining files.
This is not a WSL bug. It is a direct consequence of Windows file-locking semantics, which differ fundamentally from Linux. On native Linux, unlink() removes the directory entry immediately; the file data persists until the last file descriptor is closed, but the filename is gone. On Windows (NTFS), a file that is open by any process cannot be deleted — the deletion call fails, not the name removal.
Symlinks that cross filesystem boundaries
A directory on the ext4 filesystem that contains symlinks pointing to DrvFs paths creates a mixed deletion scenario:
mkdir ~/project
ln -s /mnt/c/Users/name/data ~/project/data-link
rm -rf ~/project
In this case, rm -rf deletes the symlink itself (which lives on ext4) but does not follow the symlink to delete the target directory on DrvFs. This is standard rm behaviour — rm never follows symlinks during recursive deletion — but it surprises users who expected the linked Windows data to be removed as well.
The reverse scenario is more dangerous: a directory on DrvFs containing symlinks that point back into the ext4 filesystem. Deleting from the Windows side (Explorer, del /s) may follow junction points or symlinks depending on the Windows version and the specific type of link, potentially deleting files inside your WSL distribution's filesystem.
The /mnt/c root directory
Running rm -rf /mnt/c/ from WSL will attempt to recursively delete the entire contents of your Windows C: drive. WSL does not prevent this. There is no safety mechanism that distinguishes this from any other recursive deletion. The only protection is NTFS ACLs and Windows file locking — system files that are in use or protected by TrustedInstaller will survive, but user data, programme files not currently in use, and anything the WSL session has write access to will be deleted. Do not assume that the WSL boundary provides any protection against accidental recursive deletion targeting a DrvFs mount point.
Performance characteristics of rm -rf across filesystems
The speed of recursive deletion varies dramatically depending on the filesystem target:
ext4 (WSL 2 internal): Fast. Comparable to native Linux performance. The operation is kernel-native within the lightweight VM. Deleting a node_modules directory with 50,000 files completes in seconds.
DrvFs via 9P (WSL 2 accessing /mnt/c): Slow. Each file deletion requires a round-trip through the 9P filesystem protocol between the Linux VM and the Windows host. The same node_modules deletion can take minutes rather than seconds. The overhead is per-operation, so directories with many small files are disproportionately affected.
VolFs (WSL 1 internal): Moderate. Faster than DrvFs cross-filesystem access but slower than native ext4 because every operation goes through the LXSS syscall translation layer.
WSL 1 / LXSS era: All filesystems — both VolFs and DrvFs — were accessed through the syscall translation layer. Performance was mediocre but consistent. The rm -rf performance difference between internal and mounted Windows paths was noticeable but not dramatic. The bigger problem was metadata corruption: files edited from Windows could lose their Linux extended attributes, causing rm to encounter unexpected permission states.
WSL 2: Internal ext4 deletion is fast (real kernel, real filesystem). DrvFs deletion is slow due to 9P protocol overhead. The performance gap between internal and mounted paths is far wider than it was under WSL 1. The standard advice — keep project files on the ext4 filesystem, not under /mnt/c — applies especially to operations that touch many files, including rm -rf on large directory trees.
Safe practices for rm -rf in WSL
Given the cross-filesystem complexities, a few practices reduce the risk of unexpected results:
1. Know which filesystem you are targeting
Before running rm -rf, check the mount point:
df -T /path/to/target
mount | grep "$(df /path/to/target | tail -1 | awk '{print $1}')"
If the filesystem type is ext4 or overlay, you are on WSL's internal filesystem. If it is 9p or drvfs, you are on a Windows mount. Adjust your expectations accordingly.
2. Dry-run with find before deleting
find /path/to/target -depth -print | head -50
find /path/to/target -depth -print | wc -l
This shows you the files that rm -rf would attempt to delete, and how many there are. On DrvFs paths, a large file count means a slow operation with potential partial failures.
3. Close Windows processes before DrvFs deletion
If you are deleting a project directory under /mnt/c, close editors, file managers, and any other Windows applications that might have files in that directory open. Stopping Windows Search indexing for the target directory (through Windows Settings → Indexing Options) eliminates one of the most common sources of file locks.
4. Use Windows tools for Windows files
For large deletions on DrvFs paths, it is sometimes faster and more reliable to use Windows tools from within WSL:
cmd.exe /c "rmdir /s /q C:\Users\name\project"
This delegates the deletion to Windows, which handles NTFS operations natively without the 9P translation overhead. The Windows rmdir /s /q is not faster per-file, but it avoids the protocol translation cost and handles Windows file locking in the expected Windows way (waiting and retrying rather than failing immediately).
5. Never target /mnt/ root directories carelessly
This should go without saying, but rm -rf /mnt/c is a real command that will really attempt to delete your Windows installation. Tab-completion in WSL does not distinguish between paths you probably want to delete and paths you definitely do not. Double-check your target path, especially in scripts.
The behaviour described in this note applies to WSL 2 on Windows 10 version 2004 and later, and Windows 11 all versions. WSL 1 behaviour differs in the specific ways noted throughout the text, primarily around the VolFs metadata handling and the absence of 9P protocol overhead. If you are still running WSL 1 (check with wsl -l -v), the DrvFs performance characteristics are different, but the permission model mismatches and file-locking issues apply equally.
Why this matters beyond rm -rf
The filesystem boundary behaviour documented here affects every file operation in WSL, not just deletion. mv, cp, chmod, chown, tar, rsync — any tool that manipulates files encounters the same DrvFs translation layer and the same permission model mismatch when operating on /mnt/c paths. rm -rf is simply the operation where the consequences of unexpected behaviour are most visible and least reversible.
Understanding the dual-filesystem nature of WSL — and the specific behaviours that arise at the boundary — is fundamental to working effectively in the environment. The standard advice to keep project files on the Linux filesystem is not arbitrary preference. It is a direct response to the observable performance and reliability characteristics documented here.
The Running X11 Applications on WSL guide covers another area where WSL's dual nature creates practical challenges, and the LXSS and lxrun tech note provides the historical context for why the filesystem architecture works the way it does.