From c4fdd390a94f220b348feb6d690230b08c6a894a Mon Sep 17 00:00:00 2001 From: jiangjianfeng Date: Tue, 2 Dec 2025 11:54:58 +0000 Subject: [PATCH] Make ext2 handle fifo and devices correctly --- kernel/src/fs/ext2/impl_for_vfs/inode.rs | 31 +++++++++++++++++++++--- kernel/src/fs/ext2/inode.rs | 25 +++++++++++++++++-- kernel/src/fs/pipe/named_pipe.rs | 6 ++--- kernel/src/fs/ramfs/fs.rs | 2 +- 4 files changed, 54 insertions(+), 10 deletions(-) diff --git a/kernel/src/fs/ext2/impl_for_vfs/inode.rs b/kernel/src/fs/ext2/impl_for_vfs/inode.rs index 6be3af678..7fbe220b9 100644 --- a/kernel/src/fs/ext2/impl_for_vfs/inode.rs +++ b/kernel/src/fs/ext2/impl_for_vfs/inode.rs @@ -2,14 +2,18 @@ use core::time::Duration; +use device_id::DeviceId; + use crate::{ + device::get_device, fs::{ ext2::{FilePerm, Inode as Ext2Inode}, + inode_handle::FileIo, notify::FsEventPublisher, utils::{ - DirentVisitor, Extension, FallocMode, FileSystem, Inode, InodeIo, InodeMode, InodeType, - Metadata, MknodType, StatusFlags, SymbolicLink, XattrName, XattrNamespace, - XattrSetFlags, + AccessMode, DirentVisitor, Extension, FallocMode, FileSystem, Inode, InodeIo, + InodeMode, InodeType, Metadata, MknodType, StatusFlags, SymbolicLink, XattrName, + XattrNamespace, XattrSetFlags, }, }, prelude::*, @@ -121,6 +125,25 @@ impl Inode for Ext2Inode { Some(self.page_cache()) } + fn open( + &self, + access_mode: AccessMode, + status_flags: StatusFlags, + ) -> Option>> { + match self.inode_type() { + InodeType::BlockDevice | InodeType::CharDevice => { + let device_id = self.device_id(); + let device = match get_device(DeviceId::from_encoded_u64(device_id)) { + Ok(device) => device, + Err(e) => return Some(Err(e)), + }; + Some(device.open()) + } + InodeType::NamedPipe => Some(self.open_named_pipe(access_mode, status_flags)), + _ => None, + } + } + fn create(&self, name: &str, type_: InodeType, mode: InodeMode) -> Result> { Ok(self.create(name, type_, mode.into())?) } @@ -133,7 +156,7 @@ impl Inode for Ext2Inode { inode.set_device_id(dev.id().as_encoded_u64()).unwrap(); inode } - _ => todo!(), + MknodType::NamedPipe => self.create(name, inode_type, mode.into())?, }; Ok(inode) diff --git a/kernel/src/fs/ext2/inode.rs b/kernel/src/fs/ext2/inode.rs index 754938178..7ed8e725f 100644 --- a/kernel/src/fs/ext2/inode.rs +++ b/kernel/src/fs/ext2/inode.rs @@ -20,11 +20,13 @@ use super::{ }; use crate::{ fs::{ + inode_handle::FileIo, notify::FsEventPublisher, path::{is_dot, is_dot_or_dotdot, is_dotdot}, + pipe::NamedPipe, utils::{ - Extension, FallocMode, Inode as _, InodeMode, Metadata, Permission, XattrName, - XattrNamespace, XattrSetFlags, + AccessMode, Extension, FallocMode, Inode as _, InodeMode, Metadata, Permission, + StatusFlags, XattrName, XattrNamespace, XattrSetFlags, }, }, process::{posix_thread::AsPosixThread, Gid, Uid}, @@ -688,6 +690,16 @@ impl Inode { inner.device_id() } + pub(super) fn open_named_pipe( + &self, + access_mode: AccessMode, + status_flags: StatusFlags, + ) -> Result> { + let inner = self.inner.read(); + let named_pipe = inner.named_pipe.as_ref().unwrap(); + named_pipe.open(access_mode, status_flags) + } + pub fn read_at(&self, offset: usize, writer: &mut VmWriter) -> Result { if self.type_ != InodeType::File { return_errno!(Errno::EISDIR); @@ -960,11 +972,19 @@ fn write_lock_multiple_inodes(inodes: Vec<&Inode>) -> Vec. + named_pipe: Option, } impl InodeInner { pub fn new(desc: Dirty, weak_self: Weak, fs: Weak) -> Self { let num_page_bytes = desc.num_page_bytes(); + let named_pipe = if desc.type_ == InodeType::NamedPipe { + Some(NamedPipe::new()) + } else { + None + }; let inode_impl = InodeImpl::new(desc, weak_self, fs); Self { page_cache: PageCache::with_capacity( @@ -973,6 +993,7 @@ impl InodeInner { ) .unwrap(), inode_impl, + named_pipe, } } diff --git a/kernel/src/fs/pipe/named_pipe.rs b/kernel/src/fs/pipe/named_pipe.rs index 9cb39f7bb..0c6b4adbe 100644 --- a/kernel/src/fs/pipe/named_pipe.rs +++ b/kernel/src/fs/pipe/named_pipe.rs @@ -134,11 +134,11 @@ pub struct NamedPipe { impl NamedPipe { /// Creates a new named pipe. - pub fn new() -> Result { - Ok(Self { + pub fn new() -> Self { + Self { pipe: Mutex::new(NamedPipeInner::default()), wait_queue: WaitQueue::new(), - }) + } } /// Opens the named pipe with the specified access mode and status flags. diff --git a/kernel/src/fs/ramfs/fs.rs b/kernel/src/fs/ramfs/fs.rs index dbd44e3ed..758af654e 100644 --- a/kernel/src/fs/ramfs/fs.rs +++ b/kernel/src/fs/ramfs/fs.rs @@ -154,7 +154,7 @@ impl Inner { } pub(self) fn new_named_pipe() -> Self { - Self::NamedPipe(NamedPipe::new().unwrap()) + Self::NamedPipe(NamedPipe::new()) } pub(self) fn new_file_in_memfd(this: Weak) -> Self {