From 65c34574867f4b8f1687bfd5ef21790fa7c9d61a Mon Sep 17 00:00:00 2001 From: Xiaoyang Han Date: Thu, 25 Jul 2024 17:39:50 +0800 Subject: [PATCH] [scorpio]: Add Readonly dictionary FUSE--fix path acquisition and deadlock bugs Signed-off-by: Xiaoyang Han --- scorpio/src/dicfuse/mod.rs | 11 +++++------ scorpio/src/dicfuse/store.rs | 29 ++++++++++++++++------------- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/scorpio/src/dicfuse/mod.rs b/scorpio/src/dicfuse/mod.rs index 20c5ac93..0c2bbdea 100644 --- a/scorpio/src/dicfuse/mod.rs +++ b/scorpio/src/dicfuse/mod.rs @@ -42,6 +42,7 @@ impl FileSystem for Dicfuse{ fn init(&self, capable:FsOptions) -> Result { self.store.import(); + //let mut ops = FsOptions::DO_READDIRPLUS | FsOptions::READDIRPLUS_AUTO; Ok(fuse_backend_rs::abi::fuse_abi::FsOptions::empty()) } @@ -293,7 +294,7 @@ impl FileSystem for Dicfuse{ mod tests { use std::{io, path::Path, sync::Arc,thread}; - use fuse_backend_rs::{api::server::Server, transport::{FuseChannel, FuseSession}}; + use fuse_backend_rs::{ api::server::Server, transport::{FuseChannel, FuseSession}}; use signal_hook::{consts::TERM_SIGNALS, iterator::Signals}; use super::Dicfuse; @@ -341,18 +342,16 @@ mod tests { #[test] fn test_svc_loop_success() { let dicfuse = Arc::new(Dicfuse::new()); + // dicfuse.init(FsOptions::empty()).unwrap(); // Create fuse session let mut se = FuseSession::new(Path::new(&"/home/luxian/ccode/mega/dictest"), "dic", "", true).unwrap(); se.mount().unwrap(); let ch: FuseChannel = se.new_channel().unwrap(); + println!("start fs servers"); let server = Arc::new(Server::new(dicfuse.clone())); - let mut dicfuse_server = DicFuseServer { server, ch }; - // Mock the behavior of get_request to simulate a successful request - // This would require implementing a mock or a stub for FuseChannel - // For the sake of this example, we will assume it is done correctly + let mut dicfuse_server = DicFuseServer { server, ch }; - // Spawn server thread let handle = thread::spawn(move || { let _ = dicfuse_server.svc_loop(); diff --git a/scorpio/src/dicfuse/store.rs b/scorpio/src/dicfuse/store.rs index 3d6bf0ad..fe41cb2e 100644 --- a/scorpio/src/dicfuse/store.rs +++ b/scorpio/src/dicfuse/store.rs @@ -27,7 +27,7 @@ pub struct Item { #[allow(unused)] pub struct DicItem{ inode:u64, - name:GPath, + path_name:GPath, content_type: Mutex, children:Mutex>>, parent:u64, @@ -44,7 +44,7 @@ impl DicItem { pub fn new(inode:u64,parent:u64, item:Item) -> Self { DicItem { inode, - name: item.name.into(), // Assuming GPath can be created from String + path_name: item.path.into(), // Assuming GPath can be created from String content_type: match item.content_type.as_str() { "file" => ContentType::File.into(), "directory" => ContentType::Dictionary(false).into(), @@ -56,11 +56,11 @@ impl DicItem { } //get the total path pub fn get_path(&self) -> String { - self.name.to_string() + self.path_name.to_string() } //get the file or dic name . aka tail name. pub fn get_name(&self) -> String { - self.name.name() + self.path_name.name() } // add a children item pub fn push_children(&self,children:Arc){ @@ -130,7 +130,7 @@ impl DictionaryStore { }; let root_item = DicItem{ inode: 1, - name: GPath::new(), + path_name: GPath::new(), content_type: ContentType::Dictionary(false).into(), children: Mutex::new(HashMap::new()), parent: UNKNOW_INODE, // root dictory has no parent @@ -141,6 +141,8 @@ impl DictionaryStore { self.next_inode.fetch_add(1, std::sync::atomic::Ordering::Relaxed); let alloc_inode = self.next_inode.load(std::sync::atomic::Ordering::Relaxed); self.radix_trie.lock().unwrap().insert(item.path.clone(), alloc_inode); + + self.queue.lock().unwrap().push_back(alloc_inode); if let Some(parent) = pitem{ let newitem = Arc::new(DicItem::new(alloc_inode, parent.get_inode(),item)); @@ -150,21 +152,22 @@ impl DictionaryStore { self.inodes.lock().unwrap().insert(alloc_inode, Arc::new(DicItem::new(alloc_inode, UNKNOW_INODE,item))); } - self.queue.lock().unwrap().push_back(alloc_inode); + } pub fn import(&self){ const ROOT_DIR: &str ="/"; - let mut queue = VecDeque::new(); let items: Vec = tokio::runtime::Runtime::new().unwrap().block_on(fetch_tree(ROOT_DIR)).unwrap().collect();//todo: can't tokio for it in items{ self.update_inode(None,it); } - while !queue.is_empty() {//BFS to look up all dictionary - let one_inode = queue.pop_back().unwrap(); + loop {//BFS to look up all dictionary + if self.queue.lock().unwrap().is_empty(){ + break; + } + let one_inode = self.queue.lock().unwrap().pop_front().unwrap(); let mut new_items = Vec::new(); { - let inodes_lock = self.inodes.lock().unwrap(); - let it = inodes_lock.get(&one_inode).unwrap(); + let it = self.inodes.lock().unwrap().get(&one_inode).unwrap().clone(); if let ContentType::Dictionary(load) = *it.content_type.lock().unwrap(){ if !load{ let path = it.get_path(); @@ -186,7 +189,7 @@ impl DictionaryStore { pub fn find_path(&self,inode :u64)-> Option{ - self.inodes.lock().unwrap().get(&inode).map(|item| item.name.clone()) + self.inodes.lock().unwrap().get(&inode).map(|item| item.path_name.clone()) } pub fn get_inode(&self,inode: u64) -> Result, io::Error> { match self.inodes.lock().unwrap().get(&inode) { @@ -201,7 +204,7 @@ impl DictionaryStore { self.get_inode(*inode) } fn find_children(&self,parent: u64) -> Result{ - let path = self.inodes.lock().unwrap().get(&parent).map(|item| item.name.clone()); + let path = self.inodes.lock().unwrap().get(&parent).map(|item| item.path_name.clone()); if let Some(parent_path) = path{ let l = self.radix_trie.lock().unwrap(); let pathstr:String =parent_path.name();