diff --git a/kernel/aster-nix/src/fs/exfat/fs.rs b/kernel/aster-nix/src/fs/exfat/fs.rs index 6d50486f..3b9a8a34 100644 --- a/kernel/aster-nix/src/fs/exfat/fs.rs +++ b/kernel/aster-nix/src/fs/exfat/fs.rs @@ -364,23 +364,23 @@ impl ExfatFS { } impl PageCacheBackend for ExfatFS { - fn read_page(&self, idx: usize, frame: &Frame) -> Result { + fn read_page_async(&self, idx: usize, frame: &Frame) -> Result { if self.fs_size() < idx * PAGE_SIZE { return_errno_with_message!(Errno::EINVAL, "invalid read size") } let waiter = self .block_device - .read_block(BlockId::new(idx as u64), frame)?; + .read_block_async(BlockId::new(idx as u64), frame)?; Ok(waiter) } - fn write_page(&self, idx: usize, frame: &Frame) -> Result { + fn write_page_async(&self, idx: usize, frame: &Frame) -> Result { if self.fs_size() < idx * PAGE_SIZE { return_errno_with_message!(Errno::EINVAL, "invalid write size") } let waiter = self .block_device - .write_block(BlockId::new(idx as u64), frame)?; + .write_block_async(BlockId::new(idx as u64), frame)?; Ok(waiter) } diff --git a/kernel/aster-nix/src/fs/exfat/inode.rs b/kernel/aster-nix/src/fs/exfat/inode.rs index d22b950e..7da4fe3e 100644 --- a/kernel/aster-nix/src/fs/exfat/inode.rs +++ b/kernel/aster-nix/src/fs/exfat/inode.rs @@ -135,20 +135,20 @@ struct ExfatInodeInner { } impl PageCacheBackend for ExfatInode { - fn read_page(&self, idx: usize, frame: &Frame) -> Result { + fn read_page_async(&self, idx: usize, frame: &Frame) -> 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 waiter = inner.fs().block_device().read_block( + let waiter = inner.fs().block_device().read_block_async( BlockId::from_offset(sector_id * inner.fs().sector_size()), frame, )?; Ok(waiter) } - fn write_page(&self, idx: usize, frame: &Frame) -> Result { + fn write_page_async(&self, idx: usize, frame: &Frame) -> Result { let inner = self.inner.read(); let sector_size = inner.fs().sector_size(); @@ -156,7 +156,7 @@ 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 waiter = inner.fs().block_device().write_block( + let waiter = inner.fs().block_device().write_block_async( BlockId::from_offset(sector_id * inner.fs().sector_size()), frame, )?; @@ -1274,10 +1274,7 @@ impl Inode for ExfatInode { for _ in Bid::from_offset(read_off)..Bid::from_offset(read_off + read_len) { let physical_bid = Bid::from_offset(cur_cluster.cluster_id() as usize * cluster_size + cur_offset); - inner - .fs() - .block_device() - .read_block_sync(physical_bid, &frame)?; + inner.fs().block_device().read_block(physical_bid, &frame)?; frame.read_bytes(0, &mut buf[buf_offset..buf_offset + BLOCK_SIZE])?; buf_offset += BLOCK_SIZE; @@ -1388,7 +1385,7 @@ impl Inode for ExfatInode { let physical_bid = Bid::from_offset(cur_cluster.cluster_id() as usize * cluster_size + cur_offset); let fs = inner.fs(); - fs.block_device().write_block_sync(physical_bid, &frame)?; + fs.block_device().write_block(physical_bid, &frame)?; buf_offset += BLOCK_SIZE; cur_offset += BLOCK_SIZE; diff --git a/kernel/aster-nix/src/fs/ext2/block_group.rs b/kernel/aster-nix/src/fs/ext2/block_group.rs index 298b2a2a..ccc2368e 100644 --- a/kernel/aster-nix/src/fs/ext2/block_group.rs +++ b/kernel/aster-nix/src/fs/ext2/block_group.rs @@ -318,12 +318,12 @@ impl Debug for BlockGroup { } impl PageCacheBackend for BlockGroupImpl { - fn read_page(&self, idx: usize, frame: &Frame) -> Result { + fn read_page_async(&self, idx: usize, frame: &Frame) -> Result { let bid = self.inode_table_bid + idx as Ext2Bid; self.fs.upgrade().unwrap().read_block_async(bid, frame) } - fn write_page(&self, idx: usize, frame: &Frame) -> Result { + fn write_page_async(&self, idx: usize, frame: &Frame) -> Result { let bid = self.inode_table_bid + idx as Ext2Bid; self.fs.upgrade().unwrap().write_block_async(bid, frame) } diff --git a/kernel/aster-nix/src/fs/ext2/fs.rs b/kernel/aster-nix/src/fs/ext2/fs.rs index 6420096f..b559f4dd 100644 --- a/kernel/aster-nix/src/fs/ext2/fs.rs +++ b/kernel/aster-nix/src/fs/ext2/fs.rs @@ -49,7 +49,7 @@ impl Ext2 { let segment = FrameAllocOptions::new(npages) .uninit(true) .alloc_contiguous()?; - match block_device.read_blocks_sync(super_block.group_descriptors_bid(0), &segment)? { + match block_device.read_blocks(super_block.group_descriptors_bid(0), &segment)? { BioStatus::Complete => (), err_status => { return Err(Error::from(err_status)); @@ -300,7 +300,7 @@ impl Ext2 { pub(super) fn read_blocks(&self, bid: Ext2Bid, segment: &Segment) -> Result<()> { let status = self .block_device - .read_blocks_sync(Bid::new(bid as u64), segment)?; + .read_blocks(Bid::new(bid as u64), segment)?; match status { BioStatus::Complete => Ok(()), err_status => Err(Error::from(err_status)), @@ -311,15 +311,13 @@ impl Ext2 { pub(super) fn read_blocks_async(&self, bid: Ext2Bid, segment: &Segment) -> Result { let waiter = self .block_device - .read_blocks(Bid::new(bid as u64), segment)?; + .read_blocks_async(Bid::new(bid as u64), segment)?; Ok(waiter) } /// Reads one block indicated by the `bid` synchronously. pub(super) fn read_block(&self, bid: Ext2Bid, frame: &Frame) -> Result<()> { - let status = self - .block_device - .read_block_sync(Bid::new(bid as u64), frame)?; + let status = self.block_device.read_block(Bid::new(bid as u64), frame)?; match status { BioStatus::Complete => Ok(()), err_status => Err(Error::from(err_status)), @@ -328,7 +326,9 @@ impl Ext2 { /// Reads one block indicated by the `bid` asynchronously. pub(super) fn read_block_async(&self, bid: Ext2Bid, frame: &Frame) -> Result { - let waiter = self.block_device.read_block(Bid::new(bid as u64), frame)?; + let waiter = self + .block_device + .read_block_async(Bid::new(bid as u64), frame)?; Ok(waiter) } @@ -336,7 +336,7 @@ impl Ext2 { pub(super) fn write_blocks(&self, bid: Ext2Bid, segment: &Segment) -> Result<()> { let status = self .block_device - .write_blocks_sync(Bid::new(bid as u64), segment)?; + .write_blocks(Bid::new(bid as u64), segment)?; match status { BioStatus::Complete => Ok(()), err_status => Err(Error::from(err_status)), @@ -347,15 +347,13 @@ impl Ext2 { pub(super) fn write_blocks_async(&self, bid: Ext2Bid, segment: &Segment) -> Result { let waiter = self .block_device - .write_blocks(Bid::new(bid as u64), segment)?; + .write_blocks_async(Bid::new(bid as u64), segment)?; Ok(waiter) } /// Writes one block indicated by the `bid` synchronously. pub(super) fn write_block(&self, bid: Ext2Bid, frame: &Frame) -> Result<()> { - let status = self - .block_device - .write_block_sync(Bid::new(bid as u64), frame)?; + let status = self.block_device.write_block(Bid::new(bid as u64), frame)?; match status { BioStatus::Complete => Ok(()), err_status => Err(Error::from(err_status)), @@ -364,7 +362,9 @@ impl Ext2 { /// Writes one block indicated by the `bid` asynchronously. pub(super) fn write_block_async(&self, bid: Ext2Bid, frame: &Frame) -> Result { - let waiter = self.block_device.write_block(Bid::new(bid as u64), frame)?; + let waiter = self + .block_device + .write_block_async(Bid::new(bid as u64), frame)?; Ok(waiter) } @@ -388,7 +388,7 @@ impl Ext2 { self.block_device .write_bytes_async(SUPER_BLOCK_OFFSET, raw_super_block.as_bytes())?, ); - bio_waiter.concat(self.block_device.write_blocks( + bio_waiter.concat(self.block_device.write_blocks_async( super_block.group_descriptors_bid(0), &self.group_descriptors_segment, )?); @@ -407,7 +407,7 @@ impl Ext2 { super_block.bid(idx as usize).to_offset(), raw_super_block_backup.as_bytes(), )?); - bio_waiter.concat(self.block_device.write_blocks( + bio_waiter.concat(self.block_device.write_blocks_async( super_block.group_descriptors_bid(idx as usize), &self.group_descriptors_segment, )?); diff --git a/kernel/aster-nix/src/fs/ext2/inode.rs b/kernel/aster-nix/src/fs/ext2/inode.rs index 365fb3f4..e5a73980 100644 --- a/kernel/aster-nix/src/fs/ext2/inode.rs +++ b/kernel/aster-nix/src/fs/ext2/inode.rs @@ -1941,12 +1941,12 @@ impl InodeImpl { } impl PageCacheBackend for InodeImpl { - fn read_page(&self, idx: usize, frame: &Frame) -> Result { + fn read_page_async(&self, idx: usize, frame: &Frame) -> Result { let bid = idx as Ext2Bid; self.read_blocks_async(bid, &Segment::from(frame.clone())) } - fn write_page(&self, idx: usize, frame: &Frame) -> Result { + fn write_page_async(&self, idx: usize, frame: &Frame) -> Result { let bid = idx as Ext2Bid; self.write_blocks_async(bid, &Segment::from(frame.clone())) } diff --git a/kernel/aster-nix/src/fs/ramfs/fs.rs b/kernel/aster-nix/src/fs/ramfs/fs.rs index f0a978b2..d49e6903 100644 --- a/kernel/aster-nix/src/fs/ramfs/fs.rs +++ b/kernel/aster-nix/src/fs/ramfs/fs.rs @@ -481,13 +481,13 @@ impl RamInode { } impl PageCacheBackend for RamInode { - fn read_page(&self, _idx: usize, frame: &Frame) -> Result { + fn read_page_async(&self, _idx: usize, frame: &Frame) -> Result { // Initially, any block/page in a RamFs inode contains all zeros frame.writer().fill(0); Ok(BioWaiter::new()) } - fn write_page(&self, _idx: usize, _frame: &Frame) -> Result { + fn write_page_async(&self, _idx: usize, _frame: &Frame) -> Result { // do nothing Ok(BioWaiter::new()) } diff --git a/kernel/aster-nix/src/fs/utils/page_cache.rs b/kernel/aster-nix/src/fs/utils/page_cache.rs index 1675a461..5dbf53a8 100644 --- a/kernel/aster-nix/src/fs/utils/page_cache.rs +++ b/kernel/aster-nix/src/fs/utils/page_cache.rs @@ -305,7 +305,7 @@ impl ReadaheadState { }; for async_idx in window.readahead_range() { let mut async_page = Page::alloc()?; - let pg_waiter = backend.read_page(async_idx, async_page.frame())?; + let pg_waiter = backend.read_page_async(async_idx, async_page.frame())?; self.waiter.concat(pg_waiter); async_page.set_state(PageState::Uninit); pages.put(async_idx, async_page); @@ -341,8 +341,9 @@ impl PageCacheManager { // Discard pages without writing them back to disk. pub fn discard_range(&self, range: Range) { let page_idx_range = get_page_idx_range(&range); + let mut pages = self.pages.lock(); for idx in page_idx_range { - self.pages.lock().pop(&idx); + pages.pop(&idx); } } @@ -356,7 +357,7 @@ impl PageCacheManager { for idx in page_idx_range.start..page_idx_range.end { if let Some(page) = pages.peek(&idx) { if *page.state() == PageState::Dirty && idx < backend_npages { - let waiter = backend.write_page(idx, page.frame())?; + let waiter = backend.write_page_async(idx, page.frame())?; bio_waiter.concat(waiter); } } @@ -407,7 +408,7 @@ impl PageCacheManager { // Conducts the sync read operation. let page = if idx < backend.npages() { let mut page = Page::alloc()?; - backend.read_page_sync(idx, page.frame())?; + backend.read_page(idx, page.frame())?; page.set_state(PageState::UpToDate); page } else { @@ -458,7 +459,7 @@ impl Pager for PageCacheManager { return Ok(()); }; if idx < backend.npages() { - backend.write_page_sync(idx, page.frame())?; + backend.write_page(idx, page.frame())?; } } } @@ -528,25 +529,25 @@ enum PageState { /// This trait represents the backend for the page cache. pub trait PageCacheBackend: Sync + Send { /// Reads a page from the backend asynchronously. - fn read_page(&self, idx: usize, frame: &Frame) -> Result; + fn read_page_async(&self, idx: usize, frame: &Frame) -> Result; /// Writes a page to the backend asynchronously. - fn write_page(&self, idx: usize, frame: &Frame) -> Result; + fn write_page_async(&self, idx: usize, frame: &Frame) -> 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_sync(&self, idx: usize, frame: &Frame) -> Result<()> { - let waiter = self.read_page(idx, frame)?; + fn read_page(&self, idx: usize, frame: &Frame) -> Result<()> { + let waiter = self.read_page_async(idx, frame)?; match waiter.wait() { Some(BioStatus::Complete) => Ok(()), _ => return_errno!(Errno::EIO), } } /// Writes a page to the backend synchronously. - fn write_page_sync(&self, idx: usize, frame: &Frame) -> Result<()> { - let waiter = self.write_page(idx, frame)?; + fn write_page(&self, idx: usize, frame: &Frame) -> Result<()> { + let waiter = self.write_page_async(idx, frame)?; match waiter.wait() { Some(BioStatus::Complete) => Ok(()), _ => return_errno!(Errno::EIO), diff --git a/kernel/comps/block/src/bio.rs b/kernel/comps/block/src/bio.rs index 37bf9e39..b17f747e 100644 --- a/kernel/comps/block/src/bio.rs +++ b/kernel/comps/block/src/bio.rs @@ -110,7 +110,7 @@ impl Bio { /// # Panics /// /// The caller must not submit a `Bio` more than once. Otherwise, a panic shall be triggered. - pub fn submit_sync( + pub fn submit_and_wait( &self, block_device: &dyn BlockDevice, ) -> Result { diff --git a/kernel/comps/block/src/impl_block_device.rs b/kernel/comps/block/src/impl_block_device.rs index f4764a6a..76e85c0f 100644 --- a/kernel/comps/block/src/impl_block_device.rs +++ b/kernel/comps/block/src/impl_block_device.rs @@ -14,61 +14,61 @@ use crate::prelude::*; // TODO: Add API to submit bio with multiple segments in scatter/gather manner. impl dyn BlockDevice { /// Synchronously reads contiguous blocks starting from the `bid`. - pub fn read_blocks_sync( - &self, - bid: Bid, - segment: &Segment, - ) -> Result { + pub fn read_blocks(&self, bid: Bid, segment: &Segment) -> Result { let bio = create_bio_from_segment(BioType::Read, bid, segment); - let status = bio.submit_sync(self)?; + let status = bio.submit_and_wait(self)?; Ok(status) } /// Asynchronously reads contiguous blocks starting from the `bid`. - pub fn read_blocks(&self, bid: Bid, segment: &Segment) -> Result { + pub fn read_blocks_async( + &self, + bid: Bid, + segment: &Segment, + ) -> Result { let bio = create_bio_from_segment(BioType::Read, bid, segment); bio.submit(self) } /// Synchronously reads one block indicated by the `bid`. - pub fn read_block_sync(&self, bid: Bid, frame: &Frame) -> Result { + pub fn read_block(&self, bid: Bid, frame: &Frame) -> Result { let bio = create_bio_from_frame(BioType::Read, bid, frame); - let status = bio.submit_sync(self)?; + let status = bio.submit_and_wait(self)?; Ok(status) } /// Asynchronously reads one block indicated by the `bid`. - pub fn read_block(&self, bid: Bid, frame: &Frame) -> Result { + pub fn read_block_async(&self, bid: Bid, frame: &Frame) -> Result { let bio = create_bio_from_frame(BioType::Read, bid, frame); bio.submit(self) } /// Synchronously writes contiguous blocks starting from the `bid`. - pub fn write_blocks_sync( - &self, - bid: Bid, - segment: &Segment, - ) -> Result { + pub fn write_blocks(&self, bid: Bid, segment: &Segment) -> Result { let bio = create_bio_from_segment(BioType::Write, bid, segment); - let status = bio.submit_sync(self)?; + let status = bio.submit_and_wait(self)?; Ok(status) } /// Asynchronously writes contiguous blocks starting from the `bid`. - pub fn write_blocks(&self, bid: Bid, segment: &Segment) -> Result { + pub fn write_blocks_async( + &self, + bid: Bid, + segment: &Segment, + ) -> Result { let bio = create_bio_from_segment(BioType::Write, bid, segment); bio.submit(self) } /// Synchronously writes one block indicated by the `bid`. - pub fn write_block_sync(&self, bid: Bid, frame: &Frame) -> Result { + pub fn write_block(&self, bid: Bid, frame: &Frame) -> Result { let bio = create_bio_from_frame(BioType::Write, bid, frame); - let status = bio.submit_sync(self)?; + let status = bio.submit_and_wait(self)?; Ok(status) } /// Asynchronously writes one block indicated by the `bid`. - pub fn write_block(&self, bid: Bid, frame: &Frame) -> Result { + pub fn write_block_async(&self, bid: Bid, frame: &Frame) -> Result { let bio = create_bio_from_frame(BioType::Write, bid, frame); bio.submit(self) } @@ -106,7 +106,7 @@ impl VmIo for dyn BlockDevice { ) }; - let status = bio.submit_sync(self)?; + let status = bio.submit_and_wait(self)?; match status { BioStatus::Complete => { let _ = bio_segment.reader().read(&mut buf.into()); @@ -148,7 +148,7 @@ impl VmIo for dyn BlockDevice { ) }; - let status = bio.submit_sync(self)?; + let status = bio.submit_and_wait(self)?; match status { BioStatus::Complete => Ok(()), _ => Err(ostd::Error::IoError),