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