Skip to main content
rm -rf command behaviour analysis across WSL filesystem boundaries including DrvFs and VolFs interactions

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

→ Short Answer

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.

⬡ Observed Behaviour

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.

Diagram showing rm -rf operation flow across WSL ext4 and DrvFs filesystem boundaries

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:

Default DrvFs permission mapping
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.

⚠ Common Pitfall

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:

/etc/wsl.conf — enabling DrvFs metadata
[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:

⬡ Observed Behaviour

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.

A directory on the ext4 filesystem that contains symlinks pointing to DrvFs paths creates a mixed deletion scenario:

Bash — symlink crossing the boundary
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

⚠ Common Pitfall

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.

Then

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.

Now

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.

Performance comparison of rm -rf on WSL ext4 versus DrvFs filesystem showing per-file operation overhead

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:

Bash — identify filesystem type
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

Bash — preview what rm -rf would delete
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:

Bash — using Windows cmd for deletion
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.

⚙ Compatibility Note

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.