11use super :: { BlockDevice , BLOCK_SZ } ;
22use alloc:: collections:: VecDeque ;
33use alloc:: sync:: Arc ;
4+ use alloc:: vec;
5+ use alloc:: vec:: Vec ;
6+ use core:: ptr:: { addr_of, addr_of_mut} ;
7+ use core:: slice;
48use lazy_static:: * ;
59use spin:: Mutex ;
10+
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+
634/// Cached block inside memory
735pub struct BlockCache {
836 /// cached block data
9- cache : [ u8 ; BLOCK_SZ ] ,
37+ cache : CacheData ,
1038 /// underlying block id
1139 block_id : usize ,
1240 /// underlying block device
@@ -18,8 +46,9 @@ pub struct BlockCache {
1846impl BlockCache {
1947 /// Load a new BlockCache from disk.
2048 pub fn new ( block_id : usize , block_device : Arc < dyn BlockDevice > ) -> Self {
21- let mut cache = [ 0u8 ; BLOCK_SZ ] ;
22- block_device. read_block ( block_id, & mut cache) ;
49+ // for alignment and move effciency
50+ let mut cache = CacheData :: new ( ) ;
51+ block_device. read_block ( block_id, cache. as_mut ( ) ) ;
2352 Self {
2453 cache,
2554 block_id,
@@ -28,8 +57,12 @@ impl BlockCache {
2857 }
2958 }
3059 /// Get the address of an offset inside the cached block data
31- fn addr_of_offset ( & self , offset : usize ) -> usize {
32- & self . cache [ offset] as * const _ as usize
60+ fn addr_of_offset ( & self , offset : usize ) -> * const u8 {
61+ addr_of ! ( self . cache. as_ref( ) [ offset] )
62+ }
63+
64+ fn addr_of_offset_mut ( & mut self , offset : usize ) -> * mut u8 {
65+ addr_of_mut ! ( self . cache. as_mut( ) [ offset] )
3366 }
3467
3568 pub fn get_ref < T > ( & self , offset : usize ) -> & T
@@ -38,8 +71,8 @@ impl BlockCache {
3871 {
3972 let type_size = core:: mem:: size_of :: < T > ( ) ;
4073 assert ! ( offset + type_size <= BLOCK_SZ ) ;
41- let addr = self . addr_of_offset ( offset) ;
42- unsafe { & * ( addr as * const T ) }
74+ let addr = self . addr_of_offset ( offset) as * const T ;
75+ unsafe { & * addr }
4376 }
4477
4578 pub fn get_mut < T > ( & mut self , offset : usize ) -> & mut T
@@ -49,8 +82,8 @@ impl BlockCache {
4982 let type_size = core:: mem:: size_of :: < T > ( ) ;
5083 assert ! ( offset + type_size <= BLOCK_SZ ) ;
5184 self . modified = true ;
52- let addr = self . addr_of_offset ( offset) ;
53- unsafe { & mut * ( addr as * mut T ) }
85+ let addr = self . addr_of_offset_mut ( offset) as * mut T ;
86+ unsafe { & mut * addr }
5487 }
5588
5689 pub fn read < T , V > ( & self , offset : usize , f : impl FnOnce ( & T ) -> V ) -> V {
@@ -64,7 +97,8 @@ impl BlockCache {
6497 pub fn sync ( & mut self ) {
6598 if self . modified {
6699 self . modified = false ;
67- self . block_device . write_block ( self . block_id , & self . cache ) ;
100+ self . block_device
101+ . write_block ( self . block_id , self . cache . as_ref ( ) ) ;
68102 }
69103 }
70104}
0 commit comments