Expand description
§fsys
Foundation-tier filesystem IO for Rust storage engines: journal substrate, io_uring, NVMe passthrough, atomic writes, cross-platform durability.
fsys sits one layer below your data structures and one layer above
std::fs. It pairs an explicit durability model (you choose a
Method, you get the platform’s best matching primitive, you
observe any fallback via Handle::active_durability_primitive)
with a journal substrate built for write-ahead-log workloads.
§Quickstart
Append-only journal — the canonical WAL pattern:
use std::sync::Arc;
let fs = Arc::new(fsys::builder().build()?);
let log = fs.journal("/var/lib/myapp/log.wal")?;
let _ = log.append(b"txn 1: insert")?;
let _ = log.append(b"txn 2: update")?;
let lsn = log.append(b"txn 3: commit")?;
// One fsync covers every prior append — group-commit.
log.sync_through(lsn)?;One-shot durable file write, no handle required:
fsys::quick::write("/etc/myapp/config.toml", b"value = 42")?;
let data = fsys::quick::read("/etc/myapp/config.toml")?;§Three tiers of API
§Tier 1 — one-shot helpers
For programs that issue one IO op and don’t need a long-lived handle.
Backed by a lazily-initialised default Handle with
Method::Auto.
fsys::quick::write("/tmp/greeting.txt", b"hello")?;
let data = fsys::quick::read("/tmp/greeting.txt")?;
assert_eq!(data, b"hello");§Tier 2 — handle-based
The primary API for everything beyond one-shot use. Build a Handle
with new() (default Method::Auto) or with(method);
share across threads via Arc.
let fs = fsys::new()?; // Method::Auto
let fs = fsys::with(fsys::Method::Data)?; // explicit method
fs.write("/tmp/world.txt", b"world")?;
let read = fs.read("/tmp/world.txt")?;§Tier 3 — full builder
For advanced configuration: custom root, dev/prod mode, per-handle batch knobs, io_uring queue depth, buffer pool size, observer hook, workload presets.
let fs = fsys::builder()
.method(fsys::Method::Direct)
.root("/var/lib/myapp")
.mode(fsys::Mode::Prod)
.tune_for(fsys::Workload::Database)
.build()?;§Choosing a method
| If you… | Pick |
|---|---|
| Don’t know what you need | Method::Auto |
| Need universal correctness floor | Method::Sync |
Want Linux’s fdatasync speedup | Method::Data |
| Have read-heavy random-access workloads | Method::Mmap |
| Need < 100 µs single-write latency on NVMe | Method::Direct |
See docs/METHODS.md
for the full per-platform matrix and the Method::Auto decision ladder.
§Crash safety
Every write API (write, write_copy, write_batch,
Batch::commit) uses an atomic temp-file + rename pattern. The target
file is either entirely the old payload (kill before rename) or
entirely the new payload (kill after rename) — never torn.
The journal substrate adds explicit durability via
JournalHandle::sync_through; group-commit amortises the fsync
cost across many appends. See
docs/CRASH-SAFETY.md
for the full per-method contract.
§Async (feature async)
let fs = std::sync::Arc::new(fsys::builder().build()?);
fs.clone().write_async("/tmp/async.dat", b"payload".to_vec()).await?;
let data = fs.clone().read_async("/tmp/async.dat").await?;On Linux + Method::Direct, async ops submit directly to the
per-handle io_uring ring — the native substrate, observable via
Handle::async_substrate returning AsyncSubstrate::NativeIoUring.
Everywhere else, async ops route through tokio::task::spawn_blocking
(AsyncSubstrate::SpawnBlocking).
Calling sync fs.write() from inside a tokio runtime is supported
(it just blocks the calling thread). Calling async fs.write_async()
outside a tokio runtime returns Error::AsyncRuntimeRequired
rather than panicking.
§Cargo features
| Feature | Default | Purpose |
|---|---|---|
async | off | _async siblings for every sync method; pulls in tokio |
tracing | off | Structured spans + events on the write / read / journal hot paths |
stress | off | Run tests/stress.rs for the full 1-hour soak (CI-nightly only) |
fuzz | off | Compile-only flag for fuzz-target wiring; targets live in fuzz/ |
§Concept reference
| Concept | Type / module | Reach for it when… |
|---|---|---|
| Handle to filesystem | Handle | Any non-one-shot IO. The primary type. |
| Configure handle | Builder | Custom root, method, tuning, observer. |
| Durability strategy | Method | Five variants: Sync, Data, Mmap, Direct, Auto. |
| Append-only WAL | JournalHandle | High-throughput durable writes (WAL / ledger / queue). |
| Multi-op transaction | Batch | Group N writes / deletes / copies under one durability barrier. |
| One-shot helpers | quick | Single-call file IO without holding a handle. |
| Async layer | fsys::async_io (feature async) | Tokio integration; _async siblings for every sync method. |
| Telemetry hook | observer::FsysObserver | Per-op events (append / sync / write / read). |
| Hardware introspection | hardware | Probe PLP status, atomic-write unit, sector size. |
| Errors | Error / Result | 21 variants with stable FS-XXXXX codes. |
§Version history
Per-version deltas live in
CHANGELOG.md.
1.0.0 is the first stable release; the 1.x line is API-stable
and on-disk-format-stable per the contract in
docs/STABILITY-1.0.md.
Re-exports§
pub use crate::advice::Advice;pub use crate::batch::Batch;pub use crate::builder::Builder;pub use crate::builder::SpdkConfig;pub use crate::builder::Workload;pub use crate::capability::Capabilities;pub use crate::capability::HardwareSummary;pub use crate::capability::IoUringFeature;pub use crate::capability::PciAddress;pub use crate::capability::SpdkEligibility;pub use crate::capability::SpdkSkipReason;pub use crate::error::BatchError;pub use crate::error::Error;pub use crate::error::Result;pub use crate::handle::Handle;pub use crate::journal::JournalBackend;pub use crate::journal::JournalBackendHealth;pub use crate::journal::JournalBackendInfo;pub use crate::journal::JournalBackendKind;pub use crate::journal::JournalHandle;pub use crate::journal::JournalOptions;pub use crate::journal::JournalReader;pub use crate::journal::JournalRecord;pub use crate::journal::JournalTailState;pub use crate::journal::Lsn;pub use crate::journal::SyncMode;pub use crate::journal::WriteLifetimeHint;pub use crate::meta::DirEntry;pub use crate::meta::FileMeta;pub use crate::meta::Permissions;pub use crate::method::Method;pub use crate::path::Mode;pub use crate::substrate::AsyncSubstrate;
Modules§
- advice
- Access-pattern hints for the kernel page cache.
- async_
io - Async wrappers for fsys’s sync IO core.
- batch
- Public
Batchbuilder for the group lane. - builder
Builderfor constructing a configuredHandle.- capability
- System capability detection and on-disk cache (1.1.0).
- crud
- CRUD operations on files and directories.
- error
- Error type for the
fsyscrate. - handle
- The
Handlestruct — the primary entry point for file IO operations. - hardware
- Hardware probing.
- journal
- Write-ahead-log / journal substrate (0.8.0).
- meta
- File and directory metadata types.
- method
- Durability strategy enum and automatic hardware-aware selection.
- observer
FsysObserver— opt-in structured telemetry for fsys hot paths.- os
- Operating-system detection and metadata.
- path
- Per-OS default paths plus formatting and sanitisation helpers.
- primitive
- Canonical names for the durability primitives that fsys actually
invokes under the hood, returned by
crate::Handle::active_durability_primitive. - quick
- Convenience free functions for one-shot file IO.
- substrate
AsyncSubstrate— which runtime substrate the async layer uses.
Constants§
- VERSION
- Library version, matching the crate version declared in
Cargo.toml.