From 70342c5f46cc90e700bd02b3096d39493c3ae70a Mon Sep 17 00:00:00 2001 From: TheOddGarlic Date: Sat, 6 Aug 2022 21:38:30 +0300 Subject: [PATCH] VFS: move stuff into a VirtualFileSystem struct --- ableos/src/filesystem/ext2.rs | 24 ++++++++------ ableos/src/filesystem/mod.rs | 10 ++++-- ableos/src/filesystem/vfs.rs | 60 ++++++++++++++++++++++++----------- ableos/src/scratchpad.rs | 9 +++--- 4 files changed, 67 insertions(+), 36 deletions(-) diff --git a/ableos/src/filesystem/ext2.rs b/ableos/src/filesystem/ext2.rs index 5fd9928be..1140ecdb5 100644 --- a/ableos/src/filesystem/ext2.rs +++ b/ableos/src/filesystem/ext2.rs @@ -13,7 +13,7 @@ use ext2::volume::Volume; use crate::handle::{Handle, HandleResource}; use super::errors::FsError; -use super::vfs::{add_fs_node, find_fs_node, DirectoryEntry, FsFlags}; +use super::vfs::{DirectoryEntry, FsFlags, VFS}; use super::{FsNode, FsResult as Result, StorageDevice}; pub struct Ext2StorageDevice @@ -43,7 +43,8 @@ where Weak::new(), )); - add_fs_node(root.clone()); + let mut vfs = VFS.lock(); + vfs.add_fs_node(root.clone()); Ok(Self { fs, @@ -93,9 +94,11 @@ where .fs .inode_nth(entry.inode) .ok_or_else(|| FsError::InodeNotFound)?; - let entry_node_handle = - find_fs_node(entry.inode, self.device_handle).unwrap_or_else(|| { - add_fs_node(Arc::new(FsNode::new( + let mut vfs = VFS.lock(); + let entry_node_handle = vfs + .find_fs_node(entry.inode, self.device_handle) + .unwrap_or_else(|| { + vfs.add_fs_node(Arc::new(FsNode::new( ext2_type_to_fs_flags(entry_inode.type_perm()), inode.size(), entry.inode, @@ -117,6 +120,7 @@ where .ok_or_else(|| FsError::InodeNotFound)?; let dir = inode.directory().ok_or_else(|| FsError::NotADirectory)?; let mut found_node = Err(FsError::NotFound); + let mut vfs = VFS.lock(); for entry in dir { if entry.is_err() { continue; @@ -124,17 +128,17 @@ where let entry = entry.unwrap(); if entry.file_name_string() == name { - found_node = Ok( - find_fs_node(entry.inode, self.device_handle).unwrap_or_else(|| { - add_fs_node(Arc::new(FsNode::new( + found_node = Ok(vfs + .find_fs_node(entry.inode, self.device_handle) + .unwrap_or_else(|| { + vfs.add_fs_node(Arc::new(FsNode::new( ext2_type_to_fs_flags(inode.type_perm()), inode.size(), entry.inode, self.device_handle, Weak::new(), ))) - }), - ); + })); } } diff --git a/ableos/src/filesystem/mod.rs b/ableos/src/filesystem/mod.rs index bc3820164..8f25dd0ac 100644 --- a/ableos/src/filesystem/mod.rs +++ b/ableos/src/filesystem/mod.rs @@ -11,7 +11,7 @@ pub mod vfs; use ::ext2::sector::Size1024; use alloc::sync::Arc; -use crate::{filesystem::vfs::fs_node, handle::Handle, KERNEL_STATE}; +use crate::{filesystem::vfs::VFS, handle::Handle, KERNEL_STATE}; use self::{ errors::FsError, @@ -39,7 +39,10 @@ where pub fn init() -> Result<()> { let mut state = KERNEL_STATE.lock(); - state.add_storage_device(load_fs()?); + let mut vfs = VFS.lock(); + let fs = load_fs()?; + vfs.init(fs.root_node()); + state.add_storage_device(fs); Ok(()) } @@ -53,8 +56,9 @@ fn load_fs() -> Result>> { pub fn walk>(dir: Arc, path: S) { let path = path.into(); if let Some(dir) = dir.directory() { + let mut vfs = VFS.lock(); for entry in dir { - let fs_node = fs_node(entry.node()).unwrap(); + let fs_node = vfs.fs_node(entry.node()).unwrap(); println!("{}/{} => {}", path, entry.name(), fs_node.inode()); trace!("{entry:#?}"); if entry.name() != "." && entry.name() != ".." { diff --git a/ableos/src/filesystem/vfs.rs b/ableos/src/filesystem/vfs.rs index 00624d5a2..5d6b4aec9 100644 --- a/ableos/src/filesystem/vfs.rs +++ b/ableos/src/filesystem/vfs.rs @@ -18,30 +18,52 @@ use crate::{ }; lazy_static! { - static ref FS_NODES: Mutex>> = Default::default(); + pub static ref VFS: Mutex = Default::default(); } -pub fn add_fs_node(fs_node: Arc) -> Handle { - let handle = Handle::new(HandleResource::FsNode); - let mut nodes = FS_NODES.lock(); - nodes.insert(handle, fs_node); - handle +pub struct VirtualFileSystem { + fs_nodes: HashMap>, + root_node: Weak, } -pub fn find_fs_node(inode: usize, device_handle: Handle) -> Option { - let nodes = FS_NODES.lock(); - nodes.iter().find_map(|(handle, fs_node)| { - if fs_node.inode == inode && fs_node.device_handle == device_handle { - Some(*handle) - } else { - None +impl VirtualFileSystem { + pub fn init(&mut self, root_node: Arc) { + self.root_node = Arc::downgrade(&root_node) + } + + pub fn add_fs_node(&mut self, fs_node: Arc) -> Handle { + let handle = Handle::new(HandleResource::FsNode); + self.fs_nodes.insert(handle, fs_node); + handle + } + + pub fn find_fs_node(&mut self, inode: usize, device_handle: Handle) -> Option { + self.fs_nodes.iter().find_map(|(handle, fs_node)| { + if fs_node.inode == inode && fs_node.device_handle == device_handle { + Some(*handle) + } else { + None + } + }) + } + + pub fn fs_node(&mut self, handle: Handle) -> Option> { + self.fs_nodes.get(&handle).cloned() + } + + pub fn root_node(&self) -> Arc { + // okay to unwrap since this should never be called before init + self.root_node.upgrade().unwrap() + } +} + +impl Default for VirtualFileSystem { + fn default() -> Self { + Self { + fs_nodes: HashMap::new(), + root_node: Weak::new(), } - }) -} - -pub fn fs_node(handle: Handle) -> Option> { - let nodes = FS_NODES.lock(); - nodes.get(&handle).cloned() + } } /// A VFS node, that can either be a file or a directory. diff --git a/ableos/src/scratchpad.rs b/ableos/src/scratchpad.rs index f545120b9..8cbf600e5 100644 --- a/ableos/src/scratchpad.rs +++ b/ableos/src/scratchpad.rs @@ -7,13 +7,14 @@ use crate::arch::drivers::sysinfo::master; use crate::arch::interrupts::{reset_pit_for_cpu, set_pit_2}; use crate::devices::pci::brute_force_scan; +use crate::filesystem::vfs::VFS; 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, + vterm::VTerm, // wasm_jumploader::run_program, }; use crate::{filesystem, KERNEL_STATE}; @@ -123,13 +124,13 @@ pub fn scratchpad() { ); let root = { - let state = KERNEL_STATE.lock(); - state.storage_devices.iter().next().unwrap().1.root_node() + let vfs = VFS.lock(); + vfs.root_node() }; filesystem::walk(root, ""); - // real_shell(); + real_shell(); } pub fn acpi() {