Skip to content

feat(fuse): close T101 + repair FUSE directory listing (Charter-01 Fase 2)#41

Merged
montfort merged 2 commits into
mainfrom
feat/charter-01-phase-2-t101-perf
May 31, 2026
Merged

feat(fuse): close T101 + repair FUSE directory listing (Charter-01 Fase 2)#41
montfort merged 2 commits into
mainfrom
feat/charter-01-phase-2-t101-perf

Conversation

@montfort

Copy link
Copy Markdown
Contributor

Closes T101 (the sole remaining work item of Charter-01 Fase 2): FUSE performance validation. Implementing it as a real-mount integration test made it the first end-to-end FUSE mount exercised in the codebase, which surfaced a chain of functional bugs that made directory listing non-functional. Those are fixed here, with CI-runnable regression tests, before the numbers could be taken.

T101 result (real mount)

Metric Target Measured
getattr (lookup+getattr upper bound) < 1 ms 43.7 µs
readdir, 1000 entries < 10 ms 1.40 ms
idle RSS, 10k tracked files < 50 MB 37.9 MB

Functional bugs found & fixed (commit 1)

  1. init() panicked on every mountstart_periodic() does tokio::spawn but init() runs on fuser's thread with no runtime entered ("there is no reactor running"). The daemon auto-mounts the same way, so auto-mount was broken. Fix: enter self.rt_handle for the spawn.
  2. children() listed the root as its own child (ino == parent_ino, empty name) → readdir stalls after ./.. → empty ls. Fix: exclude the self-referential entry. (Root cause of empty listings.)
  3. readdir paged over unstable DashMap order → large dirs lost files non-deterministically. Fix: sort children() by inode.
  4. opendir used FOPEN_KEEP_CACHE on a dynamic directory → kernel stopped re-issuing readdir. Fix: no cache flags.
  5. inode not persisted across save_item (INSERT OR REPLACE dropped the column; from_row never read it) → unstable inodes between mounts. Fix: persist + read back.

Discarded: get_next_inode is already transactional/atomic — no change.

Tests

  • tests/integration_perf_t101.rs (new, #[ignore] — needs /dev/fuse): the 3 T101 metrics over a real mount.
  • CI-runnable regressions: inode.rs (root self-exclusion, stable order) + repository_tests.rs (inode round-trip).
  • cargo test --workspace green; clippy -D warnings clean.

See AILOG-2026-05-31-001 for the full analysis. The Charter is updated to note the other three Fase-2 items were already completed during Fase 1.

🤖 Generated with Claude Code

montfort and others added 2 commits May 31, 2026 02:37
The first real FUSE mount (added for T101) exposed a chain of functional
bugs that made directory listing non-functional. Fixed here with
CI-runnable regression tests:

- init(): enter the runtime held in rt_handle before start_periodic(),
  which does tokio::spawn — init() runs on fuser's thread with no runtime
  entered, so every mount panicked with "there is no reactor running".
- children(): exclude the self-referential root (ino == parent_ino), which
  was listed as its own child with an empty name and stalled readdir after
  ./.. — yielding an empty `ls`.
- children(): sort by inode so readdir's positional offset paging is stable
  across kernel calls (DashMap iteration order is not), fixing
  non-deterministic entry loss in large directories.
- opendir(): drop FOPEN_KEEP_CACHE so the kernel re-issues readdir on a
  dynamic directory instead of serving a stale (initially empty) cache.
- save_item()/sync_item_from_row(): persist and read back the inode column
  so inodes stay stable across mounts instead of being re-allocated.

Refs: Charter-01 Fase 2, AILOG-2026-05-31-001

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Validate FUSE performance against a real mount (the first end-to-end mount
test in the codebase), closing T101 — the sole remaining work item of
Charter-01 Fase 2:

- getattr (lookup+getattr upper bound): 43.7µs   (target < 1ms)
- readdir, 1000 entries:                1.40ms   (target < 10ms)
- idle RSS, 10k tracked files:          37.9MB   (target < 50MB)

The integration test is #[ignore] (needs /dev/fuse + fusermount3, absent in
CI) and configurable via LNXDRIVE_PERF_N. The functional fixes it required
landed in the previous commit; this commit adds the test, marks T101 done,
records the Fase-2 AILOG, and updates the Charter to reflect that the other
three Fase-2 items were already completed during Fase 1.

Refs: Charter-01 Fase 2, AILOG-2026-05-31-001

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@montfort montfort merged commit ecc987b into main May 31, 2026
9 checks passed
@montfort montfort deleted the feat/charter-01-phase-2-t101-perf branch May 31, 2026 08:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant