You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@opendal.apache.org by xu...@apache.org on 2026/10/26 07:43:20 UTC
(opendal-yinyang) branch xuanwo/linux-fuse-foundation updated: fix: bridge FUSE inode newtypes to the inode table
This is an automated email from the ASF dual-hosted git repository.
Xuanwo pushed a commit to branch xuanwo/linux-fuse-foundation
in repository https://gitbox.apache.org/repos/asf/opendal-yinyang.git
The following commit(s) were added to refs/heads/xuanwo/linux-fuse-foundation by this push:
new 9e3fe55 fix: bridge FUSE inode newtypes to the inode table
9e3fe55 is described below
commit 9e3fe555f9e0e50e9d24a44dbe53eab687af91aa
Author: Xuanwo <gi...@xuanwo.io>
AuthorDate: Mon Oct 26 15:42:27 2026 +0800
fix: bridge FUSE inode newtypes to the inode table
fuser represents inode numbers with the `INodeNo` newtype while the
volume-lifetime map keys plain u64 values. Convert at the adapter
boundary so the root constant, table lookups, and kernel reference
counters have matching types, and release the inode-table guard before
reacquiring it in `resolve_entry` to avoid a cached-readdir deadlock.
Co-authored-by: Chojan Shang <ps...@apache.org>
---
src/fuse/frontend.rs | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/src/fuse/frontend.rs b/src/fuse/frontend.rs
index 903655b..9babe9d 100644
--- a/src/fuse/frontend.rs
+++ b/src/fuse/frontend.rs
@@ -42,7 +42,7 @@
//! exit is the actual point where remaining tasks are dropped.
use super::attrs::{ATTR_TTL, DIRECTORY_SIZE, attribute};
-use super::inode::{CachedInfo, InodeTable, ROOT_INODE};
+use super::inode::{CachedInfo, InodeTable};
use crate::mount::{Mount, MountFile};
use fuser::{
AccessFlags, BsdFileFlags, FileAttr, FileHandle, FileType, Filesystem, FopenFlags, Generation,
@@ -122,19 +122,19 @@ impl Inner {
if let Some(info) = info {
inodes.cache(id, info);
}
- inodes.inode(id).map_err(|_| fuser::Errno::EIO)
+ inodes.inode(id).map(INodeNo).map_err(|_| fuser::Errno::EIO)
}
fn node(&self, ino: INodeNo) -> Option<NodeId> {
- guard(&self.inodes).node(ino)
+ guard(&self.inodes).node(ino.0)
}
fn remember_lookup(&self, ino: INodeNo) {
- guard(&self.inodes).remember_lookup(ino);
+ guard(&self.inodes).remember_lookup(ino.0);
}
fn forget(&self, ino: INodeNo, count: u64) {
- guard(&self.inodes).forget(ino, count);
+ guard(&self.inodes).forget(ino.0, count);
}
fn open_file(&self, fh: FileHandle) -> Option<Arc<OpenFile>> {
@@ -187,7 +187,7 @@ impl Inner {
/// `fstat` and read bytes describe the same pinned version.
async fn handle_attr(&self, open: &OpenFile) -> Result<FileAttr, fuser::Errno> {
let status = open.file.status().await.map_err(|e| runtime_errno(&e))?;
- let cached = guard(&self.inodes).cached(open.node);
+ let cached = { guard(&self.inodes).cached(open.node) };
let ino = self.inode_for(open.node, None)?;
Ok(attribute(
ino,
@@ -315,7 +315,7 @@ impl Inner {
Err(errno) => return reply.error(errno),
},
// The root's "." and ".." both denote itself.
- None => ROOT_INODE,
+ None => INodeNo::ROOT,
};
guard(&self.inodes).cache(
id,
@@ -423,7 +423,10 @@ impl Inner {
snapshot: &Snapshot,
id: NodeId,
) -> Result<(INodeNo, FileType), fuser::Errno> {
- if let Some(info) = guard(&self.inodes).cached(id) {
+ // Release the inode-table guard before `inode_for` reacquires it;
+ // an `if let` scrutinee would keep the temporary guard alive.
+ let cached = { guard(&self.inodes).cached(id) };
+ if let Some(info) = cached {
let ino = self.inode_for(id, None)?;
return Ok((ino, entry_kind(info.directory)));
}