Skip to content

Commit 6ba1ba5

Browse files
Luv-Raywyfcyx
authored andcommitted
fix alignment
-------- Cherry picked from #158.
1 parent 5b846fc commit 6ba1ba5

File tree

1 file changed

+44
-10
lines changed

1 file changed

+44
-10
lines changed

easy-fs/src/block_cache.rs

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,40 @@
11
use super::{BlockDevice, BLOCK_SZ};
22
use alloc::collections::VecDeque;
33
use 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;
48
use lazy_static::*;
59
use 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
735
pub 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 {
1846
impl 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

Comments
 (0)