mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 07:06:47 +00:00
新增SysFS (#250)
* 添加sysfs * 注册sysfs * 添加sysfs相关 * 添加rust-anlyzer辅助配置 * 将设备与sysfs相关联 * 添加单独的文件管理sysfs下的文件夹
This commit is contained in:
parent
cde5492f72
commit
dd9f1fc1a4
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
@ -178,5 +178,8 @@
|
|||||||
"C_Cpp.errorSquiggles": "Enabled",
|
"C_Cpp.errorSquiggles": "Enabled",
|
||||||
"esbonio.sphinx.confDir": "",
|
"esbonio.sphinx.confDir": "",
|
||||||
"rust-analyzer.cargo.target": "x86_64-unknown-none",
|
"rust-analyzer.cargo.target": "x86_64-unknown-none",
|
||||||
"rust-analyzer.checkOnSave.allTargets": false
|
"rust-analyzer.checkOnSave.allTargets": false,
|
||||||
|
"rust-analyzer.linkedProjects": [
|
||||||
|
"./kernel/Cargo.toml"
|
||||||
|
]
|
||||||
}
|
}
|
@ -1,5 +1,9 @@
|
|||||||
use super::{driver::Driver, Device, DeviceState, IdTable};
|
use super::{driver::Driver, Device, DeviceError, DeviceState, IdTable};
|
||||||
use crate::libs::spinlock::SpinLock;
|
use crate::{
|
||||||
|
filesystem::sysfs::{self, SYS_BUS_INODE},
|
||||||
|
kdebug,
|
||||||
|
libs::spinlock::SpinLock,
|
||||||
|
};
|
||||||
use alloc::{collections::BTreeMap, sync::Arc};
|
use alloc::{collections::BTreeMap, sync::Arc};
|
||||||
use core::fmt::Debug;
|
use core::fmt::Debug;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
@ -54,7 +58,30 @@ pub trait BusDriver: Driver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @brief: 总线设备trait,所有总线都应实现该trait
|
/// @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: 总线管理结构体
|
/// @brief: 总线管理结构体
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use crate::filesystem::sysfs::devices::device_register;
|
||||||
use core::{any::Any, fmt::Debug};
|
use core::{any::Any, fmt::Debug};
|
||||||
|
|
||||||
pub mod bus;
|
pub mod bus;
|
||||||
@ -49,6 +50,7 @@ pub enum DeviceError {
|
|||||||
InitializeFailed, // 初始化错误
|
InitializeFailed, // 初始化错误
|
||||||
NoDeviceForDriver, // 没有合适的设备匹配驱动
|
NoDeviceForDriver, // 没有合适的设备匹配驱动
|
||||||
NoDriverForDevice, // 没有合适的驱动匹配设备
|
NoDriverForDevice, // 没有合适的驱动匹配设备
|
||||||
|
RegisterError, // 注册失败
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief: 将u32类型转换为设备状态类型
|
/// @brief: 将u32类型转换为设备状态类型
|
||||||
@ -84,4 +86,14 @@ pub trait Device: Any + Send + Sync + Debug {
|
|||||||
/// @parameter: None
|
/// @parameter: None
|
||||||
/// @return: 该设备唯一标识
|
/// @return: 该设备唯一标识
|
||||||
fn get_id_table(&self) -> IdTable;
|
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),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -345,6 +345,7 @@ pub fn platform_bus_init() {
|
|||||||
BUS_PLATFORM_DEVICE.clone(),
|
BUS_PLATFORM_DEVICE.clone(),
|
||||||
);
|
);
|
||||||
BUS_PLATFORM_DEVICE.set_state(BusState::Initialized);
|
BUS_PLATFORM_DEVICE.set_state(BusState::Initialized);
|
||||||
|
let _ = BUS_PLATFORM_DEVICE.register_bus("platform");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -3,4 +3,5 @@ pub mod fat;
|
|||||||
pub mod mbr;
|
pub mod mbr;
|
||||||
pub mod procfs;
|
pub mod procfs;
|
||||||
pub mod ramfs;
|
pub mod ramfs;
|
||||||
|
pub mod sysfs;
|
||||||
pub mod vfs;
|
pub mod vfs;
|
||||||
|
54
kernel/src/filesystem/sysfs/bus.rs
Normal file
54
kernel/src/filesystem/sysfs/bus.rs
Normal file
@ -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<Arc<dyn IndexNode>, SystemError> {
|
||||||
|
let binding: Arc<dyn IndexNode> = SYS_BUS_INODE();
|
||||||
|
kdebug!("Before bus_register: ls /sys/bus/: {:?}", binding.list());
|
||||||
|
binding
|
||||||
|
.as_any_ref()
|
||||||
|
.downcast_ref::<LockedSysFSInode>()
|
||||||
|
.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<dyn IndexNode> = SYS_BUS_INODE();
|
||||||
|
binding
|
||||||
|
.as_any_ref()
|
||||||
|
.downcast_ref::<LockedSysFSInode>()
|
||||||
|
.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<dyn IndexNode>,
|
||||||
|
) -> Result<(Arc<dyn IndexNode>, Arc<dyn IndexNode>), SystemError> {
|
||||||
|
match inode.as_any_ref().downcast_ref::<LockedSysFSInode>() {
|
||||||
|
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),
|
||||||
|
}
|
||||||
|
}
|
66
kernel/src/filesystem/sysfs/class.rs
Normal file
66
kernel/src/filesystem/sysfs/class.rs
Normal file
@ -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<Arc<dyn IndexNode>, SystemError> {
|
||||||
|
let binding: Arc<dyn IndexNode> = SYS_CLASS_INODE();
|
||||||
|
binding
|
||||||
|
.as_any_ref()
|
||||||
|
.downcast_ref::<LockedSysFSInode>()
|
||||||
|
.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<dyn IndexNode> = SYS_CLASS_INODE();
|
||||||
|
binding
|
||||||
|
.as_any_ref()
|
||||||
|
.downcast_ref::<LockedSysFSInode>()
|
||||||
|
.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<dyn IndexNode>,
|
||||||
|
device_name: &str,
|
||||||
|
) -> Result<Arc<dyn IndexNode>, SystemError> {
|
||||||
|
class
|
||||||
|
.as_any_ref()
|
||||||
|
.downcast_ref::<LockedSysFSInode>()
|
||||||
|
.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<dyn IndexNode>, device_name: &str) -> Result<(), SystemError> {
|
||||||
|
class
|
||||||
|
.as_any_ref()
|
||||||
|
.downcast_ref::<LockedSysFSInode>()
|
||||||
|
.ok_or(SystemError::E2BIG)
|
||||||
|
.unwrap()
|
||||||
|
.remove(device_name)
|
||||||
|
}
|
33
kernel/src/filesystem/sysfs/devices.rs
Normal file
33
kernel/src/filesystem/sysfs/devices.rs
Normal file
@ -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<Arc<dyn IndexNode>, SystemError> {
|
||||||
|
let binding: Arc<dyn IndexNode> = SYS_DEVICES_INODE();
|
||||||
|
binding
|
||||||
|
.as_any_ref()
|
||||||
|
.downcast_ref::<LockedSysFSInode>()
|
||||||
|
.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<dyn IndexNode> = SYS_DEVICES_INODE();
|
||||||
|
binding
|
||||||
|
.as_any_ref()
|
||||||
|
.downcast_ref::<LockedSysFSInode>()
|
||||||
|
.ok_or(SystemError::E2BIG)
|
||||||
|
.unwrap()
|
||||||
|
.remove(device_name)
|
||||||
|
}
|
33
kernel/src/filesystem/sysfs/fs.rs
Normal file
33
kernel/src/filesystem/sysfs/fs.rs
Normal file
@ -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<Arc<dyn IndexNode>, SystemError> {
|
||||||
|
let binding: Arc<dyn IndexNode> = SYS_FS_INODE();
|
||||||
|
binding
|
||||||
|
.as_any_ref()
|
||||||
|
.downcast_ref::<LockedSysFSInode>()
|
||||||
|
.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<dyn IndexNode> = SYS_FS_INODE();
|
||||||
|
binding
|
||||||
|
.as_any_ref()
|
||||||
|
.downcast_ref::<LockedSysFSInode>()
|
||||||
|
.ok_or(SystemError::E2BIG)
|
||||||
|
.unwrap()
|
||||||
|
.remove(fs_name)
|
||||||
|
}
|
446
kernel/src/filesystem/sysfs/mod.rs
Normal file
446
kernel/src/filesystem/sysfs/mod.rs
Normal file
@ -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<dyn IndexNode> = null_mut();
|
||||||
|
static mut __SYS_BUS_INODE: *mut Arc<dyn IndexNode> = null_mut();
|
||||||
|
static mut __SYS_CLASS_INODE: *mut Arc<dyn IndexNode> = null_mut();
|
||||||
|
static mut __SYS_FS_INODE: *mut Arc<dyn IndexNode> = null_mut();
|
||||||
|
|
||||||
|
/// @brief 获取全局的sys/devices节点
|
||||||
|
#[inline(always)]
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
pub fn SYS_DEVICES_INODE() -> Arc<dyn IndexNode> {
|
||||||
|
unsafe {
|
||||||
|
return __SYS_DEVICES_INODE.as_ref().unwrap().clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief 获取全局的sys/bus节点
|
||||||
|
#[inline(always)]
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
pub fn SYS_BUS_INODE() -> Arc<dyn IndexNode> {
|
||||||
|
unsafe {
|
||||||
|
return __SYS_BUS_INODE.as_ref().unwrap().clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief 获取全局的sys/class节点
|
||||||
|
#[inline(always)]
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
pub fn SYS_CLASS_INODE() -> Arc<dyn IndexNode> {
|
||||||
|
unsafe {
|
||||||
|
return __SYS_CLASS_INODE.as_ref().unwrap().clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief 获取全局的sys/fs节点
|
||||||
|
#[inline(always)]
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
pub fn SYS_FS_INODE() -> Arc<dyn IndexNode> {
|
||||||
|
unsafe {
|
||||||
|
return __SYS_FS_INODE.as_ref().unwrap().clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief dev文件系统
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct SysFS {
|
||||||
|
// 文件系统根节点
|
||||||
|
root_inode: Arc<LockedSysFSInode>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FileSystem for SysFS {
|
||||||
|
fn as_any_ref(&self) -> &dyn core::any::Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn root_inode(&self) -> Arc<dyn super::vfs::IndexNode> {
|
||||||
|
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<Self> {
|
||||||
|
// 初始化root inode
|
||||||
|
let root: Arc<LockedSysFSInode> = Arc::new(LockedSysFSInode(SpinLock::new(
|
||||||
|
// /sys 的权限设置为 读+执行,root 可以读写
|
||||||
|
// root 的 parent 是空指针
|
||||||
|
SysFSInode::new(FileType::Dir, 0o755 as u32, 0),
|
||||||
|
)));
|
||||||
|
|
||||||
|
let sysfs: Arc<SysFS> = Arc::new(SysFS { root_inode: root });
|
||||||
|
|
||||||
|
// 对root inode加锁,并继续完成初始化工作
|
||||||
|
let mut root_guard: SpinLockGuard<SysFSInode> = 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<LockedSysFSInode> = &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<SysFSInode>);
|
||||||
|
|
||||||
|
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<usize, SystemError> {
|
||||||
|
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_at(
|
||||||
|
&self,
|
||||||
|
_offset: usize,
|
||||||
|
_len: usize,
|
||||||
|
_buf: &[u8],
|
||||||
|
_data: &mut super::vfs::FilePrivateData,
|
||||||
|
) -> Result<usize, SystemError> {
|
||||||
|
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn poll(&self) -> Result<super::vfs::PollStatus, SystemError> {
|
||||||
|
// 加锁
|
||||||
|
let inode: SpinLockGuard<SysFSInode> = 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<Metadata, SystemError> {
|
||||||
|
return Ok(self.0.lock().metadata.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fs(&self) -> Arc<dyn FileSystem> {
|
||||||
|
return self.0.lock().fs.upgrade().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_entry_name(&self, ino: super::vfs::InodeId) -> Result<String, SystemError> {
|
||||||
|
let inode: SpinLockGuard<SysFSInode> = 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<String> = 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<Arc<dyn IndexNode>, 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<usize, SystemError> {
|
||||||
|
Err(SystemError::EOPNOTSUPP_OR_ENOTSUP)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn list(&self) -> Result<Vec<String>, SystemError> {
|
||||||
|
let info = self.metadata()?;
|
||||||
|
if info.file_type != FileType::Dir {
|
||||||
|
return Err(SystemError::ENOTDIR);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut keys: Vec<String> = 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<SysFSInode>,
|
||||||
|
_name: &str,
|
||||||
|
_file_type: FileType,
|
||||||
|
_mode: u32,
|
||||||
|
_data: usize,
|
||||||
|
) -> Result<Arc<dyn IndexNode>, 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<LockedSysFSInode> = 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<Arc<dyn IndexNode>, SystemError> {
|
||||||
|
let guard: SpinLockGuard<SysFSInode> = 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<dyn IndexNode>) -> 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<dyn IndexNode> {
|
||||||
|
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<LockedSysFSInode>,
|
||||||
|
/// 指向自身的弱引用
|
||||||
|
self_ref: Weak<LockedSysFSInode>,
|
||||||
|
/// 子Inode的B树
|
||||||
|
children: BTreeMap<String, Arc<dyn IndexNode>>,
|
||||||
|
/// 指向inode所在的文件系统对象的指针
|
||||||
|
fs: Weak<SysFS>,
|
||||||
|
/// 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<LockedSysFSInode>,
|
||||||
|
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(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -14,6 +14,7 @@ use crate::{
|
|||||||
fat::fs::FATFileSystem,
|
fat::fs::FATFileSystem,
|
||||||
procfs::ProcFS,
|
procfs::ProcFS,
|
||||||
ramfs::RamFS,
|
ramfs::RamFS,
|
||||||
|
sysfs::SysFS,
|
||||||
vfs::{file::File, mount::MountFS, FileSystem, FileType},
|
vfs::{file::File, mount::MountFS, FileSystem, FileType},
|
||||||
},
|
},
|
||||||
include::bindings::bindings::PAGE_4K_SIZE,
|
include::bindings::bindings::PAGE_4K_SIZE,
|
||||||
@ -63,6 +64,9 @@ pub extern "C" fn vfs_init() -> i32 {
|
|||||||
root_inode
|
root_inode
|
||||||
.create("dev", FileType::Dir, 0o777)
|
.create("dev", FileType::Dir, 0o777)
|
||||||
.expect("Failed to create /dev");
|
.expect("Failed to create /dev");
|
||||||
|
root_inode
|
||||||
|
.create("sys", FileType::Dir, 0o777)
|
||||||
|
.expect("Failed to create /sys");
|
||||||
|
|
||||||
// // 创建procfs实例
|
// // 创建procfs实例
|
||||||
let procfs: Arc<ProcFS> = ProcFS::new();
|
let procfs: Arc<ProcFS> = ProcFS::new();
|
||||||
@ -85,6 +89,16 @@ pub extern "C" fn vfs_init() -> i32 {
|
|||||||
.expect("Failed to mount devfs");
|
.expect("Failed to mount devfs");
|
||||||
kinfo!("DevFS mounted.");
|
kinfo!("DevFS mounted.");
|
||||||
|
|
||||||
|
// 创建 sysfs 实例
|
||||||
|
let sysfs: Arc<SysFS> = 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");
|
let root_inode = ROOT_INODE().list().expect("VFS init failed");
|
||||||
if root_inode.len() > 0 {
|
if root_inode.len() > 0 {
|
||||||
kinfo!("Successfully initialized VFS!");
|
kinfo!("Successfully initialized VFS!");
|
||||||
@ -126,6 +140,8 @@ fn migrate_virtual_filesystem(new_fs: Arc<dyn FileSystem>) -> Result<(), SystemE
|
|||||||
let proc: &MountFS = binding.as_any_ref().downcast_ref::<MountFS>().unwrap();
|
let proc: &MountFS = binding.as_any_ref().downcast_ref::<MountFS>().unwrap();
|
||||||
let binding = ROOT_INODE().find("dev").expect("DevFS not mounted!").fs();
|
let binding = ROOT_INODE().find("dev").expect("DevFS not mounted!").fs();
|
||||||
let dev: &MountFS = binding.as_any_ref().downcast_ref::<MountFS>().unwrap();
|
let dev: &MountFS = binding.as_any_ref().downcast_ref::<MountFS>().unwrap();
|
||||||
|
let binding = ROOT_INODE().find("sys").expect("SysFs not mounted!").fs();
|
||||||
|
let sys: &MountFS = binding.as_any_ref().downcast_ref::<MountFS>().unwrap();
|
||||||
|
|
||||||
let new_fs = MountFS::new(new_fs, None);
|
let new_fs = MountFS::new(new_fs, None);
|
||||||
// 获取新的根文件系统的根节点的引用
|
// 获取新的根文件系统的根节点的引用
|
||||||
@ -134,6 +150,7 @@ fn migrate_virtual_filesystem(new_fs: Arc<dyn FileSystem>) -> Result<(), SystemE
|
|||||||
// 把上述文件系统,迁移到新的文件系统下
|
// 把上述文件系统,迁移到新的文件系统下
|
||||||
do_migrate(new_root_inode.clone(), "proc", proc)?;
|
do_migrate(new_root_inode.clone(), "proc", proc)?;
|
||||||
do_migrate(new_root_inode.clone(), "dev", dev)?;
|
do_migrate(new_root_inode.clone(), "dev", dev)?;
|
||||||
|
do_migrate(new_root_inode.clone(), "sys", sys)?;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
// drop旧的Root inode
|
// drop旧的Root inode
|
||||||
|
Loading…
x
Reference in New Issue
Block a user