Skip to content

Commit b64a7c1

Browse files
committed
refactor: write file, write dir
1 parent 1a7970d commit b64a7c1

File tree

5 files changed

+324
-231
lines changed

5 files changed

+324
-231
lines changed

src/bitmap.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,23 @@ pub struct Bitmap {
22
data: Vec<u8>,
33
}
44

5-
impl Bitmap{
6-
pub fn new(size: usize)->Self{
7-
Bitmap{
8-
data: vec![0;size/8 + 1],
5+
impl Bitmap {
6+
pub fn new(size: usize) -> Self {
7+
Bitmap {
8+
data: vec![0; size / 8 + 1],
99
}
1010
}
1111
pub fn get(&self, index: usize) -> bool {
12-
self.data[index/8] & (1 << (7 - (index % 8))) != 0
12+
self.data[index / 8] & (1 << (7 - (index % 8))) != 0
1313
}
1414
pub fn set(&mut self, index: usize, value: bool) {
1515
if value {
16-
self.data[index/8] |= 1 << (7 - (index % 8));
16+
self.data[index / 8] |= 1 << (7 - (index % 8));
1717
} else {
18-
self.data[index/8] &= !(1 << (7 - (index % 8)));
18+
self.data[index / 8] &= !(1 << (7 - (index % 8)));
1919
}
2020
}
21-
pub fn free_index(&self) -> Option<usize>{
21+
pub fn free_index(&self) -> Option<usize> {
2222
for i in 0..(self.data.len()) {
2323
if self.data[i] != 0xff {
2424
for j in 0..8 {
@@ -30,4 +30,4 @@ impl Bitmap{
3030
}
3131
return None;
3232
}
33-
}
33+
}

src/block.rs

Lines changed: 159 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
1-
use core::num;
2-
use std::{time::{SystemTime, UNIX_EPOCH}, vec, io::{Bytes, SeekFrom}, mem, cmp::min, sync::Arc};
1+
use crate::{bitmap::*, block, file::*};
32
use bincode;
3+
use log::debug;
44
use serde::de::value::SeqDeserializer;
5-
use crate::{file::*, block, bitmap::*};
6-
7-
pub const BLOCK_SIZE : usize = 1024; //每个数据块的大小为1kB
8-
//一个块的大小控制了,inode和bitmap的位图的大就是一个块的大小
9-
//那么块的数据也就确定了,1024*8
10-
pub const BLOCK_COUNT : usize = BLOCK_SIZE * 8;
5+
use std::{
6+
alloc::System,
7+
clone,
8+
cmp::{max, min},
9+
io::{Bytes, SeekFrom},
10+
mem,
11+
sync::Arc,
12+
time::{SystemTime, UNIX_EPOCH},
13+
vec,
14+
};
1115

16+
pub const BLOCK_SIZE: usize = 1024; //每个数据块的大小为1kB
17+
//一个块的大小控制了,inode和bitmap的位图的大就是一个块的大小
18+
//那么块的数据也就确定了,1024*8
19+
pub const BLOCK_COUNT: usize = BLOCK_SIZE * 8;
1220

1321
//part 1
1422
pub struct BootBlock {}
@@ -43,11 +51,14 @@ pub struct GroupDescriperTable {
4351

4452
pub struct Inode {
4553
i_mode: u16, //16位置用于表示文件的类型和权限
54+
i_uid: u16, //用户id
4655
i_size: u32,
4756
i_atime: u32, //存储的是秒数
4857
i_ctime: u32,
4958
i_mtime: u32,
5059
i_dtime: u32,
60+
i_gid: u16, //组id
61+
i_links_count: u16,
5162
i_block: [Option<u32>; 15], //指向的是数据块
5263
//file_type: FileType,可有可无
5364
pub direct_pointer: [Option<u32>; 12], //直接索引,前12个块 Some是指向数字的指针,要么就是None
@@ -61,51 +72,97 @@ struct DataBlock {
6172
}
6273

6374
impl BlockGroup {
75+
pub fn new_root() -> Self {
76+
let mut bg = BlockGroup::new();
77+
78+
bg.inode_bitmap.set(1, true);
79+
let inode = bg.inode_table.get_mut(0).unwrap();
80+
// 777 dir
81+
inode.i_mode = 0x41ff;
82+
bg.add_entry_to_directory(".".to_string(), 1);
83+
bg.add_entry_to_directory("..".to_string(), 1);
84+
bg
85+
}
86+
6487
pub fn new() -> Self {
6588
BlockGroup {
6689
superblock: SuperBlock::new(),
6790
group_descriper_table: GroupDescriperTable::new(),
6891
inode_bitmap: Bitmap::new(BLOCK_SIZE),
6992
block_bitmap: Bitmap::new(BLOCK_SIZE),
70-
inode_table: vec![],
71-
data_block: vec![],
93+
inode_table: vec![Inode::new(); BLOCK_SIZE*8],
94+
data_block: vec![DataBlock::new(); BLOCK_SIZE*8],
7295
}
7396
}
97+
7498
pub fn full(&self) -> bool {
7599
self.block_bitmap.free_index() == None
76100
}
77101

78-
pub fn read_file(&self,inode_index : usize) -> Vec<u8> {
79-
let mut data:Vec<u8> = vec![];
102+
pub fn read_file(&self, inode_index: usize) -> Vec<u8> {
103+
let mut data: Vec<u8> = vec![];
80104
for block_index in self.inode_table[inode_index].direct_pointer {
81105
match block_index {
82106
Some(index) => {
83107
data.extend_from_slice(self.data_block[index as usize].read());
84-
},
85-
None => ()
86-
}
108+
}
109+
None => (),
87110
}
111+
}
88112
data
89-
}
113+
}
114+
115+
pub fn write_file_offset(&mut self, inode_idx: usize, offset: usize, data: &[u8]) {
116+
let inode = self.inode_table.get_mut(inode_idx - 1).unwrap();
117+
inode.inode_update_size(max(inode.i_size, (offset + data.len()) as u32));
90118

91-
pub fn write_file(&mut self,parent_inode : usize,data :&[u8]) {
92-
let inode_index = self.inode_table[parent_inode].get_index();
93-
let block_index = self.get_block_for_file();
94-
self.data_block[block_index].write(data, 0);
95-
119+
let (mut write_entry_block_idx, mut inner_offset) = convert_offset(offset);
120+
let mut write_pos = 0;
121+
loop {
122+
let block = self.get_block_by_inode_rel_block(inode_idx, write_entry_block_idx);
123+
let write_count = min(BLOCK_SIZE - inner_offset, data.len() - write_pos);
124+
125+
block.write(&data[write_pos..write_pos + write_count], inner_offset);
126+
write_pos += write_count;
127+
write_entry_block_idx += 1;
128+
inner_offset = 0;
129+
if write_pos >= data.len() {
130+
break;
131+
}
132+
}
133+
}
134+
135+
fn get_block_by_inode_rel_block(&mut self, inode: usize, block_idx: usize) -> &mut DataBlock {
136+
// todo: 多级混合索引
137+
match block_idx {
138+
0..=11 => {
139+
match self.inode_table[inode - 1].direct_pointer[block_idx] {
140+
Some(index) => self.data_block.get_mut(index as usize).unwrap(),
141+
None => {
142+
// 自动扩容
143+
let datablock = self.get_block_for_file();
144+
self.inode_table[inode - 1].direct_pointer[block_idx] =
145+
Some(datablock as u32);
146+
&mut self.data_block[datablock]
147+
}
148+
}
149+
}
150+
_ => panic!("not implemented"),
151+
}
96152
}
97153

98-
pub fn bg_list(&self,parent_inode : usize) {
99-
let mut all_dirs:Vec<DirectoryEntry> = vec![];
100-
for index in self.inode_table[parent_inode as usize].direct_pointer{
154+
pub fn bg_list(&self, parent_inode: usize) {
155+
let mut all_dirs: Vec<DirectoryEntry> = vec![];
156+
for index in self.inode_table[parent_inode as usize].direct_pointer {
101157
if let Some(i_block) = index {
102158
all_dirs.append(&mut self.data_block[i_block as usize].get_all_dirs_name());
103159
}
104160
}
105161
for it in &all_dirs {
106-
print!("{}",it.name);
162+
print!("{}", it.name);
107163
}
108164
}
165+
109166
pub fn bg_rmdir(&mut self, parent_inode: usize, name: String) {
110167
for block_index in self.inode_table[parent_inode].direct_pointer {
111168
if let Some(index) = block_index {
@@ -120,68 +177,59 @@ impl BlockGroup {
120177
self.add_entry_to_directory("..".to_string(), child_inode);
121178
}
122179

180+
pub fn bg_getattr(&self, inode_index: usize) -> fuser::FileAttr {
181+
let inode = &self.inode_table[inode_index];
182+
fuser::FileAttr {
183+
ino: inode_index as u64,
184+
size: inode.i_size as u64,
185+
// todo
186+
blocks: 0,
187+
atime: SystemTime::UNIX_EPOCH + std::time::Duration::from_secs(inode.i_atime as u64),
188+
mtime: SystemTime::UNIX_EPOCH + std::time::Duration::from_secs(inode.i_mtime as u64),
189+
ctime: SystemTime::UNIX_EPOCH + std::time::Duration::from_secs(inode.i_ctime as u64),
190+
crtime: SystemTime::UNIX_EPOCH + std::time::Duration::from_secs(inode.i_ctime as u64),
191+
kind: match inode.i_mode & 0xf000 {
192+
0x8000 => fuser::FileType::RegularFile,
193+
0x4000 => fuser::FileType::Directory,
194+
_ => fuser::FileType::RegularFile,
195+
},
196+
perm: inode.i_mode & 0x0fff,
197+
nlink: inode.i_links_count as u32,
198+
uid: inode.i_uid as u32,
199+
gid: inode.i_gid as u32,
200+
// 不熟这些 attr 先不实现
201+
rdev: 0,
202+
flags: 0,
203+
blksize: BLOCK_SIZE as u32,
204+
padding: 0,
205+
}
206+
}
207+
123208
pub fn add_entry_to_directory(&mut self, name: String, parent_inode: usize) -> usize {
124209
let inode_index = self.get_inode(); //分配一个inode
125210
let mut dir = DirectoryEntry::new(name, FileType::Directory, inode_index as u32, 0);
126211
let (dir_data, dir_size) = dir.to_bytes();
127-
let (block_index, offset, i_block_index) = self.get_block_for_dir(parent_inode, dir_size); //找到写入的块
128-
self.data_block[block_index].write(&dir_data, offset);
129-
self.inode_table[parent_inode].inode_update(
130-
dir_size as i32,
131-
i_block_index,
132-
block_index as u32,
133-
);
134-
self.inode_bitmap.set(inode_index, true);
135-
self.block_bitmap.set(block_index, true);
212+
213+
let inode = self.inode_table.get(parent_inode - 1).unwrap();
214+
self.write_file_offset(parent_inode, inode.i_size as usize, &dir_data);
215+
136216
inode_index
137217
}
138-
//找到第一个还有容量的块能够写入文件夹的块,用于写入文件夹
139-
pub fn get_block_for_dir(&self, inode_index: usize, dir_byte: u16) -> (usize, usize, usize) {
140-
//先实现直接指针的,todo多级指针
141-
let mut inode_index = 0;
142-
for i in self.inode_table[inode_index].direct_pointer {
143-
if let Some(val) = i {
144-
let free_bytes = self.data_block[val as usize].count_free_bytes();
145-
if free_bytes > dir_byte {
146-
return (val as usize, BLOCK_SIZE - free_bytes as usize, inode_index);
147-
}
148-
inode_index += 1;
149-
}
150-
}
151-
(0, 0, 0)
152-
}
153218

154-
pub fn get_inode_index(&mut self, inode_index: usize) -> i32 {
155-
self.inode_table[inode_index].get_index()
156-
}
157219
fn get_inode(&mut self) -> usize {
158220
match self.inode_bitmap.free_index() {
159221
Some(index) => return index,
160222
None => {
161-
self.inode_bitmap.set(self.inode_table.len() - 1, true);
162-
self.inode_table.push(Inode::new());
163-
self.inode_table.len()
223+
panic!("no free inode")
164224
}
165225
}
166226
}
167227
//找到空的块
168228
pub fn get_block_for_file(&mut self) -> usize {
169-
if let Some(index) = self.block_bitmap.free_index() {
170-
return index;
229+
match self.block_bitmap.free_index() {
230+
Some(index) => return index + 1,
231+
None => panic!("no free block"),
171232
}
172-
self.block_bitmap.set(self.data_block.len(), true);
173-
self.data_block.push(DataBlock::new());
174-
return self.data_block.len();
175-
}
176-
177-
fn bg_update(&mut self, block_index: usize, inode_index: usize) {
178-
self.block_bitmap.set(block_index, true);
179-
self.inode_bitmap.set(inode_index, true);
180-
}
181-
//将文件写入数据块中
182-
pub fn write_to_block(&mut self, data: &[u8], block_index: usize, offset: usize) -> usize {
183-
self.data_block[block_index as usize].write(&data, offset);
184-
return block_index as usize;
185233
}
186234
}
187235

@@ -235,6 +283,27 @@ pub enum Filetype {
235283
// SymbolicLink = 0xA000,
236284
}
237285

286+
impl Clone for Inode{
287+
fn clone(&self) -> Self {
288+
Inode {
289+
i_mode: self.i_mode,
290+
i_size: self.i_size,
291+
i_atime: self.i_atime,
292+
i_ctime: self.i_ctime,
293+
i_mtime: self.i_mtime,
294+
i_dtime: self.i_dtime,
295+
i_block: self.i_block,
296+
direct_pointer: self.direct_pointer.clone(),
297+
singly_indirect_block: self.singly_indirect_block.clone(),
298+
doubly_indirect_block: self.doubly_indirect_block.clone(),
299+
triply_indirect_block: self.triply_indirect_block.clone(),
300+
i_uid: self.i_uid,
301+
i_gid: self.i_gid,
302+
i_links_count: self.i_links_count,
303+
}
304+
}
305+
}
306+
238307
impl Inode {
239308
fn new() -> Self {
240309
Inode {
@@ -249,25 +318,26 @@ impl Inode {
249318
singly_indirect_block: None,
250319
doubly_indirect_block: None,
251320
triply_indirect_block: None,
321+
i_uid: 0,
322+
i_gid: 0,
323+
i_links_count: 1,
252324
}
253325
}
254-
//找到第一个空的直接指向的指针
255-
pub fn get_index(&self) -> i32 {
256-
for i in self.direct_pointer {
257-
if i == None {
258-
return i.unwrap() as i32;
259-
}
260-
}
261-
-1
262-
}
263326

264-
pub fn inode_update(&mut self, size: i32, index: usize, block_index: u32) {
265-
self.i_size += (size + self.i_size as i32) as u32;
266-
self.direct_pointer[index] = Option::Some(block_index);
327+
pub fn inode_update_size(&mut self, size: u32) {
328+
self.i_size += size + self.i_size;
267329
self.i_ctime = get_current_time();
268330
}
269331
}
270332

333+
impl Clone for DataBlock{
334+
fn clone(&self) -> Self {
335+
DataBlock {
336+
data: self.data.clone(),
337+
}
338+
}
339+
}
340+
271341
impl DataBlock {
272342
pub fn get_file(&self) -> DirectoryEntry {
273343
bincode::deserialize(&self.data).unwrap()
@@ -280,13 +350,13 @@ impl DataBlock {
280350
pub fn write(&mut self, data: &[u8], offset: usize) {
281351
for (i, &byte) in data.iter().enumerate().take(BLOCK_SIZE) {
282352
self.data[i + offset] = byte;
283-
}
353+
}
284354
}
285355

286-
pub fn read(&self) -> &[u8]{
356+
pub fn read(&self) -> &[u8] {
287357
&self.data
288358
}
289-
pub fn count_free_bytes(&self) -> u16{
359+
pub fn count_free_bytes(&self) -> u16 {
290360
let mut used_byte = 0;
291361
for &byte in self.data.iter() {
292362
if byte != 0x00 {
@@ -343,3 +413,7 @@ fn get_current_time() -> u32 {
343413
.expect("Time went backwards");
344414
duration.as_secs() as u32
345415
}
416+
417+
pub fn convert_offset(offset: usize) -> (usize, usize) {
418+
(offset / BLOCK_SIZE, offset % BLOCK_SIZE)
419+
}

0 commit comments

Comments
 (0)