Werunos is a lightweight userspace driver that mounts Ext4 and Btrfs partitions (as well as raw .img files) directly as native Windows drives. Running as a single, standalone binary, it operates independently of WSL2, virtual machines, or external kernel modules, emphasizing simplicity, high performance, and reliability.
Werunos enables direct access to Linux partitions on Windows without requiring dual-booting or virtual machines. It implements on-disk structure parsing, JBD2 journal replay, B-tree traversal, and logical chunk map resolution. Utilizing WinFsp, it exposes filesystems through a clean POSIX-compliant interface. Under Btrfs, it supports transparent on-the-fly decompression (zlib, LZO, and ZSTD segments), and incorporates native circular JBD2 journaling on Ext4 and native Copy-on-Write (CoW) B-tree updates on Btrfs to ensure crash-safe writes. Following the successful completion of the three core engineering phases, Werunos is fully complete, stable, and ready for production workloads.
- Overview
- Key capabilities
- Features
- Status
- Roadmap and phases
- Quick start
- Project layout
- Contributing
- Installation
- Usage
- Building
- Performance
- Limitations
- FAQ
- License
- Transparent decompression: Decodes zlib, LZO, and ZSTD compressed Btrfs extents on-the-fly.
- Robust B-tree mutations: Transactional Copy-on-Write B-tree root commits with CRC32c validation and multi-level splitting.
- Circular journal recovery: Replays the ext4 jbd2 journal to recover from unclean shutdowns.
- Crash-safe writes: Employs native JBD2 circular journaling on Ext4 and native Copy-on-Write (CoW) on Btrfs, with a sector-level redo log fallback.
- Read-only mount switch (
--ro): Enables 100% write-protected mounting for safe data recovery, forensics, and explorer access without administrative write authorization. - Superblock filesystem auto-detect: Queries and identifies Ext4 and Btrfs superblock signatures during disk listing, command checks, and mounting.
- Full POSIX semantics: High-fidelity support for hard links, symlinks, chmod, chown, and renames on both filesystems.
- Disk image mounting: Supports mounting raw partitions or
.imgfiles as native Windows drive letters. - Built-in filesystem check: Five-phase ext4 integrity checker (
fsck) with auto-repair and multi-tree Btrfs validation.
| Operation | Ext4 Support | Btrfs Support | Technical Implementation / Reference |
|---|---|---|---|
| Read files | Yes | Yes | reader.go (ext4) / tree.go (btrfs): Chunk translation, inline and regular extent walks |
| Write files | Yes | Yes (inline & regular) | writer.go (ext4) / fs.go (btrfs): Block allocs (ext4) and inline/regular writes with recursive multi-level B-tree node/leaf splitting (btrfs) |
| Create files | Yes | Yes | allocate.go (ext4) / fs.go (btrfs): Inode allocation, directory indexing updates |
| Delete files | Yes | Yes | reclaim.go (ext4) / fs.go (btrfs): Block reclamation (ext4), B-tree leaf key unlinking (btrfs) |
| Truncate (grow/shrink) | Yes | Yes | reclaim.go (ext4) / fs.go (btrfs): Extent splitting (ext4) and Copy-on-Write B-tree leaf resizing (btrfs) |
| Directory Ops | Yes | Yes | Traverses directory entries, initializes . and .. listings, performs unique DIR_INDEX counts |
| Rename | Yes | Yes | Unlinks old locations and registers new entries; unlinks targets atomically if already present |
| Symlinks | Yes | Yes | Fast/slow inode data pathways (ext4), and transparent inline symlink extent writing (btrfs) |
| Hard links | Yes | Yes | Reference counts (nlink) dynamically updated; blocks directory linking for POSIX compliance |
| chmod / chown | Yes | Yes | Directly mutates permission modes, UIDs, and GIDs, recalculating metadata CRCs / checksums |
| Compression | No | Yes | compress.go (btrfs): Transparent frame decompression (zlib, LZO, ZSTD) and dynamic Zlib write compression |
| Protection | Implementation |
|---|---|
| Redo log | redolog.go: pre-read (with thread-safe 64-slot LRU block cache) + log + fsync + write + truncate (fallback layer) |
| JBD2 commit | journal_writer.go: memory-buffered write transaction interceptor, packing descriptor blocks, escaped data blocks, and commit records circularly to the native JBD2 log area |
| Btrfs native CoW | writer.go / super.go: allocates new physical blocks for modified leaves/nodes, propagating pointers recursively, and transactionally commits updated roots directly to the superblock with CRC32c validation |
| jbd2 replay | jbd2.go: circular buffer walk, tag parse, escape deobfuscation |
| Orphan cleanup | jbd2.go: S_last_orphan list traversal, block + inode free |
| State auto-clear | reclaim.go: ClearSuperblockErrors() sets S_state = CLEAN |
| Recovery flag clear | jbd2.go: EXT4_FEATURE_INCOMPAT_RECOVERY cleared after replay |
| Superblock flush | Destroy() calls WriteSuperBlockPublic() on unmount |
| Graceful fallback | Journal replay failure → mount with warning (not block) |
| Command | Filesystem | Scope / What it checks |
|---|---|---|
werunos fsck |
Ext4 | 5-phase validation: block/inode bitmaps, inode sizes, directory structures (./..), and metadata/free-block balance. Auto-corrects mismatch states if --fix is passed. |
werunos fsck |
Btrfs | Systematically validates superblock fields, chunk logical-to-physical stripe mapping trees, and recursively checks CRC32c signatures and key index order. |
| Structure | Read | Write | File |
|---|---|---|---|
| Superblock (1024B at offset 1024) | ReadSuperBlock |
writeSuperBlock |
super.go |
| Group descriptors (32/64B each) | ReadGroupDescriptors |
WriteGroupDescriptor |
bgdesc.go, allocate.go |
| Inodes (128/256B) | ReadInode |
WriteInode |
inodes.go, allocate.go |
| Block bitmaps (1 block per group) | via fs.dev.ReadAt |
via fs.dev.WriteAt |
allocate.go, reclaim.go |
| Inode bitmaps (1 block per group) | via fs.dev.ReadAt |
via fs.dev.WriteAt |
allocate.go, reclaim.go |
| Extent trees (depth ≥0) | ReadExtents |
AppendExtent |
extents.go, allocate.go |
| Directory entries (DirEntry2) | ReadDir, Lookup |
AddDirEntry, RemoveDirEntry |
directory.go, dirent.go |
| jbd2 journal (circular buffer) | Read & replay | Native circular journal writes | jbd2.go, journal_writer.go |
| Symlinks (fast/slow) | ReadSymlink |
via I_block / WriteBlock + AppendExtent |
symlinks.go, bridge.go |
| Structure | Read | Write | File |
|---|---|---|---|
| Superblock (1024B at offset 65536) | ReadSuperBlock |
writeSuperBlock |
btrfs/super.go |
| Chunk tree physical maps | resolveChunkTree |
- | btrfs/tree.go |
| Inodes (160B inode items) | readInodeInfo |
updateInLeaf / insertInodeItem |
btrfs/fs.go, btrfs/writer.go |
| B-Tree node leaves | walkFSTree |
insertIntoLeaf / deleteFromLeaf / updateInLeaf |
btrfs/tree.go, btrfs/writer.go |
| Extent data items | readFile |
Write (inline & regular) |
btrfs/fs.go |
| Directory entries (DIR_INDEX) | readDirEntries |
insertDirEntry |
btrfs/fs.go, btrfs/writer.go |
| Symlinks (inline extents) | readSymlink |
Symlink (inline extent data) |
btrfs/fs.go |
Werunos is advanced and production-ready, but since it interacts directly with your raw filesystem blocks, you should always treat it with care. We highly recommend testing it on disk images or read-only copies first before running it on any critical, irreplaceable data. Always keep a backup!
To guarantee extreme stability and ensure every component compiles and runs flawlessly without regressions, the Werunos project follows a structured engineering roadmap consisting of three distinct execution phases:
- SafeDevice sector LRU block cache: Avoids synchronous physical disk pre-reads during sequential write operations.
- Real Btrfs ZSTD decompression: Integrates high-performance native ZSTD frame decoding for modern Linux partitions.
- Btrfs write compression: Adds transparent zlib write compression for compressible regular extents.
- Btrfs FSCK tree validator: Traverses chunk, root, and filesystem trees systematically, validating CRC32c signatures.
- Btrfs recursive multi-level index splits: Implements full index node splits up to arbitrary depths during directory growths.
- Ext4 multi-depth extent trees (Depth > 0): Implements intermediate extent indexing, splits, and tree depth scaling for large files.
- Ext4 Extended Attribute (EA) writes: Adds a full read-modify-write extended attribute engine supporting both fast in-inode and rollover external block writes.
- Btrfs native Copy-on-Write: Implements leaf and node updates via dynamic memory-resident block allocation and pointer propagation, committing roots directly to the serialized superblock with CRC32c checksum verification.
- Ext4 native JBD2 journal pipeline: Buffers write operations in an active memory-resident transaction wrapper, writing descriptor blocks, escaped data blocks, and commit records circularly to the JBD2 log area for standard recovery, eliminating the external block-level redo log requirement for journaled writes.
- Read-Only Safety Switch (
--ro): Intercepts mount parameters to allocate read-only descriptors, enforce fail-safe block write rejections, and mount the WinFsp drive letter with system-level write prevention. - Dynamic partition filesystem probing: Probes superblock offsets (
0x400for ext4,0x10000for btrfs) during disk listings to instantly detect and report formatted filesystem types.
Prerequisites:
- Go installed on your machine. Recommended: Go 1.18 or newer.
- WinFsp installed on Windows for FUSE support.
Build the project:
go build ./...
Run from source (example):
go run main.go
Run the test suite:
go test ./...
main.go- CLI entry point and mounting helpers.block/- low-level disk access, partition parsing, and sector alignment.host/- WinFsp integration and FUSE bridge code.fs/- unified virtual filesystem interface for transparent driver auto-detection.ext4/- ext4 adapter layer mapping path-level operations.btrfs/- btrfs core engine: B-tree parsing, logical chunk map walks, Copy-on-Write B-tree commits (CRC32c), and zlib/LZO segment decompression.vfs/- ext4 core implementation: superblock, inodes, extents, journal, and filesystem operations.docs/- design notes and ext4 reference material.
Contributions are welcome. If you plan to submit code:
- Open an issue to discuss large changes before implementing them.
- Fork the repository and create a feature branch for your work.
- Submit a pull request with tests and a clear description of the change.
Be careful when testing with real disks. Prefer disk images for development.
PartitionReader wraps an io.ReadWriterAt (the raw disk handle) and
translates every I/O by the partition's byte offset, so offset 0 of the
reader corresponds to the first byte of the partition. All reads/writes are
clamped to the partition boundary. The underlying handle is wrapped in
AlignedReaderAt for sector alignment.
Windows raw disk handles (\\.\PhysicalDriveN) require all I/O to be:
- Offset aligned to sector size (typically 512 or 4096 bytes)
- Length a multiple of sector size
AlignedReaderAt transparently rounds every request outward to sector
boundaries. Reads overshoot then discard. Writes use read-modify-write for
boundary sectors.
Detect GPT (UEFI) and MBR (legacy) partition tables. Parse all entries and
return structured Partition objects with type, offset, size, and name.
All 12 standard FUSE filesystem operations are implemented in host/bridge.go:
| Operation | Purpose |
|---|---|
Init/Destroy |
Lifecycle: log start/stop, flush superblock on unmount |
Statfs |
Filesystem statistics: total/free blocks and inodes |
Getattr |
File metadata: mode, size, timestamps, link count |
Opendir/Readdir/Releasedir |
Directory listing with cached entries |
Open/Read/Release |
File reading with extent caching in handles |
Write |
File writing with inode persistence and handle refresh |
Truncate |
Resize with block reclamation on shrink |
Create |
File creation with inode allocation and dir entry |
Mkdir |
Directory creation with ./.. initialization |
Unlink/Rmdir |
Deletion with block/inode free at link count 0 |
Rename |
Cross-directory move with existing-target handling |
Chmod/Chown |
Permission and ownership changes |
Symlink |
Fast/slow symlink creation |
Link |
Hard link creation (directory linking rejected) |
Werunos features a fully automated, interactive CLI installer that fetches, downloads, and silently configures WinFsp on Windows without requiring manual web downloads.
- Live Progress Indicators: Displays real-time download percentages and human-readable transfer counts (e.g.,
45% (9.8 MB / 21.6 MB)) directly in your terminal. - API Standard Compliance: Queries the GitHub API with a compliant User-Agent to safely locate the latest WinFsp release without rate-limiting rejections.
- Silent Background Execution: Executes the MSI package in silent mode (
msiexec /qn) to register drivers instantly behind the scenes. - Force Re-installation: If local files are corrupted, pass
--forceor-fto trigger a clean overwrite download.
# Open terminal as Administrator, then execute:
werunos install
# Force a clean re-install:
werunos install --forcewerunos devicesOutput:
Found 2 disk(s):
Disk 0: \\.\PhysicalDrive0
Partition table: GPT
# Name Type Filesystem Size
---- ------------------------ ------------------- ------------ -------
1 EFI system partition EFI System unknown 100 MiB
2 Microsoft reserved Microsoft basic data unknown 16 MiB
3 Basic data partition Microsoft basic data unknown 237 GiB
4 Linux filesystem Linux filesystem ext4 256 MiB
Disk 1: \\.\PhysicalDrive1
Partition table: GPT
# Name Type Filesystem Size
---- ------------------------ ------------------- ------------ -------
1 Linux filesystem Linux filesystem btrfs 1 TiB
werunos \\.\PhysicalDrive1 1# Mount a physical disk partition (supports ext4 & btrfs)
werunos mount G: 0 4 # PhysicalDrive0 partition 4 → G:\
werunos mount E: 1 1 # PhysicalDrive1 partition 1 → E:\
# Mount a partition in read-only safety mode
werunos mount F: 0 4 --ro # Mounts partition 4 of disk 0 in write-protected mode
# Mount a raw disk image file (supports ext4 & btrfs)
werunos mount Z: btrfs_test.imgThe mount blocks until Ctrl+C. While mounted, the drive appears in File Explorer and is accessible from any Windows application.
# Read-only scan
werunos fsck \\.\PhysicalDrive0 4
# Scan + fix
werunos fsck --fix \\.\PhysicalDrive0 4
# Scan a raw image
werunos fsck testfs.imgOutput:
Volume: home
Block size: 4096
Inodes: 65536
Blocks: 262144
Block groups: 8
Running integrity check...
Inodes checked: 1000
Directories: 24
Extents checked: 312
Blocks ref'd: 28147
No problems found: filesystem is healthy
go build -o Werunos.exe .Requires Go 1.21+. The only external dependency is github.com/winfsp/cgofuse.
All metadata writes are synchronous. The redo log adds one extra read (old data)
and one extra write (log entry) per WriteAt. For interactive workloads
(editing files, saving documents), the overhead is imperceptible.
For bulk operations (extracting archives, building code, database writes), performance is bottlenecked by the disk's random I/O speed. Typical throughput on a SATA SSD for sequential writes: 150-300 MB/s. Random 4K writes: 5-15 MB/s.
| Limitation | Impact | Technical reason / Rationale |
|---|---|---|
| No encryption | Encrypted files (EXT4_ENCRYPT_FL / fscrypt) are skipped. |
Requires integration with kernel keychain/keyring libraries. |
| No ext4 metadata checksums | metadata_csum feature is not verified or updated on ext4 writes. |
Verification would add significant parsing overhead (Btrfs CRC32c is fully calculated). |
| No online defrag | FICLONE / FIDEDUPERANGE IOCTLs are ignored. |
These are Linux-kernel specific IOCTL calls. |
Will this corrupt my Linux partition?
We put safety first. Every single write is covered by our redo log, which makes it fully recoverable. If Werunos crashes mid-write, the next startup will automatically restore the pre-write state. We also have circular journal replays and dynamic filesystem checks (fsck) to add extra layers of protection. That said, because this code operates directly at the raw filesystem block level, there are no absolute guarantees. Always keep a backup of your important data!
How do I unmount?
Press Ctrl+C in the terminal where Werunos mount is running.
What happens if the power goes out while writing?
The redo log has the pre-write block content, fsynced to disk. On next startup,
NewSafeDevice detects the pending log, writes the old data back, and clears
the log. The filesystem is in the same state as before the write.
Does this work with Windows fast startup?
Yes, absolutely. Windows' fast startup feature only affects NTFS system partitions; it does not touch your Linux ext4 or btrfs partitions, so you are completely safe.
Why not just use WSL2?
While WSL2's wsl --mount works, it requires you to have WSL2 fully installed, a Linux VM running in the background, and the drive must be mountable as a volume. Werunos, on the other hand, is a single standalone Windows binary with absolutely no dependencies beyond WinFsp. It is quick, clean, and runs instantly without loading a VM.
What filesystem features are NOT supported?
For Ext4: legacy indirect blocks, inline data, and encryption. For Btrfs: RAID stripe groups (such as RAID5/6) and subvolume-level tracking. All common layout structures (ext4 extents, flex_bg, 64bit, HTree directories, btrfs system chunk tables, logical stripe chunk maps, leaf items, zlib/LZO/ZSTD segment frames) are fully supported.
Werunos aims to expand userspace driver coverage and enhance transactional safety. The roadmap includes:
- Online Metadata Defragmentation: Support standard filesystem block defragmentation and layout optimization directly from userspace.
- Ext4/Btrfs Native Encryption Integration: Interface with Windows security descriptor keychains to support transparent read-write access to
fscryptencrypted files. - Subvolume and Multi-Device RAID Support (Btrfs): Extend Btrfs stripe parsing to support fully native RAID5/RAID6 multi-device volume configurations.
MIT