Files
rustfs/docs/architecture
Zhengchao An 9b197fc1c2 docs(architecture): correct erasure-coding spec statements that contradict main (#5012)
The normative erasure-coding spec stated several target behaviors and known baseline defects as active invariants, and cited two symbols that do not exist on main. Each correction below was verified against the code.

- §4.1 shard size: legacy even-padding is RustFS-legacy-only and is NOT MinIO's sizing. MinIO (and the modern GF(2⁸) path) use plain div_ceil; for 1 MiB / 6 data shards that is 174763 bytes versus the legacy even-padded 174764. MinIO-migrated data is decoded by the modern path, so the legacy formula never applies to it.
- §6.3 / §11 MTime: the MTime key is always written (a None mod_time encodes as UNIX_EPOCH = 0), not omitted. Round-trip safety to None is enforced on the decode side, not by write omission. Only the legacy StatInfo.ModTime field is omitted-when-None.
- §7 commit: rollback after a missed write quorum is best-effort — undo failures are counted and warn!-logged, never propagated or retried — so a partially-failed rollback can leave shards behind; softened "never left partially committed" accordingly.
- §7 data_dir: reduce_common_data_dir votes over each disk's old_data_dir (a GC input for reclaiming the superseded dir), not the newly committed data_dir.
- §7 convergence: classify_rename_convergence is consumed only by the multipart-complete path (convergence.needs_heal()); the regular put_object path discards it.
- §7 write layout: removed the WriteLayout / resolve_write_layout citation — neither symbol exists on main (the write layout is computed inline), which violated the spec's own cite-real-symbols rule.
- §6.6 inline: inline presence is read from the meta_sys[inline-data] body marker alone; the header InlineData flag is written but not consulted on read, and disagreement is tolerated (MinIO may write the flag unset with inline data present). Removed the false "must agree" invariant.
- §11 UUID tolerance: version_id / data_dir (ID/DDir) decode as a fixed 16-byte Uuid::from_bytes and fail closed on a present-but-non-16-byte value; only transitioned-versionID uses the tolerant Uuid::from_slice(...).ok().filter(!nil). Split the previously-conflated bullet.
- §11 decode blanket: narrowed "everything else must degrade to a tolerant default" to enumerate the legitimate structural/geometry/version/length fail-closed guards (header array length, unknown header_ver, version > max, versions_len / bin_len bounds, non-16-byte ID/DDir).
- §8 / §13 codec guard: has_valid_dimensions() is a &self method, so it runs after construction and reliably covers only block_size == 0; a data_blocks == 0 geometry with parity > 0 panics in the .expect constructor before the guard runs. Noted the fallible-constructor fix.

Refuted and intentionally left unchanged: the "accepts container major == 1 with any minor" statement is correct — the reader compares only major (rejects major > 1) and never gates on minor, so minor 4 is accepted.
2026-07-18 21:05:22 +08:00
..

Architecture Documentation

Durable architecture reference for RustFS: migration guardrails, runtime contracts, boundary rules, and support matrices.

Two rules keep this directory healthy:

  1. Durable reference only. One-shot implementation plans, task trackers, and PR templates do not belong in the repository — keep them in the issue tracker or your local worktree. When their work closes, delete them rather than archiving them here.
  2. No copies of other sources of truth. Crate lists come from Cargo.toml, CI steps from .github/workflows/ci.yml, code structure from the code. scripts/check_doc_paths.sh fails the pre-commit gate when a doc here references a file path that no longer exists.

Start here

  • overview.md — migration baseline, phase order, core principles

CI-enforced core (required by scripts/check_architecture_migration_rules.sh)

Contracts & invariants

Support matrices (release-facing, keep current)

Inventories & baselines (snapshots that feed migration work)

Historical plans and trackers (rebalance/decommission phases, migration-progress ledger, and the one-shot migration snapshots that fed it — startup timeline, scheduler baseline, profiling/NUMA capability inventory, KMS development defaults inventory) were retired in 2026-07 once the architecture-review ledger they served closed out (backlog#660/#665). Planning documents are no longer kept in the repository.