fix: 修复部分函数的爆栈问题 (#1172)

* fix:修复部分函数的爆栈问题

* feat(filesystem): 重构FAT文件系统重命名和移动文件逻辑

将rename_file_in_same_dir和move_file_to_other_dir函数重构为LockedFATInode的方法,优化代码结构。同时更新clippy配置,添加栈大小和数组大小阈值。

Signed-off-by: longjin <longjin@DragonOS.org>

---------

Signed-off-by: longjin <longjin@DragonOS.org>
Co-authored-by: longjin <longjin@DragonOS.org>
This commit is contained in:
DoL 2025-05-24 13:29:03 +08:00 committed by GitHub
parent 2a867f467e
commit e061e1b93d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 115 additions and 73 deletions

View File

@ -1,4 +1,5 @@
# 这是clippy的配置文件详情请见
# https://doc.rust-lang.org/clippy/lint_configuration.html
stack-size-threshold = 4096
array-size-threshold = 1024
array-size-threshold = 1024

View File

@ -102,10 +102,7 @@ impl TSCManager {
/// 使用pit、hpet、ptimer来测量CPU总线的频率
fn calibrate_cpu_by_pit_hpet_ptimer() -> Result<u64, SystemError> {
let hpet = is_hpet_enabled();
debug!(
"Calibrating TSC with {}",
if hpet { "HPET" } else { "PMTIMER" }
);
log_for_hpet(hpet);
let mut tsc_pit_min = u64::MAX;
let mut tsc_ref_min = u64::MAX;
@ -389,3 +386,12 @@ impl TSCManager {
}
}
}
/// # 从calibrate_cpu_by_pit_hpet_ptimer 解耦出减少calibrate_cpu_by_pit_hpet_ptimer的栈帧
#[inline(never)]
fn log_for_hpet(hpet: bool) {
debug!(
"Calibrating TSC with {}",
if hpet { "HPET" } else { "PMTIMER" }
);
}

View File

@ -294,6 +294,13 @@ interrupt_handler!(255);
#[inline(never)]
pub unsafe fn arch_setup_interrupt_gate() {
arch_setup_interrupt_gate_32_130();
arch_setup_interrupt_gate_131_255();
}
/// # 从arch_setup_interrupt_gate()解耦出,避免函数体过大导致爆栈
#[inline(never)]
unsafe fn arch_setup_interrupt_gate_32_130() {
set_intr_gate(32, 0, VirtAddr::new(irq_handler32 as usize));
set_intr_gate(33, 0, VirtAddr::new(irq_handler33 as usize));
set_intr_gate(34, 0, VirtAddr::new(irq_handler34 as usize));
@ -401,7 +408,11 @@ pub unsafe fn arch_setup_interrupt_gate() {
set_intr_gate(127, 0, VirtAddr::new(irq_handler127 as usize));
set_intr_gate(129, 0, VirtAddr::new(irq_handler129 as usize));
set_intr_gate(130, 0, VirtAddr::new(irq_handler130 as usize));
}
/// # 从arch_setup_interrupt_gate()解耦出,避免函数体过大导致爆栈
#[inline(never)]
unsafe fn arch_setup_interrupt_gate_131_255() {
set_intr_gate(131, 0, VirtAddr::new(irq_handler131 as usize));
set_intr_gate(132, 0, VirtAddr::new(irq_handler132 as usize));
set_intr_gate(133, 0, VirtAddr::new(irq_handler133 as usize));

View File

@ -546,7 +546,7 @@ unsafe fn allocator_init() {
compiler_fence(Ordering::SeqCst);
mapper.make_current();
compiler_fence(Ordering::SeqCst);
debug!("New page table enabled");
//debug!("New page table enabled");
}
debug!("Successfully enabled new page table");
}

View File

@ -55,8 +55,11 @@ pub fn ahci_init() -> Result<(), SystemError> {
let standard_device = device.as_standard_device().unwrap();
standard_device.bar_ioremap();
// 对于每一个ahci控制器分配一块空间
let ahci_port_base_vaddr =
Box::leak(Box::new([0u8; (1 << 20) as usize])) as *mut u8 as usize;
// let ahci_port_base_vaddr =
// Box::leak(Box::new([0u8; (1 << 20) as usize])) as *mut u8 as usize;
let buffer = Box::leak(vec![0u8; (1 << 20) as usize].into_boxed_slice());
let ahci_port_base_vaddr = buffer.as_mut_ptr() as usize;
let virtaddr = standard_device
.bar()
.ok_or(SystemError::EACCES)?

View File

@ -149,8 +149,8 @@ impl NTtyData {
cursor_column: 0,
canon_cursor_column: 0,
echo_tail: 0,
read_buf: Box::new([0; NTTY_BUFSIZE]),
echo_buf: Box::new([0; NTTY_BUFSIZE]),
read_buf: vec![0; NTTY_BUFSIZE].into_boxed_slice().try_into().unwrap(),
echo_buf: vec![0; NTTY_BUFSIZE].into_boxed_slice().try_into().unwrap(),
read_flags: StaticBitmap::new(),
char_map: StaticBitmap::new(),
tty: Weak::default(),

View File

@ -251,6 +251,83 @@ impl LockedFATInode {
return inode;
}
#[inline(never)]
fn rename_file_in_current_dir(
&self,
old_name: &str,
new_name: &str,
) -> Result<(), SystemError> {
let mut guard = self.0.lock();
let old_inode: Arc<LockedFATInode> = guard.find(old_name)?;
// 对目标inode上锁以防更改
let old_inode_guard: SpinLockGuard<FATInode> = old_inode.0.lock();
let fs = old_inode_guard.fs.upgrade().unwrap();
// 从缓存删除
let old_dir = match &guard.inode_type {
FATDirEntry::File(_) | FATDirEntry::VolId(_) => {
return Err(SystemError::ENOTDIR);
}
FATDirEntry::Dir(d) => d,
FATDirEntry::UnInit => {
error!("FATFS: param: Inode_type uninitialized.");
return Err(SystemError::EROFS);
}
};
// 检查文件是否存在
// old_dir.check_existence(old_name, Some(false), guard.fs.upgrade().unwrap())?;
old_dir.rename(fs, old_name, new_name)?;
let _nod = guard.children.remove(&to_search_name(old_name));
Ok(())
}
#[inline(never)]
fn move_to_another_dir(
&self,
old_name: &str,
new_name: &str,
target: &Arc<dyn IndexNode>,
) -> Result<(), SystemError> {
let mut old_guard = self.0.lock();
let other: &LockedFATInode = target
.downcast_ref::<LockedFATInode>()
.ok_or(SystemError::EPERM)?;
let new_guard = other.0.lock();
let old_inode: Arc<LockedFATInode> = old_guard.find(old_name)?;
// 对目标inode上锁以防更改
let old_inode_guard: SpinLockGuard<FATInode> = old_inode.0.lock();
let fs = old_inode_guard.fs.upgrade().unwrap();
let old_dir = match &old_guard.inode_type {
FATDirEntry::File(_) | FATDirEntry::VolId(_) => {
return Err(SystemError::ENOTDIR);
}
FATDirEntry::Dir(d) => d,
FATDirEntry::UnInit => {
error!("FATFS: param: Inode_type uninitialized.");
return Err(SystemError::EROFS);
}
};
let new_dir = match &new_guard.inode_type {
FATDirEntry::File(_) | FATDirEntry::VolId(_) => {
return Err(SystemError::ENOTDIR);
}
FATDirEntry::Dir(d) => d,
FATDirEntry::UnInit => {
error!("FATFA: param: Inode_type uninitialized.");
return Err(SystemError::EROFS);
}
};
// 检查文件是否存在
old_dir.check_existence(old_name, Some(false), old_guard.fs.upgrade().unwrap())?;
old_dir.rename_across(fs, new_dir, old_name, new_name)?;
// 从缓存删除
let _nod = old_guard.children.remove(&to_search_name(old_name));
Ok(())
}
}
/// FsInfo结构体内存中的一份拷贝当卸载卷或者sync的时候把它写入磁盘
@ -1762,64 +1839,9 @@ impl IndexNode for LockedFATInode {
let new_id = target.metadata().unwrap().inode_id;
// 若在同一父目录下
if old_id == new_id {
let mut guard = self.0.lock();
let old_inode: Arc<LockedFATInode> = guard.find(old_name)?;
// 对目标inode上锁以防更改
let old_inode_guard: SpinLockGuard<FATInode> = old_inode.0.lock();
let fs = old_inode_guard.fs.upgrade().unwrap();
// 从缓存删除
let old_dir = match &guard.inode_type {
FATDirEntry::File(_) | FATDirEntry::VolId(_) => {
return Err(SystemError::ENOTDIR);
}
FATDirEntry::Dir(d) => d,
FATDirEntry::UnInit => {
error!("FATFS: param: Inode_type uninitialized.");
return Err(SystemError::EROFS);
}
};
// 检查文件是否存在
// old_dir.check_existence(old_name, Some(false), guard.fs.upgrade().unwrap())?;
old_dir.rename(fs, old_name, new_name)?;
let _nod = guard.children.remove(&to_search_name(old_name));
self.rename_file_in_current_dir(old_name, new_name)?;
} else {
let mut old_guard = self.0.lock();
let other: &LockedFATInode = target
.downcast_ref::<LockedFATInode>()
.ok_or(SystemError::EPERM)?;
let new_guard = other.0.lock();
let old_inode: Arc<LockedFATInode> = old_guard.find(old_name)?;
// 对目标inode上锁以防更改
let old_inode_guard: SpinLockGuard<FATInode> = old_inode.0.lock();
let fs = old_inode_guard.fs.upgrade().unwrap();
let old_dir = match &old_guard.inode_type {
FATDirEntry::File(_) | FATDirEntry::VolId(_) => {
return Err(SystemError::ENOTDIR);
}
FATDirEntry::Dir(d) => d,
FATDirEntry::UnInit => {
error!("FATFS: param: Inode_type uninitialized.");
return Err(SystemError::EROFS);
}
};
let new_dir = match &new_guard.inode_type {
FATDirEntry::File(_) | FATDirEntry::VolId(_) => {
return Err(SystemError::ENOTDIR);
}
FATDirEntry::Dir(d) => d,
FATDirEntry::UnInit => {
error!("FATFA: param: Inode_type uninitialized.");
return Err(SystemError::EROFS);
}
};
// 检查文件是否存在
old_dir.check_existence(old_name, Some(false), old_guard.fs.upgrade().unwrap())?;
old_dir.rename_across(fs, new_dir, old_name, new_name)?;
// 从缓存删除
let _nod = old_guard.children.remove(&to_search_name(old_name));
self.move_to_another_dir(old_name, new_name, target)?;
}
return Ok(());

View File

@ -26,8 +26,10 @@
#![allow(static_mut_refs, non_local_definitions, internal_features)]
// clippy的配置
#![deny(clippy::all)]
#![deny(clippy::large_stack_frames)]
#![deny(clippy::large_const_arrays)]
// 取消下面的注释以启用clippy对栈帧大小的检查
// #![deny(clippy::large_stack_frames)]
// #![deny(clippy::large_const_arrays)]
// DragonOS允许在函数中使用return语句尤其是长函数时我们推荐这么做
#![allow(
clippy::macro_metavars_in_unsafe,

View File

@ -1,4 +1,3 @@
use alloc::boxed::Box;
use core::{
alloc::Layout,
cmp::{max, min},
@ -634,9 +633,7 @@ impl PageFaultHandler {
// TODO 同步预读
//涉及磁盘IO返回标志为VM_FAULT_MAJOR
ret = VmFaultReason::VM_FAULT_MAJOR;
let mut buffer = Box::new([0u8; MMArch::PAGE_SIZE]);
let mut buffer = vec![0u8; MMArch::PAGE_SIZE];
file.pread(
file_pgoff * MMArch::PAGE_SIZE,
MMArch::PAGE_SIZE,