Skip to content

Commit b02a7a1

Browse files
committed
fix alignment
1 parent 54ef6f3 commit b02a7a1

File tree

1 file changed

+41
-10
lines changed

1 file changed

+41
-10
lines changed

easy-fs/src/block_cache.rs

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
use core::ptr::{addr_of, addr_of_mut};
2+
use core::slice;
3+
14
use super::{BlockDevice, BLOCK_SZ};
25
use alloc::collections::VecDeque;
36
use alloc::sync::Arc;
@@ -6,8 +9,31 @@ use alloc::vec::Vec;
69
use lazy_static::*;
710
use 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+
935
pub 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

Comments
 (0)