1004e86ffSlogin use core::any::Any; 2004e86ffSlogin 3004e86ffSlogin use alloc::{ 4004e86ffSlogin collections::BTreeMap, 5004e86ffSlogin sync::{Arc, Weak}, 6004e86ffSlogin }; 7004e86ffSlogin 8004e86ffSlogin use crate::{ 9004e86ffSlogin include::bindings::bindings::{EBUSY, ENOTDIR}, 10*84407d36Slogin libs::spinlock::SpinLock, 11004e86ffSlogin }; 12004e86ffSlogin 13004e86ffSlogin use super::{FilePrivateData, FileSystem, FileType, IndexNode, InodeId}; 14004e86ffSlogin 15004e86ffSlogin /// @brief 挂载文件系统 16004e86ffSlogin /// 挂载文件系统的时候,套了MountFS这一层,以实现文件系统的递归挂载 17004e86ffSlogin #[derive(Debug)] 18004e86ffSlogin pub struct MountFS { 19004e86ffSlogin // MountFS内部的文件系统 20004e86ffSlogin inner_filesystem: Arc<dyn FileSystem>, 21004e86ffSlogin /// 用来存储InodeID->挂载点的MountFS的B树 22004e86ffSlogin mountpoints: SpinLock<BTreeMap<InodeId, Arc<MountFS>>>, 23004e86ffSlogin /// 当前文件系统挂载到的那个挂载点的Inode 24004e86ffSlogin self_mountpoint: Option<Arc<MountFSInode>>, 25004e86ffSlogin /// 指向当前MountFS的弱引用 26004e86ffSlogin self_ref: Weak<MountFS>, 27004e86ffSlogin } 28004e86ffSlogin 29004e86ffSlogin /// @brief MountFS的Index Node 注意,这个IndexNode只是一个中间层。它的目的是将具体文件系统的Inode与挂载机制连接在一起。 30004e86ffSlogin #[derive(Debug)] 31004e86ffSlogin pub struct MountFSInode { 32004e86ffSlogin /// 当前挂载点对应到具体的文件系统的Inode 33004e86ffSlogin inner_inode: Arc<dyn IndexNode>, 34004e86ffSlogin /// 当前Inode对应的MountFS 35004e86ffSlogin mount_fs: Arc<MountFS>, 36004e86ffSlogin /// 指向自身的弱引用 37004e86ffSlogin self_ref: Weak<MountFSInode>, 38004e86ffSlogin } 39004e86ffSlogin 40004e86ffSlogin impl MountFS { 41004e86ffSlogin pub fn new( 42004e86ffSlogin inner_fs: Arc<dyn FileSystem>, 43004e86ffSlogin self_mountpoint: Option<Arc<MountFSInode>>, 44004e86ffSlogin ) -> Arc<Self> { 45004e86ffSlogin return MountFS { 46004e86ffSlogin inner_filesystem: inner_fs, 47004e86ffSlogin mountpoints: SpinLock::new(BTreeMap::new()), 48004e86ffSlogin self_mountpoint: self_mountpoint, 49004e86ffSlogin self_ref: Weak::default(), 50004e86ffSlogin } 51004e86ffSlogin .wrap(); 52004e86ffSlogin } 53004e86ffSlogin 54004e86ffSlogin /// @brief 用Arc指针包裹MountFS对象。 55004e86ffSlogin /// 本函数的主要功能为,初始化MountFS对象中的自引用Weak指针 56004e86ffSlogin /// 本函数只应在构造器中被调用 57004e86ffSlogin fn wrap(self) -> Arc<Self> { 58004e86ffSlogin // 创建Arc指针 59004e86ffSlogin let mount_fs: Arc<MountFS> = Arc::new(self); 60004e86ffSlogin // 创建weak指针 61004e86ffSlogin let weak: Weak<MountFS> = Arc::downgrade(&mount_fs); 62004e86ffSlogin 63004e86ffSlogin // 将Arc指针转为Raw指针并对其内部的self_ref字段赋值 64004e86ffSlogin let ptr: *mut MountFS = Arc::into_raw(mount_fs) as *mut Self; 65004e86ffSlogin unsafe { 66004e86ffSlogin (*ptr).self_ref = weak; 67004e86ffSlogin // 返回初始化好的MountFS对象 68004e86ffSlogin return Arc::from_raw(ptr); 69004e86ffSlogin } 70004e86ffSlogin } 71004e86ffSlogin 72004e86ffSlogin /// @brief 获取挂载点的文件系统的root inode 73004e86ffSlogin pub fn mountpoint_root_inode(&self) -> Arc<MountFSInode> { 74004e86ffSlogin return MountFSInode { 75004e86ffSlogin inner_inode: self.inner_filesystem.root_inode(), 76004e86ffSlogin mount_fs: self.self_ref.upgrade().unwrap(), 77004e86ffSlogin self_ref: Weak::default(), 78004e86ffSlogin } 79004e86ffSlogin .wrap(); 80004e86ffSlogin } 81004e86ffSlogin 82004e86ffSlogin pub fn inner_filesystem(&self) -> Arc<dyn FileSystem> { 83004e86ffSlogin return self.inner_filesystem.clone(); 84004e86ffSlogin } 85004e86ffSlogin } 86004e86ffSlogin 87004e86ffSlogin impl MountFSInode { 88004e86ffSlogin /// @brief 用Arc指针包裹MountFSInode对象。 89004e86ffSlogin /// 本函数的主要功能为,初始化MountFSInode对象中的自引用Weak指针 90004e86ffSlogin /// 本函数只应在构造器中被调用 91004e86ffSlogin fn wrap(self) -> Arc<Self> { 92004e86ffSlogin // 创建Arc指针 93004e86ffSlogin let inode: Arc<MountFSInode> = Arc::new(self); 94004e86ffSlogin // 创建Weak指针 95004e86ffSlogin let weak: Weak<MountFSInode> = Arc::downgrade(&inode); 96004e86ffSlogin // 将Arc指针转为Raw指针并对其内部的self_ref字段赋值 97004e86ffSlogin let ptr: *mut MountFSInode = Arc::into_raw(inode) as *mut Self; 98004e86ffSlogin unsafe { 99004e86ffSlogin (*ptr).self_ref = weak; 100004e86ffSlogin 101004e86ffSlogin // 返回初始化好的MountFSInode对象 102004e86ffSlogin return Arc::from_raw(ptr); 103004e86ffSlogin } 104004e86ffSlogin } 105004e86ffSlogin 106004e86ffSlogin /// @brief 判断当前inode是否为它所在的文件系统的root inode 107004e86ffSlogin fn is_mountpoint_root(&self) -> Result<bool, i32> { 108004e86ffSlogin return Ok(self.inner_inode.fs().root_inode().metadata()?.inode_id 109004e86ffSlogin == self.inner_inode.metadata()?.inode_id); 110004e86ffSlogin } 111004e86ffSlogin 112004e86ffSlogin /// @brief 在挂载树上进行inode替换。 113004e86ffSlogin /// 如果当前inode是父MountFS内的一个挂载点,那么,本函数将会返回挂载到这个挂载点下的文件系统的root inode. 114004e86ffSlogin /// 如果当前inode在父MountFS内,但不是挂载点,那么说明在这里不需要进行inode替换,因此直接返回当前inode。 115004e86ffSlogin /// 116004e86ffSlogin /// @return Arc<MountFSInode> 117004e86ffSlogin fn overlaid_inode(&self) -> Arc<MountFSInode> { 118004e86ffSlogin let inode_id = self.metadata().unwrap().inode_id; 119004e86ffSlogin 120004e86ffSlogin if let Some(sub_mountfs) = self.mount_fs.mountpoints.lock().get(&inode_id) { 121004e86ffSlogin return sub_mountfs.mountpoint_root_inode(); 122004e86ffSlogin } else { 123004e86ffSlogin return self.self_ref.upgrade().unwrap(); 124004e86ffSlogin } 125004e86ffSlogin } 126004e86ffSlogin } 127004e86ffSlogin 128004e86ffSlogin impl IndexNode for MountFSInode { 129004e86ffSlogin fn open(&self, data: &mut FilePrivateData) -> Result<(), i32> { 130004e86ffSlogin return self.inner_inode.open(data); 131004e86ffSlogin } 132004e86ffSlogin 133004e86ffSlogin fn close(&self, data: &mut FilePrivateData) -> Result<(), i32> { 134004e86ffSlogin return self.inner_inode.close(data); 135004e86ffSlogin } 136004e86ffSlogin 137004e86ffSlogin fn create_with_data( 138004e86ffSlogin &self, 139004e86ffSlogin name: &str, 140004e86ffSlogin file_type: FileType, 141004e86ffSlogin mode: u32, 142004e86ffSlogin data: usize, 143004e86ffSlogin ) -> Result<Arc<dyn IndexNode>, i32> { 144004e86ffSlogin return self 145004e86ffSlogin .inner_inode 146004e86ffSlogin .create_with_data(name, file_type, mode, data); 147004e86ffSlogin } 148004e86ffSlogin 149004e86ffSlogin fn truncate(&self, len: usize) -> Result<(), i32> { 150004e86ffSlogin return self.inner_inode.truncate(len); 151004e86ffSlogin } 152004e86ffSlogin 153004e86ffSlogin fn read_at( 154004e86ffSlogin &self, 155004e86ffSlogin offset: usize, 156004e86ffSlogin len: usize, 157004e86ffSlogin buf: &mut [u8], 158004e86ffSlogin data: &mut FilePrivateData, 159004e86ffSlogin ) -> Result<usize, i32> { 160*84407d36Slogin return self.inner_inode.read_at(offset, len, buf, data); 161004e86ffSlogin } 162004e86ffSlogin 163004e86ffSlogin fn write_at( 164004e86ffSlogin &self, 165004e86ffSlogin offset: usize, 166004e86ffSlogin len: usize, 167004e86ffSlogin buf: &[u8], 168004e86ffSlogin _data: &mut FilePrivateData, 169004e86ffSlogin ) -> Result<usize, i32> { 170004e86ffSlogin return self 171004e86ffSlogin .inner_inode 172004e86ffSlogin .write_at(offset, len, buf, &mut FilePrivateData::Unused); 173004e86ffSlogin } 174004e86ffSlogin 175004e86ffSlogin #[inline] 176004e86ffSlogin fn poll(&self) -> Result<super::PollStatus, i32> { 177004e86ffSlogin return self.inner_inode.poll(); 178004e86ffSlogin } 179004e86ffSlogin 180004e86ffSlogin #[inline] 181004e86ffSlogin fn fs(&self) -> Arc<dyn FileSystem> { 182004e86ffSlogin return self.mount_fs.clone(); 183004e86ffSlogin } 184004e86ffSlogin 185004e86ffSlogin #[inline] 186004e86ffSlogin fn as_any_ref(&self) -> &dyn core::any::Any { 187004e86ffSlogin return self.inner_inode.as_any_ref(); 188004e86ffSlogin } 189004e86ffSlogin 190004e86ffSlogin #[inline] 191004e86ffSlogin fn metadata(&self) -> Result<super::Metadata, i32> { 192004e86ffSlogin return self.inner_inode.metadata(); 193004e86ffSlogin } 194004e86ffSlogin 195004e86ffSlogin #[inline] 196004e86ffSlogin fn set_metadata(&self, metadata: &super::Metadata) -> Result<(), i32> { 197004e86ffSlogin return self.inner_inode.set_metadata(metadata); 198004e86ffSlogin } 199004e86ffSlogin 200004e86ffSlogin #[inline] 201004e86ffSlogin fn resize(&self, len: usize) -> Result<(), i32> { 202004e86ffSlogin return self.inner_inode.resize(len); 203004e86ffSlogin } 204004e86ffSlogin 205004e86ffSlogin #[inline] 206004e86ffSlogin fn create( 207004e86ffSlogin &self, 208004e86ffSlogin name: &str, 209004e86ffSlogin file_type: FileType, 210004e86ffSlogin mode: u32, 211004e86ffSlogin ) -> Result<Arc<dyn IndexNode>, i32> { 212004e86ffSlogin return Ok(MountFSInode { 213004e86ffSlogin inner_inode: self.inner_inode.create(name, file_type, mode)?, 214004e86ffSlogin mount_fs: self.mount_fs.clone(), 215004e86ffSlogin self_ref: Weak::default(), 216004e86ffSlogin } 217004e86ffSlogin .wrap()); 218004e86ffSlogin } 219004e86ffSlogin 220004e86ffSlogin fn link(&self, name: &str, other: &Arc<dyn IndexNode>) -> Result<(), i32> { 221004e86ffSlogin return self.inner_inode.link(name, other); 222004e86ffSlogin } 223004e86ffSlogin 224004e86ffSlogin /// @brief 在挂载文件系统中删除文件/文件夹 225004e86ffSlogin #[inline] 226004e86ffSlogin fn unlink(&self, name: &str) -> Result<(), i32> { 227004e86ffSlogin let inode_id = self.inner_inode.find(name)?.metadata()?.inode_id; 228004e86ffSlogin 229004e86ffSlogin // 先检查这个inode是否为一个挂载点,如果当前inode是一个挂载点,那么就不能删除这个inode 230004e86ffSlogin if self.mount_fs.mountpoints.lock().contains_key(&inode_id) { 231004e86ffSlogin return Err(-(EBUSY as i32)); 232004e86ffSlogin } 233004e86ffSlogin // 调用内层的inode的方法来删除这个inode 234004e86ffSlogin return self.inner_inode.unlink(name); 235004e86ffSlogin } 236004e86ffSlogin 237004e86ffSlogin #[inline] 238004e86ffSlogin fn rmdir(&self, name: &str) -> Result<(), i32> { 239004e86ffSlogin let inode_id = self.inner_inode.find(name)?.metadata()?.inode_id; 240*84407d36Slogin 241004e86ffSlogin // 先检查这个inode是否为一个挂载点,如果当前inode是一个挂载点,那么就不能删除这个inode 242004e86ffSlogin if self.mount_fs.mountpoints.lock().contains_key(&inode_id) { 243004e86ffSlogin return Err(-(EBUSY as i32)); 244004e86ffSlogin } 245004e86ffSlogin // 调用内层的rmdir的方法来删除这个inode 246004e86ffSlogin let r = self.inner_inode.rmdir(name); 247*84407d36Slogin 248004e86ffSlogin return r; 249004e86ffSlogin } 250004e86ffSlogin 251004e86ffSlogin #[inline] 252004e86ffSlogin fn move_( 253004e86ffSlogin &self, 254004e86ffSlogin old_name: &str, 255004e86ffSlogin target: &Arc<dyn IndexNode>, 256004e86ffSlogin new_name: &str, 257004e86ffSlogin ) -> Result<(), i32> { 258004e86ffSlogin return self.inner_inode.move_(old_name, target, new_name); 259004e86ffSlogin } 260004e86ffSlogin 261004e86ffSlogin fn find(&self, name: &str) -> Result<Arc<dyn IndexNode>, i32> { 262004e86ffSlogin match name { 263004e86ffSlogin // 查找的是当前目录 264004e86ffSlogin "" | "." => return Ok(self.self_ref.upgrade().unwrap()), 265004e86ffSlogin // 往父级查找 266004e86ffSlogin ".." => { 267004e86ffSlogin if self.is_mountpoint_root()? { 268004e86ffSlogin // 当前inode是它所在的文件系统的root inode 269004e86ffSlogin match &self.mount_fs.self_mountpoint { 270004e86ffSlogin Some(inode) => { 271004e86ffSlogin return inode.find(name); 272004e86ffSlogin } 273004e86ffSlogin None => { 274004e86ffSlogin return Ok(self.self_ref.upgrade().unwrap()); 275004e86ffSlogin } 276004e86ffSlogin } 277004e86ffSlogin } else { 278004e86ffSlogin // 向上查找时,不会跨过文件系统的边界,因此直接调用当前inode所在的文件系统的find方法进行查找 279004e86ffSlogin return Ok(MountFSInode { 280004e86ffSlogin inner_inode: self.inner_inode.find(name)?, 281004e86ffSlogin mount_fs: self.mount_fs.clone(), 282004e86ffSlogin self_ref: Weak::default(), 283004e86ffSlogin } 284004e86ffSlogin .wrap()); 285004e86ffSlogin } 286004e86ffSlogin } 287004e86ffSlogin // 在当前目录下查找 288004e86ffSlogin _ => { 289004e86ffSlogin // 直接调用当前inode所在的文件系统的find方法进行查找 290004e86ffSlogin // 由于向下查找可能会跨越文件系统的边界,因此需要尝试替换inode 291004e86ffSlogin return Ok(MountFSInode { 292004e86ffSlogin inner_inode: self.inner_inode.find(name)?, 293004e86ffSlogin mount_fs: self.mount_fs.clone(), 294004e86ffSlogin self_ref: Weak::default(), 295004e86ffSlogin } 296004e86ffSlogin .wrap() 297004e86ffSlogin .overlaid_inode()); 298004e86ffSlogin } 299004e86ffSlogin } 300004e86ffSlogin } 301004e86ffSlogin 302004e86ffSlogin #[inline] 303004e86ffSlogin fn get_entry_name(&self, ino: InodeId) -> Result<alloc::string::String, i32> { 304004e86ffSlogin return self.inner_inode.get_entry_name(ino); 305004e86ffSlogin } 306004e86ffSlogin 307004e86ffSlogin #[inline] 308004e86ffSlogin fn get_entry_name_and_metadata( 309004e86ffSlogin &self, 310004e86ffSlogin ino: InodeId, 311004e86ffSlogin ) -> Result<(alloc::string::String, super::Metadata), i32> { 312004e86ffSlogin return self.inner_inode.get_entry_name_and_metadata(ino); 313004e86ffSlogin } 314004e86ffSlogin 315004e86ffSlogin #[inline] 316004e86ffSlogin fn ioctl(&self, cmd: u32, data: usize) -> Result<usize, i32> { 317004e86ffSlogin return self.inner_inode.ioctl(cmd, data); 318004e86ffSlogin } 319004e86ffSlogin 320004e86ffSlogin #[inline] 321004e86ffSlogin fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, i32> { 322004e86ffSlogin return self.inner_inode.list(); 323004e86ffSlogin } 324004e86ffSlogin 325004e86ffSlogin /// @brief 在当前inode下,挂载一个文件系统 326004e86ffSlogin /// 327004e86ffSlogin /// @return Ok(Arc<MountFS>) 挂载成功,返回指向MountFS的指针 328004e86ffSlogin fn mount(&self, fs: Arc<dyn FileSystem>) -> Result<Arc<MountFS>, i32> { 329004e86ffSlogin let metadata = self.inner_inode.metadata()?; 330004e86ffSlogin if metadata.file_type != FileType::Dir { 331004e86ffSlogin return Err(-(ENOTDIR as i32)); 332004e86ffSlogin } 333004e86ffSlogin 334004e86ffSlogin // 为新的挂载点创建挂载文件系统 335004e86ffSlogin let new_mount_fs: Arc<MountFS> = MountFS::new(fs, Some(self.self_ref.upgrade().unwrap())); 336004e86ffSlogin // 将新的挂载点-挂载文件系统添加到父级的挂载树 337004e86ffSlogin self.mount_fs 338004e86ffSlogin .mountpoints 339004e86ffSlogin .lock() 340004e86ffSlogin .insert(metadata.inode_id, new_mount_fs.clone()); 341004e86ffSlogin return Ok(new_mount_fs); 342004e86ffSlogin } 343004e86ffSlogin } 344004e86ffSlogin 345004e86ffSlogin impl FileSystem for MountFS { 346004e86ffSlogin fn root_inode(&self) -> Arc<dyn IndexNode> { 347004e86ffSlogin match &self.self_mountpoint { 348004e86ffSlogin Some(inode) => return inode.mount_fs.root_inode(), 349004e86ffSlogin // 当前文件系统是rootfs 350004e86ffSlogin None => self.mountpoint_root_inode(), 351004e86ffSlogin } 352004e86ffSlogin } 353004e86ffSlogin 354004e86ffSlogin fn info(&self) -> super::FsInfo { 355004e86ffSlogin return self.inner_filesystem.info(); 356004e86ffSlogin } 357004e86ffSlogin 358004e86ffSlogin /// @brief 本函数用于实现动态转换。 359004e86ffSlogin /// 具体的文件系统在实现本函数时,最简单的方式就是:直接返回self 360004e86ffSlogin fn as_any_ref(&self) -> &dyn Any { 361004e86ffSlogin self 362004e86ffSlogin } 363004e86ffSlogin } 364