From 5303ea45818a0651be38b7bf235ae13819c535c1 Mon Sep 17 00:00:00 2001 From: Julien CLEMENT Date: Tue, 27 Dec 2022 21:38:45 +0100 Subject: [PATCH] add prefix tree map to search for mount points Signed-off-by: Julien CLEMENT --- src/drivers/atapi/mod.rs | 5 ++-- src/fd/mod.rs | 5 +--- src/fs/iso/fd.rs | 2 +- src/fs/iso/iso9660.rs | 2 +- src/fs/iso/mod.rs | 11 ++++----- src/fs/mod.rs | 50 +++++++++++++++++++++++++++++++++++----- src/utils/mod.rs | 2 +- 7 files changed, 55 insertions(+), 22 deletions(-) diff --git a/src/drivers/atapi/mod.rs b/src/drivers/atapi/mod.rs index bbb04cc..c4a6622 100644 --- a/src/drivers/atapi/mod.rs +++ b/src/drivers/atapi/mod.rs @@ -58,7 +58,8 @@ static ATAPI_SIG: [u8; 4] = [ ]; lazy_static! { - pub static ref DRIVE: AsyncMutex> = AsyncMutex::new(ATABus::discover_atapi_drive()); + pub static ref DRIVE: AsyncMutex> = + AsyncMutex::new(ATABus::discover_atapi_drive()); } pub async fn init() { @@ -328,4 +329,4 @@ pub async fn print_block(lba: u32) { pub async fn read_block(lba: u32) -> [u8; CD_SECTOR_SIZE] { DRIVE.lock().await.as_mut().unwrap().read_block(lba).await -} \ No newline at end of file +} diff --git a/src/fd/mod.rs b/src/fd/mod.rs index 123084c..a4617e5 100644 --- a/src/fd/mod.rs +++ b/src/fd/mod.rs @@ -37,10 +37,7 @@ impl FDTable { pub fn unregister_fd(&mut self, fd: &dyn FileDescriptor) { self.table.remove(&fd.get_fd()); - println!( - "Unregistered fd: {:?}", - fd.get_fd() - ); + println!("Unregistered fd: {:?}", fd.get_fd()); } pub fn register_fd(&mut self, fd: FDt) { diff --git a/src/fs/iso/fd.rs b/src/fs/iso/fd.rs index 8825d40..ae98dbb 100644 --- a/src/fs/iso/fd.rs +++ b/src/fs/iso/fd.rs @@ -11,7 +11,7 @@ pub struct IsoFD { pub fd: FDId, offset: u32, lba: u32, - size: u32 + size: u32, } impl IsoFD { diff --git a/src/fs/iso/iso9660.rs b/src/fs/iso/iso9660.rs index b48b3f6..caa653d 100644 --- a/src/fs/iso/iso9660.rs +++ b/src/fs/iso/iso9660.rs @@ -77,7 +77,7 @@ impl IsoDir { #[allow(unaligned_references)] pub fn get_idf(&self) -> &[u8] { let mut len: usize = self.idf_len as usize; - unsafe { + unsafe { let mut idf = core::slice::from_raw_parts(self.idf.as_ptr(), len as usize); if len > 2 && idf[len - 2] == b';' && idf[len - 1] == b'1' { len -= 2; diff --git a/src/fs/iso/mod.rs b/src/fs/iso/mod.rs index 3334d59..ee9098e 100644 --- a/src/fs/iso/mod.rs +++ b/src/fs/iso/mod.rs @@ -2,7 +2,7 @@ mod fd; pub mod iso9660; use crate::drivers::atapi::read_block; -use crate::fd::{FDt}; +use crate::fd::FDt; use crate::utils::unserialize; use super::FileSystem; @@ -31,20 +31,18 @@ impl FileSystem for IsoFS { } let root: &IsoDir = &voldesc.root_dir; - let mut curr_entry_block: [u8; iso9660::ISO_BLOCK_SIZE as usize] = read_block(root.data_blk.le).await; + let mut curr_entry_block: [u8; iso9660::ISO_BLOCK_SIZE as usize] = + read_block(root.data_blk.le).await; let mut curr_entry: &IsoDir = unserialize(curr_entry_block.as_ptr()); let path_s: String = String::from(path); let path_split: Vec<&str> = path_s.split("/").collect(); - let path_it = path_s - .split("/") - .filter(|p| p != &""); + let path_it = path_s.split("/").filter(|p| p != &""); for path_component in path_it { let mut found = false; while curr_entry.idf_len != 0 { - // Found entry if curr_entry.matches(path_component) { found = true; @@ -76,7 +74,6 @@ impl FileSystem for IsoFS { } } - pub async fn get_prim_vol_desc() -> IsoPrimVolDesc { let desc_block = read_block(iso9660::ISO_PRIM_VOLDESC_BLOCK).await; *unserialize::(desc_block.as_ptr()) diff --git a/src/fs/mod.rs b/src/fs/mod.rs index e9f9d44..9fffa68 100644 --- a/src/fs/mod.rs +++ b/src/fs/mod.rs @@ -3,10 +3,11 @@ pub mod iso; use crate::fd::FDt; use crate::utils::mutex::AsyncMutex; -use alloc::{boxed::Box, sync::Arc}; +use alloc::{boxed::Box, string::String, sync::Arc, vec::Vec}; use async_trait::async_trait; use core::cell::RefCell; use lazy_static::lazy_static; +use prefix_tree_map::{PrefixTreeMap, PrefixTreeMapBuilder}; pub type FSt = Arc>; @@ -20,20 +21,57 @@ pub trait FileSystem { } pub struct VirtualFS { - fs: FSt, + map_builder: PrefixTreeMapBuilder, + map: Option>, } impl VirtualFS { fn new() -> Self { - VirtualFS { - fs: Arc::new(RefCell::new(iso::IsoFS {})), - } + let mut res = VirtualFS { + map_builder: PrefixTreeMapBuilder::new(), + map: None, + }; + let fs = Arc::new(RefCell::new(iso::IsoFS {})); + let fs2 = Arc::new(RefCell::new(iso::IsoFS {})); + res.mount("/", fs); + res.mount("/mnt/iso", fs2); + res + } + + fn mount(&mut self, path: &str, fs: FSt) { + let path_s: String = String::from(path); + self.map_builder.insert_exact( + path_s + .split("/") + .filter(|p| p != &"") + .map(|s| String::from(s)), + fs, + ); + self.map = Some(self.map_builder.clone().build()); } } #[async_trait(?Send)] impl FileSystem for VirtualFS { async fn open(&mut self, path: &str, flags: u32) -> Option { - self.fs.borrow_mut().open(path, flags).await + if let Some(map) = &self.map { + let path_s: String = String::from(path); + let mut path_split: Vec = path_s + .split("/") + .filter(|p| p != &"") + .map(|s| String::from(s)) + .collect(); + loop { + if let Some(fs) = map.find_exact(&path_split) { + // TODO, remove path prefix of the mount point + return fs.borrow_mut().open(path, flags).await; + } + else { + path_split.truncate(path_split.len() - 1); + } + } + } else { + None + } } } diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 9b88c2c..5ef6f53 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -16,4 +16,4 @@ pub fn ref_raw_offset(r: &T, off: isize) -> &T { unsafe { return &*ref_ptr.cast::().offset(off).cast::(); } -} \ No newline at end of file +}