Skip to content
xdqiPublic

Repository files navigation

anyfs-reader

Read any Linux-supported filesystem from userspace — no root, no FUSE, no kernel modules.

Uses LKL (Linux Kernel Library) to run actual kernel filesystem code in a library. Supports raw disk images and QEMU-compatible formats (qcow2, vmdk, vdi) via linked QEMU block layer.

Get it

Edition Where Engine
Web https://anyfs.kosaka.moe: open a local image or an HTTP(S) URL; the image is read in the browser, not uploaded wasm (LKL + QEMU block layer built with emscripten) in a Web Worker
Desktop: Linux x64, Windows x64, macOS (Apple silicon and Intel) Electron app, see Desktop app native addon (anyfs_native.node); the wasm engine is the fallback
CLI servers and tools anyfs-ksmbd, anyfs-nfsd, anyfs-lspart, anyfs-fuse: tarballs from the linux, mingw64 and macos CI workflows, see docs/distribution.md and docs/macos.md native

Desktop app

The desktop app is the web app's interface in Electron, with the kernel running natively in the app process instead of in wasm. It opens images by path (raw, qcow2, vmdk, vdi, vhd(x), dmg, ...) and HTTP(S) URLs, and reads them read-only.

Partition picker for an Ubuntu 26.10 cloud image

An Ubuntu 26.10 cloud image (qcow2, development branch) opened in the Linux build: every GPT partition with its size, label, filesystem and partition type. The BIOS boot partition has no filesystem and cannot be opened.

Root directory of the ext4 root partition

The image's ext4 root filesystem, read by the Linux kernel's own ext4 driver running inside the app (LKL). Symbolic links (bin, lib, sbin) carry a link icon.

Properties of /etc/hosts

Properties of /etc/hosts: mode, owner, inode, block usage and timestamps come from the kernel's stat.

The screenshots show the Linux x64 package built by CI (sha-d11d371), captured with Playwright (ts/tests/e2e/packaged/docs-screenshots.spec.ts).

Download. Tagged releases (vX.Y.Z) attach anyfs-electron-X.Y.Z-linux-x64.tar.gz, anyfs-electron-X.Y.Z-windows-x64.zip, anyfs-electron-X.Y.Z-macos-arm64.zip, anyfs-electron-X.Y.Z-macos-x64.zip and SHA256SUMS to GitHub Releases; no desktop release has been tagged yet. Every commit on main is also packaged by the electron workflow: open a run and download the anyfs-electron-sha-<commit>-<linux|windows|macos>-<x64|arm64> artifact (GitHub sign-in required, kept 14 days). Each artifact holds the archive and its .sha256.

Run.

# Linux
sha256sum -c anyfs-electron-<version>-linux-x64.tar.gz.sha256
tar -xzf anyfs-electron-<version>-linux-x64.tar.gz
./anyfs-electron-<version>-linux-x64/anyfs-demo
# macOS (arm64 for Apple silicon, x64 for Intel)
shasum -a 256 -c anyfs-electron-<version>-macos-arm64.zip.sha256
ditto -x -k anyfs-electron-<version>-macos-arm64.zip .
xattr -dr com.apple.quarantine anyfs-electron-<version>-macos-arm64/anyfs-demo.app
open anyfs-electron-<version>-macos-arm64/anyfs-demo.app

On Windows, check the hash with Get-FileHash anyfs-electron-<version>-windows-x64.zip, extract the zip and start anyfs-demo.exe. The packages are not code-signed: Windows SmartScreen may show "Windows protected your PC" (choose More info, then Run anyway). The macOS app is signed ad hoc only, not with a Developer ID and not notarized, so macOS refuses to open a downloaded copy until the quarantine attribute is removed as above (or System Settings → Privacy & Security → Open Anyway is used after the first attempt). On Linux distributions that restrict unprivileged user namespaces (Ubuntu 24.04 and later), Chromium's sandbox cannot start from an unpacked archive; run anyfs-demo --no-sandbox, or make chrome-sandbox owned by root with mode 4755.

