POSIX correctness,
measured performance.
BrewFS treats filesystem behavior and performance as separate release gates. This page records the current reproducible methods and published validation coverage; results apply to the documented configuration, not every deployment.
Test the filesystem contract, not only happy paths.
The PR completes metadata semantics across SQLite, PostgreSQL, Redis, etcd, and TiKV. Compose runners test FUSE behavior against RustFS-backed object storage and retain artifacts for every run.
Namespace and metadata
Create, unlink, rename, hard links, timestamps, xattrs, special inodes, and setgid inheritance are checked through full POSIX suites.
Concurrency semantics
Byte-range locks, lookup/stat paths, close-to-open behavior, and writeback-sensitive paths are exercised across transactional metadata backends.
Cross-backend evidence
Configured xfstests and LTP profiles run with SQLite, Redis, etcd, and TiKV, each paired with RustFS object storage.
Current correctness coverage
| Suite | What it covers | Recorded result |
|---|---|---|
| xfstests | FUSE, metadata, locking, writeback and object-store behavior | 708 / 708 configured cases on SQLite, Redis, etcd and TiKV |
| pjdfstest | POSIX paths, permissions, links, special nodes, rename, unlink and timestamps | 246 files / 9,134 assertions on Redis and TiKV |
| LTP filesystem | Linux filesystem scenarios and record-lock coverage | Passed on all four backends; buffered iogen01 remains documented skip |
| stress-ng smoke | Short metadata and small-write stress | Passed with no residual files |
cargo test --workspace --lib --bins -- --test-threads=1
bash docker/compose-xfstests/run_redis_pjdfstest.sh
bash docker/compose-xfstests/run_redis_xfstests.sh
bash docker/compose-xfstests/run_redis_ltp.sh
bash docker/compose-xfstests/run_redis_stress_ng.sh --profile smokeKnown, explicit limits
- generic/075 stays excluded: buffered FUSE mmap after truncate/extend can expose stale page-cache bytes. Direct I/O cannot run that mmap shape.
- LTP iogen01 stays skipped in the normal buffered profile because a split-write/page-cache coherency race remains; it is kept as a diagnostic, not hidden.
- open_by_handle_at, shared mount propagation, selected O_DIRECT sparse-hole cases, and long fsstress soaks remain explicitly classified in the test matrix.
Profiles are part of the result.
The compared Redis + RustFS snapshot uses the same host, 4 MiB fio blocks, buffered fio, compression disabled, and matching writeback-throughput profiles. Writes are reported both as foreground acceptance and after the writeback queue is fully drained.
Published profile snapshot: BrewFS / JuiceFS
| Workload | BrewFS | JuiceFS | Ratio |
|---|---|---|---|
| Matched rows led | 15 of 24 | Baseline | 10/14 data · 5/10 meta |
| Mixed I/O (fully drained) | 218.60 MiB/s | 113.86 MiB/s | 1.92x |
| Foreground mixed I/O | 495.54 MiB/s | 328.76 MiB/s | 1.51x |
| Random read | 1,726.10 MiB/s | 1,256.80 MiB/s | 1.37x |
| Readdir | 28,634.94 ops/s | 16,020.25 ops/s | 1.79x |
PERF_LOG_TO_CONSOLE=false PERF_FIO_SIZE=512m PERF_FIO_RUNTIME=20 \
bash docker/compose-xfstests/run_redis_perf.sh --s3 --writeback-throughput-profile
JUICEFS_META_BACKEND=redis PERF_LOG_TO_CONSOLE=false \
PERF_FIO_SIZE=512m PERF_FIO_RUNTIME=20 \
bash docker/compose-xfstests/run_juicefs_perf.sh --writeback-throughput-profileRules for a credible performance claim
- Run the target workload at least three times and report the median; keep non-target fio and metadata regressions within 5%.
- Do not attribute a warm-cache result to Rust alone. Cache warmth, FUSE profile, metadata round trips, and dirty-overlay behavior are measured variables.
- Mark commit-before-upload, direct-I/O read handles, or write-open caching as opt-in profiles, not default behavior.
- Re-run xfstests, pjdfstest, LTP filesystem, and stress-ng whenever a hot-path optimization changes filesystem behavior.