Repository navigation
Releases
TimeFS v0.1.0
Installing the prebuilt binary
timefs-v0.1.0-x86_64-linux.tar.gzis built on Ubuntu and linkslibfuse3.so.3
(libfuse 3.x before 3.18: Ubuntu, Debian, Fedora and most current distributions).- Distributions shipping libfuse 3.18+ (
libfuse3.so.4, for example Arch Linux) should
build from source:cargo build --release(needslibfuse3headers andpkg-config). - Verify the download:
sha256sum -c timefs-v0.1.0-x86_64-linux.tar.gz.sha256.
First release.
Added
-
Pack store (format 2, now the default): objects and refs in one append-only log, one
fdatasyncper checkpoint, torn-tail trimming, sync markers that turn damage of durable
data into a loud error, single-writer lock, compaction as GC (ADR-0009). -
Refstrait whosewritemakes objects durable first;FileRefsfor the loose layout. -
Paged extent lists (
FileIndex, object kind 5) and hole extents: a small edit to a big file
rewrites one page; sparse files cost one extent per hole; files up to 1 PiB. -
timefs init --store pack|loose,timefs migrate <dest> --store ..., store kind instats. -
timefs branch <name>works while a pack repository is mounted (sent to the mount). -
SIGKILL crash-injection test that alternates both stores (
crates/timefs-cli/tests/crash.rs). -
Design docs: motivation, architecture, canonical on-disk format v1, ADRs, testing
and benchmark methodology, roadmap, contributor guide, CI skeleton. -
Core objects: BLAKE3 identity, canonical binary codec (rejects non-minimal varints and
trailing bytes), Blob, File, Tree and Commit objects with validating decoders. -
Chunking: fixed-size and FastCDC chunkers.
-
Loose object store with atomic writes, read verification, dedupe counters and batched fsync.
-
Refs with atomic writes (tmp, fsync, rename, fsync dir).
-
Repository: init/open, flock, HEAD, branches, revision parsing, log, merge base.
-
Host directory import/export, path lookup, tree walk and structural diff.
-
Reachability marking and
fsckintegrity check. -
WorkTree overlay with an extent engine (stored, in-memory and hole segments); checkpoints
rewrite only dirty paths; unlinked inodes stay valid until forget and release. -
Read-write FUSE mount (libfuse3 via
fuser) as a thin adapter over WorkTree. -
Checkpoints to
refs/wip/<branch>, snapshots to the branch, crash recovery on next mount. -
Periodic checkpoint thread with inline flush on a dirty threshold.
-
Unix control socket with
snap,checkpointandstatus. -
Tree-level 3-way merge with explicit conflict types; conflicts abort untouched by default,
--resolve ours|theirssettles them. -
Mark-and-sweep GC with a grace period; refuses damaged repositories.
-
promote_checkpointturns a saved checkpoint into a commit. -
CLI:
init,import,export,log,ls,cat,diff,branch,fsck,stats,
mount(graceful unmount on SIGINT/SIGTERM),snap(live or offline),checkpoint,
status,merge,checkout,reset,gc; lock and checkpoint guards. -
CachedStore: a two-generation read cache for immutable objects. -
Benchmark harness: deterministic generators, median/min/max reports as Markdown tables.
-
Core benchmark scenarios: snapshot (vs
cp -rand git), branch/restore, merge, write
amplification, loose store overhead, dedupe and chunker comparison. -
Mount benchmark workloads, a passthrough FUSE baseline and an fsync phase breakdown.
-
Tests: unit tests, a model-based WorkTree property test, CLI black-box tests and real-mount
FUSE integration tests.
Changed
- Docs rewritten as bullets; README, architecture and ADRs brought up to date.
- WorkTree split into modules: error, node, extents, dir_ops, file_ops, persist, lifetime.
- Hex decoding uses
as_chunks(fixes a clippy lint on newer stable toolchains).
Fixed
- Checkpoint of a never-persisted empty tree (found by the model-based test).
- chmod, chown or touch on a file or symlink that was never read made every later checkpoint
fail; metadata-only changes now reuse the existing content object. The model test gained a
chmod operation and catches the old behaviour. - A torn object left by a crash was trusted by deduplication;
putnow checks the stored
length, rewrites a torn object, and fsyncs reused objects before a ref names them. - A failed
syncdropped its pending list, so a later sync could report success over
objects that were never made durable. - Unlinked-but-open files kept their data in memory forever; checkpoints now spill it.
- Files larger than the size limit are refused with
EFBIGinstead of hanging a checkpoint
(the limit is now 1 PiB, see Added). - A mount no longer overwrites a branch that moved underneath it (checkpoint and snapshot
refuse), and a checkpoint equal to the branch state is cleared instead of written. - Unlinked files report
nlink0;RENAME_WHITEOUTis rejected withEINVAL. - Looking up a name longer than 255 bytes returned
ENOENT; it now returnsENAMETOOLONG
like native filesystems (found by the differential stress test and pjdfstest).
Performance
- Loose store fsyncs objects in parallel over scoped threads; engine syncs once per snapshot.
- Measured on ext4 (SATA SSD), 1000 files: initial import 4792 ms to 662 ms.
- 100-file edit snapshot 471 ms to 70 ms, 1-file edit 21 ms to 9.5 ms.
- Loose store syncs files then directories in two parallel fsync rounds (A/B measured).
- Read cache and
FOPEN_KEEP_CACHE(every write goes through the mount).- Warm sequential read 821 to 6539 MB/s, cold 4K random read 15.3k to 54.4k IOPS.
- fsync latency still 9.4 ms (ref write needs 2 fsync rounds, see
docs/benchmarks.md).