ableos/ableos/src/filesystem/mod.rs

91 lines
2.3 KiB
Rust

/*
* Copyright (c) 2022, Umut İnan Erdoğan <umutinanerdogan@pm.me>
*
* SPDX-License-Identifier: MPL-2.0
*/
pub mod errors;
pub mod ext2;
pub mod vfs;
use ::ext2::sector::Size1024;
use alloc::sync::Arc;
use crate::{filesystem::vfs::VFS, handle::Handle, KERNEL_STATE};
use self::{
errors::FsError,
ext2::Ext2StorageDevice,
vfs::{DirectoryEntry, FsNode, VirtualFileSystem},
};
use FsResult as Result;
pub type FsResult<T> = core::result::Result<T, FsError>;
/// The methods on this trait are to be used internally.
pub trait StorageDevice
where
Self: Send,
{
fn read(&self, node: &FsNode, offset: usize, size: usize, buffer: &mut Vec<u8>) -> Result<()>;
fn write(&self, node: &FsNode, offset: usize, buffer: &[u8]) -> Result<()>;
fn read_dir(&self, node: &FsNode, index: usize) -> Result<DirectoryEntry>;
fn find_dir(&self, vfs: &mut VirtualFileSystem, node: &FsNode, name: &str) -> Result<Handle>;
// TODO: flush to disk
fn root(&self) -> Handle;
fn device_handle(&self) -> Handle;
}
pub fn init() -> Result<()> {
let mut state = KERNEL_STATE.lock();
let fs = load_fs()?;
let mut vfs = VFS.lock();
vfs.set_root(fs.root())?;
state.add_storage_device(fs);
Ok(())
}
fn load_fs() -> Result<Ext2StorageDevice<Size1024, Vec<u8>>> {
let mut volume = Vec::new();
volume.extend_from_slice(include_bytes!("../../../userland/root_fs/ext2.img"));
Ext2StorageDevice::new(volume)
}
pub fn tree(path: &str) -> Result<()> {
let dir = {
let mut vfs = VFS.lock();
let handle = vfs.resolve(path)?;
vfs.fs_node(handle).ok_or_else(|| FsError::NotFound)?
};
tree_inner(
dir,
if path.starts_with('/') {
&path[1..]
} else {
path
},
);
Ok(())
}
fn tree_inner<S: Into<String>>(dir: Arc<FsNode>, path: S) {
let path = path.into();
if let Some(dir) = dir.directory() {
for entry in dir {
let fs_node = {
let vfs = VFS.lock();
vfs.fs_node(entry.node()).unwrap()
};
println!("{}/{} => {}", path, entry.name(), fs_node.inode());
trace!("{entry:#?}");
if entry.name() != "." && entry.name() != ".." {
tree_inner(fs_node, format!("{}/{}", path, entry.name()));
}
}
}
}