1+ use core:: ptr:: { addr_of, addr_of_mut} ;
2+ use core:: slice;
3+
14use super :: { BlockDevice , BLOCK_SZ } ;
25use alloc:: collections:: VecDeque ;
36use alloc:: sync:: Arc ;
@@ -6,8 +9,31 @@ use alloc::vec::Vec;
69use lazy_static:: * ;
710use spin:: Mutex ;
811
12+ /// use `Vec<u64>` to ensure the alignment of addr is `8`
13+ struct CacheData ( Vec < u64 > ) ;
14+
15+ impl CacheData {
16+ fn new ( ) -> Self {
17+ Self ( vec ! [ 0u64 ; BLOCK_SZ / 8 ] )
18+ }
19+ }
20+
21+ impl AsRef < [ u8 ] > for CacheData {
22+ fn as_ref ( & self ) -> & [ u8 ] {
23+ let ptr = self . 0 . as_ptr ( ) as * const u8 ;
24+ unsafe { slice:: from_raw_parts ( ptr, BLOCK_SZ ) }
25+ }
26+ }
27+
28+ impl AsMut < [ u8 ] > for CacheData {
29+ fn as_mut ( & mut self ) -> & mut [ u8 ] {
30+ let ptr = self . 0 . as_mut_ptr ( ) as * mut u8 ;
31+ unsafe { slice:: from_raw_parts_mut ( ptr, BLOCK_SZ ) }
32+ }
33+ }
34+
935pub struct BlockCache {
10- cache : Vec < u8 > ,
36+ cache : CacheData ,
1137 block_id : usize ,
1238 block_device : Arc < dyn BlockDevice > ,
1339 modified : bool ,
@@ -17,8 +43,8 @@ impl BlockCache {
1743 /// Load a new BlockCache from disk.
1844 pub fn new ( block_id : usize , block_device : Arc < dyn BlockDevice > ) -> Self {
1945 // for alignment and move effciency
20- let mut cache = vec ! [ 0u8 ; BLOCK_SZ ] ;
21- block_device. read_block ( block_id, & mut cache) ;
46+ let mut cache = CacheData :: new ( ) ;
47+ block_device. read_block ( block_id, cache. as_mut ( ) ) ;
2248 Self {
2349 cache,
2450 block_id,
@@ -27,8 +53,12 @@ impl BlockCache {
2753 }
2854 }
2955
30- fn addr_of_offset ( & self , offset : usize ) -> usize {
31- & self . cache [ offset] as * const _ as usize
56+ fn addr_of_offset ( & self , offset : usize ) -> * const u8 {
57+ addr_of ! ( self . cache. as_ref( ) [ offset] )
58+ }
59+
60+ fn addr_of_offset_mut ( & mut self , offset : usize ) -> * mut u8 {
61+ addr_of_mut ! ( self . cache. as_mut( ) [ offset] )
3262 }
3363
3464 pub fn get_ref < T > ( & self , offset : usize ) -> & T
@@ -37,8 +67,8 @@ impl BlockCache {
3767 {
3868 let type_size = core:: mem:: size_of :: < T > ( ) ;
3969 assert ! ( offset + type_size <= BLOCK_SZ ) ;
40- let addr = self . addr_of_offset ( offset) ;
41- unsafe { & * ( addr as * const T ) }
70+ let addr = self . addr_of_offset ( offset) as * const T ;
71+ unsafe { & * addr }
4272 }
4373
4474 pub fn get_mut < T > ( & mut self , offset : usize ) -> & mut T
@@ -48,8 +78,8 @@ impl BlockCache {
4878 let type_size = core:: mem:: size_of :: < T > ( ) ;
4979 assert ! ( offset + type_size <= BLOCK_SZ ) ;
5080 self . modified = true ;
51- let addr = self . addr_of_offset ( offset) ;
52- unsafe { & mut * ( addr as * mut T ) }
81+ let addr = self . addr_of_offset_mut ( offset) as * mut T ;
82+ unsafe { & mut * addr }
5383 }
5484
5585 pub fn read < T , V > ( & self , offset : usize , f : impl FnOnce ( & T ) -> V ) -> V {
@@ -63,7 +93,8 @@ impl BlockCache {
6393 pub fn sync ( & mut self ) {
6494 if self . modified {
6595 self . modified = false ;
66- self . block_device . write_block ( self . block_id , & self . cache ) ;
96+ self . block_device
97+ . write_block ( self . block_id , self . cache . as_ref ( ) ) ;
6798 }
6899 }
69100}
0 commit comments