Ext2: find_dir implementation
This commit is contained in:
parent
e21b34a3e7
commit
52cd72a949
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,16 +69,62 @@ 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>>>> {
|
||||||
|
|
|
@ -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,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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> {
|
||||||
|
|
Loading…
Reference in a new issue