Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[scorpio]: Add Readonly dictionary FUSE #480

Merged
merged 1 commit into from
Jul 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions scorpio/src/dicfuse/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ impl FileSystem for Dicfuse{

fn init(&self, capable:FsOptions) -> Result<FsOptions> {
self.store.import();
//let mut ops = FsOptions::DO_READDIRPLUS | FsOptions::READDIRPLUS_AUTO;
Ok(fuse_backend_rs::abi::fuse_abi::FsOptions::empty())
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand Down
29 changes: 16 additions & 13 deletions scorpio/src/dicfuse/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub struct Item {
#[allow(unused)]
pub struct DicItem{
inode:u64,
name:GPath,
path_name:GPath,
content_type: Mutex<ContentType>,
children:Mutex<HashMap<String, Arc<DicItem>>>,
parent:u64,
Expand All @@ -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(),
Expand All @@ -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<DicItem>){
Expand Down Expand Up @@ -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
Expand All @@ -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));
Expand All @@ -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<Item> = 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();
Expand All @@ -186,7 +189,7 @@ impl DictionaryStore {


pub fn find_path(&self,inode :u64)-> Option<GPath>{
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<Arc<DicItem>, io::Error> {
match self.inodes.lock().unwrap().get(&inode) {
Expand All @@ -201,7 +204,7 @@ impl DictionaryStore {
self.get_inode(*inode)
}
fn find_children(&self,parent: u64) -> Result<DicItem,io::Error>{
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();
Expand Down
Loading