/* * Copyright (c) 2022, Umut İnan Erdoğan <umutinanerdogan@pm.me> * * SPDX-License-Identifier: MPL-2.0 */ use ext2::fs::{sync::Synced, Ext2}; use ext2::sector::SectorSize; use ext2::volume::Volume; use super::errors::FsError; use super::{DirectoryEntry, FsNode, FsResult as Result, StorageDevice}; pub struct Ext2StorageDevice<S, V> where S: SectorSize, V: Volume<u8, S>, { fs: Synced<Ext2<S, V>>, } impl<S, V> Ext2StorageDevice<S, V> where S: SectorSize, V: Volume<u8, S>, { pub fn new(volume: V) -> Result<Self> { Ok(Self { fs: Synced::new(volume).map_err(|e| e.into())?, }) } } impl<S, V> StorageDevice for Ext2StorageDevice<S, V> where S: SectorSize + Send, V: Volume<u8, S> + Send, { fn read(&self, node: &FsNode, offset: usize, size: usize, buffer: &mut Vec<u8>) -> Result<()> { let inode = self .fs .inode_nth(node.inode as usize) .ok_or_else(|| FsError::InodeNotFound)?; // FIXME: I don't really know how Ext2 works, so for now we don't // support non-zero offsets and buffer sizes that don't match // the file length. We always read the whole file. if offset > 0 || size != inode.size() { Err(FsError::UnsupportedOperation)?; } inode.read_to_end(buffer).map_err(|e| e.into())?; Ok(()) } fn write(&self, _node: &FsNode, _offset: usize, _buffer: &[u8]) -> Result<()> { todo!() } fn read_dir(&self, _node: &FsNode, _index: usize) -> Result<DirectoryEntry> { todo!() } fn find_dir(&self, _node: &FsNode, _name: &str) -> Result<FsNode> { todo!() } } // fn load_fs() -> Arc<Mutex<Ext2<Size1024, Vec<u8>>>> { // let mut volume = Vec::new(); // volume.extend_from_slice(include_bytes!("../../../userland/root_fs/ext2.img")); // Arc::<Ext2<Size1024, _>>::new(volume).unwrap() // } // pub fn walk<S: SectorSize, V: Volume<u8, S>>( // fs: &Synced<Ext2<S, V>>, // inode: Inode<S, V>, // name: String, // ) { // if let Some(dir) = inode.directory() { // for entry in dir { // assert!(entry.is_ok()); // let entry = entry.unwrap(); // let entry_name = String::from_utf8_lossy(&entry.name); // println!("{}/{} => {}", name, entry_name, entry.inode,); // if entry_name != "." && entry_name != ".." { // walk( // fs, // fs.inode_nth(entry.inode).unwrap(), // format!("{}/{}", name, entry_name), // ); // } // } // } // }