Skip to content

Commit e55c520

Browse files
committed
Merge dev: ch7 updates
2 parents 4668911 + 67372ac commit e55c520

File tree

22 files changed

+477
-62
lines changed

22 files changed

+477
-62
lines changed

easy-fs-fuse/src/main.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,8 @@ fn efs_test() -> std::io::Result<()> {
118118
let filea = root_inode.find("filea").unwrap();
119119
let greet_str = "Hello, world!";
120120
filea.write_at(0, greet_str.as_bytes());
121-
let mut buffer = [0u8; 512];
121+
//let mut buffer = [0u8; 512];
122+
let mut buffer = [0u8; 233];
122123
let len = filea.read_at(0, &mut buffer);
123124
assert_eq!(
124125
greet_str,
@@ -159,6 +160,9 @@ fn efs_test() -> std::io::Result<()> {
159160
random_str_test(100 * BLOCK_SZ);
160161
random_str_test(70 * BLOCK_SZ + BLOCK_SZ / 7);
161162
random_str_test((12 + 128) * BLOCK_SZ);
163+
random_str_test(400 * BLOCK_SZ);
164+
random_str_test(1000 * BLOCK_SZ);
165+
random_str_test(2000 * BLOCK_SZ);
162166

163167
Ok(())
164168
}

easy-fs/src/efs.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,7 @@ impl EasyFileSystem {
8080
)
8181
.lock()
8282
.modify(root_inode_offset, |disk_inode: &mut DiskInode| {
83-
disk_inode.initialize(
84-
DiskInodeType::Directory,efs.alloc_data()
85-
);
83+
disk_inode.initialize(DiskInodeType::Directory);
8684
});
8785
Arc::new(Mutex::new(efs))
8886
}
@@ -158,6 +156,14 @@ impl EasyFileSystem {
158156
}
159157

160158
pub fn dealloc_data(&mut self, block_id: u32) {
159+
get_block_cache(
160+
block_id as usize,
161+
Arc::clone(&self.block_device)
162+
)
163+
.lock()
164+
.modify(0, |data_block: &mut DataBlock| {
165+
data_block.iter_mut().for_each(|p| { *p = 0; })
166+
});
161167
self.data_bitmap.dealloc(
162168
&self.block_device,
163169
(block_id - self.data_area_start_block) as usize

easy-fs/src/layout.rs

Lines changed: 212 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,14 @@ use alloc::sync::Arc;
88
use alloc::vec::Vec;
99

1010
const EFS_MAGIC: u32 = 0x3b800001;
11-
const INODE_DIRECT_COUNT: usize = 60;
11+
const INODE_DIRECT_COUNT: usize = 28;
1212
const NAME_LENGTH_LIMIT: usize = 27;
13+
const INODE_INDIRECT1_COUNT: usize = BLOCK_SZ / 4;
14+
const INODE_INDIRECT2_COUNT: usize = INODE_INDIRECT1_COUNT * INODE_INDIRECT1_COUNT;
15+
const DIRECT_BOUND: usize = INODE_DIRECT_COUNT;
16+
const INDIRECT1_BOUND: usize = DIRECT_BOUND + INODE_INDIRECT1_COUNT;
17+
#[allow(unused)]
18+
const INDIRECT2_BOUND: usize = INDIRECT1_BOUND + INODE_INDIRECT2_COUNT;
1319

1420
#[repr(C)]
1521
pub struct SuperBlock {
@@ -76,11 +82,11 @@ pub struct DiskInode {
7682
}
7783

7884
impl DiskInode {
79-
/// indirect1 block is allocated when the file is created.
80-
pub fn initialize(&mut self, type_: DiskInodeType, indirect1: u32) {
85+
/// indirect1 and indirect2 block are allocated only when they are needed.
86+
pub fn initialize(&mut self, type_: DiskInodeType) {
8187
self.size = 0;
8288
self.direct.iter_mut().for_each(|v| *v = 0);
83-
self.indirect1 = indirect1;
89+
self.indirect1 = 0;
8490
self.indirect2 = 0;
8591
self.type_ = type_;
8692
}
@@ -91,57 +97,146 @@ impl DiskInode {
9197
pub fn is_file(&self) -> bool {
9298
self.type_ == DiskInodeType::File
9399
}
94-
pub fn blocks(&self) -> u32 {
95-
Self::_blocks(self.size)
100+
/// Return block number correspond to size.
101+
pub fn data_blocks(&self) -> u32 {
102+
Self::_data_blocks(self.size)
96103
}
97-
fn _blocks(size: u32) -> u32 {
104+
fn _data_blocks(size: u32) -> u32 {
98105
(size + BLOCK_SZ as u32 - 1) / BLOCK_SZ as u32
99106
}
107+
/// Return number of blocks needed include indirect1/2.
108+
pub fn total_blocks(size: u32) -> u32 {
109+
let data_blocks = Self::_data_blocks(size) as usize;
110+
let mut total = data_blocks as usize;
111+
// indirect1
112+
if data_blocks > INODE_DIRECT_COUNT {
113+
total += 1;
114+
}
115+
// indirect2
116+
if data_blocks > INDIRECT1_BOUND {
117+
total += 1;
118+
// sub indirect1
119+
total += (data_blocks - INDIRECT1_BOUND + INODE_INDIRECT1_COUNT - 1) / INODE_INDIRECT1_COUNT;
120+
}
121+
total as u32
122+
}
123+
pub fn blocks_num_needed(&self, new_size: u32) -> u32 {
124+
assert!(new_size >= self.size);
125+
Self::total_blocks(new_size) - Self::total_blocks(self.size)
126+
}
100127
pub fn get_block_id(&self, inner_id: u32, block_device: &Arc<dyn BlockDevice>) -> u32 {
101128
let inner_id = inner_id as usize;
102129
if inner_id < INODE_DIRECT_COUNT {
103130
self.direct[inner_id]
104-
} else {
105-
// only support indirect1 now
131+
} else if inner_id < INDIRECT1_BOUND {
106132
get_block_cache(self.indirect1 as usize, Arc::clone(block_device))
107133
.lock()
108134
.read(0, |indirect_block: &IndirectBlock| {
109135
indirect_block[inner_id - INODE_DIRECT_COUNT]
110136
})
137+
} else {
138+
let last = inner_id - INDIRECT1_BOUND;
139+
let indirect1 = get_block_cache(
140+
self.indirect2 as usize,
141+
Arc::clone(block_device)
142+
)
143+
.lock()
144+
.read(0, |indirect2: &IndirectBlock| {
145+
indirect2[last / INODE_INDIRECT1_COUNT]
146+
});
147+
get_block_cache(
148+
indirect1 as usize,
149+
Arc::clone(block_device)
150+
)
151+
.lock()
152+
.read(0, |indirect1: &IndirectBlock| {
153+
indirect1[last % INODE_INDIRECT1_COUNT]
154+
})
111155
}
112156
}
113-
pub fn blocks_num_needed(&self, new_size: u32) -> u32 {
114-
assert!(new_size >= self.size);
115-
Self::_blocks(new_size) - self.blocks()
116-
}
117157
pub fn increase_size(
118158
&mut self,
119159
new_size: u32,
120160
new_blocks: Vec<u32>,
121161
block_device: &Arc<dyn BlockDevice>,
122162
) {
123-
assert_eq!(new_blocks.len() as u32, self.blocks_num_needed(new_size));
124-
let last_blocks = self.blocks();
163+
let mut current_blocks = self.data_blocks();
125164
self.size = new_size;
126-
let current_blocks = self.blocks();
165+
let mut total_blocks = self.data_blocks();
166+
let mut new_blocks = new_blocks.into_iter();
167+
// fill direct
168+
while current_blocks < total_blocks.min(INODE_DIRECT_COUNT as u32) {
169+
self.direct[current_blocks as usize] = new_blocks.next().unwrap();
170+
current_blocks += 1;
171+
}
172+
// alloc indirect1
173+
if total_blocks > INODE_DIRECT_COUNT as u32{
174+
if current_blocks == INODE_DIRECT_COUNT as u32 {
175+
self.indirect1 = new_blocks.next().unwrap();
176+
}
177+
current_blocks -= INODE_DIRECT_COUNT as u32;
178+
total_blocks -= INODE_DIRECT_COUNT as u32;
179+
} else {
180+
return;
181+
}
182+
// fill indirect1
127183
get_block_cache(
128184
self.indirect1 as usize,
129185
Arc::clone(block_device)
130186
)
131187
.lock()
132-
.modify(0, |indirect_block: &mut IndirectBlock| {
133-
for i in 0..current_blocks - last_blocks {
134-
let inner_id = (last_blocks + i) as usize;
135-
let new_block = new_blocks[i as usize];
136-
if inner_id < INODE_DIRECT_COUNT {
137-
self.direct[inner_id] = new_block;
138-
} else {
139-
indirect_block[inner_id - INODE_DIRECT_COUNT] = new_block;
140-
}
188+
.modify(0, |indirect1: &mut IndirectBlock| {
189+
while current_blocks < total_blocks.min(INODE_INDIRECT1_COUNT as u32) {
190+
indirect1[current_blocks as usize] = new_blocks.next().unwrap();
191+
current_blocks += 1;
141192
}
142193
});
194+
// alloc indirect2
195+
if total_blocks > INODE_INDIRECT1_COUNT as u32 {
196+
if current_blocks == INODE_INDIRECT1_COUNT as u32 {
197+
self.indirect2 = new_blocks.next().unwrap();
198+
}
199+
current_blocks -= INODE_INDIRECT1_COUNT as u32;
200+
total_blocks -= INODE_INDIRECT1_COUNT as u32;
201+
} else {
202+
return;
203+
}
204+
// fill indirect2 from (a0, b0) -> (a1, b1)
205+
let mut a0 = current_blocks as usize / INODE_INDIRECT1_COUNT;
206+
let mut b0 = current_blocks as usize % INODE_INDIRECT1_COUNT;
207+
let a1 = total_blocks as usize / INODE_INDIRECT1_COUNT;
208+
let b1 = total_blocks as usize % INODE_INDIRECT1_COUNT;
209+
// alloc low-level indirect1
210+
get_block_cache(
211+
self.indirect2 as usize,
212+
Arc::clone(block_device)
213+
)
214+
.lock()
215+
.modify(0, |indirect2: &mut IndirectBlock| {
216+
while (a0 < a1) || (a0 == a1 && b0 < b1) {
217+
if b0 == 0 {
218+
indirect2[a0] = new_blocks.next().unwrap();
219+
}
220+
// fill current
221+
get_block_cache(
222+
indirect2[a0] as usize,
223+
Arc::clone(block_device)
224+
)
225+
.lock()
226+
.modify(0, |indirect1: &mut IndirectBlock| {
227+
indirect1[b0] = new_blocks.next().unwrap();
228+
});
229+
// move to next
230+
b0 += 1;
231+
if b0 == INODE_INDIRECT1_COUNT {
232+
b0 = 0;
233+
a0 += 1;
234+
}
235+
}
236+
});
143237
}
144-
/// Clear size to zero and return blocks that should be deallocated.
238+
239+
/*
145240
pub fn clear_size(&mut self, block_device: &Arc<dyn BlockDevice>) -> Vec<u32> {
146241
let mut v: Vec<u32> = Vec::new();
147242
let blocks = self.blocks() as usize;
@@ -165,6 +260,97 @@ impl DiskInode {
165260
}
166261
v
167262
}
263+
*/
264+
265+
/// Clear size to zero and return blocks that should be deallocated.
266+
///
267+
/// We will clear the block contents to zero later.
268+
pub fn clear_size(&mut self, block_device: &Arc<dyn BlockDevice>) -> Vec<u32> {
269+
let mut v: Vec<u32> = Vec::new();
270+
let mut data_blocks = self.data_blocks() as usize;
271+
self.size = 0;
272+
let mut current_blocks = 0usize;
273+
// direct
274+
while current_blocks < data_blocks.min(INODE_DIRECT_COUNT) {
275+
v.push(self.direct[current_blocks]);
276+
self.direct[current_blocks] = 0;
277+
current_blocks += 1;
278+
}
279+
// indirect1 block
280+
if data_blocks > INODE_DIRECT_COUNT {
281+
v.push(self.indirect1);
282+
data_blocks -= INODE_DIRECT_COUNT;
283+
current_blocks = 0;
284+
} else {
285+
return v;
286+
}
287+
// indirect1
288+
get_block_cache(
289+
self.indirect1 as usize,
290+
Arc::clone(block_device),
291+
)
292+
.lock()
293+
.modify(0, |indirect1: &mut IndirectBlock| {
294+
while current_blocks < data_blocks.min(INODE_INDIRECT1_COUNT) {
295+
v.push(indirect1[current_blocks]);
296+
//indirect1[current_blocks] = 0;
297+
current_blocks += 1;
298+
}
299+
});
300+
self.indirect1 = 0;
301+
// indirect2 block
302+
if data_blocks > INODE_INDIRECT1_COUNT {
303+
v.push(self.indirect2);
304+
data_blocks -= INODE_INDIRECT1_COUNT;
305+
} else {
306+
return v;
307+
}
308+
// indirect2
309+
assert!(data_blocks <= INODE_INDIRECT2_COUNT);
310+
let a1 = data_blocks / INODE_INDIRECT1_COUNT;
311+
let b1 = data_blocks % INODE_INDIRECT1_COUNT;
312+
get_block_cache(
313+
self.indirect2 as usize,
314+
Arc::clone(block_device),
315+
)
316+
.lock()
317+
.modify(0, |indirect2: &mut IndirectBlock| {
318+
// full indirect1 blocks
319+
for i in 0..a1 {
320+
v.push(indirect2[i]);
321+
get_block_cache(
322+
indirect2[i] as usize,
323+
Arc::clone(block_device),
324+
)
325+
.lock()
326+
.modify(0, |indirect1: &mut IndirectBlock| {
327+
for j in 0..INODE_INDIRECT1_COUNT {
328+
v.push(indirect1[j]);
329+
//indirect1[j] = 0;
330+
}
331+
});
332+
//indirect2[i] = 0;
333+
}
334+
// last indirect1 block
335+
if b1 > 0 {
336+
v.push(indirect2[a1]);
337+
get_block_cache(
338+
indirect2[a1] as usize,
339+
Arc::clone(block_device),
340+
)
341+
.lock()
342+
.modify(0, |indirect1: &mut IndirectBlock| {
343+
for j in 0..b1 {
344+
v.push(indirect1[j]);
345+
//indirect1[j] = 0;
346+
}
347+
});
348+
//indirect2[a1] = 0;
349+
}
350+
});
351+
self.indirect2 = 0;
352+
v
353+
}
168354
pub fn read_at(
169355
&self,
170356
offset: usize,

easy-fs/src/vfs.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -122,22 +122,18 @@ impl Inode {
122122
}).is_some() {
123123
return None;
124124
}
125-
//println!("same file does not exist in Inode::create.");
126125
// create a new file
127126
// alloc a inode with an indirect block
128127
let new_inode_id = fs.alloc_inode();
129-
let indirect1 = fs.alloc_data();
130128
// initialize inode
131129
let (new_inode_block_id, new_inode_block_offset)
132130
= fs.get_disk_inode_pos(new_inode_id);
133-
//println!("new_inode_id={} ({},{})", new_inode_id, new_inode_block_id, new_inode_block_offset);
134131
get_block_cache(
135132
new_inode_block_id as usize,
136133
Arc::clone(&self.block_device)
137134
).lock().modify(new_inode_block_offset, |new_inode: &mut DiskInode| {
138-
new_inode.initialize(DiskInodeType::File, indirect1);
135+
new_inode.initialize(DiskInodeType::File);
139136
});
140-
//println!("new inode has been initialized.");
141137
self.modify_disk_inode(|root_inode| {
142138
// append file in the dirent
143139
let file_count = (root_inode.size as usize) / DIRENT_SZ;
@@ -152,7 +148,6 @@ impl Inode {
152148
&self.block_device,
153149
);
154150
});
155-
//println!("new file has been inserted into root inode.");
156151
// release efs lock manually because we will acquire it again in Inode::new
157152
drop(fs);
158153
// return inode
@@ -202,7 +197,9 @@ impl Inode {
202197
pub fn clear(&self) {
203198
let mut fs = self.fs.lock();
204199
self.modify_disk_inode(|disk_inode| {
200+
let size = disk_inode.size;
205201
let data_blocks_dealloc = disk_inode.clear_size(&self.block_device);
202+
assert!(data_blocks_dealloc.len() == DiskInode::total_blocks(size) as usize);
206203
for data_block in data_blocks_dealloc.into_iter() {
207204
fs.dealloc_data(data_block);
208205
}

os/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ KERNEL_BIN := $(KERNEL_ELF).bin
66
DISASM_TMP := target/$(TARGET)/$(MODE)/asm
77
FS_IMG := ../user/target/$(TARGET)/$(MODE)/fs.img
88
SDCARD := /dev/sdb
9-
APPS := ../user/src/bin
9+
APPS := ../user/src/bin/*
1010

1111
# BOARD
1212
BOARD ?= qemu

0 commit comments

Comments
 (0)