xref: /DragonOS/kernel/src/filesystem/vfs/mount.rs (revision cf7f801e1d50ee5b04cb728e4251a57f4183bfbc)
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 {
new( inner_filesystem: Arc<dyn FileSystem>, self_mountpoint: Option<Arc<MountFSInode>>, ) -> Arc<Self>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]
wrap(self) -> Arc<Self>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
mountpoint_root_inode(&self) -> Arc<MountFSInode>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 
inner_filesystem(&self) -> Arc<dyn FileSystem>102     pub fn inner_filesystem(&self) -> Arc<dyn FileSystem> {
103         return self.inner_filesystem.clone();
104     }
105 
self_ref(&self) -> Arc<Self>106     pub fn self_ref(&self) -> Arc<Self> {
107         self.self_ref.upgrade().unwrap()
108     }
109 
110     /// 卸载文件系统
111     /// # Errors
112     /// 如果当前文件系统是根文件系统,那么将会返回`EINVAL`
umount(&self) -> Result<Arc<MountFS>, SystemError>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]
wrap(self) -> Arc<Self>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
is_mountpoint_root(&self) -> Result<bool, SystemError>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>
overlaid_inode(&self) -> 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 
do_find(&self, name: &str) -> Result<Arc<MountFSInode>, SystemError>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 
do_parent(&self) -> Result<Arc<MountFSInode>, SystemError>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     /// 移除挂载点下的文件系统
do_umount(&self) -> Result<Arc<MountFS>, SystemError>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 
do_absolute_path(&self, len: usize) -> Result<String, SystemError>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 {
open( &self, data: SpinLockGuard<FilePrivateData>, mode: &FileMode, ) -> Result<(), SystemError>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 
close(&self, data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError>236     fn close(&self, data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
237         return self.inner_inode.close(data);
238     }
239 
create_with_data( &self, name: &str, file_type: FileType, mode: ModeType, data: usize, ) -> Result<Arc<dyn IndexNode>, SystemError>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 
truncate(&self, len: usize) -> Result<(), SystemError>257     fn truncate(&self, len: usize) -> Result<(), SystemError> {
258         return self.inner_inode.truncate(len);
259     }
260 
read_at( &self, offset: usize, len: usize, buf: &mut [u8], data: SpinLockGuard<FilePrivateData>, ) -> Result<usize, SystemError>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 
write_at( &self, offset: usize, len: usize, buf: &[u8], data: SpinLockGuard<FilePrivateData>, ) -> Result<usize, SystemError>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]
fs(&self) -> Arc<dyn FileSystem>282     fn fs(&self) -> Arc<dyn FileSystem> {
283         return self.mount_fs.clone();
284     }
285 
286     #[inline]
as_any_ref(&self) -> &dyn core::any::Any287     fn as_any_ref(&self) -> &dyn core::any::Any {
288         return self.inner_inode.as_any_ref();
289     }
290 
291     #[inline]
metadata(&self) -> Result<super::Metadata, SystemError>292     fn metadata(&self) -> Result<super::Metadata, SystemError> {
293         return self.inner_inode.metadata();
294     }
295 
296     #[inline]
set_metadata(&self, metadata: &super::Metadata) -> Result<(), SystemError>297     fn set_metadata(&self, metadata: &super::Metadata) -> Result<(), SystemError> {
298         return self.inner_inode.set_metadata(metadata);
299     }
300 
301     #[inline]
resize(&self, len: usize) -> Result<(), SystemError>302     fn resize(&self, len: usize) -> Result<(), SystemError> {
303         return self.inner_inode.resize(len);
304     }
305 
306     #[inline]
create( &self, name: &str, file_type: FileType, mode: ModeType, ) -> Result<Arc<dyn IndexNode>, SystemError>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 
link(&self, name: &str, other: &Arc<dyn IndexNode>) -> Result<(), SystemError>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]
unlink(&self, name: &str) -> Result<(), SystemError>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]
rmdir(&self, name: &str) -> Result<(), SystemError>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]
move_to( &self, old_name: &str, target: &Arc<dyn IndexNode>, new_name: &str, ) -> Result<(), SystemError>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 
find(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError>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]
get_entry_name(&self, ino: InodeId) -> Result<alloc::string::String, SystemError>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]
get_entry_name_and_metadata( &self, ino: InodeId, ) -> Result<(alloc::string::String, super::Metadata), SystemError>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]
ioctl( &self, cmd: u32, data: usize, private_data: &FilePrivateData, ) -> Result<usize, SystemError>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]
list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, SystemError>403     fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, SystemError> {
404         return self.inner_inode.list();
405     }
406 
mount(&self, fs: Arc<dyn FileSystem>) -> Result<Arc<MountFS>, SystemError>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 
mount_from(&self, from: Arc<dyn IndexNode>) -> Result<Arc<MountFS>, SystemError>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 
umount(&self) -> Result<Arc<MountFS>, SystemError>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 
absolute_path(&self) -> Result<String, SystemError>462     fn absolute_path(&self) -> Result<String, SystemError> {
463         self.do_absolute_path(0)
464     }
465 
466     #[inline]
mknod( &self, filename: &str, mode: ModeType, dev_t: DeviceNumber, ) -> Result<Arc<dyn IndexNode>, SystemError>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]
special_node(&self) -> Option<super::SpecialNodeData>482     fn special_node(&self) -> Option<super::SpecialNodeData> {
483         self.inner_inode.special_node()
484     }
485 
486     #[inline]
poll(&self, private_data: &FilePrivateData) -> Result<usize, SystemError>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     /// 在默认情况下,性能非常差!!!
dname(&self) -> Result<DName, SystemError>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 
parent(&self) -> Result<Arc<dyn IndexNode>, SystemError>504     fn parent(&self) -> Result<Arc<dyn IndexNode>, SystemError> {
505         return self.do_parent().map(|inode| inode as Arc<dyn IndexNode>);
506     }
507 
page_cache(&self) -> Option<Arc<PageCache>>508     fn page_cache(&self) -> Option<Arc<PageCache>> {
509         self.inner_inode.page_cache()
510     }
511 }
512 
513 impl FileSystem for MountFS {
root_inode(&self) -> Arc<dyn IndexNode>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 
info(&self) -> super::FsInfo522     fn info(&self) -> super::FsInfo {
523         return self.inner_filesystem.info();
524     }
525 
526     /// @brief 本函数用于实现动态转换。
527     /// 具体的文件系统在实现本函数时,最简单的方式就是:直接返回self
as_any_ref(&self) -> &dyn Any528     fn as_any_ref(&self) -> &dyn Any {
529         self
530     }
531 
name(&self) -> &str532     fn name(&self) -> &str {
533         "mountfs"
534     }
super_block(&self) -> SuperBlock535     fn super_block(&self) -> SuperBlock {
536         SuperBlock::new(Magic::MOUNT_MAGIC, MOUNTFS_BLOCK_SIZE, MOUNTFS_MAX_NAMELEN)
537     }
538 
fault(&self, pfm: &mut PageFaultMessage) -> VmFaultReason539     unsafe fn fault(&self, pfm: &mut PageFaultMessage) -> VmFaultReason {
540         self.inner_filesystem.fault(pfm)
541     }
542 
map_pages( &self, pfm: &mut PageFaultMessage, start_pgoff: usize, end_pgoff: usize, ) -> VmFaultReason543     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 {
from(value: &str) -> Self566     fn from(value: &str) -> Self {
567         Self(String::from(value))
568     }
569 }
570 
571 impl From<String> for MountPath {
from(value: String) -> Self572     fn from(value: String) -> Self {
573         Self(value)
574     }
575 }
576 
577 impl AsRef<str> for MountPath {
as_ref(&self) -> &str578     fn as_ref(&self) -> &str {
579         &self.0
580     }
581 }
582 
583 impl PartialOrd for MountPath {
partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering>584     fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
585         Some(self.cmp(other))
586     }
587 }
588 
589 impl Ord for MountPath {
cmp(&self, other: &Self) -> core::cmp::Ordering590     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)]
init_mountlist()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)]
MOUNT_LIST() -> &'static Arc<MountList>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]
insert<T: AsRef<str>>(&self, path: T, fs: Arc<MountFS>)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)]
get_mount_point<T: AsRef<str>>( &self, path: T, ) -> Option<(String, String, Arc<MountFS>)>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]
remove<T: Into<MountPath>>(&self, path: T) -> Option<Arc<MountFS>>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 {
fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result713     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