Skip to main content

Crate fsys

Crate fsys 

Source
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 needMethod::Auto
Need universal correctness floorMethod::Sync
Want Linux’s fdatasync speedupMethod::Data
Have read-heavy random-access workloadsMethod::Mmap
Need < 100 µs single-write latency on NVMeMethod::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

FeatureDefaultPurpose
asyncoff_async siblings for every sync method; pulls in tokio
tracingoffStructured spans + events on the write / read / journal hot paths
stressoffRun tests/stress.rs for the full 1-hour soak (CI-nightly only)
fuzzoffCompile-only flag for fuzz-target wiring; targets live in fuzz/

§Concept reference

ConceptType / moduleReach for it when…
Handle to filesystemHandleAny non-one-shot IO. The primary type.
Configure handleBuilderCustom root, method, tuning, observer.
Durability strategyMethodFive variants: Sync, Data, Mmap, Direct, Auto.
Append-only WALJournalHandleHigh-throughput durable writes (WAL / ledger / queue).
Multi-op transactionBatchGroup N writes / deletes / copies under one durability barrier.
One-shot helpersquickSingle-call file IO without holding a handle.
Async layerfsys::async_io (feature async)Tokio integration; _async siblings for every sync method.
Telemetry hookobserver::FsysObserverPer-op events (append / sync / write / read).
Hardware introspectionhardwareProbe PLP status, atomic-write unit, sector size.
ErrorsError / Result21 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 Batch builder for the group lane.
builder
Builder for constructing a configured Handle.
capability
System capability detection and on-disk cache (1.1.0).
crud
CRUD operations on files and directories.
error
Error type for the fsys crate.
handle
The Handle struct — 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.

Functions§

builder
Returns a new Builder with default settings.
new
Creates a default Handle using Method::Auto and no root scope.
with
Creates a Handle using the specified Method.