Use CachePage in all related block functions

This commit is contained in:
Zhang Junyang
2024-12-27 11:55:56 +08:00
committed by Tate, Hongliang Tian
parent 983a6af3cc
commit ff453f5933
11 changed files with 72 additions and 67 deletions

View File

@ -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<BioWaiter> {
fn read_page_async(&self, idx: usize, frame: &CachePage) -> Result<BioWaiter> {
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<BioWaiter> {
fn write_page_async(&self, idx: usize, frame: &CachePage) -> Result<BioWaiter> {
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)?;

View File

@ -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<BioWaiter> {
fn read_page_async(&self, idx: usize, frame: &CachePage) -> Result<BioWaiter> {
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<BioWaiter> {
fn write_page_async(&self, idx: usize, frame: &CachePage) -> Result<BioWaiter> {
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,

View File

@ -318,20 +318,24 @@ impl Debug for BlockGroup {
}
impl PageCacheBackend for BlockGroupImpl {
fn read_page_async(&self, idx: usize, frame: &UFrame) -> Result<BioWaiter> {
fn read_page_async(&self, idx: usize, frame: &CachePage) -> Result<BioWaiter> {
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<BioWaiter> {
fn write_page_async(&self, idx: usize, frame: &CachePage) -> Result<BioWaiter> {
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()

View File

@ -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::<RawGroupDescriptor>())
.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)

View File

@ -1733,7 +1733,7 @@ impl InodeImpl {
writer: &mut VmWriter,
) -> Result<BioWaiter>;
pub fn read_blocks(&self, bid: Ext2Bid, nblocks: usize, writer: &mut VmWriter) -> Result<()>;
pub fn read_block_async(&self, bid: Ext2Bid, frame: &UFrame) -> Result<BioWaiter>;
pub fn read_block_async(&self, bid: Ext2Bid, frame: &CachePage) -> Result<BioWaiter>;
pub fn write_blocks_async(
&self,
bid: Ext2Bid,
@ -1741,7 +1741,7 @@ impl InodeImpl {
reader: &mut VmReader,
) -> Result<BioWaiter>;
pub fn write_blocks(&self, bid: Ext2Bid, nblocks: usize, reader: &mut VmReader) -> Result<()>;
pub fn write_block_async(&self, bid: Ext2Bid, frame: &UFrame) -> Result<BioWaiter>;
pub fn write_block_async(&self, bid: Ext2Bid, frame: &CachePage) -> Result<BioWaiter>;
}
/// 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<BioWaiter> {
pub fn read_block_async(&self, bid: Ext2Bid, frame: &CachePage) -> Result<BioWaiter> {
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<BioWaiter> {
pub fn write_block_async(&self, bid: Ext2Bid, frame: &CachePage) -> Result<BioWaiter> {
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<BioWaiter> {
fn read_page_async(&self, idx: usize, frame: &CachePage) -> Result<BioWaiter> {
let bid = idx as Ext2Bid;
self.read_block_async(bid, frame)
}
fn write_page_async(&self, idx: usize, frame: &UFrame) -> Result<BioWaiter> {
fn write_page_async(&self, idx: usize, frame: &CachePage) -> Result<BioWaiter> {
let bid = idx as Ext2Bid;
self.write_block_async(bid, frame)
}

View File

@ -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,

View File

@ -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<BioWaiter> {
fn read_page_async(&self, _idx: usize, frame: &CachePage) -> Result<BioWaiter> {
// 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<BioWaiter> {
fn write_page_async(&self, _idx: usize, _frame: &CachePage) -> Result<BioWaiter> {
// do nothing
Ok(BioWaiter::new())
}

View File

@ -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,

View File

@ -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<BioWaiter>;
fn read_page_async(&self, idx: usize, frame: &CachePage) -> Result<BioWaiter>;
/// Writes a page to the backend asynchronously.
fn write_page_async(&self, idx: usize, frame: &UFrame) -> Result<BioWaiter>;
fn write_page_async(&self, idx: usize, frame: &CachePage) -> Result<BioWaiter>;
/// 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(()),