Provider / local S3-compatible service

Validated

RustFS

RustFS is the reproducible local/CI S3-compatible service used to exercise the object block path without confusing a local service with Cloudflare R2 or AWS S3 acceptance.

Metadata

RustFS stores no mount-rs namespace metadata. Pair its S3 gateway with an independent metadata provider such as SQLite, PGlite, TiDB, or FoundationDB through ChunkedFs.

Immutable blocks

The block adapter uses an owned S3 bucket/prefix and immutable object creates. Objects are addressed by the generated block ID below that prefix; the service does not reinterpret their contents.

Storage anatomy

Follow one file through both planes.

A mount-rs namespace stores names, attributes, directory entries, layouts, and block references. The bytes stay in the independent block plane. The example below is illustrative; the provider-specific schema, keys, and prefixes are the inspectable contract.

Logical file/docs/readme.mdinode 42 · size 8,192NodeMetadata → NodeData::File(FileLayout)
blocksbucket objects under an owned prefixBlockId → raw bytes
Illustrative Namespace / FileLayout record (shape, not serialized bytes)
Namespace {
  nodes[42] = NodeMetadata {
    stats: { ino: 42, size: 8192, mode: regular },
    data: File(FileLayout {
      chunker: { algorithm: "fixed-size", version: 1, chunk_size: 4096 },
      extents: [
        { file_offset: 0,    block: "b012...", block_offset: 0, length: 4096 },
        { file_offset: 4096, block: "bfed...", block_offset: 0, length: 4096 }
      ]
    })
  }
}

BlockId "b012..." -> [4 KiB raw bytes]
BlockId "bfed..."  -> [4 KiB raw bytes]

Object storage

RustFS S3 gateway prefix map

block-only bucket

RustFS exposes the same S3 object shape as the R2 block adapter. Its service boundary is local/CI evidence, not a claim about every S3-compatible deployment.

Bucketmount-rs
mount-rs/
└─mount-rs-tests/owned-run/
├─b0123456789abcdef0123456789abcdef
└─bfedcba9876543210fedcba987654321
selected relational/KV provider

Stores the namespace and the references that make each object part of a file.

blocksbucket objects under an owned prefix

Stores only raw bytes at exact keys. LIST shows a prefix; it does not reveal a directory tree.

mount-rs-tests/test namespace

bucket prefix; no directory object is required

mount-rs-tests/owned-run/cleanup boundary

LIST prefix for one harness-owned run

mount-rs-tests/owned-run/b0123456789abcdef0123456789abcdefblock object

raw block bytes

mount-rs-tests/owned-run/bfedcba9876543210fedcba987654321block object

raw block bytes

What the key does not tell you

Use S3 LIST/HEAD/GET/RANGE to inspect these objects. The namespace and the block references remain in the separately selected metadata provider. The file name, inode, offsets, and chunk layout are not encoded in the object key; inspect the metadata plane to map them.

Validated — scoped evidence

Pinned service contract, restart, CAS, range, hosted RustFS checks, and real FoundationDB/TiDB composition checkpoints passed; bounded TiDB/RustFS Node and CLI configuration gates are wired, while replicated topology and credential-gated live consumer coverage remain open. The bounded current-tree harness passed immutable block writes/reopens, SQLite and PGlite metadata compositions, N-API factories, remote CLI HTTP reopen, SQLite VFS over RustFS blocks, fault recovery, service restart/reopen, and the RustFS benchmark. FoundationDB and TiDB mixed provider runs also passed, with TiDB limited to single-node v8.5.7. The bounded consumer slice now wires TiDB metadata with RustFS/S3-compatibler2 blocks through the public Rust SDK, N-API, and both CLIs, covering configuration, partial write, truncate, shutdown/reopen, and owned-prefix cleanup. Its local matrix records Nodepass=4 skip=3 fail=0 and CLIpass=10 skip=3 fail=0; live mixed-store rows remain credential-gated. The maturity label is scoped to these service paths, not every S3-compatible server or a replicated production topology.

Layout and chunking

The same fixed-size chunker and metadata references used by R2 apply to RustFS. Use the service's S3 API to observe object keys, HEAD metadata, full bytes, and range reads.

Durability and consistency

The pinned harness exercises conditional writes, CAS publication, concurrent access, ranges, fresh reads, restart, and cleanup. Service replication, disk policy, authentication, and failure durability are deployment properties rather than promises of the adapter.

Across every split-store composition, new blocks are flushed before metadata references are published. A provider acknowledgement is not automatically a power-loss or distributed-locking guarantee.

Use the S3 API against the loopback gateway

Read-only inspection example
export S3_ENDPOINT='http://127.0.0.1:<port>'
export S3_BUCKET='mount-rs'
export S3_PREFIX='mount-rs-tests/owned-run'

aws s3api list-objects-v2 --endpoint-url "$S3_ENDPOINT"   --bucket "$S3_BUCKET" --prefix "$S3_PREFIX/"
aws s3api head-object --endpoint-url "$S3_ENDPOINT"   --bucket "$S3_BUCKET" --key "$S3_PREFIX/<block-id>"
aws s3api get-object --endpoint-url "$S3_ENDPOINT"   --bucket "$S3_BUCKET" --key "$S3_PREFIX/<block-id>"   --range bytes=0-63 /tmp/block-prefix.bin

Credentials, cleanup, and safe operations

Use the harness-owned container, bucket, and prefix only. Keep any S3 credentials in the test environment, stop the service before removing its data directory, and do not use RustFS results as evidence for a different remote provider.

Current limits

The all-in-one local deployment is not production authentication or replicated-durability evidence. TiDB/FoundationDB composition passed bounded single-node checkpoints, while replicated topology, provider restart promotion, broader CLI/Node coverage, and release qualification remain tracked separately. The TiDB/RustFS consumer rows require MOUNT_RS_TIDB_URL and loopback RustFS credentials; without them, those rows remain explicit skips.

← Back to providers