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

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 {