diff --git a/kernel/aster-nix/src/fs/device.rs b/kernel/aster-nix/src/fs/device.rs index 229fde6c2..2cfafb276 100644 --- a/kernel/aster-nix/src/fs/device.rs +++ b/kernel/aster-nix/src/fs/device.rs @@ -125,7 +125,7 @@ pub fn add_node(device: Arc, path: &str) -> Result> { dentry = dentry.mknod( next_name, InodeMode::from_bits_truncate(0o666), - device.clone(), + device.clone().into(), )?; } else { // Mkdir parent path diff --git a/kernel/aster-nix/src/fs/devpts/mod.rs b/kernel/aster-nix/src/fs/devpts/mod.rs index 1af688aab..3ca4db6c7 100644 --- a/kernel/aster-nix/src/fs/devpts/mod.rs +++ b/kernel/aster-nix/src/fs/devpts/mod.rs @@ -8,6 +8,7 @@ use aster_util::slot_vec::SlotVec; use id_alloc::IdAlloc; use self::{ptmx::Ptmx, slave::PtySlaveInode}; +use super::utils::MknodType; use crate::{ device::PtyMaster, fs::{ @@ -222,7 +223,7 @@ impl Inode for RootInode { Err(Error::new(Errno::EPERM)) } - fn mknod(&self, name: &str, mode: InodeMode, dev: Arc) -> Result> { + fn mknod(&self, name: &str, mode: InodeMode, type_: MknodType) -> Result> { Err(Error::new(Errno::EPERM)) } diff --git a/kernel/aster-nix/src/fs/exfat/inode.rs b/kernel/aster-nix/src/fs/exfat/inode.rs index 959dca178..897594ae6 100644 --- a/kernel/aster-nix/src/fs/exfat/inode.rs +++ b/kernel/aster-nix/src/fs/exfat/inode.rs @@ -28,11 +28,10 @@ use super::{ use crate::{ events::IoEvents, fs::{ - device::Device, exfat::{dentry::ExfatDentryIterator, fat::ExfatChain, fs::ExfatFS}, utils::{ - DirentVisitor, Extension, Inode, InodeMode, InodeType, IoctlCmd, Metadata, PageCache, - PageCacheBackend, + DirentVisitor, Extension, Inode, InodeMode, InodeType, IoctlCmd, Metadata, MknodType, + PageCache, PageCacheBackend, }, }, prelude::*, @@ -1444,7 +1443,7 @@ impl Inode for ExfatInode { Ok(result) } - fn mknod(&self, name: &str, mode: InodeMode, dev: Arc) -> Result> { + fn mknod(&self, name: &str, mode: InodeMode, type_: MknodType) -> Result> { return_errno_with_message!(Errno::EINVAL, "unsupported operation") } diff --git a/kernel/aster-nix/src/fs/ext2/impl_for_vfs/inode.rs b/kernel/aster-nix/src/fs/ext2/impl_for_vfs/inode.rs index bb2ddbd0d..206d98479 100644 --- a/kernel/aster-nix/src/fs/ext2/impl_for_vfs/inode.rs +++ b/kernel/aster-nix/src/fs/ext2/impl_for_vfs/inode.rs @@ -8,11 +8,10 @@ use aster_rights::Full; use crate::{ fs::{ - device::Device, ext2::{FilePerm, Inode as Ext2Inode}, utils::{ DirentVisitor, Extension, FallocMode, FileSystem, Inode, InodeMode, InodeType, - IoctlCmd, Metadata, + IoctlCmd, Metadata, MknodType, }, }, prelude::*, @@ -131,9 +130,17 @@ impl Inode for Ext2Inode { Ok(self.create(name, type_, mode.into())?) } - fn mknod(&self, name: &str, mode: InodeMode, dev: Arc) -> Result> { - let inode = self.create(name, InodeType::from(dev.type_()), mode.into())?; - inode.set_device_id(dev.id().into()).unwrap(); + fn mknod(&self, name: &str, mode: InodeMode, type_: MknodType) -> Result> { + let inode_type = type_.inode_type(); + let inode = match type_ { + MknodType::CharDeviceNode(dev) | MknodType::BlockDeviceNode(dev) => { + let inode = self.create(name, inode_type, mode.into())?; + inode.set_device_id(dev.id().into()).unwrap(); + inode + } + _ => todo!(), + }; + Ok(inode) } diff --git a/kernel/aster-nix/src/fs/path/dentry.rs b/kernel/aster-nix/src/fs/path/dentry.rs index 0f5e00982..b160ecd3a 100644 --- a/kernel/aster-nix/src/fs/path/dentry.rs +++ b/kernel/aster-nix/src/fs/path/dentry.rs @@ -12,9 +12,8 @@ use inherit_methods_macro::inherit_methods; use crate::{ fs::{ - device::Device, path::mount::MountNode, - utils::{FileSystem, Inode, InodeMode, InodeType, Metadata, NAME_MAX}, + utils::{FileSystem, Inode, InodeMode, InodeType, Metadata, MknodType, NAME_MAX}, }, prelude::*, process::{Gid, Uid}, @@ -182,7 +181,7 @@ impl Dentry_ { } /// Create a Dentry_ by making a device inode. - pub fn mknod(&self, name: &str, mode: InodeMode, device: Arc) -> Result> { + pub fn mknod(&self, name: &str, mode: InodeMode, type_: MknodType) -> Result> { if self.inode.type_() != InodeType::Dir { return_errno!(Errno::ENOTDIR); } @@ -192,7 +191,7 @@ impl Dentry_ { } let child = { - let inode = self.inode.mknod(name, mode, device)?; + let inode = self.inode.mknod(name, mode, type_)?; let dentry = Self::new( inode, DentryOptions::Leaf((String::from(name), self.this())), @@ -622,9 +621,9 @@ impl Dentry { Ok(child_mount) } - /// Create a Dentry by making a device inode. - pub fn mknod(&self, name: &str, mode: InodeMode, device: Arc) -> Result> { - let inner = self.inner.mknod(name, mode, device)?; + /// Create a Dentry by making a device inode or others. + pub fn mknod(&self, name: &str, mode: InodeMode, type_: MknodType) -> Result> { + let inner = self.inner.mknod(name, mode, type_)?; Ok(Self::new(self.mount_node.clone(), inner.clone())) } diff --git a/kernel/aster-nix/src/fs/procfs/template/dir.rs b/kernel/aster-nix/src/fs/procfs/template/dir.rs index 212ddc087..a91e3154f 100644 --- a/kernel/aster-nix/src/fs/procfs/template/dir.rs +++ b/kernel/aster-nix/src/fs/procfs/template/dir.rs @@ -9,10 +9,7 @@ use inherit_methods_macro::inherit_methods; use super::{Common, ProcFS}; use crate::{ - fs::{ - device::Device, - utils::{DirentVisitor, FileSystem, Inode, InodeMode, InodeType, Metadata}, - }, + fs::utils::{DirentVisitor, FileSystem, Inode, InodeMode, InodeType, Metadata, MknodType}, prelude::*, process::{Gid, Uid}, }; @@ -97,12 +94,7 @@ impl Inode for ProcDir { Err(Error::new(Errno::EPERM)) } - fn mknod( - &self, - _name: &str, - _mode: InodeMode, - _device: Arc, - ) -> Result> { + fn mknod(&self, _name: &str, _mode: InodeMode, type_: MknodType) -> Result> { Err(Error::new(Errno::EPERM)) } diff --git a/kernel/aster-nix/src/fs/ramfs/fs.rs b/kernel/aster-nix/src/fs/ramfs/fs.rs index 65d9c4012..d20540e08 100644 --- a/kernel/aster-nix/src/fs/ramfs/fs.rs +++ b/kernel/aster-nix/src/fs/ramfs/fs.rs @@ -20,7 +20,7 @@ use crate::{ device::Device, utils::{ CStr256, DirentVisitor, Extension, FallocMode, FileSystem, FsFlags, Inode, InodeMode, - InodeType, IoctlCmd, Metadata, PageCache, PageCacheBackend, SuperBlock, + InodeType, IoctlCmd, Metadata, MknodType, PageCache, PageCacheBackend, SuperBlock, }, }, prelude::*, @@ -676,12 +676,7 @@ impl Inode for RamInode { Ok(()) } - fn mknod( - &self, - name: &str, - mode: InodeMode, - device: Arc, - ) -> Result> { + fn mknod(&self, name: &str, mode: InodeMode, type_: MknodType) -> Result> { if name.len() > NAME_MAX { return_errno!(Errno::ENAMETOOLONG); } @@ -693,22 +688,27 @@ impl Inode for RamInode { if self_inode.inner.as_direntry().unwrap().contains_entry(name) { return_errno_with_message!(Errno::EEXIST, "entry exists"); } - let device_inode = RamInode::new_device( - &self.fs.upgrade().unwrap(), - mode, - Uid::new_root(), - Gid::new_root(), - device, - ); + let inode = match type_ { + MknodType::CharDeviceNode(device) | MknodType::BlockDeviceNode(device) => { + RamInode::new_device( + &self.fs.upgrade().unwrap(), + mode, + Uid::new_root(), + Gid::new_root(), + device, + ) + } + _ => return_errno_with_message!(Errno::EPERM, "unimplemented file types"), + }; let mut self_inode = self_inode.upgrade(); self_inode .inner .as_direntry_mut() .unwrap() - .append_entry(name, device_inode.clone()); + .append_entry(name, inode.clone()); self_inode.inc_size(); - Ok(device_inode) + Ok(inode) } fn as_device(&self) -> Option> { diff --git a/kernel/aster-nix/src/fs/utils/inode.rs b/kernel/aster-nix/src/fs/utils/inode.rs index efcab5818..7a01cdbb0 100644 --- a/kernel/aster-nix/src/fs/utils/inode.rs +++ b/kernel/aster-nix/src/fs/utils/inode.rs @@ -254,6 +254,33 @@ impl Metadata { } } +pub enum MknodType { + NamedPipeNode, + CharDeviceNode(Arc), + BlockDeviceNode(Arc), +} + +impl MknodType { + pub fn inode_type(&self) -> InodeType { + match self { + MknodType::NamedPipeNode => InodeType::NamedPipe, + MknodType::CharDeviceNode(_) => InodeType::CharDevice, + MknodType::BlockDeviceNode(_) => InodeType::BlockDevice, + } + } +} + +impl From> for MknodType { + fn from(device: Arc) -> Self { + let inode_type: InodeType = device.type_().into(); + match inode_type { + InodeType::CharDevice => Self::CharDeviceNode(device), + InodeType::BlockDevice => Self::BlockDeviceNode(device), + _ => unreachable!(), + } + } +} + pub trait Inode: Any + Sync + Send { fn size(&self) -> usize; @@ -313,7 +340,7 @@ pub trait Inode: Any + Sync + Send { Err(Error::new(Errno::ENOTDIR)) } - fn mknod(&self, name: &str, mode: InodeMode, dev: Arc) -> Result> { + fn mknod(&self, name: &str, mode: InodeMode, type_: MknodType) -> Result> { Err(Error::new(Errno::ENOTDIR)) } diff --git a/kernel/aster-nix/src/fs/utils/mod.rs b/kernel/aster-nix/src/fs/utils/mod.rs index bfcd022ba..86a72eaf5 100644 --- a/kernel/aster-nix/src/fs/utils/mod.rs +++ b/kernel/aster-nix/src/fs/utils/mod.rs @@ -11,7 +11,7 @@ pub use falloc_mode::FallocMode; pub use file_creation_mask::FileCreationMask; pub use flock::{FlockItem, FlockList, FlockType}; pub use fs::{FileSystem, FsFlags, SuperBlock}; -pub use inode::{Extension, Inode, InodeMode, InodeType, Metadata}; +pub use inode::{Extension, Inode, InodeMode, InodeType, Metadata, MknodType}; pub use ioctl::IoctlCmd; pub use page_cache::{PageCache, PageCacheBackend}; pub use random_test::{generate_random_operation, new_fs_in_memory}; diff --git a/kernel/aster-nix/src/syscall/mknod.rs b/kernel/aster-nix/src/syscall/mknod.rs index 8961c3b09..c3c7e245d 100644 --- a/kernel/aster-nix/src/syscall/mknod.rs +++ b/kernel/aster-nix/src/syscall/mknod.rs @@ -51,7 +51,7 @@ pub fn sys_mknodat( } InodeType::CharDevice | InodeType::BlockDevice => { let device_inode = get_device(dev)?; - let _ = dir_dentry.mknod(&name, inode_mode, device_inode)?; + let _ = dir_dentry.mknod(&name, inode_mode, device_inode.into())?; } InodeType::NamedPipe | InodeType::Socket => { return_errno_with_message!(Errno::EINVAL, "unsupported file types")