Ext2: find_dir implementation

This commit is contained in:
TheOddGarlic 2022-08-04 13:56:37 +03:00
parent e21b34a3e7
commit 52cd72a949
5 changed files with 73 additions and 18 deletions

View file

@ -10,6 +10,7 @@ pub enum FsError {
InvalidDevice, InvalidDevice,
IsDirectory, IsDirectory,
NotADirectory, NotADirectory,
NotFound,
UnsupportedOperation, UnsupportedOperation,
} }
@ -31,7 +32,7 @@ impl Into<FsError> for ext2::error::Error {
ext2::error::Error::InodeNotFound { inode: _ } => FsError::InodeNotFound, ext2::error::Error::InodeNotFound { inode: _ } => FsError::InodeNotFound,
ext2::error::Error::NotADirectory { inode: _, name: _ } => FsError::NotADirectory, ext2::error::Error::NotADirectory { inode: _, name: _ } => FsError::NotADirectory,
ext2::error::Error::NotAbsolute { name: _ } => todo!(), 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 * SPDX-License-Identifier: MPL-2.0
*/ */
use alloc::sync::Weak;
use ext2::fs::{sync::Synced, Ext2}; use ext2::fs::{sync::Synced, Ext2};
use ext2::sector::SectorSize; use ext2::sector::SectorSize;
use ext2::sys::inode::TypePerm;
use ext2::volume::Volume; use ext2::volume::Volume;
use crate::handle::Handle;
use super::errors::FsError; 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> pub struct Ext2StorageDevice<S, V>
where where
@ -17,6 +21,7 @@ where
V: Volume<u8, S>, V: Volume<u8, S>,
{ {
fs: Synced<Ext2<S, V>>, fs: Synced<Ext2<S, V>>,
device_handle: Handle,
} }
impl<S, V> Ext2StorageDevice<S, V> impl<S, V> Ext2StorageDevice<S, V>
@ -24,9 +29,10 @@ where
S: SectorSize, S: SectorSize,
V: Volume<u8, S>, V: Volume<u8, S>,
{ {
pub fn new(volume: V) -> Result<Self> { pub fn new(volume: V, device_handle: Handle) -> Result<Self> {
Ok(Self { Ok(Self {
fs: Synced::new(volume).map_err(|e| e.into())?, fs: Synced::new(volume).map_err(|e| e.into())?,
device_handle,
}) })
} }
} }
@ -63,18 +69,64 @@ where
.inode_nth(node.inode as usize) .inode_nth(node.inode as usize)
.ok_or_else(|| FsError::InodeNotFound)?; .ok_or_else(|| FsError::InodeNotFound)?;
let mut dir = inode.directory().ok_or_else(|| FsError::NotADirectory)?; 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)? .ok_or_else(|| FsError::InodeNotFound)?
.map_err(|e| e.into())?; .map_err(|e| e.into())?;
Ok(DirectoryEntry::new(entry.file_name_string(), entry.inode)) Ok(DirectoryEntry::new(entry.file_name_string(), entry.inode))
} }
fn find_dir(&self, _node: &FsNode, _name: &str) -> Result<FsNode> { fn find_dir(&self, node: &FsNode, name: &str) -> Result<FsNode> {
todo!() 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>>>> { // fn load_fs() -> Arc<Mutex<Ext2<Size1024, Vec<u8>>>> {
// let mut volume = Vec::new(); // let mut volume = Vec::new();
// volume.extend_from_slice(include_bytes!("../../../userland/root_fs/ext2.img")); // volume.extend_from_slice(include_bytes!("../../../userland/root_fs/ext2.img"));

View file

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

View file

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

View file

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