Skip to content

Prefetching (non-slop)#40

Open
markovejnovic wants to merge 2 commits intomainfrom
marko/mes-696-lookup-pre-fetch-post-readdir-2
Open

Prefetching (non-slop)#40
markovejnovic wants to merge 2 commits intomainfrom
marko/mes-696-lookup-pre-fetch-post-readdir-2

Conversation

@markovejnovic
Copy link
Collaborator

No description provided.

@blacksmith-sh
Copy link
Contributor

blacksmith-sh bot commented Feb 18, 2026

Found 2 test failures on Blacksmith runners:

Failures

Test View Logs
test_directory_layout/test_directory_layout_matches_clone[github-samples/planventure] View Logs
test_directory_layout/test_directory_layout_matches_clone[kelseyhightower/nocode] View Logs

Fix in Cursor

@mesa-dot-dev
Copy link

mesa-dot-dev bot commented Feb 18, 2026

Mesa Description

This PR implements a "post-readdir" prefetching strategy to improve filesystem performance for metadata-heavy directory listings (e.g., ls -l).

When a directory is read, this change proactively fetches the attributes for all of its children in a single batch operation. This populates the inode cache, ensuring that subsequent lookup calls for those files are served directly from memory, eliminating numerous high-latency round trips.

The "(non-slop)" approach signifies that the prefetching is targeted only at the immediate children of the listed directory, preventing cache pollution from over-fetching.

Description generated by Mesa. Update settings

Copy link

@mesa-dot-dev mesa-dot-dev bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Performed full review of e2d3738...b4fa0dc

Analysis

  1. Incomplete architecture for new asynchronous filesystem caching - the AsyncFs component lacks critical interfaces for table population and write-through to the directory cache, making these data structures currently unusable.

  2. Background task orchestration framework is added but not connected to the rest of the system, leaving the foundational infrastructure without clear integration paths.

  3. Significant regression in telemetry configuration - removal of Trc::with_telemetry and hard-coding of OTLP exporter means application-level telemetry settings are now ignored.

  4. The PR attempts to introduce multiple significant architectural changes simultaneously (async filesystem caching, background tasks, telemetry rework) without complete implementation paths for each.

Tip

Help

Slash Commands:

  • /review - Request a full code review
  • /review latest - Review only changes since the last review
  • /describe - Generate PR description. This will update the PR body or issue comment depending on your configuration
  • /help - Get help with Mesa commands and configuration options

0 files reviewed | 9 comments | Edit Agent SettingsRead Docs

@@ -0,0 +1,203 @@
//! Async INode Table which supports concurrent access and modification.
use std::{ffi::OsStr, sync::Arc};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Medium

FsDataProvider uses the Future trait in its associated type, but this module never brings std::future::Future into scope. As written the file doesn’t compile (cannot find type �Future� in this scope). Please import std::future::Future before defining the trait.

Fix in Cursor • Fix in Claude

Prompt for Agent
Task: Address review feedback left on GitHub.
Repository: mesa-dot-dev/gitfs#40
File: lib/fs/async_fs.rs#L3
Action: Open this file location in your editor, inspect the highlighted code, and resolve the issue described below.

Feedback:
`FsDataProvider` uses the `Future` trait in its associated type, but this module never brings `std::future::Future` into scope. As written the file doesn’t compile (`cannot find type �Future� in this scope`). Please import `std::future::Future` before defining the trait.

self.cache.peek_with(&key, |_, v| v.clone())
}

pub fn insert(&self, parent_ino: LoadedAddr, name: OsString, ino: LoadedAddr, is_dir: bool) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Medium

TreeIndex::insert_sync returns Err((key, value)) when the key already exists. Because the result is ignored, refreshes never replace the old dentry even though the comment says overwrites are expected. Cached directory entries therefore stay stale until they are explicitly removed. Consider using upsert_sync or removing/reinserting so that lookups see the refreshed inode info.

Fix in Cursor • Fix in Claude

Prompt for Agent
Task: Address review feedback left on GitHub.
Repository: mesa-dot-dev/gitfs#40
File: lib/fs/dcache.rs#L38
Action: Open this file location in your editor, inspect the highlighted code, and resolve the issue described below.

