xref: /DragonOS/kernel/src/filesystem/vfs/mount.rs (revision 597ecc08c2444dcc8f527eb021932718b69c9cc5)
11496ba7bSLoGin use core::{
21496ba7bSLoGin     any::Any,
31496ba7bSLoGin     sync::atomic::{compiler_fence, Ordering},
41496ba7bSLoGin };
5004e86ffSlogin 
6004e86ffSlogin use alloc::{
7004e86ffSlogin     collections::BTreeMap,
8004e86ffSlogin     sync::{Arc, Weak},
9004e86ffSlogin };
1091e9d4abSLoGin use system_error::SystemError;
11004e86ffSlogin 
12c566df45SLoGin use crate::{driver::base::device::device_number::DeviceNumber, libs::spinlock::SpinLock};
13004e86ffSlogin 
146b4e7a29SLoGin use super::{
156b4e7a29SLoGin     file::FileMode, syscall::ModeType, FilePrivateData, FileSystem, FileType, IndexNode, InodeId,
16*597ecc08STTaq     Magic, SuperBlock,
176b4e7a29SLoGin };
18004e86ffSlogin 
19*597ecc08STTaq const MOUNTFS_BLOCK_SIZE: u64 = 512;
20*597ecc08STTaq const MOUNTFS_MAX_NAMELEN: u64 = 64;
21004e86ffSlogin /// @brief 挂载文件系统
22004e86ffSlogin /// 挂载文件系统的时候,套了MountFS这一层,以实现文件系统的递归挂载
23004e86ffSlogin #[derive(Debug)]
24004e86ffSlogin pub struct MountFS {
25004e86ffSlogin     // MountFS内部的文件系统
26004e86ffSlogin     inner_filesystem: Arc<dyn FileSystem>,
27004e86ffSlogin     /// 用来存储InodeID->挂载点的MountFS的B树
28004e86ffSlogin     mountpoints: SpinLock<BTreeMap<InodeId, Arc<MountFS>>>,
29004e86ffSlogin     /// 当前文件系统挂载到的那个挂载点的Inode
30004e86ffSlogin     self_mountpoint: Option<Arc<MountFSInode>>,
31004e86ffSlogin     /// 指向当前MountFS的弱引用
32004e86ffSlogin     self_ref: Weak<MountFS>,
33004e86ffSlogin }
34004e86ffSlogin 
35004e86ffSlogin /// @brief MountFS的Index Node 注意,这个IndexNode只是一个中间层。它的目的是将具体文件系统的Inode与挂载机制连接在一起。
36004e86ffSlogin #[derive(Debug)]
37004e86ffSlogin pub struct MountFSInode {
38004e86ffSlogin     /// 当前挂载点对应到具体的文件系统的Inode
39004e86ffSlogin     inner_inode: Arc<dyn IndexNode>,
40004e86ffSlogin     /// 当前Inode对应的MountFS
41004e86ffSlogin     mount_fs: Arc<MountFS>,
42004e86ffSlogin     /// 指向自身的弱引用
43004e86ffSlogin     self_ref: Weak<MountFSInode>,
44004e86ffSlogin }
45004e86ffSlogin 
46004e86ffSlogin impl MountFS {
47004e86ffSlogin     pub fn new(
48004e86ffSlogin         inner_fs: Arc<dyn FileSystem>,
49004e86ffSlogin         self_mountpoint: Option<Arc<MountFSInode>>,
50004e86ffSlogin     ) -> Arc<Self> {
51004e86ffSlogin         return MountFS {
52004e86ffSlogin             inner_filesystem: inner_fs,
53004e86ffSlogin             mountpoints: SpinLock::new(BTreeMap::new()),
54b5b571e0SLoGin             self_mountpoint,
55004e86ffSlogin             self_ref: Weak::default(),
56004e86ffSlogin         }
57004e86ffSlogin         .wrap();
58004e86ffSlogin     }
59004e86ffSlogin 
60004e86ffSlogin     /// @brief 用Arc指针包裹MountFS对象。
61004e86ffSlogin     /// 本函数的主要功能为,初始化MountFS对象中的自引用Weak指针
62004e86ffSlogin     /// 本函数只应在构造器中被调用
63004e86ffSlogin     fn wrap(self) -> Arc<Self> {
64004e86ffSlogin         // 创建Arc指针
65004e86ffSlogin         let mount_fs: Arc<MountFS> = Arc::new(self);
66004e86ffSlogin         // 创建weak指针
67004e86ffSlogin         let weak: Weak<MountFS> = Arc::downgrade(&mount_fs);
68004e86ffSlogin 
69004e86ffSlogin         // 将Arc指针转为Raw指针并对其内部的self_ref字段赋值
7034e6d6c8Syuyi2439         let ptr: *mut MountFS = mount_fs.as_ref() as *const Self as *mut Self;
71004e86ffSlogin         unsafe {
72004e86ffSlogin             (*ptr).self_ref = weak;
73004e86ffSlogin             // 返回初始化好的MountFS对象
7434e6d6c8Syuyi2439             return mount_fs;
75004e86ffSlogin         }
76004e86ffSlogin     }
77004e86ffSlogin 
78004e86ffSlogin     /// @brief 获取挂载点的文件系统的root inode
79004e86ffSlogin     pub fn mountpoint_root_inode(&self) -> Arc<MountFSInode> {
80004e86ffSlogin         return MountFSInode {
81004e86ffSlogin             inner_inode: self.inner_filesystem.root_inode(),
82004e86ffSlogin             mount_fs: self.self_ref.upgrade().unwrap(),
83004e86ffSlogin             self_ref: Weak::default(),
84004e86ffSlogin         }
85004e86ffSlogin         .wrap();
86004e86ffSlogin     }
87004e86ffSlogin 
88004e86ffSlogin     pub fn inner_filesystem(&self) -> Arc<dyn FileSystem> {
89004e86ffSlogin         return self.inner_filesystem.clone();
90004e86ffSlogin     }
91004e86ffSlogin }
92004e86ffSlogin 
93004e86ffSlogin impl MountFSInode {
94004e86ffSlogin     /// @brief 用Arc指针包裹MountFSInode对象。
95004e86ffSlogin     /// 本函数的主要功能为,初始化MountFSInode对象中的自引用Weak指针
96004e86ffSlogin     /// 本函数只应在构造器中被调用
97004e86ffSlogin     fn wrap(self) -> Arc<Self> {
98004e86ffSlogin         // 创建Arc指针
99004e86ffSlogin         let inode: Arc<MountFSInode> = Arc::new(self);
100004e86ffSlogin         // 创建Weak指针
101004e86ffSlogin         let weak: Weak<MountFSInode> = Arc::downgrade(&inode);
102004e86ffSlogin         // 将Arc指针转为Raw指针并对其内部的self_ref字段赋值
1031496ba7bSLoGin         compiler_fence(Ordering::SeqCst);
10434e6d6c8Syuyi2439         let ptr: *mut MountFSInode = inode.as_ref() as *const Self as *mut Self;
1051496ba7bSLoGin         compiler_fence(Ordering::SeqCst);
106004e86ffSlogin         unsafe {
107004e86ffSlogin             (*ptr).self_ref = weak;
1081496ba7bSLoGin             compiler_fence(Ordering::SeqCst);
109004e86ffSlogin 
110004e86ffSlogin             // 返回初始化好的MountFSInode对象
1111496ba7bSLoGin             return inode;
112004e86ffSlogin         }
113004e86ffSlogin     }
114004e86ffSlogin 
115004e86ffSlogin     /// @brief 判断当前inode是否为它所在的文件系统的root inode
116676b8ef6SMork     fn is_mountpoint_root(&self) -> Result<bool, SystemError> {
117004e86ffSlogin         return Ok(self.inner_inode.fs().root_inode().metadata()?.inode_id
118004e86ffSlogin             == self.inner_inode.metadata()?.inode_id);
119004e86ffSlogin     }
120004e86ffSlogin 
121004e86ffSlogin     /// @brief 在挂载树上进行inode替换。
122004e86ffSlogin     /// 如果当前inode是父MountFS内的一个挂载点,那么,本函数将会返回挂载到这个挂载点下的文件系统的root inode.
123004e86ffSlogin     /// 如果当前inode在父MountFS内,但不是挂载点,那么说明在这里不需要进行inode替换,因此直接返回当前inode。
124004e86ffSlogin     ///
125004e86ffSlogin     /// @return Arc<MountFSInode>
126004e86ffSlogin     fn overlaid_inode(&self) -> Arc<MountFSInode> {
127004e86ffSlogin         let inode_id = self.metadata().unwrap().inode_id;
128004e86ffSlogin 
129004e86ffSlogin         if let Some(sub_mountfs) = self.mount_fs.mountpoints.lock().get(&inode_id) {
130004e86ffSlogin             return sub_mountfs.mountpoint_root_inode();
131004e86ffSlogin         } else {
132004e86ffSlogin             return self.self_ref.upgrade().unwrap();
133004e86ffSlogin         }
134004e86ffSlogin     }
135004e86ffSlogin }
136004e86ffSlogin 
137004e86ffSlogin impl IndexNode for MountFSInode {
138676b8ef6SMork     fn open(&self, data: &mut FilePrivateData, mode: &FileMode) -> Result<(), SystemError> {
1390d48c3c9Slogin         return self.inner_inode.open(data, mode);
140004e86ffSlogin     }
141004e86ffSlogin 
142676b8ef6SMork     fn close(&self, data: &mut FilePrivateData) -> Result<(), SystemError> {
143004e86ffSlogin         return self.inner_inode.close(data);
144004e86ffSlogin     }
145004e86ffSlogin 
146004e86ffSlogin     fn create_with_data(
147004e86ffSlogin         &self,
148004e86ffSlogin         name: &str,
149004e86ffSlogin         file_type: FileType,
1506b4e7a29SLoGin         mode: ModeType,
151004e86ffSlogin         data: usize,
152676b8ef6SMork     ) -> Result<Arc<dyn IndexNode>, SystemError> {
1531496ba7bSLoGin         return Ok(MountFSInode {
1541496ba7bSLoGin             inner_inode: self
155004e86ffSlogin                 .inner_inode
1561496ba7bSLoGin                 .create_with_data(name, file_type, mode, data)?,
1571496ba7bSLoGin             mount_fs: self.mount_fs.clone(),
1581496ba7bSLoGin             self_ref: Weak::default(),
1591496ba7bSLoGin         }
1601496ba7bSLoGin         .wrap());
161004e86ffSlogin     }
162004e86ffSlogin 
163676b8ef6SMork     fn truncate(&self, len: usize) -> Result<(), SystemError> {
164004e86ffSlogin         return self.inner_inode.truncate(len);
165004e86ffSlogin     }
166004e86ffSlogin 
167004e86ffSlogin     fn read_at(
168004e86ffSlogin         &self,
169004e86ffSlogin         offset: usize,
170004e86ffSlogin         len: usize,
171004e86ffSlogin         buf: &mut [u8],
172004e86ffSlogin         data: &mut FilePrivateData,
173676b8ef6SMork     ) -> Result<usize, SystemError> {
17484407d36Slogin         return self.inner_inode.read_at(offset, len, buf, data);
175004e86ffSlogin     }
176004e86ffSlogin 
177004e86ffSlogin     fn write_at(
178004e86ffSlogin         &self,
179004e86ffSlogin         offset: usize,
180004e86ffSlogin         len: usize,
181004e86ffSlogin         buf: &[u8],
18220e3152eSlogin         data: &mut FilePrivateData,
183676b8ef6SMork     ) -> Result<usize, SystemError> {
18478bf93f0SYJwu2023         return self.inner_inode.write_at(offset, len, buf, data);
185004e86ffSlogin     }
186004e86ffSlogin 
187004e86ffSlogin     #[inline]
188004e86ffSlogin     fn fs(&self) -> Arc<dyn FileSystem> {
189004e86ffSlogin         return self.mount_fs.clone();
190004e86ffSlogin     }
191004e86ffSlogin 
192004e86ffSlogin     #[inline]
193004e86ffSlogin     fn as_any_ref(&self) -> &dyn core::any::Any {
194004e86ffSlogin         return self.inner_inode.as_any_ref();
195004e86ffSlogin     }
196004e86ffSlogin 
197004e86ffSlogin     #[inline]
198676b8ef6SMork     fn metadata(&self) -> Result<super::Metadata, SystemError> {
199004e86ffSlogin         return self.inner_inode.metadata();
200004e86ffSlogin     }
201004e86ffSlogin 
202004e86ffSlogin     #[inline]
203676b8ef6SMork     fn set_metadata(&self, metadata: &super::Metadata) -> Result<(), SystemError> {
204004e86ffSlogin         return self.inner_inode.set_metadata(metadata);
205004e86ffSlogin     }
206004e86ffSlogin 
207004e86ffSlogin     #[inline]
208676b8ef6SMork     fn resize(&self, len: usize) -> Result<(), SystemError> {
209004e86ffSlogin         return self.inner_inode.resize(len);
210004e86ffSlogin     }
211004e86ffSlogin 
212004e86ffSlogin     #[inline]
213004e86ffSlogin     fn create(
214004e86ffSlogin         &self,
215004e86ffSlogin         name: &str,
216004e86ffSlogin         file_type: FileType,
2176b4e7a29SLoGin         mode: ModeType,
218676b8ef6SMork     ) -> Result<Arc<dyn IndexNode>, SystemError> {
219004e86ffSlogin         return Ok(MountFSInode {
220004e86ffSlogin             inner_inode: self.inner_inode.create(name, file_type, mode)?,
221004e86ffSlogin             mount_fs: self.mount_fs.clone(),
222004e86ffSlogin             self_ref: Weak::default(),
223004e86ffSlogin         }
224004e86ffSlogin         .wrap());
225004e86ffSlogin     }
226004e86ffSlogin 
227676b8ef6SMork     fn link(&self, name: &str, other: &Arc<dyn IndexNode>) -> Result<(), SystemError> {
228004e86ffSlogin         return self.inner_inode.link(name, other);
229004e86ffSlogin     }
230004e86ffSlogin 
231004e86ffSlogin     /// @brief 在挂载文件系统中删除文件/文件夹
232004e86ffSlogin     #[inline]
233676b8ef6SMork     fn unlink(&self, name: &str) -> Result<(), SystemError> {
234004e86ffSlogin         let inode_id = self.inner_inode.find(name)?.metadata()?.inode_id;
235004e86ffSlogin 
236004e86ffSlogin         // 先检查这个inode是否为一个挂载点,如果当前inode是一个挂载点,那么就不能删除这个inode
237004e86ffSlogin         if self.mount_fs.mountpoints.lock().contains_key(&inode_id) {
238676b8ef6SMork             return Err(SystemError::EBUSY);
239004e86ffSlogin         }
240004e86ffSlogin         // 调用内层的inode的方法来删除这个inode
241004e86ffSlogin         return self.inner_inode.unlink(name);
242004e86ffSlogin     }
243004e86ffSlogin 
244004e86ffSlogin     #[inline]
245676b8ef6SMork     fn rmdir(&self, name: &str) -> Result<(), SystemError> {
246004e86ffSlogin         let inode_id = self.inner_inode.find(name)?.metadata()?.inode_id;
24784407d36Slogin 
248004e86ffSlogin         // 先检查这个inode是否为一个挂载点,如果当前inode是一个挂载点,那么就不能删除这个inode
249004e86ffSlogin         if self.mount_fs.mountpoints.lock().contains_key(&inode_id) {
250676b8ef6SMork             return Err(SystemError::EBUSY);
251004e86ffSlogin         }
252004e86ffSlogin         // 调用内层的rmdir的方法来删除这个inode
253004e86ffSlogin         let r = self.inner_inode.rmdir(name);
25484407d36Slogin 
255004e86ffSlogin         return r;
256004e86ffSlogin     }
257004e86ffSlogin 
258004e86ffSlogin     #[inline]
2599e481b3bSTTaq     fn move_to(
260004e86ffSlogin         &self,
261004e86ffSlogin         old_name: &str,
262004e86ffSlogin         target: &Arc<dyn IndexNode>,
263004e86ffSlogin         new_name: &str,
264676b8ef6SMork     ) -> Result<(), SystemError> {
2659e481b3bSTTaq         return self.inner_inode.move_to(old_name, target, new_name);
266004e86ffSlogin     }
267004e86ffSlogin 
268676b8ef6SMork     fn find(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError> {
269004e86ffSlogin         match name {
270004e86ffSlogin             // 查找的是当前目录
271004e86ffSlogin             "" | "." => return Ok(self.self_ref.upgrade().unwrap()),
272004e86ffSlogin             // 往父级查找
273004e86ffSlogin             ".." => {
274004e86ffSlogin                 if self.is_mountpoint_root()? {
275004e86ffSlogin                     // 当前inode是它所在的文件系统的root inode
276004e86ffSlogin                     match &self.mount_fs.self_mountpoint {
277004e86ffSlogin                         Some(inode) => {
278004e86ffSlogin                             return inode.find(name);
279004e86ffSlogin                         }
280004e86ffSlogin                         None => {
281004e86ffSlogin                             return Ok(self.self_ref.upgrade().unwrap());
282004e86ffSlogin                         }
283004e86ffSlogin                     }
284004e86ffSlogin                 } else {
285004e86ffSlogin                     // 向上查找时,不会跨过文件系统的边界,因此直接调用当前inode所在的文件系统的find方法进行查找
286004e86ffSlogin                     return Ok(MountFSInode {
287004e86ffSlogin                         inner_inode: self.inner_inode.find(name)?,
288004e86ffSlogin                         mount_fs: self.mount_fs.clone(),
289004e86ffSlogin                         self_ref: Weak::default(),
290004e86ffSlogin                     }
291004e86ffSlogin                     .wrap());
292004e86ffSlogin                 }
293004e86ffSlogin             }
294004e86ffSlogin             // 在当前目录下查找
295004e86ffSlogin             _ => {
296004e86ffSlogin                 // 直接调用当前inode所在的文件系统的find方法进行查找
297004e86ffSlogin                 // 由于向下查找可能会跨越文件系统的边界,因此需要尝试替换inode
298004e86ffSlogin                 return Ok(MountFSInode {
299004e86ffSlogin                     inner_inode: self.inner_inode.find(name)?,
300004e86ffSlogin                     mount_fs: self.mount_fs.clone(),
301004e86ffSlogin                     self_ref: Weak::default(),
302004e86ffSlogin                 }
303004e86ffSlogin                 .wrap()
304004e86ffSlogin                 .overlaid_inode());
305004e86ffSlogin             }
306004e86ffSlogin         }
307004e86ffSlogin     }
308004e86ffSlogin 
309004e86ffSlogin     #[inline]
310676b8ef6SMork     fn get_entry_name(&self, ino: InodeId) -> Result<alloc::string::String, SystemError> {
311004e86ffSlogin         return self.inner_inode.get_entry_name(ino);
312004e86ffSlogin     }
313004e86ffSlogin 
314004e86ffSlogin     #[inline]
315004e86ffSlogin     fn get_entry_name_and_metadata(
316004e86ffSlogin         &self,
317004e86ffSlogin         ino: InodeId,
318676b8ef6SMork     ) -> Result<(alloc::string::String, super::Metadata), SystemError> {
319004e86ffSlogin         return self.inner_inode.get_entry_name_and_metadata(ino);
320004e86ffSlogin     }
321004e86ffSlogin 
322004e86ffSlogin     #[inline]
32352da9a59SGnoCiYeH     fn ioctl(
32452da9a59SGnoCiYeH         &self,
32552da9a59SGnoCiYeH         cmd: u32,
32652da9a59SGnoCiYeH         data: usize,
32752da9a59SGnoCiYeH         private_data: &FilePrivateData,
32852da9a59SGnoCiYeH     ) -> Result<usize, SystemError> {
32952da9a59SGnoCiYeH         return self.inner_inode.ioctl(cmd, data, private_data);
330004e86ffSlogin     }
331004e86ffSlogin 
332004e86ffSlogin     #[inline]
333676b8ef6SMork     fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, SystemError> {
334004e86ffSlogin         return self.inner_inode.list();
335004e86ffSlogin     }
336004e86ffSlogin 
337004e86ffSlogin     /// @brief 在当前inode下,挂载一个文件系统
338004e86ffSlogin     ///
339004e86ffSlogin     /// @return Ok(Arc<MountFS>) 挂载成功,返回指向MountFS的指针
340676b8ef6SMork     fn mount(&self, fs: Arc<dyn FileSystem>) -> Result<Arc<MountFS>, SystemError> {
341004e86ffSlogin         let metadata = self.inner_inode.metadata()?;
342004e86ffSlogin         if metadata.file_type != FileType::Dir {
343676b8ef6SMork             return Err(SystemError::ENOTDIR);
344004e86ffSlogin         }
345004e86ffSlogin 
346004e86ffSlogin         // 为新的挂载点创建挂载文件系统
347004e86ffSlogin         let new_mount_fs: Arc<MountFS> = MountFS::new(fs, Some(self.self_ref.upgrade().unwrap()));
348004e86ffSlogin         // 将新的挂载点-挂载文件系统添加到父级的挂载树
349004e86ffSlogin         self.mount_fs
350004e86ffSlogin             .mountpoints
351004e86ffSlogin             .lock()
352004e86ffSlogin             .insert(metadata.inode_id, new_mount_fs.clone());
353004e86ffSlogin         return Ok(new_mount_fs);
354004e86ffSlogin     }
3552dbef785SGnoCiYeH 
3562dbef785SGnoCiYeH     #[inline]
3572dbef785SGnoCiYeH     fn mknod(
3582dbef785SGnoCiYeH         &self,
3592dbef785SGnoCiYeH         filename: &str,
3602dbef785SGnoCiYeH         mode: ModeType,
3612dbef785SGnoCiYeH         dev_t: DeviceNumber,
3622dbef785SGnoCiYeH     ) -> Result<Arc<dyn IndexNode>, SystemError> {
3632dbef785SGnoCiYeH         return Ok(MountFSInode {
3642dbef785SGnoCiYeH             inner_inode: self.inner_inode.mknod(filename, mode, dev_t)?,
3652dbef785SGnoCiYeH             mount_fs: self.mount_fs.clone(),
3662dbef785SGnoCiYeH             self_ref: Weak::default(),
3672dbef785SGnoCiYeH         }
3682dbef785SGnoCiYeH         .wrap());
3692dbef785SGnoCiYeH     }
3702dbef785SGnoCiYeH 
3712dbef785SGnoCiYeH     #[inline]
3722dbef785SGnoCiYeH     fn special_node(&self) -> Option<super::SpecialNodeData> {
3732dbef785SGnoCiYeH         self.inner_inode.special_node()
3742dbef785SGnoCiYeH     }
37552bcb59eSGnoCiYeH 
37652bcb59eSGnoCiYeH     #[inline]
37752bcb59eSGnoCiYeH     fn poll(&self, private_data: &FilePrivateData) -> Result<usize, SystemError> {
37852bcb59eSGnoCiYeH         self.inner_inode.poll(private_data)
37952bcb59eSGnoCiYeH     }
380004e86ffSlogin }
381004e86ffSlogin 
382004e86ffSlogin impl FileSystem for MountFS {
383004e86ffSlogin     fn root_inode(&self) -> Arc<dyn IndexNode> {
384004e86ffSlogin         match &self.self_mountpoint {
385004e86ffSlogin             Some(inode) => return inode.mount_fs.root_inode(),
386004e86ffSlogin             // 当前文件系统是rootfs
387004e86ffSlogin             None => self.mountpoint_root_inode(),
388004e86ffSlogin         }
389004e86ffSlogin     }
390004e86ffSlogin 
391004e86ffSlogin     fn info(&self) -> super::FsInfo {
392004e86ffSlogin         return self.inner_filesystem.info();
393004e86ffSlogin     }
394004e86ffSlogin 
395004e86ffSlogin     /// @brief 本函数用于实现动态转换。
396004e86ffSlogin     /// 具体的文件系统在实现本函数时,最简单的方式就是:直接返回self
397004e86ffSlogin     fn as_any_ref(&self) -> &dyn Any {
398004e86ffSlogin         self
399004e86ffSlogin     }
4001d37ca6dSDonkey Kane 
4011d37ca6dSDonkey Kane     fn name(&self) -> &str {
4021d37ca6dSDonkey Kane         "mountfs"
4031d37ca6dSDonkey Kane     }
404*597ecc08STTaq     fn super_block(&self) -> SuperBlock {
405*597ecc08STTaq         SuperBlock::new(Magic::MOUNT_MAGIC, MOUNTFS_BLOCK_SIZE, MOUNTFS_MAX_NAMELEN)
406*597ecc08STTaq     }
407004e86ffSlogin }
408