diff --git a/kernel/src/fs/exfat/fs.rs b/kernel/src/fs/exfat/fs.rs index 979ae8709..3ceafbac9 100644 --- a/kernel/src/fs/exfat/fs.rs +++ b/kernel/src/fs/exfat/fs.rs @@ -12,7 +12,7 @@ use aster_block::{ }; use hashbrown::HashMap; use lru::LruCache; -use ostd::mm::UFrame; +use ostd::mm::Segment; pub(super) use ostd::mm::VmIo; use super::{ @@ -25,7 +25,7 @@ use super::{ use crate::{ fs::{ exfat::{constants::*, inode::Ino}, - utils::{FileSystem, FsFlags, Inode, PageCache, PageCacheBackend, SuperBlock}, + utils::{CachePage, FileSystem, FsFlags, Inode, PageCache, PageCacheBackend, SuperBlock}, }, prelude::*, }; @@ -368,24 +368,28 @@ impl ExfatFS { } impl PageCacheBackend for ExfatFS { - fn read_page_async(&self, idx: usize, frame: &UFrame) -> Result { + fn read_page_async(&self, idx: usize, frame: &CachePage) -> Result { if self.fs_size() < idx * PAGE_SIZE { return_errno_with_message!(Errno::EINVAL, "invalid read size") } - let bio_segment = - BioSegment::new_from_segment(frame.clone().into(), BioDirection::FromDevice); + let bio_segment = BioSegment::new_from_segment( + Segment::from(frame.clone()).into(), + BioDirection::FromDevice, + ); let waiter = self .block_device .read_blocks_async(BlockId::new(idx as u64), bio_segment)?; Ok(waiter) } - fn write_page_async(&self, idx: usize, frame: &UFrame) -> Result { + fn write_page_async(&self, idx: usize, frame: &CachePage) -> Result { if self.fs_size() < idx * PAGE_SIZE { return_errno_with_message!(Errno::EINVAL, "invalid write size") } - let bio_segment = - BioSegment::new_from_segment(frame.clone().into(), BioDirection::ToDevice); + let bio_segment = BioSegment::new_from_segment( + Segment::from(frame.clone()).into(), + BioDirection::ToDevice, + ); let waiter = self .block_device .write_blocks_async(BlockId::new(idx as u64), bio_segment)?; diff --git a/kernel/src/fs/exfat/inode.rs b/kernel/src/fs/exfat/inode.rs index 922cfcf98..44c4ed747 100644 --- a/kernel/src/fs/exfat/inode.rs +++ b/kernel/src/fs/exfat/inode.rs @@ -13,7 +13,7 @@ use aster_block::{ BLOCK_SIZE, }; use aster_rights::Full; -use ostd::mm::{UFrame, VmIo}; +use ostd::mm::{Segment, VmIo}; use super::{ constants::*, @@ -30,8 +30,8 @@ use crate::{ fs::{ exfat::{dentry::ExfatDentryIterator, fat::ExfatChain, fs::ExfatFS}, utils::{ - DirentVisitor, Extension, Inode, InodeMode, InodeType, IoctlCmd, Metadata, MknodType, - PageCache, PageCacheBackend, + CachePage, DirentVisitor, Extension, Inode, InodeMode, InodeType, IoctlCmd, Metadata, + MknodType, PageCache, PageCacheBackend, }, }, prelude::*, @@ -135,14 +135,16 @@ struct ExfatInodeInner { } impl PageCacheBackend for ExfatInode { - fn read_page_async(&self, idx: usize, frame: &UFrame) -> Result { + fn read_page_async(&self, idx: usize, frame: &CachePage) -> Result { let inner = self.inner.read(); if inner.size < idx * PAGE_SIZE { return_errno_with_message!(Errno::EINVAL, "Invalid read size") } let sector_id = inner.get_sector_id(idx * PAGE_SIZE / inner.fs().sector_size())?; - let bio_segment = - BioSegment::new_from_segment(frame.clone().into(), BioDirection::FromDevice); + let bio_segment = BioSegment::new_from_segment( + Segment::from(frame.clone()).into(), + BioDirection::FromDevice, + ); let waiter = inner.fs().block_device().read_blocks_async( BlockId::from_offset(sector_id * inner.fs().sector_size()), bio_segment, @@ -150,7 +152,7 @@ impl PageCacheBackend for ExfatInode { Ok(waiter) } - fn write_page_async(&self, idx: usize, frame: &UFrame) -> Result { + fn write_page_async(&self, idx: usize, frame: &CachePage) -> Result { let inner = self.inner.read(); let sector_size = inner.fs().sector_size(); @@ -158,8 +160,10 @@ impl PageCacheBackend for ExfatInode { // FIXME: We may need to truncate the file if write_page fails. // To fix this issue, we need to change the interface of the PageCacheBackend trait. - let bio_segment = - BioSegment::new_from_segment(frame.clone().into(), BioDirection::ToDevice); + let bio_segment = BioSegment::new_from_segment( + Segment::from(frame.clone()).into(), + BioDirection::ToDevice, + ); let waiter = inner.fs().block_device().write_blocks_async( BlockId::from_offset(sector_id * inner.fs().sector_size()), bio_segment, diff --git a/kernel/src/fs/ext2/block_group.rs b/kernel/src/fs/ext2/block_group.rs index ebf65e787..2e86fc7d8 100644 --- a/kernel/src/fs/ext2/block_group.rs +++ b/kernel/src/fs/ext2/block_group.rs @@ -318,20 +318,24 @@ impl Debug for BlockGroup { } impl PageCacheBackend for BlockGroupImpl { - fn read_page_async(&self, idx: usize, frame: &UFrame) -> Result { + fn read_page_async(&self, idx: usize, frame: &CachePage) -> Result { let bid = self.inode_table_bid + idx as Ext2Bid; - let bio_segment = - BioSegment::new_from_segment(frame.clone().into(), BioDirection::FromDevice); + let bio_segment = BioSegment::new_from_segment( + Segment::from(frame.clone()).into(), + BioDirection::FromDevice, + ); self.fs .upgrade() .unwrap() .read_blocks_async(bid, bio_segment) } - fn write_page_async(&self, idx: usize, frame: &UFrame) -> Result { + fn write_page_async(&self, idx: usize, frame: &CachePage) -> Result { let bid = self.inode_table_bid + idx as Ext2Bid; - let bio_segment = - BioSegment::new_from_segment(frame.clone().into(), BioDirection::ToDevice); + let bio_segment = BioSegment::new_from_segment( + Segment::from(frame.clone()).into(), + BioDirection::ToDevice, + ); self.fs .upgrade() .unwrap() diff --git a/kernel/src/fs/ext2/fs.rs b/kernel/src/fs/ext2/fs.rs index 5a3e31a47..4c9bd9c42 100644 --- a/kernel/src/fs/ext2/fs.rs +++ b/kernel/src/fs/ext2/fs.rs @@ -42,7 +42,7 @@ impl Ext2 { "currently only support 4096-byte block size" ); - let group_descriptors_segment = { + let group_descriptors_segment: USegment = { let npages = ((super_block.block_groups_count() as usize) * core::mem::size_of::()) .div_ceil(BLOCK_SIZE); @@ -57,7 +57,7 @@ impl Ext2 { return Err(Error::from(err_status)); } } - segment + segment.into() }; // Load the block groups information @@ -88,12 +88,12 @@ impl Ext2 { block_groups: load_block_groups( weak_ref.clone(), block_device.as_ref(), - (&group_descriptors_segment).into(), + &group_descriptors_segment, ) .unwrap(), block_device, super_block: RwMutex::new(Dirty::new(super_block)), - group_descriptors_segment: group_descriptors_segment.into(), + group_descriptors_segment, self_ref: weak_ref.clone(), }); Ok(ext2) diff --git a/kernel/src/fs/ext2/inode.rs b/kernel/src/fs/ext2/inode.rs index 5c71ac4eb..7d3fd85f4 100644 --- a/kernel/src/fs/ext2/inode.rs +++ b/kernel/src/fs/ext2/inode.rs @@ -1733,7 +1733,7 @@ impl InodeImpl { writer: &mut VmWriter, ) -> Result; pub fn read_blocks(&self, bid: Ext2Bid, nblocks: usize, writer: &mut VmWriter) -> Result<()>; - pub fn read_block_async(&self, bid: Ext2Bid, frame: &UFrame) -> Result; + pub fn read_block_async(&self, bid: Ext2Bid, frame: &CachePage) -> Result; pub fn write_blocks_async( &self, bid: Ext2Bid, @@ -1741,7 +1741,7 @@ impl InodeImpl { reader: &mut VmReader, ) -> Result; pub fn write_blocks(&self, bid: Ext2Bid, nblocks: usize, reader: &mut VmReader) -> Result<()>; - pub fn write_block_async(&self, bid: Ext2Bid, frame: &UFrame) -> Result; + pub fn write_block_async(&self, bid: Ext2Bid, frame: &CachePage) -> Result; } /// Manages the inode blocks and block I/O operations. @@ -1789,13 +1789,15 @@ impl InodeBlockManager { } } - pub fn read_block_async(&self, bid: Ext2Bid, frame: &UFrame) -> Result { + pub fn read_block_async(&self, bid: Ext2Bid, frame: &CachePage) -> Result { let mut bio_waiter = BioWaiter::new(); for dev_range in DeviceRangeReader::new(self, bid..bid + 1 as Ext2Bid)? { let start_bid = dev_range.start as Ext2Bid; - let bio_segment = - BioSegment::new_from_segment(frame.clone().into(), BioDirection::FromDevice); + let bio_segment = BioSegment::new_from_segment( + Segment::from(frame.clone()).into(), + BioDirection::FromDevice, + ); let waiter = self.fs().read_blocks_async(start_bid, bio_segment)?; bio_waiter.concat(waiter); } @@ -1834,13 +1836,15 @@ impl InodeBlockManager { } } - pub fn write_block_async(&self, bid: Ext2Bid, frame: &UFrame) -> Result { + pub fn write_block_async(&self, bid: Ext2Bid, frame: &CachePage) -> Result { let mut bio_waiter = BioWaiter::new(); for dev_range in DeviceRangeReader::new(self, bid..bid + 1 as Ext2Bid)? { let start_bid = dev_range.start as Ext2Bid; - let bio_segment = - BioSegment::new_from_segment(frame.clone().into(), BioDirection::ToDevice); + let bio_segment = BioSegment::new_from_segment( + Segment::from(frame.clone()).into(), + BioDirection::ToDevice, + ); let waiter = self.fs().write_blocks_async(start_bid, bio_segment)?; bio_waiter.concat(waiter); } @@ -1858,12 +1862,12 @@ impl InodeBlockManager { } impl PageCacheBackend for InodeBlockManager { - fn read_page_async(&self, idx: usize, frame: &UFrame) -> Result { + fn read_page_async(&self, idx: usize, frame: &CachePage) -> Result { let bid = idx as Ext2Bid; self.read_block_async(bid, frame) } - fn write_page_async(&self, idx: usize, frame: &UFrame) -> Result { + fn write_page_async(&self, idx: usize, frame: &CachePage) -> Result { let bid = idx as Ext2Bid; self.write_block_async(bid, frame) } diff --git a/kernel/src/fs/ext2/prelude.rs b/kernel/src/fs/ext2/prelude.rs index ce780a61d..ead2bb334 100644 --- a/kernel/src/fs/ext2/prelude.rs +++ b/kernel/src/fs/ext2/prelude.rs @@ -13,14 +13,16 @@ pub(super) use aster_block::{ }; pub(super) use aster_rights::Full; pub(super) use ostd::{ - mm::{Frame, FrameAllocOptions, Segment, UFrame, USegment, VmIo}, + mm::{Frame, FrameAllocOptions, Segment, USegment, VmIo}, sync::{RwMutex, RwMutexReadGuard, RwMutexWriteGuard}, }; pub(super) use static_assertions::const_assert; pub(super) use super::utils::{Dirty, IsPowerOf}; pub(super) use crate::{ - fs::utils::{CStr256, DirentVisitor, InodeType, PageCache, PageCacheBackend, Str16, Str64}, + fs::utils::{ + CStr256, CachePage, DirentVisitor, InodeType, PageCache, PageCacheBackend, Str16, Str64, + }, prelude::*, time::UnixTime, vm::vmo::Vmo, diff --git a/kernel/src/fs/ramfs/fs.rs b/kernel/src/fs/ramfs/fs.rs index f14cd266e..1b798b48f 100644 --- a/kernel/src/fs/ramfs/fs.rs +++ b/kernel/src/fs/ramfs/fs.rs @@ -11,7 +11,7 @@ use aster_rights::Full; use aster_util::slot_vec::SlotVec; use hashbrown::HashMap; use ostd::{ - mm::{UFrame, UntypedMem, VmIo}, + mm::{UntypedMem, VmIo}, sync::{PreemptDisabled, RwLockWriteGuard}, }; @@ -23,8 +23,9 @@ use crate::{ file_handle::FileLike, named_pipe::NamedPipe, utils::{ - CStr256, DirentVisitor, Extension, FallocMode, FileSystem, FsFlags, Inode, InodeMode, - InodeType, IoctlCmd, Metadata, MknodType, PageCache, PageCacheBackend, SuperBlock, + CStr256, CachePage, DirentVisitor, Extension, FallocMode, FileSystem, FsFlags, Inode, + InodeMode, InodeType, IoctlCmd, Metadata, MknodType, PageCache, PageCacheBackend, + SuperBlock, }, }, prelude::*, @@ -484,7 +485,7 @@ impl RamInode { } impl PageCacheBackend for RamInode { - fn read_page_async(&self, _idx: usize, frame: &UFrame) -> Result { + fn read_page_async(&self, _idx: usize, frame: &CachePage) -> Result { // Initially, any block/page in a RamFs inode contains all zeros frame .writer() @@ -494,7 +495,7 @@ impl PageCacheBackend for RamInode { Ok(BioWaiter::new()) } - fn write_page_async(&self, _idx: usize, _frame: &UFrame) -> Result { + fn write_page_async(&self, _idx: usize, _frame: &CachePage) -> Result { // do nothing Ok(BioWaiter::new()) } diff --git a/kernel/src/fs/utils/mod.rs b/kernel/src/fs/utils/mod.rs index d9381c2ad..058639632 100644 --- a/kernel/src/fs/utils/mod.rs +++ b/kernel/src/fs/utils/mod.rs @@ -13,7 +13,7 @@ pub use flock::{FlockItem, FlockList, FlockType}; pub use fs::{FileSystem, FsFlags, SuperBlock}; pub use inode::{Extension, Inode, InodeMode, InodeType, Metadata, MknodType, Permission}; pub use ioctl::IoctlCmd; -pub use page_cache::{PageCache, PageCacheBackend}; +pub use page_cache::{CachePage, PageCache, PageCacheBackend}; pub use random_test::{generate_random_operation, new_fs_in_memory}; pub use range_lock::{ FileRange, RangeLockItem, RangeLockItemBuilder, RangeLockList, RangeLockType, OFFSET_MAX, diff --git a/kernel/src/fs/utils/page_cache.rs b/kernel/src/fs/utils/page_cache.rs index 0689df2a5..990f27323 100644 --- a/kernel/src/fs/utils/page_cache.rs +++ b/kernel/src/fs/utils/page_cache.rs @@ -312,7 +312,7 @@ impl ReadaheadState { }; for async_idx in window.readahead_range() { let mut async_page = CachePage::alloc()?; - let pg_waiter = backend.read_page_async(async_idx, (&async_page).into())?; + let pg_waiter = backend.read_page_async(async_idx, &async_page)?; if pg_waiter.nreqs() > 0 { self.waiter.concat(pg_waiter); } else { @@ -368,7 +368,7 @@ impl PageCacheManager { for idx in page_idx_range.start..page_idx_range.end { if let Some(page) = pages.peek(&idx) { if page.load_state() == PageState::Dirty && idx < backend_npages { - let waiter = backend.write_page_async(idx, page.into())?; + let waiter = backend.write_page_async(idx, page)?; bio_waiter.concat(waiter); } } @@ -417,7 +417,7 @@ impl PageCacheManager { // Conducts the sync read operation. let page = if idx < backend.npages() { let mut page = CachePage::alloc()?; - backend.read_page(idx, (&page).into())?; + backend.read_page(idx, &page)?; page.store_state(PageState::UpToDate); page } else { @@ -468,7 +468,7 @@ impl Pager for PageCacheManager { return Ok(()); }; if idx < backend.npages() { - backend.write_page(idx, (&page).into())?; + backend.write_page(idx, &page)?; } } } @@ -573,16 +573,16 @@ impl AtomicPageState { /// This trait represents the backend for the page cache. pub trait PageCacheBackend: Sync + Send { /// Reads a page from the backend asynchronously. - fn read_page_async(&self, idx: usize, frame: &UFrame) -> Result; + fn read_page_async(&self, idx: usize, frame: &CachePage) -> Result; /// Writes a page to the backend asynchronously. - fn write_page_async(&self, idx: usize, frame: &UFrame) -> Result; + fn write_page_async(&self, idx: usize, frame: &CachePage) -> Result; /// Returns the number of pages in the backend. fn npages(&self) -> usize; } impl dyn PageCacheBackend { /// Reads a page from the backend synchronously. - fn read_page(&self, idx: usize, frame: &UFrame) -> Result<()> { + fn read_page(&self, idx: usize, frame: &CachePage) -> Result<()> { let waiter = self.read_page_async(idx, frame)?; match waiter.wait() { Some(BioStatus::Complete) => Ok(()), @@ -590,7 +590,7 @@ impl dyn PageCacheBackend { } } /// Writes a page to the backend synchronously. - fn write_page(&self, idx: usize, frame: &UFrame) -> Result<()> { + fn write_page(&self, idx: usize, frame: &CachePage) -> Result<()> { let waiter = self.write_page_async(idx, frame)?; match waiter.wait() { Some(BioStatus::Complete) => Ok(()), diff --git a/ostd/src/mm/frame/mod.rs b/ostd/src/mm/frame/mod.rs index 0486e1a06..e11a4cceb 100644 --- a/ostd/src/mm/frame/mod.rs +++ b/ostd/src/mm/frame/mod.rs @@ -307,13 +307,6 @@ impl From> for UFrame { } } -impl From<&Frame> for &UFrame { - fn from(frame: &Frame) -> Self { - // SAFETY: The metadata is coerceable and the struct is transmutable. - unsafe { core::mem::transmute(frame) } - } -} - impl From for Frame { fn from(frame: UFrame) -> Self { // SAFETY: The metadata is coerceable and the struct is transmutable. diff --git a/ostd/src/mm/frame/segment.rs b/ostd/src/mm/frame/segment.rs index 6e41036ff..ac86a916e 100644 --- a/ostd/src/mm/frame/segment.rs +++ b/ostd/src/mm/frame/segment.rs @@ -231,13 +231,6 @@ impl From> for USegment { } } -impl From<&Segment> for &USegment { - fn from(seg: &Segment) -> Self { - // SAFETY: The metadata is coerceable and the struct is transmutable. - unsafe { core::mem::transmute(seg) } - } -} - impl TryFrom> for USegment { type Error = Segment;