diff --git a/ableos/src/filesystem/errors.rs b/ableos/src/filesystem/errors.rs index 827bd956..db6c8874 100644 --- a/ableos/src/filesystem/errors.rs +++ b/ableos/src/filesystem/errors.rs @@ -5,8 +5,9 @@ */ pub enum FsError { - UnsupportedOperation, + InodeNotFound, InvalidDevice, + UnsupportedOperation, } impl Into for ext2::error::Error { @@ -15,9 +16,16 @@ impl Into for ext2::error::Error { ext2::error::Error::Other(_) => todo!(), ext2::error::Error::BadMagic { magic: _ } => todo!(), ext2::error::Error::OutOfBounds { index: _ } => todo!(), - ext2::error::Error::AddressOutOfBounds { sector: _, offset: _, size: _ } => todo!(), - ext2::error::Error::BadBlockGroupCount { by_blocks: _, by_inodes: _ } => todo!(), - ext2::error::Error::InodeNotFound { inode: _ } => todo!(), + ext2::error::Error::AddressOutOfBounds { + sector: _, + offset: _, + size: _, + } => todo!(), + ext2::error::Error::BadBlockGroupCount { + by_blocks: _, + by_inodes: _, + } => todo!(), + ext2::error::Error::InodeNotFound { inode: _ } => FsError::InodeNotFound, ext2::error::Error::NotADirectory { inode: _, name: _ } => todo!(), ext2::error::Error::NotAbsolute { name: _ } => todo!(), ext2::error::Error::NotFound { name: _ } => todo!(), diff --git a/ableos/src/filesystem/ext2.rs b/ableos/src/filesystem/ext2.rs index f1f071dc..b1ad1c98 100644 --- a/ableos/src/filesystem/ext2.rs +++ b/ableos/src/filesystem/ext2.rs @@ -4,10 +4,11 @@ * SPDX-License-Identifier: MPL-2.0 */ -use ext2::fs::Ext2; +use ext2::fs::{sync::Synced, Ext2}; use ext2::sector::SectorSize; use ext2::volume::Volume; +use super::errors::FsError; use super::{FsResult as Result, StorageDevice}; pub struct Ext2StorageDevice @@ -15,7 +16,7 @@ where S: SectorSize, V: Volume, { - fs: Ext2, + fs: Synced>, } impl Ext2StorageDevice @@ -25,7 +26,7 @@ where { pub fn new(volume: V) -> Result { Ok(Self { - fs: Ext2::new(volume).map_err(|e| e.into())?, + fs: Synced::new(volume).map_err(|e| e.into())?, }) } } @@ -36,6 +37,11 @@ where V: Volume + Send, { fn open(&self, node: &super::FsNode /* TODO: flags */) -> Result { + let inode = self + .fs + .inode_nth(node.inode as usize) + .ok_or_else(|| FsError::InodeNotFound)?; + todo!() } diff --git a/ableos/src/filesystem/mod.rs b/ableos/src/filesystem/mod.rs index 1f661c64..f62122c7 100644 --- a/ableos/src/filesystem/mod.rs +++ b/ableos/src/filesystem/mod.rs @@ -30,14 +30,19 @@ where } /// A VFS node, that can either be a file or a directory. +/// +/// VFS nodes are created whenever a file that doesn't have an open VFS node is +/// opened. When there are no open file descriptors to a file, the associated +/// VFS node is dropped. pub struct FsNode { flags: FsNodeFlags, - length: u32, // in bytes - inode: u32, // implementation specific identifier for the node + length: u32, // in bytes + fd_count: u32, // count of open file descriptors + inode: u32, // implementation specific identifier for the node device_handle: Handle, // uniquely assigned device handle - ptr: Weak, // used by mountpoints and symlinks - // todo: permissions mask - // todo: owning user/group + ptr: Weak, // used by mountpoints and symlinks + // todo: permissions mask + // todo: owning user/group } impl FsNode { @@ -51,12 +56,14 @@ impl FsNode { Self { flags, length, + fd_count: 0, inode, device_handle, ptr, } } + /// This method opens a new file descriptor for this VFS node. // TODO: make this take flags pub fn open(&self) -> Result { let state = KERNEL_STATE.lock(); @@ -67,6 +74,8 @@ impl FsNode { device.open(self) } + /// This method is for closing the VFS node, which is done when no open file + /// descriptors for this file are left. pub fn close(&self) -> Result<()> { let state = KERNEL_STATE.lock(); let device = state @@ -76,6 +85,9 @@ impl FsNode { device.close(self) } + /// This method reads from the VFS node without opening a new file + /// descriptor. This is intended to be used internally, if you're trying to + /// read a file then you probably want to read from a file descriptor. pub fn read(&self, offset: u32, size: u32) -> Result> { let state = KERNEL_STATE.lock(); let device = state @@ -85,6 +97,9 @@ impl FsNode { device.read(self, offset, size) } + /// This method writes to the VFS node without opening a new file + /// descriptor. This is intended to be used internally, if you're trying to + /// write to a file then you probably want to write to a file descriptor. pub fn write(&self, offset: u32, buffer: Box<[u8]>) -> Result<()> { let state = KERNEL_STATE.lock(); let device = state @@ -115,7 +130,7 @@ impl FsNode { bitflags! { /// Flags associated with VFS nodes. - /// + /// /// 0x00000MST /// T is set to 0 for files, 1 for directories /// S is set when the node is a symbolic link @@ -128,6 +143,9 @@ bitflags! { } } +/// A file descriptor. +pub struct FileDescriptor {} + pub struct DirectoryEntry { name: String, inode: u32, diff --git a/ableos/src/kernel_state.rs b/ableos/src/kernel_state.rs index 25b27f48..29fcda5f 100644 --- a/ableos/src/kernel_state.rs +++ b/ableos/src/kernel_state.rs @@ -1,7 +1,10 @@ use hashbrown::HashMap; use spin::Lazy; -use crate::{handle::{Handle, HandleResource}, filesystem::StorageDevice}; +use crate::{ + filesystem::StorageDevice, + handle::{Handle, HandleResource}, +}; pub static KERNEL_STATE: Lazy> = Lazy::new(|| spin::Mutex::new(KernelInternalState::new())); @@ -26,7 +29,8 @@ impl KernelInternalState { } pub fn add_storage_device(&mut self, device: impl StorageDevice + Send + 'static) { - self.storage_devices.insert(Handle::new(HandleResource::StorageDevice), Box::new(device)); + self.storage_devices + .insert(Handle::new(HandleResource::StorageDevice), Box::new(device)); } pub fn get_storage_device(&self, handle: Handle) -> Option<&dyn StorageDevice> { diff --git a/ableos/src/scratchpad.rs b/ableos/src/scratchpad.rs index 00056064..b7b7fe6e 100644 --- a/ableos/src/scratchpad.rs +++ b/ableos/src/scratchpad.rs @@ -11,7 +11,9 @@ use crate::systeminfo::{KERNEL_VERSION, RELEASE_TYPE}; use crate::time::fetch_time; use crate::KERNEL_STATE; use crate::{ - arch::shutdown, rhai_shell::KEYBUFF, vterm::Term, + arch::shutdown, + rhai_shell::KEYBUFF, + vterm::Term, // wasm_jumploader::run_program, }; @@ -231,19 +233,12 @@ pub fn command_parser(user: String, command: String) { // } // } -<<<<<<< HEAD - "echo" => match conf_args.1.arguments.get("p") { - Some(path) => echo_file(path.to_string(), fs), + // "echo" => match conf_args.1.arguments.get("p") { + // Some(path) => echo_file(path.to_string(), fs), - None => println!("No path provided"), - }, - "test" => {} -======= - // "echo" => { - // echo_file(iter.next().unwrap().to_string(), fs); + // None => println!("No path provided"), // } ->>>>>>> 5149f26... vfs: move operations into trait StorageDevice, hold StorageDevices in KERNEL_STATE - + "test" => {} "quit" => shutdown(), _ => { @@ -263,23 +258,8 @@ pub fn command_parser(user: String, command: String) { // Ok(file) => file, // Err(error) => { // trace!("{:?}", error); - println!("No such binary: {}", bin_name); - error!("No such binary: {}", bin_name); - return; -<<<<<<< HEAD - } - } - } - } - }; - - let mut binary = vec![]; - file.read_to_end(&mut binary).unwrap(); - - // let args = iter.collect::>(); - // println!("{:?}", args); - run_program(&binary); -======= + println!("No such binary: {}", bin_name); + error!("No such binary: {}", bin_name); // } // } // } @@ -292,7 +272,6 @@ pub fn command_parser(user: String, command: String) { // let args = iter.collect::>(); // println!("{:?}", args); // run_program(&binary); ->>>>>>> 5149f26... vfs: move operations into trait StorageDevice, hold StorageDevices in KERNEL_STATE } } }