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:: * } ;
3
2
use bincode;
3
+ use log:: debug;
4
4
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
+ } ;
11
15
16
+ pub const BLOCK_SIZE : usize = 1024 ; //每个数据块的大小为1kB
17
+ //一个块的大小控制了,inode和bitmap的位图的大就是一个块的大小
18
+ //那么块的数据也就确定了,1024*8
19
+ pub const BLOCK_COUNT : usize = BLOCK_SIZE * 8 ;
12
20
13
21
//part 1
14
22
pub struct BootBlock { }
@@ -43,11 +51,14 @@ pub struct GroupDescriperTable {
43
51
44
52
pub struct Inode {
45
53
i_mode : u16 , //16位置用于表示文件的类型和权限
54
+ i_uid : u16 , //用户id
46
55
i_size : u32 ,
47
56
i_atime : u32 , //存储的是秒数
48
57
i_ctime : u32 ,
49
58
i_mtime : u32 ,
50
59
i_dtime : u32 ,
60
+ i_gid : u16 , //组id
61
+ i_links_count : u16 ,
51
62
i_block : [ Option < u32 > ; 15 ] , //指向的是数据块
52
63
//file_type: FileType,可有可无
53
64
pub direct_pointer : [ Option < u32 > ; 12 ] , //直接索引,前12个块 Some是指向数字的指针,要么就是None
@@ -61,51 +72,97 @@ struct DataBlock {
61
72
}
62
73
63
74
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
+
64
87
pub fn new ( ) -> Self {
65
88
BlockGroup {
66
89
superblock : SuperBlock :: new ( ) ,
67
90
group_descriper_table : GroupDescriperTable :: new ( ) ,
68
91
inode_bitmap : Bitmap :: new ( BLOCK_SIZE ) ,
69
92
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 ] ,
72
95
}
73
96
}
97
+
74
98
pub fn full ( & self ) -> bool {
75
99
self . block_bitmap . free_index ( ) == None
76
100
}
77
101
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 ! [ ] ;
80
104
for block_index in self . inode_table [ inode_index] . direct_pointer {
81
105
match block_index {
82
106
Some ( index) => {
83
107
data. extend_from_slice ( self . data_block [ index as usize ] . read ( ) ) ;
84
- } ,
85
- None => ( )
86
- }
108
+ }
109
+ None => ( ) ,
87
110
}
111
+ }
88
112
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 ) ) ;
90
118
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
+ }
96
152
}
97
153
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 {
101
157
if let Some ( i_block) = index {
102
158
all_dirs. append ( & mut self . data_block [ i_block as usize ] . get_all_dirs_name ( ) ) ;
103
159
}
104
160
}
105
161
for it in & all_dirs {
106
- print ! ( "{}" , it. name) ;
162
+ print ! ( "{}" , it. name) ;
107
163
}
108
164
}
165
+
109
166
pub fn bg_rmdir ( & mut self , parent_inode : usize , name : String ) {
110
167
for block_index in self . inode_table [ parent_inode] . direct_pointer {
111
168
if let Some ( index) = block_index {
@@ -120,68 +177,59 @@ impl BlockGroup {
120
177
self . add_entry_to_directory ( ".." . to_string ( ) , child_inode) ;
121
178
}
122
179
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
+
123
208
pub fn add_entry_to_directory ( & mut self , name : String , parent_inode : usize ) -> usize {
124
209
let inode_index = self . get_inode ( ) ; //分配一个inode
125
210
let mut dir = DirectoryEntry :: new ( name, FileType :: Directory , inode_index as u32 , 0 ) ;
126
211
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
+
136
216
inode_index
137
217
}
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
- }
153
218
154
- pub fn get_inode_index ( & mut self , inode_index : usize ) -> i32 {
155
- self . inode_table [ inode_index] . get_index ( )
156
- }
157
219
fn get_inode ( & mut self ) -> usize {
158
220
match self . inode_bitmap . free_index ( ) {
159
221
Some ( index) => return index,
160
222
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" )
164
224
}
165
225
}
166
226
}
167
227
//找到空的块
168
228
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" ) ,
171
232
}
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 ;
185
233
}
186
234
}
187
235
@@ -235,6 +283,27 @@ pub enum Filetype {
235
283
// SymbolicLink = 0xA000,
236
284
}
237
285
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
+
238
307
impl Inode {
239
308
fn new ( ) -> Self {
240
309
Inode {
@@ -249,25 +318,26 @@ impl Inode {
249
318
singly_indirect_block : None ,
250
319
doubly_indirect_block : None ,
251
320
triply_indirect_block : None ,
321
+ i_uid : 0 ,
322
+ i_gid : 0 ,
323
+ i_links_count : 1 ,
252
324
}
253
325
}
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
- }
263
326
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 ;
267
329
self . i_ctime = get_current_time ( ) ;
268
330
}
269
331
}
270
332
333
+ impl Clone for DataBlock {
334
+ fn clone ( & self ) -> Self {
335
+ DataBlock {
336
+ data : self . data . clone ( ) ,
337
+ }
338
+ }
339
+ }
340
+
271
341
impl DataBlock {
272
342
pub fn get_file ( & self ) -> DirectoryEntry {
273
343
bincode:: deserialize ( & self . data ) . unwrap ( )
@@ -280,13 +350,13 @@ impl DataBlock {
280
350
pub fn write ( & mut self , data : & [ u8 ] , offset : usize ) {
281
351
for ( i, & byte) in data. iter ( ) . enumerate ( ) . take ( BLOCK_SIZE ) {
282
352
self . data [ i + offset] = byte;
283
- }
353
+ }
284
354
}
285
355
286
- pub fn read ( & self ) -> & [ u8 ] {
356
+ pub fn read ( & self ) -> & [ u8 ] {
287
357
& self . data
288
358
}
289
- pub fn count_free_bytes ( & self ) -> u16 {
359
+ pub fn count_free_bytes ( & self ) -> u16 {
290
360
let mut used_byte = 0 ;
291
361
for & byte in self . data . iter ( ) {
292
362
if byte != 0x00 {
@@ -343,3 +413,7 @@ fn get_current_time() -> u32 {
343
413
. expect ( "Time went backwards" ) ;
344
414
duration. as_secs ( ) as u32
345
415
}
416
+
417
+ pub fn convert_offset ( offset : usize ) -> ( usize , usize ) {
418
+ ( offset / BLOCK_SIZE , offset % BLOCK_SIZE )
419
+ }
0 commit comments