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