xref: /DragonOS/kernel/src/filesystem/vfs/mount.rs (revision 173c4567cf4fb2276ef3f4614b69da7913fc8381)
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         // kdebug!("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