OS Arch Requirement Tested in CI on
Linux x64 glibc 2.25 or later and Chromium's usual desktop libraries (GTK 3, NSS, libgbm) Ubuntu 26.04
Windows x64 Windows 10 or later Windows Server 2025
macOS arm64, x64 macOS 12 or later (Electron 42's floor; the native libraries alone would go lower) macOS 15 on Apple silicon and on Intel

Native and wasm. The start screen says "Native bridge active" when the native addon is loaded. If it cannot load, the app falls back to the wasm engine the web edition uses; Settings → Disable native module switches to it on purpose. CI checks that every package starts on the native backend. "Open system drive…" lists the computer's disks and partitions with their filesystems, labels and mountpoints (the drivelist-anyfs addon); opening a raw device still needs the rights to read it (administrator, root or the disk group).

What CI runs on every package, on a runner of its OS (Ubuntu 26.04, Windows Server 2025, macOS 15 on Apple silicon and Intel):

  • Image file: open a qcow2 test image, list its partitions, mount ext4 and hash a file.
  • Drive enumeration: list the runner's own disks through "Open system drive…" (listing only; the runner's disks are never opened).
  • Virtual block device I/O: the job attaches a test image as a read-only disk of its own (Linux loop and nbd, a Windows VHDX, a macOS disk image) and reads it as a device: the native backend, clicking it in "Open system drive…", and the CLI tools (anyfs-lspart, anyfs-ksmbd, anyfs-nfsd), plus a run without access to the device that must be refused. The image is checked to be unchanged afterwards. Files served by anyfs-nfsd are read back on Linux and macOS only: Windows has no NFSv4 client.
  • Physical disks: real external drives are not tested.

Build and packaging details: ts/examples/electron-demo/README.md.

Features

  • Mount and read ext4, btrfs, xfs, f2fs, FAT, NTFS, etc. without root
  • Multiple I/O backends:
    • raw — direct pread(), fastest (~1.3 GB/s)
    • gio — GLib GIO GInputStream (~1.1 GB/s)
    • qemu — QEMU block layer for qcow2/vmdk/vdi/vhd (~0.8 GB/s)
  • Userspace SMB3 (anyfs-ksmbd) and NFSv4 (anyfs-nfsd) servers — a host-side TCP splice routes traffic into the in-LKL servers without libslirp on the data path
  • FUSE frontend (anyfs-fuse) on Linux; WinFSP frontend (anyfs-winfsp) on Windows
  • Minimal C API: 4 functions for kernel/disk management, then use LKL syscalls directly

API

#include "anyfs.h"
#include <lkl.h>
#include <lkl/linux/stat.h>

// 1. Start kernel
anyfs_kernel_init(NULL);  // or pass AnyfsKernelOpts

// 2. Add disk (auto-selects backend, or specify ANYFS_BACKEND_QEMU etc.)
int disk_id = anyfs_disk_add("disk.qcow2", ANYFS_DISK_READONLY);

// 3. Mount partition 1 — anyfs_mount picks an LKL mount point under /lklmnt/
AnyfsMount m;
anyfs_mount(disk_id, 1, "ext4", LKL_MS_RDONLY, NULL, &m);

// 4. Use LKL syscalls — full Linux VFS at your disposal
char path[256];
snprintf(path, sizeof path, "%s/etc/passwd", m.mount_point);
long fd = lkl_sys_open(path, LKL_O_RDONLY, 0);
lkl_sys_read(fd, buf, sizeof(buf));
lkl_sys_close(fd);

struct lkl_stat st;
lkl_sys_lstat(path, &st);

struct lkl_dir *dir = lkl_opendir(m.mount_point, &err);
// ...

// 5. Cleanup
anyfs_umount(m.mount_point);
anyfs_disk_remove(disk_id);
anyfs_kernel_halt();

Building

Prerequisites

  • Linux (x86_64)
  • Meson ≥ 0.60, Ninja
  • Pre-built LKL (liblkl.a) from linux/tools/lkl/
  • Optional: static GLib/GIO for GIO backend
  • Optional: static QEMU block libs for QEMU backend

Build Configurations

# Minimal (raw backend only)
meson setup builddir -Dlkl_root=$HOME/linux/tools/lkl

