summaryrefslogtreecommitdiff
path: root/ayafs-core/src/memory/cached_block.rs
diff options
context:
space:
mode:
authorChuyan Zhang <me@zcy.moe>2023-12-01 19:42:13 -0800
committerChuyan Zhang <me@zcy.moe>2023-12-01 19:42:13 -0800
commit4c34414b26bf71e747ea3ecb2586645bab4aba52 (patch)
treeb569935a94c7fb3e0a23a19207f6545b4d7719c3 /ayafs-core/src/memory/cached_block.rs
parentfd125947c9db0b33761414e65e919f73d9bf1815 (diff)
downloadmyfs-4c34414b26bf71e747ea3ecb2586645bab4aba52.tar.gz
myfs-4c34414b26bf71e747ea3ecb2586645bab4aba52.zip
Multiple bugfix, it works!
Diffstat (limited to 'ayafs-core/src/memory/cached_block.rs')
-rw-r--r--ayafs-core/src/memory/cached_block.rs79
1 files changed, 63 insertions, 16 deletions
diff --git a/ayafs-core/src/memory/cached_block.rs b/ayafs-core/src/memory/cached_block.rs
index c3d0338..24f08c0 100644
--- a/ayafs-core/src/memory/cached_block.rs
+++ b/ayafs-core/src/memory/cached_block.rs
@@ -4,6 +4,7 @@ use crate::AyaFS;
use lru::LruCache;
use std::num::NonZeroUsize;
use std::sync::Arc;
+use log::debug;
#[derive(Clone)]
pub struct CachedBlock<T: Block> {
@@ -27,20 +28,37 @@ pub fn convert<U: Block, T: Block>(input_block: &CachedBlock<U>) -> &CachedBlock
pub(crate) struct BlockCache<T: Block> {
device: Arc<dyn BlockDevice>,
cache: LruCache<usize, CachedBlock<T>>,
+ pub global_offset: usize,
}
impl<T: Block> BlockCache<T> {
- pub(crate) fn new(device: Arc<dyn BlockDevice>, cache_size: usize) -> Self {
+ pub(crate) fn new(device: Arc<dyn BlockDevice>, cache_size: usize, global_offset: usize) -> Self {
Self {
device,
cache: LruCache::new(NonZeroUsize::new(cache_size).unwrap()),
+ global_offset,
+ }
+ }
+
+ pub(crate) fn write_back(&self) {
+ for (_, cached_block) in self.cache.iter() {
+ if cached_block.dirty {
+ debug!("write_back: dirty block {}", self.global_offset + cached_block.index);
+ let block_buffer = unsafe {
+ let block_ptr = &cached_block.block as *const T as *const u8;
+ std::slice::from_raw_parts(block_ptr, std::mem::size_of::<T>())
+ };
+ self.device.write(self.global_offset + cached_block.index, block_buffer);
+ } else {
+ debug!("write_back: clean block {}", self.global_offset + cached_block.index);
+ }
}
}
pub(crate) fn load_block(&mut self, index: usize) -> bool {
if self.cache.contains(&index) == false {
let mut buffer = [0u8; BLOCK_SIZE];
- self.device.read(index, &mut buffer);
+ self.device.read(self.global_offset + index, &mut buffer);
let block: T = unsafe { std::mem::transmute_copy(&buffer) };
let cached_block = CachedBlock {
block,
@@ -50,10 +68,12 @@ impl<T: Block> BlockCache<T> {
if let Some((old_index, old_block)) = self.cache.push(index, cached_block) {
assert_ne!(old_index, index); // 只有 block 不在 cache 里的时候才会插入
if old_block.dirty {
- let old_block_ptr = &old_block.block as *const T as *mut u8;
- let old_block_buffer =
- unsafe { std::slice::from_raw_parts(old_block_ptr, BLOCK_SIZE) };
- self.device.write(old_index, old_block_buffer);
+ debug!("write_back: evicted dirty block {} while loading {}", self.global_offset + old_block.index, self.global_offset + index);
+ let old_block_buffer = unsafe {
+ let old_block_ptr = &old_block.block as *const T as *mut u8;
+ std::slice::from_raw_parts(old_block_ptr, BLOCK_SIZE)
+ };
+ self.device.write(self.global_offset + old_block.index, old_block_buffer);
}
}
}
@@ -64,21 +84,43 @@ impl<T: Block> BlockCache<T> {
/// 这个函数不应该返回 None
pub(crate) fn get_block<U: Block>(&mut self, index: usize) -> Option<&CachedBlock<U>> {
if !self.cache.contains(&index) {
+ debug!("get_block(global_block_id: {}) loading from disk", index + self.global_offset);
self.load_block(index);
}
- self.cache.get(&index).map(convert::<T, U>)
+
+ if let Some(block) = self.cache.get(&index) {
+ debug!("get_block(global_block_id: {}) found", index + self.global_offset);
+ Some(convert::<T, U>(block))
+ } else {
+ debug!("get_block(global_block_id: {}) not found", index + self.global_offset);
+ None
+ }
+ // debug!("get_block(global_block_id: {}) found", index + self.global_offset);
+ // self.cache.get(&index).map(convert::<T, U>)
}
/// 从 LRU cache 里获取一个 block 的可变引用, 如果没有在 cache 中会加载.
/// 这个函数不应该返回 None
pub(crate) fn get_block_mut<U: Block>(&mut self, index: usize) -> Option<&mut CachedBlock<U>> {
if !self.cache.contains(&index) {
+ debug!("get_block_mut(global_block_id: {}) loading from disk", index + self.global_offset);
self.load_block(index);
}
- self.cache.get_mut(&index).map(|block| {
+
+ if let Some(block) = self.cache.get_mut(&index) {
+ debug!("get_block_mut(global_block_id: {}) found", index + self.global_offset);
block.dirty = true;
- convert_mut::<T, U>(block)
- })
+ Some(convert_mut::<T, U>(block))
+ } else {
+ debug!("get_block_mut(global_block_id: {}) not found", index + self.global_offset);
+ None
+ }
+
+ // self.cache.get_mut(&index).map(|block| {
+ // debug!("get_block_mut(global_block_id: {}) found", index + self.global_offset);
+ // block.dirty = true;
+ // convert_mut::<T, U>(block)
+ // })
}
/// 向 LRU cache 中插入一个全新初始化的 block
@@ -94,7 +136,7 @@ impl<T: Block> BlockCache<T> {
let old_block_ptr = &old_block.block as *const T as *mut u8;
let old_block_buffer =
unsafe { std::slice::from_raw_parts(old_block_ptr, BLOCK_SIZE) };
- self.device.write(old_index, old_block_buffer);
+ self.device.write(self.global_offset + old_index, old_block_buffer);
}
}
}
@@ -115,15 +157,18 @@ impl<T: Block> BlockCache<T> {
if self.cache.contains(&block.index) {
let mut data_block = convert::<U, T>(&block).clone();
data_block.dirty = true; // TODO 需要把显式写回的都标记为 dirty 吗
- self.cache.push(block.index, data_block);
+ let (entry, _value) = self.cache.push(block.index, data_block).unwrap();
+ assert_eq!(entry, block.index);
+ debug!("update_block(global_block_id: {})", block.index + self.global_offset);
true
} else {
false
}
}
- fn pop(&mut self, entry: &usize) -> Option<CachedBlock<T>> {
- self.cache.pop(entry)
+ fn pop(&mut self, entry: usize) -> Option<CachedBlock<T>> {
+ debug!("pop_block(global_block_id: {})", entry + self.global_offset);
+ self.cache.pop(&entry)
}
}
@@ -134,9 +179,11 @@ impl AyaFS {
pub(crate) fn get_block<T: Block>(&mut self, index: usize) -> Option<&CachedBlock<T>> {
if self.data_bitmap.query(index) {
+ debug!("get_block(block_id: {}) found", index);
Some(self.cached_blocks.get_block::<T>(index).unwrap())
} else {
- self.cached_blocks.pop(&index);
+ debug!("get_block(block_id: {}) not exist", index);
+ self.cached_blocks.pop(index);
None
}
// self.data_bitmap
@@ -149,7 +196,7 @@ impl AyaFS {
if self.data_bitmap.query(index) {
Some(self.cached_blocks.get_block_mut::<T>(index).unwrap())
} else {
- self.cached_blocks.pop(&index);
+ self.cached_blocks.pop(index);
None
}
// self.data_bitmap