Ext2: find_dir implementation

master
TheOddGarlic 2022-08-04 13:56:37 +03:00
parent 379b4deb91
commit e6aa9a3651
5 changed files with 73 additions and 18 deletions

View File

@ -10,6 +10,7 @@ pub enum FsError {
InvalidDevice,
IsDirectory,
NotADirectory,
NotFound,
UnsupportedOperation,
}
@ -31,7 +32,7 @@ impl Into<FsError> for ext2::error::Error {
ext2::error::Error::InodeNotFound { inode: _ } => FsError::InodeNotFound,
ext2::error::Error::NotADirectory { inode: _, name: _ } => FsError::NotADirectory,
ext2::error::Error::NotAbsolute { name: _ } => todo!(),
ext2::error::Error::NotFound { name: _ } => todo!(),
ext2::error::Error::NotFound { name: _ } => FsError::NotFound,
}
}
}

View File

@ -4,12 +4,16 @@
* SPDX-License-Identifier: MPL-2.0
*/
use alloc::sync::Weak;
use ext2::fs::{sync::Synced, Ext2};
use ext2::sector::SectorSize;
use ext2::sys::inode::TypePerm;
use ext2::volume::Volume;
use crate::handle::Handle;
use super::errors::FsError;
use super::{DirectoryEntry, FsNode, FsResult as Result, StorageDevice};
use super::{DirectoryEntry, FsFlags, FsNode, FsResult as Result, StorageDevice};
pub struct Ext2StorageDevice<S, V>
where
@ -17,6 +21,7 @@ where
V: Volume<u8, S>,
{
fs: Synced<Ext2<S, V>>,
device_handle: Handle,
}
impl<S, V> Ext2StorageDevice<S, V>
@ -24,9 +29,10 @@ where
S: SectorSize,
V: Volume<u8, S>,
{
pub fn new(volume: V) -> Result<Self> {
pub fn new(volume: V, device_handle: Handle) -> Result<Self> {
Ok(Self {
fs: Synced::new(volume).map_err(|e| e.into())?,
device_handle,
})
}
}
@ -63,18 +69,64 @@ where
.inode_nth(node.inode as usize)
.ok_or_else(|| FsError::InodeNotFound)?;
let mut dir = inode.directory().ok_or_else(|| FsError::NotADirectory)?;
let entry = dir.nth(index)
let entry = dir
.nth(index)
.ok_or_else(|| FsError::InodeNotFound)?
.map_err(|e| e.into())?;
Ok(DirectoryEntry::new(entry.file_name_string(), entry.inode))
}
fn find_dir(&self, _node: &FsNode, _name: &str) -> Result<FsNode> {
todo!()
fn find_dir(&self, node: &FsNode, name: &str) -> Result<FsNode> {
let inode = self
.fs
.inode_nth(node.inode as usize)
.ok_or_else(|| FsError::InodeNotFound)?;
let dir = inode.directory().ok_or_else(|| FsError::NotADirectory)?;
let mut found_node = Err(FsError::NotFound);
for entry in dir {
if entry.is_err() {
continue;
}
let entry = entry.unwrap();
if entry.file_name_string() == name {
let inode = self
.fs
.inode_nth(entry.inode as usize)
.ok_or_else(|| FsError::InodeNotFound)?;
let flags = ext2_type_to_fs_flags(inode.type_perm());
found_node = Ok(FsNode::new(
flags,
inode.size(),
entry.inode,
self.device_handle,
Weak::new(),
))
}
}
found_node
}
}
fn ext2_type_to_fs_flags(type_perm: TypePerm) -> FsFlags {
let is_directory = type_perm & TypePerm::DIRECTORY == TypePerm::DIRECTORY;
let is_symlink = type_perm & TypePerm::SYMLINK == TypePerm::SYMLINK;
let t = if is_directory {
FsFlags::DIRECTORY
} else {
FsFlags::FILE
};
let s = if is_symlink {
FsFlags::SYMBOLIC_LINK
} else {
FsFlags::empty()
};
t | s
}
// fn load_fs() -> Arc<Mutex<Ext2<Size1024, Vec<u8>>>> {
// let mut volume = Vec::new();
// volume.extend_from_slice(include_bytes!("../../../userland/root_fs/ext2.img"));

View File

@ -9,7 +9,7 @@ pub mod ext2;
use core::cmp;
use alloc::sync::{Weak, Arc};
use alloc::sync::{Arc, Weak};
use bitflags::bitflags;
use crate::{handle::Handle, KERNEL_STATE};
@ -140,9 +140,9 @@ impl Drop for FsNode {
bitflags! {
/// Flags associated with VFS nodes and file descriptors
///
/// 0x00000MST
/// T is set to 0 for files, 1 for directories
/// S is set when the file is a symbolic link
/// 0x00000MST \
/// T is set to 0 for files, 1 for directories \
/// S is set when the file is a symbolic link \
/// M is set if the file is an active mount point
pub struct FsFlags: u8 {
const FILE = 0b00000000;
@ -159,9 +159,6 @@ pub struct DirectoryEntry {
impl DirectoryEntry {
fn new(name: String, inode: usize) -> Self {
Self {
name,
inode,
}
Self { name, inode }
}
}

View File

@ -3,7 +3,7 @@ use hashbrown::HashMap;
use spin::Lazy;
use crate::{
filesystem::{StorageDevice, FsNode},
filesystem::{FsNode, StorageDevice},
handle::{Handle, HandleResource},
};
@ -81,8 +81,6 @@ pub struct FileTableEntry {
impl FileTableEntry {
fn new(fs_node: Arc<FsNode>) -> Self {
Self {
fs_node
}
Self { fs_node }
}
}

View File

@ -1,5 +1,7 @@
//!
use crate::sys::inode::TypePerm;
use {
super::Ext2,
alloc::{
@ -543,6 +545,11 @@ impl<S: SectorSize, V: Volume<u8, S>> Inode<S, V> {
pub fn size(&self) -> usize {
self.size32() as usize
}
/// ableOS: expose type_perm
pub fn type_perm(&self) -> TypePerm {
self.inner.type_perm
}
}
impl<S: SectorSize, V: Volume<u8, S>> File for Inode<S, V> {