forked from AbleOS/ableos
91 lines
2.3 KiB
Rust
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()));
|
|
}
|
|
}
|
|
}
|
|
}
|