Skip to content

Conversation

@benhillis
Copy link
Member

SectionFs::forget() unconditionally removed the inode regardless of the lookup_count parameter. This could cause premature inode removal when multiple kernel references existed. Track the count per inode and only remove when it reaches zero.

@benhillis benhillis requested a review from a team as a code owner February 10, 2026 16:30
Copilot AI review requested due to automatic review settings February 10, 2026 16:30
@github-actions github-actions bot added the unsafe Related to unsafe code label Feb 10, 2026
@github-actions
Copy link

⚠️ Unsafe Code Detected

This PR modifies files containing unsafe Rust code. Extra scrutiny is required during review.

For more on why we check whole files, instead of just diffs, check out the Rustonomicon

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the SectionFs virtio-fs backend to avoid dropping inode state on FORGET until the kernel’s lookup references have been released, aligning behavior with FUSE’s lookup_count semantics.

Changes:

  • Add per-inode lookup_count tracking to SectionFs inodes.
  • Update SectionFs::forget() to decrement by lookup_count and only remove the inode when the count reaches zero.

Comment on lines 250 to 255
let inode = Inode {
size,
state: InodeState::Open(section),
lookup_count: 1,
};
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

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

lookup_count is always initialized to 1 when creating an Inode, but there’s no code path that ever increments it on subsequent lookups of the same inode/node_id. As a result, this won’t actually prevent premature removal in scenarios where the kernel holds multiple lookup references to the same node_id. To truly “track the count per inode”, you’ll need to reuse an existing node_id for repeated lookups and increment the stored count (similar to how VirtioFsInode::lookup() works), or otherwise redesign the inode table to key by object identity/path and bump the count when returning an existing entry.

Copilot uses AI. Check for mistakes.
fn forget(&self, node_id: u64, lookup_count: u64) {
let mut inodes = self.inodes.lock();
if let Some(inode) = inodes.get_mut(node_id) {
inode.lookup_count = inode.lookup_count.saturating_sub(lookup_count);
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

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

saturating_sub() will silently clamp to 0 if lookup_count is greater than the tracked count, which can hide lookup/forget mismatches and cause unexpected inode removal. Consider matching the behavior used elsewhere in this crate (e.g., warn when too many forgets are observed) so unexpected kernel/client behavior is diagnosable.

Suggested change
inode.lookup_count = inode.lookup_count.saturating_sub(lookup_count);
if lookup_count > inode.lookup_count {
tracing::warn!(
node_id,
lookup_count,
current_lookup_count = inode.lookup_count,
"received forget with lookup_count greater than tracked count"
);
inode.lookup_count = 0;
} else {
inode.lookup_count -= lookup_count;
}

Copilot uses AI. Check for mistakes.
@benhillis benhillis marked this pull request as draft February 10, 2026 17:27
OpenVMM Team added 2 commits February 10, 2026 18:48
SectionFs::forget() unconditionally removed the inode regardless of the
lookup_count parameter. This could cause premature inode removal when
multiple kernel references existed. Track the count per inode and only
remove when it reaches zero.
@benhillis benhillis force-pushed the fix/virtiofs-section-forget branch from 9eb7bd3 to 2f918b8 Compare February 10, 2026 19:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

unsafe Related to unsafe code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant