Merge pull request #271 from arihant2math/ext4plus-bump

Use as_any to downcast inodes for updating in ext4
This commit is contained in:
Matthew Leach
2026-04-03 08:53:40 +01:00
committed by GitHub
17 changed files with 163 additions and 17 deletions

59
Cargo.lock generated
View File

@@ -35,6 +35,17 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13696b1c2b59992f4223e0ae5bb173c81c63039367ca90eee845346ad2a13421"
[[package]]
name = "async-lock"
version = "3.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311"
dependencies = [
"event-listener",
"event-listener-strategy",
"pin-project-lite",
]
[[package]]
name = "async-trait"
version = "0.1.89"
@@ -131,6 +142,15 @@ dependencies = [
"windows-sys",
]
[[package]]
name = "concurrent-queue"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973"
dependencies = [
"crossbeam-utils",
]
[[package]]
name = "cpufeatures"
version = "0.3.0"
@@ -266,14 +286,36 @@ dependencies = [
]
[[package]]
name = "ext4plus"
version = "0.1.0-alpha.5"
name = "event-listener"
version = "5.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "866bc656467be17c403c70ab35ccb0f3294a7aaa6425c879b63d6aa878e3ffab"
checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab"
dependencies = [
"concurrent-queue",
"pin-project-lite",
]
[[package]]
name = "event-listener-strategy"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93"
dependencies = [
"event-listener",
"pin-project-lite",
]
[[package]]
name = "ext4plus"
version = "0.1.0-alpha.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9dc277b4b40b9c396d5519685fa08c9feada784011646ce7f40fa8ec68baf8e5"
dependencies = [
"async-lock",
"async-trait",
"bitflags 2.11.0",
"crc",
"maybe-async",
]
[[package]]
@@ -524,6 +566,17 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d"
[[package]]
name = "maybe-async"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5cf92c10c7e361d6b99666ec1c6f9805b0bea2c3bd8c78dc6fe98ac5bd78db11"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "memchr"
version = "2.8.0"

View File

@@ -6,7 +6,7 @@ edition = "2024"
[dependencies]
async-trait = { workspace = true }
bitflags = { workspace = true }
ext4plus = "0.1.0-alpha.5"
ext4plus = "0.1.0-alpha.7"
intrusive-collections = { version = "0.10.0", default-features = false }
log = { workspace = true }
object = { version = "0.38.0", default-features = false, features = ["core", "elf", "read_core"] }

View File

@@ -26,6 +26,7 @@ use alloc::{
sync::{Arc, Weak},
};
use async_trait::async_trait;
use core::any::Any;
use core::error::Error;
use core::marker::PhantomData;
use core::num::NonZeroU32;
@@ -157,7 +158,7 @@ impl InodeInner {
InodeInner::Regular(File::open_inode(fs, inode).unwrap())
}
ext4plus::FileType::Directory => {
InodeInner::Directory(Dir::open_inode(fs, inode).await.unwrap())
InodeInner::Directory(Dir::open_inode(fs, inode).unwrap())
}
_ => InodeInner::Other(inode),
}
@@ -378,11 +379,13 @@ where
if inode.id().fs_id() != fs.id() {
return Err(KernelError::Fs(FsError::CrossDevice));
}
let mut other_inode = ExtInode::read(
&fs.inner,
(inode.id().inode_id() as u32).try_into().unwrap(),
)
.await?;
let mut other_inode = inode
.as_any()
.downcast_ref::<Ext4Inode<CPU>>()
.ok_or(FsError::CrossDevice)?
.inner
.lock()
.await;
let file_type = other_inode.file_type();
inner_dir
.link(
@@ -443,15 +446,20 @@ where
return Ok(());
}
let old_parent_id = old_parent.id();
if old_parent.id().fs_id() != self.id().fs_id() {
return Err(KernelError::Fs(FsError::CrossDevice));
}
let fs = self.fs_ref.upgrade().unwrap();
let old_parent_inode = ExtInode::read(
&fs.inner,
(old_parent_id.inode_id() as u32).try_into().unwrap(),
)
.await?;
let old_parent_dir = Dir::open_inode(&fs.inner, old_parent_inode).await?;
let old_parent_inode = old_parent
.as_any()
.downcast_ref::<Ext4Inode<CPU>>()
.ok_or(FsError::CrossDevice)?
.inner
.lock()
.await
.clone();
let old_parent_dir = Dir::open_inode(&fs.inner, old_parent_inode)?;
let inner = self.inner.lock().await;
let inner_dir = match &*inner {
@@ -532,6 +540,13 @@ where
child_inode,
)
.await?;
*old_parent
.as_any()
.downcast_ref::<Ext4Inode<CPU>>()
.ok_or(FsError::CrossDevice)?
.inner
.lock()
.await = InodeInner::Directory(old_parent_dir);
Ok(())
}
@@ -564,6 +579,10 @@ where
inner.write(&fs.inner).await?;
Ok(())
}
fn as_any(&self) -> &dyn Any {
self
}
}
/// An EXT4 filesystem instance.

View File

@@ -11,6 +11,7 @@ use crate::{
};
use alloc::{boxed::Box, string::String, sync::Arc, vec::Vec};
use async_trait::async_trait;
use core::any::Any;
use log::warn;
bitflags::bitflags! {
@@ -399,6 +400,10 @@ impl<T: Fat32Operations> Inode for Fat32DirNode<T> {
async fn getattr(&self) -> Result<FileAttr> {
Ok(self.attr.clone())
}
fn as_any(&self) -> &dyn Any {
self
}
}
#[cfg(test)]

View File

@@ -5,6 +5,7 @@ use crate::{
use alloc::boxed::Box;
use alloc::sync::Arc;
use async_trait::async_trait;
use core::any::Any;
use super::{Cluster, Fat32Operations, reader::Fat32Reader};
@@ -39,6 +40,10 @@ impl<T: Fat32Operations> Inode for Fat32FileNode<T> {
async fn getattr(&self) -> Result<FileAttr> {
Ok(self.attr.clone())
}
fn as_any(&self) -> &dyn Any {
self
}
}
#[cfg(test)]

View File

@@ -23,6 +23,7 @@ use alloc::{
vec::Vec,
};
use async_trait::async_trait;
use core::any::Any;
use core::time::Duration;
use core::{
cmp::min,
@@ -325,6 +326,10 @@ where
*self.attr.lock_save_irq() = attr;
Ok(())
}
fn as_any(&self) -> &dyn Any {
self
}
}
struct TmpFsDirEnt {
@@ -660,6 +665,10 @@ where
fn dir_is_empty(&self) -> Result<bool> {
Ok(self.entries.lock_save_irq().is_empty())
}
fn as_any(&self) -> &dyn Any {
self
}
}
impl<C, G, T> TmpFsDirInode<C, G, T>
@@ -752,6 +761,10 @@ impl<C: CpuOps> Inode for TmpFsSymlinkInode<C> {
Ok(())
}
}
fn as_any(&self) -> &dyn Any {
self
}
}
impl<C: CpuOps> TmpFsSymlinkInode<C> {

View File

@@ -328,6 +328,8 @@ pub trait Inode: Send + Sync + Any {
async fn datasync(&self) -> Result<()> {
Ok(())
}
fn as_any(&self) -> &dyn Any;
}
/// A simplified trait for read-only files in procfs/sysfs that provides default implementations
@@ -377,6 +379,10 @@ where
async fn readlink(&self) -> Result<PathBuf> {
self.readlink().await
}
fn as_any(&self) -> &dyn Any {
self
}
}
pub struct SimpleDirStream {

View File

@@ -486,6 +486,7 @@ impl VMArea {
#[cfg(test)]
pub mod tests {
use crate::fs::InodeId;
use core::any::Any;
use super::*;
use async_trait::async_trait;
@@ -498,6 +499,10 @@ pub mod tests {
fn id(&self) -> InodeId {
unreachable!("Not called")
}
fn as_any(&self) -> &dyn Any {
self
}
}
pub fn create_test_vma(vaddr: usize, memsz: usize, file_offset: u64, filesz: u64) -> VMArea {

View File

@@ -94,6 +94,10 @@ macro_rules! static_dir {
)*
Ok(Box::new(SimpleDirStream::new(entries, start_offset)))
}
fn as_any(&self) -> &dyn core::any::Any {
self
}
}
};
}

