Create two files and list them.

This commit is contained in:
Yifan Wu 2020-12-19 15:28:42 +08:00
parent 00eaa64e7d
commit 3c1419185d
7 changed files with 104 additions and 36 deletions

View file

@ -1,45 +1,38 @@
use super::BlockDevice;
use super::BLOCK_SZ;
use super::{
BlockDevice,
BLOCK_SZ,
BlockCache,
get_block_cache,
};
use alloc::sync::Arc;
use core::marker::PhantomData;
pub struct Dirty<T> {
block_id: usize,
block_cache: [u8; BLOCK_SZ],
block_cache: Arc<BlockCache>,
offset: usize,
dirty: bool,
block_device: Arc<dyn BlockDevice>,
phantom: PhantomData<T>,
}
impl<T> Dirty<T> where T: Sized {
pub fn new(block_id: usize, offset: usize, block_device: Arc<dyn BlockDevice>) -> Self {
Self {
block_id,
block_cache: {
let mut cache = [0u8; BLOCK_SZ];
block_device.read_block(block_id as usize, &mut cache);
cache
},
block_cache: get_block_cache(block_id, block_device.clone()),
offset,
dirty: false,
block_device,
phantom: PhantomData,
}
}
pub fn get_mut(&mut self) -> &mut T {
self.dirty = true;
let type_size = core::mem::size_of::<T>();
// assert that the struct is inside a block
assert!(self.offset + type_size <= BLOCK_SZ);
let start_addr = &self.block_cache[self.offset] as *const _ as usize;
let start_addr = self.block_cache.start_addr(self.offset);
unsafe { &mut *(start_addr as *mut T) }
}
pub fn get_ref(&self) -> &T {
let type_size = core::mem::size_of::<T>();
// assert that the struct is inside a block
assert!(self.offset + type_size <= BLOCK_SZ);
let start_addr = &self.block_cache[self.offset] as *const _ as usize;
let start_addr = self.block_cache.start_addr(self.offset);
unsafe { &*(start_addr as *const T) }
}
pub fn read<V>(&self, f: impl FnOnce(&T) -> V) -> V {
@ -48,16 +41,4 @@ impl<T> Dirty<T> where T: Sized {
pub fn modify(&mut self, f: impl FnOnce(&mut T)) {
f(self.get_mut());
}
pub fn write_back(&mut self) {
if self.dirty {
self.block_device
.write_block(self.block_id as usize, &self.block_cache);
}
}
}
impl<T> Drop for Dirty<T> {
fn drop(&mut self) {
self.write_back();
}
}