Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions kernel/src/arch/x86_64/mm/fault.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::{
},
exception::{extable::ExceptionTableManager, InterruptArch},
ipc::{
signal::force_sig_fault_to_current,
signal::{force_kernel_signal_to_current, force_sig_fault_to_current},
signal_types::{BUS_ADRERR, SEGV_ACCERR, SEGV_MAPERR},
},
mm::{
Expand Down Expand Up @@ -516,7 +516,9 @@ impl X86_64MMArch {
regs.rip,
fault
);
// TODO: OOM 处理
if let Err(err) = force_kernel_signal_to_current(Signal::SIGKILL) {
error!("failed to send SIGKILL for page fault OOM: {:?}", err);
}
return;
} else if fault.contains(VmFaultReason::VM_FAULT_SIGBUS)
|| fault.contains(VmFaultReason::VM_FAULT_HWPOISON)
Expand Down
3 changes: 2 additions & 1 deletion kernel/src/filesystem/ext4/filesystem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::{
VFS_MAX_FOLLOW_SYMLINK_TIMES,
},
},
libs::mutex::Mutex,
libs::{mutex::Mutex, rwsem::RwSem},
mm::{
fault::{PageFaultHandler, PageFaultMessage},
VmFaultReason,
Expand Down Expand Up @@ -297,6 +297,7 @@ impl Ext4FileSystem {
dirty_state: super::inode::InodeDirtyState::empty(),
}),
Mutex::new(()),
RwSem::new(()),
)
});

