@@ -3,11 +3,39 @@ use alloc::collections::VecDeque;
33use alloc:: sync:: Arc ;
44use alloc:: vec;
55use alloc:: vec:: Vec ;
6+ use core:: ptr:: { addr_of, addr_of_mut} ;
7+ use core:: slice;
68use lazy_static:: * ;
79use spin:: Mutex ;
810
11+ /// use `Vec<u64>` to ensure the alignment of addr is `8`
12+ struct CacheData ( Vec < u64 > ) ;
13+
14+ impl CacheData {
15+ fn new ( ) -> Self {
16+ Self ( vec ! [ 0u64 ; BLOCK_SZ / 8 ] )
17+ }
18+ }
19+
20+ impl AsRef < [ u8 ] > for CacheData {
21+ fn as_ref ( & self ) -> & [ u8 ] {
22+ let ptr = self . 0 . as_ptr ( ) as * const u8 ;
23+ unsafe { slice:: from_raw_parts ( ptr, BLOCK_SZ ) }
24+ }
25+ }
26+
27+ impl AsMut < [ u8 ] > for CacheData {
28+ fn as_mut ( & mut self ) -> & mut [ u8 ] {
29+ let ptr = self . 0 . as_mut_ptr ( ) as * mut u8 ;
30+ unsafe { slice:: from_raw_parts_mut ( ptr, BLOCK_SZ ) }
31+ }
32+ }
33+
34+ /// Cached block inside memory
935pub struct BlockCache {
10- cache : Vec < u8 > ,
36+ /// cached block data
37+ cache : CacheData ,
38+ /// underlying block id
1139 block_id : usize ,
1240 block_device : Arc < dyn BlockDevice > ,
1341 modified : bool ,
@@ -17,18 +45,22 @@ impl BlockCache {
1745 /// Load a new BlockCache from disk.
1846 pub fn new ( block_id : usize , block_device : Arc < dyn BlockDevice > ) -> Self {
1947 // for alignment and move effciency
20- let mut cache = vec ! [ 0u8 ; BLOCK_SZ ] ;
21- block_device. read_block ( block_id, & mut cache) ;
48+ let mut cache = CacheData :: new ( ) ;
49+ block_device. read_block ( block_id, cache. as_mut ( ) ) ;
2250 Self {
2351 cache,
2452 block_id,
2553 block_device,
2654 modified : false ,
2755 }
2856 }
57+ /// Get the address of an offset inside the cached block data
58+ fn addr_of_offset ( & self , offset : usize ) -> * const u8 {
59+ addr_of ! ( self . cache. as_ref( ) [ offset] )
60+ }
2961
30- fn addr_of_offset ( & self , offset : usize ) -> usize {
31- & self . cache [ offset] as * const _ as usize
62+ fn addr_of_offset_mut ( & mut self , offset : usize ) -> * mut u8 {
63+ addr_of_mut ! ( self . cache. as_mut ( ) [ offset] )
3264 }
3365
3466 pub fn get_ref < T > ( & self , offset : usize ) -> & T
@@ -37,8 +69,8 @@ impl BlockCache {
3769 {
3870 let type_size = core:: mem:: size_of :: < T > ( ) ;
3971 assert ! ( offset + type_size <= BLOCK_SZ ) ;
40- let addr = self . addr_of_offset ( offset) ;
41- unsafe { & * ( addr as * const T ) }
72+ let addr = self . addr_of_offset ( offset) as * const T ;
73+ unsafe { & * addr }
4274 }
4375
4476 pub fn get_mut < T > ( & mut self , offset : usize ) -> & mut T
@@ -48,8 +80,8 @@ impl BlockCache {
4880 let type_size = core:: mem:: size_of :: < T > ( ) ;
4981 assert ! ( offset + type_size <= BLOCK_SZ ) ;
5082 self . modified = true ;
51- let addr = self . addr_of_offset ( offset) ;
52- unsafe { & mut * ( addr as * mut T ) }
83+ let addr = self . addr_of_offset_mut ( offset) as * mut T ;
84+ unsafe { & mut * addr }
5385 }
5486
5587 pub fn read < T , V > ( & self , offset : usize , f : impl FnOnce ( & T ) -> V ) -> V {
@@ -63,7 +95,8 @@ impl BlockCache {
6395 pub fn sync ( & mut self ) {
6496 if self . modified {
6597 self . modified = false ;
66- self . block_device . write_block ( self . block_id , & self . cache ) ;
98+ self . block_device
99+ . write_block ( self . block_id , self . cache . as_ref ( ) ) ;
67100 }
68101 }
69102}
0 commit comments