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