Sfoglia il codice sorgente

fix(page_cache): 修复mmap然后直接通过访存方式读取文件时,读到空值的bug

Signed-off-by: longjin <longjin@DragonOS.org>
longjin 3 settimane fa
parent
commit
fc3db31cdc
3 ha cambiato i file con 13 aggiunte e 29 eliminazioni
  1. 4 0
      kernel/src/arch/x86_64/mm/fault.rs
  2. 7 27
      kernel/src/mm/fault.rs
  3. 2 2
      kernel/src/mm/syscall.rs

+ 4 - 0
kernel/src/arch/x86_64/mm/fault.rs

@@ -177,6 +177,10 @@ impl X86_64MMArch {
         error_code: X86PfErrorCode,
         address: VirtAddr,
     ) {
+        // log::debug!("fault at {:?}:{:?}",
+        // address,
+        // error_code,
+        // );
         let rflags = RFlags::from_bits_truncate(regs.rflags);
         let mut flags: FaultFlags = FaultFlags::FAULT_FLAG_ALLOW_RETRY
             | FaultFlags::FAULT_FLAG_KILLABLE

+ 7 - 27
kernel/src/mm/fault.rs

@@ -1,3 +1,4 @@
+use alloc::boxed::Box;
 use core::{
     alloc::Layout,
     cmp::{max, min},
@@ -20,10 +21,7 @@ use crate::{
 
 use crate::mm::MemoryManagementArch;
 
-use super::{
-    allocator::page_frame::FrameAllocator,
-    page::{FileMapInfo, Page, PageFlags, PageType},
-};
+use super::page::{Page, PageFlags};
 
 bitflags! {
     pub struct FaultFlags: u64{
@@ -620,7 +618,6 @@ impl PageFaultHandler {
         let file = vma_guard.vm_file().expect("no vm_file in vma");
         let page_cache = file.inode().page_cache().unwrap();
         let file_pgoff = pfm.file_pgoff.expect("no file_pgoff");
-        let mapper = &mut pfm.mapper;
         let mut ret = VmFaultReason::empty();
 
         let page = page_cache.lock_irqsave().get_page(file_pgoff);
@@ -633,37 +630,20 @@ impl PageFaultHandler {
             // TODO 同步预读
             //涉及磁盘IO,返回标志为VM_FAULT_MAJOR
             ret = VmFaultReason::VM_FAULT_MAJOR;
-            // let mut buf: Vec<u8> = vec![0; MMArch::PAGE_SIZE];
 
-            let allocator = mapper.allocator_mut();
+            let mut buffer = Box::new([0u8; MMArch::PAGE_SIZE]);
 
-            // 分配一个物理页面作为加入PageCache的新页
-            let new_cache_page = allocator.allocate_one().unwrap();
-            // (MMArch::phys_2_virt(new_cache_page).unwrap().data() as *mut u8)
-            //     .copy_from_nonoverlapping(buf.as_mut_ptr(), MMArch::PAGE_SIZE);
             file.pread(
                 file_pgoff * MMArch::PAGE_SIZE,
                 MMArch::PAGE_SIZE,
-                core::slice::from_raw_parts_mut(
-                    MMArch::phys_2_virt(new_cache_page).unwrap().data() as *mut u8,
-                    MMArch::PAGE_SIZE,
-                ),
+                buffer.as_mut_slice(),
             )
             .expect("failed to read file to create pagecache page");
+            drop(buffer);
 
-            let page = page_manager_lock_irqsave()
-                .create_one_page(
-                    PageType::File(FileMapInfo {
-                        page_cache: page_cache.clone(),
-                        index: file_pgoff,
-                    }),
-                    PageFlags::PG_LRU,
-                    allocator,
-                )
-                .expect("failed to create page");
-            pfm.page = Some(page.clone());
+            let page = page_cache.lock_irqsave().get_page(file_pgoff);
 
-            page_cache.lock_irqsave().add_page(file_pgoff, &page);
+            pfm.page = page;
         }
         ret
     }

+ 2 - 2
kernel/src/mm/syscall.rs

@@ -251,7 +251,7 @@ impl From<VmFlags> for ProtFlags {
 
 impl Syscall {
     pub fn brk(new_addr: VirtAddr) -> Result<VirtAddr, SystemError> {
-        // debug!("brk: new_addr={:?}", new_addr);
+        // log::debug!("brk: new_addr={:?}", new_addr);
         let address_space = AddressSpace::current()?;
         let mut address_space = address_space.write();
 
@@ -263,6 +263,7 @@ impl Syscall {
         }
 
         unsafe {
+            // log::debug!("brk: set_brk new_addr={:?}", new_addr);
             address_space
                 .set_brk(VirtAddr::new(page_align_up(new_addr.data())))
                 .ok();
@@ -346,7 +347,6 @@ impl Syscall {
                 false,
             )?
         };
-
         return Ok(start_page.virt_address().data());
     }