VFS: move stuff into a VirtualFileSystem struct

This commit is contained in:
TheOddGarlic 2022-08-06 21:38:30 +03:00
parent b01ce11fab
commit 70342c5f46
4 changed files with 67 additions and 36 deletions

View file

@ -13,7 +13,7 @@ use ext2::volume::Volume;
use crate::handle::{Handle, HandleResource}; use crate::handle::{Handle, HandleResource};
use super::errors::FsError; 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}; use super::{FsNode, FsResult as Result, StorageDevice};
pub struct Ext2StorageDevice<S, V> pub struct Ext2StorageDevice<S, V>
@ -43,7 +43,8 @@ where
Weak::new(), Weak::new(),
)); ));
add_fs_node(root.clone()); let mut vfs = VFS.lock();
vfs.add_fs_node(root.clone());
Ok(Self { Ok(Self {
fs, fs,
@ -93,9 +94,11 @@ where
.fs .fs
.inode_nth(entry.inode) .inode_nth(entry.inode)
.ok_or_else(|| FsError::InodeNotFound)?; .ok_or_else(|| FsError::InodeNotFound)?;
let entry_node_handle = let mut vfs = VFS.lock();
find_fs_node(entry.inode, self.device_handle).unwrap_or_else(|| { let entry_node_handle = vfs
add_fs_node(Arc::new(FsNode::new( .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()), ext2_type_to_fs_flags(entry_inode.type_perm()),
inode.size(), inode.size(),
entry.inode, entry.inode,
@ -117,6 +120,7 @@ where
.ok_or_else(|| FsError::InodeNotFound)?; .ok_or_else(|| FsError::InodeNotFound)?;
let dir = inode.directory().ok_or_else(|| FsError::NotADirectory)?; let dir = inode.directory().ok_or_else(|| FsError::NotADirectory)?;
let mut found_node = Err(FsError::NotFound); let mut found_node = Err(FsError::NotFound);
let mut vfs = VFS.lock();
for entry in dir { for entry in dir {
if entry.is_err() { if entry.is_err() {
continue; continue;
@ -124,17 +128,17 @@ where
let entry = entry.unwrap(); let entry = entry.unwrap();
if entry.file_name_string() == name { if entry.file_name_string() == name {
found_node = Ok( found_node = Ok(vfs
find_fs_node(entry.inode, self.device_handle).unwrap_or_else(|| { .find_fs_node(entry.inode, self.device_handle)
add_fs_node(Arc::new(FsNode::new( .unwrap_or_else(|| {
vfs.add_fs_node(Arc::new(FsNode::new(
ext2_type_to_fs_flags(inode.type_perm()), ext2_type_to_fs_flags(inode.type_perm()),
inode.size(), inode.size(),
entry.inode, entry.inode,
self.device_handle, self.device_handle,
Weak::new(), Weak::new(),
))) )))
}), }));
);
} }
} }

View file

@ -11,7 +11,7 @@ pub mod vfs;
use ::ext2::sector::Size1024; use ::ext2::sector::Size1024;
use alloc::sync::Arc; 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::{ use self::{
errors::FsError, errors::FsError,
@ -39,7 +39,10 @@ where
pub fn init() -> Result<()> { pub fn init() -> Result<()> {
let mut state = KERNEL_STATE.lock(); 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(()) Ok(())
} }
@ -53,8 +56,9 @@ fn load_fs() -> Result<Ext2StorageDevice<Size1024, Vec<u8>>> {
pub fn walk<S: Into<String>>(dir: Arc<FsNode>, path: S) { pub fn walk<S: Into<String>>(dir: Arc<FsNode>, path: S) {
let path = path.into(); let path = path.into();
if let Some(dir) = dir.directory() { if let Some(dir) = dir.directory() {
let mut vfs = VFS.lock();
for entry in dir { 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()); println!("{}/{} => {}", path, entry.name(), fs_node.inode());
trace!("{entry:#?}"); trace!("{entry:#?}");
if entry.name() != "." && entry.name() != ".." { if entry.name() != "." && entry.name() != ".." {

View file

@ -18,30 +18,52 @@ use crate::{
}; };
lazy_static! { lazy_static! {
static ref FS_NODES: Mutex<HashMap<Handle, Arc<FsNode>>> = Default::default(); pub static ref VFS: Mutex<VirtualFileSystem> = Default::default();
} }
pub fn add_fs_node(fs_node: Arc<FsNode>) -> Handle { pub struct VirtualFileSystem {
let handle = Handle::new(HandleResource::FsNode); fs_nodes: HashMap<Handle, Arc<FsNode>>,
let mut nodes = FS_NODES.lock(); root_node: Weak<FsNode>,
nodes.insert(handle, fs_node);
handle
} }
pub fn find_fs_node(inode: usize, device_handle: Handle) -> Option<Handle> { impl VirtualFileSystem {
let nodes = FS_NODES.lock(); pub fn init(&mut self, root_node: Arc<FsNode>) {
nodes.iter().find_map(|(handle, fs_node)| { self.root_node = Arc::downgrade(&root_node)
if fs_node.inode == inode && fs_node.device_handle == device_handle { }
Some(*handle)
} else { pub fn add_fs_node(&mut self, fs_node: Arc<FsNode>) -> Handle {
None 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<Handle> {
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<Arc<FsNode>> {
self.fs_nodes.get(&handle).cloned()
}
pub fn root_node(&self) -> Arc<FsNode> {
// 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<Arc<FsNode>> {
let nodes = FS_NODES.lock();
nodes.get(&handle).cloned()
} }
/// A VFS node, that can either be a file or a directory. /// A VFS node, that can either be a file or a directory.

View file

@ -7,13 +7,14 @@
use crate::arch::drivers::sysinfo::master; use crate::arch::drivers::sysinfo::master;
use crate::arch::interrupts::{reset_pit_for_cpu, set_pit_2}; use crate::arch::interrupts::{reset_pit_for_cpu, set_pit_2};
use crate::devices::pci::brute_force_scan; use crate::devices::pci::brute_force_scan;
use crate::filesystem::vfs::VFS;
use crate::systeminfo::{KERNEL_VERSION, RELEASE_TYPE}; use crate::systeminfo::{KERNEL_VERSION, RELEASE_TYPE};
use crate::time::fetch_time; use crate::time::fetch_time;
use crate::KERNEL_STATE; use crate::KERNEL_STATE;
use crate::{ use crate::{
arch::shutdown, arch::shutdown,
rhai_shell::KEYBUFF, rhai_shell::KEYBUFF,
vterm::Term, vterm::VTerm,
// wasm_jumploader::run_program, // wasm_jumploader::run_program,
}; };
use crate::{filesystem, KERNEL_STATE}; use crate::{filesystem, KERNEL_STATE};
@ -123,13 +124,13 @@ pub fn scratchpad() {
); );
let root = { let root = {
let state = KERNEL_STATE.lock(); let vfs = VFS.lock();
state.storage_devices.iter().next().unwrap().1.root_node() vfs.root_node()
}; };
filesystem::walk(root, ""); filesystem::walk(root, "");
// real_shell(); real_shell();
} }
pub fn acpi() { pub fn acpi() {