diff --git a/Cargo.lock b/Cargo.lock index fb5ef91..57eb766 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -44,6 +44,9 @@ name = "bitflags" version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +dependencies = [ + "serde", +] [[package]] name = "byteorder" @@ -69,6 +72,14 @@ version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f64009896348fc5af4222e9cf7d7d82a95a256c634ebcf61c53e4ea461422242" +[[package]] +name = "dir_rpc" +version = "0.1.0" +dependencies = [ + "parking_lot", + "postcard", +] + [[package]] name = "either" version = "1.13.0" @@ -92,6 +103,7 @@ name = "ext2" version = "0.1.0" dependencies = [ "binread", + "dir_rpc", "file_rpc", "fs_rpc", "itertools", @@ -104,6 +116,7 @@ dependencies = [ name = "file_rpc" version = "0.1.0" dependencies = [ + "bitflags", "parking_lot", "postcard", "serde", diff --git a/Cargo.toml b/Cargo.toml index 812a7c7..7cf5ae1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" [dependencies] binread = "2.2.0" +dir_rpc = { version = "0.1.0", path = "../dir_rpc" } file_rpc = { version = "0.1.0", path = "../file_rpc" } fs_rpc = { version = "0.1.0", path = "../fs_rpc" } itertools = "0.13.0" diff --git a/src/ext2.rs b/src/ext2.rs index 84e48e2..2a8094e 100644 --- a/src/ext2.rs +++ b/src/ext2.rs @@ -40,7 +40,7 @@ impl Ext2 { }) } - fn path_inode>(&self, path: P) -> io::Result { + pub fn path_inode>(&self, path: P) -> io::Result { let path = path.as_ref(); let dentry = { self.dentry_cache.read().get(path).cloned() }; if let Some(dentry) = dentry { diff --git a/src/ext2/structs.rs b/src/ext2/structs.rs index 9305e8a..ecdee80 100644 --- a/src/ext2/structs.rs +++ b/src/ext2/structs.rs @@ -160,7 +160,8 @@ impl Inode { if let Some(block) = fs.ind_block_cache.read().get(&block_no) { return Ok(block.clone()); } - let block = fs.reader + let block = fs + .reader .read_block(block_no)? .into_inner() .iter() diff --git a/src/main.rs b/src/main.rs index 1e42839..abde40f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,12 +8,14 @@ use std::{ }; use ext2::Ext2; +use itertools::Itertools; use parking_lot::RwLock; #[derive(Clone)] struct Serv { mounts: Arc>>, files: Arc>>, + dirs: Arc, usize)>>>, } impl fs_rpc::Server for Serv { @@ -33,6 +35,17 @@ impl fs_rpc::Server for Serv { let res = Ok((None, (self.files.read().len() - 1) as u64)); res } + + fn open_dir(&self, path: &std::path::Path, mount_id: u64) -> Result<(Option, u64), ()> { + let mounts = self.mounts.read(); + let mount = &mounts[mount_id as usize]; + let entries = mount.read_dir(path).map_err(|_| ())?.map_ok(|x| x.file_name()).collect::, _>>().map_err(|_| ())?; + self.dirs + .write() + .push((entries, 0)); + let res = Ok((None, (self.dirs.read().len() - 1) as u64)); + res + } } impl file_rpc::Server for Serv { @@ -64,13 +77,31 @@ impl file_rpc::Server for Serv { } } +impl dir_rpc::Server for Serv { + fn next_entry(&self, fd: u64) -> Result, ()> { + let dirs = self.dirs.write(); + let &(ref entries, entry_no) = &dirs[fd as usize]; + if entry_no == entries.len() { + return Ok(None); + } + let entry = entries[entry_no].clone(); + std::mem::drop(dirs); + self.dirs.write()[fd as usize].1 += 1; + Ok(Some(entry)) + } + + fn close(&self, _fd: u64) {} +} + fn main() { let serv = Serv { mounts: Arc::new(RwLock::new(Vec::new())), files: Arc::new(RwLock::new(Vec::new())), + dirs: Arc::new(RwLock::new(Vec::new())), }; fs_rpc::register_server(Box::new(serv.clone())); - file_rpc::register_server(Box::new(serv)); + file_rpc::register_server(Box::new(serv.clone())); + dir_rpc::register_server(Box::new(serv)); let vfs_pid; loop { if let Some(pid) = syscalls::try_get_registered(0) {