Skip to content

Commit

Permalink
fix(mm): 修复fat文件系统的PageCache同步问题 (#1005)
Browse files Browse the repository at this point in the history
---------

Co-authored-by: longjin <[email protected]>
  • Loading branch information
MemoryShore and fslongjin authored Jan 1, 2025
1 parent a08191c commit e92424d
Show file tree
Hide file tree
Showing 18 changed files with 1,005 additions and 441 deletions.
1 change: 0 additions & 1 deletion kernel/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ paste = "=1.0.14"
slabmalloc = { path = "crates/rust-slabmalloc" }
log = "0.4.21"
kprobe = { path = "crates/kprobe" }
xarray = "0.1.0"
lru = "0.12.3"

rbpf = { path = "crates/rbpf" }
Expand Down
8 changes: 2 additions & 6 deletions kernel/src/driver/net/dma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::arch::mm::kernel_page_flags;
use crate::arch::MMArch;

use crate::mm::kernel_mapper::KernelMapper;
use crate::mm::page::{page_manager_lock_irqsave, EntryFlags};
use crate::mm::page::EntryFlags;
use crate::mm::{
allocator::page_frame::{
allocate_page_frames, deallocate_page_frames, PageFrameCount, PhysPageFrame,
Expand Down Expand Up @@ -61,11 +61,7 @@ pub unsafe fn dma_dealloc(paddr: usize, vaddr: NonNull<u8>, pages: usize) -> i32
flusher.flush();

unsafe {
deallocate_page_frames(
PhysPageFrame::new(PhysAddr::new(paddr)),
page_count,
&mut page_manager_lock_irqsave(),
);
deallocate_page_frames(PhysPageFrame::new(PhysAddr::new(paddr)), page_count);
}
return 0;
}
8 changes: 2 additions & 6 deletions kernel/src/driver/virtio/virtio_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::arch::mm::kernel_page_flags;
use crate::arch::MMArch;

use crate::mm::kernel_mapper::KernelMapper;
use crate::mm::page::{page_manager_lock_irqsave, EntryFlags};
use crate::mm::page::EntryFlags;
use crate::mm::{
allocator::page_frame::{
allocate_page_frames, deallocate_page_frames, PageFrameCount, PhysPageFrame,
Expand Down Expand Up @@ -72,11 +72,7 @@ unsafe impl Hal for HalImpl {
flusher.flush();

unsafe {
deallocate_page_frames(
PhysPageFrame::new(PhysAddr::new(paddr)),
page_count,
&mut page_manager_lock_irqsave(),
);
deallocate_page_frames(PhysPageFrame::new(PhysAddr::new(paddr)), page_count);
}
return 0;
}
Expand Down
127 changes: 98 additions & 29 deletions kernel/src/filesystem/fat/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use alloc::{

use crate::driver::base::block::gendisk::GenDisk;
use crate::driver::base::device::device_number::DeviceNumber;
use crate::filesystem::vfs::file::PageCache;
use crate::filesystem::page_cache::PageCache;
use crate::filesystem::vfs::utils::DName;
use crate::filesystem::vfs::{Magic, SpecialNodeData, SuperBlock};
use crate::ipc::pipe::LockedPipeInode;
Expand Down Expand Up @@ -129,9 +129,8 @@ pub struct FATInode {
}

impl FATInode {
/// @brief 更新当前inode的元数据
pub fn update_metadata(&mut self) {
// todo: 更新文件的访问时间等信息
/// 将inode的元数据与磁盘同步
pub fn synchronize_metadata(&mut self) {
match &self.inode_type {
FATDirEntry::File(f) | FATDirEntry::VolId(f) => {
self.metadata.size = f.size() as i64;
Expand All @@ -146,6 +145,19 @@ impl FATInode {
};
}

/// 更新inode的元数据
pub fn update_metadata(&mut self, size: Option<i64>) {
if let Some(new_size) = size {
self.metadata.size = new_size;
}
self.update_time();
}

/// 更新访问时间
pub fn update_time(&mut self) {
// log::warn!("update_time has not yet been implemented");
}

fn find(&mut self, name: &str) -> Result<Arc<LockedFATInode>, SystemError> {
match &self.inode_type {
FATDirEntry::Dir(d) => {
Expand Down Expand Up @@ -234,7 +246,7 @@ impl LockedFATInode {

inode.0.lock().self_ref = Arc::downgrade(&inode);

inode.0.lock().update_metadata();
inode.0.lock().synchronize_metadata();

return inode;
}
Expand Down Expand Up @@ -1386,24 +1398,14 @@ impl FATFsInfo {
}

impl IndexNode for LockedFATInode {
fn read_at(
&self,
offset: usize,
len: usize,
buf: &mut [u8],
_data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> {
let mut guard: SpinLockGuard<FATInode> = self.0.lock();
fn read_sync(&self, offset: usize, buf: &mut [u8]) -> Result<usize, SystemError> {
let guard: SpinLockGuard<FATInode> = self.0.lock();
match &guard.inode_type {
FATDirEntry::File(f) | FATDirEntry::VolId(f) => {
let r = f.read(
&guard.fs.upgrade().unwrap(),
&mut buf[0..len],
offset as u64,
);
guard.update_metadata();
let r = f.read(&guard.fs.upgrade().unwrap(), buf, offset as u64);
return r;
}

FATDirEntry::Dir(_) => {
return Err(SystemError::EISDIR);
}
Expand All @@ -1414,32 +1416,95 @@ impl IndexNode for LockedFATInode {
}
}

fn write_at(
&self,
offset: usize,
len: usize,
buf: &[u8],
_data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> {
fn write_sync(&self, offset: usize, buf: &[u8]) -> Result<usize, SystemError> {
let mut guard: SpinLockGuard<FATInode> = self.0.lock();
let fs: &Arc<FATFileSystem> = &guard.fs.upgrade().unwrap();

match &mut guard.inode_type {
FATDirEntry::File(f) | FATDirEntry::VolId(f) => {
let r = f.write(fs, &buf[0..len], offset as u64);
guard.update_metadata();
let r = f.write(fs, buf, offset as u64);
return r;
}

FATDirEntry::Dir(_) => {
return Err(SystemError::EISDIR);
}

FATDirEntry::UnInit => {
error!("FATFS: param: Inode_type uninitialized.");
return Err(SystemError::EROFS);
}
}
}

fn read_at(
&self,
offset: usize,
len: usize,
buf: &mut [u8],
data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> {
let len = core::cmp::min(len, buf.len());
let buf = &mut buf[0..len];

let page_cache = self.0.lock().page_cache.clone();
if let Some(page_cache) = page_cache {
let r = page_cache.lock_irqsave().read(offset, &mut buf[0..len]);
// self.0.lock_irqsave().update_metadata();
return r;
} else {
return self.read_direct(offset, len, buf, data);
}
}

fn write_at(
&self,
offset: usize,
len: usize,
buf: &[u8],
data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> {
let len = core::cmp::min(len, buf.len());
let buf = &buf[0..len];

let page_cache = self.0.lock().page_cache.clone();
if let Some(page_cache) = page_cache {
let write_len = page_cache.lock_irqsave().write(offset, buf)?;
let mut guard = self.0.lock();
let old_size = guard.metadata.size;
guard.update_metadata(Some(core::cmp::max(old_size, (offset + write_len) as i64)));
return Ok(write_len);
} else {
return self.write_direct(offset, len, buf, data);
}
}

fn read_direct(
&self,
offset: usize,
len: usize,
buf: &mut [u8],
_data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> {
let len = core::cmp::min(len, buf.len());
let r = self.read_sync(offset, &mut buf[0..len]);
// self.0.lock_irqsave().update_metadata();
return r;
}

fn write_direct(
&self,
offset: usize,
len: usize,
buf: &[u8],
_data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> {
let len = core::cmp::min(len, buf.len());
let r = self.write_sync(offset, &buf[0..len]);
// self.0.lock_irqsave().update_metadata();
return r;
}

fn create(
&self,
name: &str,
Expand Down Expand Up @@ -1496,6 +1561,10 @@ impl IndexNode for LockedFATInode {
Ok(())
}
fn resize(&self, len: usize) -> Result<(), SystemError> {
if let Some(page_cache) = self.page_cache() {
return page_cache.lock_irqsave().resize(len);
}

let mut guard: SpinLockGuard<FATInode> = self.0.lock();
let fs: &Arc<FATFileSystem> = &guard.fs.upgrade().unwrap();
let old_size = guard.metadata.size as usize;
Expand Down Expand Up @@ -1527,7 +1596,7 @@ impl IndexNode for LockedFATInode {
file.truncate(fs, len as u64)?;
}
}
guard.update_metadata();
guard.synchronize_metadata();
return Ok(());
}
FATDirEntry::Dir(_) => return Err(SystemError::ENOSYS),
Expand Down
1 change: 1 addition & 0 deletions kernel/src/filesystem/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub mod fat;
pub mod kernfs;
pub mod mbr;
pub mod overlayfs;
pub mod page_cache;
pub mod procfs;
pub mod ramfs;
pub mod sysfs;
Expand Down
Loading

0 comments on commit e92424d

Please sign in to comment.