VFS: Updated the API and worked on some implementation

This commit is contained in:
able 2023-09-13 05:31:35 -05:00
parent a7414ca01a
commit 6df69e2f1a
5 changed files with 161 additions and 15 deletions

42
drivers/vfs/src/cache.rs Normal file
View file

@ -0,0 +1,42 @@
pub struct Cache {
// A limit on how many open files can be in this cache
// Usefull to prevent hundreds of processes caching thousands of files
// 0 == No Limit
file_id_limit: u64,
// Total bytes allowed to be cached before a file is pushed out of the cache
total_byte_size: u64,
current_byte_size: u64,
cache: Vec<(FileID, Vec<u8>)>,
}
impl Cache {
fn default() -> Self {
Self {
file_id_limit: 1024,
total_byte_size: 1024 * 16,
current_byte_size: 0,
cache: Vec::new(),
}
}
fn recalculate_cache(&mut self) {
let mut current: u64 = 0;
for (_, file) in &self.cache {
current += file.len() as u64;
}
self.current_byte_size = current;
}
}
#[test]
fn recalc_cache_test() {
let mut cache = Cache::default();
let mut temp_file_vec: Vec<u8> = Vec::new();
for x in 0u64..=10 {
temp_file_vec.push(x.try_into().unwrap());
let file = (x, temp_file_vec.clone());
cache.cache.push(file);
}
cache.recalculate_cache();
assert_eq!(cache.current_byte_size, 66);
}

View file

@ -1,18 +1,105 @@
// #![no_std]
#![feature(async_fn_in_trait)]
use std::path::Path;
// use std::prelude::rust_2021::alloc;
pub mod cache;
extern crate alloc;
use alloc::vec::Vec;
pub type Path = String;
fn main() {}
fn main() {
let vfs = VFS::new();
// TODO: load config for the vfs
pub type File = Vec<u8>;
// TODO: implement better VFS api
pub trait FileIO {
fn read(file: &mut File, file_address: u64, read_length: u64);
fn write(file: &mut File, file_address: u64, dest_ptr: u64, src_len: usize);
fn open(path: Path);
fn close(file: &mut File);
// advertise the VFS service
// wait on proccesses to subscribe and send messages
}
// NOTE: in the implementation this should be a basevalue of some randomized value to
// prevent the ability to check how many files are open on the system
pub type FileID = u64;
pub trait FileIO {
// Store the FileID in the VFS to allow multiple programs to have a FileID without conflicting
fn s_open(path: Path) -> Result<FileID, FileIOError>;
async fn a_open(path: Path) -> Result<FileID, FileIOError>;
// Close the file and flush changes to disk
fn s_close(file_id: FileID) -> Result<(), FileIOError>;
async fn a_close(file_id: FileID) -> Result<(), FileIOError>;
// Offset into the file to allow for things like reading a specific value
// Length from the offset
fn s_read(file_id: FileID, offset: usize, length: u64) -> Result<Vec<u8>, FileIOError>;
async fn a_read(file_id: FileID, offset: usize, length: u64) -> Result<Vec<u8>, FileIOError>;
// Offset into the file to allow for things like reading a specific value
fn s_write(file_id: FileID, offset: usize, data: Vec<u8>) -> Result<(), FileIOError>;
async fn a_write(file_id: FileID, offset: usize, data: Vec<u8>) -> Result<(), FileIOError>;
}
pub enum FileIOError {
NoMountPoint,
}
pub struct MountPoint {
mount: Path,
// Use this to send the file requests to the right filesystem driver
filesystem_proc_id: u64,
}
pub struct VFS {
// If a file is used twice move it from first cache to second cache
// This is under the assumption that if you write to a file twice you will write again
first_layer: Cache,
second_layer: Cache,
mount_point_list: Vec<MountPoint>,
}
impl VFS {
fn new() -> Self {
Self {
first_layer: Cache::default(),
second_layer: Cache::default(),
mount_point_list: Vec::new(),
}
}
fn resolve_mountpoint(self, path: Path) -> Result<MountPoint, FileIOError> {
return Err(FileIOError::NoMountPoint);
}
}
impl FileIO for VFS {
fn s_open(path: Path) -> Result<FileID, FileIOError> {
// Break up the path into a mountpoint and a path fragment
todo!()
}
async fn a_open(path: Path) -> Result<FileID, FileIOError> {
todo!()
}
fn s_close(file_id: FileID) -> Result<(), FileIOError> {
todo!()
}
async fn a_close(file_id: FileID) -> Result<(), FileIOError> {
todo!()
}
fn s_read(file_id: FileID, offset: usize, length: u64) -> Result<Vec<u8>, FileIOError> {
todo!()
}
async fn a_read(file_id: FileID, offset: usize, length: u64) -> Result<Vec<u8>, FileIOError> {
todo!()
}
fn s_write(file_id: FileID, offset: usize, data: Vec<u8>) -> Result<(), FileIOError> {
todo!()
}
async fn a_write(file_id: FileID, offset: usize, data: Vec<u8>) -> Result<(), FileIOError> {
todo!()
}
}
pub enum FileError {}

View file

@ -5,7 +5,7 @@ type Handle = i64;
#[repr(C)]
pub struct OSString {
pub address: i32,
pub length: i32,
pub length: i32,
}
extern "C" {
@ -21,10 +21,10 @@ pub enum ExternErrors {
#[repr(C)]
pub struct Result<T> {
pub ok: T,
pub ok: T,
pub err: ExternErrors,
}
pub struct Path {
parts: String,
parts: OSString,
}

View file

@ -0,0 +1,16 @@
use alloc::alloc::{GlobalAlloc, Layout};
struct MyAllocator;
unsafe impl GlobalAlloc for MyAllocator {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
panic!();
}
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
panic!();
}
}
#[global_allocator]
static GLOBAL: MyAllocator = MyAllocator;

View file

@ -9,6 +9,7 @@ pub mod env;
pub mod exit;
pub mod io;
pub mod allocator;
#[cfg(not(test))]
pub mod panic;
@ -63,7 +64,7 @@ pub struct LocationInFile<'a> {
// TODO: replace &str with ableOS path
file_path: &'a str,
line: u16,
line: u16,
column: u16,
}
impl<'a> Display for LocationInFile<'a> {