Skip to content

Commit 6724423

Browse files
Luv-Raywyfcyx
authored andcommitted
fix alignment
-------- Cherry-picked from #158.
1 parent 4e73a82 commit 6724423

File tree

1 file changed

+43
-10
lines changed

1 file changed

+43
-10
lines changed

easy-fs/src/block_cache.rs

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,39 @@ use alloc::collections::VecDeque;
33
use alloc::sync::Arc;
44
use alloc::vec;
55
use alloc::vec::Vec;
6+
use core::ptr::{addr_of, addr_of_mut};
7+
use core::slice;
68
use lazy_static::*;
79
use 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
935
pub 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

Comments
 (0)