From ef9c935732c381bc889e117e6d01b7c1bca824f9 Mon Sep 17 00:00:00 2001 From: YJwu2023 Date: Mon, 26 May 2025 17:33:25 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=A3=80=E6=9F=A5=E6=A0=88=E5=B8=A7?= =?UTF-8?q?=E5=A4=A7=E5=B0=8F=20(#1126)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 打开clippy的stack overflow静态检查 *限制栈大小最大为4096字节 *限制栈中的数组最大为1024字节 * fix: 修复部分函数的爆栈问题 (#1172) * fix:修复部分函数的爆栈问题 * feat(filesystem): 重构FAT文件系统重命名和移动文件逻辑 将rename_file_in_same_dir和move_file_to_other_dir函数重构为LockedFATInode的方法,优化代码结构。同时更新clippy配置,添加栈大小和数组大小阈值。 Signed-off-by: longjin --------- Signed-off-by: longjin Co-authored-by: longjin --------- Signed-off-by: longjin Co-authored-by: DoL <1240800466@qq.com> Co-authored-by: longjin --- kernel/.clippy.toml | 5 +- kernel/src/arch/x86_64/driver/tsc.rs | 14 ++- kernel/src/arch/x86_64/interrupt/entry.rs | 11 ++ kernel/src/arch/x86_64/mm/mod.rs | 2 +- kernel/src/driver/disk/ahci/mod.rs | 7 +- kernel/src/driver/tty/tty_ldisc/ntty.rs | 4 +- kernel/src/filesystem/fat/fs.rs | 136 +++++++++++++--------- kernel/src/lib.rs | 4 + kernel/src/mm/fault.rs | 5 +- 9 files changed, 117 insertions(+), 71 deletions(-) diff --git a/kernel/.clippy.toml b/kernel/.clippy.toml index 2655a17f..ec3c9e21 100644 --- a/kernel/.clippy.toml +++ b/kernel/.clippy.toml @@ -1,2 +1,5 @@ # 这是clippy的配置文件,详情请见: -# https://doc.rust-lang.org/clippy/lint_configuration.html \ No newline at end of file +# https://doc.rust-lang.org/clippy/lint_configuration.html + +stack-size-threshold = 4096 +array-size-threshold = 1024 diff --git a/kernel/src/arch/x86_64/driver/tsc.rs b/kernel/src/arch/x86_64/driver/tsc.rs index ef97ec6a..80dfee19 100644 --- a/kernel/src/arch/x86_64/driver/tsc.rs +++ b/kernel/src/arch/x86_64/driver/tsc.rs @@ -102,10 +102,7 @@ impl TSCManager { /// 使用pit、hpet、ptimer来测量CPU总线的频率 fn calibrate_cpu_by_pit_hpet_ptimer() -> Result { 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" } + ); +} diff --git a/kernel/src/arch/x86_64/interrupt/entry.rs b/kernel/src/arch/x86_64/interrupt/entry.rs index 072ec4dd..64695fe8 100644 --- a/kernel/src/arch/x86_64/interrupt/entry.rs +++ b/kernel/src/arch/x86_64/interrupt/entry.rs @@ -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)); diff --git a/kernel/src/arch/x86_64/mm/mod.rs b/kernel/src/arch/x86_64/mm/mod.rs index af3a4e43..dc1ee339 100644 --- a/kernel/src/arch/x86_64/mm/mod.rs +++ b/kernel/src/arch/x86_64/mm/mod.rs @@ -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"); } diff --git a/kernel/src/driver/disk/ahci/mod.rs b/kernel/src/driver/disk/ahci/mod.rs index 8af50581..2e610407 100644 --- a/kernel/src/driver/disk/ahci/mod.rs +++ b/kernel/src/driver/disk/ahci/mod.rs @@ -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)? diff --git a/kernel/src/driver/tty/tty_ldisc/ntty.rs b/kernel/src/driver/tty/tty_ldisc/ntty.rs index 6b758931..56eec21d 100644 --- a/kernel/src/driver/tty/tty_ldisc/ntty.rs +++ b/kernel/src/driver/tty/tty_ldisc/ntty.rs @@ -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(), diff --git a/kernel/src/filesystem/fat/fs.rs b/kernel/src/filesystem/fat/fs.rs index a0d5acc4..16682dc4 100644 --- a/kernel/src/filesystem/fat/fs.rs +++ b/kernel/src/filesystem/fat/fs.rs @@ -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 = guard.find(old_name)?; + // 对目标inode上锁,以防更改 + let old_inode_guard: SpinLockGuard = 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, + ) -> Result<(), SystemError> { + let mut old_guard = self.0.lock(); + let other: &LockedFATInode = target + .downcast_ref::() + .ok_or(SystemError::EPERM)?; + + let new_guard = other.0.lock(); + let old_inode: Arc = old_guard.find(old_name)?; + // 对目标inode上锁,以防更改 + let old_inode_guard: SpinLockGuard = 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 = guard.find(old_name)?; - // 对目标inode上锁,以防更改 - let old_inode_guard: SpinLockGuard = 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::() - .ok_or(SystemError::EPERM)?; - - let new_guard = other.0.lock(); - let old_inode: Arc = old_guard.find(old_name)?; - // 对目标inode上锁,以防更改 - let old_inode_guard: SpinLockGuard = 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(()); diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index ca4968e2..50a1287a 100644 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -26,6 +26,10 @@ #![allow(static_mut_refs, non_local_definitions, internal_features)] // clippy的配置 #![deny(clippy::all)] +// 取消下面的注释以启用clippy对栈帧大小的检查 +// #![deny(clippy::large_stack_frames)] +// #![deny(clippy::large_const_arrays)] + // DragonOS允许在函数中使用return语句(尤其是长函数时,我们推荐这么做) #![allow( clippy::macro_metavars_in_unsafe, diff --git a/kernel/src/mm/fault.rs b/kernel/src/mm/fault.rs index f8442d77..1c9ee9a8 100644 --- a/kernel/src/mm/fault.rs +++ b/kernel/src/mm/fault.rs @@ -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,