Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

poormanfs

CI

UNDER HEAVY DEVELOPMENT

This is an experiment to see whether we can use LLMs to engineer a decently complex project, with widely available public information, and ensure utmost quality of the result.

A distributed filesystem that just works, written in Zig.

This filesystem's aims are:

  • Easy to set up and minimal operational overhead - Not everyone can afford maintaining a filesystem cluster full time
  • Work with a mix of various hardware (HDD, SSD, NVMe, consumer-grade, server-grade, TCP, RDMA) - Not everybody can purchase the latest or uniform hardware

To ensure the quality of the project, we use:

  • Unit tests with high coverage (~90%+, 332+ test blocks across 50 files), including end-to-end multi-server replication, EC pipeline, multi-master Raft, client-side encryption, dedup, S3 gateway, native C ABI round-trip, peer cache transfer, NFSv3/SMB2/protobuf/gRPC/CSI wire-format round-trips, persistent block-device + bitmap allocator, and architectural-invariant tests (J1/J2)
  • Fuzz testing via Zig's built-in std.testing.fuzz (protocol parsing, needle format, checksums)
  • Deterministic Simulation Testing framework (planned - think FoundationDB's simulation layer, or Antithesis)
  • Property-based testing embedded in fuzz tests (serialize/deserialize round-trips, checksum integrity)
  • Integration tests with real TCP loopback (master server RPC, volume server I/O)
  • CI pipeline with lint, test, and release automation (GitHub Actions)
  • Chaos and fault injection testing (planned - network partitions, disk failures, corrupt data)
  • Performance benchmarking and regression tracking (planned)

Project Structure

  • base/: A collection of smaller libraries. Contains building blocks of the filesystem
  • sim/: A simulation library, used for deterministic simulated testing of the filesystem
  • fs/: Actual filesystem code. Mostly combining components from base libraries

Usage

# You will need at least 3 master nodes
poormanfs master --bootstrap 10.1.1.24:9005,10.1.1.25:9005,10.1.1.26:9005

# And you need some volume nodes
poormanfs volume /local/disk1,/local/disk2 --bootstrap 10.1.1.24:9005,10.1.1.25:9005,10.1.1.26:9005

# And then you can mount it
poormanfs mount 10.1.1.24:9005,10.1.1.25:9005,10.1.1.26:9005 /mnt/poor

Feature Implementation Status

See docs/FEATURES.md for the full feature list with descriptions.

Done

Organised by category. "Partial" entries have a working core but known gaps; "Done" entries have tests that exercise the feature end-to-end.

A. Placement & distribution

Feature Status Notes
A1 - Algorithmic placement Basic Hash-based volume selection via master
A2 - Placement groups Done PoolManager + Pool in fs/master/placement_group.zig; objects hash into PGs, each PG backed by a replica group
A3 - Topology-aware placement Done spread_rack / spread_datacenter policies with fallback
A4 - Volume/Haystack storage Done Needle format with superblock, append-only

B. Metadata

Feature Status Notes
B1 - Pluggable metadata engine Done MetaEngine vtable in fs/master/meta_engine.zig with in-memory + file-backed WAL implementations, shared conformance test
B2 - Distributed metadata sharding Base library base/meta_shard.zig: hash-based shard router + dynamic subtree pinning (CephFS-style); deeper pins override shallower ones
B3 - Metadata embedded in file ID Done volume_id + needle_id routing
B4 - Separate metadata/data planes Done Master handles namespace, volumes handle data

C. Data organisation

Feature Status Notes
C1 - Three-level data org (chunk→slice→block) Done fs/mount/chunkslice.zig: slices overlay within a chunk, compaction collapses them
C2 - File sharding/striping Done 64 MiB chunk-based sharding
C3 - Small file optimization Done Single-chunk for files < 64 MiB

D. Replication & erasure coding

Feature Status Notes
D1 - Synchronous replication Done Replica groups via shared volume_id, client-coordinated fan-out
D2 - Erasure coding (Reed-Solomon) Done GF(2^8) + Vandermonde encoder + end-to-end client pipeline in fs/mount/ec.zig
D3 - Locally Recoverable Codes Done XOR local parity + global RS parity (base/lrc.zig)
D4 - Quorum-based writes Done Configurable write_quorum; default = majority
Read failover Done LookupResponse.extras carries every replica member

E. Caching

Feature Status Notes
E1 - Client-side block cache Done LRU block cache keyed by needle id (fs/mount/cache.zig)
E2 - Distributed / peer cache Base library base/peer_cache.zig: content-addressed LocalPeerCache + PeerCacheIndex (advertise/lookup/revoke) + query/response wire codec; in-process round-trip test where peer B fetches a block from peer A
E3 - Multi-layer cache stack Done TieredCache in fs/mount/tieredcache.zig: L1 in front of L2 with promote/demote
E4 - Read-ahead and write-behind Done SequentialDetector + WriteBehindBuffer in fs/mount/readahead.zig

F. Data reduction

Feature Status Notes
F1 - Inline compression Done Per-chunk deflate wired into mount client
F2 - Deduplication Done SHA-256 content-addressed block store in fs/mount/dedup.zig, identical writes collapse to one needle
F3 - Similarity-based reduction Base library base/simhash.zig (locality-sensitive 64-bit SimHash + bucketed SimilarityIndex) + base/delta.zig (XOR-RLE delta encoder; mostly-identical 4 KiB blocks compress to <25% of the original)

G. Fault tolerance

Feature Status Notes
G1 - Self-healing scrub Done Background needle verification (fs/volume/scrub.zig)
G2 - Automatic rebalancing Done Utilization-based migration planner (fs/master/rebalance.zig)
G3 - Checksumming Done End-to-end CRC32C (client, volume, disk)

H. Storage backend

Feature Status Notes
H1 - Object-storage backend interface Done BlobStore vtable in fs/volume/blob_store.zig + in-memory and local-fs implementations
H2 - Direct-to-block-device backend Base library base/block_device.zig: raw BlockDevice (file-backed in tests, /dev/sdX-ready in prod) + bitmap BlockAllocator + FormattedDevice with persistent superblock+bitmap that survives reopen
H3 - Tiered storage (hot/warm/cold) Done Tier enum on VolumeInfo, tier-aware assign

I. Access protocols

Feature Status Notes
I1 - FUSE client Done High-level API, basic POSIX ops
I2 - NFSv3 + SMB2 wire formats Base library base/nfs.zig: XDR codec + RPC record marker + Fattr3 + LOOKUP/READ/WRITE procedure structs. base/smb.zig: NetBIOS framing + 64-byte SMB2 sync header + NEGOTIATE/READ/WRITE bodies; full-stack round-trip test (NetBIOS → SMB2 header → READ body)
I3 - S3-compatible gateway Done fs/mount/s3_gateway.zig — bucket/object → fs path translation with put/get/delete/list
I4 - Native library (C ABI) Done fs/mount/libpoormanfs.zig exports poormanfs_open/create/write/read_full/delete/close
I5 - Kubernetes CSI driver Base library base/protobuf.zig (wire format encoder/decoder), base/grpc.zig (5-byte envelope + HTTP/2 frame parser), base/csi.zig (Identity/Controller/Node message types, service dispatch table, full encode→envelope→dispatch→decode round-trip test)

J. Cluster architecture

Feature Status Notes
J1 - Disaggregated compute and storage Done Master + volume are independent processes; J1 test confirms volume still serves reads after master dies
J2 - Shared-everything Done Any master in a Raft cluster can serve namespace reads; J2 test confirms all followers see replicated writes
J3 - Raft consensus Done Multi-master leader election + log replication of namespace mutations
J4 - Single binary Done poormanfs master|volume|mount

K. Advanced features

Feature Status Notes
K1 - Snapshots and clones Done Namespace.takeSnapshot / restoreFromSnapshot
K2 - Client-side encryption Done AES-256-GCM per-chunk envelope, opt-in via FuseClient.encryption_key
K3 - Geo-replication Done Async Raft log shipping in fs/master/geo_replication.zig via LogShipper with source/sink vtables
K4 - Background compaction/GC Done Tombstone reclamation via volume rewrite
K5 - Stackable translator pipeline Done fs/mount/pipeline.zig — composable compress/encrypt/checksum stages that stack in either order

Status taxonomy

The "Status" column distinguishes three levels of completeness:

  • Done — the feature is wired into the running filesystem (either the default code path or as an opt-in path) and has end-to-end tests against a real master + volume cluster.
  • Base library — the algorithms and wire formats live in base/ (or fs/master/) with comprehensive unit tests, but the surrounding filesystem still uses the simpler default path. A real deployment would plug these in via a small integration layer; the tests prove the primitives are correct in isolation.
  • Basic — partial implementation noted alongside the row.

Coverage

Every feature from docs/FEATURES.md now has either a Done (wired into the filesystem) or Base library (algorithms + wire formats tested in base/) implementation. Nothing is missing.

About

Experimental fs

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages