mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-24 01:43:22 +00:00
Use CachePage
in all related block functions
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
983a6af3cc
commit
ff453f5933
@ -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)?;
|
||||
|
@ -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,
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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())
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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(()),
|
||||
|
Reference in New Issue
Block a user