Expand Down
77 changes: 52 additions & 25 deletions kernel/src/filesystem/ext4/inode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::{
libs::{
casting::DowncastArc,
mutex::{Mutex, MutexGuard},
rwsem::RwSem,
},
mm::{truncate::truncate_inode_pages, MemoryManagementArch},
time::PosixTimeSpec,
Expand Down Expand Up @@ -81,7 +82,11 @@ pub struct Ext4Inode {
}

#[derive(Debug)]
pub struct LockedExt4Inode(pub(super) Mutex<Ext4Inode>, pub(super) Mutex<()>);
pub struct LockedExt4Inode(
pub(super) Mutex<Ext4Inode>,
pub(super) Mutex<()>,
pub(super) RwSem<()>,
);

impl IndexNode for LockedExt4Inode {
fn mmap(&self, _start: usize, _len: usize, _offset: usize) -> Result<(), SystemError> {
Expand Down Expand Up @@ -208,6 +213,7 @@ impl IndexNode for LockedExt4Inode {
if len == 0 {
return Ok(0);
}
let _size_guard = self.2.read();
let buf = &buf[0..len];

let (fs, inode_num, page_cache) = {
Expand Down Expand Up @@ -553,31 +559,51 @@ impl IndexNode for LockedExt4Inode {
}

fn resize(&self, len: usize) -> Result<(), SystemError> {
let guard = self.0.lock();
let ext4 = &guard.concret_fs().fs;
// 仅调整文件大小,其他属性保持不变
ext4.setattr(
guard.inner_inode_num,
another_ext4::SetAttr {
mode: None,
uid: None,
gid: None,
size: Some(len as u64),
atime: None,
mtime: None,
ctime: None,
crtime: None,
},
)
.map_err(SystemError::from)?;
drop(guard);
// 更新缓存的文件大小
let _size_guard = self.2.write();
let (fs, inode_num, page_cache, cached_size) = {
let guard = self.0.lock();
(
guard.concret_fs(),
guard.inner_inode_num,
guard.page_cache.clone(),
guard.cached_file_size,
)
};
let old_size = match cached_size {
Some(size) => size,
None => fs.fs.getattr(inode_num)?.size,
};
{
let mut guard = self.0.lock();
guard.cached_file_size = Some(len as u64);
guard
.dirty_state
.remove(InodeDirtyState::SIZE_DIRTY | InodeDirtyState::MTIME_DIRTY);
let _io_guard = self.1.lock();
let ext4 = &fs.fs;
// 仅调整文件大小,其他属性保持不变
ext4.setattr(
inode_num,
another_ext4::SetAttr {
mode: None,
uid: None,
gid: None,
size: Some(len as u64),
atime: None,
mtime: None,
ctime: None,
crtime: None,
},
)
.map_err(SystemError::from)?;
// 更新缓存的文件大小
{
let mut guard = self.0.lock();
guard.cached_file_size = Some(len as u64);
guard
.dirty_state
.remove(InodeDirtyState::SIZE_DIRTY | InodeDirtyState::MTIME_DIRTY);
}
}
if len < old_size as usize {
if let Some(page_cache) = page_cache {
page_cache.truncate(len)?;
}
}
Ok(())
}
Expand Down Expand Up @@ -1004,6 +1030,7 @@ impl LockedExt4Inode {
LockedExt4Inode(
Mutex::new(Ext4Inode::new(inode_num, fs_ptr.clone(), dname, parent)),
Mutex::new(()),
RwSem::new(()),
)
});
let mut guard = inode.0.lock();
Expand Down
169 changes: 95 additions & 74 deletions kernel/src/filesystem/fat/fs.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::arch::MMArch;
use crate::filesystem::vfs::syscall::RenameFlags;
use crate::mm::truncate::truncate_inode_pages;
use crate::mm::MemoryManagementArch;
use alloc::string::ToString;
use alloc::{
Expand All @@ -24,6 +23,7 @@ use crate::filesystem::vfs::utils::DName;
use crate::filesystem::vfs::{Magic, SpecialNodeData, SuperBlock};
use crate::ipc::pipe::LockedPipeInode;
use crate::libs::casting::DowncastArc;
use crate::libs::rwsem::RwSem;
use crate::mm::fault::{PageFaultHandler, PageFaultMessage};
use crate::mm::VmFaultReason;
use crate::{
Expand Down Expand Up @@ -126,7 +126,7 @@ pub struct FATFileSystem {

/// FAT文件系统的Inode
#[derive(Debug)]
pub struct LockedFATInode(Mutex<FATInode>);
pub struct LockedFATInode(Mutex<FATInode>, RwSem<()>);

#[derive(Debug)]
pub struct LockedFATFsInfo(Mutex<FATFsInfo>);
Expand Down Expand Up @@ -286,39 +286,42 @@ impl LockedFATInode {
FileType::File
};

let inode: Arc<LockedFATInode> = Arc::new(LockedFATInode(Mutex::new(FATInode {
parent,
self_ref: Weak::default(),
children: HashMap::new(),
negative_children: FATInode::negative_children_cache(),
fs: Arc::downgrade(&fs),
inode_type,
metadata: Metadata {
dev_id: 0,
inode_id: generate_inode_id(),
size: 0,
blk_size: fs.bpb.bytes_per_sector as usize,
blocks: if let FATType::FAT32(_) = fs.bpb.fat_type {
fs.bpb.total_sectors_32 as usize
} else {
fs.bpb.total_sectors_16 as usize
let inode: Arc<LockedFATInode> = Arc::new(LockedFATInode(
Mutex::new(FATInode {
parent,
self_ref: Weak::default(),
children: HashMap::new(),
negative_children: FATInode::negative_children_cache(),
fs: Arc::downgrade(&fs),
inode_type,
metadata: Metadata {
dev_id: 0,
inode_id: generate_inode_id(),
size: 0,
blk_size: fs.bpb.bytes_per_sector as usize,
blocks: if let FATType::FAT32(_) = fs.bpb.fat_type {
fs.bpb.total_sectors_32 as usize
} else {
fs.bpb.total_sectors_16 as usize
},
atime: PosixTimeSpec::default(),
mtime: PosixTimeSpec::default(),
ctime: PosixTimeSpec::default(),
btime: PosixTimeSpec::default(),
file_type,
mode: InodeMode::S_IRWXUGO,
flags: InodeFlags::empty(),
nlinks: if file_type == FileType::Dir { 2 } else { 1 },
uid: 0,
gid: 0,
raw_dev: DeviceNumber::default(),
},
atime: PosixTimeSpec::default(),
mtime: PosixTimeSpec::default(),
ctime: PosixTimeSpec::default(),
btime: PosixTimeSpec::default(),
file_type,
mode: InodeMode::S_IRWXUGO,
flags: InodeFlags::empty(),
nlinks: if file_type == FileType::Dir { 2 } else { 1 },
uid: 0,
gid: 0,
raw_dev: DeviceNumber::default(),
},
special_node: None,
dname,
page_cache: None,
})));
special_node: None,
dname,
page_cache: None,
}),
RwSem::new(()),
));

if !inode.0.lock().inode_type.is_dir() {
let backend = Arc::new(AsyncPageCacheBackend::new(
Expand Down Expand Up @@ -720,39 +723,42 @@ impl FATFileSystem {
bpb.rsvd_sec_cnt as u64 + (bpb.num_fats as u64 * fat_size) + root_dir_sectors;

// 创建文件系统的根节点
let root_inode: Arc<LockedFATInode> = Arc::new(LockedFATInode(Mutex::new(FATInode {
parent: Weak::default(),
self_ref: Weak::default(),
children: HashMap::new(),
negative_children: FATInode::negative_children_cache(),
fs: Weak::default(),
inode_type: FATDirEntry::UnInit,
metadata: Metadata {
dev_id: 0,
inode_id: generate_inode_id(),
size: 0,
blk_size: bpb.bytes_per_sector as usize,
blocks: if let FATType::FAT32(_) = bpb.fat_type {
bpb.total_sectors_32 as usize
} else {
bpb.total_sectors_16 as usize
let root_inode: Arc<LockedFATInode> = Arc::new(LockedFATInode(
Mutex::new(FATInode {
parent: Weak::default(),
self_ref: Weak::default(),
children: HashMap::new(),
negative_children: FATInode::negative_children_cache(),
fs: Weak::default(),
inode_type: FATDirEntry::UnInit,
metadata: Metadata {
dev_id: 0,
inode_id: generate_inode_id(),
size: 0,
blk_size: bpb.bytes_per_sector as usize,
blocks: if let FATType::FAT32(_) = bpb.fat_type {
bpb.total_sectors_32 as usize
} else {
bpb.total_sectors_16 as usize
},
atime: PosixTimeSpec::default(),
mtime: PosixTimeSpec::default(),
ctime: PosixTimeSpec::default(),
btime: PosixTimeSpec::default(),
file_type: FileType::Dir,
mode: InodeMode::S_IRWXUGO,
flags: InodeFlags::empty(),
nlinks: 2,
uid: 0,
gid: 0,
raw_dev: DeviceNumber::default(),
},
atime: PosixTimeSpec::default(),
mtime: PosixTimeSpec::default(),
ctime: PosixTimeSpec::default(),
btime: PosixTimeSpec::default(),
file_type: FileType::Dir,
mode: InodeMode::S_IRWXUGO,
flags: InodeFlags::empty(),
nlinks: 2,
uid: 0,
gid: 0,
raw_dev: DeviceNumber::default(),
},
special_node: None,
dname: DName::default(),
page_cache: None,
})));
special_node: None,
dname: DName::default(),
page_cache: None,
}),
RwSem::new(()),
));

let result: Arc<FATFileSystem> = Arc::new(FATFileSystem {
gendisk,
Expand Down Expand Up @@ -1836,6 +1842,7 @@ impl LockedFATInode {
}

fn try_write_pagecache(&self, offset: usize, buf: &[u8]) -> Result<usize, SystemError> {
let _size_guard = self.1.read();
let page_cache = self.0.lock().page_cache.clone();
if let Some(page_cache) = page_cache {
let write_len = PageCache::write(&page_cache, offset, buf)?;
Expand Down Expand Up @@ -2091,20 +2098,15 @@ impl IndexNode for LockedFATInode {
Ok(())
}
fn resize(&self, len: usize) -> Result<(), SystemError> {
let _size_guard = self.1.write();
//检查是否超过fat支持的最大容量
if (len as u64) > MAX_FILE_SIZE {
return Err(SystemError::EFBIG);
}
// 先调整页缓存:清除被截断区间的缓存页,再缩容缓存大小
if let Some(page_cache) = self.page_cache() {
let start_page = (len + MMArch::PAGE_SIZE - 1) >> MMArch::PAGE_SHIFT;
truncate_inode_pages(page_cache.clone(), start_page);
page_cache.manager().resize(len)?;
}

let mut guard: MutexGuard<FATInode> = self.0.lock();
let fs: &Arc<FATFileSystem> = &guard.fs.upgrade().unwrap();
let old_size = guard.metadata.size as usize;
let page_cache = guard.page_cache.clone();

match &mut guard.inode_type {
FATDirEntry::File(file) | FATDirEntry::VolId(file) => {
Expand All @@ -2127,7 +2129,26 @@ impl IndexNode for LockedFATInode {
}
}
Ordering::Less => {
file.truncate(fs, len as u64)?;
guard.metadata.size = len as i64;
drop(guard);
if let Some(page_cache) = page_cache {
page_cache.manager().resize(len)?;
}
let mut guard: MutexGuard<FATInode> = self.0.lock();
let fs: &Arc<FATFileSystem> = &guard.fs.upgrade().unwrap();
match &mut guard.inode_type {
FATDirEntry::File(file) | FATDirEntry::VolId(file) => {
file.truncate(fs, len as u64)?;
guard.synchronize_metadata();
guard.metadata.size = len as i64;
return Ok(());
}
FATDirEntry::Dir(_) => return Err(SystemError::ENOSYS),
FATDirEntry::UnInit => {
error!("FATFS: param: Inode_type uninitialized.");
return Err(SystemError::EROFS);
}
}
}
}
// 同步元数据:从文件对象获取最新大小,并确保一致
Expand Down
Loading
Loading