From 95f67b3d67cf769e9b7914740276223bd575fa07 Mon Sep 17 00:00:00 2001 From: Yuke Peng Date: Fri, 16 Aug 2024 10:45:37 +0800 Subject: [PATCH] Remove duplicate `FileType` enumerate --- kernel/aster-nix/src/fs/ext2/dir.rs | 51 +++---- kernel/aster-nix/src/fs/ext2/fs.rs | 8 +- .../src/fs/ext2/impl_for_vfs/inode.rs | 22 +-- kernel/aster-nix/src/fs/ext2/inode.rs | 140 +++++++----------- kernel/aster-nix/src/fs/ext2/mod.rs | 4 +- kernel/aster-nix/src/fs/utils/inode.rs | 15 +- kernel/aster-nix/src/syscall/mknod.rs | 16 +- kernel/aster-nix/src/syscall/stat.rs | 32 ---- 8 files changed, 114 insertions(+), 174 deletions(-) diff --git a/kernel/aster-nix/src/fs/ext2/dir.rs b/kernel/aster-nix/src/fs/ext2/dir.rs index 84e6dc5f0..90f4df92a 100644 --- a/kernel/aster-nix/src/fs/ext2/dir.rs +++ b/kernel/aster-nix/src/fs/ext2/dir.rs @@ -2,10 +2,7 @@ #![allow(unused_variables)] -use super::{ - inode::{FileType, MAX_FNAME_LEN}, - prelude::*, -}; +use super::{inode::MAX_FNAME_LEN, prelude::*}; /// The data structure in a directory's data block. It is stored in a linked list. /// @@ -21,8 +18,8 @@ pub struct DirEntry { impl DirEntry { /// Constructs a new `DirEntry` object with the specified inode (`ino`), - /// name (`name`), and file type (`file_type`). - pub(super) fn new(ino: u32, name: &str, file_type: FileType) -> Self { + /// name (`name`), and file type (`inode_type`). + pub(super) fn new(ino: u32, name: &str, inode_type: InodeType) -> Self { debug_assert!(name.len() <= MAX_FNAME_LEN); let record_len = (Self::header_len() + name.len()).align_up(4) as u16; @@ -31,7 +28,7 @@ impl DirEntry { ino, record_len, name_len: name.len() as u8, - file_type: DirEntryFileType::from(file_type) as _, + inode_type: DirEntryFileType::from(inode_type) as _, }, name: CStr256::from(name), } @@ -39,12 +36,12 @@ impl DirEntry { /// Constructs a `DirEntry` with the name "." and `self_ino` as its inode. pub(super) fn self_entry(self_ino: u32) -> Self { - Self::new(self_ino, ".", FileType::Dir) + Self::new(self_ino, ".", InodeType::Dir) } /// Constructs a `DirEntry` with the name ".." and `parent_ino` as its inode. pub(super) fn parent_entry(parent_ino: u32) -> Self { - Self::new(parent_ino, "..", FileType::Dir) + Self::new(parent_ino, "..", InodeType::Dir) } /// Returns a reference to the header. @@ -73,8 +70,8 @@ impl DirEntry { } /// Returns the type. - pub fn type_(&self) -> FileType { - FileType::from(DirEntryFileType::try_from(self.header.file_type).unwrap()) + pub fn type_(&self) -> InodeType { + InodeType::from(DirEntryFileType::try_from(self.header.inode_type).unwrap()) } /// Returns the distance to the next entry. @@ -110,7 +107,7 @@ struct DirEntryHeader { /// Name Length name_len: u8, /// Type indicator - file_type: u8, + inode_type: u8, } /// The type indicator in the `DirEntry`. @@ -127,29 +124,29 @@ enum DirEntryFileType { Symlink = 7, } -impl From for DirEntryFileType { - fn from(file_type: FileType) -> Self { - match file_type { - FileType::Fifo => Self::Fifo, - FileType::Char => Self::Char, - FileType::Dir => Self::Dir, - FileType::Block => Self::Block, - FileType::File => Self::File, - FileType::Symlink => Self::Symlink, - FileType::Socket => Self::Socket, +impl From for DirEntryFileType { + fn from(inode_type: InodeType) -> Self { + match inode_type { + InodeType::NamedPipe => Self::Fifo, + InodeType::CharDevice => Self::Char, + InodeType::Dir => Self::Dir, + InodeType::BlockDevice => Self::Block, + InodeType::File => Self::File, + InodeType::SymLink => Self::Symlink, + InodeType::Socket => Self::Socket, } } } -impl From for FileType { +impl From for InodeType { fn from(file_type: DirEntryFileType) -> Self { match file_type { - DirEntryFileType::Fifo => Self::Fifo, - DirEntryFileType::Char => Self::Char, + DirEntryFileType::Fifo => Self::NamedPipe, + DirEntryFileType::Char => Self::CharDevice, DirEntryFileType::Dir => Self::Dir, - DirEntryFileType::Block => Self::Block, + DirEntryFileType::Block => Self::BlockDevice, DirEntryFileType::File => Self::File, - DirEntryFileType::Symlink => Self::Symlink, + DirEntryFileType::Symlink => Self::SymLink, DirEntryFileType::Socket => Self::Socket, DirEntryFileType::Unknown => panic!("unknown file type"), } diff --git a/kernel/aster-nix/src/fs/ext2/fs.rs b/kernel/aster-nix/src/fs/ext2/fs.rs index b559f4dd4..b5d6392db 100644 --- a/kernel/aster-nix/src/fs/ext2/fs.rs +++ b/kernel/aster-nix/src/fs/ext2/fs.rs @@ -5,7 +5,7 @@ use super::{ block_group::{BlockGroup, RawGroupDescriptor}, block_ptr::Ext2Bid, - inode::{FilePerm, FileType, Inode, InodeDesc, RawInode}, + inode::{FilePerm, Inode, InodeDesc, RawInode}, prelude::*, super_block::{RawSuperBlock, SuperBlock, SUPER_BLOCK_OFFSET}, }; @@ -143,13 +143,13 @@ impl Ext2 { pub(super) fn create_inode( &self, dir_block_group_idx: usize, - file_type: FileType, + inode_type: InodeType, file_perm: FilePerm, ) -> Result> { let (block_group_idx, ino) = - self.alloc_ino(dir_block_group_idx, file_type == FileType::Dir)?; + self.alloc_ino(dir_block_group_idx, inode_type == InodeType::Dir)?; let inode = { - let inode_desc = InodeDesc::new(file_type, file_perm); + let inode_desc = InodeDesc::new(inode_type, file_perm); Inode::new(ino, block_group_idx, inode_desc, self.self_ref.clone()) }; let block_group = &self.block_groups[block_group_idx]; 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 8f1ef3c17..bb2ddbd0d 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 @@ -9,7 +9,7 @@ use aster_rights::Full; use crate::{ fs::{ device::Device, - ext2::{FilePerm, FileType, Inode as Ext2Inode}, + ext2::{FilePerm, Inode as Ext2Inode}, utils::{ DirentVisitor, Extension, FallocMode, FileSystem, Inode, InodeMode, InodeType, IoctlCmd, Metadata, @@ -39,7 +39,7 @@ impl Inode for Ext2Inode { atime: self.atime(), mtime: self.mtime(), ctime: self.ctime(), - type_: InodeType::from(self.file_type()), + type_: self.inode_type(), mode: InodeMode::from(self.file_perm()), nlinks: self.hard_links() as _, uid: Uid::new(self.uid()), @@ -77,7 +77,7 @@ impl Inode for Ext2Inode { } fn type_(&self) -> InodeType { - InodeType::from(self.file_type()) + self.inode_type() } fn mode(&self) -> Result { @@ -128,11 +128,11 @@ impl Inode for Ext2Inode { } fn create(&self, name: &str, type_: InodeType, mode: InodeMode) -> Result> { - Ok(self.create(name, type_.into(), mode.into())?) + 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_()).into(), mode.into())?; + let inode = self.create(name, InodeType::from(dev.type_()), mode.into())?; inode.set_device_id(dev.id().into()).unwrap(); Ok(inode) } @@ -211,15 +211,3 @@ impl From for FilePerm { Self::from_bits_truncate(mode.bits() as _) } } - -impl From for InodeType { - fn from(type_: FileType) -> Self { - Self::try_from(type_ as u32).unwrap() - } -} - -impl From for FileType { - fn from(type_: InodeType) -> Self { - Self::try_from(type_ as u16).unwrap() - } -} diff --git a/kernel/aster-nix/src/fs/ext2/inode.rs b/kernel/aster-nix/src/fs/ext2/inode.rs index 4db9b3d9c..2a6905358 100644 --- a/kernel/aster-nix/src/fs/ext2/inode.rs +++ b/kernel/aster-nix/src/fs/ext2/inode.rs @@ -63,7 +63,7 @@ impl Inode { pub fn resize(&self, new_size: usize) -> Result<()> { let inner = self.inner.upread(); - if inner.file_type() != FileType::File { + if inner.inode_type() != InodeType::File { return_errno!(Errno::EISDIR); } if new_size == inner.file_size() { @@ -86,7 +86,7 @@ impl Inode { pub fn create( &self, name: &str, - file_type: FileType, + inode_type: InodeType, file_perm: FilePerm, ) -> Result> { if name.len() > MAX_FNAME_LEN { @@ -94,7 +94,7 @@ impl Inode { } let inner = self.inner.upread(); - if inner.file_type() != FileType::Dir { + if inner.inode_type() != InodeType::Dir { return_errno!(Errno::ENOTDIR); } if inner.hard_links() == 0 { @@ -106,13 +106,13 @@ impl Inode { let inode = self .fs() - .create_inode(self.block_group_idx, file_type, file_perm)?; - let is_dir = file_type == FileType::Dir; + .create_inode(self.block_group_idx, inode_type, file_perm)?; + let is_dir = inode_type == InodeType::Dir; if let Err(e) = inode.init(self.ino) { self.fs().free_inode(inode.ino, is_dir).unwrap(); return Err(e); } - let new_entry = DirEntry::new(inode.ino, name, file_type); + let new_entry = DirEntry::new(inode.ino, name, inode_type); let mut inner = inner.upgrade(); if let Err(e) = inner.append_entry(new_entry) { @@ -132,7 +132,7 @@ impl Inode { } let inner = self.inner.read(); - if inner.file_type() != FileType::Dir { + if inner.inode_type() != InodeType::Dir { return_errno!(Errno::ENOTDIR); } if inner.hard_links() == 0 { @@ -150,15 +150,15 @@ impl Inode { } let inner = self.inner.upread(); - if inner.file_type() != FileType::Dir { + if inner.inode_type() != InodeType::Dir { return_errno!(Errno::ENOTDIR); } if inner.hard_links() == 0 { return_errno_with_message!(Errno::ENOENT, "dir removed"); } - let inode_type = inode.file_type(); - if inode_type == FileType::Dir { + let inode_type = inode.inode_type(); + if inode_type == InodeType::Dir { return_errno!(Errno::EPERM); } @@ -187,7 +187,7 @@ impl Inode { } let file = self.lookup(name)?; - if file.file_type() == FileType::Dir { + if file.inode_type() == InodeType::Dir { return_errno!(Errno::EISDIR); } @@ -228,7 +228,7 @@ impl Inode { let dir_inode = self.lookup(name)?; let dir_inner = dir_inode.inner.read(); - if dir_inner.file_type() != FileType::Dir { + if dir_inner.inode_type() != InodeType::Dir { return_errno!(Errno::ENOTDIR); } if dir_inner.entry_count() > 2 { @@ -252,7 +252,7 @@ impl Inode { if !Arc::ptr_eq(&dir_inode, &potential_new_dir) { return_errno!(Errno::ENOENT); } - if dir_inner.file_type() != FileType::Dir { + if dir_inner.inode_type() != InodeType::Dir { return_errno!(Errno::ENOTDIR); } if dir_inner.entry_count() > 2 { @@ -272,7 +272,7 @@ impl Inode { /// Rename within its own directory. fn rename_within(&self, old_name: &str, new_name: &str) -> Result<()> { let self_inner = self.inner.upread(); - if self_inner.file_type() != FileType::Dir { + if self_inner.inode_type() != InodeType::Dir { return_errno!(Errno::ENOTDIR); } if self_inner.hard_links() == 0 { @@ -336,15 +336,15 @@ impl Inode { let dst_inode_typ = new_dst_entry.type_(); match (src_inode_typ, dst_inode_typ) { - (FileType::Dir, FileType::Dir) => { + (InodeType::Dir, InodeType::Dir) => { if dst_inner.entry_count() > 2 { return_errno!(Errno::ENOTEMPTY); } } - (FileType::Dir, _) => { + (InodeType::Dir, _) => { return_errno!(Errno::ENOTDIR); } - (_, FileType::Dir) => { + (_, InodeType::Dir) => { return_errno!(Errno::EISDIR); } _ => {} @@ -357,7 +357,7 @@ impl Inode { self_inner.set_ctime(now); dst_inner.dec_hard_links(); - if dst_inode_typ == FileType::Dir { + if dst_inode_typ == InodeType::Dir { dst_inner.dec_hard_links(); // For "." } dst_inner.set_ctime(now); @@ -383,7 +383,8 @@ impl Inode { } let (self_inner, target_inner) = read_lock_two_inodes(self, target); - if self_inner.file_type() != FileType::Dir || target_inner.file_type() != FileType::Dir { + if self_inner.inode_type() != InodeType::Dir || target_inner.inode_type() != InodeType::Dir + { return_errno!(Errno::ENOTDIR); } if self_inner.hard_links() == 0 || target_inner.hard_links() == 0 { @@ -401,7 +402,7 @@ impl Inode { if src_inode.ino == target.ino { return_errno!(Errno::EINVAL); } - let is_dir = src_inode_typ == FileType::Dir; + let is_dir = src_inode_typ == InodeType::Dir; let Some(dst_ino) = target_inner.get_entry_ino(new_name) else { drop(self_inner); @@ -503,15 +504,15 @@ impl Inode { let mut dst_inner = write_guards.pop().unwrap(); let dst_inode_typ = new_dst_entry.type_(); match (src_inode_typ, dst_inode_typ) { - (FileType::Dir, FileType::Dir) => { + (InodeType::Dir, InodeType::Dir) => { if dst_inner.entry_count() > 2 { return_errno!(Errno::ENOTEMPTY); } } - (FileType::Dir, _) => { + (InodeType::Dir, _) => { return_errno!(Errno::ENOTDIR); } - (_, FileType::Dir) => { + (_, InodeType::Dir) => { return_errno!(Errno::EISDIR); } _ => {} @@ -547,7 +548,7 @@ impl Inode { pub fn readdir_at(&self, offset: usize, visitor: &mut dyn DirentVisitor) -> Result { let offset_read = { let inner = self.inner.read(); - if inner.file_type() != FileType::Dir { + if inner.inode_type() != InodeType::Dir { return_errno!(Errno::ENOTDIR); } if inner.hard_links() == 0 { @@ -560,7 +561,7 @@ impl Inode { visitor.visit( dir_entry.name(), dir_entry.ino() as u64, - InodeType::from(dir_entry.type_()), + dir_entry.type_(), dir_entry.record_len(), )?; *offset += dir_entry.record_len(); @@ -583,7 +584,7 @@ impl Inode { pub fn write_link(&self, target: &str) -> Result<()> { let mut inner = self.inner.write(); - if inner.file_type() != FileType::Symlink { + if inner.inode_type() != InodeType::SymLink { return_errno!(Errno::EISDIR); } @@ -593,7 +594,7 @@ impl Inode { pub fn read_link(&self) -> Result { let inner = self.inner.read(); - if inner.file_type() != FileType::Symlink { + if inner.inode_type() != InodeType::SymLink { return_errno!(Errno::EISDIR); } @@ -602,8 +603,8 @@ impl Inode { pub fn set_device_id(&self, device_id: u64) -> Result<()> { let mut inner = self.inner.write(); - let file_type = inner.file_type(); - if file_type != FileType::Block && file_type != FileType::Char { + let inode_type = inner.inode_type(); + if inode_type != InodeType::BlockDevice && inode_type != InodeType::CharDevice { return_errno!(Errno::EISDIR); } @@ -613,8 +614,8 @@ impl Inode { pub fn device_id(&self) -> u64 { let inner = self.inner.read(); - let file_type = inner.file_type(); - if file_type != FileType::Block && file_type != FileType::Char { + let inode_type = inner.inode_type(); + if inode_type != InodeType::BlockDevice && inode_type != InodeType::CharDevice { return 0; } inner.device_id() @@ -623,7 +624,7 @@ impl Inode { pub fn read_at(&self, offset: usize, writer: &mut VmWriter) -> Result { let bytes_read = { let inner = self.inner.read(); - if inner.file_type() != FileType::File { + if inner.inode_type() != InodeType::File { return_errno!(Errno::EISDIR); } @@ -639,7 +640,7 @@ impl Inode { pub fn read_direct_at(&self, offset: usize, writer: &mut VmWriter) -> Result { let bytes_read = { let inner = self.inner.read(); - if inner.file_type() != FileType::File { + if inner.inode_type() != InodeType::File { return_errno!(Errno::EISDIR); } if !is_block_aligned(offset) || !is_block_aligned(writer.avail()) { @@ -657,7 +658,7 @@ impl Inode { pub fn write_at(&self, offset: usize, reader: &mut VmReader) -> Result { let bytes_written = { let inner = self.inner.upread(); - if inner.file_type() != FileType::File { + if inner.inode_type() != InodeType::File { return_errno!(Errno::EISDIR); } @@ -682,7 +683,7 @@ impl Inode { pub fn write_direct_at(&self, offset: usize, reader: &mut VmReader) -> Result { let bytes_written = { let inner = self.inner.upread(); - if inner.file_type() != FileType::File { + if inner.inode_type() != InodeType::File { return_errno!(Errno::EISDIR); } if !is_block_aligned(offset) || !is_block_aligned(reader.remain()) { @@ -702,8 +703,8 @@ impl Inode { fn init(&self, dir_ino: u32) -> Result<()> { let mut inner = self.inner.write(); - match inner.file_type() { - FileType::Dir => { + match inner.inode_type() { + InodeType::Dir => { inner.init_dir(self.ino, dir_ino)?; } _ => { @@ -743,7 +744,7 @@ impl Inode { } pub fn fallocate(&self, mode: FallocMode, offset: usize, len: usize) -> Result<()> { - if self.file_type() != FileType::File { + if self.inode_type() != InodeType::File { return_errno_with_message!(Errno::EISDIR, "not regular file"); } @@ -794,7 +795,7 @@ impl Inode { #[inherit_methods(from = "self.inner.read()")] impl Inode { pub fn file_size(&self) -> usize; - pub fn file_type(&self) -> FileType; + pub fn inode_type(&self) -> InodeType; pub fn file_perm(&self) -> FilePerm; pub fn uid(&self) -> u32; pub fn gid(&self) -> u32; @@ -875,7 +876,7 @@ struct Inner { #[inherit_methods(from = "self.inode_impl")] impl Inner { pub fn file_size(&self) -> usize; - pub fn file_type(&self) -> FileType; + pub fn inode_type(&self) -> InodeType; pub fn file_perm(&self) -> FilePerm; pub fn set_file_perm(&mut self, perm: FilePerm); pub fn uid(&self) -> u32; @@ -1039,7 +1040,7 @@ impl Inner { } pub fn append_entry(&mut self, entry: DirEntry) -> Result<()> { - let is_dir = entry.type_() == FileType::Dir; + let is_dir = entry.type_() == InodeType::Dir; let is_parent = entry.name() == ".."; DirEntryWriter::new(&self.page_cache, 0).append_entry(entry)?; @@ -1056,7 +1057,7 @@ impl Inner { pub fn remove_entry_at(&mut self, name: &str, offset: usize) -> Result<()> { let entry = DirEntryWriter::new(&self.page_cache, offset).remove_entry(name)?; - let is_dir = entry.type_() == FileType::Dir; + let is_dir = entry.type_() == InodeType::Dir; let file_size = self.inode_impl.file_size(); let page_cache_size = self.page_cache.pages().size(); if page_cache_size < file_size { @@ -1786,7 +1787,7 @@ impl InodeImpl { self.0.write().resize(new_size) } - pub fn file_type(&self) -> FileType { + pub fn inode_type(&self) -> InodeType { self.0.read().desc.type_ } @@ -1985,7 +1986,7 @@ impl InodeImpl { if !inner.is_freed { inode .fs() - .free_inode(inode.ino(), inner.desc.type_ == FileType::Dir)?; + .free_inode(inode.ino(), inner.desc.type_ == InodeType::Dir)?; inner.is_freed = true; } } @@ -2023,7 +2024,7 @@ impl PageCacheBackend for InodeImpl { #[derive(Clone, Copy, Debug)] pub(super) struct InodeDesc { /// Type. - type_: FileType, + type_: InodeType, /// Permission. perm: FilePerm, /// User Id. @@ -2056,13 +2057,13 @@ impl TryFrom for InodeDesc { type Error = crate::error::Error; fn try_from(inode: RawInode) -> Result { - let file_type = FileType::from_raw_mode(inode.mode)?; + let inode_type = InodeType::from_raw_mode(inode.mode)?; Ok(Self { - type_: file_type, + type_: inode_type, perm: FilePerm::from_raw_mode(inode.mode)?, uid: (inode.os_dependent_2.uid_high as u32) << 16 | inode.uid as u32, gid: (inode.os_dependent_2.gid_high as u32) << 16 | inode.gid as u32, - size: if file_type == FileType::File { + size: if inode_type == InodeType::File { (inode.size_high as usize) << 32 | inode.size_low as usize } else { inode.size_low as usize @@ -2076,9 +2077,9 @@ impl TryFrom for InodeDesc { flags: FileFlags::from_bits(inode.flags) .ok_or(Error::with_message(Errno::EINVAL, "invalid file flags"))?, block_ptrs: inode.block_ptrs, - acl: match file_type { - FileType::File => Some(Bid::new(inode.file_acl as _)), - FileType::Dir => Some(Bid::new(inode.size_high as _)), + acl: match inode_type { + InodeType::File => Some(Bid::new(inode.file_acl as _)), + InodeType::Dir => Some(Bid::new(inode.size_high as _)), _ => None, }, }) @@ -2086,7 +2087,7 @@ impl TryFrom for InodeDesc { } impl InodeDesc { - pub fn new(type_: FileType, perm: FilePerm) -> Dirty { + pub fn new(type_: InodeType, perm: FilePerm) -> Dirty { let now = now(); Dirty::new_dirty(Self { type_, @@ -2103,7 +2104,7 @@ impl InodeDesc { flags: FileFlags::empty(), block_ptrs: BlockPtrs::default(), acl: match type_ { - FileType::File | FileType::Dir => Some(Bid::new(0)), + InodeType::File | InodeType::Dir => Some(Bid::new(0)), _ => None, }, }) @@ -2124,40 +2125,13 @@ impl InodeDesc { #[inline] fn size_to_blocks(&self, size: usize) -> Ext2Bid { - if self.type_ == FileType::Symlink && size <= MAX_FAST_SYMLINK_LEN { + if self.type_ == InodeType::SymLink && size <= MAX_FAST_SYMLINK_LEN { return 0; } size.div_ceil(BLOCK_SIZE) as Ext2Bid } } -#[repr(u16)] -#[derive(Copy, Clone, Debug, Eq, PartialEq, TryFromInt)] -pub enum FileType { - /// FIFO special file - Fifo = 0o010000, - /// Character device - Char = 0o020000, - /// Directory - Dir = 0o040000, - /// Block device - Block = 0o060000, - /// Regular file - File = 0o100000, - /// Symbolic link - Symlink = 0o120000, - /// Socket - Socket = 0o140000, -} - -impl FileType { - pub fn from_raw_mode(mode: u16) -> Result { - const TYPE_MASK: u16 = 0o170000; - Self::try_from(mode & TYPE_MASK) - .map_err(|_| Error::with_message(Errno::EINVAL, "invalid file type")) - } -} - bitflags! { pub struct FilePerm: u16 { /// set-user-ID @@ -2299,11 +2273,11 @@ impl From<&InodeDesc> for RawInode { flags: inode.flags.bits(), block_ptrs: inode.block_ptrs, file_acl: match inode.acl { - Some(acl) if inode.type_ == FileType::File => acl.to_raw() as u32, + Some(acl) if inode.type_ == InodeType::File => acl.to_raw() as u32, _ => Default::default(), }, size_high: match inode.acl { - Some(acl) if inode.type_ == FileType::Dir => acl.to_raw() as u32, + Some(acl) if inode.type_ == InodeType::Dir => acl.to_raw() as u32, _ => Default::default(), }, os_dependent_2: Osd2 { diff --git a/kernel/aster-nix/src/fs/ext2/mod.rs b/kernel/aster-nix/src/fs/ext2/mod.rs index 6c4b00efb..46e68074b 100644 --- a/kernel/aster-nix/src/fs/ext2/mod.rs +++ b/kernel/aster-nix/src/fs/ext2/mod.rs @@ -23,7 +23,7 @@ //! // Lookup the root inode. //! let root = ext2.root_inode()?; //! // Create a file inside root directory. -//! let file = root.create("file", FileType::File, FilePerm::from_bits_truncate(0o666))?; +//! let file = root.create("file", InodeType::File, FilePerm::from_bits_truncate(0o666))?; //! // Write data into the file. //! const WRITE_DATA: &[u8] = b"Hello, World"; //! let len = file.write_at(0, WRITE_DATA)?; @@ -37,7 +37,7 @@ //! 2. Handles the intermediate failure status correctly. pub use fs::Ext2; -pub use inode::{FilePerm, FileType, Inode}; +pub use inode::{FilePerm, Inode}; pub use super_block::{SuperBlock, MAGIC_NUM}; mod block_group; diff --git a/kernel/aster-nix/src/fs/utils/inode.rs b/kernel/aster-nix/src/fs/utils/inode.rs index 98fad0a24..efcab5818 100644 --- a/kernel/aster-nix/src/fs/utils/inode.rs +++ b/kernel/aster-nix/src/fs/utils/inode.rs @@ -17,7 +17,7 @@ use crate::{ vm::vmo::Vmo, }; -#[repr(u32)] +#[repr(u16)] #[derive(Copy, Clone, Debug, Eq, PartialEq, TryFromInt)] pub enum InodeType { NamedPipe = 0o010000, @@ -55,6 +55,19 @@ impl InodeType { pub fn is_device(&self) -> bool { *self == InodeType::BlockDevice || *self == InodeType::CharDevice } + + /// Parse the inode type in the `mode` from syscall, and convert it into `InodeType`. + pub fn from_raw_mode(mut mode: u16) -> Result { + const TYPE_MASK: u16 = 0o170000; + mode &= TYPE_MASK; + + // Special case + if mode == 0 { + return Ok(Self::File); + } + Self::try_from(mode & TYPE_MASK) + .map_err(|_| Error::with_message(Errno::EINVAL, "invalid file type")) + } } impl From for InodeType { diff --git a/kernel/aster-nix/src/syscall/mknod.rs b/kernel/aster-nix/src/syscall/mknod.rs index a673014de..8961c3b09 100644 --- a/kernel/aster-nix/src/syscall/mknod.rs +++ b/kernel/aster-nix/src/syscall/mknod.rs @@ -9,7 +9,7 @@ use crate::{ utils::{InodeMode, InodeType}, }, prelude::*, - syscall::{constants::MAX_FILENAME_LEN, stat::FileType}, + syscall::constants::MAX_FILENAME_LEN, }; pub fn sys_mknodat( @@ -27,10 +27,10 @@ pub fn sys_mknodat( let mask_mode = mode & !current.umask().read().get(); InodeMode::from_bits_truncate(mask_mode) }; - let file_type = FileType::from_mode(mode); + let inode_type = InodeType::from_raw_mode(mode)?; debug!( - "dirfd = {}, path = {:?}, inode_mode = {:?}, file_type = {:?}, dev = {}", - dirfd, path, inode_mode, file_type, dev + "dirfd = {}, path = {:?}, inode_mode = {:?}, inode_type = {:?}, dev = {}", + dirfd, path, inode_mode, inode_type, dev ); let (dir_dentry, name) = { @@ -45,15 +45,15 @@ pub fn sys_mknodat( .lookup_dir_and_new_basename(&fs_path, false)? }; - match file_type { - FileType::RegularFile => { + match inode_type { + InodeType::File => { let _ = dir_dentry.new_fs_child(&name, InodeType::File, inode_mode)?; } - FileType::CharacterDevice | FileType::BlockDevice => { + InodeType::CharDevice | InodeType::BlockDevice => { let device_inode = get_device(dev)?; let _ = dir_dentry.mknod(&name, inode_mode, device_inode)?; } - FileType::Fifo | FileType::Socket => { + InodeType::NamedPipe | InodeType::Socket => { return_errno_with_message!(Errno::EINVAL, "unsupported file types") } _ => return_errno_with_message!(Errno::EPERM, "unimplemented file types"), diff --git a/kernel/aster-nix/src/syscall/stat.rs b/kernel/aster-nix/src/syscall/stat.rs index 29b5c265f..89fc63e08 100644 --- a/kernel/aster-nix/src/syscall/stat.rs +++ b/kernel/aster-nix/src/syscall/stat.rs @@ -75,38 +75,6 @@ pub fn sys_fstatat( Ok(SyscallReturn::Return(0)) } -/// File type mask. -const S_IFMT: u16 = 0o170000; - -/// Enum representing different file types. -#[derive(Debug, PartialEq)] -pub enum FileType { - Socket, - CharacterDevice, - BlockDevice, - Directory, - Fifo, - RegularFile, - Symlink, - Unknown, -} - -impl FileType { - /// Extract the file type from the mode. - pub fn from_mode(mode: u16) -> FileType { - match mode & S_IFMT { - 0o140000 => FileType::Socket, // Socket. - 0o020000 => FileType::CharacterDevice, // Character device. - 0o060000 => FileType::BlockDevice, // Block device. - 0o040000 => FileType::Directory, // Directory. - 0o010000 => FileType::Fifo, // FIFO (named pipe). - 0 | 0o100000 => FileType::RegularFile, // Regular file. - 0o120000 => FileType::Symlink, // Symbolic link. - _ => FileType::Unknown, // Unkonwn file type. - } - } -} - /// File Stat #[derive(Debug, Clone, Copy, Pod, Default)] #[repr(C)]