Feedback:
`TreeIndex::insert_sync` returns `Err((key, value))` when the key already exists. Because the result is ignored, refreshes never replace the old dentry even though the comment says overwrites are expected. Cached directory entries therefore stay stale until they are explicitly removed. Consider using `upsert_sync` or removing/reinserting so that lookups see the refreshed inode info.

@@ -0,0 +1,191 @@
//! Random tokio extensions.

use std::{fmt::Debug, hash::Hash, pin::Pin, sync::Arc};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Medium

BackgroundTaskPoolMap::spawn is generic over Future, but std::future::Future isn’t imported anywhere in this module. This causes a compile error when the file is built. Please add use std::future::Future; (or qualify the trait) before using it in the signatures.

Fix in Cursor • Fix in Claude

Prompt for Agent
Task: Address review feedback left on GitHub.
Repository: mesa-dot-dev/gitfs#40
File: lib/tokex.rs#L3
Action: Open this file location in your editor, inspect the highlighted code, and resolve the issue described below.

Feedback:
`BackgroundTaskPoolMap::spawn` is generic over `Future`, but `std::future::Future` isn’t imported anywhere in this module. This causes a compile error when the file is built. Please add `use std::future::Future;` (or qualify the trait) before using it in the signatures.

return;
}

// SAFETY: The Drop implementation here guarantees that the future will be aborted before
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

High

std::mem::transmute is extending both the future and self to 'static so they can be moved into tokio::spawn, but nothing actually guarantees those references outlive the spawned task. Drop only calls JoinHandle::abort, which just schedules cancellation—it doesn’t wait for the task to finish touching self. If the pool is dropped while a task is still running, the task now holds a 'static reference to freed memory, leading to use-after-free UB. Instead of transmutes, require callers to give you 'static futs or move an Arc<Self> (or other owned state) into the task.

Fix in Cursor • Fix in Claude

Prompt for Agent
Task: Address review feedback left on GitHub.
Repository: mesa-dot-dev/gitfs#40
File: lib/tokex.rs#L37
Action: Open this file location in your editor, inspect the highlighted code, and resolve the issue described below.

Feedback:
`std::mem::transmute` is extending both the future and `self` to `'static` so they can be moved into `tokio::spawn`, but nothing actually guarantees those references outlive the spawned task. `Drop` only calls `JoinHandle::abort`, which just schedules cancellation—it doesn’t wait for the task to finish touching `self`. If the pool is dropped while a task is still running, the task now holds a `'static` reference to freed memory, leading to use-after-free UB. Instead of transmutes, require callers to give you `'static` futs or move an `Arc<Self>` (or other owned state) into the task.

self.handles.insert_sync(handle_id, handle).unwrap();
}

// Notify the future that it can modify
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Medium

trigger_task_rx lives inside the spawned task. If that task panics or returns before reaching trigger_task_rx.await, the receiver is dropped and this send(...).unwrap() will panic, crashing the entire pool. Consider handling the Err case (log and continue or clean up the maps) instead of unconditionally unwrapping here.

Fix in Cursor • Fix in Claude

Prompt for Agent
Task: Address review feedback left on GitHub.
Repository: mesa-dot-dev/gitfs#40
File: lib/tokex.rs#L93
Action: Open this file location in your editor, inspect the highlighted code, and resolve the issue described below.

Feedback:
`trigger_task_rx` lives inside the spawned task. If that task panics or returns before reaching `trigger_task_rx.await`, the receiver is dropped and this `send(...).unwrap()` will panic, crashing the entire pool. Consider handling the `Err` case (log and continue or clean up the maps) instead of unconditionally unwrapping here.

