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 }, 22*cf7f801eSMemoryShore mm::{fault::PageFaultMessage, VmFaultReason}, 23dfe53cf0SGnoCiYeH }; 24004e86ffSlogin 256b4e7a29SLoGin use super::{ 26*cf7f801eSMemoryShore file::{FileMode, PageCache}, 27*cf7f801eSMemoryShore syscall::ModeType, 28*cf7f801eSMemoryShore utils::DName, 29*cf7f801eSMemoryShore FilePrivateData, FileSystem, FileType, IndexNode, InodeId, Magic, SuperBlock, 306b4e7a29SLoGin }; 31004e86ffSlogin 32597ecc08STTaq const MOUNTFS_BLOCK_SIZE: u64 = 512; 33597ecc08STTaq const MOUNTFS_MAX_NAMELEN: u64 = 64; 34004e86ffSlogin /// @brief 挂载文件系统 35004e86ffSlogin /// 挂载文件系统的时候,套了MountFS这一层,以实现文件系统的递归挂载 36004e86ffSlogin #[derive(Debug)] 37004e86ffSlogin pub struct MountFS { 38004e86ffSlogin // MountFS内部的文件系统 39004e86ffSlogin inner_filesystem: Arc<dyn FileSystem>, 40004e86ffSlogin /// 用来存储InodeID->挂载点的MountFS的B树 41004e86ffSlogin mountpoints: SpinLock<BTreeMap<InodeId, Arc<MountFS>>>, 42004e86ffSlogin /// 当前文件系统挂载到的那个挂载点的Inode 43004e86ffSlogin self_mountpoint: Option<Arc<MountFSInode>>, 44004e86ffSlogin /// 指向当前MountFS的弱引用 45004e86ffSlogin self_ref: Weak<MountFS>, 46004e86ffSlogin } 47004e86ffSlogin 48004e86ffSlogin /// @brief MountFS的Index Node 注意,这个IndexNode只是一个中间层。它的目的是将具体文件系统的Inode与挂载机制连接在一起。 49004e86ffSlogin #[derive(Debug)] 50dfe53cf0SGnoCiYeH #[cast_to([sync] IndexNode)] 51004e86ffSlogin pub struct MountFSInode { 52004e86ffSlogin /// 当前挂载点对应到具体的文件系统的Inode 53004e86ffSlogin inner_inode: Arc<dyn IndexNode>, 54004e86ffSlogin /// 当前Inode对应的MountFS 55004e86ffSlogin mount_fs: Arc<MountFS>, 56004e86ffSlogin /// 指向自身的弱引用 57004e86ffSlogin self_ref: Weak<MountFSInode>, 58004e86ffSlogin } 59004e86ffSlogin 60004e86ffSlogin impl MountFS { 61004e86ffSlogin pub fn new( 621074eb34SSamuel Dai inner_filesystem: Arc<dyn FileSystem>, 63004e86ffSlogin self_mountpoint: Option<Arc<MountFSInode>>, 64004e86ffSlogin ) -> Arc<Self> { 651074eb34SSamuel Dai return Arc::new_cyclic(|self_ref| MountFS { 661074eb34SSamuel Dai inner_filesystem, 67004e86ffSlogin mountpoints: SpinLock::new(BTreeMap::new()), 68b5b571e0SLoGin self_mountpoint, 691074eb34SSamuel Dai self_ref: self_ref.clone(), 701074eb34SSamuel Dai }); 71004e86ffSlogin } 72004e86ffSlogin 73004e86ffSlogin /// @brief 用Arc指针包裹MountFS对象。 74004e86ffSlogin /// 本函数的主要功能为,初始化MountFS对象中的自引用Weak指针 75004e86ffSlogin /// 本函数只应在构造器中被调用 761074eb34SSamuel Dai #[allow(dead_code)] 771074eb34SSamuel Dai #[deprecated] 78004e86ffSlogin fn wrap(self) -> Arc<Self> { 79004e86ffSlogin // 创建Arc指针 80004e86ffSlogin let mount_fs: Arc<MountFS> = Arc::new(self); 81004e86ffSlogin // 创建weak指针 82004e86ffSlogin let weak: Weak<MountFS> = Arc::downgrade(&mount_fs); 83004e86ffSlogin 84004e86ffSlogin // 将Arc指针转为Raw指针并对其内部的self_ref字段赋值 8534e6d6c8Syuyi2439 let ptr: *mut MountFS = mount_fs.as_ref() as *const Self as *mut Self; 86004e86ffSlogin unsafe { 87004e86ffSlogin (*ptr).self_ref = weak; 88004e86ffSlogin // 返回初始化好的MountFS对象 8934e6d6c8Syuyi2439 return mount_fs; 90004e86ffSlogin } 91004e86ffSlogin } 92004e86ffSlogin 93004e86ffSlogin /// @brief 获取挂载点的文件系统的root inode 94004e86ffSlogin pub fn mountpoint_root_inode(&self) -> Arc<MountFSInode> { 951074eb34SSamuel Dai return Arc::new_cyclic(|self_ref| MountFSInode { 96004e86ffSlogin inner_inode: self.inner_filesystem.root_inode(), 97004e86ffSlogin mount_fs: self.self_ref.upgrade().unwrap(), 981074eb34SSamuel Dai self_ref: self_ref.clone(), 991074eb34SSamuel Dai }); 100004e86ffSlogin } 101004e86ffSlogin 102004e86ffSlogin pub fn inner_filesystem(&self) -> Arc<dyn FileSystem> { 103004e86ffSlogin return self.inner_filesystem.clone(); 104004e86ffSlogin } 105dfe53cf0SGnoCiYeH 106dfe53cf0SGnoCiYeH pub fn self_ref(&self) -> Arc<Self> { 107dfe53cf0SGnoCiYeH self.self_ref.upgrade().unwrap() 108dfe53cf0SGnoCiYeH } 1091074eb34SSamuel Dai 1101074eb34SSamuel Dai /// 卸载文件系统 1111074eb34SSamuel Dai /// # Errors 1121074eb34SSamuel Dai /// 如果当前文件系统是根文件系统,那么将会返回`EINVAL` 1131074eb34SSamuel Dai pub fn umount(&self) -> Result<Arc<MountFS>, SystemError> { 1141074eb34SSamuel Dai self.self_mountpoint 1151074eb34SSamuel Dai .as_ref() 1161074eb34SSamuel Dai .ok_or(SystemError::EINVAL)? 1171074eb34SSamuel Dai .do_umount() 1181074eb34SSamuel Dai } 119004e86ffSlogin } 120004e86ffSlogin 121004e86ffSlogin impl MountFSInode { 122004e86ffSlogin /// @brief 用Arc指针包裹MountFSInode对象。 123004e86ffSlogin /// 本函数的主要功能为,初始化MountFSInode对象中的自引用Weak指针 124004e86ffSlogin /// 本函数只应在构造器中被调用 1251074eb34SSamuel Dai #[allow(dead_code)] 1261074eb34SSamuel Dai #[deprecated] 127004e86ffSlogin fn wrap(self) -> Arc<Self> { 128004e86ffSlogin // 创建Arc指针 129004e86ffSlogin let inode: Arc<MountFSInode> = Arc::new(self); 130004e86ffSlogin // 创建Weak指针 131004e86ffSlogin let weak: Weak<MountFSInode> = Arc::downgrade(&inode); 132004e86ffSlogin // 将Arc指针转为Raw指针并对其内部的self_ref字段赋值 1331496ba7bSLoGin compiler_fence(Ordering::SeqCst); 13434e6d6c8Syuyi2439 let ptr: *mut MountFSInode = inode.as_ref() as *const Self as *mut Self; 1351496ba7bSLoGin compiler_fence(Ordering::SeqCst); 136004e86ffSlogin unsafe { 137004e86ffSlogin (*ptr).self_ref = weak; 1381496ba7bSLoGin compiler_fence(Ordering::SeqCst); 139004e86ffSlogin 140004e86ffSlogin // 返回初始化好的MountFSInode对象 1411496ba7bSLoGin return inode; 142004e86ffSlogin } 143004e86ffSlogin } 144004e86ffSlogin 145004e86ffSlogin /// @brief 判断当前inode是否为它所在的文件系统的root inode 146676b8ef6SMork fn is_mountpoint_root(&self) -> Result<bool, SystemError> { 147004e86ffSlogin return Ok(self.inner_inode.fs().root_inode().metadata()?.inode_id 148004e86ffSlogin == self.inner_inode.metadata()?.inode_id); 149004e86ffSlogin } 150004e86ffSlogin 151004e86ffSlogin /// @brief 在挂载树上进行inode替换。 152004e86ffSlogin /// 如果当前inode是父MountFS内的一个挂载点,那么,本函数将会返回挂载到这个挂载点下的文件系统的root inode. 153004e86ffSlogin /// 如果当前inode在父MountFS内,但不是挂载点,那么说明在这里不需要进行inode替换,因此直接返回当前inode。 154004e86ffSlogin /// 155004e86ffSlogin /// @return Arc<MountFSInode> 156004e86ffSlogin fn overlaid_inode(&self) -> Arc<MountFSInode> { 157004e86ffSlogin let inode_id = self.metadata().unwrap().inode_id; 158004e86ffSlogin 159004e86ffSlogin if let Some(sub_mountfs) = self.mount_fs.mountpoints.lock().get(&inode_id) { 160004e86ffSlogin return sub_mountfs.mountpoint_root_inode(); 161004e86ffSlogin } else { 162004e86ffSlogin return self.self_ref.upgrade().unwrap(); 163004e86ffSlogin } 164004e86ffSlogin } 165dfe53cf0SGnoCiYeH 1661074eb34SSamuel Dai fn do_find(&self, name: &str) -> Result<Arc<MountFSInode>, SystemError> { 1671074eb34SSamuel Dai // 直接调用当前inode所在的文件系统的find方法进行查找 1681074eb34SSamuel Dai // 由于向下查找可能会跨越文件系统的边界,因此需要尝试替换inode 1691074eb34SSamuel Dai let inner_inode = self.inner_inode.find(name)?; 1701074eb34SSamuel Dai return Ok(Arc::new_cyclic(|self_ref| MountFSInode { 1711074eb34SSamuel Dai inner_inode, 1721074eb34SSamuel Dai mount_fs: self.mount_fs.clone(), 1731074eb34SSamuel Dai self_ref: self_ref.clone(), 1741074eb34SSamuel Dai }) 1751074eb34SSamuel Dai .overlaid_inode()); 1761074eb34SSamuel Dai } 1771074eb34SSamuel Dai 1781074eb34SSamuel Dai pub(super) fn do_parent(&self) -> Result<Arc<MountFSInode>, SystemError> { 1791074eb34SSamuel Dai if self.is_mountpoint_root()? { 1801074eb34SSamuel Dai // 当前inode是它所在的文件系统的root inode 1811074eb34SSamuel Dai match &self.mount_fs.self_mountpoint { 1821074eb34SSamuel Dai Some(inode) => { 1831074eb34SSamuel Dai let inner_inode = inode.parent()?; 1841074eb34SSamuel Dai return Ok(Arc::new_cyclic(|self_ref| MountFSInode { 1851074eb34SSamuel Dai inner_inode, 1861074eb34SSamuel Dai mount_fs: self.mount_fs.clone(), 1871074eb34SSamuel Dai self_ref: self_ref.clone(), 1881074eb34SSamuel Dai })); 1891074eb34SSamuel Dai } 1901074eb34SSamuel Dai None => { 1911074eb34SSamuel Dai return Ok(self.self_ref.upgrade().unwrap()); 1921074eb34SSamuel Dai } 1931074eb34SSamuel Dai } 1941074eb34SSamuel Dai } else { 1951074eb34SSamuel Dai let inner_inode = self.inner_inode.parent()?; 1961074eb34SSamuel Dai // 向上查找时,不会跨过文件系统的边界,因此直接调用当前inode所在的文件系统的find方法进行查找 1971074eb34SSamuel Dai return Ok(Arc::new_cyclic(|self_ref| MountFSInode { 1981074eb34SSamuel Dai inner_inode, 1991074eb34SSamuel Dai mount_fs: self.mount_fs.clone(), 2001074eb34SSamuel Dai self_ref: self_ref.clone(), 2011074eb34SSamuel Dai })); 2021074eb34SSamuel Dai } 2031074eb34SSamuel Dai } 2041074eb34SSamuel Dai 2051074eb34SSamuel Dai /// 移除挂载点下的文件系统 2061074eb34SSamuel Dai fn do_umount(&self) -> Result<Arc<MountFS>, SystemError> { 2071074eb34SSamuel Dai if self.metadata()?.file_type != FileType::Dir { 2081074eb34SSamuel Dai return Err(SystemError::ENOTDIR); 2091074eb34SSamuel Dai } 2101074eb34SSamuel Dai return self 2111074eb34SSamuel Dai .mount_fs 2121074eb34SSamuel Dai .mountpoints 2131074eb34SSamuel Dai .lock() 2141074eb34SSamuel Dai .remove(&self.inner_inode.metadata()?.inode_id) 2151074eb34SSamuel Dai .ok_or(SystemError::ENOENT); 2161074eb34SSamuel Dai } 2171074eb34SSamuel Dai 2181074eb34SSamuel Dai fn do_absolute_path(&self, len: usize) -> Result<String, SystemError> { 2191074eb34SSamuel Dai if self.metadata()?.inode_id == ROOT_INODE().metadata()?.inode_id { 2201074eb34SSamuel Dai return Ok(String::with_capacity(len)); 2211074eb34SSamuel Dai } 2221074eb34SSamuel Dai let name = self.dname()?; 2231074eb34SSamuel Dai return Ok(self.do_parent()?.do_absolute_path(len + name.0.len() + 1)? + "/" + &name.0); 2241074eb34SSamuel Dai } 225004e86ffSlogin } 226004e86ffSlogin 227004e86ffSlogin impl IndexNode for MountFSInode { 228dfe53cf0SGnoCiYeH fn open( 229dfe53cf0SGnoCiYeH &self, 230dfe53cf0SGnoCiYeH data: SpinLockGuard<FilePrivateData>, 231dfe53cf0SGnoCiYeH mode: &FileMode, 232dfe53cf0SGnoCiYeH ) -> Result<(), SystemError> { 2330d48c3c9Slogin return self.inner_inode.open(data, mode); 234004e86ffSlogin } 235004e86ffSlogin 236dfe53cf0SGnoCiYeH fn close(&self, data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> { 237004e86ffSlogin return self.inner_inode.close(data); 238004e86ffSlogin } 239004e86ffSlogin 240004e86ffSlogin fn create_with_data( 241004e86ffSlogin &self, 242004e86ffSlogin name: &str, 243004e86ffSlogin file_type: FileType, 2446b4e7a29SLoGin mode: ModeType, 245004e86ffSlogin data: usize, 246676b8ef6SMork ) -> Result<Arc<dyn IndexNode>, SystemError> { 2471074eb34SSamuel Dai let inner_inode = self 248004e86ffSlogin .inner_inode 2491074eb34SSamuel Dai .create_with_data(name, file_type, mode, data)?; 2501074eb34SSamuel Dai return Ok(Arc::new_cyclic(|self_ref| MountFSInode { 2511074eb34SSamuel Dai inner_inode, 2521496ba7bSLoGin mount_fs: self.mount_fs.clone(), 2531074eb34SSamuel Dai self_ref: self_ref.clone(), 2541074eb34SSamuel Dai })); 255004e86ffSlogin } 256004e86ffSlogin 257676b8ef6SMork fn truncate(&self, len: usize) -> Result<(), SystemError> { 258004e86ffSlogin return self.inner_inode.truncate(len); 259004e86ffSlogin } 260004e86ffSlogin 261004e86ffSlogin fn read_at( 262004e86ffSlogin &self, 263004e86ffSlogin offset: usize, 264004e86ffSlogin len: usize, 265004e86ffSlogin buf: &mut [u8], 266dfe53cf0SGnoCiYeH data: SpinLockGuard<FilePrivateData>, 267676b8ef6SMork ) -> Result<usize, SystemError> { 26884407d36Slogin return self.inner_inode.read_at(offset, len, buf, data); 269004e86ffSlogin } 270004e86ffSlogin 271004e86ffSlogin fn write_at( 272004e86ffSlogin &self, 273004e86ffSlogin offset: usize, 274004e86ffSlogin len: usize, 275004e86ffSlogin buf: &[u8], 276dfe53cf0SGnoCiYeH data: SpinLockGuard<FilePrivateData>, 277676b8ef6SMork ) -> Result<usize, SystemError> { 27878bf93f0SYJwu2023 return self.inner_inode.write_at(offset, len, buf, data); 279004e86ffSlogin } 280004e86ffSlogin 281004e86ffSlogin #[inline] 282004e86ffSlogin fn fs(&self) -> Arc<dyn FileSystem> { 283004e86ffSlogin return self.mount_fs.clone(); 284004e86ffSlogin } 285004e86ffSlogin 286004e86ffSlogin #[inline] 287004e86ffSlogin fn as_any_ref(&self) -> &dyn core::any::Any { 288004e86ffSlogin return self.inner_inode.as_any_ref(); 289004e86ffSlogin } 290004e86ffSlogin 291004e86ffSlogin #[inline] 292676b8ef6SMork fn metadata(&self) -> Result<super::Metadata, SystemError> { 293004e86ffSlogin return self.inner_inode.metadata(); 294004e86ffSlogin } 295004e86ffSlogin 296004e86ffSlogin #[inline] 297676b8ef6SMork fn set_metadata(&self, metadata: &super::Metadata) -> Result<(), SystemError> { 298004e86ffSlogin return self.inner_inode.set_metadata(metadata); 299004e86ffSlogin } 300004e86ffSlogin 301004e86ffSlogin #[inline] 302676b8ef6SMork fn resize(&self, len: usize) -> Result<(), SystemError> { 303004e86ffSlogin return self.inner_inode.resize(len); 304004e86ffSlogin } 305004e86ffSlogin 306004e86ffSlogin #[inline] 307004e86ffSlogin fn create( 308004e86ffSlogin &self, 309004e86ffSlogin name: &str, 310004e86ffSlogin file_type: FileType, 3116b4e7a29SLoGin mode: ModeType, 312676b8ef6SMork ) -> Result<Arc<dyn IndexNode>, SystemError> { 3131074eb34SSamuel Dai let inner_inode = self.inner_inode.create(name, file_type, mode)?; 3141074eb34SSamuel Dai return Ok(Arc::new_cyclic(|self_ref| MountFSInode { 3151074eb34SSamuel Dai inner_inode, 316004e86ffSlogin mount_fs: self.mount_fs.clone(), 3171074eb34SSamuel Dai self_ref: self_ref.clone(), 3181074eb34SSamuel Dai })); 319004e86ffSlogin } 320004e86ffSlogin 321676b8ef6SMork fn link(&self, name: &str, other: &Arc<dyn IndexNode>) -> Result<(), SystemError> { 322004e86ffSlogin return self.inner_inode.link(name, other); 323004e86ffSlogin } 324004e86ffSlogin 325004e86ffSlogin /// @brief 在挂载文件系统中删除文件/文件夹 326004e86ffSlogin #[inline] 327676b8ef6SMork fn unlink(&self, name: &str) -> Result<(), SystemError> { 328004e86ffSlogin let inode_id = self.inner_inode.find(name)?.metadata()?.inode_id; 329004e86ffSlogin 330004e86ffSlogin // 先检查这个inode是否为一个挂载点,如果当前inode是一个挂载点,那么就不能删除这个inode 331004e86ffSlogin if self.mount_fs.mountpoints.lock().contains_key(&inode_id) { 332676b8ef6SMork return Err(SystemError::EBUSY); 333004e86ffSlogin } 334004e86ffSlogin // 调用内层的inode的方法来删除这个inode 335004e86ffSlogin return self.inner_inode.unlink(name); 336004e86ffSlogin } 337004e86ffSlogin 338004e86ffSlogin #[inline] 339676b8ef6SMork fn rmdir(&self, name: &str) -> Result<(), SystemError> { 340004e86ffSlogin let inode_id = self.inner_inode.find(name)?.metadata()?.inode_id; 34184407d36Slogin 342004e86ffSlogin // 先检查这个inode是否为一个挂载点,如果当前inode是一个挂载点,那么就不能删除这个inode 343004e86ffSlogin if self.mount_fs.mountpoints.lock().contains_key(&inode_id) { 344676b8ef6SMork return Err(SystemError::EBUSY); 345004e86ffSlogin } 346004e86ffSlogin // 调用内层的rmdir的方法来删除这个inode 347004e86ffSlogin let r = self.inner_inode.rmdir(name); 34884407d36Slogin 349004e86ffSlogin return r; 350004e86ffSlogin } 351004e86ffSlogin 352004e86ffSlogin #[inline] 3539e481b3bSTTaq fn move_to( 354004e86ffSlogin &self, 355004e86ffSlogin old_name: &str, 356004e86ffSlogin target: &Arc<dyn IndexNode>, 357004e86ffSlogin new_name: &str, 358676b8ef6SMork ) -> Result<(), SystemError> { 3599e481b3bSTTaq return self.inner_inode.move_to(old_name, target, new_name); 360004e86ffSlogin } 361004e86ffSlogin 362676b8ef6SMork fn find(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError> { 363004e86ffSlogin match name { 364004e86ffSlogin // 查找的是当前目录 3651074eb34SSamuel Dai "" | "." => self 3661074eb34SSamuel Dai .self_ref 3671074eb34SSamuel Dai .upgrade() 3681074eb34SSamuel Dai .map(|inode| inode as Arc<dyn IndexNode>) 3691074eb34SSamuel Dai .ok_or(SystemError::ENOENT), 370004e86ffSlogin // 往父级查找 3711074eb34SSamuel Dai ".." => self.parent(), 372004e86ffSlogin // 在当前目录下查找 373004e86ffSlogin // 直接调用当前inode所在的文件系统的find方法进行查找 374004e86ffSlogin // 由于向下查找可能会跨越文件系统的边界,因此需要尝试替换inode 3751074eb34SSamuel Dai _ => self.do_find(name).map(|inode| inode as Arc<dyn IndexNode>), 376004e86ffSlogin } 377004e86ffSlogin } 378004e86ffSlogin 379004e86ffSlogin #[inline] 380676b8ef6SMork fn get_entry_name(&self, ino: InodeId) -> Result<alloc::string::String, SystemError> { 381004e86ffSlogin return self.inner_inode.get_entry_name(ino); 382004e86ffSlogin } 383004e86ffSlogin 384004e86ffSlogin #[inline] 385004e86ffSlogin fn get_entry_name_and_metadata( 386004e86ffSlogin &self, 387004e86ffSlogin ino: InodeId, 388676b8ef6SMork ) -> Result<(alloc::string::String, super::Metadata), SystemError> { 389004e86ffSlogin return self.inner_inode.get_entry_name_and_metadata(ino); 390004e86ffSlogin } 391004e86ffSlogin 392004e86ffSlogin #[inline] 39352da9a59SGnoCiYeH fn ioctl( 39452da9a59SGnoCiYeH &self, 39552da9a59SGnoCiYeH cmd: u32, 39652da9a59SGnoCiYeH data: usize, 39752da9a59SGnoCiYeH private_data: &FilePrivateData, 39852da9a59SGnoCiYeH ) -> Result<usize, SystemError> { 39952da9a59SGnoCiYeH return self.inner_inode.ioctl(cmd, data, private_data); 400004e86ffSlogin } 401004e86ffSlogin 402004e86ffSlogin #[inline] 403676b8ef6SMork fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, SystemError> { 404004e86ffSlogin return self.inner_inode.list(); 405004e86ffSlogin } 406004e86ffSlogin 407676b8ef6SMork fn mount(&self, fs: Arc<dyn FileSystem>) -> Result<Arc<MountFS>, SystemError> { 408004e86ffSlogin let metadata = self.inner_inode.metadata()?; 409004e86ffSlogin if metadata.file_type != FileType::Dir { 410676b8ef6SMork return Err(SystemError::ENOTDIR); 411004e86ffSlogin } 412004e86ffSlogin 4131074eb34SSamuel Dai if self.is_mountpoint_root()? { 4141074eb34SSamuel Dai return Err(SystemError::EBUSY); 4151074eb34SSamuel Dai } 4161074eb34SSamuel Dai 4171074eb34SSamuel Dai // 若已有挂载系统,保证MountFS只包一层 4181074eb34SSamuel Dai let to_mount_fs = fs 4191074eb34SSamuel Dai .clone() 4201074eb34SSamuel Dai .downcast_arc::<MountFS>() 4211074eb34SSamuel Dai .map(|it| it.inner_filesystem()) 4221074eb34SSamuel Dai .unwrap_or(fs); 4231074eb34SSamuel Dai let new_mount_fs = MountFS::new(to_mount_fs, Some(self.self_ref.upgrade().unwrap())); 4241074eb34SSamuel Dai self.mount_fs 4251074eb34SSamuel Dai .mountpoints 4261074eb34SSamuel Dai .lock() 4271074eb34SSamuel Dai .insert(metadata.inode_id, new_mount_fs.clone()); 4281074eb34SSamuel Dai 4291074eb34SSamuel Dai let mount_path = self.absolute_path(); 4301074eb34SSamuel Dai 4311074eb34SSamuel Dai MOUNT_LIST().insert(mount_path?, new_mount_fs.clone()); 432004e86ffSlogin return Ok(new_mount_fs); 433004e86ffSlogin } 4342dbef785SGnoCiYeH 4351074eb34SSamuel Dai fn mount_from(&self, from: Arc<dyn IndexNode>) -> Result<Arc<MountFS>, SystemError> { 4361074eb34SSamuel Dai let metadata = self.metadata()?; 4371074eb34SSamuel Dai if from.metadata()?.file_type != FileType::Dir || metadata.file_type != FileType::Dir { 4381074eb34SSamuel Dai return Err(SystemError::ENOTDIR); 4391074eb34SSamuel Dai } 4401074eb34SSamuel Dai if self.is_mountpoint_root()? { 4411074eb34SSamuel Dai return Err(SystemError::EBUSY); 4421074eb34SSamuel Dai } 4432eab6dd7S曾俊 // debug!("from {:?}, to {:?}", from, self); 4441074eb34SSamuel Dai let new_mount_fs = from.umount()?; 4451074eb34SSamuel Dai self.mount_fs 4461074eb34SSamuel Dai .mountpoints 4471074eb34SSamuel Dai .lock() 4481074eb34SSamuel Dai .insert(metadata.inode_id, new_mount_fs.clone()); 4491074eb34SSamuel Dai 4501074eb34SSamuel Dai // MOUNT_LIST().remove(from.absolute_path()?); 4511074eb34SSamuel Dai // MOUNT_LIST().insert(self.absolute_path()?, new_mount_fs.clone()); 4521074eb34SSamuel Dai return Ok(new_mount_fs); 4531074eb34SSamuel Dai } 4541074eb34SSamuel Dai 4551074eb34SSamuel Dai fn umount(&self) -> Result<Arc<MountFS>, SystemError> { 4561074eb34SSamuel Dai if !self.is_mountpoint_root()? { 4571074eb34SSamuel Dai return Err(SystemError::EINVAL); 4581074eb34SSamuel Dai } 4591074eb34SSamuel Dai return self.mount_fs.umount(); 4601074eb34SSamuel Dai } 4611074eb34SSamuel Dai 4621074eb34SSamuel Dai fn absolute_path(&self) -> Result<String, SystemError> { 4631074eb34SSamuel Dai self.do_absolute_path(0) 4641074eb34SSamuel Dai } 4651074eb34SSamuel Dai 4662dbef785SGnoCiYeH #[inline] 4672dbef785SGnoCiYeH fn mknod( 4682dbef785SGnoCiYeH &self, 4692dbef785SGnoCiYeH filename: &str, 4702dbef785SGnoCiYeH mode: ModeType, 4712dbef785SGnoCiYeH dev_t: DeviceNumber, 4722dbef785SGnoCiYeH ) -> Result<Arc<dyn IndexNode>, SystemError> { 4731074eb34SSamuel Dai let inner_inode = self.inner_inode.mknod(filename, mode, dev_t)?; 4741074eb34SSamuel Dai return Ok(Arc::new_cyclic(|self_ref| MountFSInode { 4751074eb34SSamuel Dai inner_inode, 4762dbef785SGnoCiYeH mount_fs: self.mount_fs.clone(), 4771074eb34SSamuel Dai self_ref: self_ref.clone(), 4781074eb34SSamuel Dai })); 4792dbef785SGnoCiYeH } 4802dbef785SGnoCiYeH 4812dbef785SGnoCiYeH #[inline] 4822dbef785SGnoCiYeH fn special_node(&self) -> Option<super::SpecialNodeData> { 4832dbef785SGnoCiYeH self.inner_inode.special_node() 4842dbef785SGnoCiYeH } 48552bcb59eSGnoCiYeH 48652bcb59eSGnoCiYeH #[inline] 48752bcb59eSGnoCiYeH fn poll(&self, private_data: &FilePrivateData) -> Result<usize, SystemError> { 48852bcb59eSGnoCiYeH self.inner_inode.poll(private_data) 48952bcb59eSGnoCiYeH } 4901074eb34SSamuel Dai 4911074eb34SSamuel Dai /// 若不支持,则调用第二种情况来从父目录获取文件名 4921074eb34SSamuel Dai /// # Performance 4931074eb34SSamuel Dai /// 应尽可能引入DName, 4941074eb34SSamuel Dai /// 在默认情况下,性能非常差!!! 4951074eb34SSamuel Dai fn dname(&self) -> Result<DName, SystemError> { 4961074eb34SSamuel Dai if self.is_mountpoint_root()? { 4971074eb34SSamuel Dai if let Some(inode) = &self.mount_fs.self_mountpoint { 4981074eb34SSamuel Dai return inode.inner_inode.dname(); 4991074eb34SSamuel Dai } 5001074eb34SSamuel Dai } 5011074eb34SSamuel Dai return self.inner_inode.dname(); 5021074eb34SSamuel Dai } 5031074eb34SSamuel Dai 5041074eb34SSamuel Dai fn parent(&self) -> Result<Arc<dyn IndexNode>, SystemError> { 5051074eb34SSamuel Dai return self.do_parent().map(|inode| inode as Arc<dyn IndexNode>); 5061074eb34SSamuel Dai } 507*cf7f801eSMemoryShore 508*cf7f801eSMemoryShore fn page_cache(&self) -> Option<Arc<PageCache>> { 509*cf7f801eSMemoryShore self.inner_inode.page_cache() 510*cf7f801eSMemoryShore } 511004e86ffSlogin } 512004e86ffSlogin 513004e86ffSlogin impl FileSystem for MountFS { 514004e86ffSlogin fn root_inode(&self) -> Arc<dyn IndexNode> { 515004e86ffSlogin match &self.self_mountpoint { 516004e86ffSlogin Some(inode) => return inode.mount_fs.root_inode(), 517004e86ffSlogin // 当前文件系统是rootfs 518004e86ffSlogin None => self.mountpoint_root_inode(), 519004e86ffSlogin } 520004e86ffSlogin } 521004e86ffSlogin 522004e86ffSlogin fn info(&self) -> super::FsInfo { 523004e86ffSlogin return self.inner_filesystem.info(); 524004e86ffSlogin } 525004e86ffSlogin 526004e86ffSlogin /// @brief 本函数用于实现动态转换。 527004e86ffSlogin /// 具体的文件系统在实现本函数时,最简单的方式就是:直接返回self 528004e86ffSlogin fn as_any_ref(&self) -> &dyn Any { 529004e86ffSlogin self 530004e86ffSlogin } 5311d37ca6dSDonkey Kane 5321d37ca6dSDonkey Kane fn name(&self) -> &str { 5331d37ca6dSDonkey Kane "mountfs" 5341d37ca6dSDonkey Kane } 535597ecc08STTaq fn super_block(&self) -> SuperBlock { 536597ecc08STTaq SuperBlock::new(Magic::MOUNT_MAGIC, MOUNTFS_BLOCK_SIZE, MOUNTFS_MAX_NAMELEN) 537597ecc08STTaq } 538*cf7f801eSMemoryShore 539*cf7f801eSMemoryShore unsafe fn fault(&self, pfm: &mut PageFaultMessage) -> VmFaultReason { 540*cf7f801eSMemoryShore self.inner_filesystem.fault(pfm) 541*cf7f801eSMemoryShore } 542*cf7f801eSMemoryShore 543*cf7f801eSMemoryShore unsafe fn map_pages( 544*cf7f801eSMemoryShore &self, 545*cf7f801eSMemoryShore pfm: &mut PageFaultMessage, 546*cf7f801eSMemoryShore start_pgoff: usize, 547*cf7f801eSMemoryShore end_pgoff: usize, 548*cf7f801eSMemoryShore ) -> VmFaultReason { 549*cf7f801eSMemoryShore self.inner_filesystem.map_pages(pfm, start_pgoff, end_pgoff) 550*cf7f801eSMemoryShore } 551004e86ffSlogin } 5521074eb34SSamuel Dai 5531074eb34SSamuel Dai /// MountList 5541074eb34SSamuel Dai /// ```rust 5551074eb34SSamuel Dai /// use alloc::collection::BTreeSet; 5561074eb34SSamuel Dai /// let map = BTreeSet::from([ 5571074eb34SSamuel Dai /// "/sys", "/dev", "/", "/bin", "/proc" 5581074eb34SSamuel Dai /// ]); 5591074eb34SSamuel Dai /// assert_eq!(format!("{:?}", map), "{\"/\", \"/bin\", \"/dev\", \"/proc\", \"/sys\"}"); 5601074eb34SSamuel Dai /// // {"/", "/bin", "/dev", "/proc", "/sys"} 5611074eb34SSamuel Dai /// ``` 5621074eb34SSamuel Dai #[derive(PartialEq, Eq, Debug)] 5631074eb34SSamuel Dai pub struct MountPath(String); 5641074eb34SSamuel Dai 5651074eb34SSamuel Dai impl From<&str> for MountPath { 5661074eb34SSamuel Dai fn from(value: &str) -> Self { 5671074eb34SSamuel Dai Self(String::from(value)) 5681074eb34SSamuel Dai } 5691074eb34SSamuel Dai } 5701074eb34SSamuel Dai 5711074eb34SSamuel Dai impl From<String> for MountPath { 5721074eb34SSamuel Dai fn from(value: String) -> Self { 5731074eb34SSamuel Dai Self(value) 5741074eb34SSamuel Dai } 5751074eb34SSamuel Dai } 5761074eb34SSamuel Dai 5771074eb34SSamuel Dai impl AsRef<str> for MountPath { 5781074eb34SSamuel Dai fn as_ref(&self) -> &str { 5791074eb34SSamuel Dai &self.0 5801074eb34SSamuel Dai } 5811074eb34SSamuel Dai } 5821074eb34SSamuel Dai 5831074eb34SSamuel Dai impl PartialOrd for MountPath { 5841074eb34SSamuel Dai fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> { 5851074eb34SSamuel Dai Some(self.cmp(other)) 5861074eb34SSamuel Dai } 5871074eb34SSamuel Dai } 5881074eb34SSamuel Dai 5891074eb34SSamuel Dai impl Ord for MountPath { 5901074eb34SSamuel Dai fn cmp(&self, other: &Self) -> core::cmp::Ordering { 5911074eb34SSamuel Dai let self_dep = self.0.chars().filter(|c| *c == '/').count(); 5921074eb34SSamuel Dai let othe_dep = other.0.chars().filter(|c| *c == '/').count(); 5931074eb34SSamuel Dai if self_dep == othe_dep { 5941074eb34SSamuel Dai // 深度一样时反序来排 5951074eb34SSamuel Dai // 根目录和根目录下的文件的绝对路径都只有一个'/' 5961074eb34SSamuel Dai other.0.cmp(&self.0) 5971074eb34SSamuel Dai } else { 5981074eb34SSamuel Dai // 根据深度,深度 5991074eb34SSamuel Dai othe_dep.cmp(&self_dep) 6001074eb34SSamuel Dai } 6011074eb34SSamuel Dai } 6021074eb34SSamuel Dai } 6031074eb34SSamuel Dai 6041074eb34SSamuel Dai // 维护一个挂载点的记录,以支持特定于文件系统的索引 6051074eb34SSamuel Dai pub struct MountList(RwLock<BTreeMap<MountPath, Arc<MountFS>>>); 6061074eb34SSamuel Dai // pub struct MountList(Option<Arc<MountListInner>>); 6071074eb34SSamuel Dai static mut __MOUNTS_LIST: Option<Arc<MountList>> = None; 6081074eb34SSamuel Dai 6091074eb34SSamuel Dai /// # init_mountlist - 初始化挂载列表 6101074eb34SSamuel Dai /// 6111074eb34SSamuel Dai /// 此函数用于初始化系统的挂载列表。挂载列表记录了系统中所有的文件系统挂载点及其属性。 6121074eb34SSamuel Dai /// 6131074eb34SSamuel Dai /// ## 参数 6141074eb34SSamuel Dai /// 6151074eb34SSamuel Dai /// - 无 6161074eb34SSamuel Dai /// 6171074eb34SSamuel Dai /// ## 返回值 6181074eb34SSamuel Dai /// 6191074eb34SSamuel Dai /// - 无 6201074eb34SSamuel Dai #[inline(always)] 6211074eb34SSamuel Dai pub fn init_mountlist() { 6221074eb34SSamuel Dai unsafe { 6231074eb34SSamuel Dai __MOUNTS_LIST = Some(Arc::new(MountList(RwLock::new(BTreeMap::new())))); 6241074eb34SSamuel Dai } 6251074eb34SSamuel Dai } 6261074eb34SSamuel Dai 6271074eb34SSamuel Dai /// # MOUNT_LIST - 获取全局挂载列表 6281074eb34SSamuel Dai /// 6291074eb34SSamuel Dai /// 该函数用于获取一个对全局挂载列表的引用。全局挂载列表是系统中所有挂载点的集合。 6301074eb34SSamuel Dai /// 6311074eb34SSamuel Dai /// ## 返回值 6321074eb34SSamuel Dai /// - &'static Arc<MountList>: 返回全局挂载列表的引用。 6331074eb34SSamuel Dai #[inline(always)] 6341074eb34SSamuel Dai #[allow(non_snake_case)] 6351074eb34SSamuel Dai pub fn MOUNT_LIST() -> &'static Arc<MountList> { 6361074eb34SSamuel Dai unsafe { 6371074eb34SSamuel Dai return __MOUNTS_LIST.as_ref().unwrap(); 6381074eb34SSamuel Dai } 6391074eb34SSamuel Dai } 6401074eb34SSamuel Dai 6411074eb34SSamuel Dai impl MountList { 6421074eb34SSamuel Dai /// # insert - 将文件系统挂载点插入到挂载表中 6431074eb34SSamuel Dai /// 6441074eb34SSamuel Dai /// 将一个新的文件系统挂载点插入到挂载表中。如果挂载点已经存在,则会更新对应的文件系统。 6451074eb34SSamuel Dai /// 6461074eb34SSamuel Dai /// 此函数是线程安全的,因为它使用了RwLock来保证并发访问。 6471074eb34SSamuel Dai /// 6481074eb34SSamuel Dai /// ## 参数 6491074eb34SSamuel Dai /// 6501074eb34SSamuel Dai /// - `path`: &str, 挂载点的路径。这个路径会被转换成`MountPath`类型。 6511074eb34SSamuel Dai /// - `fs`: Arc<MountFS>, 共享的文件系统实例。 6521074eb34SSamuel Dai /// 6531074eb34SSamuel Dai /// ## 返回值 6541074eb34SSamuel Dai /// 6551074eb34SSamuel Dai /// - 无 6561074eb34SSamuel Dai #[inline] 6571074eb34SSamuel Dai pub fn insert<T: AsRef<str>>(&self, path: T, fs: Arc<MountFS>) { 6581074eb34SSamuel Dai self.0.write().insert(MountPath::from(path.as_ref()), fs); 6591074eb34SSamuel Dai } 6601074eb34SSamuel Dai 6611074eb34SSamuel Dai /// # get_mount_point - 获取挂载点的路径 6621074eb34SSamuel Dai /// 6631074eb34SSamuel Dai /// 这个函数用于查找给定路径的挂载点。它搜索一个内部映射,找到与路径匹配的挂载点。 6641074eb34SSamuel Dai /// 6651074eb34SSamuel Dai /// ## 参数 6661074eb34SSamuel Dai /// 6671074eb34SSamuel Dai /// - `path: T`: 这是一个可转换为字符串的引用,表示要查找其挂载点的路径。 6681074eb34SSamuel Dai /// 6691074eb34SSamuel Dai /// ## 返回值 6701074eb34SSamuel Dai /// 6711074eb34SSamuel Dai /// - `Option<(String, String, Arc<MountFS>)>`: 6721074eb34SSamuel Dai /// - `Some((mount_point, rest_path, fs))`: 如果找到了匹配的挂载点,返回一个包含挂载点路径、剩余路径和挂载文件系统的元组。 6731074eb34SSamuel Dai /// - `None`: 如果没有找到匹配的挂载点,返回 None。 6741074eb34SSamuel Dai #[inline] 6751074eb34SSamuel Dai #[allow(dead_code)] 6761074eb34SSamuel Dai pub fn get_mount_point<T: AsRef<str>>( 6771074eb34SSamuel Dai &self, 6781074eb34SSamuel Dai path: T, 6791074eb34SSamuel Dai ) -> Option<(String, String, Arc<MountFS>)> { 6801074eb34SSamuel Dai self.0 6811074eb34SSamuel Dai .upgradeable_read() 6821074eb34SSamuel Dai .iter() 6831074eb34SSamuel Dai .filter_map(|(key, fs)| { 6841074eb34SSamuel Dai let strkey = key.as_ref(); 6851074eb34SSamuel Dai if let Some(rest) = path.as_ref().strip_prefix(strkey) { 6861074eb34SSamuel Dai return Some((strkey.to_string(), rest.to_string(), fs.clone())); 6871074eb34SSamuel Dai } 6881074eb34SSamuel Dai None 6891074eb34SSamuel Dai }) 6901074eb34SSamuel Dai .next() 6911074eb34SSamuel Dai } 6921074eb34SSamuel Dai 6931074eb34SSamuel Dai /// # remove - 移除挂载点 6941074eb34SSamuel Dai /// 6951074eb34SSamuel Dai /// 从挂载点管理器中移除一个挂载点。 6961074eb34SSamuel Dai /// 6971074eb34SSamuel Dai /// 此函数用于从挂载点管理器中移除一个已经存在的挂载点。如果挂载点不存在,则不进行任何操作。 6981074eb34SSamuel Dai /// 6991074eb34SSamuel Dai /// ## 参数 7001074eb34SSamuel Dai /// 7011074eb34SSamuel Dai /// - `path: T`: `T` 实现了 `Into<MountPath>` trait,代表要移除的挂载点的路径。 7021074eb34SSamuel Dai /// 7031074eb34SSamuel Dai /// ## 返回值 7041074eb34SSamuel Dai /// 7051074eb34SSamuel Dai /// - `Option<Arc<MountFS>>`: 返回一个 `Arc<MountFS>` 类型的可选值,表示被移除的挂载点,如果挂载点不存在则返回 `None`。 7061074eb34SSamuel Dai #[inline] 7071074eb34SSamuel Dai pub fn remove<T: Into<MountPath>>(&self, path: T) -> Option<Arc<MountFS>> { 7081074eb34SSamuel Dai self.0.write().remove(&path.into()) 7091074eb34SSamuel Dai } 7101074eb34SSamuel Dai } 7111074eb34SSamuel Dai 7121074eb34SSamuel Dai impl Debug for MountList { 7131074eb34SSamuel Dai fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 7141074eb34SSamuel Dai f.debug_map().entries(MOUNT_LIST().0.read().iter()).finish() 7151074eb34SSamuel Dai } 7161074eb34SSamuel Dai } 717