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