xref: /DragonOS/kernel/src/filesystem/vfs/mount.rs (revision 2eab6dd743e94a86a685f1f3c01e599adf86610a)
11496ba7bSLoGin use core::{
21496ba7bSLoGin     any::Any,
31074eb34SSamuel Dai     fmt::Debug,
41496ba7bSLoGin     sync::atomic::{compiler_fence, Ordering},
51496ba7bSLoGin };
6004e86ffSlogin 
7004e86ffSlogin use alloc::{
8004e86ffSlogin     collections::BTreeMap,
91074eb34SSamuel Dai     string::{String, ToString},
10004e86ffSlogin     sync::{Arc, Weak},
11004e86ffSlogin };
1291e9d4abSLoGin use system_error::SystemError;
13004e86ffSlogin 
14dfe53cf0SGnoCiYeH use crate::{
15dfe53cf0SGnoCiYeH     driver::base::device::device_number::DeviceNumber,
161074eb34SSamuel Dai     filesystem::vfs::ROOT_INODE,
171074eb34SSamuel Dai     libs::{
181074eb34SSamuel Dai         casting::DowncastArc,
191074eb34SSamuel Dai         rwlock::RwLock,
201074eb34SSamuel Dai         spinlock::{SpinLock, SpinLockGuard},
211074eb34SSamuel Dai     },
22dfe53cf0SGnoCiYeH };
23004e86ffSlogin 
246b4e7a29SLoGin use super::{
251074eb34SSamuel Dai     file::FileMode, syscall::ModeType, utils::DName, FilePrivateData, FileSystem, FileType,
261074eb34SSamuel Dai     IndexNode, InodeId, Magic, SuperBlock,
276b4e7a29SLoGin };
28004e86ffSlogin 
29597ecc08STTaq const MOUNTFS_BLOCK_SIZE: u64 = 512;
30597ecc08STTaq const MOUNTFS_MAX_NAMELEN: u64 = 64;
31004e86ffSlogin /// @brief 挂载文件系统
32004e86ffSlogin /// 挂载文件系统的时候,套了MountFS这一层,以实现文件系统的递归挂载
33004e86ffSlogin #[derive(Debug)]
34004e86ffSlogin pub struct MountFS {
35004e86ffSlogin     // MountFS内部的文件系统
36004e86ffSlogin     inner_filesystem: Arc<dyn FileSystem>,
37004e86ffSlogin     /// 用来存储InodeID->挂载点的MountFS的B树
38004e86ffSlogin     mountpoints: SpinLock<BTreeMap<InodeId, Arc<MountFS>>>,
39004e86ffSlogin     /// 当前文件系统挂载到的那个挂载点的Inode
40004e86ffSlogin     self_mountpoint: Option<Arc<MountFSInode>>,
41004e86ffSlogin     /// 指向当前MountFS的弱引用
42004e86ffSlogin     self_ref: Weak<MountFS>,
43004e86ffSlogin }
44004e86ffSlogin 
45004e86ffSlogin /// @brief MountFS的Index Node 注意,这个IndexNode只是一个中间层。它的目的是将具体文件系统的Inode与挂载机制连接在一起。
46004e86ffSlogin #[derive(Debug)]
47dfe53cf0SGnoCiYeH #[cast_to([sync] IndexNode)]
48004e86ffSlogin pub struct MountFSInode {
49004e86ffSlogin     /// 当前挂载点对应到具体的文件系统的Inode
50004e86ffSlogin     inner_inode: Arc<dyn IndexNode>,
51004e86ffSlogin     /// 当前Inode对应的MountFS
52004e86ffSlogin     mount_fs: Arc<MountFS>,
53004e86ffSlogin     /// 指向自身的弱引用
54004e86ffSlogin     self_ref: Weak<MountFSInode>,
55004e86ffSlogin }
56004e86ffSlogin 
57004e86ffSlogin impl MountFS {
58004e86ffSlogin     pub fn new(
591074eb34SSamuel Dai         inner_filesystem: Arc<dyn FileSystem>,
60004e86ffSlogin         self_mountpoint: Option<Arc<MountFSInode>>,
61004e86ffSlogin     ) -> Arc<Self> {
621074eb34SSamuel Dai         return Arc::new_cyclic(|self_ref| MountFS {
631074eb34SSamuel Dai             inner_filesystem,
64004e86ffSlogin             mountpoints: SpinLock::new(BTreeMap::new()),
65b5b571e0SLoGin             self_mountpoint,
661074eb34SSamuel Dai             self_ref: self_ref.clone(),
671074eb34SSamuel Dai         });
68004e86ffSlogin     }
69004e86ffSlogin 
70004e86ffSlogin     /// @brief 用Arc指针包裹MountFS对象。
71004e86ffSlogin     /// 本函数的主要功能为,初始化MountFS对象中的自引用Weak指针
72004e86ffSlogin     /// 本函数只应在构造器中被调用
731074eb34SSamuel Dai     #[allow(dead_code)]
741074eb34SSamuel Dai     #[deprecated]
75004e86ffSlogin     fn wrap(self) -> Arc<Self> {
76004e86ffSlogin         // 创建Arc指针
77004e86ffSlogin         let mount_fs: Arc<MountFS> = Arc::new(self);
78004e86ffSlogin         // 创建weak指针
79004e86ffSlogin         let weak: Weak<MountFS> = Arc::downgrade(&mount_fs);
80004e86ffSlogin 
81004e86ffSlogin         // 将Arc指针转为Raw指针并对其内部的self_ref字段赋值
8234e6d6c8Syuyi2439         let ptr: *mut MountFS = mount_fs.as_ref() as *const Self as *mut Self;
83004e86ffSlogin         unsafe {
84004e86ffSlogin             (*ptr).self_ref = weak;
85004e86ffSlogin             // 返回初始化好的MountFS对象
8634e6d6c8Syuyi2439             return mount_fs;
87004e86ffSlogin         }
88004e86ffSlogin     }
89004e86ffSlogin 
90004e86ffSlogin     /// @brief 获取挂载点的文件系统的root inode
91004e86ffSlogin     pub fn mountpoint_root_inode(&self) -> Arc<MountFSInode> {
921074eb34SSamuel Dai         return Arc::new_cyclic(|self_ref| MountFSInode {
93004e86ffSlogin             inner_inode: self.inner_filesystem.root_inode(),
94004e86ffSlogin             mount_fs: self.self_ref.upgrade().unwrap(),
951074eb34SSamuel Dai             self_ref: self_ref.clone(),
961074eb34SSamuel Dai         });
97004e86ffSlogin     }
98004e86ffSlogin 
99004e86ffSlogin     pub fn inner_filesystem(&self) -> Arc<dyn FileSystem> {
100004e86ffSlogin         return self.inner_filesystem.clone();
101004e86ffSlogin     }
102dfe53cf0SGnoCiYeH 
103dfe53cf0SGnoCiYeH     pub fn self_ref(&self) -> Arc<Self> {
104dfe53cf0SGnoCiYeH         self.self_ref.upgrade().unwrap()
105dfe53cf0SGnoCiYeH     }
1061074eb34SSamuel Dai 
1071074eb34SSamuel Dai     /// 卸载文件系统
1081074eb34SSamuel Dai     /// # Errors
1091074eb34SSamuel Dai     /// 如果当前文件系统是根文件系统,那么将会返回`EINVAL`
1101074eb34SSamuel Dai     pub fn umount(&self) -> Result<Arc<MountFS>, SystemError> {
1111074eb34SSamuel Dai         self.self_mountpoint
1121074eb34SSamuel Dai             .as_ref()
1131074eb34SSamuel Dai             .ok_or(SystemError::EINVAL)?
1141074eb34SSamuel Dai             .do_umount()
1151074eb34SSamuel Dai     }
116004e86ffSlogin }
117004e86ffSlogin 
118004e86ffSlogin impl MountFSInode {
119004e86ffSlogin     /// @brief 用Arc指针包裹MountFSInode对象。
120004e86ffSlogin     /// 本函数的主要功能为,初始化MountFSInode对象中的自引用Weak指针
121004e86ffSlogin     /// 本函数只应在构造器中被调用
1221074eb34SSamuel Dai     #[allow(dead_code)]
1231074eb34SSamuel Dai     #[deprecated]
124004e86ffSlogin     fn wrap(self) -> Arc<Self> {
125004e86ffSlogin         // 创建Arc指针
126004e86ffSlogin         let inode: Arc<MountFSInode> = Arc::new(self);
127004e86ffSlogin         // 创建Weak指针
128004e86ffSlogin         let weak: Weak<MountFSInode> = Arc::downgrade(&inode);
129004e86ffSlogin         // 将Arc指针转为Raw指针并对其内部的self_ref字段赋值
1301496ba7bSLoGin         compiler_fence(Ordering::SeqCst);
13134e6d6c8Syuyi2439         let ptr: *mut MountFSInode = inode.as_ref() as *const Self as *mut Self;
1321496ba7bSLoGin         compiler_fence(Ordering::SeqCst);
133004e86ffSlogin         unsafe {
134004e86ffSlogin             (*ptr).self_ref = weak;
1351496ba7bSLoGin             compiler_fence(Ordering::SeqCst);
136004e86ffSlogin 
137004e86ffSlogin             // 返回初始化好的MountFSInode对象
1381496ba7bSLoGin             return inode;
139004e86ffSlogin         }
140004e86ffSlogin     }
141004e86ffSlogin 
142004e86ffSlogin     /// @brief 判断当前inode是否为它所在的文件系统的root inode
143676b8ef6SMork     fn is_mountpoint_root(&self) -> Result<bool, SystemError> {
144004e86ffSlogin         return Ok(self.inner_inode.fs().root_inode().metadata()?.inode_id
145004e86ffSlogin             == self.inner_inode.metadata()?.inode_id);
146004e86ffSlogin     }
147004e86ffSlogin 
148004e86ffSlogin     /// @brief 在挂载树上进行inode替换。
149004e86ffSlogin     /// 如果当前inode是父MountFS内的一个挂载点,那么,本函数将会返回挂载到这个挂载点下的文件系统的root inode.
150004e86ffSlogin     /// 如果当前inode在父MountFS内,但不是挂载点,那么说明在这里不需要进行inode替换,因此直接返回当前inode。
151004e86ffSlogin     ///
152004e86ffSlogin     /// @return Arc<MountFSInode>
153004e86ffSlogin     fn overlaid_inode(&self) -> Arc<MountFSInode> {
154004e86ffSlogin         let inode_id = self.metadata().unwrap().inode_id;
155004e86ffSlogin 
156004e86ffSlogin         if let Some(sub_mountfs) = self.mount_fs.mountpoints.lock().get(&inode_id) {
157004e86ffSlogin             return sub_mountfs.mountpoint_root_inode();
158004e86ffSlogin         } else {
159004e86ffSlogin             return self.self_ref.upgrade().unwrap();
160004e86ffSlogin         }
161004e86ffSlogin     }
162dfe53cf0SGnoCiYeH 
163dfe53cf0SGnoCiYeH     /// 将新的挂载点-挂载文件系统添加到父级的挂载树
164dfe53cf0SGnoCiYeH     pub(super) fn do_mount(
165dfe53cf0SGnoCiYeH         &self,
166dfe53cf0SGnoCiYeH         inode_id: InodeId,
167dfe53cf0SGnoCiYeH         new_mount_fs: Arc<MountFS>,
168dfe53cf0SGnoCiYeH     ) -> Result<(), SystemError> {
169dfe53cf0SGnoCiYeH         let mut guard = self.mount_fs.mountpoints.lock();
170dfe53cf0SGnoCiYeH         if guard.contains_key(&inode_id) {
171dfe53cf0SGnoCiYeH             return Err(SystemError::EBUSY);
172dfe53cf0SGnoCiYeH         }
173dfe53cf0SGnoCiYeH         guard.insert(inode_id, new_mount_fs);
174dfe53cf0SGnoCiYeH 
175dfe53cf0SGnoCiYeH         return Ok(());
176dfe53cf0SGnoCiYeH     }
177dfe53cf0SGnoCiYeH 
178dfe53cf0SGnoCiYeH     pub(super) fn inode_id(&self) -> InodeId {
179dfe53cf0SGnoCiYeH         self.metadata().map(|x| x.inode_id).unwrap()
180dfe53cf0SGnoCiYeH     }
1811074eb34SSamuel Dai 
1821074eb34SSamuel Dai     fn do_find(&self, name: &str) -> Result<Arc<MountFSInode>, SystemError> {
1831074eb34SSamuel Dai         // 直接调用当前inode所在的文件系统的find方法进行查找
1841074eb34SSamuel Dai         // 由于向下查找可能会跨越文件系统的边界,因此需要尝试替换inode
1851074eb34SSamuel Dai         let inner_inode = self.inner_inode.find(name)?;
1861074eb34SSamuel Dai         return Ok(Arc::new_cyclic(|self_ref| MountFSInode {
1871074eb34SSamuel Dai             inner_inode,
1881074eb34SSamuel Dai             mount_fs: self.mount_fs.clone(),
1891074eb34SSamuel Dai             self_ref: self_ref.clone(),
1901074eb34SSamuel Dai         })
1911074eb34SSamuel Dai         .overlaid_inode());
1921074eb34SSamuel Dai     }
1931074eb34SSamuel Dai 
1941074eb34SSamuel Dai     pub(super) fn do_parent(&self) -> Result<Arc<MountFSInode>, SystemError> {
1951074eb34SSamuel Dai         if self.is_mountpoint_root()? {
1961074eb34SSamuel Dai             // 当前inode是它所在的文件系统的root inode
1971074eb34SSamuel Dai             match &self.mount_fs.self_mountpoint {
1981074eb34SSamuel Dai                 Some(inode) => {
1991074eb34SSamuel Dai                     let inner_inode = inode.parent()?;
2001074eb34SSamuel Dai                     return Ok(Arc::new_cyclic(|self_ref| MountFSInode {
2011074eb34SSamuel Dai                         inner_inode,
2021074eb34SSamuel Dai                         mount_fs: self.mount_fs.clone(),
2031074eb34SSamuel Dai                         self_ref: self_ref.clone(),
2041074eb34SSamuel Dai                     }));
2051074eb34SSamuel Dai                 }
2061074eb34SSamuel Dai                 None => {
2071074eb34SSamuel Dai                     return Ok(self.self_ref.upgrade().unwrap());
2081074eb34SSamuel Dai                 }
2091074eb34SSamuel Dai             }
2101074eb34SSamuel Dai         } else {
2111074eb34SSamuel Dai             let inner_inode = self.inner_inode.parent()?;
2121074eb34SSamuel Dai             // 向上查找时,不会跨过文件系统的边界,因此直接调用当前inode所在的文件系统的find方法进行查找
2131074eb34SSamuel Dai             return Ok(Arc::new_cyclic(|self_ref| MountFSInode {
2141074eb34SSamuel Dai                 inner_inode,
2151074eb34SSamuel Dai                 mount_fs: self.mount_fs.clone(),
2161074eb34SSamuel Dai                 self_ref: self_ref.clone(),
2171074eb34SSamuel Dai             }));
2181074eb34SSamuel Dai         }
2191074eb34SSamuel Dai     }
2201074eb34SSamuel Dai 
2211074eb34SSamuel Dai     /// 移除挂载点下的文件系统
2221074eb34SSamuel Dai     fn do_umount(&self) -> Result<Arc<MountFS>, SystemError> {
2231074eb34SSamuel Dai         if self.metadata()?.file_type != FileType::Dir {
2241074eb34SSamuel Dai             return Err(SystemError::ENOTDIR);
2251074eb34SSamuel Dai         }
2261074eb34SSamuel Dai         return self
2271074eb34SSamuel Dai             .mount_fs
2281074eb34SSamuel Dai             .mountpoints
2291074eb34SSamuel Dai             .lock()
2301074eb34SSamuel Dai             .remove(&self.inner_inode.metadata()?.inode_id)
2311074eb34SSamuel Dai             .ok_or(SystemError::ENOENT);
2321074eb34SSamuel Dai     }
2331074eb34SSamuel Dai 
2341074eb34SSamuel Dai     fn do_absolute_path(&self, len: usize) -> Result<String, SystemError> {
2351074eb34SSamuel Dai         if self.metadata()?.inode_id == ROOT_INODE().metadata()?.inode_id {
2361074eb34SSamuel Dai             return Ok(String::with_capacity(len));
2371074eb34SSamuel Dai         }
2381074eb34SSamuel Dai         let name = self.dname()?;
2391074eb34SSamuel Dai         return Ok(self.do_parent()?.do_absolute_path(len + name.0.len() + 1)? + "/" + &name.0);
2401074eb34SSamuel Dai     }
241004e86ffSlogin }
242004e86ffSlogin 
243004e86ffSlogin impl IndexNode for MountFSInode {
244dfe53cf0SGnoCiYeH     fn open(
245dfe53cf0SGnoCiYeH         &self,
246dfe53cf0SGnoCiYeH         data: SpinLockGuard<FilePrivateData>,
247dfe53cf0SGnoCiYeH         mode: &FileMode,
248dfe53cf0SGnoCiYeH     ) -> Result<(), SystemError> {
2490d48c3c9Slogin         return self.inner_inode.open(data, mode);
250004e86ffSlogin     }
251004e86ffSlogin 
252dfe53cf0SGnoCiYeH     fn close(&self, data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
253004e86ffSlogin         return self.inner_inode.close(data);
254004e86ffSlogin     }
255004e86ffSlogin 
256004e86ffSlogin     fn create_with_data(
257004e86ffSlogin         &self,
258004e86ffSlogin         name: &str,
259004e86ffSlogin         file_type: FileType,
2606b4e7a29SLoGin         mode: ModeType,
261004e86ffSlogin         data: usize,
262676b8ef6SMork     ) -> Result<Arc<dyn IndexNode>, SystemError> {
2631074eb34SSamuel Dai         let inner_inode = self
264004e86ffSlogin             .inner_inode
2651074eb34SSamuel Dai             .create_with_data(name, file_type, mode, data)?;
2661074eb34SSamuel Dai         return Ok(Arc::new_cyclic(|self_ref| MountFSInode {
2671074eb34SSamuel Dai             inner_inode,
2681496ba7bSLoGin             mount_fs: self.mount_fs.clone(),
2691074eb34SSamuel Dai             self_ref: self_ref.clone(),
2701074eb34SSamuel Dai         }));
271004e86ffSlogin     }
272004e86ffSlogin 
273676b8ef6SMork     fn truncate(&self, len: usize) -> Result<(), SystemError> {
274004e86ffSlogin         return self.inner_inode.truncate(len);
275004e86ffSlogin     }
276004e86ffSlogin 
277004e86ffSlogin     fn read_at(
278004e86ffSlogin         &self,
279004e86ffSlogin         offset: usize,
280004e86ffSlogin         len: usize,
281004e86ffSlogin         buf: &mut [u8],
282dfe53cf0SGnoCiYeH         data: SpinLockGuard<FilePrivateData>,
283676b8ef6SMork     ) -> Result<usize, SystemError> {
28484407d36Slogin         return self.inner_inode.read_at(offset, len, buf, data);
285004e86ffSlogin     }
286004e86ffSlogin 
287004e86ffSlogin     fn write_at(
288004e86ffSlogin         &self,
289004e86ffSlogin         offset: usize,
290004e86ffSlogin         len: usize,
291004e86ffSlogin         buf: &[u8],
292dfe53cf0SGnoCiYeH         data: SpinLockGuard<FilePrivateData>,
293676b8ef6SMork     ) -> Result<usize, SystemError> {
29478bf93f0SYJwu2023         return self.inner_inode.write_at(offset, len, buf, data);
295004e86ffSlogin     }
296004e86ffSlogin 
297004e86ffSlogin     #[inline]
298004e86ffSlogin     fn fs(&self) -> Arc<dyn FileSystem> {
299004e86ffSlogin         return self.mount_fs.clone();
300004e86ffSlogin     }
301004e86ffSlogin 
302004e86ffSlogin     #[inline]
303004e86ffSlogin     fn as_any_ref(&self) -> &dyn core::any::Any {
304004e86ffSlogin         return self.inner_inode.as_any_ref();
305004e86ffSlogin     }
306004e86ffSlogin 
307004e86ffSlogin     #[inline]
308676b8ef6SMork     fn metadata(&self) -> Result<super::Metadata, SystemError> {
309004e86ffSlogin         return self.inner_inode.metadata();
310004e86ffSlogin     }
311004e86ffSlogin 
312004e86ffSlogin     #[inline]
313676b8ef6SMork     fn set_metadata(&self, metadata: &super::Metadata) -> Result<(), SystemError> {
314004e86ffSlogin         return self.inner_inode.set_metadata(metadata);
315004e86ffSlogin     }
316004e86ffSlogin 
317004e86ffSlogin     #[inline]
318676b8ef6SMork     fn resize(&self, len: usize) -> Result<(), SystemError> {
319004e86ffSlogin         return self.inner_inode.resize(len);
320004e86ffSlogin     }
321004e86ffSlogin 
322004e86ffSlogin     #[inline]
323004e86ffSlogin     fn create(
324004e86ffSlogin         &self,
325004e86ffSlogin         name: &str,
326004e86ffSlogin         file_type: FileType,
3276b4e7a29SLoGin         mode: ModeType,
328676b8ef6SMork     ) -> Result<Arc<dyn IndexNode>, SystemError> {
3291074eb34SSamuel Dai         let inner_inode = self.inner_inode.create(name, file_type, mode)?;
3301074eb34SSamuel Dai         return Ok(Arc::new_cyclic(|self_ref| MountFSInode {
3311074eb34SSamuel Dai             inner_inode,
332004e86ffSlogin             mount_fs: self.mount_fs.clone(),
3331074eb34SSamuel Dai             self_ref: self_ref.clone(),
3341074eb34SSamuel Dai         }));
335004e86ffSlogin     }
336004e86ffSlogin 
337676b8ef6SMork     fn link(&self, name: &str, other: &Arc<dyn IndexNode>) -> Result<(), SystemError> {
338004e86ffSlogin         return self.inner_inode.link(name, other);
339004e86ffSlogin     }
340004e86ffSlogin 
341004e86ffSlogin     /// @brief 在挂载文件系统中删除文件/文件夹
342004e86ffSlogin     #[inline]
343676b8ef6SMork     fn unlink(&self, name: &str) -> Result<(), SystemError> {
344004e86ffSlogin         let inode_id = self.inner_inode.find(name)?.metadata()?.inode_id;
345004e86ffSlogin 
346004e86ffSlogin         // 先检查这个inode是否为一个挂载点,如果当前inode是一个挂载点,那么就不能删除这个inode
347004e86ffSlogin         if self.mount_fs.mountpoints.lock().contains_key(&inode_id) {
348676b8ef6SMork             return Err(SystemError::EBUSY);
349004e86ffSlogin         }
350004e86ffSlogin         // 调用内层的inode的方法来删除这个inode
351004e86ffSlogin         return self.inner_inode.unlink(name);
352004e86ffSlogin     }
353004e86ffSlogin 
354004e86ffSlogin     #[inline]
355676b8ef6SMork     fn rmdir(&self, name: &str) -> Result<(), SystemError> {
356004e86ffSlogin         let inode_id = self.inner_inode.find(name)?.metadata()?.inode_id;
35784407d36Slogin 
358004e86ffSlogin         // 先检查这个inode是否为一个挂载点,如果当前inode是一个挂载点,那么就不能删除这个inode
359004e86ffSlogin         if self.mount_fs.mountpoints.lock().contains_key(&inode_id) {
360676b8ef6SMork             return Err(SystemError::EBUSY);
361004e86ffSlogin         }
362004e86ffSlogin         // 调用内层的rmdir的方法来删除这个inode
363004e86ffSlogin         let r = self.inner_inode.rmdir(name);
36484407d36Slogin 
365004e86ffSlogin         return r;
366004e86ffSlogin     }
367004e86ffSlogin 
368004e86ffSlogin     #[inline]
3699e481b3bSTTaq     fn move_to(
370004e86ffSlogin         &self,
371004e86ffSlogin         old_name: &str,
372004e86ffSlogin         target: &Arc<dyn IndexNode>,
373004e86ffSlogin         new_name: &str,
374676b8ef6SMork     ) -> Result<(), SystemError> {
3759e481b3bSTTaq         return self.inner_inode.move_to(old_name, target, new_name);
376004e86ffSlogin     }
377004e86ffSlogin 
378676b8ef6SMork     fn find(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError> {
379004e86ffSlogin         match name {
380004e86ffSlogin             // 查找的是当前目录
3811074eb34SSamuel Dai             "" | "." => self
3821074eb34SSamuel Dai                 .self_ref
3831074eb34SSamuel Dai                 .upgrade()
3841074eb34SSamuel Dai                 .map(|inode| inode as Arc<dyn IndexNode>)
3851074eb34SSamuel Dai                 .ok_or(SystemError::ENOENT),
386004e86ffSlogin             // 往父级查找
3871074eb34SSamuel Dai             ".." => self.parent(),
388004e86ffSlogin             // 在当前目录下查找
389004e86ffSlogin             // 直接调用当前inode所在的文件系统的find方法进行查找
390004e86ffSlogin             // 由于向下查找可能会跨越文件系统的边界,因此需要尝试替换inode
3911074eb34SSamuel Dai             _ => self.do_find(name).map(|inode| inode as Arc<dyn IndexNode>),
392004e86ffSlogin         }
393004e86ffSlogin     }
394004e86ffSlogin 
395004e86ffSlogin     #[inline]
396676b8ef6SMork     fn get_entry_name(&self, ino: InodeId) -> Result<alloc::string::String, SystemError> {
397004e86ffSlogin         return self.inner_inode.get_entry_name(ino);
398004e86ffSlogin     }
399004e86ffSlogin 
400004e86ffSlogin     #[inline]
401004e86ffSlogin     fn get_entry_name_and_metadata(
402004e86ffSlogin         &self,
403004e86ffSlogin         ino: InodeId,
404676b8ef6SMork     ) -> Result<(alloc::string::String, super::Metadata), SystemError> {
405004e86ffSlogin         return self.inner_inode.get_entry_name_and_metadata(ino);
406004e86ffSlogin     }
407004e86ffSlogin 
408004e86ffSlogin     #[inline]
40952da9a59SGnoCiYeH     fn ioctl(
41052da9a59SGnoCiYeH         &self,
41152da9a59SGnoCiYeH         cmd: u32,
41252da9a59SGnoCiYeH         data: usize,
41352da9a59SGnoCiYeH         private_data: &FilePrivateData,
41452da9a59SGnoCiYeH     ) -> Result<usize, SystemError> {
41552da9a59SGnoCiYeH         return self.inner_inode.ioctl(cmd, data, private_data);
416004e86ffSlogin     }
417004e86ffSlogin 
418004e86ffSlogin     #[inline]
419676b8ef6SMork     fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, SystemError> {
420004e86ffSlogin         return self.inner_inode.list();
421004e86ffSlogin     }
422004e86ffSlogin 
423676b8ef6SMork     fn mount(&self, fs: Arc<dyn FileSystem>) -> Result<Arc<MountFS>, SystemError> {
424004e86ffSlogin         let metadata = self.inner_inode.metadata()?;
425004e86ffSlogin         if metadata.file_type != FileType::Dir {
426676b8ef6SMork             return Err(SystemError::ENOTDIR);
427004e86ffSlogin         }
428004e86ffSlogin 
4291074eb34SSamuel Dai         if self.is_mountpoint_root()? {
4301074eb34SSamuel Dai             return Err(SystemError::EBUSY);
4311074eb34SSamuel Dai         }
4321074eb34SSamuel Dai 
4331074eb34SSamuel Dai         // 若已有挂载系统,保证MountFS只包一层
4341074eb34SSamuel Dai         let to_mount_fs = fs
4351074eb34SSamuel Dai             .clone()
4361074eb34SSamuel Dai             .downcast_arc::<MountFS>()
4371074eb34SSamuel Dai             .map(|it| it.inner_filesystem())
4381074eb34SSamuel Dai             .unwrap_or(fs);
4391074eb34SSamuel Dai         let new_mount_fs = MountFS::new(to_mount_fs, Some(self.self_ref.upgrade().unwrap()));
4401074eb34SSamuel Dai         self.mount_fs
4411074eb34SSamuel Dai             .mountpoints
4421074eb34SSamuel Dai             .lock()
4431074eb34SSamuel Dai             .insert(metadata.inode_id, new_mount_fs.clone());
4441074eb34SSamuel Dai 
4451074eb34SSamuel Dai         let mount_path = self.absolute_path();
4461074eb34SSamuel Dai 
4471074eb34SSamuel Dai         MOUNT_LIST().insert(mount_path?, new_mount_fs.clone());
448004e86ffSlogin         return Ok(new_mount_fs);
449004e86ffSlogin     }
4502dbef785SGnoCiYeH 
4511074eb34SSamuel Dai     fn mount_from(&self, from: Arc<dyn IndexNode>) -> Result<Arc<MountFS>, SystemError> {
4521074eb34SSamuel Dai         let metadata = self.metadata()?;
4531074eb34SSamuel Dai         if from.metadata()?.file_type != FileType::Dir || metadata.file_type != FileType::Dir {
4541074eb34SSamuel Dai             return Err(SystemError::ENOTDIR);
4551074eb34SSamuel Dai         }
4561074eb34SSamuel Dai         if self.is_mountpoint_root()? {
4571074eb34SSamuel Dai             return Err(SystemError::EBUSY);
4581074eb34SSamuel Dai         }
459*2eab6dd7S曾俊         // debug!("from {:?}, to {:?}", from, self);
4601074eb34SSamuel Dai         let new_mount_fs = from.umount()?;
4611074eb34SSamuel Dai         self.mount_fs
4621074eb34SSamuel Dai             .mountpoints
4631074eb34SSamuel Dai             .lock()
4641074eb34SSamuel Dai             .insert(metadata.inode_id, new_mount_fs.clone());
4651074eb34SSamuel Dai 
4661074eb34SSamuel Dai         // MOUNT_LIST().remove(from.absolute_path()?);
4671074eb34SSamuel Dai         // MOUNT_LIST().insert(self.absolute_path()?, new_mount_fs.clone());
4681074eb34SSamuel Dai         return Ok(new_mount_fs);
4691074eb34SSamuel Dai     }
4701074eb34SSamuel Dai 
4711074eb34SSamuel Dai     fn umount(&self) -> Result<Arc<MountFS>, SystemError> {
4721074eb34SSamuel Dai         if !self.is_mountpoint_root()? {
4731074eb34SSamuel Dai             return Err(SystemError::EINVAL);
4741074eb34SSamuel Dai         }
4751074eb34SSamuel Dai         return self.mount_fs.umount();
4761074eb34SSamuel Dai     }
4771074eb34SSamuel Dai 
4781074eb34SSamuel Dai     fn absolute_path(&self) -> Result<String, SystemError> {
4791074eb34SSamuel Dai         self.do_absolute_path(0)
4801074eb34SSamuel Dai     }
4811074eb34SSamuel Dai 
4822dbef785SGnoCiYeH     #[inline]
4832dbef785SGnoCiYeH     fn mknod(
4842dbef785SGnoCiYeH         &self,
4852dbef785SGnoCiYeH         filename: &str,
4862dbef785SGnoCiYeH         mode: ModeType,
4872dbef785SGnoCiYeH         dev_t: DeviceNumber,
4882dbef785SGnoCiYeH     ) -> Result<Arc<dyn IndexNode>, SystemError> {
4891074eb34SSamuel Dai         let inner_inode = self.inner_inode.mknod(filename, mode, dev_t)?;
4901074eb34SSamuel Dai         return Ok(Arc::new_cyclic(|self_ref| MountFSInode {
4911074eb34SSamuel Dai             inner_inode,
4922dbef785SGnoCiYeH             mount_fs: self.mount_fs.clone(),
4931074eb34SSamuel Dai             self_ref: self_ref.clone(),
4941074eb34SSamuel Dai         }));
4952dbef785SGnoCiYeH     }
4962dbef785SGnoCiYeH 
4972dbef785SGnoCiYeH     #[inline]
4982dbef785SGnoCiYeH     fn special_node(&self) -> Option<super::SpecialNodeData> {
4992dbef785SGnoCiYeH         self.inner_inode.special_node()
5002dbef785SGnoCiYeH     }
50152bcb59eSGnoCiYeH 
50252bcb59eSGnoCiYeH     #[inline]
50352bcb59eSGnoCiYeH     fn poll(&self, private_data: &FilePrivateData) -> Result<usize, SystemError> {
50452bcb59eSGnoCiYeH         self.inner_inode.poll(private_data)
50552bcb59eSGnoCiYeH     }
5061074eb34SSamuel Dai 
5071074eb34SSamuel Dai     /// 若不支持,则调用第二种情况来从父目录获取文件名
5081074eb34SSamuel Dai     /// # Performance
5091074eb34SSamuel Dai     /// 应尽可能引入DName,
5101074eb34SSamuel Dai     /// 在默认情况下,性能非常差!!!
5111074eb34SSamuel Dai     fn dname(&self) -> Result<DName, SystemError> {
5121074eb34SSamuel Dai         if self.is_mountpoint_root()? {
5131074eb34SSamuel Dai             if let Some(inode) = &self.mount_fs.self_mountpoint {
5141074eb34SSamuel Dai                 return inode.inner_inode.dname();
5151074eb34SSamuel Dai             }
5161074eb34SSamuel Dai         }
5171074eb34SSamuel Dai         return self.inner_inode.dname();
5181074eb34SSamuel Dai     }
5191074eb34SSamuel Dai 
5201074eb34SSamuel Dai     fn parent(&self) -> Result<Arc<dyn IndexNode>, SystemError> {
5211074eb34SSamuel Dai         return self.do_parent().map(|inode| inode as Arc<dyn IndexNode>);
5221074eb34SSamuel Dai     }
523004e86ffSlogin }
524004e86ffSlogin 
525004e86ffSlogin impl FileSystem for MountFS {
526004e86ffSlogin     fn root_inode(&self) -> Arc<dyn IndexNode> {
527004e86ffSlogin         match &self.self_mountpoint {
528004e86ffSlogin             Some(inode) => return inode.mount_fs.root_inode(),
529004e86ffSlogin             // 当前文件系统是rootfs
530004e86ffSlogin             None => self.mountpoint_root_inode(),
531004e86ffSlogin         }
532004e86ffSlogin     }
533004e86ffSlogin 
534004e86ffSlogin     fn info(&self) -> super::FsInfo {
535004e86ffSlogin         return self.inner_filesystem.info();
536004e86ffSlogin     }
537004e86ffSlogin 
538004e86ffSlogin     /// @brief 本函数用于实现动态转换。
539004e86ffSlogin     /// 具体的文件系统在实现本函数时,最简单的方式就是:直接返回self
540004e86ffSlogin     fn as_any_ref(&self) -> &dyn Any {
541004e86ffSlogin         self
542004e86ffSlogin     }
5431d37ca6dSDonkey Kane 
5441d37ca6dSDonkey Kane     fn name(&self) -> &str {
5451d37ca6dSDonkey Kane         "mountfs"
5461d37ca6dSDonkey Kane     }
547597ecc08STTaq     fn super_block(&self) -> SuperBlock {
548597ecc08STTaq         SuperBlock::new(Magic::MOUNT_MAGIC, MOUNTFS_BLOCK_SIZE, MOUNTFS_MAX_NAMELEN)
549597ecc08STTaq     }
550004e86ffSlogin }
5511074eb34SSamuel Dai 
5521074eb34SSamuel Dai /// MountList
5531074eb34SSamuel Dai /// ```rust
5541074eb34SSamuel Dai /// use alloc::collection::BTreeSet;
5551074eb34SSamuel Dai /// let map = BTreeSet::from([
5561074eb34SSamuel Dai ///     "/sys", "/dev", "/", "/bin", "/proc"
5571074eb34SSamuel Dai /// ]);
5581074eb34SSamuel Dai /// assert_eq!(format!("{:?}", map), "{\"/\", \"/bin\", \"/dev\", \"/proc\", \"/sys\"}");
5591074eb34SSamuel Dai /// // {"/", "/bin", "/dev", "/proc", "/sys"}
5601074eb34SSamuel Dai /// ```
5611074eb34SSamuel Dai #[derive(PartialEq, Eq, Debug)]
5621074eb34SSamuel Dai pub struct MountPath(String);
5631074eb34SSamuel Dai 
5641074eb34SSamuel Dai impl From<&str> for MountPath {
5651074eb34SSamuel Dai     fn from(value: &str) -> Self {
5661074eb34SSamuel Dai         Self(String::from(value))
5671074eb34SSamuel Dai     }
5681074eb34SSamuel Dai }
5691074eb34SSamuel Dai 
5701074eb34SSamuel Dai impl From<String> for MountPath {
5711074eb34SSamuel Dai     fn from(value: String) -> Self {
5721074eb34SSamuel Dai         Self(value)
5731074eb34SSamuel Dai     }
5741074eb34SSamuel Dai }
5751074eb34SSamuel Dai 
5761074eb34SSamuel Dai impl AsRef<str> for MountPath {
5771074eb34SSamuel Dai     fn as_ref(&self) -> &str {
5781074eb34SSamuel Dai         &self.0
5791074eb34SSamuel Dai     }
5801074eb34SSamuel Dai }
5811074eb34SSamuel Dai 
5821074eb34SSamuel Dai impl PartialOrd for MountPath {
5831074eb34SSamuel Dai     fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
5841074eb34SSamuel Dai         Some(self.cmp(other))
5851074eb34SSamuel Dai     }
5861074eb34SSamuel Dai }
5871074eb34SSamuel Dai 
5881074eb34SSamuel Dai impl Ord for MountPath {
5891074eb34SSamuel Dai     fn cmp(&self, other: &Self) -> core::cmp::Ordering {
5901074eb34SSamuel Dai         let self_dep = self.0.chars().filter(|c| *c == '/').count();
5911074eb34SSamuel Dai         let othe_dep = other.0.chars().filter(|c| *c == '/').count();
5921074eb34SSamuel Dai         if self_dep == othe_dep {
5931074eb34SSamuel Dai             // 深度一样时反序来排
5941074eb34SSamuel Dai             // 根目录和根目录下的文件的绝对路径都只有一个'/'
5951074eb34SSamuel Dai             other.0.cmp(&self.0)
5961074eb34SSamuel Dai         } else {
5971074eb34SSamuel Dai             // 根据深度,深度
5981074eb34SSamuel Dai             othe_dep.cmp(&self_dep)
5991074eb34SSamuel Dai         }
6001074eb34SSamuel Dai     }
6011074eb34SSamuel Dai }
6021074eb34SSamuel Dai 
6031074eb34SSamuel Dai // 维护一个挂载点的记录,以支持特定于文件系统的索引
6041074eb34SSamuel Dai pub struct MountList(RwLock<BTreeMap<MountPath, Arc<MountFS>>>);
6051074eb34SSamuel Dai // pub struct MountList(Option<Arc<MountListInner>>);
6061074eb34SSamuel Dai static mut __MOUNTS_LIST: Option<Arc<MountList>> = None;
6071074eb34SSamuel Dai 
6081074eb34SSamuel Dai /// # init_mountlist - 初始化挂载列表
6091074eb34SSamuel Dai ///
6101074eb34SSamuel Dai /// 此函数用于初始化系统的挂载列表。挂载列表记录了系统中所有的文件系统挂载点及其属性。
6111074eb34SSamuel Dai ///
6121074eb34SSamuel Dai /// ## 参数
6131074eb34SSamuel Dai ///
6141074eb34SSamuel Dai /// - 无
6151074eb34SSamuel Dai ///
6161074eb34SSamuel Dai /// ## 返回值
6171074eb34SSamuel Dai ///
6181074eb34SSamuel Dai /// - 无
6191074eb34SSamuel Dai #[inline(always)]
6201074eb34SSamuel Dai pub fn init_mountlist() {
6211074eb34SSamuel Dai     unsafe {
6221074eb34SSamuel Dai         __MOUNTS_LIST = Some(Arc::new(MountList(RwLock::new(BTreeMap::new()))));
6231074eb34SSamuel Dai     }
6241074eb34SSamuel Dai }
6251074eb34SSamuel Dai 
6261074eb34SSamuel Dai /// # MOUNT_LIST - 获取全局挂载列表
6271074eb34SSamuel Dai ///
6281074eb34SSamuel Dai /// 该函数用于获取一个对全局挂载列表的引用。全局挂载列表是系统中所有挂载点的集合。
6291074eb34SSamuel Dai ///
6301074eb34SSamuel Dai /// ## 返回值
6311074eb34SSamuel Dai /// - &'static Arc<MountList>: 返回全局挂载列表的引用。
6321074eb34SSamuel Dai #[inline(always)]
6331074eb34SSamuel Dai #[allow(non_snake_case)]
6341074eb34SSamuel Dai pub fn MOUNT_LIST() -> &'static Arc<MountList> {
6351074eb34SSamuel Dai     unsafe {
6361074eb34SSamuel Dai         return __MOUNTS_LIST.as_ref().unwrap();
6371074eb34SSamuel Dai     }
6381074eb34SSamuel Dai }
6391074eb34SSamuel Dai 
6401074eb34SSamuel Dai impl MountList {
6411074eb34SSamuel Dai     /// # insert - 将文件系统挂载点插入到挂载表中
6421074eb34SSamuel Dai     ///
6431074eb34SSamuel Dai     /// 将一个新的文件系统挂载点插入到挂载表中。如果挂载点已经存在,则会更新对应的文件系统。
6441074eb34SSamuel Dai     ///
6451074eb34SSamuel Dai     /// 此函数是线程安全的,因为它使用了RwLock来保证并发访问。
6461074eb34SSamuel Dai     ///
6471074eb34SSamuel Dai     /// ## 参数
6481074eb34SSamuel Dai     ///
6491074eb34SSamuel Dai     /// - `path`: &str, 挂载点的路径。这个路径会被转换成`MountPath`类型。
6501074eb34SSamuel Dai     /// - `fs`: Arc<MountFS>, 共享的文件系统实例。
6511074eb34SSamuel Dai     ///
6521074eb34SSamuel Dai     /// ## 返回值
6531074eb34SSamuel Dai     ///
6541074eb34SSamuel Dai     /// - 无
6551074eb34SSamuel Dai     #[inline]
6561074eb34SSamuel Dai     pub fn insert<T: AsRef<str>>(&self, path: T, fs: Arc<MountFS>) {
6571074eb34SSamuel Dai         self.0.write().insert(MountPath::from(path.as_ref()), fs);
6581074eb34SSamuel Dai     }
6591074eb34SSamuel Dai 
6601074eb34SSamuel Dai     /// # get_mount_point - 获取挂载点的路径
6611074eb34SSamuel Dai     ///
6621074eb34SSamuel Dai     /// 这个函数用于查找给定路径的挂载点。它搜索一个内部映射,找到与路径匹配的挂载点。
6631074eb34SSamuel Dai     ///
6641074eb34SSamuel Dai     /// ## 参数
6651074eb34SSamuel Dai     ///
6661074eb34SSamuel Dai     /// - `path: T`: 这是一个可转换为字符串的引用,表示要查找其挂载点的路径。
6671074eb34SSamuel Dai     ///
6681074eb34SSamuel Dai     /// ## 返回值
6691074eb34SSamuel Dai     ///
6701074eb34SSamuel Dai     /// - `Option<(String, String, Arc<MountFS>)>`:
6711074eb34SSamuel Dai     ///   - `Some((mount_point, rest_path, fs))`: 如果找到了匹配的挂载点,返回一个包含挂载点路径、剩余路径和挂载文件系统的元组。
6721074eb34SSamuel Dai     ///   - `None`: 如果没有找到匹配的挂载点,返回 None。
6731074eb34SSamuel Dai     #[inline]
6741074eb34SSamuel Dai     #[allow(dead_code)]
6751074eb34SSamuel Dai     pub fn get_mount_point<T: AsRef<str>>(
6761074eb34SSamuel Dai         &self,
6771074eb34SSamuel Dai         path: T,
6781074eb34SSamuel Dai     ) -> Option<(String, String, Arc<MountFS>)> {
6791074eb34SSamuel Dai         self.0
6801074eb34SSamuel Dai             .upgradeable_read()
6811074eb34SSamuel Dai             .iter()
6821074eb34SSamuel Dai             .filter_map(|(key, fs)| {
6831074eb34SSamuel Dai                 let strkey = key.as_ref();
6841074eb34SSamuel Dai                 if let Some(rest) = path.as_ref().strip_prefix(strkey) {
6851074eb34SSamuel Dai                     return Some((strkey.to_string(), rest.to_string(), fs.clone()));
6861074eb34SSamuel Dai                 }
6871074eb34SSamuel Dai                 None
6881074eb34SSamuel Dai             })
6891074eb34SSamuel Dai             .next()
6901074eb34SSamuel Dai     }
6911074eb34SSamuel Dai 
6921074eb34SSamuel Dai     /// # remove - 移除挂载点
6931074eb34SSamuel Dai     ///
6941074eb34SSamuel Dai     /// 从挂载点管理器中移除一个挂载点。
6951074eb34SSamuel Dai     ///
6961074eb34SSamuel Dai     /// 此函数用于从挂载点管理器中移除一个已经存在的挂载点。如果挂载点不存在,则不进行任何操作。
6971074eb34SSamuel Dai     ///
6981074eb34SSamuel Dai     /// ## 参数
6991074eb34SSamuel Dai     ///
7001074eb34SSamuel Dai     /// - `path: T`: `T` 实现了 `Into<MountPath>`  trait,代表要移除的挂载点的路径。
7011074eb34SSamuel Dai     ///
7021074eb34SSamuel Dai     /// ## 返回值
7031074eb34SSamuel Dai     ///
7041074eb34SSamuel Dai     /// - `Option<Arc<MountFS>>`: 返回一个 `Arc<MountFS>` 类型的可选值,表示被移除的挂载点,如果挂载点不存在则返回 `None`。
7051074eb34SSamuel Dai     #[inline]
7061074eb34SSamuel Dai     pub fn remove<T: Into<MountPath>>(&self, path: T) -> Option<Arc<MountFS>> {
7071074eb34SSamuel Dai         self.0.write().remove(&path.into())
7081074eb34SSamuel Dai     }
7091074eb34SSamuel Dai }
7101074eb34SSamuel Dai 
7111074eb34SSamuel Dai impl Debug for MountList {
7121074eb34SSamuel Dai     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
7131074eb34SSamuel Dai         f.debug_map().entries(MOUNT_LIST().0.read().iter()).finish()
7141074eb34SSamuel Dai     }
7151074eb34SSamuel Dai }
716