feat(fuse): close T101 + repair FUSE directory listing (Charter-01 Fase 2)#41
Merged
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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)
getattr(lookup+getattr upper bound)readdir, 1000 entriesFunctional bugs found & fixed (commit 1)
init()panicked on every mount —start_periodic()doestokio::spawnbutinit()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: enterself.rt_handlefor the spawn.children()listed the root as its own child (ino == parent_ino, empty name) →readdirstalls after./..→ emptyls. Fix: exclude the self-referential entry. (Root cause of empty listings.)readdirpaged over unstableDashMaporder → large dirs lost files non-deterministically. Fix: sortchildren()by inode.opendirusedFOPEN_KEEP_CACHEon a dynamic directory → kernel stopped re-issuingreaddir. Fix: no cache flags.save_item(INSERT OR REPLACE dropped the column;from_rownever read it) → unstable inodes between mounts. Fix: persist + read back.Discarded:
get_next_inodeis already transactional/atomic — no change.Tests
tests/integration_perf_t101.rs(new,#[ignore]— needs/dev/fuse): the 3 T101 metrics over a real mount.inode.rs(root self-exclusion, stable order) +repository_tests.rs(inode round-trip).cargo test --workspacegreen;clippy -D warningsclean.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