View File

@@ -7,6 +7,7 @@ use alloc::{
sync::Arc,
};
use async_trait::async_trait;
use core::any::Any;
use core::sync::atomic::{AtomicU64, Ordering};
use libkernel::fs::attr::{FileAttr, FilePermissions};
use libkernel::fs::{BlockDevice, DirStream, Dirent, Filesystem};
@@ -171,6 +172,10 @@ impl Inode for DevFsINode {
InodeKind::CharDevice { .. } => Err(FsError::NotADirectory.into()),
}
}
fn as_any(&self) -> &dyn Any {
self
}
}
/// The driver for the `devfs` filesystem itself.

View File

@@ -143,4 +143,8 @@ impl Inode for ProcRootInode {
Ok(Box::new(SimpleDirStream::new(entries, start_offset)))
}
fn as_any(&self) -> &dyn core::any::Any {
self
}
}

View File

@@ -96,6 +96,10 @@ impl Inode for ProcFdInode {
Ok(Box::new(SimpleDirStream::new(entries, start_offset)))
}
fn as_any(&self) -> &dyn core::any::Any {
self
}
}
// TODO: Support fd links in /proc/[pid]/fd/

View File

@@ -12,6 +12,7 @@ use alloc::string::ToString;
use alloc::sync::Arc;
use alloc::vec::Vec;
use async_trait::async_trait;
use core::any::Any;
use libkernel::error::FsError;
use libkernel::fs::attr::{FileAttr, FilePermissions};
use libkernel::fs::{
@@ -143,4 +144,8 @@ impl Inode for ProcTaskInode {
Ok(Box::new(SimpleDirStream::new(entries, start_offset)))
}
fn as_any(&self) -> &dyn Any {
self
}
}

View File

@@ -75,4 +75,8 @@ impl Inode for ProcTaskDirInode {
}
Ok(Box::new(SimpleDirStream::new(entries, start_offset)))
}
fn as_any(&self) -> &dyn core::any::Any {
self
}
}

View File

@@ -95,6 +95,10 @@ macro_rules! static_dir {
)*
Ok(Box::new(SimpleDirStream::new(entries, start_offset)))
}
fn as_any(&self) -> &dyn core::any::Any {
self
}
}
};
}

View File

@@ -6,6 +6,7 @@ use crate::{
};
use alloc::{borrow::ToOwned, boxed::Box, collections::btree_map::BTreeMap, sync::Arc, vec::Vec};
use async_trait::async_trait;
use core::any::Any;
use core::sync::atomic::{AtomicU64, Ordering};
use dir::DirFile;
use libkernel::{
@@ -35,6 +36,10 @@ impl Inode for DummyInode {
fn id(&self) -> InodeId {
InodeId::dummy()
}
fn as_any(&self) -> &dyn Any {
self
}
}
/// Represents a mounted filesystem.

View File

@@ -11,6 +11,7 @@ use crate::{
};
use alloc::{boxed::Box, sync::Arc};
use async_trait::async_trait;
use core::any::Any;
use core::{
future,
pin::pin,
@@ -68,6 +69,10 @@ impl Inode for PipeInode {
gid: self.gid,
})
}
fn as_any(&self) -> &dyn Any {
self
}
}
#[derive(Clone)]