From dd9f1fc1a42406461e6f0d38cce1e56e22a1a15f Mon Sep 17 00:00:00 2001 From: TingHuang <92705854+TingSHub@users.noreply.github.com> Date: Fri, 21 Apr 2023 16:03:42 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9ESysFS=20(#250)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 添加sysfs * 注册sysfs * 添加sysfs相关 * 添加rust-anlyzer辅助配置 * 将设备与sysfs相关联 * 添加单独的文件管理sysfs下的文件夹 --- .vscode/settings.json | 5 +- kernel/src/driver/base/device/bus.rs | 33 +- kernel/src/driver/base/device/mod.rs | 12 + kernel/src/driver/base/platform/mod.rs | 1 + kernel/src/filesystem/mod.rs | 1 + kernel/src/filesystem/sysfs/bus.rs | 54 +++ kernel/src/filesystem/sysfs/class.rs | 66 ++++ kernel/src/filesystem/sysfs/devices.rs | 33 ++ kernel/src/filesystem/sysfs/fs.rs | 33 ++ kernel/src/filesystem/sysfs/mod.rs | 446 +++++++++++++++++++++++++ kernel/src/filesystem/vfs/core.rs | 17 + 11 files changed, 697 insertions(+), 4 deletions(-) create mode 100644 kernel/src/filesystem/sysfs/bus.rs create mode 100644 kernel/src/filesystem/sysfs/class.rs create mode 100644 kernel/src/filesystem/sysfs/devices.rs create mode 100644 kernel/src/filesystem/sysfs/fs.rs create mode 100644 kernel/src/filesystem/sysfs/mod.rs diff --git a/.vscode/settings.json b/.vscode/settings.json index eb8af2a1..b2c684d6 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -178,5 +178,8 @@ "C_Cpp.errorSquiggles": "Enabled", "esbonio.sphinx.confDir": "", "rust-analyzer.cargo.target": "x86_64-unknown-none", - "rust-analyzer.checkOnSave.allTargets": false + "rust-analyzer.checkOnSave.allTargets": false, + "rust-analyzer.linkedProjects": [ + "./kernel/Cargo.toml" + ] } \ No newline at end of file diff --git a/kernel/src/driver/base/device/bus.rs b/kernel/src/driver/base/device/bus.rs index 9fb697e3..911fd8ed 100644 --- a/kernel/src/driver/base/device/bus.rs +++ b/kernel/src/driver/base/device/bus.rs @@ -1,5 +1,9 @@ -use super::{driver::Driver, Device, DeviceState, IdTable}; -use crate::libs::spinlock::SpinLock; +use super::{driver::Driver, Device, DeviceError, DeviceState, IdTable}; +use crate::{ + filesystem::sysfs::{self, SYS_BUS_INODE}, + kdebug, + libs::spinlock::SpinLock, +}; use alloc::{collections::BTreeMap, sync::Arc}; use core::fmt::Debug; use lazy_static::lazy_static; @@ -54,7 +58,30 @@ pub trait BusDriver: Driver { } /// @brief: 总线设备trait,所有总线都应实现该trait -pub trait Bus: Device {} +pub trait Bus: Device { + /// @brief: 注册bus,在sysfs中生成相应文件夹 + /// @parameter name: 文件夹名 + /// @return: 注册成功,返回(),注册失败,返回错误码 + fn register_bus(&self, name: &str) -> Result<(), DeviceError> { + match self.register_device(name) { + Ok(_) => { + let bus = sysfs::bus::bus_register(name).unwrap(); + kdebug!( + "After register_bus: ls /sys/bus/: {:?}", + SYS_BUS_INODE().list() + ); + match sysfs::bus::bus_init(&bus) { + Ok(_) => { + kdebug!("After register_bus: ls /sys/bus/{}: {:?}", name, bus.list()); + return Ok(()); + } + Err(_) => Err(DeviceError::RegisterError), + } + } + Err(err) => Err(err), + } + } +} /// @brief: 总线管理结构体 #[derive(Debug, Clone)] diff --git a/kernel/src/driver/base/device/mod.rs b/kernel/src/driver/base/device/mod.rs index 3951b38a..a70ad764 100644 --- a/kernel/src/driver/base/device/mod.rs +++ b/kernel/src/driver/base/device/mod.rs @@ -1,3 +1,4 @@ +use crate::filesystem::sysfs::devices::device_register; use core::{any::Any, fmt::Debug}; pub mod bus; @@ -49,6 +50,7 @@ pub enum DeviceError { InitializeFailed, // 初始化错误 NoDeviceForDriver, // 没有合适的设备匹配驱动 NoDriverForDevice, // 没有合适的驱动匹配设备 + RegisterError, // 注册失败 } /// @brief: 将u32类型转换为设备状态类型 @@ -84,4 +86,14 @@ pub trait Device: Any + Send + Sync + Debug { /// @parameter: None /// @return: 该设备唯一标识 fn get_id_table(&self) -> IdTable; + + /// @brief: 设备注册 + /// @parameter: name: 设备名 + /// @return: 操作成功,返回(),操作失败,返回错误码 + fn register_device(&self, name: &str) -> Result<(), DeviceError> { + match device_register(name) { + Ok(_) => Ok(()), + Err(_) => Err(DeviceError::RegisterError), + } + } } diff --git a/kernel/src/driver/base/platform/mod.rs b/kernel/src/driver/base/platform/mod.rs index 61d2aa14..862c4848 100644 --- a/kernel/src/driver/base/platform/mod.rs +++ b/kernel/src/driver/base/platform/mod.rs @@ -345,6 +345,7 @@ pub fn platform_bus_init() { BUS_PLATFORM_DEVICE.clone(), ); BUS_PLATFORM_DEVICE.set_state(BusState::Initialized); + let _ = BUS_PLATFORM_DEVICE.register_bus("platform"); } #[no_mangle] diff --git a/kernel/src/filesystem/mod.rs b/kernel/src/filesystem/mod.rs index e0de780b..c848c897 100644 --- a/kernel/src/filesystem/mod.rs +++ b/kernel/src/filesystem/mod.rs @@ -3,4 +3,5 @@ pub mod fat; pub mod mbr; pub mod procfs; pub mod ramfs; +pub mod sysfs; pub mod vfs; diff --git a/kernel/src/filesystem/sysfs/bus.rs b/kernel/src/filesystem/sysfs/bus.rs new file mode 100644 index 00000000..39760cb4 --- /dev/null +++ b/kernel/src/filesystem/sysfs/bus.rs @@ -0,0 +1,54 @@ +use super::{LockedSysFSInode, SYS_BUS_INODE}; +use crate::{filesystem::vfs::IndexNode, kdebug, syscall::SystemError}; +use alloc::sync::Arc; + +/// @brief: 注册bus,在sys/bus下生成文件夹 +/// @parameter bus_name: 总线文件夹名 +/// @return: 操作成功,返回inode,操作失败,返回错误码 +#[inline] +#[allow(dead_code)] +pub fn bus_register(bus_name: &str) -> Result, SystemError> { + let binding: Arc = SYS_BUS_INODE(); + kdebug!("Before bus_register: ls /sys/bus/: {:?}", binding.list()); + binding + .as_any_ref() + .downcast_ref::() + .ok_or(SystemError::E2BIG) + .unwrap() + .add_dir(bus_name) +} + +/// @brief: 注销bus,在sys/bus删除文件夹 +/// @parameter bus_name: 总线文件夹名 +/// @return: 操作成功,返回(),操作失败,返回错误码 +#[inline] +#[allow(dead_code)] +pub fn bus_unregister(bus_name: &str) -> Result<(), SystemError> { + let binding: Arc = SYS_BUS_INODE(); + binding + .as_any_ref() + .downcast_ref::() + .ok_or(SystemError::E2BIG) + .unwrap() + .remove(bus_name) +} + +/// @brief: 在相应总线文件夹下生成devices和drivers文件夹 +/// @parameter inode: 总线文件夹inode +/// @return: 操作成功,返回devices inode和drivers inode,操作失败,返回错误码 +#[inline] +#[allow(dead_code)] +pub fn bus_init( + inode: &Arc, +) -> Result<(Arc, Arc), SystemError> { + match inode.as_any_ref().downcast_ref::() { + Some(lock_bus) => match lock_bus.add_dir("devices") { + Ok(devices) => match lock_bus.add_dir("drivers") { + Ok(drivers) => Ok((devices, drivers)), + Err(err) => Err(err), + }, + Err(err) => Err(err), + }, + None => Err(SystemError::E2BIG), + } +} diff --git a/kernel/src/filesystem/sysfs/class.rs b/kernel/src/filesystem/sysfs/class.rs new file mode 100644 index 00000000..779fe596 --- /dev/null +++ b/kernel/src/filesystem/sysfs/class.rs @@ -0,0 +1,66 @@ +use super::{LockedSysFSInode, SYS_CLASS_INODE}; +use crate::{filesystem::vfs::IndexNode, syscall::SystemError}; +use alloc::sync::Arc; + +/// @brief: 注册class,在sys/class下生成文件夹 +/// @parameter class_name: 类文件夹名 +/// @return: 操作成功,返回inode,操作失败,返回错误码 +#[inline] +#[allow(dead_code)] +pub fn class_register(class_name: &str) -> Result, SystemError> { + let binding: Arc = SYS_CLASS_INODE(); + binding + .as_any_ref() + .downcast_ref::() + .ok_or(SystemError::E2BIG) + .unwrap() + .add_dir(class_name) +} + +/// @brief: 注销class,在sys/class删除文件夹 +/// @parameter class_name: 总线文件夹名 +/// @return: 操作成功,返回(),操作失败,返回错误码 +#[inline] +#[allow(dead_code)] +pub fn class_unregister(class_name: &str) -> Result<(), SystemError> { + let binding: Arc = SYS_CLASS_INODE(); + binding + .as_any_ref() + .downcast_ref::() + .ok_or(SystemError::E2BIG) + .unwrap() + .remove(class_name) +} + +/// @brief: 注册device,在对应类下操作设备文件夹 +/// @parameter class: 类文件夹inode +/// @parameter device_name: 设备文件夹名 +/// @return: 操作成功,返回inode,操作失败,返回错误码 +#[inline] +#[allow(dead_code)] +pub fn device_register( + class: Arc, + device_name: &str, +) -> Result, SystemError> { + class + .as_any_ref() + .downcast_ref::() + .ok_or(SystemError::E2BIG) + .unwrap() + .add_dir(device_name) +} + +/// @brief: 操作device,在对应类下删除设备文件夹 +/// @parameter class: 类文件夹inode +/// @parameter device_name: 设备文件夹名 +/// @return: 操作成功,返回(),操作失败,返回错误码 +#[inline] +#[allow(dead_code)] +pub fn device_unregister(class: Arc, device_name: &str) -> Result<(), SystemError> { + class + .as_any_ref() + .downcast_ref::() + .ok_or(SystemError::E2BIG) + .unwrap() + .remove(device_name) +} diff --git a/kernel/src/filesystem/sysfs/devices.rs b/kernel/src/filesystem/sysfs/devices.rs new file mode 100644 index 00000000..fd6ff5f3 --- /dev/null +++ b/kernel/src/filesystem/sysfs/devices.rs @@ -0,0 +1,33 @@ +use super::{LockedSysFSInode, SYS_DEVICES_INODE}; +use crate::{filesystem::vfs::IndexNode, syscall::SystemError}; +use alloc::sync::Arc; + +/// @brief: 注册device,在sys/devices下生成文件夹 +/// @parameter device_name: 类文件夹名 +/// @return: 操作成功,返回inode,操作失败,返回错误码 +#[inline] +#[allow(dead_code)] +pub fn device_register(device_name: &str) -> Result, SystemError> { + let binding: Arc = SYS_DEVICES_INODE(); + binding + .as_any_ref() + .downcast_ref::() + .ok_or(SystemError::E2BIG) + .unwrap() + .add_dir(device_name) +} + +/// @brief: 操作bus,在sys/devices删除文件夹 +/// @parameter device_name: 总线文件夹名 +/// @return: 操作成功,返回(),操作失败,返回错误码 +#[inline] +#[allow(dead_code)] +pub fn device_unregister(device_name: &str) -> Result<(), SystemError> { + let binding: Arc = SYS_DEVICES_INODE(); + binding + .as_any_ref() + .downcast_ref::() + .ok_or(SystemError::E2BIG) + .unwrap() + .remove(device_name) +} diff --git a/kernel/src/filesystem/sysfs/fs.rs b/kernel/src/filesystem/sysfs/fs.rs new file mode 100644 index 00000000..3d555859 --- /dev/null +++ b/kernel/src/filesystem/sysfs/fs.rs @@ -0,0 +1,33 @@ +use super::{LockedSysFSInode, SYS_FS_INODE}; +use crate::{filesystem::vfs::IndexNode, syscall::SystemError}; +use alloc::sync::Arc; + +/// @brief: 注册fs,在sys/fs下是生成文件夹 +/// @parameter fs_name: 类文件夹名 +/// @return: 操作成功,返回inode,操作失败,返回错误码 +#[inline] +#[allow(dead_code)] +pub fn fs_register(fs_name: &str) -> Result, SystemError> { + let binding: Arc = SYS_FS_INODE(); + binding + .as_any_ref() + .downcast_ref::() + .ok_or(SystemError::E2BIG) + .unwrap() + .add_dir(fs_name) +} + +/// @brief: 注销fs,在sys/fs删除文件夹 +/// @parameter fs_name: 总线文件夹名 +/// @return: 操作成功,返回(),操作失败,返回错误码 +#[inline] +#[allow(dead_code)] +pub fn fs_unregister(fs_name: &str) -> Result<(), SystemError> { + let binding: Arc = SYS_FS_INODE(); + binding + .as_any_ref() + .downcast_ref::() + .ok_or(SystemError::E2BIG) + .unwrap() + .remove(fs_name) +} diff --git a/kernel/src/filesystem/sysfs/mod.rs b/kernel/src/filesystem/sysfs/mod.rs new file mode 100644 index 00000000..90d5d770 --- /dev/null +++ b/kernel/src/filesystem/sysfs/mod.rs @@ -0,0 +1,446 @@ +use super::vfs::{ + core::generate_inode_id, file::FileMode, FileSystem, FileType, FsInfo, IndexNode, Metadata, + PollStatus, +}; +use crate::{ + libs::spinlock::{SpinLock, SpinLockGuard}, + syscall::SystemError, + time::TimeSpec, +}; +use alloc::{ + boxed::Box, + collections::BTreeMap, + string::{String, ToString}, + sync::{Arc, Weak}, + vec::Vec, +}; +use core::ptr::null_mut; + +pub mod bus; +pub mod class; +pub mod devices; +pub mod fs; + +const SYSFS_MAX_NAMELEN: usize = 64; + +static mut __SYS_DEVICES_INODE: *mut Arc = null_mut(); +static mut __SYS_BUS_INODE: *mut Arc = null_mut(); +static mut __SYS_CLASS_INODE: *mut Arc = null_mut(); +static mut __SYS_FS_INODE: *mut Arc = null_mut(); + +/// @brief 获取全局的sys/devices节点 +#[inline(always)] +#[allow(non_snake_case)] +pub fn SYS_DEVICES_INODE() -> Arc { + unsafe { + return __SYS_DEVICES_INODE.as_ref().unwrap().clone(); + } +} + +/// @brief 获取全局的sys/bus节点 +#[inline(always)] +#[allow(non_snake_case)] +pub fn SYS_BUS_INODE() -> Arc { + unsafe { + return __SYS_BUS_INODE.as_ref().unwrap().clone(); + } +} + +/// @brief 获取全局的sys/class节点 +#[inline(always)] +#[allow(non_snake_case)] +pub fn SYS_CLASS_INODE() -> Arc { + unsafe { + return __SYS_CLASS_INODE.as_ref().unwrap().clone(); + } +} + +/// @brief 获取全局的sys/fs节点 +#[inline(always)] +#[allow(non_snake_case)] +pub fn SYS_FS_INODE() -> Arc { + unsafe { + return __SYS_FS_INODE.as_ref().unwrap().clone(); + } +} + +/// @brief dev文件系统 +#[derive(Debug)] +pub struct SysFS { + // 文件系统根节点 + root_inode: Arc, +} + +impl FileSystem for SysFS { + fn as_any_ref(&self) -> &dyn core::any::Any { + self + } + + fn root_inode(&self) -> Arc { + return self.root_inode.clone(); + } + + fn info(&self) -> super::vfs::FsInfo { + return FsInfo { + blk_dev_id: 0, + max_name_len: SYSFS_MAX_NAMELEN, + }; + } +} + +impl SysFS { + pub fn new() -> Arc { + // 初始化root inode + let root: Arc = Arc::new(LockedSysFSInode(SpinLock::new( + // /sys 的权限设置为 读+执行,root 可以读写 + // root 的 parent 是空指针 + SysFSInode::new(FileType::Dir, 0o755 as u32, 0), + ))); + + let sysfs: Arc = Arc::new(SysFS { root_inode: root }); + + // 对root inode加锁,并继续完成初始化工作 + let mut root_guard: SpinLockGuard = sysfs.root_inode.0.lock(); + root_guard.parent = Arc::downgrade(&sysfs.root_inode); + root_guard.self_ref = Arc::downgrade(&sysfs.root_inode); + root_guard.fs = Arc::downgrade(&sysfs); + // 释放锁 + drop(root_guard); + + // 创建文件夹 + let root: &Arc = &sysfs.root_inode; + match root.add_dir("devices") { + Ok(devices) => unsafe { + __SYS_DEVICES_INODE = Box::leak(Box::new(devices)); + }, + Err(_) => panic!("SysFS: Failed to create /sys/devices"), + } + + match root.add_dir("bus") { + Ok(bus) => unsafe { + __SYS_BUS_INODE = Box::leak(Box::new(bus)); + }, + Err(_) => panic!("SysFS: Failed to create /sys/bus"), + } + + match root.add_dir("class") { + Ok(class) => unsafe { + __SYS_CLASS_INODE = Box::leak(Box::new(class)); + }, + Err(_) => panic!("SysFS: Failed to create /sys/class"), + } + + match root.add_dir("fs") { + Ok(fs) => unsafe { + __SYS_FS_INODE = Box::leak(Box::new(fs)); + }, + Err(_) => panic!("SysFS: Failed to create /sys/fs"), + } + // 初始化platform总线 + crate::driver::base::platform::platform_bus_init(); + return sysfs; + } +} + +/// @brief sys文件i节点(锁) +#[derive(Debug)] +pub struct LockedSysFSInode(SpinLock); + +impl IndexNode for LockedSysFSInode { + fn as_any_ref(&self) -> &dyn core::any::Any { + self + } + + fn open( + &self, + _data: &mut super::vfs::FilePrivateData, + _mode: &FileMode, + ) -> Result<(), SystemError> { + return Ok(()); + } + + fn close(&self, _data: &mut super::vfs::FilePrivateData) -> Result<(), SystemError> { + return Ok(()); + } + + fn read_at( + &self, + _offset: usize, + _len: usize, + _buf: &mut [u8], + _data: &mut super::vfs::FilePrivateData, + ) -> Result { + return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); + } + + fn write_at( + &self, + _offset: usize, + _len: usize, + _buf: &[u8], + _data: &mut super::vfs::FilePrivateData, + ) -> Result { + return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); + } + + fn poll(&self) -> Result { + // 加锁 + let inode: SpinLockGuard = self.0.lock(); + + // 检查当前inode是否为一个文件夹,如果是的话,就返回错误 + if inode.metadata.file_type == FileType::Dir { + return Err(SystemError::EISDIR); + } + + return Ok(PollStatus::READ | PollStatus::WRITE); + } + + fn metadata(&self) -> Result { + return Ok(self.0.lock().metadata.clone()); + } + + fn fs(&self) -> Arc { + return self.0.lock().fs.upgrade().unwrap(); + } + + fn get_entry_name(&self, ino: super::vfs::InodeId) -> Result { + let inode: SpinLockGuard = self.0.lock(); + if inode.metadata.file_type != FileType::Dir { + return Err(SystemError::ENOTDIR); + } + + match ino { + 0 => { + return Ok(String::from(".")); + } + 1 => { + return Ok(String::from("..")); + } + ino => { + // 暴力遍历所有的children,判断inode id是否相同 + // TODO: 优化这里,这个地方性能很差! + let mut key: Vec = inode + .children + .keys() + .filter(|k| inode.children.get(*k).unwrap().metadata().unwrap().inode_id == 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) + } + } + } + } + + fn find(&self, name: &str) -> Result, SystemError> { + let inode = self.0.lock(); + + if inode.metadata.file_type != FileType::Dir { + return Err(SystemError::ENOTDIR); + } + + match name { + "" | "." => { + return Ok(inode.self_ref.upgrade().ok_or(SystemError::ENOENT)?); + } + ".." => { + return Ok(inode.parent.upgrade().ok_or(SystemError::ENOENT)?); + } + name => { + // 在子目录项中查找 + // match inode.children.get(name) { + // Some(_) => {} + // None => kdebug!("Sysfs find {} error", name), + // } + return Ok(inode.children.get(name).ok_or(SystemError::ENOENT)?.clone()); + } + } + } + + fn ioctl(&self, _cmd: u32, _data: usize) -> Result { + Err(SystemError::EOPNOTSUPP_OR_ENOTSUP) + } + + fn list(&self) -> Result, SystemError> { + let info = self.metadata()?; + if info.file_type != FileType::Dir { + return Err(SystemError::ENOTDIR); + } + + let mut keys: Vec = Vec::new(); + keys.push(String::from(".")); + keys.push(String::from("..")); + keys.append(&mut self.0.lock().children.keys().cloned().collect()); + + return Ok(keys); + } +} + +impl LockedSysFSInode { + fn do_create_with_data( + &self, + mut guard: SpinLockGuard, + _name: &str, + _file_type: FileType, + _mode: u32, + _data: usize, + ) -> Result, SystemError> { + if guard.metadata.file_type != FileType::Dir { + return Err(SystemError::ENOTDIR); + } + + // 如果有重名的,则返回 + if guard.children.contains_key(_name) { + return Err(SystemError::EEXIST); + } + + // 创建inode + let result: Arc = Arc::new(LockedSysFSInode(SpinLock::new(SysFSInode { + parent: guard.self_ref.clone(), + self_ref: Weak::default(), + children: BTreeMap::new(), + metadata: Metadata { + dev_id: 0, + inode_id: generate_inode_id(), + size: 0, + blk_size: 0, + blocks: 0, + atime: TimeSpec::default(), + mtime: TimeSpec::default(), + ctime: TimeSpec::default(), + file_type: _file_type, + mode: _mode, + nlinks: 1, + uid: 0, + gid: 0, + raw_dev: _data, + }, + fs: guard.fs.clone(), + }))); + + // 初始化inode的自引用的weak指针 + result.0.lock().self_ref = Arc::downgrade(&result); + + // 将子inode插入父inode的B树中 + guard.children.insert(String::from(_name), result.clone()); + return Ok(result); + } + + /// @brief 在当前目录下,创建一个目录 + /// @param name: 目录名 + /// @return 成功返回目录inode, 失败返回Err(错误码) + #[inline] + #[allow(dead_code)] + pub fn add_dir(&self, name: &str) -> Result, SystemError> { + let guard: SpinLockGuard = self.0.lock(); + + if guard.children.contains_key(name) { + return Err(SystemError::EEXIST); + } + + match self.do_create_with_data(guard, name, FileType::Dir, 0o755 as u32, 0) { + Ok(inode) => return Ok(inode), + Err(err) => { + return Err(err); + } + }; + } + + /// @brief 在当前目录下,创建一个二进制文件 + /// @param name: 文件名 + /// @return 成功返回Ok(()), 失败返回Err(错误码) + #[inline] + #[allow(dead_code)] + pub fn add_file(&self, name: &str, file: Arc) -> Result<(), SystemError> { + let mut this = self.0.lock(); + + if this.children.contains_key(name) { + return Err(SystemError::EEXIST); + } + + this.children.insert(name.to_string(), file); + return Ok(()); + } + + /// @brief 为该inode创建硬链接 + /// @param None + /// @return 当前inode强引用 + #[inline] + #[allow(dead_code)] + pub fn link(&self) -> Arc { + return self + .0 + .lock() + .self_ref + .clone() + .upgrade() + .ok_or(SystemError::E2BIG) + .unwrap(); + } + + pub fn remove(&self, name: &str) -> Result<(), SystemError> { + let x = self + .0 + .lock() + .children + .remove(name) + .ok_or(SystemError::ENOENT)?; + + drop(x); + return Ok(()); + } +} + +/// @brief sys文件i节点(无锁) +#[derive(Debug)] +pub struct SysFSInode { + /// 指向父Inode的弱引用 + parent: Weak, + /// 指向自身的弱引用 + self_ref: Weak, + /// 子Inode的B树 + children: BTreeMap>, + /// 指向inode所在的文件系统对象的指针 + fs: Weak, + /// INode 元数据 + metadata: Metadata, +} + +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_with_parent( + parent: Weak, + dev_type_: FileType, + mode_: u32, + data_: usize, + ) -> Self { + return SysFSInode { + parent: parent, + self_ref: Weak::default(), + children: BTreeMap::new(), + metadata: Metadata { + dev_id: 1, + inode_id: generate_inode_id(), + size: 0, + blk_size: 0, + blocks: 0, + atime: TimeSpec::default(), + mtime: TimeSpec::default(), + ctime: TimeSpec::default(), + file_type: dev_type_, // 文件夹 + mode: mode_, + nlinks: 1, + uid: 0, + gid: 0, + raw_dev: data_, + }, + fs: Weak::default(), + }; + } +} diff --git a/kernel/src/filesystem/vfs/core.rs b/kernel/src/filesystem/vfs/core.rs index 94294f70..68ac6e41 100644 --- a/kernel/src/filesystem/vfs/core.rs +++ b/kernel/src/filesystem/vfs/core.rs @@ -14,6 +14,7 @@ use crate::{ fat::fs::FATFileSystem, procfs::ProcFS, ramfs::RamFS, + sysfs::SysFS, vfs::{file::File, mount::MountFS, FileSystem, FileType}, }, include::bindings::bindings::PAGE_4K_SIZE, @@ -63,6 +64,9 @@ pub extern "C" fn vfs_init() -> i32 { root_inode .create("dev", FileType::Dir, 0o777) .expect("Failed to create /dev"); + root_inode + .create("sys", FileType::Dir, 0o777) + .expect("Failed to create /sys"); // // 创建procfs实例 let procfs: Arc = ProcFS::new(); @@ -85,6 +89,16 @@ pub extern "C" fn vfs_init() -> i32 { .expect("Failed to mount devfs"); kinfo!("DevFS mounted."); + // 创建 sysfs 实例 + let sysfs: Arc = SysFS::new(); + // sysfs 挂载 + let _t = root_inode + .find("sys") + .expect("Cannot find /sys") + .mount(sysfs) + .expect("Failed to mount sysfs"); + kinfo!("SysFS mounted."); + let root_inode = ROOT_INODE().list().expect("VFS init failed"); if root_inode.len() > 0 { kinfo!("Successfully initialized VFS!"); @@ -126,6 +140,8 @@ fn migrate_virtual_filesystem(new_fs: Arc) -> Result<(), SystemE let proc: &MountFS = binding.as_any_ref().downcast_ref::().unwrap(); let binding = ROOT_INODE().find("dev").expect("DevFS not mounted!").fs(); let dev: &MountFS = binding.as_any_ref().downcast_ref::().unwrap(); + let binding = ROOT_INODE().find("sys").expect("SysFs not mounted!").fs(); + let sys: &MountFS = binding.as_any_ref().downcast_ref::().unwrap(); let new_fs = MountFS::new(new_fs, None); // 获取新的根文件系统的根节点的引用 @@ -134,6 +150,7 @@ fn migrate_virtual_filesystem(new_fs: Arc) -> Result<(), SystemE // 把上述文件系统,迁移到新的文件系统下 do_migrate(new_root_inode.clone(), "proc", proc)?; do_migrate(new_root_inode.clone(), "dev", dev)?; + do_migrate(new_root_inode.clone(), "sys", sys)?; unsafe { // drop旧的Root inode