1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
use core::marker::PhantomData;
use super::{BlockDevice, Fat};
use crate::{
block_cache::{Cache, CacheManager},
layout::{DiskInodeType, BPB},
Inode, BLOCK_SZ,
};
use alloc::sync::Arc;
pub struct EasyFileSystem<T: CacheManager, F: CacheManager> {
used_marker: PhantomData<T>,
pub block_device: Arc<dyn BlockDevice>,
pub fat: Fat<F>,
pub data_area_start_block: u32,
pub root_clus: u32,
pub sec_per_clus: u8,
pub byts_per_sec: u16,
ino_cnt: spin::Mutex<u64>,
}
#[allow(unused)]
type DataBlock = [u8; crate::BLOCK_SZ];
impl<T: CacheManager, F: CacheManager> EasyFileSystem<T, F> {
#[inline(always)]
pub fn this_fat_ent_offset(&self, n: u32) -> u32 {
self.fat.this_fat_ent_offset(n) as u32
}
#[inline(always)]
pub fn this_fat_sec_num(&self, n: u32) -> u32 {
self.fat.this_fat_sec_num(n) as u32
}
#[inline(always)]
pub fn get_next_clus_num(&self, result: u32) -> u32 {
self.fat.get_next_clus_num(result, &self.block_device)
}
}
impl<T: CacheManager, F: CacheManager> EasyFileSystem<T, F> {
pub fn first_data_sector(&self) -> u32 {
self.data_area_start_block
}
#[inline(always)]
pub fn clus_size(&self) -> u32 {
self.byts_per_sec as u32 * self.sec_per_clus as u32
}
}
impl<T: CacheManager, F: CacheManager> EasyFileSystem<T, F> {
pub fn alloc_new_inode(&self) -> u64 {
let mut ino = self.ino_cnt.lock();
*ino += 1;
*ino - 1
}
#[inline(always)]
pub fn first_sector_of_cluster(&self, n: u32) -> u32 {
assert_eq!(self.sec_per_clus.count_ones(), 1);
assert!(n >= 2);
let start_block = self.data_area_start_block;
let offset_blocks = (n - 2) * self.sec_per_clus as u32;
start_block + offset_blocks
}
#[inline(always)]
pub fn in_cluster(&self, block_id: u32) -> u32 {
((block_id - self.first_data_sector()) >> self.sec_per_clus.trailing_zeros()) + 2
}
pub fn open(
block_device: Arc<dyn BlockDevice>,
bpb_fat_cache_mgr: Arc<spin::Mutex<F>>,
) -> Arc<Self> {
assert!(F::CACHE_SZ % BLOCK_SZ == 0);
assert!(T::CACHE_SZ % BLOCK_SZ == 0);
let fat_cache_mgr = bpb_fat_cache_mgr.clone();
bpb_fat_cache_mgr
.lock()
.get_block_cache(
0,
0,
|| -> alloc::vec::Vec<usize> { alloc::vec::Vec::new() },
Arc::clone(&block_device),
)
.lock()
.read(0, |super_block: &BPB| {
assert!(super_block.is_valid(), "Error loading EFS!");
let efs = Self {
used_marker: Default::default(),
block_device,
ino_cnt: spin::Mutex::new(
32 + (super_block.data_sector_count() / super_block.sec_per_clus as u32)
as u64,
),
fat: Fat::new(
super_block.rsvd_sec_cnt as usize,
super_block.byts_per_sec as usize,
(super_block.data_sector_count() / super_block.sec_per_clus as u32)
as usize,
fat_cache_mgr,
),
root_clus: super_block.root_clus,
sec_per_clus: super_block.sec_per_clus,
byts_per_sec: super_block.byts_per_sec,
data_area_start_block: super_block.first_data_sector(),
};
Arc::new(efs)
})
}
pub fn root_inode(efs: &Arc<Self>) -> Arc<Inode<T, F>> {
let rt_clus = efs.root_clus;
Inode::new(
rt_clus,
DiskInodeType::Directory,
None,
None,
Arc::clone(efs),
)
}
pub fn get_disk_fat_pos(&self, n: u32) -> (u32, usize) {
(
self.fat.this_fat_sec_num(n) as u32,
self.fat.this_fat_ent_offset(n) as usize,
)
}
}