# Full (raw + GIO + QEMU)
meson setup builddir --default-library=static \
    -Dlkl_root=$HOME/linux/tools/lkl \
    -Dglib_root=$HOME/glib -Denable_gio=true \
    -Denable_qemu=true \
    -Dqemu_root=$HOME/qemu \
    -Dqemu_build=$HOME/qemu/build-anyfs2

ninja -C builddir

Benchmarks

Reading ~150 MB of files from a 256 MB ext4 image:

Backend Raw image qcow2
raw (pread) 1295 MB/s —
gio 1071 MB/s —
qemu 722 MB/s 818 MB/s

Run yourself: ./builddir/bench_backends <image> <fstype> [part]

File Servers

anyfs-reader includes two userspace file servers that expose disk-image partitions over the network using LKL's in-tree ksmbd and nfsd subsystems. No root, no kernel modules; a host-side TCP splice (src/host_proxy/) routes client traffic into the in-LKL listener — libslirp is not on the data path.

Server Protocol Host port (default) Build option
anyfs-ksmbd SMB3 (CIFS) 4455 -Denable_ksmbd=true
anyfs-nfsd NFSv4 20049 (same flag)
# Build the servers
meson setup builddir-ksmbd -Dlkl_root=$HOME/linux/tools/lkl \
    -Denable_ksmbd=true -Dksmbd_tools_root=$HOME/ksmbd-tools
ninja -C builddir-ksmbd anyfs-ksmbd anyfs-nfsd

# Discover partition paths first
./builddir-ksmbd/src/lspart/anyfs-lspart disk.img

# SMB3 server
./builddir-ksmbd/anyfs-ksmbd disk.img --share data=disk0/p1
smbclient //localhost/data -U guest%guest --port=4455

# NFSv4 server
./builddir-ksmbd/anyfs-nfsd -w disk.img --share data=disk0/p1
mount -t nfs4 localhost:/data /mnt -o port=20049,vers=4

See docs/lkl-servers.md for kernel config, the --share DSL, NFSv4 implementation details, and pynfs results.

Browser / Node packages

The ts/ workspace ships the same anyfs stack as a wasm bundle plus thin JS wrappers, so disk images can be inspected entirely client-side:

Package Role
@anyfs/core wasm kernel (LKL + QEMU block layer) + JS bindings; runs in a Web Worker
@anyfs/react React 18/19 hooks (useDir, useFile) over @anyfs/core
@anyfs/trees <AnyfsFileBrowser> — Chonky-based file UI
@anyfs/native Node N-API addon, links the native libs instead of wasm (Linux, Windows, macOS)

A live build of the browser demo (ts/examples/vite-demo) is hosted at https://anyfs.kosaka.moe — drop a disk image onto the page or paste an HTTP URL and the kernel boots in-browser. The desktop app (ts/examples/electron-demo) wraps the same interface in Electron.

cd ts
pnpm install
pnpm -r --filter './packages/*' build
pnpm -F vite-demo dev    # http://localhost:5173

See docs/ts-packages.md for the full layout, build recipes, and the wasm-specific gotchas.

Project Structure

include/anyfs.h              — Public API (4 functions + a few mount helpers)
include/anyfs_disk.h         — Multi-partition session layer
src/core/anyfs.c             — Kernel init + disk management
src/core/anyfs_disk.c        — Partition session + container recursion
src/core/raw_blk_backend.c   — pread-based block backend
src/core/gio_blk_backend.c   — GIO synchronous backend
src/core/qemu_blk_backend.c  — QEMU block backend bridge
src/host_proxy/              — Host-side TCP splice (used by ksmbd/nfsd)
src/ksmbd/lkl_ksmbd.c        — SMB3 server (LKL + ksmbd-tools)
src/nfsd/lkl_nfsd.c          — NFSv4 server (LKL nfsd + mini mountd)
src/fuse/anyfs_fuse.c        — FUSE3 frontend (Linux) and WinFSP frontend (Windows)
src/lspart/anyfs_lspart.c    — Partition lister
src/bench/                   — Benchmark / diagnostic utilities
tests/                       — Regression tests
docs/                        — Architecture, distribution, server docs
scripts/                     — gen_lkl_config / build_lkl / build_qemu / build_anyfs / package_*

Documentation

See docs/README.md for the full documentation index.

License

GPL-2.0 — see LICENSE.

Releases

Packages

Contributors

Languages