Browse Source

增加kernfs (#386)

* 增加kernfs

* kernfs文档
LoGin 1 year ago
parent
commit
6b4e7a2972

+ 1 - 0
docs/kernel/filesystem/index.rst

@@ -12,4 +12,5 @@ todo: 由于文件系统模块重构,文档暂时不可用,预计在2023年4
    overview
    vfs/index
    sysfs
+   kernfs
 

+ 22 - 0
docs/kernel/filesystem/kernfs.md

@@ -0,0 +1,22 @@
+# KernFS
+
+:::{note}
+
+Maintainer:
+- 龙进 <[email protected]>
+:::
+
+## 1. 简介
+&emsp;&emsp;KernFS是一个伪文件系统,它充当其它内核文件系统的容器,面向用户提供文件接口。其核心功能就是,当kernfs的文件被读/写或者触发回调点的时候,将会对预设的回调函数进行调用,触发其它内核文件系统的操作。
+
+&emsp;&emsp;这种设计使得SysFS和文件系统的基本操作解耦,KernFS作为SysFS的承载物,使得SysFS能更专注于KObject的管理,让代码更加优雅。
+
+&emsp;&emsp;在未来,DragonOS的内核子系统,或者其它的内核文件系统,可以使用KernFS作为文件系统操作的承载物,让系统管理的逻辑与具体的文件系统操作解除耦合。
+
+## 2. 使用方法
+
+&emsp;&emsp;以SysFS为例,新创建一个KernFS实例,作为SysFS的文件系统接口,然后挂载到`/sys`目录下。接着sysfs实现上层逻辑,管理KObject,每个上层的Kobject里面都需要包含KernFSInode。并且通过设置KernFSInode的PrivateData,使得KernFS能够根据Inode获取到其指向的KObject或者sysfs的attribute。并且在创建KernFSInode的时候,为具体的Inode传入不同的callback,以此实现“不同的Inode在读写时能够触发不同的回调行为”。
+
+&emsp;&emsp;当发生回调时,KernFS会把回调信息、私有信息传入到回调函数中,让回调函数能够根据传入的信息,获取到对应的KObject或者sysfs的attribute,从而实现sysfs提供的高层功能。
+
+&emsp;&emsp;从上述描述我们能够看出:KernFS就是通过存储上层文件系统的回调函数、回调信息,来实现“把具体文件操作与高层管理逻辑进行解耦”的目的。

+ 2 - 1
kernel/src/driver/disk/ahci/ahci_inode.rs

@@ -1,6 +1,7 @@
 use crate::driver::base::block::block_device::BlockDevice;
 use crate::filesystem::devfs::{DevFS, DeviceINode};
 use crate::filesystem::vfs::file::FileMode;
+use crate::filesystem::vfs::syscall::ModeType;
 use crate::filesystem::vfs::{
     core::generate_inode_id, make_rawdev, FilePrivateData, FileSystem, FileType, IndexNode,
     Metadata, PollStatus,
@@ -49,7 +50,7 @@ impl LockedAhciInode {
                 mtime: TimeSpec::default(),
                 ctime: TimeSpec::default(),
                 file_type: FileType::BlockDevice, // 文件夹,block设备,char设备
-                mode: 0o666,
+                mode: ModeType::from_bits_truncate(0o666),
                 nlinks: 1,
                 uid: 0,
                 gid: 0,

+ 5 - 2
kernel/src/driver/keyboard/ps2_keyboard.rs

@@ -6,7 +6,10 @@ use crate::{
     driver::tty::tty_device::TTY_DEVICES,
     filesystem::{
         devfs::{devfs_register, DevFS, DeviceINode},
-        vfs::{core::generate_inode_id, file::FileMode, FileType, IndexNode, Metadata, PollStatus},
+        vfs::{
+            core::generate_inode_id, file::FileMode, syscall::ModeType, FileType, IndexNode,
+            Metadata, PollStatus,
+        },
     },
     include::bindings::bindings::{vfs_file_operations_t, vfs_file_t, vfs_index_node_t},
     libs::{keyboard_parser::TypeOneFSM, rwlock::RwLock, spinlock::SpinLock},
@@ -59,7 +62,7 @@ impl LockedPS2KeyBoardInode {
                 mtime: TimeSpec::default(),
                 ctime: TimeSpec::default(),
                 file_type: FileType::CharDevice, // 文件夹,block设备,char设备
-                mode: 0o666,
+                mode: ModeType::from_bits_truncate(0o666),
                 nlinks: 1,
                 uid: 0,
                 gid: 0,

+ 5 - 2
kernel/src/driver/tty/tty_device.rs

@@ -7,7 +7,10 @@ use alloc::{
 use crate::{
     filesystem::{
         devfs::{devfs_register, DevFS, DeviceINode},
-        vfs::{file::FileMode, FilePrivateData, FileType, IndexNode, Metadata, ROOT_INODE},
+        vfs::{
+            file::FileMode, syscall::ModeType, FilePrivateData, FileType, IndexNode, Metadata,
+            ROOT_INODE,
+        },
     },
     kerror,
     libs::{
@@ -271,7 +274,7 @@ impl IndexNode for TtyDevice {
 
 impl TtyDevicePrivateData {
     pub fn new(name: &str) -> RwLock<Self> {
-        let mut metadata = Metadata::new(FileType::CharDevice, 0o755);
+        let mut metadata = Metadata::new(FileType::CharDevice, ModeType::from_bits_truncate(0o755));
         metadata.size = TtyCore::STDIN_BUF_SIZE as i64;
         return RwLock::new(TtyDevicePrivateData {
             name: name.to_string(),

+ 6 - 3
kernel/src/driver/uart/uart_device.rs

@@ -15,7 +15,10 @@ use crate::{
     filesystem::{
         devfs::{devfs_register, DevFS, DeviceINode},
         sysfs::bus::{bus_device_register, bus_driver_register},
-        vfs::{FilePrivateData, FileSystem, FileType, IndexNode, Metadata, PollStatus},
+        vfs::{
+            syscall::ModeType, FilePrivateData, FileSystem, FileType, IndexNode, Metadata,
+            PollStatus,
+        },
     },
     include::bindings::bindings::{io_in8, io_out8},
     kinfo,
@@ -314,7 +317,7 @@ impl IndexNode for LockedUart {
         &self,
         name: &str,
         file_type: FileType,
-        mode: u32,
+        mode: ModeType,
     ) -> Result<Arc<dyn IndexNode>, SystemError> {
         // 若文件系统没有实现此方法,则默认调用其create_with_data方法。如果仍未实现,则会得到一个Err(-EOPNOTSUPP_OR_ENOTSUP)的返回值
         return self.create_with_data(name, file_type, mode, 0);
@@ -324,7 +327,7 @@ impl IndexNode for LockedUart {
         &self,
         _name: &str,
         _file_type: FileType,
-        _mode: u32,
+        _mode: ModeType,
         _data: usize,
     ) -> Result<Arc<dyn IndexNode>, SystemError> {
         // 若文件系统没有实现此方法,则返回“不支持”

+ 46 - 21
kernel/src/filesystem/devfs/mod.rs

@@ -5,6 +5,7 @@ pub mod zero_dev;
 use super::vfs::{
     core::{generate_inode_id, ROOT_INODE},
     file::FileMode,
+    syscall::ModeType,
     FileSystem, FileType, FsInfo, IndexNode, Metadata, PollStatus,
 };
 use crate::{
@@ -55,7 +56,7 @@ impl DevFS {
         let root: Arc<LockedDevFSInode> = Arc::new(LockedDevFSInode(SpinLock::new(
             // /dev 的权限设置为 读+执行,root 可以读写
             // root 的 parent 是空指针
-            DevFSInode::new(FileType::Dir, 0o755 as u32, 0),
+            DevFSInode::new(FileType::Dir, ModeType::from_bits_truncate(0o755), 0),
         )));
 
         let devfs: Arc<DevFS> = Arc::new(DevFS { root_inode: root });
@@ -109,7 +110,11 @@ impl DevFS {
             // 字节设备挂载在 /dev/char
             FileType::CharDevice => {
                 if let Err(_) = dev_root_inode.find("char") {
-                    dev_root_inode.create("char", FileType::Dir, 0o755)?;
+                    dev_root_inode.create(
+                        "char",
+                        FileType::Dir,
+                        ModeType::from_bits_truncate(0o755),
+                    )?;
                 }
 
                 let any_char_inode = dev_root_inode.find("char")?;
@@ -128,7 +133,11 @@ impl DevFS {
             }
             FileType::BlockDevice => {
                 if let Err(_) = dev_root_inode.find("block") {
-                    dev_root_inode.create("block", FileType::Dir, 0o755)?;
+                    dev_root_inode.create(
+                        "block",
+                        FileType::Dir,
+                        ModeType::from_bits_truncate(0o755),
+                    )?;
                 }
 
                 let any_block_inode = dev_root_inode.find("block")?;
@@ -212,14 +221,14 @@ pub struct DevFSInode {
 }
 
 impl DevFSInode {
-    pub fn new(dev_type_: FileType, mode_: u32, data_: usize) -> Self {
-        return Self::new_with_parent(Weak::default(), dev_type_, mode_, data_);
+    pub fn new(dev_type_: FileType, mode: ModeType, data_: usize) -> Self {
+        return Self::new_with_parent(Weak::default(), dev_type_, mode, data_);
     }
 
     pub fn new_with_parent(
         parent: Weak<LockedDevFSInode>,
         dev_type_: FileType,
-        mode_: u32,
+        mode: ModeType,
         data_: usize,
     ) -> Self {
         return DevFSInode {
@@ -236,7 +245,7 @@ impl DevFSInode {
                 mtime: TimeSpec::default(),
                 ctime: TimeSpec::default(),
                 file_type: dev_type_, // 文件夹
-                mode: mode_,
+                mode,
                 nlinks: 1,
                 uid: 0,
                 gid: 0,
@@ -255,7 +264,13 @@ impl LockedDevFSInode {
             return Err(SystemError::EEXIST);
         }
 
-        match self.do_create_with_data(guard, name, FileType::Dir, 0o755 as u32, 0) {
+        match self.do_create_with_data(
+            guard,
+            name,
+            FileType::Dir,
+            ModeType::from_bits_truncate(0o755),
+            0,
+        ) {
             Ok(inode) => inode,
             Err(err) => {
                 return Err(err);
@@ -291,17 +306,17 @@ impl LockedDevFSInode {
     fn do_create_with_data(
         &self,
         mut guard: SpinLockGuard<DevFSInode>,
-        _name: &str,
-        _file_type: FileType,
-        _mode: u32,
-        _data: usize,
+        name: &str,
+        file_type: FileType,
+        mode: ModeType,
+        data: usize,
     ) -> Result<Arc<dyn IndexNode>, SystemError> {
         if guard.metadata.file_type != FileType::Dir {
             return Err(SystemError::ENOTDIR);
         }
 
         // 如果有重名的,则返回
-        if guard.children.contains_key(_name) {
+        if guard.children.contains_key(name) {
             return Err(SystemError::EEXIST);
         }
 
@@ -319,12 +334,12 @@ impl LockedDevFSInode {
                 atime: TimeSpec::default(),
                 mtime: TimeSpec::default(),
                 ctime: TimeSpec::default(),
-                file_type: _file_type,
-                mode: _mode,
+                file_type,
+                mode,
                 nlinks: 1,
                 uid: 0,
                 gid: 0,
-                raw_dev: _data,
+                raw_dev: data,
             },
             fs: guard.fs.clone(),
         })));
@@ -333,7 +348,7 @@ impl LockedDevFSInode {
         result.0.lock().self_ref = Arc::downgrade(&result);
 
         // 将子inode插入父inode的B树中
-        guard.children.insert(String::from(_name), result.clone());
+        guard.children.insert(String::from(name), result.clone());
         return Ok(result);
     }
 }
@@ -359,7 +374,7 @@ impl IndexNode for LockedDevFSInode {
         &self,
         name: &str,
         file_type: FileType,
-        mode: u32,
+        mode: ModeType,
         data: usize,
     ) -> Result<Arc<dyn IndexNode>, SystemError> {
         // 获取当前inode
@@ -399,7 +414,7 @@ impl IndexNode for LockedDevFSInode {
             return Err(SystemError::ENOTDIR);
         }
 
-        match ino {
+        match ino.into() {
             0 => {
                 return Ok(String::from("."));
             }
@@ -412,14 +427,24 @@ impl IndexNode for LockedDevFSInode {
                 let mut key: Vec<String> = inode
                     .children
                     .keys()
-                    .filter(|k| inode.children.get(*k).unwrap().metadata().unwrap().inode_id == ino)
+                    .filter(|k| {
+                        inode
+                            .children
+                            .get(*k)
+                            .unwrap()
+                            .metadata()
+                            .unwrap()
+                            .inode_id
+                            .into()
+                            == ino
+                    })
                     .cloned()
                     .collect();
 
                 match key.len() {
                     0=>{return Err(SystemError::ENOENT);}
                     1=>{return Ok(key.remove(0));}
-                    _ => panic!("Devfs get_entry_name: key.len()={key_len}>1, current inode_id={inode_id}, to find={to_find}", key_len=key.len(), inode_id = inode.metadata.inode_id, to_find=ino)
+                    _ => panic!("Devfs get_entry_name: key.len()={key_len}>1, current inode_id={inode_id:?}, to find={to_find:?}", key_len=key.len(), inode_id = inode.metadata.inode_id, to_find=ino)
                 }
             }
         }

+ 2 - 1
kernel/src/filesystem/devfs/null_dev.rs

@@ -1,5 +1,6 @@
 use crate::filesystem::vfs::file::FileMode;
 use crate::filesystem::vfs::make_rawdev;
+use crate::filesystem::vfs::syscall::ModeType;
 use crate::filesystem::vfs::{
     core::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata, PollStatus,
 };
@@ -43,7 +44,7 @@ impl LockedNullInode {
                 mtime: TimeSpec::default(),
                 ctime: TimeSpec::default(),
                 file_type: FileType::CharDevice, // 文件夹,block设备,char设备
-                mode: 0o666,
+                mode: ModeType::from_bits_truncate(0o666),
                 nlinks: 1,
                 uid: 0,
                 gid: 0,

+ 2 - 1
kernel/src/filesystem/devfs/zero_dev.rs

@@ -1,5 +1,6 @@
 use crate::filesystem::vfs::file::FileMode;
 use crate::filesystem::vfs::make_rawdev;
+use crate::filesystem::vfs::syscall::ModeType;
 use crate::filesystem::vfs::{
     core::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata, PollStatus,
 };
@@ -43,7 +44,7 @@ impl LockedZeroInode {
                 mtime: TimeSpec::default(),
                 ctime: TimeSpec::default(),
                 file_type: FileType::CharDevice, // 文件夹,block设备,char设备
-                mode: 0o666,
+                mode: ModeType::from_bits_truncate(0o666),
                 nlinks: 1,
                 uid: 0,
                 gid: 0,

+ 17 - 6
kernel/src/filesystem/fat/fs.rs

@@ -13,6 +13,7 @@ use crate::{
     filesystem::vfs::{
         core::generate_inode_id,
         file::{FileMode, FilePrivateData},
+        syscall::ModeType,
         FileSystem, FileType, IndexNode, InodeId, Metadata, PollStatus,
     },
     kerror,
@@ -189,7 +190,7 @@ impl LockedFATInode {
                 mtime: TimeSpec::default(),
                 ctime: TimeSpec::default(),
                 file_type: file_type,
-                mode: 0o777,
+                mode: ModeType::from_bits_truncate(0o777),
                 nlinks: 1,
                 uid: 0,
                 gid: 0,
@@ -308,7 +309,7 @@ impl FATFileSystem {
                 mtime: TimeSpec::default(),
                 ctime: TimeSpec::default(),
                 file_type: FileType::Dir,
-                mode: 0o777,
+                mode: ModeType::from_bits_truncate(0o777),
                 nlinks: 1,
                 uid: 0,
                 gid: 0,
@@ -1421,7 +1422,7 @@ impl IndexNode for LockedFATInode {
         &self,
         name: &str,
         file_type: FileType,
-        _mode: u32,
+        _mode: ModeType,
     ) -> Result<Arc<dyn IndexNode>, SystemError> {
         // 由于FAT32不支持文件权限的功能,因此忽略mode参数
         let mut guard: SpinLockGuard<FATInode> = self.0.lock();
@@ -1627,7 +1628,7 @@ impl IndexNode for LockedFATInode {
         if guard.metadata.file_type != FileType::Dir {
             return Err(SystemError::ENOTDIR);
         }
-        match ino {
+        match ino.into() {
             0 => {
                 return Ok(String::from("."));
             }
@@ -1640,14 +1641,24 @@ impl IndexNode for LockedFATInode {
                 let mut key: Vec<String> = guard
                     .children
                     .keys()
-                    .filter(|k| guard.children.get(*k).unwrap().metadata().unwrap().inode_id == ino)
+                    .filter(|k| {
+                        guard
+                            .children
+                            .get(*k)
+                            .unwrap()
+                            .metadata()
+                            .unwrap()
+                            .inode_id
+                            .into()
+                            == ino
+                    })
                     .cloned()
                     .collect();
 
                 match key.len() {
                     0=>{return Err(SystemError::ENOENT);}
                     1=>{return Ok(key.remove(0));}
-                    _ => panic!("FatFS get_entry_name: key.len()={key_len}>1, current inode_id={inode_id}, to find={to_find}", key_len=key.len(), inode_id = guard.metadata.inode_id, to_find=ino)
+                    _ => panic!("FatFS get_entry_name: key.len()={key_len}>1, current inode_id={inode_id:?}, to find={to_find:?}", key_len=key.len(), inode_id = guard.metadata.inode_id, to_find=ino)
                 }
             }
         }

+ 73 - 0
kernel/src/filesystem/kernfs/callback.rs

@@ -0,0 +1,73 @@
+use crate::{
+    filesystem::{sysfs::SysFSKernPrivateData, vfs::PollStatus},
+    libs::spinlock::SpinLockGuard,
+    syscall::SystemError,
+};
+use alloc::sync::Arc;
+use core::fmt::Debug;
+
+use super::KernFSInode;
+
+/// KernFS文件的回调接口
+///
+/// 当用户态程序打开、读取、写入、关闭文件时,kernfs会调用相应的回调函数。
+pub trait KernFSCallback: Send + Sync + Debug {
+    fn open(&self, data: KernCallbackData) -> Result<(), SystemError>;
+
+    fn read(
+        &self,
+        data: KernCallbackData,
+        buf: &mut [u8],
+        offset: usize,
+    ) -> Result<usize, SystemError>;
+
+    fn write(
+        &self,
+        data: KernCallbackData,
+        buf: &[u8],
+        offset: usize,
+    ) -> Result<usize, SystemError>;
+
+    fn poll(&self, data: KernCallbackData) -> Result<PollStatus, SystemError>;
+}
+
+/// KernFS文件的回调数据
+#[derive(Debug)]
+pub struct KernCallbackData<'a> {
+    kern_inode: Arc<KernFSInode>,
+    private_data: SpinLockGuard<'a, Option<KernInodePrivateData>>,
+}
+
+#[allow(dead_code)]
+impl<'a> KernCallbackData<'a> {
+    pub fn new(
+        kern_inode: Arc<KernFSInode>,
+        private_data: SpinLockGuard<'a, Option<KernInodePrivateData>>,
+    ) -> Self {
+        Self {
+            kern_inode,
+            private_data,
+        }
+    }
+
+    #[inline(always)]
+    pub fn kern_inode(&self) -> &Arc<KernFSInode> {
+        return &self.kern_inode;
+    }
+
+    #[inline(always)]
+    pub fn private_data(&self) -> &Option<KernInodePrivateData> {
+        return &self.private_data;
+    }
+
+    #[inline(always)]
+    pub fn private_data_mut(&mut self) -> &mut Option<KernInodePrivateData> {
+        return &mut self.private_data;
+    }
+}
+
+#[allow(dead_code)]
+#[derive(Debug)]
+pub enum KernInodePrivateData {
+    SysFS(SysFSKernPrivateData),
+}

+ 486 - 0
kernel/src/filesystem/kernfs/mod.rs

@@ -0,0 +1,486 @@
+use core::{fmt::Debug, intrinsics::unlikely};
+
+use alloc::{
+    string::String,
+    sync::{Arc, Weak},
+    vec::Vec,
+};
+use hashbrown::HashMap;
+
+use crate::{
+    libs::{rwlock::RwLock, spinlock::SpinLock},
+    syscall::SystemError,
+    time::TimeSpec,
+};
+
+use self::callback::{KernCallbackData, KernFSCallback, KernInodePrivateData};
+
+use super::vfs::{
+    core::generate_inode_id, file::FileMode, syscall::ModeType, FilePrivateData, FileSystem,
+    FileType, FsInfo, IndexNode, InodeId, Metadata, PollStatus,
+};
+
+pub mod callback;
+
+#[derive(Debug)]
+pub struct KernFS {
+    root_inode: Arc<KernFSInode>,
+}
+
+impl FileSystem for KernFS {
+    fn as_any_ref(&self) -> &dyn core::any::Any {
+        self
+    }
+
+    fn info(&self) -> FsInfo {
+        return FsInfo {
+            blk_dev_id: 0,
+            max_name_len: KernFS::MAX_NAMELEN,
+        };
+    }
+
+    fn root_inode(&self) -> Arc<dyn IndexNode> {
+        return self.root_inode.clone();
+    }
+}
+
+impl KernFS {
+    pub const MAX_NAMELEN: usize = 4096;
+
+    #[allow(dead_code)]
+    pub fn new() -> Arc<Self> {
+        let root_inode = Self::create_root_inode();
+        let fs = Arc::new(Self {
+            root_inode: root_inode.clone(),
+        });
+
+        {
+            let ptr = root_inode.as_ref() as *const KernFSInode as *mut KernFSInode;
+            unsafe {
+                (*ptr).self_ref = Arc::downgrade(&root_inode);
+            }
+        }
+        root_inode.inner.lock().parent = Arc::downgrade(&root_inode);
+        *root_inode.fs.write() = Arc::downgrade(&fs);
+        return fs;
+    }
+
+    fn create_root_inode() -> Arc<KernFSInode> {
+        let metadata = Metadata {
+            size: 0,
+            mode: ModeType::from_bits_truncate(0o755),
+            uid: 0,
+            gid: 0,
+            blk_size: 0,
+            blocks: 0,
+            atime: TimeSpec::new(0, 0),
+            mtime: TimeSpec::new(0, 0),
+            ctime: TimeSpec::new(0, 0),
+            dev_id: 0,
+            inode_id: generate_inode_id(),
+            file_type: FileType::Dir,
+            nlinks: 1,
+            raw_dev: 0,
+        };
+        let root_inode = Arc::new(KernFSInode {
+            inner: SpinLock::new(InnerKernFSInode {
+                parent: Weak::new(),
+                metadata,
+            }),
+            self_ref: Weak::new(),
+            fs: RwLock::new(Weak::new()),
+            private_data: SpinLock::new(None),
+            callback: None,
+            children: SpinLock::new(HashMap::new()),
+            inode_type: KernInodeType::Dir,
+        });
+
+        return root_inode;
+    }
+}
+
+#[derive(Debug)]
+pub struct KernFSInode {
+    inner: SpinLock<InnerKernFSInode>,
+    /// 指向当前Inode所属的文件系统的弱引用
+    fs: RwLock<Weak<KernFS>>,
+    /// 指向自身的弱引用
+    self_ref: Weak<KernFSInode>,
+    /// 私有数据
+    private_data: SpinLock<Option<KernInodePrivateData>>,
+    /// 回调函数
+    callback: Option<&'static dyn KernFSCallback>,
+    /// 子Inode
+    children: SpinLock<HashMap<String, Arc<KernFSInode>>>,
+    /// Inode类型
+    inode_type: KernInodeType,
+}
+
+#[derive(Debug)]
+pub struct InnerKernFSInode {
+    parent: Weak<KernFSInode>,
+
+    /// 当前inode的元数据
+    metadata: Metadata,
+}
+
+impl IndexNode for KernFSInode {
+    fn as_any_ref(&self) -> &dyn core::any::Any {
+        self
+    }
+
+    fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> {
+        if let Some(callback) = self.callback {
+            let callback_data =
+                KernCallbackData::new(self.self_ref.upgrade().unwrap(), self.private_data.lock());
+            return callback.open(callback_data);
+        }
+
+        return Ok(());
+    }
+
+    fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
+        return Ok(());
+    }
+
+    fn metadata(&self) -> Result<Metadata, SystemError> {
+        return Ok(self.inner.lock().metadata.clone());
+    }
+
+    fn set_metadata(&self, _metadata: &Metadata) -> Result<(), SystemError> {
+        // 若文件系统没有实现此方法,则返回“不支持”
+        return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
+    }
+
+    fn resize(&self, _len: usize) -> Result<(), SystemError> {
+        return Ok(());
+    }
+
+    fn create_with_data(
+        &self,
+        _name: &str,
+        _file_type: FileType,
+        _mode: ModeType,
+        _data: usize,
+    ) -> Result<Arc<dyn IndexNode>, SystemError> {
+        // 应当通过kernfs的其它方法来创建文件,而不能从用户态直接调用此方法。
+        return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
+    }
+
+    fn link(&self, _name: &str, _other: &Arc<dyn IndexNode>) -> Result<(), SystemError> {
+        // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。
+        return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
+    }
+
+    fn unlink(&self, _name: &str) -> Result<(), SystemError> {
+        // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。
+        return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
+    }
+
+    fn rmdir(&self, _name: &str) -> Result<(), SystemError> {
+        // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。
+        return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
+    }
+
+    fn move_(
+        &self,
+        _old_name: &str,
+        _target: &Arc<dyn IndexNode>,
+        _new_name: &str,
+    ) -> Result<(), SystemError> {
+        // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。
+        return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
+    }
+
+    fn find(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError> {
+        if unlikely(name.len() > KernFS::MAX_NAMELEN) {
+            return Err(SystemError::ENAMETOOLONG);
+        }
+        if unlikely(self.inode_type != KernInodeType::Dir) {
+            return Err(SystemError::ENOTDIR);
+        }
+        let x: Arc<KernFSInode> = self
+            .children
+            .lock()
+            .get(name)
+            .cloned()
+            .ok_or(SystemError::ENOENT)?;
+        return Ok(x);
+    }
+
+    fn get_entry_name(&self, ino: InodeId) -> Result<String, SystemError> {
+        if self.inode_type != KernInodeType::Dir {
+            return Err(SystemError::ENOTDIR);
+        }
+
+        let children = self.children.lock();
+        let r = children
+            .iter()
+            .find(|(_, v)| v.metadata().unwrap().inode_id == ino)
+            .map(|(k, _)| k.clone());
+
+        return r.ok_or(SystemError::ENOENT);
+    }
+
+    fn get_entry_name_and_metadata(&self, ino: InodeId) -> Result<(String, Metadata), SystemError> {
+        // 如果有条件,请在文件系统中使用高效的方式实现本接口,而不是依赖这个低效率的默认实现。
+        let name = self.get_entry_name(ino)?;
+        let entry = self.find(&name)?;
+        return Ok((name, entry.metadata()?));
+    }
+
+    fn ioctl(&self, _cmd: u32, _data: usize) -> Result<usize, SystemError> {
+        // 若文件系统没有实现此方法,则返回“不支持”
+        return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
+    }
+
+    fn truncate(&self, _len: usize) -> Result<(), SystemError> {
+        // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。
+        return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
+    }
+
+    fn sync(&self) -> Result<(), SystemError> {
+        return Ok(());
+    }
+
+    fn fs(&self) -> Arc<dyn FileSystem> {
+        return self.fs.read().upgrade().unwrap();
+    }
+
+    fn list(&self) -> Result<Vec<String>, SystemError> {
+        let mut list = Vec::new();
+        for (name, _) in self.children.lock().iter() {
+            list.push(name.clone());
+        }
+        return Ok(list);
+    }
+
+    fn poll(&self) -> Result<PollStatus, SystemError> {
+        // todo: 根据inode的具体attribute,返回PollStatus
+        return Ok(PollStatus::READ | PollStatus::WRITE);
+    }
+
+    fn read_at(
+        &self,
+        offset: usize,
+        len: usize,
+        buf: &mut [u8],
+        _data: &mut FilePrivateData,
+    ) -> Result<usize, SystemError> {
+        if self.inode_type != KernInodeType::File {
+            return Err(SystemError::EISDIR);
+        }
+
+        if self.callback.is_none() {
+            return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
+        }
+
+        let callback_data =
+            KernCallbackData::new(self.self_ref.upgrade().unwrap(), self.private_data.lock());
+        return self
+            .callback
+            .as_ref()
+            .unwrap()
+            .read(callback_data, &mut buf[..len], offset);
+    }
+
+    fn write_at(
+        &self,
+        offset: usize,
+        len: usize,
+        buf: &[u8],
+        _data: &mut FilePrivateData,
+    ) -> Result<usize, SystemError> {
+        if self.inode_type != KernInodeType::File {
+            return Err(SystemError::EISDIR);
+        }
+
+        if self.callback.is_none() {
+            return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
+        }
+
+        let callback_data =
+            KernCallbackData::new(self.self_ref.upgrade().unwrap(), self.private_data.lock());
+        return self
+            .callback
+            .as_ref()
+            .unwrap()
+            .write(callback_data, &buf[..len], offset);
+    }
+}
+
+impl KernFSInode {
+    /// 在当前inode下增加子目录
+    ///
+    /// ## 参数
+    ///
+    /// - `name`:子目录名称
+    /// - `mode`:子目录权限
+    /// - `private_data`:子目录私有数据
+    /// - `callback`:子目录回调函数
+    ///
+    /// ## 返回值
+    ///
+    /// - 成功:子目录inode
+    /// - 失败:错误码
+    #[allow(dead_code)]
+    #[inline]
+    pub fn add_dir(
+        &self,
+        name: String,
+        mode: ModeType,
+        private_data: Option<KernInodePrivateData>,
+        callback: Option<&'static dyn KernFSCallback>,
+    ) -> Result<Arc<KernFSInode>, SystemError> {
+        if unlikely(self.inode_type != KernInodeType::Dir) {
+            return Err(SystemError::ENOTDIR);
+        }
+
+        return self.inner_create(name, KernInodeType::Dir, mode, private_data, callback);
+    }
+
+    /// 在当前inode下增加文件
+    ///
+    /// ## 参数
+    ///
+    /// - `name`:文件名称
+    /// - `mode`:文件权限
+    /// - `private_data`:文件私有数据
+    /// - `callback`:文件回调函数
+    ///
+    /// ## 返回值
+    ///
+    /// - 成功:文件inode
+    /// - 失败:错误码
+    #[allow(dead_code)]
+    #[inline]
+    pub fn add_file(
+        &self,
+        name: String,
+        mode: ModeType,
+        private_data: Option<KernInodePrivateData>,
+        callback: Option<&'static dyn KernFSCallback>,
+    ) -> Result<Arc<KernFSInode>, SystemError> {
+        if unlikely(self.inode_type != KernInodeType::Dir) {
+            return Err(SystemError::ENOTDIR);
+        }
+
+        return self.inner_create(name, KernInodeType::File, mode, private_data, callback);
+    }
+
+    fn inner_create(
+        &self,
+        name: String,
+        file_type: KernInodeType,
+        mode: ModeType,
+        private_data: Option<KernInodePrivateData>,
+        callback: Option<&'static dyn KernFSCallback>,
+    ) -> Result<Arc<KernFSInode>, SystemError> {
+        let metadata = Metadata {
+            size: 0,
+            mode,
+            uid: 0,
+            gid: 0,
+            blk_size: 0,
+            blocks: 0,
+            atime: TimeSpec::new(0, 0),
+            mtime: TimeSpec::new(0, 0),
+            ctime: TimeSpec::new(0, 0),
+            dev_id: 0,
+            inode_id: generate_inode_id(),
+            file_type: file_type.into(),
+            nlinks: 1,
+            raw_dev: 0,
+        };
+
+        let new_inode: Arc<KernFSInode> = Self::new(
+            self.self_ref.upgrade().unwrap(),
+            metadata,
+            KernInodeType::Dir,
+            private_data,
+            callback,
+        );
+
+        self.children.lock().insert(name, new_inode.clone());
+
+        return Ok(new_inode);
+    }
+
+    /// 在当前inode下删除子目录或者文件
+    ///
+    /// 如果要删除的是子目录,且子目录不为空,则返回ENOTEMPTY
+    ///
+    /// ## 参数
+    ///
+    /// - `name`:子目录或者文件名称
+    ///
+    /// ## 返回值
+    ///
+    /// - 成功:()
+    /// - 失败:错误码
+    #[allow(dead_code)]
+    pub fn remove(&self, name: &str) -> Result<(), SystemError> {
+        if unlikely(self.inode_type != KernInodeType::Dir) {
+            return Err(SystemError::ENOTDIR);
+        }
+
+        let mut children = self.children.lock();
+        let inode = children.get(name).ok_or(SystemError::ENOENT)?;
+        if inode.children.lock().is_empty() {
+            children.remove(name);
+            return Ok(());
+        } else {
+            return Err(SystemError::ENOTEMPTY);
+        }
+    }
+
+    pub(self) fn new(
+        parent: Arc<KernFSInode>,
+        metadata: Metadata,
+        inode_type: KernInodeType,
+        private_data: Option<KernInodePrivateData>,
+        callback: Option<&'static dyn KernFSCallback>,
+    ) -> Arc<KernFSInode> {
+        let inode = Arc::new(KernFSInode {
+            inner: SpinLock::new(InnerKernFSInode {
+                parent: Arc::downgrade(&parent),
+                metadata,
+            }),
+            self_ref: Weak::new(),
+            fs: RwLock::new(Weak::new()),
+            private_data: SpinLock::new(private_data),
+            callback,
+            children: SpinLock::new(HashMap::new()),
+            inode_type,
+        });
+
+        {
+            let ptr = inode.as_ref() as *const KernFSInode as *mut KernFSInode;
+            unsafe {
+                (*ptr).self_ref = Arc::downgrade(&inode);
+            }
+        }
+        *inode.fs.write() = Arc::downgrade(
+            parent
+                .fs()
+                .as_any_ref()
+                .downcast_ref()
+                .expect("KernFSInode::new: parent is not a KernFS instance"),
+        );
+        return inode;
+    }
+}
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub(self) enum KernInodeType {
+    Dir,
+    File,
+}
+
+impl Into<FileType> for KernInodeType {
+    fn into(self) -> FileType {
+        match self {
+            KernInodeType::Dir => FileType::Dir,
+            KernInodeType::File => FileType::File,
+        }
+    }
+}

+ 1 - 0
kernel/src/filesystem/mod.rs

@@ -1,5 +1,6 @@
 pub mod devfs;
 pub mod fat;
+pub mod kernfs;
 pub mod mbr;
 pub mod procfs;
 pub mod ramfs;

+ 27 - 7
kernel/src/filesystem/procfs/mod.rs

@@ -26,6 +26,7 @@ use crate::{
 
 use super::vfs::{
     file::{FileMode, FilePrivateData},
+    syscall::ModeType,
     FileSystem, FsInfo, IndexNode, InodeId, Metadata, PollStatus,
 };
 
@@ -262,7 +263,7 @@ impl ProcFS {
                     mtime: TimeSpec::default(),
                     ctime: TimeSpec::default(),
                     file_type: FileType::Dir,
-                    mode: 0o777,
+                    mode: ModeType::from_bits_truncate(0o777),
                     nlinks: 1,
                     uid: 0,
                     gid: 0,
@@ -294,10 +295,18 @@ impl ProcFS {
         // 获取当前inode
         let proc: Arc<dyn IndexNode> = self.root_inode();
         // 创建对应进程文件夹
-        let _pf: Arc<dyn IndexNode> = proc.create(&pid.to_string(), FileType::Dir, 0o777)?;
+        let _pf: Arc<dyn IndexNode> = proc.create(
+            &pid.to_string(),
+            FileType::Dir,
+            ModeType::from_bits_truncate(0o777),
+        )?;
         // 创建相关文件
         // status文件
-        let binding: Arc<dyn IndexNode> = _pf.create("status", FileType::File, 0o777)?;
+        let binding: Arc<dyn IndexNode> = _pf.create(
+            "status",
+            FileType::File,
+            ModeType::from_bits_truncate(0o777),
+        )?;
         let _sf: &LockedProcFSInode = binding
             .as_any_ref()
             .downcast_ref::<LockedProcFSInode>()
@@ -482,7 +491,7 @@ impl IndexNode for LockedProcFSInode {
         &self,
         name: &str,
         file_type: FileType,
-        mode: u32,
+        mode: ModeType,
         data: usize,
     ) -> Result<Arc<dyn IndexNode>, SystemError> {
         // 获取当前inode
@@ -623,7 +632,7 @@ impl IndexNode for LockedProcFSInode {
             return Err(SystemError::ENOTDIR);
         }
 
-        match ino {
+        match ino.into() {
             0 => {
                 return Ok(String::from("."));
             }
@@ -636,14 +645,25 @@ impl IndexNode for LockedProcFSInode {
                 let mut key: Vec<String> = inode
                     .children
                     .keys()
-                    .filter(|k| inode.children.get(*k).unwrap().0.lock().metadata.inode_id == ino)
+                    .filter(|k| {
+                        inode
+                            .children
+                            .get(*k)
+                            .unwrap()
+                            .0
+                            .lock()
+                            .metadata
+                            .inode_id
+                            .into()
+                            == ino
+                    })
                     .cloned()
                     .collect();
 
                 match key.len() {
                         0=>{return Err(SystemError::ENOENT);}
                         1=>{return Ok(key.remove(0));}
-                        _ => panic!("Procfs get_entry_name: key.len()={key_len}>1, current inode_id={inode_id}, to find={to_find}", key_len=key.len(), inode_id = inode.metadata.inode_id, to_find=ino)
+                        _ => panic!("Procfs get_entry_name: key.len()={key_len}>1, current inode_id={inode_id:?}, to find={to_find:?}", key_len=key.len(), inode_id = inode.metadata.inode_id, to_find=ino)
                     }
             }
         }

+ 18 - 6
kernel/src/filesystem/ramfs/mod.rs

@@ -15,7 +15,8 @@ use crate::{
 };
 
 use super::vfs::{
-    file::FilePrivateData, FileSystem, FsInfo, IndexNode, InodeId, Metadata, PollStatus,
+    file::FilePrivateData, syscall::ModeType, FileSystem, FsInfo, IndexNode, InodeId, Metadata,
+    PollStatus,
 };
 
 /// RamFS的inode名称的最大长度
@@ -90,7 +91,7 @@ impl RamFS {
                 mtime: TimeSpec::default(),
                 ctime: TimeSpec::default(),
                 file_type: FileType::Dir,
-                mode: 0o777,
+                mode: ModeType::from_bits_truncate(0o777),
                 nlinks: 1,
                 uid: 0,
                 gid: 0,
@@ -258,7 +259,7 @@ impl IndexNode for LockedRamFSInode {
         &self,
         name: &str,
         file_type: FileType,
-        mode: u32,
+        mode: ModeType,
         data: usize,
     ) -> Result<Arc<dyn IndexNode>, SystemError> {
         // 获取当前inode
@@ -425,7 +426,7 @@ impl IndexNode for LockedRamFSInode {
             return Err(SystemError::ENOTDIR);
         }
 
-        match ino {
+        match ino.into() {
             0 => {
                 return Ok(String::from("."));
             }
@@ -438,14 +439,25 @@ impl IndexNode for LockedRamFSInode {
                 let mut key: Vec<String> = inode
                     .children
                     .keys()
-                    .filter(|k| inode.children.get(*k).unwrap().0.lock().metadata.inode_id == ino)
+                    .filter(|k| {
+                        inode
+                            .children
+                            .get(*k)
+                            .unwrap()
+                            .0
+                            .lock()
+                            .metadata
+                            .inode_id
+                            .into()
+                            == ino
+                    })
                     .cloned()
                     .collect();
 
                 match key.len() {
                     0=>{return Err(SystemError::ENOENT);}
                     1=>{return Ok(key.remove(0));}
-                    _ => panic!("Ramfs get_entry_name: key.len()={key_len}>1, current inode_id={inode_id}, to find={to_find}", key_len=key.len(), inode_id = inode.metadata.inode_id, to_find=ino)
+                    _ => panic!("Ramfs get_entry_name: key.len()={key_len}>1, current inode_id={inode_id:?}, to find={to_find:?}", key_len=key.len(), inode_id = inode.metadata.inode_id, to_find=ino)
                 }
             }
         }

+ 32 - 0
kernel/src/filesystem/sysfs/dir.rs

@@ -0,0 +1,32 @@
+#![allow(dead_code)]
+use alloc::sync::Arc;
+
+use crate::driver::base::device::KObject;
+
+use super::AttributeGroup;
+
+#[derive(Debug)]
+pub struct SysKernDirPriv {
+    kobj: Arc<dyn KObject>,
+    attribute_group: Option<&'static dyn AttributeGroup>,
+}
+
+impl SysKernDirPriv {
+    pub fn new(
+        kobj: Arc<dyn KObject>,
+        attribute_group: Option<&'static dyn AttributeGroup>,
+    ) -> Self {
+        Self {
+            kobj,
+            attribute_group,
+        }
+    }
+
+    pub fn kobj(&self) -> Arc<dyn KObject> {
+        self.kobj.clone()
+    }
+
+    pub fn attribute_group(&self) -> Option<&'static dyn AttributeGroup> {
+        self.attribute_group
+    }
+}

+ 21 - 0
kernel/src/filesystem/sysfs/file.rs

@@ -0,0 +1,21 @@
+#![allow(dead_code)]
+use super::Attribute;
+
+#[derive(Debug)]
+pub struct SysKernFilePriv {
+    attribute: Option<&'static dyn Attribute>,
+    // todo: 增加bin attribute,它和attribute二选一,只能有一个为Some
+}
+
+impl SysKernFilePriv {
+    pub fn new(attribute: Option<&'static dyn Attribute>) -> Self {
+        if attribute.is_none() {
+            panic!("attribute can't be None");
+        }
+        return Self { attribute };
+    }
+
+    pub fn attribute(&self) -> Option<&'static dyn Attribute> {
+        self.attribute
+    }
+}

+ 66 - 23
kernel/src/filesystem/sysfs/mod.rs

@@ -1,9 +1,13 @@
+use core::fmt::Debug;
+
+use self::{dir::SysKernDirPriv, file::SysKernFilePriv};
+
 use super::vfs::{
-    core::generate_inode_id, file::FileMode, FileSystem, FileType, FsInfo, IndexNode, Metadata,
-    PollStatus,
+    core::generate_inode_id, file::FileMode, syscall::ModeType, FileSystem, FileType, FsInfo,
+    IndexNode, Metadata, PollStatus,
 };
 use crate::{
-    driver::base::platform::platform_bus_init,
+    driver::base::{device::KObject, platform::platform_bus_init},
     filesystem::{sysfs::bus::sys_bus_init, vfs::ROOT_INODE},
     kdebug, kinfo,
     libs::{
@@ -23,6 +27,8 @@ use alloc::{
 pub mod bus;
 pub mod class;
 pub mod devices;
+mod dir;
+mod file;
 pub mod fs;
 
 const SYSFS_MAX_NAMELEN: usize = 64;
@@ -98,7 +104,7 @@ impl SysFS {
         let root: Arc<LockedSysFSInode> = Arc::new(LockedSysFSInode(SpinLock::new(
             // /sys 的权限设置为 读+执行,root 可以读写
             // root 的 parent 是空指针
-            SysFSInode::new(FileType::Dir, 0o755 as u32, 0),
+            SysFSInode::new(FileType::Dir, ModeType::from_bits_truncate(0o755), 0),
         )));
 
         let sysfs: Arc<SysFS> = Arc::new(SysFS { root_inode: root });
@@ -220,7 +226,7 @@ impl IndexNode for LockedSysFSInode {
             return Err(SystemError::ENOTDIR);
         }
 
-        match ino {
+        match ino.into() {
             0 => {
                 return Ok(String::from("."));
             }
@@ -233,14 +239,24 @@ impl IndexNode for LockedSysFSInode {
                 let mut key: Vec<String> = inode
                     .children
                     .keys()
-                    .filter(|k| inode.children.get(*k).unwrap().metadata().unwrap().inode_id == ino)
+                    .filter(|k| {
+                        inode
+                            .children
+                            .get(*k)
+                            .unwrap()
+                            .metadata()
+                            .unwrap()
+                            .inode_id
+                            .into()
+                            == ino
+                    })
                     .cloned()
                     .collect();
 
                 match key.len() {
                     0=>{return Err(SystemError::ENOENT);}
                     1=>{return Ok(key.remove(0));}
-                    _ => panic!("Sysfs get_entry_name: key.len()={key_len}>1, current inode_id={inode_id}, to find={to_find}", key_len=key.len(), inode_id = inode.metadata.inode_id, to_find=ino)
+                    _ => panic!("Sysfs get_entry_name: key.len()={key_len}>1, current inode_id={inode_id:?}, to find={to_find:?}", key_len=key.len(), inode_id = inode.metadata.inode_id, to_find=ino)
                 }
             }
         }
@@ -294,17 +310,17 @@ impl LockedSysFSInode {
     fn do_create_with_data(
         &self,
         mut guard: SpinLockGuard<SysFSInode>,
-        _name: &str,
-        _file_type: FileType,
-        _mode: u32,
-        _data: usize,
+        name: &str,
+        file_type: FileType,
+        mode: ModeType,
+        data: usize,
     ) -> Result<Arc<dyn IndexNode>, SystemError> {
         if guard.metadata.file_type != FileType::Dir {
             return Err(SystemError::ENOTDIR);
         }
 
         // 如果有重名的,则返回
-        if guard.children.contains_key(_name) {
+        if guard.children.contains_key(name) {
             return Err(SystemError::EEXIST);
         }
 
@@ -322,12 +338,12 @@ impl LockedSysFSInode {
                 atime: TimeSpec::default(),
                 mtime: TimeSpec::default(),
                 ctime: TimeSpec::default(),
-                file_type: _file_type,
-                mode: _mode,
+                file_type,
+                mode,
                 nlinks: 1,
                 uid: 0,
                 gid: 0,
-                raw_dev: _data,
+                raw_dev: data,
             },
             fs: guard.fs.clone(),
         })));
@@ -336,7 +352,7 @@ impl LockedSysFSInode {
         result.0.lock().self_ref = Arc::downgrade(&result);
 
         // 将子inode插入父inode的B树中
-        guard.children.insert(String::from(_name), result.clone());
+        guard.children.insert(String::from(name), result.clone());
         return Ok(result);
     }
 
@@ -352,7 +368,13 @@ impl LockedSysFSInode {
             return Err(SystemError::EEXIST);
         }
 
-        match self.do_create_with_data(guard, name, FileType::Dir, 0o755 as u32, 0) {
+        match self.do_create_with_data(
+            guard,
+            name,
+            FileType::Dir,
+            ModeType::from_bits_truncate(0o755),
+            0,
+        ) {
             Ok(inode) => return Ok(inode),
             Err(err) => {
                 return Err(err);
@@ -421,14 +443,14 @@ pub struct SysFSInode {
 }
 
 impl SysFSInode {
-    pub fn new(dev_type_: FileType, mode_: u32, data_: usize) -> Self {
-        return Self::new_with_parent(Weak::default(), dev_type_, mode_, data_);
+    pub fn new(file_type: FileType, mode: ModeType, data_: usize) -> Self {
+        return Self::new_with_parent(Weak::default(), file_type, mode, data_);
     }
 
     pub fn new_with_parent(
         parent: Weak<LockedSysFSInode>,
-        dev_type_: FileType,
-        mode_: u32,
+        file_type: FileType,
+        mode: ModeType,
         data_: usize,
     ) -> Self {
         return SysFSInode {
@@ -444,8 +466,8 @@ impl SysFSInode {
                 atime: TimeSpec::default(),
                 mtime: TimeSpec::default(),
                 ctime: TimeSpec::default(),
-                file_type: dev_type_, // 文件夹
-                mode: mode_,
+                file_type,
+                mode,
                 nlinks: 1,
                 uid: 0,
                 gid: 0,
@@ -485,3 +507,24 @@ pub fn sysfs_init() -> Result<(), SystemError> {
 
     return result.unwrap();
 }
+
+/// SysFS在KernFS的inode中的私有信息
+#[allow(dead_code)]
+#[derive(Debug)]
+pub enum SysFSKernPrivateData {
+    Dir(SysKernDirPriv),
+    File(SysKernFilePriv),
+}
+
+/// sysfs文件目录的属性组
+pub trait AttributeGroup: Debug + Send + Sync {
+    fn name(&self) -> &str;
+    fn attrs(&self) -> &[&'static dyn Attribute];
+    fn is_visible(&self, kobj: Arc<dyn KObject>, attr: &dyn Attribute) -> bool;
+}
+
+/// sysfs文件的属性
+pub trait Attribute: Debug + Send + Sync {
+    fn name(&self) -> &str;
+    fn mode(&self) -> ModeType;
+}

+ 17 - 13
kernel/src/filesystem/vfs/core.rs

@@ -1,7 +1,4 @@
-use core::{
-    hint::spin_loop,
-    sync::atomic::{AtomicUsize, Ordering},
-};
+use core::{hint::spin_loop, sync::atomic::Ordering};
 
 use alloc::{format, string::ToString, sync::Arc};
 
@@ -16,7 +13,7 @@ use crate::{
         procfs::procfs_init,
         ramfs::RamFS,
         sysfs::sysfs_init,
-        vfs::{mount::MountFS, FileSystem, FileType},
+        vfs::{mount::MountFS, syscall::ModeType, AtomicInodeId, FileSystem, FileType},
     },
     include::bindings::bindings::PAGE_4K_SIZE,
     kdebug, kerror, kinfo,
@@ -31,8 +28,8 @@ use super::{file::FileMode, utils::rsplit_path, IndexNode, InodeId};
 /// [0]: 对应'.'目录项
 /// [1]: 对应'..'目录项
 pub fn generate_inode_id() -> InodeId {
-    static INO: AtomicUsize = AtomicUsize::new(1);
-    return INO.fetch_add(1, Ordering::SeqCst);
+    static INO: AtomicInodeId = AtomicInodeId::new(InodeId::new(1));
+    return INO.fetch_add(InodeId::new(1), Ordering::SeqCst);
 }
 
 static mut __ROOT_INODE: Option<Arc<dyn IndexNode>> = None;
@@ -59,13 +56,13 @@ pub extern "C" fn vfs_init() -> i32 {
 
     // 创建文件夹
     root_inode
-        .create("proc", FileType::Dir, 0o777)
+        .create("proc", FileType::Dir, ModeType::from_bits_truncate(0o755))
         .expect("Failed to create /proc");
     root_inode
-        .create("dev", FileType::Dir, 0o777)
+        .create("dev", FileType::Dir, ModeType::from_bits_truncate(0o755))
         .expect("Failed to create /dev");
     root_inode
-        .create("sys", FileType::Dir, 0o777)
+        .create("sys", FileType::Dir, ModeType::from_bits_truncate(0o755))
         .expect("Failed to create /sys");
     kdebug!("dir in root:{:?}", root_inode.list());
 
@@ -94,7 +91,11 @@ fn do_migrate(
     let r = new_root_inode.find(mountpoint_name);
     let mountpoint = if r.is_err() {
         new_root_inode
-            .create(mountpoint_name, FileType::Dir, 0o777)
+            .create(
+                mountpoint_name,
+                FileType::Dir,
+                ModeType::from_bits_truncate(0o755),
+            )
             .expect(format!("Failed to create '/{mountpoint_name}' in migrating").as_str())
     } else {
         r.unwrap()
@@ -191,8 +192,11 @@ pub fn do_mkdir(path: &str, _mode: FileMode) -> Result<u64, SystemError> {
             let parent_inode: Arc<dyn IndexNode> =
                 ROOT_INODE().lookup(parent_path.unwrap_or("/"))?;
             // 创建文件夹
-            let _create_inode: Arc<dyn IndexNode> =
-                parent_inode.create(filename, FileType::Dir, 0o777)?;
+            let _create_inode: Arc<dyn IndexNode> = parent_inode.create(
+                filename,
+                FileType::Dir,
+                ModeType::from_bits_truncate(0o755),
+            )?;
         } else {
             // 不需要创建文件,因此返回错误码
             return Err(errno);

+ 3 - 3
kernel/src/filesystem/vfs/file.rs

@@ -14,7 +14,7 @@ use crate::{
     syscall::SystemError,
 };
 
-use super::{Dirent, FileType, IndexNode, Metadata};
+use super::{Dirent, FileType, IndexNode, InodeId, Metadata};
 
 /// 文件私有信息的枚举类型
 #[derive(Debug, Clone)]
@@ -185,7 +185,7 @@ impl File {
     }
 
     /// @brief 根据inode号获取子目录项的名字
-    pub fn get_entry_name(&self, ino: usize) -> Result<String, SystemError> {
+    pub fn get_entry_name(&self, ino: InodeId) -> Result<String, SystemError> {
         return self.inode.get_entry_name(ino);
     }
 
@@ -276,7 +276,7 @@ impl File {
         let name_bytes: &[u8] = name.as_bytes();
 
         self.offset += 1;
-        dirent.d_ino = sub_inode.metadata().unwrap().inode_id as u64;
+        dirent.d_ino = sub_inode.metadata().unwrap().inode_id.into() as u64;
         dirent.d_off = 0;
         dirent.d_reclen = 0;
         dirent.d_type = sub_inode.metadata().unwrap().file_type.get_file_type_num() as u8;

+ 10 - 10
kernel/src/filesystem/vfs/mod.rs

@@ -7,20 +7,20 @@ pub mod mount;
 pub mod syscall;
 mod utils;
 
-use ::core::{any::Any, fmt::Debug};
+use ::core::{any::Any, fmt::Debug, sync::atomic::AtomicUsize};
 
 use alloc::{string::String, sync::Arc, vec::Vec};
 
 use crate::{libs::casting::DowncastArc, syscall::SystemError, time::TimeSpec};
 
-use self::{core::generate_inode_id, file::FileMode};
+use self::{core::generate_inode_id, file::FileMode, syscall::ModeType};
 pub use self::{core::ROOT_INODE, file::FilePrivateData, mount::MountFS};
 
 /// vfs容许的最大的路径名称长度
 pub const MAX_PATHLEN: usize = 1024;
 
-/// 定义inode号的类型为usize
-pub type InodeId = usize;
+// 定义inode号
+int_like!(InodeId, AtomicInodeId, usize, AtomicUsize);
 
 /// 文件的类型
 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -185,7 +185,7 @@ pub trait IndexNode: Any + Sync + Send + Debug {
         &self,
         name: &str,
         file_type: FileType,
-        mode: u32,
+        mode: ModeType,
     ) -> Result<Arc<dyn IndexNode>, SystemError> {
         // 若文件系统没有实现此方法,则默认调用其create_with_data方法。如果仍未实现,则会得到一个Err(-EOPNOTSUPP_OR_ENOTSUP)的返回值
         return self.create_with_data(name, file_type, mode, 0);
@@ -204,7 +204,7 @@ pub trait IndexNode: Any + Sync + Send + Debug {
         &self,
         _name: &str,
         _file_type: FileType,
-        _mode: u32,
+        _mode: ModeType,
         _data: usize,
     ) -> Result<Arc<dyn IndexNode>, SystemError> {
         // 若文件系统没有实现此方法,则返回“不支持”
@@ -477,7 +477,7 @@ pub struct Metadata {
     pub file_type: FileType,
 
     /// 权限
-    pub mode: u32,
+    pub mode: ModeType,
 
     /// 硬链接的数量
     pub nlinks: usize,
@@ -496,7 +496,7 @@ impl Default for Metadata {
     fn default() -> Self {
         return Self {
             dev_id: 0,
-            inode_id: 0,
+            inode_id: InodeId::new(0),
             size: 0,
             blk_size: 0,
             blocks: 0,
@@ -504,7 +504,7 @@ impl Default for Metadata {
             mtime: TimeSpec::default(),
             ctime: TimeSpec::default(),
             file_type: FileType::File,
-            mode: 0,
+            mode: ModeType::empty(),
             nlinks: 1,
             uid: 0,
             gid: 0,
@@ -551,7 +551,7 @@ pub struct Dirent {
 }
 
 impl Metadata {
-    pub fn new(file_type: FileType, mode: u32) -> Self {
+    pub fn new(file_type: FileType, mode: ModeType) -> Self {
         Metadata {
             dev_id: 0,
             inode_id: generate_inode_id(),

+ 5 - 3
kernel/src/filesystem/vfs/mount.rs

@@ -10,7 +10,9 @@ use alloc::{
 
 use crate::{libs::spinlock::SpinLock, syscall::SystemError};
 
-use super::{file::FileMode, FilePrivateData, FileSystem, FileType, IndexNode, InodeId};
+use super::{
+    file::FileMode, syscall::ModeType, FilePrivateData, FileSystem, FileType, IndexNode, InodeId,
+};
 
 /// @brief 挂载文件系统
 /// 挂载文件系统的时候,套了MountFS这一层,以实现文件系统的递归挂载
@@ -141,7 +143,7 @@ impl IndexNode for MountFSInode {
         &self,
         name: &str,
         file_type: FileType,
-        mode: u32,
+        mode: ModeType,
         data: usize,
     ) -> Result<Arc<dyn IndexNode>, SystemError> {
         return Ok(MountFSInode {
@@ -213,7 +215,7 @@ impl IndexNode for MountFSInode {
         &self,
         name: &str,
         file_type: FileType,
-        mode: u32,
+        mode: ModeType,
     ) -> Result<Arc<dyn IndexNode>, SystemError> {
         return Ok(MountFSInode {
             inner_inode: self.inner_inode.create(name, file_type, mode)?,

+ 8 - 4
kernel/src/filesystem/vfs/syscall.rs

@@ -31,6 +31,7 @@ pub const SEEK_MAX: u32 = 3;
 
 bitflags! {
     /// 文件类型和权限
+    #[repr(C)]
     pub struct ModeType: u32 {
         /// 掩码
         const S_IFMT = 0o0_170_000;
@@ -154,8 +155,11 @@ impl Syscall {
                 let parent_inode: Arc<dyn IndexNode> =
                     ROOT_INODE().lookup(parent_path.unwrap_or("/"))?;
                 // 创建文件
-                let inode: Arc<dyn IndexNode> =
-                    parent_inode.create(filename, FileType::File, 0o777)?;
+                let inode: Arc<dyn IndexNode> = parent_inode.create(
+                    filename,
+                    FileType::File,
+                    ModeType::from_bits_truncate(0o755),
+                )?;
                 inode
             } else {
                 // 不需要创建文件,因此返回错误码
@@ -649,7 +653,7 @@ impl Syscall {
         let metadata = file.lock().metadata()?;
         kstat.size = metadata.size as i64;
         kstat.dev_id = metadata.dev_id as u64;
-        kstat.inode = metadata.inode_id as u64;
+        kstat.inode = metadata.inode_id.into() as u64;
         kstat.blcok_size = metadata.blk_size as i64;
         kstat.blocks = metadata.blocks as u64;
 
@@ -664,7 +668,7 @@ impl Syscall {
         kstat.uid = metadata.uid as i32;
         kstat.gid = metadata.gid as i32;
         kstat.rdev = metadata.raw_dev as i64;
-        kstat.mode.bits = metadata.mode;
+        kstat.mode = metadata.mode;
         match file.lock().file_type() {
             FileType::File => kstat.mode.insert(ModeType::S_IFMT),
             FileType::Dir => kstat.mode.insert(ModeType::S_IFDIR),

+ 3 - 3
kernel/src/ipc/pipe.rs

@@ -2,8 +2,8 @@ use crate::{
     arch::{sched::sched, CurrentIrqArch},
     exception::InterruptArch,
     filesystem::vfs::{
-        core::generate_inode_id, file::FileMode, FilePrivateData, FileSystem, FileType, IndexNode,
-        Metadata, PollStatus,
+        core::generate_inode_id, file::FileMode, syscall::ModeType, FilePrivateData, FileSystem,
+        FileType, IndexNode, Metadata, PollStatus,
     },
     libs::{spinlock::SpinLock, wait_queue::WaitQueue},
     process::ProcessState,
@@ -56,7 +56,7 @@ impl LockedPipeInode {
                 mtime: TimeSpec::default(),
                 ctime: TimeSpec::default(),
                 file_type: FileType::Pipe,
-                mode: 0o666,
+                mode: ModeType::from_bits_truncate(0o666),
                 nlinks: 1,
                 uid: 0,
                 gid: 0,

+ 2 - 2
kernel/src/net/socket.rs

@@ -10,7 +10,7 @@ use smoltcp::{
 use crate::{
     arch::rand::rand,
     driver::net::NetDriver,
-    filesystem::vfs::{FileType, IndexNode, Metadata, PollStatus},
+    filesystem::vfs::{syscall::ModeType, FileType, IndexNode, Metadata, PollStatus},
     kerror, kwarn,
     libs::{
         spinlock::{SpinLock, SpinLockGuard},
@@ -1215,7 +1215,7 @@ impl IndexNode for SocketInode {
 
     fn metadata(&self) -> Result<crate::filesystem::vfs::Metadata, SystemError> {
         let meta = Metadata {
-            mode: 0o777,
+            mode: ModeType::from_bits_truncate(0o755),
             file_type: FileType::Socket,
             ..Default::default()
         };