feat: start VFS implementation

master
TheOddGarlic 2022-08-03 12:53:02 +03:00
parent 1b51942a12
commit 95004ae7aa
4 changed files with 110 additions and 4 deletions

View File

@ -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"

View File

@ -0,0 +1,9 @@
/*
* Copyright (c) 2022, Umut İnan Erdoğan <umutinanerdogan@pm.me>
*
* SPDX-License-Identifier: MPL-2.0
*/
pub enum FsError {
UnsupportedOperation,
}

View File

@ -1,3 +1,13 @@
/*
* Copyright (c) 2022, Umut İnan Erdoğan <umutinanerdogan@pm.me>
*
* 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<Handle, FsError>;
pub type FsCloseOperation = fn(fd: Handle) -> Result<(), FsError>;
pub type FsReadOperation = fn(fd: Handle, offset: u32, size: u32) -> Result<Box<[u8]>, 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<FsNode>, // used by mountpoints and symlinks
open: Option<FsOpenOperation>,
close: Option<FsCloseOperation>,
read: Option<FsReadOperation>,
write: Option<FsWriteOperation>,
// todo: permissions mask
// todo: owning user/group
// todo: readdir, finddir fn pointers
}
impl FsNode {
// TODO: make this take flags
fn open(&self) -> Result<Handle, FsError> {
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<Box<[u8]>, 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<spin::Mutex<Synced<Ext2<Size1024, Vec<u8>>>>> =
Lazy::new(|| spin::Mutex::new(load_fs()));

View File

@ -1,3 +1,9 @@
/*
* Copyright (c) 2022, Umut İnan Erdoğan <umutinanerdogan@pm.me>
*
* 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,