xref: /DragonOS/kernel/src/filesystem/fat/fs.rs (revision 36fd013004ee0bd5fc7cfb452ba22531a83a859c)
1 #![allow(dead_code)]
2 use core::{any::Any, fmt::Debug};
3 
4 use alloc::{
5     collections::BTreeMap,
6     string::String,
7     sync::{Arc, Weak},
8     vec::Vec,
9 };
10 
11 use crate::{
12     filesystem::vfs::{
13         core::generate_inode_id,
14         file::{FileMode, FilePrivateData},
15         FileSystem, FileType, IndexNode, InodeId, Metadata, PollStatus,
16     },
17     io::{device::LBA_SIZE, disk_info::Partition, SeekFrom},
18     kerror,
19     libs::{
20         spinlock::{SpinLock, SpinLockGuard},
21         vec_cursor::VecCursor,
22     },
23     syscall::SystemError,
24     time::TimeSpec,
25 };
26 
27 use super::{
28     bpb::{BiosParameterBlock, FATType},
29     entry::{FATDir, FATDirEntry, FATDirIter, FATEntry},
30     utils::RESERVED_CLUSTERS,
31 };
32 
33 /// FAT32文件系统的最大的文件大小
34 pub const MAX_FILE_SIZE: u64 = 0xffff_ffff;
35 
36 /// @brief 表示当前簇和上一个簇的关系的结构体
37 /// 定义这样一个结构体的原因是,FAT文件系统的文件中,前后两个簇具有关联关系。
38 #[derive(Debug, Clone, Copy, Default)]
39 pub struct Cluster {
40     pub cluster_num: u64,
41     pub parent_cluster: u64,
42 }
43 
44 impl PartialOrd for Cluster {
45     /// @brief 根据当前簇号比较大小
46     fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
47         return self.cluster_num.partial_cmp(&other.cluster_num);
48     }
49 }
50 
51 impl PartialEq for Cluster {
52     /// @brief 根据当前簇号比较是否相等
53     fn eq(&self, other: &Self) -> bool {
54         self.cluster_num == other.cluster_num
55     }
56 }
57 
58 impl Eq for Cluster {}
59 
60 #[derive(Debug)]
61 pub struct FATFileSystem {
62     /// 当前文件系统所在的分区
63     pub partition: Arc<Partition>,
64     /// 当前文件系统的BOPB
65     pub bpb: BiosParameterBlock,
66     /// 当前文件系统的第一个数据扇区(相对分区开始位置)
67     pub first_data_sector: u64,
68     /// 文件系统信息结构体
69     pub fs_info: Arc<LockedFATFsInfo>,
70     /// 文件系统的根inode
71     root_inode: Arc<LockedFATInode>,
72 }
73 
74 /// FAT文件系统的Inode
75 #[derive(Debug)]
76 pub struct LockedFATInode(SpinLock<FATInode>);
77 
78 #[derive(Debug)]
79 pub struct LockedFATFsInfo(SpinLock<FATFsInfo>);
80 
81 impl LockedFATFsInfo {
82     #[inline]
83     pub fn new(fs_info: FATFsInfo) -> Self {
84         return Self(SpinLock::new(fs_info));
85     }
86 }
87 
88 #[derive(Debug)]
89 pub struct FATInode {
90     /// 指向父Inode的弱引用
91     parent: Weak<LockedFATInode>,
92     /// 指向自身的弱引用
93     self_ref: Weak<LockedFATInode>,
94     /// 子Inode的B树. 该数据结构用作缓存区。其中,它的key表示inode的名称。
95     /// 请注意,由于FAT的查询过程对大小写不敏感,因此我们选择让key全部是大写的,方便统一操作。
96     children: BTreeMap<String, Arc<LockedFATInode>>,
97     /// 当前inode的元数据
98     metadata: Metadata,
99     /// 指向inode所在的文件系统对象的指针
100     fs: Weak<FATFileSystem>,
101 
102     /// 根据不同的Inode类型,创建不同的私有字段
103     inode_type: FATDirEntry,
104 }
105 
106 impl FATInode {
107     /// @brief 更新当前inode的元数据
108     pub fn update_metadata(&mut self) {
109         // todo: 更新文件的访问时间等信息
110         match &self.inode_type {
111             FATDirEntry::File(f) | FATDirEntry::VolId(f) => {
112                 self.metadata.size = f.size() as i64;
113             }
114             FATDirEntry::Dir(d) => {
115                 self.metadata.size = d.size(&self.fs.upgrade().unwrap().clone()) as i64;
116             }
117             FATDirEntry::UnInit => {
118                 kerror!("update_metadata: Uninitialized FATDirEntry: {:?}", self);
119                 return;
120             }
121         };
122     }
123 
124     fn find(&mut self, name: &str) -> Result<Arc<LockedFATInode>, SystemError> {
125         match &self.inode_type {
126             FATDirEntry::Dir(d) => {
127                 // 尝试在缓存区查找
128                 if let Some(entry) = self.children.get(&name.to_uppercase()) {
129                     return Ok(entry.clone());
130                 }
131                 // 在缓存区找不到
132                 // 在磁盘查找
133                 let fat_entry: FATDirEntry =
134                     d.find_entry(name, None, None, self.fs.upgrade().unwrap())?;
135                 // kdebug!("find entry from disk ok, entry={fat_entry:?}");
136                 // 创建新的inode
137                 let entry_inode: Arc<LockedFATInode> = LockedFATInode::new(
138                     self.fs.upgrade().unwrap(),
139                     self.self_ref.clone(),
140                     fat_entry,
141                 );
142                 // 加入缓存区, 由于FAT文件系统的大小写不敏感问题,因此存入缓存区的key应当是全大写的
143                 self.children
144                     .insert(name.to_uppercase(), entry_inode.clone());
145                 return Ok(entry_inode);
146             }
147             FATDirEntry::UnInit => {
148                 panic!(
149                     "Uninitialized FAT Inode, fs = {:?}, inode={self:?}",
150                     self.fs
151                 )
152             }
153             _ => {
154                 return Err(SystemError::ENOTDIR);
155             }
156         }
157     }
158 }
159 
160 impl LockedFATInode {
161     pub fn new(
162         fs: Arc<FATFileSystem>,
163         parent: Weak<LockedFATInode>,
164         inode_type: FATDirEntry,
165     ) -> Arc<LockedFATInode> {
166         let file_type = if let FATDirEntry::Dir(_) = inode_type {
167             FileType::Dir
168         } else {
169             FileType::File
170         };
171 
172         let inode: Arc<LockedFATInode> = Arc::new(LockedFATInode(SpinLock::new(FATInode {
173             parent: parent,
174             self_ref: Weak::default(),
175             children: BTreeMap::new(),
176             fs: Arc::downgrade(&fs),
177             inode_type: inode_type,
178             metadata: Metadata {
179                 dev_id: 0,
180                 inode_id: generate_inode_id(),
181                 size: 0,
182                 blk_size: fs.bpb.bytes_per_sector as usize,
183                 blocks: if let FATType::FAT32(_) = fs.bpb.fat_type {
184                     fs.bpb.total_sectors_32 as usize
185                 } else {
186                     fs.bpb.total_sectors_16 as usize
187                 },
188                 atime: TimeSpec::default(),
189                 mtime: TimeSpec::default(),
190                 ctime: TimeSpec::default(),
191                 file_type: file_type,
192                 mode: 0o777,
193                 nlinks: 1,
194                 uid: 0,
195                 gid: 0,
196                 raw_dev: 0,
197             },
198         })));
199 
200         inode.0.lock().self_ref = Arc::downgrade(&inode);
201 
202         inode.0.lock().update_metadata();
203 
204         return inode;
205     }
206 }
207 
208 /// FsInfo结构体(内存中的一份拷贝,当卸载卷或者sync的时候,把它写入磁盘)
209 #[derive(Debug)]
210 pub struct FATFsInfo {
211     /// Lead Signature - must equal 0x41615252
212     lead_sig: u32,
213     /// Value must equal 0x61417272
214     struc_sig: u32,
215     /// 空闲簇数目
216     free_count: u32,
217     /// 第一个空闲簇的位置(不一定准确,仅供加速查找)
218     next_free: u32,
219     /// 0xAA550000
220     trail_sig: u32,
221     /// Dirty flag to flush to disk
222     dirty: bool,
223     /// FsInfo Structure 在磁盘上的字节偏移量
224     /// Not present for FAT12 and FAT16
225     offset: Option<u64>,
226 }
227 
228 impl FileSystem for FATFileSystem {
229     fn root_inode(&self) -> Arc<dyn crate::filesystem::vfs::IndexNode> {
230         return self.root_inode.clone();
231     }
232 
233     fn info(&self) -> crate::filesystem::vfs::FsInfo {
234         todo!()
235     }
236 
237     /// @brief 本函数用于实现动态转换。
238     /// 具体的文件系统在实现本函数时,最简单的方式就是:直接返回self
239     fn as_any_ref(&self) -> &dyn Any {
240         self
241     }
242 }
243 
244 impl FATFileSystem {
245     /// FAT12允许的最大簇号
246     pub const FAT12_MAX_CLUSTER: u32 = 0xFF5;
247     /// FAT16允许的最大簇号
248     pub const FAT16_MAX_CLUSTER: u32 = 0xFFF5;
249     /// FAT32允许的最大簇号
250     pub const FAT32_MAX_CLUSTER: u32 = 0x0FFFFFF7;
251 
252     pub fn new(partition: Arc<Partition>) -> Result<Arc<FATFileSystem>, SystemError> {
253         let bpb = BiosParameterBlock::new(partition.clone())?;
254 
255         // 从磁盘上读取FAT32文件系统的FsInfo结构体
256         let fs_info: FATFsInfo = match bpb.fat_type {
257             FATType::FAT32(bpb32) => {
258                 let fs_info_in_disk_bytes_offset = partition.lba_start * LBA_SIZE as u64
259                     + bpb32.fs_info as u64 * bpb.bytes_per_sector as u64;
260                 FATFsInfo::new(
261                     partition.clone(),
262                     fs_info_in_disk_bytes_offset,
263                     bpb.bytes_per_sector as usize,
264                 )?
265             }
266             _ => FATFsInfo::default(),
267         };
268 
269         // 根目录项占用的扇区数(向上取整)
270         let root_dir_sectors: u64 = ((bpb.root_entries_cnt as u64 * 32)
271             + (bpb.bytes_per_sector as u64 - 1))
272             / (bpb.bytes_per_sector as u64);
273 
274         // FAT表大小(单位:扇区)
275         let fat_size = if bpb.fat_size_16 != 0 {
276             bpb.fat_size_16 as u64
277         } else {
278             match bpb.fat_type {
279                 FATType::FAT32(x) => x.fat_size_32 as u64,
280                 _ => {
281                     kerror!("FAT12 and FAT16 volumes should have non-zero BPB_FATSz16");
282                     return Err(SystemError::EINVAL);
283                 }
284             }
285         };
286 
287         let first_data_sector =
288             bpb.rsvd_sec_cnt as u64 + (bpb.num_fats as u64 * fat_size) + root_dir_sectors;
289 
290         // 创建文件系统的根节点
291         let root_inode: Arc<LockedFATInode> = Arc::new(LockedFATInode(SpinLock::new(FATInode {
292             parent: Weak::default(),
293             self_ref: Weak::default(),
294             children: BTreeMap::new(),
295             fs: Weak::default(),
296             inode_type: FATDirEntry::UnInit,
297             metadata: Metadata {
298                 dev_id: 0,
299                 inode_id: generate_inode_id(),
300                 size: 0,
301                 blk_size: bpb.bytes_per_sector as usize,
302                 blocks: if let FATType::FAT32(_) = bpb.fat_type {
303                     bpb.total_sectors_32 as usize
304                 } else {
305                     bpb.total_sectors_16 as usize
306                 },
307                 atime: TimeSpec::default(),
308                 mtime: TimeSpec::default(),
309                 ctime: TimeSpec::default(),
310                 file_type: FileType::Dir,
311                 mode: 0o777,
312                 nlinks: 1,
313                 uid: 0,
314                 gid: 0,
315                 raw_dev: 0,
316             },
317         })));
318 
319         let result: Arc<FATFileSystem> = Arc::new(FATFileSystem {
320             partition: partition,
321             bpb,
322             first_data_sector,
323             fs_info: Arc::new(LockedFATFsInfo::new(fs_info)),
324             root_inode: root_inode,
325         });
326 
327         // 对root inode加锁,并继续完成初始化工作
328         let mut root_guard: SpinLockGuard<FATInode> = result.root_inode.0.lock();
329         root_guard.inode_type = FATDirEntry::Dir(result.root_dir());
330         root_guard.parent = Arc::downgrade(&result.root_inode);
331         root_guard.self_ref = Arc::downgrade(&result.root_inode);
332         root_guard.fs = Arc::downgrade(&result);
333         // 释放锁
334         drop(root_guard);
335 
336         return Ok(result);
337     }
338 
339     /// @brief 计算每个簇有多少个字节
340     #[inline]
341     pub fn bytes_per_cluster(&self) -> u64 {
342         return (self.bpb.bytes_per_sector as u64) * (self.bpb.sector_per_cluster as u64);
343     }
344 
345     /// @brief 读取当前簇在FAT表中存储的信息
346     ///
347     /// @param cluster 当前簇
348     ///
349     /// @return Ok(FATEntry) 当前簇在FAT表中,存储的信息。(详情见FATEntry的注释)
350     /// @return Err(SystemError) 错误码
351     pub fn get_fat_entry(&self, cluster: Cluster) -> Result<FATEntry, SystemError> {
352         let current_cluster = cluster.cluster_num;
353 
354         let fat_type: FATType = self.bpb.fat_type;
355         // 获取FAT表的起始扇区(相对分区起始扇区的偏移量)
356         let fat_start_sector = self.fat_start_sector();
357         let bytes_per_sec = self.bpb.bytes_per_sector as u64;
358 
359         // cluster对应的FAT表项在分区内的字节偏移量
360         let fat_bytes_offset =
361             fat_type.get_fat_bytes_offset(cluster, fat_start_sector, bytes_per_sec);
362 
363         // FAT表项所在的LBA地址
364         // let fat_ent_lba = self.get_lba_from_offset(self.bytes_to_sector(fat_bytes_offset));
365         let fat_ent_lba = self.partition.lba_start + fat_bytes_offset / LBA_SIZE as u64;
366 
367         // FAT表项在逻辑块内的字节偏移量
368         let blk_offset = self.get_in_block_offset(fat_bytes_offset);
369 
370         let mut v = Vec::<u8>::new();
371         v.resize(self.bpb.bytes_per_sector as usize, 0);
372         self.partition
373             .disk()
374             .read_at(fat_ent_lba as usize, 1 * self.lba_per_sector(), &mut v)?;
375 
376         let mut cursor = VecCursor::new(v);
377         cursor.seek(SeekFrom::SeekSet(blk_offset as i64))?;
378 
379         let res: FATEntry = match self.bpb.fat_type {
380             FATType::FAT12(_) => {
381                 let mut entry = cursor.read_u16()?;
382                 // 由于FAT12文件系统的FAT表,每个entry占用1.5字节,因此奇数的簇需要取高12位的值。
383                 if (current_cluster & 1) > 0 {
384                     entry >>= 4;
385                 } else {
386                     entry &= 0x0fff;
387                 }
388 
389                 if entry == 0 {
390                     FATEntry::Unused
391                 } else if entry == 0x0ff7 {
392                     FATEntry::Bad
393                 } else if entry >= 0x0ff8 {
394                     FATEntry::EndOfChain
395                 } else {
396                     FATEntry::Next(Cluster {
397                         cluster_num: entry as u64,
398                         parent_cluster: current_cluster,
399                     })
400                 }
401             }
402             FATType::FAT16(_) => {
403                 let entry = cursor.read_u16()?;
404 
405                 if entry == 0 {
406                     FATEntry::Unused
407                 } else if entry == 0xfff7 {
408                     FATEntry::Bad
409                 } else if entry >= 0xfff8 {
410                     FATEntry::EndOfChain
411                 } else {
412                     FATEntry::Next(Cluster {
413                         cluster_num: entry as u64,
414                         parent_cluster: current_cluster,
415                     })
416                 }
417             }
418             FATType::FAT32(_) => {
419                 let entry = cursor.read_u32()? & 0x0fffffff;
420 
421                 match entry {
422                     _n if (current_cluster >= 0x0ffffff7 && current_cluster <= 0x0fffffff) => {
423                         // 当前簇号不是一个能被获得的簇(可能是文件系统出错了)
424                         kerror!("FAT32 get fat entry: current cluster number [{}] is not an allocatable cluster number.", current_cluster);
425                         FATEntry::Bad
426                     }
427                     0 => FATEntry::Unused,
428                     0x0ffffff7 => FATEntry::Bad,
429                     0x0ffffff8..=0x0fffffff => FATEntry::EndOfChain,
430                     _n => FATEntry::Next(Cluster {
431                         cluster_num: entry as u64,
432                         parent_cluster: current_cluster,
433                     }),
434                 }
435             }
436         };
437         return Ok(res);
438     }
439 
440     /// @brief 读取当前簇在FAT表中存储的信息(直接返回读取到的值,而不加处理)
441     ///
442     /// @param cluster 当前簇
443     ///
444     /// @return Ok(u64) 当前簇在FAT表中,存储的信息。
445     /// @return Err(SystemError) 错误码
446     pub fn get_fat_entry_raw(&self, cluster: Cluster) -> Result<u64, SystemError> {
447         let current_cluster = cluster.cluster_num;
448 
449         let fat_type: FATType = self.bpb.fat_type;
450         // 获取FAT表的起始扇区(相对分区起始扇区的偏移量)
451         let fat_start_sector = self.fat_start_sector();
452         let bytes_per_sec = self.bpb.bytes_per_sector as u64;
453 
454         // cluster对应的FAT表项在分区内的字节偏移量
455         let fat_bytes_offset =
456             fat_type.get_fat_bytes_offset(cluster, fat_start_sector, bytes_per_sec);
457 
458         // FAT表项所在的LBA地址
459         let fat_ent_lba = self.get_lba_from_offset(self.bytes_to_sector(fat_bytes_offset));
460 
461         // FAT表项在逻辑块内的字节偏移量
462         let blk_offset = self.get_in_block_offset(fat_bytes_offset);
463 
464         let mut v = Vec::<u8>::new();
465         v.resize(self.bpb.bytes_per_sector as usize, 0);
466         self.partition
467             .disk()
468             .read_at(fat_ent_lba, 1 * self.lba_per_sector(), &mut v)?;
469 
470         let mut cursor = VecCursor::new(v);
471         cursor.seek(SeekFrom::SeekSet(blk_offset as i64))?;
472 
473         let res = match self.bpb.fat_type {
474             FATType::FAT12(_) => {
475                 let mut entry = cursor.read_u16()?;
476                 entry = if (current_cluster & 0x0001) > 0 {
477                     entry >> 4
478                 } else {
479                     entry & 0x0fff
480                 };
481                 entry as u64
482             }
483             FATType::FAT16(_) => {
484                 let entry = (cursor.read_u16()?) as u64;
485                 entry
486             }
487             FATType::FAT32(_) => {
488                 let entry = cursor.read_u32()? & 0x0fff_ffff;
489                 entry as u64
490             }
491         };
492 
493         return Ok(res);
494     }
495 
496     /// @brief 获取当前文件系统的root inode,在磁盘上的字节偏移量
497     pub fn root_dir_bytes_offset(&self) -> u64 {
498         match self.bpb.fat_type {
499             FATType::FAT32(s) => {
500                 let first_sec_cluster: u64 = (s.root_cluster as u64 - 2)
501                     * (self.bpb.sector_per_cluster as u64)
502                     + self.first_data_sector;
503                 return (self.get_lba_from_offset(first_sec_cluster) * LBA_SIZE) as u64;
504             }
505             _ => {
506                 let root_sec = (self.bpb.rsvd_sec_cnt as u64)
507                     + (self.bpb.num_fats as u64) * (self.bpb.fat_size_16 as u64);
508                 return (self.get_lba_from_offset(root_sec) * LBA_SIZE) as u64;
509             }
510         }
511     }
512 
513     /// @brief 获取当前文件系统的根目录项区域的结束位置,在磁盘上的字节偏移量。
514     /// 请注意,当前函数只对FAT12/FAT16生效。对于FAT32,返回None
515     pub fn root_dir_end_bytes_offset(&self) -> Option<u64> {
516         match self.bpb.fat_type {
517             FATType::FAT12(_) | FATType::FAT16(_) => {
518                 return Some(
519                     self.root_dir_bytes_offset() + (self.bpb.root_entries_cnt as u64) * 32,
520                 );
521             }
522             _ => {
523                 return None;
524             }
525         }
526     }
527 
528     /// @brief 获取簇在磁盘内的字节偏移量(相对磁盘起始位置。注意,不是分区内偏移量)
529     pub fn cluster_bytes_offset(&self, cluster: Cluster) -> u64 {
530         if cluster.cluster_num >= 2 {
531             // 指定簇的第一个扇区号
532             let first_sec_of_cluster = (cluster.cluster_num - 2)
533                 * (self.bpb.sector_per_cluster as u64)
534                 + self.first_data_sector;
535             return (self.get_lba_from_offset(first_sec_of_cluster) * LBA_SIZE) as u64;
536         } else {
537             return 0;
538         }
539     }
540 
541     /// @brief 获取一个空闲簇
542     ///
543     /// @param prev_cluster 簇链的前一个簇。本函数将会把新获取的簇,连接到它的后面。
544     ///
545     /// @return Ok(Cluster) 新获取的空闲簇
546     /// @return Err(SystemError) 错误码
547     pub fn allocate_cluster(&self, prev_cluster: Option<Cluster>) -> Result<Cluster, SystemError> {
548         let end_cluster: Cluster = self.max_cluster_number();
549         let start_cluster: Cluster = match self.bpb.fat_type {
550             FATType::FAT32(_) => {
551                 let next_free: u64 = match self.fs_info.0.lock().next_free() {
552                     Some(x) => x,
553                     None => 0xffffffff,
554                 };
555                 if next_free < end_cluster.cluster_num {
556                     Cluster::new(next_free)
557                 } else {
558                     Cluster::new(RESERVED_CLUSTERS as u64)
559                 }
560             }
561             _ => Cluster::new(RESERVED_CLUSTERS as u64),
562         };
563 
564         // 寻找一个空的簇
565         let free_cluster: Cluster = match self.get_free_cluster(start_cluster, end_cluster) {
566             Ok(c) => c,
567             Err(_) if start_cluster.cluster_num > RESERVED_CLUSTERS as u64 => {
568                 self.get_free_cluster(Cluster::new(RESERVED_CLUSTERS as u64), end_cluster)?
569             }
570             Err(e) => return Err(e),
571         };
572 
573         self.set_entry(free_cluster, FATEntry::EndOfChain)?;
574         // 减少空闲簇计数
575         self.fs_info.0.lock().update_free_count_delta(-1);
576         // 更新搜索空闲簇的参考量
577         self.fs_info
578             .0
579             .lock()
580             .update_next_free((free_cluster.cluster_num + 1) as u32);
581 
582         // 如果这个空闲簇不是簇链的第一个簇,那么把当前簇跟前一个簇连上。
583         if let Some(prev_cluster) = prev_cluster {
584             // kdebug!("set entry, prev ={prev_cluster:?}, next = {free_cluster:?}");
585             self.set_entry(prev_cluster, FATEntry::Next(free_cluster))?;
586         }
587         // 清空新获取的这个簇
588         self.zero_cluster(free_cluster)?;
589         return Ok(free_cluster);
590     }
591 
592     /// @brief 释放簇链上的所有簇
593     ///
594     /// @param start_cluster 簇链的第一个簇
595     pub fn deallocate_cluster_chain(&self, start_cluster: Cluster) -> Result<(), SystemError> {
596         let clusters: Vec<Cluster> = self.clusters(start_cluster);
597         for c in clusters {
598             self.deallocate_cluster(c)?;
599         }
600         return Ok(());
601     }
602 
603     /// @brief 释放簇
604     ///
605     /// @param 要释放的簇
606     pub fn deallocate_cluster(&self, cluster: Cluster) -> Result<(), SystemError> {
607         let entry: FATEntry = self.get_fat_entry(cluster)?;
608         // 如果不是坏簇
609         if entry != FATEntry::Bad {
610             self.set_entry(cluster, FATEntry::Unused)?;
611             self.fs_info.0.lock().update_free_count_delta(1);
612             // 安全选项:清空被释放的簇
613             #[cfg(feature = "secure")]
614             self.zero_cluster(cluster)?;
615             return Ok(());
616         } else {
617             // 不能释放坏簇
618             kerror!("Bad clusters cannot be freed.");
619             return Err(SystemError::EFAULT);
620         }
621     }
622 
623     /// @brief 获取文件系统的根目录项
624     pub fn root_dir(&self) -> FATDir {
625         match self.bpb.fat_type {
626             FATType::FAT32(s) => {
627                 return FATDir {
628                     first_cluster: Cluster::new(s.root_cluster as u64),
629                     dir_name: String::from("/"),
630                     root_offset: None,
631                     short_dir_entry: None,
632                     loc: None,
633                 };
634             }
635             _ => FATDir {
636                 first_cluster: Cluster::new(0),
637                 dir_name: String::from("/"),
638                 root_offset: Some(self.root_dir_bytes_offset()),
639                 short_dir_entry: None,
640                 loc: None,
641             },
642         }
643     }
644 
645     /// @brief 获取FAT表的起始扇区(相对分区起始扇区的偏移量)
646     pub fn fat_start_sector(&self) -> u64 {
647         let active_fat = self.active_fat();
648         let fat_size = self.fat_size();
649         return self.bpb.rsvd_sec_cnt as u64 + active_fat * fat_size;
650     }
651 
652     /// @brief 获取当前活动的FAT表
653     pub fn active_fat(&self) -> u64 {
654         if self.mirroring_enabled() {
655             return 0;
656         } else {
657             match self.bpb.fat_type {
658                 FATType::FAT32(bpb32) => {
659                     return (bpb32.ext_flags & 0x0f) as u64;
660                 }
661                 _ => {
662                     return 0;
663                 }
664             }
665         }
666     }
667 
668     /// @brief 获取当前文件系统的每个FAT表的大小
669     pub fn fat_size(&self) -> u64 {
670         if self.bpb.fat_size_16 != 0 {
671             return self.bpb.fat_size_16 as u64;
672         } else {
673             match self.bpb.fat_type {
674                 FATType::FAT32(bpb32) => {
675                     return bpb32.fat_size_32 as u64;
676                 }
677 
678                 _ => {
679                     panic!("FAT12 and FAT16 volumes should have non-zero BPB_FATSz16");
680                 }
681             }
682         }
683     }
684 
685     /// @brief 判断当前文件系统是否启用了FAT表镜像
686     pub fn mirroring_enabled(&self) -> bool {
687         match self.bpb.fat_type {
688             FATType::FAT32(bpb32) => {
689                 return (bpb32.ext_flags & 0x80) == 0;
690             }
691             _ => {
692                 return false;
693             }
694         }
695     }
696 
697     /// @brief 根据分区内的扇区偏移量,获得在磁盘上的LBA地址
698     #[inline]
699     pub fn get_lba_from_offset(&self, in_partition_sec_offset: u64) -> usize {
700         return (self.partition.lba_start
701             + in_partition_sec_offset * (self.bpb.bytes_per_sector as u64 / LBA_SIZE as u64))
702             as usize;
703     }
704 
705     /// @brief 获取每个扇区占用多少个LBA
706     #[inline]
707     pub fn lba_per_sector(&self) -> usize {
708         return self.bpb.bytes_per_sector as usize / LBA_SIZE;
709     }
710 
711     /// @brief 将分区内字节偏移量转换为扇区偏移量
712     #[inline]
713     pub fn bytes_to_sector(&self, in_partition_bytes_offset: u64) -> u64 {
714         return in_partition_bytes_offset / (self.bpb.bytes_per_sector as u64);
715     }
716 
717     /// @brief 根据磁盘上的字节偏移量,获取对应位置在分区内的字节偏移量
718     #[inline]
719     pub fn get_in_partition_bytes_offset(&self, disk_bytes_offset: u64) -> u64 {
720         return disk_bytes_offset - (self.partition.lba_start * LBA_SIZE as u64);
721     }
722 
723     /// @brief 根据字节偏移量计算在逻辑块内的字节偏移量
724     #[inline]
725     pub fn get_in_block_offset(&self, bytes_offset: u64) -> u64 {
726         return bytes_offset % LBA_SIZE as u64;
727     }
728 
729     /// @brief 获取在FAT表中,以start_cluster开头的FAT链的所有簇的信息
730     ///
731     /// @param start_cluster 整个FAT链的起始簇号
732     pub fn clusters(&self, start_cluster: Cluster) -> Vec<Cluster> {
733         return self.cluster_iter(start_cluster).collect();
734     }
735 
736     /// @brief 获取在FAT表中,以start_cluster开头的FAT链的长度(总计经过多少个簇)
737     ///
738     /// @param start_cluster 整个FAT链的起始簇号
739     pub fn num_clusters_chain(&self, start_cluster: Cluster) -> u64 {
740         return self
741             .cluster_iter(start_cluster)
742             .fold(0, |size, _cluster| size + 1);
743     }
744     /// @brief 获取一个簇迭代器对象
745     ///
746     /// @param start_cluster 整个FAT链的起始簇号
747     fn cluster_iter(&self, start_cluster: Cluster) -> ClusterIter {
748         return ClusterIter {
749             current_cluster: Some(start_cluster),
750             fs: self,
751         };
752     }
753 
754     /// @brief 获取从start_cluster开始的簇链中,第n个簇的信息。(请注意,下标从0开始)
755     #[inline]
756     pub fn get_cluster_by_relative(&self, start_cluster: Cluster, n: usize) -> Option<Cluster> {
757         return self.cluster_iter(start_cluster).skip(n).next();
758     }
759 
760     /// @brief 获取整个簇链的最后一个簇
761     #[inline]
762     pub fn get_last_cluster(&self, start_cluster: Cluster) -> Option<Cluster> {
763         return self.cluster_iter(start_cluster).last();
764     }
765 
766     /// @brief 判断FAT文件系统的shut bit是否正常。
767     /// shut bit 表示文件系统是否正常卸载。如果这一位是1,则表示这个卷是“干净的”
768     /// 参考资料:https://thestarman.pcministry.com/DOS/DirtyShutdownFlag.html
769     ///
770     /// @return Ok(true) 正常
771     /// @return Ok(false) 不正常
772     /// @return Err(SystemError) 在判断时发生错误
773     pub fn is_shut_bit_ok(&mut self) -> Result<bool, SystemError> {
774         match self.bpb.fat_type {
775             FATType::FAT32(_) => {
776                 // 对于FAT32, error bit位于第一个扇区的第8字节。
777                 let bit = self.get_fat_entry_raw(Cluster::new(1))? & 0x0800_0000;
778                 return Ok(bit > 0);
779             }
780             FATType::FAT16(_) => {
781                 let bit = self.get_fat_entry_raw(Cluster::new(1))? & 0x8000;
782                 return Ok(bit > 0);
783             }
784             _ => return Ok(true),
785         }
786     }
787 
788     /// @brief 判断FAT文件系统的hard error bit是否正常。
789     /// 如果此位为0,则文件系统驱动程序在上次安装卷时遇到磁盘 I/O 错误,这表明
790     /// 卷上的某些扇区可能已损坏。
791     /// 参考资料:https://thestarman.pcministry.com/DOS/DirtyShutdownFlag.html
792     ///
793     /// @return Ok(true) 正常
794     /// @return Ok(false) 不正常
795     /// @return Err(SystemError) 在判断时发生错误
796     pub fn is_hard_error_bit_ok(&mut self) -> Result<bool, SystemError> {
797         match self.bpb.fat_type {
798             FATType::FAT32(_) => {
799                 let bit = self.get_fat_entry_raw(Cluster::new(1))? & 0x0400_0000;
800                 return Ok(bit > 0);
801             }
802             FATType::FAT16(_) => {
803                 let bit = self.get_fat_entry_raw(Cluster::new(1))? & 0x4000;
804                 return Ok(bit > 0);
805             }
806             _ => return Ok(true),
807         }
808     }
809 
810     /// @brief 设置文件系统的shut bit为正常状态
811     /// 参考资料:https://thestarman.pcministry.com/DOS/DirtyShutdownFlag.html
812     ///
813     /// @return Ok(()) 设置成功
814     /// @return Err(SystemError) 在设置过程中,出现错误
815     pub fn set_shut_bit_ok(&mut self) -> Result<(), SystemError> {
816         match self.bpb.fat_type {
817             FATType::FAT32(_) => {
818                 let raw_entry = self.get_fat_entry_raw(Cluster::new(1))? | 0x0800_0000;
819                 self.set_entry(Cluster::new(1), FATEntry::Next(Cluster::new(raw_entry)))?;
820 
821                 return Ok(());
822             }
823 
824             FATType::FAT16(_) => {
825                 let raw_entry = self.get_fat_entry_raw(Cluster::new(1))? | 0x8000;
826                 self.set_entry(Cluster::new(1), FATEntry::Next(Cluster::new(raw_entry)))?;
827                 return Ok(());
828             }
829             _ => return Ok(()),
830         }
831     }
832 
833     /// @brief 设置文件系统的hard error bit为正常状态
834     /// 参考资料:https://thestarman.pcministry.com/DOS/DirtyShutdownFlag.html
835     ///
836     /// @return Ok(()) 设置成功
837     /// @return Err(SystemError) 在设置过程中,出现错误
838     pub fn set_hard_error_bit_ok(&mut self) -> Result<(), SystemError> {
839         match self.bpb.fat_type {
840             FATType::FAT32(_) => {
841                 let raw_entry = self.get_fat_entry_raw(Cluster::new(1))? | 0x0400_0000;
842                 self.set_entry(Cluster::new(1), FATEntry::Next(Cluster::new(raw_entry)))?;
843                 return Ok(());
844             }
845 
846             FATType::FAT16(_) => {
847                 let raw_entry = self.get_fat_entry_raw(Cluster::new(1))? | 0x4000;
848                 self.set_entry(Cluster::new(1), FATEntry::Next(Cluster::new(raw_entry)))?;
849                 return Ok(());
850             }
851             _ => return Ok(()),
852         }
853     }
854 
855     /// @brief 执行文件系统卸载前的一些准备工作:设置好对应的标志位,并把缓存中的数据刷入磁盘
856     pub fn umount(&mut self) -> Result<(), SystemError> {
857         self.fs_info.0.lock().flush(&self.partition)?;
858 
859         self.set_shut_bit_ok()?;
860 
861         self.set_hard_error_bit_ok()?;
862 
863         self.partition.disk().sync()?;
864 
865         return Ok(());
866     }
867 
868     /// @brief 获取文件系统的最大簇号
869     pub fn max_cluster_number(&self) -> Cluster {
870         match self.bpb.fat_type {
871             FATType::FAT32(s) => {
872                 // FAT32
873 
874                 // 数据扇区数量(总扇区数-保留扇区-FAT占用的扇区)
875                 let data_sec: u64 = self.bpb.total_sectors_32 as u64
876                     - (self.bpb.rsvd_sec_cnt as u64
877                         + self.bpb.num_fats as u64 * s.fat_size_32 as u64);
878 
879                 // 数据区的簇数量
880                 let total_clusters: u64 = data_sec / self.bpb.sector_per_cluster as u64;
881 
882                 // 返回最大的簇号
883                 return Cluster::new(total_clusters + RESERVED_CLUSTERS as u64 - 1);
884             }
885 
886             _ => {
887                 // FAT12 / FAT16
888                 let root_dir_sectors: u64 = (((self.bpb.root_entries_cnt as u64) * 32)
889                     + self.bpb.bytes_per_sector as u64
890                     - 1)
891                     / self.bpb.bytes_per_sector as u64;
892                 // 数据区扇区数
893                 let data_sec: u64 = self.bpb.total_sectors_16 as u64
894                     - (self.bpb.rsvd_sec_cnt as u64
895                         + (self.bpb.num_fats as u64 * self.bpb.fat_size_16 as u64)
896                         + root_dir_sectors);
897                 let total_clusters = data_sec / self.bpb.sector_per_cluster as u64;
898                 return Cluster::new(total_clusters + RESERVED_CLUSTERS as u64 - 1);
899             }
900         }
901     }
902 
903     /// @brief 在文件系统中寻找一个簇号在给定的范围(左闭右开区间)内的空闲簇
904     ///
905     /// @param start_cluster 起始簇号
906     /// @param end_cluster 终止簇号(不包含)
907     ///
908     /// @return Ok(Cluster) 寻找到的空闲簇
909     /// @return Err(SystemError) 错误码。如果磁盘无剩余空间,或者簇号达到给定的最大值,则返回-ENOSPC.
910     pub fn get_free_cluster(
911         &self,
912         start_cluster: Cluster,
913         end_cluster: Cluster,
914     ) -> Result<Cluster, SystemError> {
915         let max_cluster: Cluster = self.max_cluster_number();
916         let mut cluster: u64 = start_cluster.cluster_num;
917 
918         let fat_type: FATType = self.bpb.fat_type;
919         let fat_start_sector: u64 = self.fat_start_sector();
920         let bytes_per_sec: u64 = self.bpb.bytes_per_sector as u64;
921 
922         match fat_type {
923             FATType::FAT12(_) => {
924                 let part_bytes_offset: u64 =
925                     fat_type.get_fat_bytes_offset(start_cluster, fat_start_sector, bytes_per_sec);
926                 let in_block_offset = self.get_in_block_offset(part_bytes_offset);
927 
928                 let lba = self.get_lba_from_offset(self.bytes_to_sector(part_bytes_offset));
929 
930                 // 由于FAT12的FAT表不大于6K,因此直接读取6K
931                 let num_lba = (6 * 1024) / LBA_SIZE;
932                 let mut v: Vec<u8> = Vec::new();
933                 v.resize(num_lba * LBA_SIZE, 0);
934                 self.partition.disk().read_at(lba, num_lba, &mut v)?;
935 
936                 let mut cursor: VecCursor = VecCursor::new(v);
937                 cursor.seek(SeekFrom::SeekSet(in_block_offset as i64))?;
938 
939                 let mut packed_val: u16 = cursor.read_u16()?;
940                 loop {
941                     let val = if (cluster & 0x1) > 0 {
942                         packed_val >> 4
943                     } else {
944                         packed_val & 0x0fff
945                     };
946                     if val == 0 {
947                         return Ok(Cluster::new(cluster as u64));
948                     }
949 
950                     cluster += 1;
951 
952                     // 磁盘无剩余空间,或者簇号达到给定的最大值
953                     if cluster == end_cluster.cluster_num || cluster == max_cluster.cluster_num {
954                         return Err(SystemError::ENOSPC);
955                     }
956 
957                     packed_val = match cluster & 1 {
958                         0 => cursor.read_u16()?,
959                         _ => {
960                             let next_byte = cursor.read_u8()? as u16;
961                             (packed_val >> 8) | (next_byte << 8)
962                         }
963                     };
964                 }
965             }
966             FATType::FAT16(_) => {
967                 // todo: 优化这里,减少读取磁盘的次数。
968                 while cluster < end_cluster.cluster_num && cluster < max_cluster.cluster_num {
969                     let part_bytes_offset: u64 = fat_type.get_fat_bytes_offset(
970                         Cluster::new(cluster),
971                         fat_start_sector,
972                         bytes_per_sec,
973                     );
974                     let in_block_offset = self.get_in_block_offset(part_bytes_offset);
975 
976                     let lba = self.get_lba_from_offset(self.bytes_to_sector(part_bytes_offset));
977 
978                     let mut v: Vec<u8> = Vec::new();
979                     v.resize(self.lba_per_sector() * LBA_SIZE, 0);
980                     self.partition
981                         .disk()
982                         .read_at(lba, self.lba_per_sector(), &mut v)?;
983 
984                     let mut cursor: VecCursor = VecCursor::new(v);
985                     cursor.seek(SeekFrom::SeekSet(in_block_offset as i64))?;
986 
987                     let val = cursor.read_u16()?;
988                     // 找到空闲簇
989                     if val == 0 {
990                         return Ok(Cluster::new(val as u64));
991                     }
992                     cluster += 1;
993                 }
994 
995                 // 磁盘无剩余空间,或者簇号达到给定的最大值
996                 return Err(SystemError::ENOSPC);
997             }
998             FATType::FAT32(_) => {
999                 // todo: 优化这里,减少读取磁盘的次数。
1000                 while cluster < end_cluster.cluster_num && cluster < max_cluster.cluster_num {
1001                     let part_bytes_offset: u64 = fat_type.get_fat_bytes_offset(
1002                         Cluster::new(cluster),
1003                         fat_start_sector,
1004                         bytes_per_sec,
1005                     );
1006                     let in_block_offset = self.get_in_block_offset(part_bytes_offset);
1007 
1008                     let lba = self.get_lba_from_offset(self.bytes_to_sector(part_bytes_offset));
1009 
1010                     let mut v: Vec<u8> = Vec::new();
1011                     v.resize(self.lba_per_sector() * LBA_SIZE, 0);
1012                     self.partition
1013                         .disk()
1014                         .read_at(lba, self.lba_per_sector(), &mut v)?;
1015 
1016                     let mut cursor: VecCursor = VecCursor::new(v);
1017                     cursor.seek(SeekFrom::SeekSet(in_block_offset as i64))?;
1018 
1019                     let val = cursor.read_u32()? & 0x0fffffff;
1020 
1021                     if val == 0 {
1022                         return Ok(Cluster::new(cluster));
1023                     }
1024                     cluster += 1;
1025                 }
1026 
1027                 // 磁盘无剩余空间,或者簇号达到给定的最大值
1028                 return Err(SystemError::ENOSPC);
1029             }
1030         }
1031     }
1032 
1033     /// @brief 在FAT表中,设置指定的簇的信息。
1034     ///
1035     /// @param cluster 目标簇
1036     /// @param fat_entry 这个簇在FAT表中,存储的信息(下一个簇的簇号)
1037     pub fn set_entry(&self, cluster: Cluster, fat_entry: FATEntry) -> Result<(), SystemError> {
1038         // fat表项在分区上的字节偏移量
1039         let fat_part_bytes_offset: u64 = self.bpb.fat_type.get_fat_bytes_offset(
1040             cluster,
1041             self.fat_start_sector(),
1042             self.bpb.bytes_per_sector as u64,
1043         );
1044 
1045         match self.bpb.fat_type {
1046             FATType::FAT12(_) => {
1047                 // 计算要写入的值
1048                 let raw_val: u16 = match fat_entry {
1049                     FATEntry::Unused => 0,
1050                     FATEntry::Bad => 0xff7,
1051                     FATEntry::EndOfChain => 0xfff,
1052                     FATEntry::Next(c) => c.cluster_num as u16,
1053                 };
1054 
1055                 let in_block_offset = self.get_in_block_offset(fat_part_bytes_offset);
1056 
1057                 let lba = self.get_lba_from_offset(self.bytes_to_sector(fat_part_bytes_offset));
1058 
1059                 let mut v: Vec<u8> = Vec::new();
1060                 v.resize(LBA_SIZE, 0);
1061                 self.partition.disk().read_at(lba, 1, &mut v)?;
1062 
1063                 let mut cursor: VecCursor = VecCursor::new(v);
1064                 cursor.seek(SeekFrom::SeekSet(in_block_offset as i64))?;
1065 
1066                 let old_val: u16 = cursor.read_u16()?;
1067                 let new_val: u16 = if (cluster.cluster_num & 0x1) > 0 {
1068                     (old_val & 0x000f) | (raw_val << 4)
1069                 } else {
1070                     (old_val & 0xf000) | raw_val
1071                 };
1072 
1073                 // 写回数据到磁盘上
1074                 cursor.seek(SeekFrom::SeekSet(in_block_offset as i64))?;
1075                 cursor.write_u16(new_val)?;
1076                 self.partition.disk().write_at(lba, 1, cursor.as_slice())?;
1077                 return Ok(());
1078             }
1079             FATType::FAT16(_) => {
1080                 // 计算要写入的值
1081                 let raw_val: u16 = match fat_entry {
1082                     FATEntry::Unused => 0,
1083                     FATEntry::Bad => 0xfff7,
1084                     FATEntry::EndOfChain => 0xfdff,
1085                     FATEntry::Next(c) => c.cluster_num as u16,
1086                 };
1087 
1088                 let in_block_offset = self.get_in_block_offset(fat_part_bytes_offset);
1089 
1090                 let lba = self.get_lba_from_offset(self.bytes_to_sector(fat_part_bytes_offset));
1091 
1092                 let mut v: Vec<u8> = Vec::new();
1093                 v.resize(LBA_SIZE, 0);
1094                 self.partition.disk().read_at(lba, 1, &mut v)?;
1095 
1096                 let mut cursor: VecCursor = VecCursor::new(v);
1097                 cursor.seek(SeekFrom::SeekSet(in_block_offset as i64))?;
1098 
1099                 cursor.write_u16(raw_val)?;
1100                 self.partition.disk().write_at(lba, 1, cursor.as_slice())?;
1101 
1102                 return Ok(());
1103             }
1104             FATType::FAT32(_) => {
1105                 let fat_size: u64 = self.fat_size();
1106                 let bound: u64 = if self.mirroring_enabled() {
1107                     1
1108                 } else {
1109                     self.bpb.num_fats as u64
1110                 };
1111                 // kdebug!("set entry, bound={bound}, fat_size={fat_size}");
1112                 for i in 0..bound {
1113                     // 当前操作的FAT表在磁盘上的字节偏移量
1114                     let f_offset: u64 = fat_part_bytes_offset + i * fat_size;
1115                     let in_block_offset: u64 = self.get_in_block_offset(f_offset);
1116                     let lba = self.get_lba_from_offset(self.bytes_to_sector(f_offset));
1117 
1118                     // kdebug!("set entry, lba={lba}, in_block_offset={in_block_offset}");
1119                     let mut v: Vec<u8> = Vec::new();
1120                     v.resize(LBA_SIZE, 0);
1121                     self.partition.disk().read_at(lba, 1, &mut v)?;
1122 
1123                     let mut cursor: VecCursor = VecCursor::new(v);
1124                     cursor.seek(SeekFrom::SeekSet(in_block_offset as i64))?;
1125 
1126                     // FAT32的高4位保留
1127                     let old_bits = cursor.read_u32()? & 0xf0000000;
1128 
1129                     if fat_entry == FATEntry::Unused
1130                         && cluster.cluster_num >= 0x0ffffff7
1131                         && cluster.cluster_num <= 0x0fffffff
1132                     {
1133                         kerror!(
1134                             "FAT32: Reserved Cluster {:?} cannot be marked as free",
1135                             cluster
1136                         );
1137                         return Err(SystemError::EPERM);
1138                     }
1139 
1140                     // 计算要写入的值
1141                     let mut raw_val: u32 = match fat_entry {
1142                         FATEntry::Unused => 0,
1143                         FATEntry::Bad => 0x0FFFFFF7,
1144                         FATEntry::EndOfChain => 0x0FFFFFFF,
1145                         FATEntry::Next(c) => c.cluster_num as u32,
1146                     };
1147 
1148                     // 恢复保留位
1149                     raw_val |= old_bits;
1150 
1151                     // kdebug!("sent entry, raw_val={raw_val}");
1152 
1153                     cursor.seek(SeekFrom::SeekSet(in_block_offset as i64))?;
1154                     cursor.write_u32(raw_val)?;
1155 
1156                     self.partition.disk().write_at(lba, 1, cursor.as_slice())?;
1157                 }
1158 
1159                 return Ok(());
1160             }
1161         }
1162     }
1163 
1164     /// @brief 清空指定的簇
1165     ///
1166     /// @param cluster 要被清空的簇
1167     pub fn zero_cluster(&self, cluster: Cluster) -> Result<(), SystemError> {
1168         // 准备数据,用于写入
1169         let zeros: Vec<u8> = vec![0u8; self.bytes_per_cluster() as usize];
1170         let offset: usize = self.cluster_bytes_offset(cluster) as usize;
1171         self.partition
1172             .disk()
1173             .device()
1174             .write_at(offset, zeros.len(), zeros.as_slice())?;
1175         return Ok(());
1176     }
1177 }
1178 
1179 impl Drop for FATFileSystem {
1180     fn drop(&mut self) {
1181         let r = self.umount();
1182         if r.is_err() {
1183             kerror!(
1184                 "Umount FAT filesystem failed: errno={:?}, FS detail:{self:?}",
1185                 r.unwrap_err()
1186             );
1187         }
1188     }
1189 }
1190 
1191 impl FATFsInfo {
1192     const LEAD_SIG: u32 = 0x41615252;
1193     const STRUC_SIG: u32 = 0x61417272;
1194     const TRAIL_SIG: u32 = 0xAA550000;
1195     const FS_INFO_SIZE: u64 = 512;
1196 
1197     /// @brief 从磁盘上读取FAT文件系统的FSInfo结构体
1198     ///
1199     /// @param partition 磁盘分区
1200     /// @param in_disk_fs_info_offset FSInfo扇区在磁盘内的字节偏移量(单位:字节)
1201     /// @param bytes_per_sec 每扇区字节数
1202     pub fn new(
1203         partition: Arc<Partition>,
1204         in_disk_fs_info_offset: u64,
1205         bytes_per_sec: usize,
1206     ) -> Result<Self, SystemError> {
1207         let mut v = Vec::<u8>::new();
1208         v.resize(bytes_per_sec, 0);
1209 
1210         // 计算fs_info扇区在磁盘上的字节偏移量,从磁盘读取数据
1211         partition
1212             .disk()
1213             .read_at(in_disk_fs_info_offset as usize / LBA_SIZE, 1, &mut v)?;
1214         let mut cursor = VecCursor::new(v);
1215 
1216         let mut fsinfo = FATFsInfo::default();
1217 
1218         fsinfo.lead_sig = cursor.read_u32()?;
1219         cursor.seek(SeekFrom::SeekCurrent(480))?;
1220         fsinfo.struc_sig = cursor.read_u32()?;
1221         fsinfo.free_count = cursor.read_u32()?;
1222         fsinfo.next_free = cursor.read_u32()?;
1223 
1224         cursor.seek(SeekFrom::SeekCurrent(12))?;
1225 
1226         fsinfo.trail_sig = cursor.read_u32()?;
1227         fsinfo.dirty = false;
1228         fsinfo.offset = Some(in_disk_fs_info_offset);
1229 
1230         if fsinfo.is_valid() {
1231             return Ok(fsinfo);
1232         } else {
1233             kerror!("Error occurred while parsing FATFsInfo.");
1234             return Err(SystemError::EINVAL);
1235         }
1236     }
1237 
1238     /// @brief 判断是否为正确的FsInfo结构体
1239     fn is_valid(&self) -> bool {
1240         self.lead_sig == Self::LEAD_SIG
1241             && self.struc_sig == Self::STRUC_SIG
1242             && self.trail_sig == Self::TRAIL_SIG
1243     }
1244 
1245     /// @brief 根据fsinfo的信息,计算当前总的空闲簇数量
1246     ///
1247     /// @param 当前文件系统的最大簇号
1248     pub fn count_free_cluster(&self, max_cluster: Cluster) -> Option<u64> {
1249         let count_clusters = max_cluster.cluster_num - RESERVED_CLUSTERS as u64 + 1;
1250         // 信息不合理,当前的FsInfo中存储的free count大于计算出来的值
1251         if self.free_count as u64 > count_clusters {
1252             return None;
1253         } else {
1254             match self.free_count {
1255                 // free count字段不可用
1256                 0xffffffff => return None,
1257                 // 返回FsInfo中存储的数据
1258                 n => return Some(n as u64),
1259             }
1260         }
1261     }
1262 
1263     /// @brief 更新FsInfo中的“空闲簇统计信息“为new_count
1264     ///
1265     /// 请注意,除非手动调用`flush()`,否则本函数不会将数据刷入磁盘
1266     pub fn update_free_count_abs(&mut self, new_count: u32) {
1267         self.free_count = new_count;
1268     }
1269 
1270     /// @brief 更新FsInfo中的“空闲簇统计信息“,把它加上delta.
1271     ///
1272     /// 请注意,除非手动调用`flush()`,否则本函数不会将数据刷入磁盘
1273     pub fn update_free_count_delta(&mut self, delta: i32) {
1274         self.free_count = (self.free_count as i32 + delta) as u32;
1275     }
1276 
1277     /// @brief 更新FsInfo中的“第一个空闲簇统计信息“为next_free.
1278     ///
1279     /// 请注意,除非手动调用`flush()`,否则本函数不会将数据刷入磁盘
1280     pub fn update_next_free(&mut self, next_free: u32) {
1281         // 这个值是参考量,不一定要准确,仅供加速查找
1282         self.next_free = next_free;
1283     }
1284 
1285     /// @brief 获取fs info 记载的第一个空闲簇。(不一定准确,仅供参考)
1286     pub fn next_free(&self) -> Option<u64> {
1287         match self.next_free {
1288             0xffffffff => return None,
1289             0 | 1 => return None,
1290             n => return Some(n as u64),
1291         };
1292     }
1293 
1294     /// @brief 把fs info刷入磁盘
1295     ///
1296     /// @param partition fs info所在的分区
1297     pub fn flush(&self, partition: &Arc<Partition>) -> Result<(), SystemError> {
1298         if let Some(off) = self.offset {
1299             let in_block_offset = off % LBA_SIZE as u64;
1300 
1301             let lba = off as usize / LBA_SIZE;
1302 
1303             let mut v: Vec<u8> = Vec::new();
1304             v.resize(LBA_SIZE, 0);
1305             partition.disk().read_at(lba, 1, &mut v)?;
1306 
1307             let mut cursor: VecCursor = VecCursor::new(v);
1308             cursor.seek(SeekFrom::SeekSet(in_block_offset as i64))?;
1309 
1310             cursor.write_u32(self.lead_sig)?;
1311             cursor.seek(SeekFrom::SeekCurrent(480))?;
1312             cursor.write_u32(self.struc_sig)?;
1313             cursor.write_u32(self.free_count)?;
1314             cursor.write_u32(self.next_free)?;
1315             cursor.seek(SeekFrom::SeekCurrent(12))?;
1316             cursor.write_u32(self.trail_sig)?;
1317 
1318             partition.disk().write_at(lba, 1, cursor.as_slice())?;
1319         }
1320         return Ok(());
1321     }
1322 
1323     /// @brief 读取磁盘上的Fs Info扇区,将里面的内容更新到结构体中
1324     ///
1325     /// @param partition fs info所在的分区
1326     pub fn update(&mut self, partition: Arc<Partition>) -> Result<(), SystemError> {
1327         if let Some(off) = self.offset {
1328             let in_block_offset = off % LBA_SIZE as u64;
1329 
1330             let lba = off as usize / LBA_SIZE;
1331 
1332             let mut v: Vec<u8> = Vec::new();
1333             v.resize(LBA_SIZE, 0);
1334             partition.disk().read_at(lba, 1, &mut v)?;
1335             let mut cursor: VecCursor = VecCursor::new(v);
1336             cursor.seek(SeekFrom::SeekSet(in_block_offset as i64))?;
1337             self.lead_sig = cursor.read_u32()?;
1338 
1339             cursor.seek(SeekFrom::SeekCurrent(480))?;
1340             self.struc_sig = cursor.read_u32()?;
1341             self.free_count = cursor.read_u32()?;
1342             self.next_free = cursor.read_u32()?;
1343             cursor.seek(SeekFrom::SeekCurrent(12))?;
1344             self.trail_sig = cursor.read_u32()?;
1345         }
1346         return Ok(());
1347     }
1348 }
1349 
1350 impl IndexNode for LockedFATInode {
1351     fn read_at(
1352         &self,
1353         offset: usize,
1354         len: usize,
1355         buf: &mut [u8],
1356         _data: &mut FilePrivateData,
1357     ) -> Result<usize, SystemError> {
1358         let mut guard: SpinLockGuard<FATInode> = self.0.lock();
1359         match &guard.inode_type {
1360             FATDirEntry::File(f) | FATDirEntry::VolId(f) => {
1361                 let r = f.read(
1362                     &guard.fs.upgrade().unwrap(),
1363                     &mut buf[0..len],
1364                     offset as u64,
1365                 );
1366                 guard.update_metadata();
1367                 return r;
1368             }
1369             FATDirEntry::Dir(_) => {
1370                 return Err(SystemError::EISDIR);
1371             }
1372             FATDirEntry::UnInit => {
1373                 kerror!("FATFS: param: Inode_type uninitialized.");
1374                 return Err(SystemError::EROFS);
1375             }
1376         }
1377     }
1378 
1379     fn write_at(
1380         &self,
1381         offset: usize,
1382         len: usize,
1383         buf: &[u8],
1384         _data: &mut FilePrivateData,
1385     ) -> Result<usize, SystemError> {
1386         let mut guard: SpinLockGuard<FATInode> = self.0.lock();
1387         let fs: &Arc<FATFileSystem> = &guard.fs.upgrade().unwrap();
1388 
1389         match &mut guard.inode_type {
1390             FATDirEntry::File(f) | FATDirEntry::VolId(f) => {
1391                 let r = f.write(fs, &buf[0..len], offset as u64);
1392                 guard.update_metadata();
1393                 return r;
1394             }
1395             FATDirEntry::Dir(_) => {
1396                 return Err(SystemError::EISDIR);
1397             }
1398             FATDirEntry::UnInit => {
1399                 kerror!("FATFS: param: Inode_type uninitialized.");
1400                 return Err(SystemError::EROFS);
1401             }
1402         }
1403     }
1404 
1405     fn poll(&self) -> Result<PollStatus, SystemError> {
1406         // 加锁
1407         let inode: SpinLockGuard<FATInode> = self.0.lock();
1408 
1409         // 检查当前inode是否为一个文件夹,如果是的话,就返回错误
1410         if inode.metadata.file_type == FileType::Dir {
1411             return Err(SystemError::EISDIR);
1412         }
1413 
1414         return Ok(PollStatus::READ | PollStatus::WRITE);
1415     }
1416 
1417     fn create(
1418         &self,
1419         name: &str,
1420         file_type: FileType,
1421         _mode: u32,
1422     ) -> Result<Arc<dyn IndexNode>, SystemError> {
1423         // 由于FAT32不支持文件权限的功能,因此忽略mode参数
1424 
1425         let mut guard: SpinLockGuard<FATInode> = self.0.lock();
1426         let fs: &Arc<FATFileSystem> = &guard.fs.upgrade().unwrap();
1427 
1428         match &mut guard.inode_type {
1429             FATDirEntry::File(_) | FATDirEntry::VolId(_) => {
1430                 return Err(SystemError::ENOTDIR);
1431             }
1432             FATDirEntry::Dir(d) => match file_type {
1433                 FileType::File => {
1434                     d.create_file(name, fs)?;
1435                     return Ok(guard.find(name)?);
1436                 }
1437                 FileType::Dir => {
1438                     d.create_dir(name, fs)?;
1439                     return Ok(guard.find(name)?);
1440                 }
1441 
1442                 FileType::SymLink => return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP),
1443                 _ => return Err(SystemError::EINVAL),
1444             },
1445             FATDirEntry::UnInit => {
1446                 kerror!("FATFS: param: Inode_type uninitialized.");
1447                 return Err(SystemError::EROFS);
1448             }
1449         }
1450     }
1451 
1452     fn fs(&self) -> Arc<dyn FileSystem> {
1453         return self.0.lock().fs.upgrade().unwrap();
1454     }
1455 
1456     fn as_any_ref(&self) -> &dyn core::any::Any {
1457         return self;
1458     }
1459 
1460     fn metadata(&self) -> Result<Metadata, SystemError> {
1461         return Ok(self.0.lock().metadata.clone());
1462     }
1463 
1464     fn list(&self) -> Result<Vec<String>, SystemError> {
1465         let mut guard: SpinLockGuard<FATInode> = self.0.lock();
1466         let fatent: &FATDirEntry = &guard.inode_type;
1467         match fatent {
1468             FATDirEntry::File(_) | FATDirEntry::VolId(_) => {
1469                 return Err(SystemError::ENOTDIR);
1470             }
1471             FATDirEntry::Dir(dir) => {
1472                 // 获取当前目录下的所有目录项
1473                 let mut ret: Vec<String> = Vec::new();
1474                 let dir_iter: FATDirIter = dir.to_iter(guard.fs.upgrade().unwrap());
1475                 for ent in dir_iter {
1476                     ret.push(ent.name());
1477 
1478                     // ====== 生成inode缓存,存入B树
1479                     let name: String = ent.name();
1480                     // kdebug!("name={name}");
1481 
1482                     if guard.children.contains_key(&name.to_uppercase()) == false
1483                         && name != "."
1484                         && name != ".."
1485                     {
1486                         // 创建新的inode
1487                         let entry_inode: Arc<LockedFATInode> = LockedFATInode::new(
1488                             guard.fs.upgrade().unwrap(),
1489                             guard.self_ref.clone(),
1490                             ent,
1491                         );
1492                         // 加入缓存区, 由于FAT文件系统的大小写不敏感问题,因此存入缓存区的key应当是全大写的
1493                         guard
1494                             .children
1495                             .insert(name.to_uppercase(), entry_inode.clone());
1496                     }
1497                 }
1498                 return Ok(ret);
1499             }
1500             FATDirEntry::UnInit => {
1501                 kerror!("FATFS: param: Inode_type uninitialized.");
1502                 return Err(SystemError::EROFS);
1503             }
1504         }
1505     }
1506 
1507     fn find(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError> {
1508         let mut guard: SpinLockGuard<FATInode> = self.0.lock();
1509         let target = guard.find(name)?;
1510         return Ok(target);
1511     }
1512 
1513     fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> {
1514         return Ok(());
1515     }
1516 
1517     fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
1518         return Ok(());
1519     }
1520 
1521     fn unlink(&self, name: &str) -> Result<(), SystemError> {
1522         let mut guard: SpinLockGuard<FATInode> = self.0.lock();
1523         let target: Arc<LockedFATInode> = guard.find(name)?;
1524         // 对目标inode上锁,以防更改
1525         let target_guard: SpinLockGuard<FATInode> = target.0.lock();
1526         // 先从缓存删除
1527         guard.children.remove(&name.to_uppercase());
1528 
1529         let dir = match &guard.inode_type {
1530             FATDirEntry::File(_) | FATDirEntry::VolId(_) => {
1531                 return Err(SystemError::ENOTDIR);
1532             }
1533             FATDirEntry::Dir(d) => d,
1534             FATDirEntry::UnInit => {
1535                 kerror!("FATFS: param: Inode_type uninitialized.");
1536                 return Err(SystemError::EROFS);
1537             }
1538         };
1539         // 检查文件是否存在
1540         dir.check_existence(name, Some(false), guard.fs.upgrade().unwrap())?;
1541 
1542         // 再从磁盘删除
1543         let r = dir.remove(guard.fs.upgrade().unwrap().clone(), name, true);
1544         drop(target_guard);
1545         return r;
1546     }
1547 
1548     fn rmdir(&self, name: &str) -> Result<(), SystemError> {
1549         let mut guard: SpinLockGuard<FATInode> = self.0.lock();
1550         let target: Arc<LockedFATInode> = guard.find(name)?;
1551         // 对目标inode上锁,以防更改
1552         let target_guard: SpinLockGuard<FATInode> = target.0.lock();
1553         // 先从缓存删除
1554         guard.children.remove(&name.to_uppercase());
1555 
1556         let dir = match &guard.inode_type {
1557             FATDirEntry::File(_) | FATDirEntry::VolId(_) => {
1558                 return Err(SystemError::ENOTDIR);
1559             }
1560             FATDirEntry::Dir(d) => d,
1561             FATDirEntry::UnInit => {
1562                 kerror!("FATFS: param: Inode_type uninitialized.");
1563                 return Err(SystemError::EROFS);
1564             }
1565         };
1566         // 检查文件夹是否存在
1567         dir.check_existence(name, Some(true), guard.fs.upgrade().unwrap())?;
1568 
1569         // 再从磁盘删除
1570         let r: Result<(), SystemError> =
1571             dir.remove(guard.fs.upgrade().unwrap().clone(), name, true);
1572         if r.is_ok() {
1573             return r;
1574         } else {
1575             let r = r.unwrap_err();
1576             if r == SystemError::ENOTEMPTY {
1577                 // 如果要删除的是目录,且不为空,则删除动作未发生,重新加入缓存
1578                 guard.children.insert(name.to_uppercase(), target.clone());
1579                 drop(target_guard);
1580             }
1581             return Err(r);
1582         }
1583     }
1584 
1585     fn get_entry_name(&self, ino: InodeId) -> Result<String, SystemError> {
1586         let guard: SpinLockGuard<FATInode> = self.0.lock();
1587         if guard.metadata.file_type != FileType::Dir {
1588             return Err(SystemError::ENOTDIR);
1589         }
1590         match ino {
1591             0 => {
1592                 return Ok(String::from("."));
1593             }
1594             1 => {
1595                 return Ok(String::from(".."));
1596             }
1597             ino => {
1598                 // 暴力遍历所有的children,判断inode id是否相同
1599                 // TODO: 优化这里,这个地方性能很差!
1600                 let mut key: Vec<String> = guard
1601                     .children
1602                     .keys()
1603                     .filter(|k| guard.children.get(*k).unwrap().metadata().unwrap().inode_id == ino)
1604                     .cloned()
1605                     .collect();
1606 
1607                 match key.len() {
1608                     0=>{return Err(SystemError::ENOENT);}
1609                     1=>{return Ok(key.remove(0));}
1610                     _ => panic!("FatFS get_entry_name: key.len()={key_len}>1, current inode_id={inode_id}, to find={to_find}", key_len=key.len(), inode_id = guard.metadata.inode_id, to_find=ino)
1611                 }
1612             }
1613         }
1614     }
1615 }
1616 
1617 impl Default for FATFsInfo {
1618     fn default() -> Self {
1619         return FATFsInfo {
1620             lead_sig: FATFsInfo::LEAD_SIG,
1621             struc_sig: FATFsInfo::STRUC_SIG,
1622             free_count: 0xFFFFFFFF,
1623             next_free: RESERVED_CLUSTERS,
1624             trail_sig: FATFsInfo::TRAIL_SIG,
1625             dirty: false,
1626             offset: None,
1627         };
1628     }
1629 }
1630 
1631 impl Cluster {
1632     pub fn new(cluster: u64) -> Self {
1633         return Cluster {
1634             cluster_num: cluster,
1635             parent_cluster: 0,
1636         };
1637     }
1638 }
1639 
1640 /// @brief 用于迭代FAT表的内容的簇迭代器对象
1641 #[derive(Debug)]
1642 struct ClusterIter<'a> {
1643     /// 迭代器的next要返回的簇
1644     current_cluster: Option<Cluster>,
1645     /// 属于的文件系统
1646     fs: &'a FATFileSystem,
1647 }
1648 
1649 impl<'a> Iterator for ClusterIter<'a> {
1650     type Item = Cluster;
1651 
1652     fn next(&mut self) -> Option<Self::Item> {
1653         // 当前要返回的簇
1654         let ret: Option<Cluster> = self.current_cluster;
1655 
1656         // 获得下一个要返回簇
1657         let new: Option<Cluster> = match self.current_cluster {
1658             Some(c) => {
1659                 let entry: Option<FATEntry> = self.fs.get_fat_entry(c).ok();
1660                 match entry {
1661                     Some(FATEntry::Next(c)) => Some(c),
1662                     _ => None,
1663                 }
1664             }
1665             _ => None,
1666         };
1667 
1668         self.current_cluster = new;
1669         return ret;
1670     }
1671 }
1672