LoGin c566df451c
添加帧缓冲区抽象并实现vesafb的驱动 (#483)
- 添加bootparams对象
- 修正由于bus的driver、device强弱引用关系 不正确从而导致对象被释放的bug
- 添加vesafb的驱动
- 实现framebuffer抽象层
- 为通用帧缓冲区抽象实现sysfs的属性
- 修改设备号DeviceNumber的定义
- 仿照linux,添加initcall,并在第一个内核线程中,调用他们。
2024-01-01 11:46:51 +08:00

388 lines
13 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

use core::{
any::Any,
sync::atomic::{compiler_fence, Ordering},
};
use alloc::{
collections::BTreeMap,
sync::{Arc, Weak},
};
use system_error::SystemError;
use crate::{driver::base::device::device_number::DeviceNumber, libs::spinlock::SpinLock};
use super::{
file::FileMode, syscall::ModeType, FilePrivateData, FileSystem, FileType, IndexNode, InodeId,
};
/// @brief 挂载文件系统
/// 挂载文件系统的时候套了MountFS这一层以实现文件系统的递归挂载
#[derive(Debug)]
pub struct MountFS {
// MountFS内部的文件系统
inner_filesystem: Arc<dyn FileSystem>,
/// 用来存储InodeID->挂载点的MountFS的B树
mountpoints: SpinLock<BTreeMap<InodeId, Arc<MountFS>>>,
/// 当前文件系统挂载到的那个挂载点的Inode
self_mountpoint: Option<Arc<MountFSInode>>,
/// 指向当前MountFS的弱引用
self_ref: Weak<MountFS>,
}
/// @brief MountFS的Index Node 注意这个IndexNode只是一个中间层。它的目的是将具体文件系统的Inode与挂载机制连接在一起。
#[derive(Debug)]
pub struct MountFSInode {
/// 当前挂载点对应到具体的文件系统的Inode
inner_inode: Arc<dyn IndexNode>,
/// 当前Inode对应的MountFS
mount_fs: Arc<MountFS>,
/// 指向自身的弱引用
self_ref: Weak<MountFSInode>,
}
impl MountFS {
pub fn new(
inner_fs: Arc<dyn FileSystem>,
self_mountpoint: Option<Arc<MountFSInode>>,
) -> Arc<Self> {
return MountFS {
inner_filesystem: inner_fs,
mountpoints: SpinLock::new(BTreeMap::new()),
self_mountpoint: self_mountpoint,
self_ref: Weak::default(),
}
.wrap();
}
/// @brief 用Arc指针包裹MountFS对象。
/// 本函数的主要功能为初始化MountFS对象中的自引用Weak指针
/// 本函数只应在构造器中被调用
fn wrap(self) -> Arc<Self> {
// 创建Arc指针
let mount_fs: Arc<MountFS> = Arc::new(self);
// 创建weak指针
let weak: Weak<MountFS> = Arc::downgrade(&mount_fs);
// 将Arc指针转为Raw指针并对其内部的self_ref字段赋值
let ptr: *mut MountFS = mount_fs.as_ref() as *const Self as *mut Self;
unsafe {
(*ptr).self_ref = weak;
// 返回初始化好的MountFS对象
return mount_fs;
}
}
/// @brief 获取挂载点的文件系统的root inode
pub fn mountpoint_root_inode(&self) -> Arc<MountFSInode> {
return MountFSInode {
inner_inode: self.inner_filesystem.root_inode(),
mount_fs: self.self_ref.upgrade().unwrap(),
self_ref: Weak::default(),
}
.wrap();
}
pub fn inner_filesystem(&self) -> Arc<dyn FileSystem> {
return self.inner_filesystem.clone();
}
}
impl MountFSInode {
/// @brief 用Arc指针包裹MountFSInode对象。
/// 本函数的主要功能为初始化MountFSInode对象中的自引用Weak指针
/// 本函数只应在构造器中被调用
fn wrap(self) -> Arc<Self> {
// 创建Arc指针
let inode: Arc<MountFSInode> = Arc::new(self);
// 创建Weak指针
let weak: Weak<MountFSInode> = Arc::downgrade(&inode);
// 将Arc指针转为Raw指针并对其内部的self_ref字段赋值
compiler_fence(Ordering::SeqCst);
let ptr: *mut MountFSInode = inode.as_ref() as *const Self as *mut Self;
compiler_fence(Ordering::SeqCst);
unsafe {
(*ptr).self_ref = weak;
compiler_fence(Ordering::SeqCst);
// 返回初始化好的MountFSInode对象
return inode;
}
}
/// @brief 判断当前inode是否为它所在的文件系统的root inode
fn is_mountpoint_root(&self) -> Result<bool, SystemError> {
return Ok(self.inner_inode.fs().root_inode().metadata()?.inode_id
== self.inner_inode.metadata()?.inode_id);
}
/// @brief 在挂载树上进行inode替换。
/// 如果当前inode是父MountFS内的一个挂载点那么本函数将会返回挂载到这个挂载点下的文件系统的root inode.
/// 如果当前inode在父MountFS内但不是挂载点那么说明在这里不需要进行inode替换因此直接返回当前inode。
///
/// @return Arc<MountFSInode>
fn overlaid_inode(&self) -> Arc<MountFSInode> {
let inode_id = self.metadata().unwrap().inode_id;
if let Some(sub_mountfs) = self.mount_fs.mountpoints.lock().get(&inode_id) {
return sub_mountfs.mountpoint_root_inode();
} else {
return self.self_ref.upgrade().unwrap();
}
}
}
impl IndexNode for MountFSInode {
fn open(&self, data: &mut FilePrivateData, mode: &FileMode) -> Result<(), SystemError> {
return self.inner_inode.open(data, mode);
}
fn close(&self, data: &mut FilePrivateData) -> Result<(), SystemError> {
return self.inner_inode.close(data);
}
fn create_with_data(
&self,
name: &str,
file_type: FileType,
mode: ModeType,
data: usize,
) -> Result<Arc<dyn IndexNode>, SystemError> {
return Ok(MountFSInode {
inner_inode: self
.inner_inode
.create_with_data(name, file_type, mode, data)?,
mount_fs: self.mount_fs.clone(),
self_ref: Weak::default(),
}
.wrap());
}
fn truncate(&self, len: usize) -> Result<(), SystemError> {
return self.inner_inode.truncate(len);
}
fn read_at(
&self,
offset: usize,
len: usize,
buf: &mut [u8],
data: &mut FilePrivateData,
) -> Result<usize, SystemError> {
return self.inner_inode.read_at(offset, len, buf, data);
}
fn write_at(
&self,
offset: usize,
len: usize,
buf: &[u8],
data: &mut FilePrivateData,
) -> Result<usize, SystemError> {
return self.inner_inode.write_at(offset, len, buf, data);
}
#[inline]
fn fs(&self) -> Arc<dyn FileSystem> {
return self.mount_fs.clone();
}
#[inline]
fn as_any_ref(&self) -> &dyn core::any::Any {
return self.inner_inode.as_any_ref();
}
#[inline]
fn metadata(&self) -> Result<super::Metadata, SystemError> {
return self.inner_inode.metadata();
}
#[inline]
fn set_metadata(&self, metadata: &super::Metadata) -> Result<(), SystemError> {
return self.inner_inode.set_metadata(metadata);
}
#[inline]
fn resize(&self, len: usize) -> Result<(), SystemError> {
return self.inner_inode.resize(len);
}
#[inline]
fn create(
&self,
name: &str,
file_type: FileType,
mode: ModeType,
) -> Result<Arc<dyn IndexNode>, SystemError> {
return Ok(MountFSInode {
inner_inode: self.inner_inode.create(name, file_type, mode)?,
mount_fs: self.mount_fs.clone(),
self_ref: Weak::default(),
}
.wrap());
}
fn link(&self, name: &str, other: &Arc<dyn IndexNode>) -> Result<(), SystemError> {
return self.inner_inode.link(name, other);
}
/// @brief 在挂载文件系统中删除文件/文件夹
#[inline]
fn unlink(&self, name: &str) -> Result<(), SystemError> {
let inode_id = self.inner_inode.find(name)?.metadata()?.inode_id;
// 先检查这个inode是否为一个挂载点如果当前inode是一个挂载点那么就不能删除这个inode
if self.mount_fs.mountpoints.lock().contains_key(&inode_id) {
return Err(SystemError::EBUSY);
}
// 调用内层的inode的方法来删除这个inode
return self.inner_inode.unlink(name);
}
#[inline]
fn rmdir(&self, name: &str) -> Result<(), SystemError> {
let inode_id = self.inner_inode.find(name)?.metadata()?.inode_id;
// 先检查这个inode是否为一个挂载点如果当前inode是一个挂载点那么就不能删除这个inode
if self.mount_fs.mountpoints.lock().contains_key(&inode_id) {
return Err(SystemError::EBUSY);
}
// 调用内层的rmdir的方法来删除这个inode
let r = self.inner_inode.rmdir(name);
return r;
}
#[inline]
fn move_(
&self,
old_name: &str,
target: &Arc<dyn IndexNode>,
new_name: &str,
) -> Result<(), SystemError> {
return self.inner_inode.move_(old_name, target, new_name);
}
fn find(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError> {
match name {
// 查找的是当前目录
"" | "." => return Ok(self.self_ref.upgrade().unwrap()),
// 往父级查找
".." => {
if self.is_mountpoint_root()? {
// 当前inode是它所在的文件系统的root inode
match &self.mount_fs.self_mountpoint {
Some(inode) => {
return inode.find(name);
}
None => {
return Ok(self.self_ref.upgrade().unwrap());
}
}
} else {
// 向上查找时不会跨过文件系统的边界因此直接调用当前inode所在的文件系统的find方法进行查找
return Ok(MountFSInode {
inner_inode: self.inner_inode.find(name)?,
mount_fs: self.mount_fs.clone(),
self_ref: Weak::default(),
}
.wrap());
}
}
// 在当前目录下查找
_ => {
// 直接调用当前inode所在的文件系统的find方法进行查找
// 由于向下查找可能会跨越文件系统的边界因此需要尝试替换inode
return Ok(MountFSInode {
inner_inode: self.inner_inode.find(name)?,
mount_fs: self.mount_fs.clone(),
self_ref: Weak::default(),
}
.wrap()
.overlaid_inode());
}
}
}
#[inline]
fn get_entry_name(&self, ino: InodeId) -> Result<alloc::string::String, SystemError> {
return self.inner_inode.get_entry_name(ino);
}
#[inline]
fn get_entry_name_and_metadata(
&self,
ino: InodeId,
) -> Result<(alloc::string::String, super::Metadata), SystemError> {
return self.inner_inode.get_entry_name_and_metadata(ino);
}
#[inline]
fn ioctl(&self, cmd: u32, data: usize) -> Result<usize, SystemError> {
return self.inner_inode.ioctl(cmd, data);
}
#[inline]
fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, SystemError> {
return self.inner_inode.list();
}
/// @brief 在当前inode下挂载一个文件系统
///
/// @return Ok(Arc<MountFS>) 挂载成功返回指向MountFS的指针
fn mount(&self, fs: Arc<dyn FileSystem>) -> Result<Arc<MountFS>, SystemError> {
let metadata = self.inner_inode.metadata()?;
if metadata.file_type != FileType::Dir {
return Err(SystemError::ENOTDIR);
}
// 为新的挂载点创建挂载文件系统
let new_mount_fs: Arc<MountFS> = MountFS::new(fs, Some(self.self_ref.upgrade().unwrap()));
// 将新的挂载点-挂载文件系统添加到父级的挂载树
self.mount_fs
.mountpoints
.lock()
.insert(metadata.inode_id, new_mount_fs.clone());
return Ok(new_mount_fs);
}
#[inline]
fn mknod(
&self,
filename: &str,
mode: ModeType,
dev_t: DeviceNumber,
) -> Result<Arc<dyn IndexNode>, SystemError> {
return Ok(MountFSInode {
inner_inode: self.inner_inode.mknod(filename, mode, dev_t)?,
mount_fs: self.mount_fs.clone(),
self_ref: Weak::default(),
}
.wrap());
}
#[inline]
fn special_node(&self) -> Option<super::SpecialNodeData> {
self.inner_inode.special_node()
}
}
impl FileSystem for MountFS {
fn root_inode(&self) -> Arc<dyn IndexNode> {
match &self.self_mountpoint {
Some(inode) => return inode.mount_fs.root_inode(),
// 当前文件系统是rootfs
None => self.mountpoint_root_inode(),
}
}
fn info(&self) -> super::FsInfo {
return self.inner_filesystem.info();
}
/// @brief 本函数用于实现动态转换。
/// 具体的文件系统在实现本函数时最简单的方式就是直接返回self
fn as_any_ref(&self) -> &dyn Any {
self
}
}