/// For each lookup call made by the kernel, it expects the icache to be updated with the
/// returned `FileAttr`.
async fn lookup(&mut self, parent: Inode, name: &OsStr) -> Result<FileAttr, Self::LookupError>;
async fn lookup(
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Medium

async fn lookup(...) -> Result<impl CreatedFileAttr, _> cannot compile inside a trait definition: opaque impl Trait return types aren’t allowed in trait methods (even with async_trait). The compiler emits "impl Trait in trait method return type is not allowed". You’ll need to introduce an associated type (e.g. type LookupOutput: CreatedFileAttr;) or return a boxed trait object instead.

Fix in Cursor • Fix in Claude

Prompt for Agent
Task: Address review feedback left on GitHub.
Repository: mesa-dot-dev/gitfs#40
File: src/fs/trait.rs#L358
Action: Open this file location in your editor, inspect the highlighted code, and resolve the issue described below.

Feedback:
`async fn lookup(...) -> Result<impl CreatedFileAttr, _>` cannot compile inside a trait definition: opaque `impl Trait` return types aren’t allowed in trait methods (even with `async_trait`). The compiler emits "impl Trait in trait method return type is not allowed". You’ll need to introduce an associated type (e.g. `type LookupOutput: CreatedFileAttr;`) or return a boxed trait object instead.

flush: bool,
) -> Result<(), Self::ReleaseError>;

/// Called when the kernel is done with an inode.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Medium

Removing Fs::forget here breaks every caller that still invokes it (e.g. src/fs/fuser.rs:324 still forwards the kernel’s FORGET ops to Fs::forget). Until those call sites and implementors are updated to the new Forgettable trait, the crate won’t compile. Either keep the method or plumb the new abstraction through the remaining modules in the same PR.

Fix in Cursor • Fix in Claude

Prompt for Agent
Task: Address review feedback left on GitHub.
Repository: mesa-dot-dev/gitfs#40
File: src/fs/trait.rs#L370
Action: Open this file location in your editor, inspect the highlighted code, and resolve the issue described below.

Feedback:
Removing `Fs::forget` here breaks every caller that still invokes it (e.g. `src/fs/fuser.rs:324` still forwards the kernel’s FORGET ops to `Fs::forget`). Until those call sites and implementors are updated to the new `Forgettable` trait, the crate won’t compile. Either keep the method or plumb the new abstraction through the remaining modules in the same PR.

}

impl Trc {
/// Configure OTLP telemetry endpoints from the application config.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Medium

Trc::with_telemetry is removed here, but main still calls it (src/main.rs:58). The crate no longer compiles because the method doesn’t exist. Please keep the API or update the call sites/config plumbing in the same change.

Fix in Cursor • Fix in Claude

Prompt for Agent
Task: Address review feedback left on GitHub.
Repository: mesa-dot-dev/gitfs#40
File: src/trc.rs#L128
Action: Open this file location in your editor, inspect the highlighted code, and resolve the issue described below.

Feedback:
`Trc::with_telemetry` is removed here, but `main` still calls it (`src/main.rs:58`). The crate no longer compiles because the method doesn’t exist. Please keep the API or update the call sites/config plumbing in the same change.

.map(|p| tracing_opentelemetry::layer().with_tracer(p.tracer("git-fs")));
#[cfg(feature = "__otlp_export")]
{
let exporter = opentelemetry_otlp::SpanExporter::builder()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Medium

All of the telemetry configuration is now hard-coded to SpanExporter::builder().with_http().build() with default endpoints, and Trc no longer stores the TelemetryConfig::endpoints() at all. That means user-provided collector URLs are ignored and 丑 mode can no longer enable OTLP export even if the config asks for it. Please keep the endpoint plumbing (or otherwise expose it) so we don’t silently drop telemetry when this lands.

Fix in Cursor • Fix in Claude

Prompt for Agent
Task: Address review feedback left on GitHub.
Repository: mesa-dot-dev/gitfs#40
File: src/trc.rs#L166
Action: Open this file location in your editor, inspect the highlighted code, and resolve the issue described below.

Feedback:
All of the telemetry configuration is now hard-coded to `SpanExporter::builder().with_http().build()` with default endpoints, and `Trc` no longer stores the `TelemetryConfig::endpoints()` at all. That means user-provided collector URLs are ignored and 丑 mode can no longer enable OTLP export even if the config asks for it. Please keep the endpoint plumbing (or otherwise expose it) so we don’t silently drop telemetry when this lands.

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