新版文件系统重构完成 (#198)

1.重构:VFS
2. 重构:ProcFS
3. 重构:DevFS
4. 重构:FAT32
5. 重构:AHCI驱动
6. 新增:RamFS
7. 新增:MountFS
8. 新增:FAT12
9. 新增:FAT16
10. 重构:设备抽象

Co-authored-by: guanjinquan <1666320330@qq.com>
Co-authored-by: DaJiYuQia <88259094+DaJiYuQia@users.noreply.github.com>
This commit is contained in:
login
2023-03-12 22:36:11 +08:00
committed by GitHub
parent 17041e0e30
commit 004e86ff19
109 changed files with 11258 additions and 7486 deletions

View File

@ -1,8 +1,16 @@
use core::ptr::{read_volatile, write_volatile};
use core::{
ffi::c_void,
ptr::{null_mut, read_volatile, write_volatile},
};
use alloc::boxed::Box;
use crate::{
arch::asm::current::current_pcb,
include::bindings::bindings::{process_control_block, PROC_RUNNING, PROC_STOPPED},
filesystem::vfs::file::{File, FileDescriptorVec},
include::bindings::bindings::{
process_control_block, CLONE_FS, EBADF, EFAULT, ENFILE, EPERM, PROC_RUNNING, PROC_STOPPED,
},
sched::core::{cpu_executing, sched_enqueue},
smp::core::{smp_get_processor_id, smp_send_reschedule},
};
@ -99,3 +107,198 @@ pub fn process_cpu(pcb: *const process_control_block) -> u32 {
pub fn process_is_executing(pcb: *const process_control_block) -> bool {
return cpu_executing(process_cpu(pcb)) as *const process_control_block == pcb;
}
impl process_control_block {
/// @brief 初始化进程PCB的文件描述符数组。
/// 请注意,如果当前进程已经有文件描述符数组,那么本操作将被禁止
pub fn init_files(&mut self) -> Result<(), i32> {
if self.fds != null_mut() {
// 这个操作不被允许,否则会产生内存泄露。
// 原因是C的pcb里面文件描述符数组的生命周期是static的如果继续执行会产生内存泄露的问题。
return Err(-(EPERM as i32));
}
let fd_vec: &mut FileDescriptorVec = Box::leak(FileDescriptorVec::new());
self.fds = fd_vec as *mut FileDescriptorVec as usize as *mut c_void;
return Ok(());
}
/// @brief 拷贝进程的文件描述符
///
/// @param clone_flags 进程fork的克隆标志位
/// @param from 源pcb。从它里面拷贝文件描述符
///
/// @return Ok(()) 拷贝成功
/// @return Err(i32) 拷贝失败,错误码
pub fn copy_files(
&mut self,
clone_flags: u64,
from: &'static process_control_block,
) -> Result<(), i32> {
// 不拷贝父进程的文件描述符
if clone_flags & CLONE_FS as u64 != 0 {
// 由于拷贝pcb的时候直接copy的指针因此这里置为空
self.fds = null_mut();
self.init_files()?;
return Ok(());
}
// 获取源pcb的文件描述符数组的引用
let old_fds: &mut FileDescriptorVec = if let Some(o_fds) = FileDescriptorVec::from_pcb(from)
{
o_fds
} else {
return self.init_files();
};
// 拷贝文件描述符数组
let new_fd_vec: &mut FileDescriptorVec = Box::leak(Box::new(old_fds.clone()));
self.fds = new_fd_vec as *mut FileDescriptorVec as usize as *mut c_void;
return Ok(());
}
/// @brief 释放文件描述符数组。本函数会drop掉整个文件描述符数组并把pcb的fds字段设置为空指针。
pub fn exit_files(&mut self) -> Result<(), i32> {
if self.fds.is_null() {
return Ok(());
}
let old_fds: Box<FileDescriptorVec> =
unsafe { Box::from_raw(self.fds as *mut FileDescriptorVec) };
drop(old_fds);
self.fds = null_mut();
return Ok(());
}
/// @brief 申请文件描述符,并把文件对象存入其中。
///
/// @return Ok(i32) 申请到的文件描述符编号
/// @return Err(i32) 申请失败返回错误码并且file对象将被drop掉
pub fn alloc_fd(&mut self, file: File) -> Result<i32, i32> {
// 获取pcb的文件描述符数组的引用
let fds: &mut FileDescriptorVec =
if let Some(f) = FileDescriptorVec::from_pcb(current_pcb()) {
f
} else {
// 如果进程还没有初始化文件描述符数组,那就初始化它
self.init_files().ok();
let r: Option<&mut FileDescriptorVec> = FileDescriptorVec::from_pcb(current_pcb());
if r.is_none() {
drop(file);
// 初始化失败
return Err(-(EFAULT as i32));
}
r.unwrap()
};
// 寻找空闲的文件描述符
let mut cnt = 0;
for x in fds.fds.iter_mut() {
if x.is_none() {
*x = Some(Box::new(file));
return Ok(cnt);
}
cnt += 1;
}
return Err(-(ENFILE as i32));
}
/// @brief 根据文件描述符序号,获取文件结构体的可变引用
///
/// @param fd 文件描述符序号
///
/// @return Option(&mut File) 文件对象的可变引用
pub fn get_file_mut_by_fd(&self, fd: i32) -> Option<&mut File> {
if !FileDescriptorVec::validate_fd(fd) {
return None;
}
let r: &mut FileDescriptorVec = FileDescriptorVec::from_pcb(current_pcb()).unwrap();
return r.fds[fd as usize].as_deref_mut();
}
/// @brief 根据文件描述符序号,获取文件结构体的不可变引用
///
/// @param fd 文件描述符序号
///
/// @return Option(&File) 文件对象的不可变引用
#[allow(dead_code)]
pub fn get_file_ref_by_fd(&self, fd: i32) -> Option<&File> {
if !FileDescriptorVec::validate_fd(fd) {
return None;
}
let r: &mut FileDescriptorVec = FileDescriptorVec::from_pcb(current_pcb()).unwrap();
return r.fds[fd as usize].as_deref();
}
/// @brief 释放文件描述符,同时关闭文件。
///
/// @param fd 文件描述符序号
pub fn drop_fd(&self, fd: i32) -> Result<(), i32> {
// 判断文件描述符的数字是否超过限制
if !FileDescriptorVec::validate_fd(fd) {
return Err(-(EBADF as i32));
}
let r: &mut FileDescriptorVec = FileDescriptorVec::from_pcb(current_pcb()).unwrap();
let f: Option<&File> = r.fds[fd as usize].as_deref();
if f.is_none() {
// 如果文件描述符不存在,报错
return Err(-(EBADF as i32));
}
// 释放文件
drop(f);
// 把文件描述符数组对应位置设置为空
r.fds[fd as usize] = None;
return Ok(());
}
}
// =========== 导出到C的函数在将来进程管理模块被完全重构之后需要删掉他们 BEGIN ============
/// @brief 初始化当前进程的文件描述符数组
/// 请注意,如果当前进程已经有文件描述符数组,那么本操作将被禁止
#[no_mangle]
pub extern "C" fn process_init_files() -> i32 {
let r = current_pcb().init_files();
if r.is_ok() {
return 0;
} else {
return r.unwrap_err();
}
}
/// @brief 拷贝当前进程的文件描述符信息
///
/// @param clone_flags 克隆标志位
/// @param pcb 新的进程的pcb
#[no_mangle]
pub extern "C" fn process_copy_files(
clone_flags: u64,
from: &'static process_control_block,
) -> i32 {
let r = current_pcb().copy_files(clone_flags, from);
if r.is_ok() {
return 0;
} else {
return r.unwrap_err();
}
}
/// @brief 回收进程的文件描述符数组
///
/// @param pcb 要被回收的进程的pcb
///
/// @return i32
#[no_mangle]
pub extern "C" fn process_exit_files(pcb: &'static mut process_control_block) -> i32 {
let r: Result<(), i32> = pcb.exit_files();
if r.is_ok() {
return 0;
} else {
return r.unwrap_err();
}
}
// =========== 以上为导出到C的函数在将来进程管理模块被完全重构之后需要删掉他们 END ============