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