diff --git a/ableos/Cargo.toml b/ableos/Cargo.toml index 665889b5..a50c735c 100644 --- a/ableos/Cargo.toml +++ b/ableos/Cargo.toml @@ -58,7 +58,7 @@ test-args = [ [dependencies] lazy_static = { version = "1.4.0", features = ["spin_no_std"] } qrcode = { path = "../qrcode-rust" } -bitflags = "1.2.1" +bitflags = "1.3" lliw = "0.2.0" spin = "0.9" pretty-hex = "0.2.1" diff --git a/ableos/src/filesystem/errors.rs b/ableos/src/filesystem/errors.rs new file mode 100644 index 00000000..01b40a02 --- /dev/null +++ b/ableos/src/filesystem/errors.rs @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2022, Umut İnan Erdoğan + * + * SPDX-License-Identifier: MPL-2.0 + */ + +pub enum FsError { + UnsupportedOperation, +} diff --git a/ableos/src/filesystem/mod.rs b/ableos/src/filesystem/mod.rs index b712e683..dfec8916 100644 --- a/ableos/src/filesystem/mod.rs +++ b/ableos/src/filesystem/mod.rs @@ -1,3 +1,13 @@ +/* + * Copyright (c) 2022, Umut İnan Erdoğan + * + * SPDX-License-Identifier: MPL-2.0 + */ + +pub mod errors; + +use alloc::rc::Weak; +use bitflags::bitflags; use ext2::{ fs::{ sync::{Inode, Synced}, @@ -8,6 +18,84 @@ use ext2::{ }; use spin::Lazy; +use crate::handle::Handle; + +use self::errors::FsError; + +pub type FsOpenOperation = fn(/* TODO: flags */) -> Result; +pub type FsCloseOperation = fn(fd: Handle) -> Result<(), FsError>; +pub type FsReadOperation = fn(fd: Handle, offset: u32, size: u32) -> Result, FsError>; +pub type FsWriteOperation = fn(fd: Handle, offset: u32, buffer: Box<[u8]>) -> Result<(), FsError>; + +/// A VFS node, that can either be a file or a directory. +pub struct FsNode { + // FIXME: move the file name into the directory listing to implement hard + // links + name: String, + flags: FsNodeFlags, + length: u32, // in bytes + inode: u32, // implementation specific identifier for the node + device_handle: Handle, // uniquely assigned device handle + ptr: Weak, // used by mountpoints and symlinks + open: Option, + close: Option, + read: Option, + write: Option, + // todo: permissions mask + // todo: owning user/group + // todo: readdir, finddir fn pointers +} + +impl FsNode { + // TODO: make this take flags + fn open(&self) -> Result { + if let Some(open) = self.open { + open() + } else { + Err(FsError::UnsupportedOperation) + } + } + + fn close(&self, fd: Handle) -> Result<(), FsError> { + if let Some(close) = self.close { + close(fd) + } else { + Err(FsError::UnsupportedOperation) + } + } + + fn read(&self, fd: Handle, offset: u32, size: u32) -> Result, FsError> { + if let Some(read) = self.read { + read(fd, offset, size) + } else { + Err(FsError::UnsupportedOperation) + } + } + + fn write(&self, fd: Handle, offset: u32, buffer: Box<[u8]>) -> Result<(), FsError> { + if let Some(write) = self.write { + write(fd, offset, buffer) + } else { + Err(FsError::UnsupportedOperation) + } + } +} + +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 + /// M is set if the node is an active mount point + pub struct FsNodeFlags: u8 { + const FILE = 0b00000000; + const DIRECTORY = 0b00000001; + const SYMBOLIC_LINK = 0b00000010; + const MOUNT_POINT = 0b00000100; + } +} + pub static FILE_SYSTEM: Lazy>>>> = Lazy::new(|| spin::Mutex::new(load_fs())); diff --git a/ableos/src/handle.rs b/ableos/src/handle.rs index dda62396..fb9f31db 100644 --- a/ableos/src/handle.rs +++ b/ableos/src/handle.rs @@ -1,3 +1,9 @@ +/* + * Copyright (c) 2022, Umut İnan Erdoğan + * + * SPDX-License-Identifier: MPL-2.0 + */ + //! A handle is a u128 with a set of permissions //! and a resource connected to it @@ -14,8 +20,9 @@ pub struct BinaryData { pub enum HandleResource { Channel, Socket, - BinaryData, + StorageDevice, + FileDescriptor, } #[derive(Debug, Eq, Hash, PartialEq, Clone, Copy)] @@ -30,16 +37,18 @@ impl Display for Handle { match &self.res { HandleResource::Channel => write!(f, "-Channel")?, HandleResource::BinaryData => write!(f, "-Binary")?, - Socket => write!(f, "-Socket")?, + HandleResource::Socket => write!(f, "-Socket")?, + HandleResource::StorageDevice => write!(f, "-StorageDevice")?, + HandleResource::FileDescriptor => write!(f, "-FileDescriptor")?, } Ok(()) } } -use crate::handle::HandleResource::*; impl Handle { pub fn new(htype: HandleResource) -> Self { + // FIXME: check if inner collides Self { inner: generate_process_pass(), res: htype,