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