1 use core::{ 2 any::Any, 3 fmt::Debug, 4 sync::atomic::{compiler_fence, Ordering}, 5 }; 6 7 use alloc::{ 8 collections::BTreeMap, 9 string::{String, ToString}, 10 sync::{Arc, Weak}, 11 vec::Vec, 12 }; 13 use system_error::SystemError; 14 15 use crate::{ 16 driver::base::device::device_number::DeviceNumber, 17 filesystem::vfs::ROOT_INODE, 18 libs::{ 19 casting::DowncastArc, 20 rwlock::RwLock, 21 spinlock::{SpinLock, SpinLockGuard}, 22 }, 23 mm::{fault::PageFaultMessage, VmFaultReason}, 24 }; 25 26 use super::{ 27 file::{FileMode, PageCache}, 28 syscall::ModeType, 29 utils::DName, 30 FilePrivateData, FileSystem, FileType, IndexNode, InodeId, Magic, SuperBlock, 31 }; 32 33 const MOUNTFS_BLOCK_SIZE: u64 = 512; 34 const MOUNTFS_MAX_NAMELEN: u64 = 64; 35 /// @brief 挂载文件系统 36 /// 挂载文件系统的时候,套了MountFS这一层,以实现文件系统的递归挂载 37 #[derive(Debug)] 38 pub struct MountFS { 39 // MountFS内部的文件系统 40 inner_filesystem: Arc<dyn FileSystem>, 41 /// 用来存储InodeID->挂载点的MountFS的B树 42 mountpoints: SpinLock<BTreeMap<InodeId, Arc<MountFS>>>, 43 /// 当前文件系统挂载到的那个挂载点的Inode 44 self_mountpoint: Option<Arc<MountFSInode>>, 45 /// 指向当前MountFS的弱引用 46 self_ref: Weak<MountFS>, 47 } 48 49 /// @brief MountFS的Index Node 注意,这个IndexNode只是一个中间层。它的目的是将具体文件系统的Inode与挂载机制连接在一起。 50 #[derive(Debug)] 51 #[cast_to([sync] IndexNode)] 52 pub struct MountFSInode { 53 /// 当前挂载点对应到具体的文件系统的Inode 54 inner_inode: Arc<dyn IndexNode>, 55 /// 当前Inode对应的MountFS 56 mount_fs: Arc<MountFS>, 57 /// 指向自身的弱引用 58 self_ref: Weak<MountFSInode>, 59 } 60 61 impl MountFS { 62 pub fn new( 63 inner_filesystem: Arc<dyn FileSystem>, 64 self_mountpoint: Option<Arc<MountFSInode>>, 65 ) -> Arc<Self> { 66 return Arc::new_cyclic(|self_ref| MountFS { 67 inner_filesystem, 68 mountpoints: SpinLock::new(BTreeMap::new()), 69 self_mountpoint, 70 self_ref: self_ref.clone(), 71 }); 72 } 73 74 /// @brief 用Arc指针包裹MountFS对象。 75 /// 本函数的主要功能为,初始化MountFS对象中的自引用Weak指针 76 /// 本函数只应在构造器中被调用 77 #[allow(dead_code)] 78 #[deprecated] 79 fn wrap(self) -> Arc<Self> { 80 // 创建Arc指针 81 let mount_fs: Arc<MountFS> = Arc::new(self); 82 // 创建weak指针 83 let weak: Weak<MountFS> = Arc::downgrade(&mount_fs); 84 85 // 将Arc指针转为Raw指针并对其内部的self_ref字段赋值 86 let ptr: *mut MountFS = mount_fs.as_ref() as *const Self as *mut Self; 87 unsafe { 88 (*ptr).self_ref = weak; 89 // 返回初始化好的MountFS对象 90 return mount_fs; 91 } 92 } 93 94 /// @brief 获取挂载点的文件系统的root inode 95 pub fn mountpoint_root_inode(&self) -> Arc<MountFSInode> { 96 return Arc::new_cyclic(|self_ref| MountFSInode { 97 inner_inode: self.inner_filesystem.root_inode(), 98 mount_fs: self.self_ref.upgrade().unwrap(), 99 self_ref: self_ref.clone(), 100 }); 101 } 102 103 pub fn inner_filesystem(&self) -> Arc<dyn FileSystem> { 104 return self.inner_filesystem.clone(); 105 } 106 107 pub fn self_ref(&self) -> Arc<Self> { 108 self.self_ref.upgrade().unwrap() 109 } 110 111 /// 卸载文件系统 112 /// # Errors 113 /// 如果当前文件系统是根文件系统,那么将会返回`EINVAL` 114 pub fn umount(&self) -> Result<Arc<MountFS>, SystemError> { 115 self.self_mountpoint 116 .as_ref() 117 .ok_or(SystemError::EINVAL)? 118 .do_umount() 119 } 120 } 121 122 impl MountFSInode { 123 /// @brief 用Arc指针包裹MountFSInode对象。 124 /// 本函数的主要功能为,初始化MountFSInode对象中的自引用Weak指针 125 /// 本函数只应在构造器中被调用 126 #[allow(dead_code)] 127 #[deprecated] 128 fn wrap(self) -> Arc<Self> { 129 // 创建Arc指针 130 let inode: Arc<MountFSInode> = Arc::new(self); 131 // 创建Weak指针 132 let weak: Weak<MountFSInode> = Arc::downgrade(&inode); 133 // 将Arc指针转为Raw指针并对其内部的self_ref字段赋值 134 compiler_fence(Ordering::SeqCst); 135 let ptr: *mut MountFSInode = inode.as_ref() as *const Self as *mut Self; 136 compiler_fence(Ordering::SeqCst); 137 unsafe { 138 (*ptr).self_ref = weak; 139 compiler_fence(Ordering::SeqCst); 140 141 // 返回初始化好的MountFSInode对象 142 return inode; 143 } 144 } 145 146 /// @brief 判断当前inode是否为它所在的文件系统的root inode 147 fn is_mountpoint_root(&self) -> Result<bool, SystemError> { 148 return Ok(self.inner_inode.fs().root_inode().metadata()?.inode_id 149 == self.inner_inode.metadata()?.inode_id); 150 } 151 152 /// @brief 在挂载树上进行inode替换。 153 /// 如果当前inode是父MountFS内的一个挂载点,那么,本函数将会返回挂载到这个挂载点下的文件系统的root inode. 154 /// 如果当前inode在父MountFS内,但不是挂载点,那么说明在这里不需要进行inode替换,因此直接返回当前inode。 155 /// 156 /// @return Arc<MountFSInode> 157 fn overlaid_inode(&self) -> Arc<MountFSInode> { 158 let inode_id = self.metadata().unwrap().inode_id; 159 160 if let Some(sub_mountfs) = self.mount_fs.mountpoints.lock().get(&inode_id) { 161 return sub_mountfs.mountpoint_root_inode(); 162 } else { 163 return self.self_ref.upgrade().unwrap(); 164 } 165 } 166 167 fn do_find(&self, name: &str) -> Result<Arc<MountFSInode>, SystemError> { 168 // 直接调用当前inode所在的文件系统的find方法进行查找 169 // 由于向下查找可能会跨越文件系统的边界,因此需要尝试替换inode 170 let inner_inode = self.inner_inode.find(name)?; 171 return Ok(Arc::new_cyclic(|self_ref| MountFSInode { 172 inner_inode, 173 mount_fs: self.mount_fs.clone(), 174 self_ref: self_ref.clone(), 175 }) 176 .overlaid_inode()); 177 } 178 179 pub(super) fn do_parent(&self) -> Result<Arc<MountFSInode>, SystemError> { 180 if self.is_mountpoint_root()? { 181 // 当前inode是它所在的文件系统的root inode 182 match &self.mount_fs.self_mountpoint { 183 Some(inode) => { 184 let inner_inode = inode.parent()?; 185 return Ok(Arc::new_cyclic(|self_ref| MountFSInode { 186 inner_inode, 187 mount_fs: self.mount_fs.clone(), 188 self_ref: self_ref.clone(), 189 })); 190 } 191 None => { 192 return Ok(self.self_ref.upgrade().unwrap()); 193 } 194 } 195 } else { 196 let inner_inode = self.inner_inode.parent()?; 197 // 向上查找时,不会跨过文件系统的边界,因此直接调用当前inode所在的文件系统的find方法进行查找 198 return Ok(Arc::new_cyclic(|self_ref| MountFSInode { 199 inner_inode, 200 mount_fs: self.mount_fs.clone(), 201 self_ref: self_ref.clone(), 202 })); 203 } 204 } 205 206 /// 移除挂载点下的文件系统 207 fn do_umount(&self) -> Result<Arc<MountFS>, SystemError> { 208 if self.metadata()?.file_type != FileType::Dir { 209 return Err(SystemError::ENOTDIR); 210 } 211 return self 212 .mount_fs 213 .mountpoints 214 .lock() 215 .remove(&self.inner_inode.metadata()?.inode_id) 216 .ok_or(SystemError::ENOENT); 217 } 218 219 fn do_absolute_path(&self) -> Result<String, SystemError> { 220 let mut path_parts = Vec::new(); 221 let mut current = self.self_ref.upgrade().unwrap(); 222 223 while current.metadata()?.inode_id != ROOT_INODE().metadata()?.inode_id { 224 let name = current.dname()?; 225 path_parts.push(name.0); 226 current = current.do_parent()?; 227 } 228 229 // 由于我们从叶子节点向上遍历到根节点,所以需要反转路径部分 230 path_parts.reverse(); 231 232 // 构建最终的绝对路径字符串 233 let mut absolute_path = String::with_capacity( 234 path_parts.iter().map(|s| s.len()).sum::<usize>() + path_parts.len(), 235 ); 236 for part in path_parts { 237 absolute_path.push('/'); 238 absolute_path.push_str(&part); 239 } 240 241 Ok(absolute_path) 242 } 243 } 244 245 impl IndexNode for MountFSInode { 246 fn open( 247 &self, 248 data: SpinLockGuard<FilePrivateData>, 249 mode: &FileMode, 250 ) -> Result<(), SystemError> { 251 return self.inner_inode.open(data, mode); 252 } 253 254 fn close(&self, data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> { 255 return self.inner_inode.close(data); 256 } 257 258 fn create_with_data( 259 &self, 260 name: &str, 261 file_type: FileType, 262 mode: ModeType, 263 data: usize, 264 ) -> Result<Arc<dyn IndexNode>, SystemError> { 265 let inner_inode = self 266 .inner_inode 267 .create_with_data(name, file_type, mode, data)?; 268 return Ok(Arc::new_cyclic(|self_ref| MountFSInode { 269 inner_inode, 270 mount_fs: self.mount_fs.clone(), 271 self_ref: self_ref.clone(), 272 })); 273 } 274 275 fn truncate(&self, len: usize) -> Result<(), SystemError> { 276 return self.inner_inode.truncate(len); 277 } 278 279 fn read_at( 280 &self, 281 offset: usize, 282 len: usize, 283 buf: &mut [u8], 284 data: SpinLockGuard<FilePrivateData>, 285 ) -> Result<usize, SystemError> { 286 return self.inner_inode.read_at(offset, len, buf, data); 287 } 288 289 fn write_at( 290 &self, 291 offset: usize, 292 len: usize, 293 buf: &[u8], 294 data: SpinLockGuard<FilePrivateData>, 295 ) -> Result<usize, SystemError> { 296 return self.inner_inode.write_at(offset, len, buf, data); 297 } 298 299 #[inline] 300 fn fs(&self) -> Arc<dyn FileSystem> { 301 return self.mount_fs.clone(); 302 } 303 304 #[inline] 305 fn as_any_ref(&self) -> &dyn core::any::Any { 306 return self.inner_inode.as_any_ref(); 307 } 308 309 #[inline] 310 fn metadata(&self) -> Result<super::Metadata, SystemError> { 311 return self.inner_inode.metadata(); 312 } 313 314 #[inline] 315 fn set_metadata(&self, metadata: &super::Metadata) -> Result<(), SystemError> { 316 return self.inner_inode.set_metadata(metadata); 317 } 318 319 #[inline] 320 fn resize(&self, len: usize) -> Result<(), SystemError> { 321 return self.inner_inode.resize(len); 322 } 323 324 #[inline] 325 fn create( 326 &self, 327 name: &str, 328 file_type: FileType, 329 mode: ModeType, 330 ) -> Result<Arc<dyn IndexNode>, SystemError> { 331 let inner_inode = self.inner_inode.create(name, file_type, mode)?; 332 return Ok(Arc::new_cyclic(|self_ref| MountFSInode { 333 inner_inode, 334 mount_fs: self.mount_fs.clone(), 335 self_ref: self_ref.clone(), 336 })); 337 } 338 339 fn link(&self, name: &str, other: &Arc<dyn IndexNode>) -> Result<(), SystemError> { 340 return self.inner_inode.link(name, other); 341 } 342 343 /// @brief 在挂载文件系统中删除文件/文件夹 344 #[inline] 345 fn unlink(&self, name: &str) -> Result<(), SystemError> { 346 let inode_id = self.inner_inode.find(name)?.metadata()?.inode_id; 347 348 // 先检查这个inode是否为一个挂载点,如果当前inode是一个挂载点,那么就不能删除这个inode 349 if self.mount_fs.mountpoints.lock().contains_key(&inode_id) { 350 return Err(SystemError::EBUSY); 351 } 352 // 调用内层的inode的方法来删除这个inode 353 return self.inner_inode.unlink(name); 354 } 355 356 #[inline] 357 fn rmdir(&self, name: &str) -> Result<(), SystemError> { 358 let inode_id = self.inner_inode.find(name)?.metadata()?.inode_id; 359 360 // 先检查这个inode是否为一个挂载点,如果当前inode是一个挂载点,那么就不能删除这个inode 361 if self.mount_fs.mountpoints.lock().contains_key(&inode_id) { 362 return Err(SystemError::EBUSY); 363 } 364 // 调用内层的rmdir的方法来删除这个inode 365 let r = self.inner_inode.rmdir(name); 366 367 return r; 368 } 369 370 #[inline] 371 fn move_to( 372 &self, 373 old_name: &str, 374 target: &Arc<dyn IndexNode>, 375 new_name: &str, 376 ) -> Result<(), SystemError> { 377 return self.inner_inode.move_to(old_name, target, new_name); 378 } 379 380 fn find(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError> { 381 match name { 382 // 查找的是当前目录 383 "" | "." => self 384 .self_ref 385 .upgrade() 386 .map(|inode| inode as Arc<dyn IndexNode>) 387 .ok_or(SystemError::ENOENT), 388 // 往父级查找 389 ".." => self.parent(), 390 // 在当前目录下查找 391 // 直接调用当前inode所在的文件系统的find方法进行查找 392 // 由于向下查找可能会跨越文件系统的边界,因此需要尝试替换inode 393 _ => self.do_find(name).map(|inode| inode as Arc<dyn IndexNode>), 394 } 395 } 396 397 #[inline] 398 fn get_entry_name(&self, ino: InodeId) -> Result<alloc::string::String, SystemError> { 399 return self.inner_inode.get_entry_name(ino); 400 } 401 402 #[inline] 403 fn get_entry_name_and_metadata( 404 &self, 405 ino: InodeId, 406 ) -> Result<(alloc::string::String, super::Metadata), SystemError> { 407 return self.inner_inode.get_entry_name_and_metadata(ino); 408 } 409 410 #[inline] 411 fn ioctl( 412 &self, 413 cmd: u32, 414 data: usize, 415 private_data: &FilePrivateData, 416 ) -> Result<usize, SystemError> { 417 return self.inner_inode.ioctl(cmd, data, private_data); 418 } 419 420 #[inline] 421 fn kernel_ioctl( 422 &self, 423 arg: Arc<dyn crate::net::event_poll::KernelIoctlData>, 424 data: &FilePrivateData, 425 ) -> Result<usize, SystemError> { 426 return self.inner_inode.kernel_ioctl(arg, data); 427 } 428 429 #[inline] 430 fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, SystemError> { 431 return self.inner_inode.list(); 432 } 433 434 fn mount(&self, fs: Arc<dyn FileSystem>) -> Result<Arc<MountFS>, SystemError> { 435 let metadata = self.inner_inode.metadata()?; 436 if metadata.file_type != FileType::Dir { 437 return Err(SystemError::ENOTDIR); 438 } 439 440 if self.is_mountpoint_root()? { 441 return Err(SystemError::EBUSY); 442 } 443 444 // 若已有挂载系统,保证MountFS只包一层 445 let to_mount_fs = fs 446 .clone() 447 .downcast_arc::<MountFS>() 448 .map(|it| it.inner_filesystem()) 449 .unwrap_or(fs); 450 let new_mount_fs = MountFS::new(to_mount_fs, Some(self.self_ref.upgrade().unwrap())); 451 self.mount_fs 452 .mountpoints 453 .lock() 454 .insert(metadata.inode_id, new_mount_fs.clone()); 455 456 let mount_path = self.absolute_path(); 457 458 MOUNT_LIST().insert(mount_path?, new_mount_fs.clone()); 459 return Ok(new_mount_fs); 460 } 461 462 fn mount_from(&self, from: Arc<dyn IndexNode>) -> Result<Arc<MountFS>, SystemError> { 463 let metadata = self.metadata()?; 464 if from.metadata()?.file_type != FileType::Dir || metadata.file_type != FileType::Dir { 465 return Err(SystemError::ENOTDIR); 466 } 467 if self.is_mountpoint_root()? { 468 return Err(SystemError::EBUSY); 469 } 470 // debug!("from {:?}, to {:?}", from, self); 471 let new_mount_fs = from.umount()?; 472 self.mount_fs 473 .mountpoints 474 .lock() 475 .insert(metadata.inode_id, new_mount_fs.clone()); 476 477 // MOUNT_LIST().remove(from.absolute_path()?); 478 // MOUNT_LIST().insert(self.absolute_path()?, new_mount_fs.clone()); 479 return Ok(new_mount_fs); 480 } 481 482 fn umount(&self) -> Result<Arc<MountFS>, SystemError> { 483 if !self.is_mountpoint_root()? { 484 return Err(SystemError::EINVAL); 485 } 486 return self.mount_fs.umount(); 487 } 488 489 fn absolute_path(&self) -> Result<String, SystemError> { 490 self.do_absolute_path() 491 } 492 493 #[inline] 494 fn mknod( 495 &self, 496 filename: &str, 497 mode: ModeType, 498 dev_t: DeviceNumber, 499 ) -> Result<Arc<dyn IndexNode>, SystemError> { 500 let inner_inode = self.inner_inode.mknod(filename, mode, dev_t)?; 501 return Ok(Arc::new_cyclic(|self_ref| MountFSInode { 502 inner_inode, 503 mount_fs: self.mount_fs.clone(), 504 self_ref: self_ref.clone(), 505 })); 506 } 507 508 #[inline] 509 fn special_node(&self) -> Option<super::SpecialNodeData> { 510 self.inner_inode.special_node() 511 } 512 513 #[inline] 514 fn poll(&self, private_data: &FilePrivateData) -> Result<usize, SystemError> { 515 self.inner_inode.poll(private_data) 516 } 517 518 /// 若不支持,则调用第二种情况来从父目录获取文件名 519 /// # Performance 520 /// 应尽可能引入DName, 521 /// 在默认情况下,性能非常差!!! 522 fn dname(&self) -> Result<DName, SystemError> { 523 if self.is_mountpoint_root()? { 524 if let Some(inode) = &self.mount_fs.self_mountpoint { 525 return inode.inner_inode.dname(); 526 } 527 } 528 return self.inner_inode.dname(); 529 } 530 531 fn parent(&self) -> Result<Arc<dyn IndexNode>, SystemError> { 532 return self.do_parent().map(|inode| inode as Arc<dyn IndexNode>); 533 } 534 535 fn page_cache(&self) -> Option<Arc<PageCache>> { 536 self.inner_inode.page_cache() 537 } 538 } 539 540 impl FileSystem for MountFS { 541 fn root_inode(&self) -> Arc<dyn IndexNode> { 542 match &self.self_mountpoint { 543 Some(inode) => return inode.mount_fs.root_inode(), 544 // 当前文件系统是rootfs 545 None => self.mountpoint_root_inode(), 546 } 547 } 548 549 fn info(&self) -> super::FsInfo { 550 return self.inner_filesystem.info(); 551 } 552 553 /// @brief 本函数用于实现动态转换。 554 /// 具体的文件系统在实现本函数时,最简单的方式就是:直接返回self 555 fn as_any_ref(&self) -> &dyn Any { 556 self 557 } 558 559 fn name(&self) -> &str { 560 "mountfs" 561 } 562 fn super_block(&self) -> SuperBlock { 563 SuperBlock::new(Magic::MOUNT_MAGIC, MOUNTFS_BLOCK_SIZE, MOUNTFS_MAX_NAMELEN) 564 } 565 566 unsafe fn fault(&self, pfm: &mut PageFaultMessage) -> VmFaultReason { 567 self.inner_filesystem.fault(pfm) 568 } 569 570 unsafe fn map_pages( 571 &self, 572 pfm: &mut PageFaultMessage, 573 start_pgoff: usize, 574 end_pgoff: usize, 575 ) -> VmFaultReason { 576 self.inner_filesystem.map_pages(pfm, start_pgoff, end_pgoff) 577 } 578 } 579 580 /// MountList 581 /// ```rust 582 /// use alloc::collection::BTreeSet; 583 /// let map = BTreeSet::from([ 584 /// "/sys", "/dev", "/", "/bin", "/proc" 585 /// ]); 586 /// assert_eq!(format!("{:?}", map), "{\"/\", \"/bin\", \"/dev\", \"/proc\", \"/sys\"}"); 587 /// // {"/", "/bin", "/dev", "/proc", "/sys"} 588 /// ``` 589 #[derive(PartialEq, Eq, Debug)] 590 pub struct MountPath(String); 591 592 impl From<&str> for MountPath { 593 fn from(value: &str) -> Self { 594 Self(String::from(value)) 595 } 596 } 597 598 impl From<String> for MountPath { 599 fn from(value: String) -> Self { 600 Self(value) 601 } 602 } 603 604 impl AsRef<str> for MountPath { 605 fn as_ref(&self) -> &str { 606 &self.0 607 } 608 } 609 610 impl PartialOrd for MountPath { 611 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> { 612 Some(self.cmp(other)) 613 } 614 } 615 616 impl Ord for MountPath { 617 fn cmp(&self, other: &Self) -> core::cmp::Ordering { 618 let self_dep = self.0.chars().filter(|c| *c == '/').count(); 619 let othe_dep = other.0.chars().filter(|c| *c == '/').count(); 620 if self_dep == othe_dep { 621 // 深度一样时反序来排 622 // 根目录和根目录下的文件的绝对路径都只有一个'/' 623 other.0.cmp(&self.0) 624 } else { 625 // 根据深度,深度 626 othe_dep.cmp(&self_dep) 627 } 628 } 629 } 630 631 // 维护一个挂载点的记录,以支持特定于文件系统的索引 632 pub struct MountList(RwLock<BTreeMap<MountPath, Arc<MountFS>>>); 633 // pub struct MountList(Option<Arc<MountListInner>>); 634 static mut __MOUNTS_LIST: Option<Arc<MountList>> = None; 635 636 /// # init_mountlist - 初始化挂载列表 637 /// 638 /// 此函数用于初始化系统的挂载列表。挂载列表记录了系统中所有的文件系统挂载点及其属性。 639 /// 640 /// ## 参数 641 /// 642 /// - 无 643 /// 644 /// ## 返回值 645 /// 646 /// - 无 647 #[inline(always)] 648 pub fn init_mountlist() { 649 unsafe { 650 __MOUNTS_LIST = Some(Arc::new(MountList(RwLock::new(BTreeMap::new())))); 651 } 652 } 653 654 /// # MOUNT_LIST - 获取全局挂载列表 655 /// 656 /// 该函数用于获取一个对全局挂载列表的引用。全局挂载列表是系统中所有挂载点的集合。 657 /// 658 /// ## 返回值 659 /// - &'static Arc<MountList>: 返回全局挂载列表的引用。 660 #[inline(always)] 661 #[allow(non_snake_case)] 662 pub fn MOUNT_LIST() -> &'static Arc<MountList> { 663 unsafe { 664 return __MOUNTS_LIST.as_ref().unwrap(); 665 } 666 } 667 668 impl MountList { 669 /// # insert - 将文件系统挂载点插入到挂载表中 670 /// 671 /// 将一个新的文件系统挂载点插入到挂载表中。如果挂载点已经存在,则会更新对应的文件系统。 672 /// 673 /// 此函数是线程安全的,因为它使用了RwLock来保证并发访问。 674 /// 675 /// ## 参数 676 /// 677 /// - `path`: &str, 挂载点的路径。这个路径会被转换成`MountPath`类型。 678 /// - `fs`: Arc<MountFS>, 共享的文件系统实例。 679 /// 680 /// ## 返回值 681 /// 682 /// - 无 683 #[inline] 684 pub fn insert<T: AsRef<str>>(&self, path: T, fs: Arc<MountFS>) { 685 self.0.write().insert(MountPath::from(path.as_ref()), fs); 686 } 687 688 /// # get_mount_point - 获取挂载点的路径 689 /// 690 /// 这个函数用于查找给定路径的挂载点。它搜索一个内部映射,找到与路径匹配的挂载点。 691 /// 692 /// ## 参数 693 /// 694 /// - `path: T`: 这是一个可转换为字符串的引用,表示要查找其挂载点的路径。 695 /// 696 /// ## 返回值 697 /// 698 /// - `Option<(String, String, Arc<MountFS>)>`: 699 /// - `Some((mount_point, rest_path, fs))`: 如果找到了匹配的挂载点,返回一个包含挂载点路径、剩余路径和挂载文件系统的元组。 700 /// - `None`: 如果没有找到匹配的挂载点,返回 None。 701 #[inline] 702 #[allow(dead_code)] 703 pub fn get_mount_point<T: AsRef<str>>( 704 &self, 705 path: T, 706 ) -> Option<(String, String, Arc<MountFS>)> { 707 self.0 708 .upgradeable_read() 709 .iter() 710 .filter_map(|(key, fs)| { 711 let strkey = key.as_ref(); 712 if let Some(rest) = path.as_ref().strip_prefix(strkey) { 713 return Some((strkey.to_string(), rest.to_string(), fs.clone())); 714 } 715 None 716 }) 717 .next() 718 } 719 720 /// # remove - 移除挂载点 721 /// 722 /// 从挂载点管理器中移除一个挂载点。 723 /// 724 /// 此函数用于从挂载点管理器中移除一个已经存在的挂载点。如果挂载点不存在,则不进行任何操作。 725 /// 726 /// ## 参数 727 /// 728 /// - `path: T`: `T` 实现了 `Into<MountPath>` trait,代表要移除的挂载点的路径。 729 /// 730 /// ## 返回值 731 /// 732 /// - `Option<Arc<MountFS>>`: 返回一个 `Arc<MountFS>` 类型的可选值,表示被移除的挂载点,如果挂载点不存在则返回 `None`。 733 #[inline] 734 pub fn remove<T: Into<MountPath>>(&self, path: T) -> Option<Arc<MountFS>> { 735 self.0.write().remove(&path.into()) 736 } 737 } 738 739 impl Debug for MountList { 740 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 741 f.debug_map().entries(MOUNT_LIST().0.read().iter()).finish() 742 } 743 } 744