1*004e86ffSlogin use core::any::Any; 2*004e86ffSlogin 3*004e86ffSlogin use alloc::{ 4*004e86ffSlogin collections::BTreeMap, 5*004e86ffSlogin sync::{Arc, Weak}, 6*004e86ffSlogin }; 7*004e86ffSlogin 8*004e86ffSlogin use crate::{ 9*004e86ffSlogin include::bindings::bindings::{EBUSY, ENOTDIR}, 10*004e86ffSlogin libs::spinlock::SpinLock, kdebug, 11*004e86ffSlogin }; 12*004e86ffSlogin 13*004e86ffSlogin use super::{FilePrivateData, FileSystem, FileType, IndexNode, InodeId}; 14*004e86ffSlogin 15*004e86ffSlogin /// @brief 挂载文件系统 16*004e86ffSlogin /// 挂载文件系统的时候,套了MountFS这一层,以实现文件系统的递归挂载 17*004e86ffSlogin #[derive(Debug)] 18*004e86ffSlogin pub struct MountFS { 19*004e86ffSlogin // MountFS内部的文件系统 20*004e86ffSlogin inner_filesystem: Arc<dyn FileSystem>, 21*004e86ffSlogin /// 用来存储InodeID->挂载点的MountFS的B树 22*004e86ffSlogin mountpoints: SpinLock<BTreeMap<InodeId, Arc<MountFS>>>, 23*004e86ffSlogin /// 当前文件系统挂载到的那个挂载点的Inode 24*004e86ffSlogin self_mountpoint: Option<Arc<MountFSInode>>, 25*004e86ffSlogin /// 指向当前MountFS的弱引用 26*004e86ffSlogin self_ref: Weak<MountFS>, 27*004e86ffSlogin } 28*004e86ffSlogin 29*004e86ffSlogin /// @brief MountFS的Index Node 注意,这个IndexNode只是一个中间层。它的目的是将具体文件系统的Inode与挂载机制连接在一起。 30*004e86ffSlogin #[derive(Debug)] 31*004e86ffSlogin pub struct MountFSInode { 32*004e86ffSlogin /// 当前挂载点对应到具体的文件系统的Inode 33*004e86ffSlogin inner_inode: Arc<dyn IndexNode>, 34*004e86ffSlogin /// 当前Inode对应的MountFS 35*004e86ffSlogin mount_fs: Arc<MountFS>, 36*004e86ffSlogin /// 指向自身的弱引用 37*004e86ffSlogin self_ref: Weak<MountFSInode>, 38*004e86ffSlogin } 39*004e86ffSlogin 40*004e86ffSlogin impl MountFS { 41*004e86ffSlogin pub fn new( 42*004e86ffSlogin inner_fs: Arc<dyn FileSystem>, 43*004e86ffSlogin self_mountpoint: Option<Arc<MountFSInode>>, 44*004e86ffSlogin ) -> Arc<Self> { 45*004e86ffSlogin return MountFS { 46*004e86ffSlogin inner_filesystem: inner_fs, 47*004e86ffSlogin mountpoints: SpinLock::new(BTreeMap::new()), 48*004e86ffSlogin self_mountpoint: self_mountpoint, 49*004e86ffSlogin self_ref: Weak::default(), 50*004e86ffSlogin } 51*004e86ffSlogin .wrap(); 52*004e86ffSlogin } 53*004e86ffSlogin 54*004e86ffSlogin /// @brief 用Arc指针包裹MountFS对象。 55*004e86ffSlogin /// 本函数的主要功能为,初始化MountFS对象中的自引用Weak指针 56*004e86ffSlogin /// 本函数只应在构造器中被调用 57*004e86ffSlogin fn wrap(self) -> Arc<Self> { 58*004e86ffSlogin // 创建Arc指针 59*004e86ffSlogin let mount_fs: Arc<MountFS> = Arc::new(self); 60*004e86ffSlogin // 创建weak指针 61*004e86ffSlogin let weak: Weak<MountFS> = Arc::downgrade(&mount_fs); 62*004e86ffSlogin 63*004e86ffSlogin // 将Arc指针转为Raw指针并对其内部的self_ref字段赋值 64*004e86ffSlogin let ptr: *mut MountFS = Arc::into_raw(mount_fs) as *mut Self; 65*004e86ffSlogin unsafe { 66*004e86ffSlogin (*ptr).self_ref = weak; 67*004e86ffSlogin // 返回初始化好的MountFS对象 68*004e86ffSlogin return Arc::from_raw(ptr); 69*004e86ffSlogin } 70*004e86ffSlogin } 71*004e86ffSlogin 72*004e86ffSlogin /// @brief 获取挂载点的文件系统的root inode 73*004e86ffSlogin pub fn mountpoint_root_inode(&self) -> Arc<MountFSInode> { 74*004e86ffSlogin return MountFSInode { 75*004e86ffSlogin inner_inode: self.inner_filesystem.root_inode(), 76*004e86ffSlogin mount_fs: self.self_ref.upgrade().unwrap(), 77*004e86ffSlogin self_ref: Weak::default(), 78*004e86ffSlogin } 79*004e86ffSlogin .wrap(); 80*004e86ffSlogin } 81*004e86ffSlogin 82*004e86ffSlogin pub fn inner_filesystem(&self) -> Arc<dyn FileSystem> { 83*004e86ffSlogin return self.inner_filesystem.clone(); 84*004e86ffSlogin } 85*004e86ffSlogin } 86*004e86ffSlogin 87*004e86ffSlogin impl MountFSInode { 88*004e86ffSlogin /// @brief 用Arc指针包裹MountFSInode对象。 89*004e86ffSlogin /// 本函数的主要功能为,初始化MountFSInode对象中的自引用Weak指针 90*004e86ffSlogin /// 本函数只应在构造器中被调用 91*004e86ffSlogin fn wrap(self) -> Arc<Self> { 92*004e86ffSlogin // 创建Arc指针 93*004e86ffSlogin let inode: Arc<MountFSInode> = Arc::new(self); 94*004e86ffSlogin // 创建Weak指针 95*004e86ffSlogin let weak: Weak<MountFSInode> = Arc::downgrade(&inode); 96*004e86ffSlogin // 将Arc指针转为Raw指针并对其内部的self_ref字段赋值 97*004e86ffSlogin let ptr: *mut MountFSInode = Arc::into_raw(inode) as *mut Self; 98*004e86ffSlogin unsafe { 99*004e86ffSlogin (*ptr).self_ref = weak; 100*004e86ffSlogin 101*004e86ffSlogin // 返回初始化好的MountFSInode对象 102*004e86ffSlogin return Arc::from_raw(ptr); 103*004e86ffSlogin } 104*004e86ffSlogin } 105*004e86ffSlogin 106*004e86ffSlogin /// @brief 判断当前inode是否为它所在的文件系统的root inode 107*004e86ffSlogin fn is_mountpoint_root(&self) -> Result<bool, i32> { 108*004e86ffSlogin return Ok(self.inner_inode.fs().root_inode().metadata()?.inode_id 109*004e86ffSlogin == self.inner_inode.metadata()?.inode_id); 110*004e86ffSlogin } 111*004e86ffSlogin 112*004e86ffSlogin /// @brief 在挂载树上进行inode替换。 113*004e86ffSlogin /// 如果当前inode是父MountFS内的一个挂载点,那么,本函数将会返回挂载到这个挂载点下的文件系统的root inode. 114*004e86ffSlogin /// 如果当前inode在父MountFS内,但不是挂载点,那么说明在这里不需要进行inode替换,因此直接返回当前inode。 115*004e86ffSlogin /// 116*004e86ffSlogin /// @return Arc<MountFSInode> 117*004e86ffSlogin fn overlaid_inode(&self) -> Arc<MountFSInode> { 118*004e86ffSlogin let inode_id = self.metadata().unwrap().inode_id; 119*004e86ffSlogin 120*004e86ffSlogin if let Some(sub_mountfs) = self.mount_fs.mountpoints.lock().get(&inode_id) { 121*004e86ffSlogin return sub_mountfs.mountpoint_root_inode(); 122*004e86ffSlogin } else { 123*004e86ffSlogin return self.self_ref.upgrade().unwrap(); 124*004e86ffSlogin } 125*004e86ffSlogin } 126*004e86ffSlogin } 127*004e86ffSlogin 128*004e86ffSlogin impl IndexNode for MountFSInode { 129*004e86ffSlogin fn open(&self, data: &mut FilePrivateData) -> Result<(), i32> { 130*004e86ffSlogin return self.inner_inode.open(data); 131*004e86ffSlogin } 132*004e86ffSlogin 133*004e86ffSlogin fn close(&self, data: &mut FilePrivateData) -> Result<(), i32> { 134*004e86ffSlogin return self.inner_inode.close(data); 135*004e86ffSlogin } 136*004e86ffSlogin 137*004e86ffSlogin fn create_with_data( 138*004e86ffSlogin &self, 139*004e86ffSlogin name: &str, 140*004e86ffSlogin file_type: FileType, 141*004e86ffSlogin mode: u32, 142*004e86ffSlogin data: usize, 143*004e86ffSlogin ) -> Result<Arc<dyn IndexNode>, i32> { 144*004e86ffSlogin return self 145*004e86ffSlogin .inner_inode 146*004e86ffSlogin .create_with_data(name, file_type, mode, data); 147*004e86ffSlogin } 148*004e86ffSlogin 149*004e86ffSlogin fn truncate(&self, len: usize) -> Result<(), i32> { 150*004e86ffSlogin return self.inner_inode.truncate(len); 151*004e86ffSlogin } 152*004e86ffSlogin 153*004e86ffSlogin fn read_at( 154*004e86ffSlogin &self, 155*004e86ffSlogin offset: usize, 156*004e86ffSlogin len: usize, 157*004e86ffSlogin buf: &mut [u8], 158*004e86ffSlogin data: &mut FilePrivateData, 159*004e86ffSlogin ) -> Result<usize, i32> { 160*004e86ffSlogin return self 161*004e86ffSlogin .inner_inode 162*004e86ffSlogin .read_at(offset, len, buf, data); 163*004e86ffSlogin } 164*004e86ffSlogin 165*004e86ffSlogin fn write_at( 166*004e86ffSlogin &self, 167*004e86ffSlogin offset: usize, 168*004e86ffSlogin len: usize, 169*004e86ffSlogin buf: &[u8], 170*004e86ffSlogin _data: &mut FilePrivateData, 171*004e86ffSlogin ) -> Result<usize, i32> { 172*004e86ffSlogin return self 173*004e86ffSlogin .inner_inode 174*004e86ffSlogin .write_at(offset, len, buf, &mut FilePrivateData::Unused); 175*004e86ffSlogin } 176*004e86ffSlogin 177*004e86ffSlogin #[inline] 178*004e86ffSlogin fn poll(&self) -> Result<super::PollStatus, i32> { 179*004e86ffSlogin return self.inner_inode.poll(); 180*004e86ffSlogin } 181*004e86ffSlogin 182*004e86ffSlogin #[inline] 183*004e86ffSlogin fn fs(&self) -> Arc<dyn FileSystem> { 184*004e86ffSlogin return self.mount_fs.clone(); 185*004e86ffSlogin } 186*004e86ffSlogin 187*004e86ffSlogin #[inline] 188*004e86ffSlogin fn as_any_ref(&self) -> &dyn core::any::Any { 189*004e86ffSlogin return self.inner_inode.as_any_ref(); 190*004e86ffSlogin } 191*004e86ffSlogin 192*004e86ffSlogin #[inline] 193*004e86ffSlogin fn metadata(&self) -> Result<super::Metadata, i32> { 194*004e86ffSlogin return self.inner_inode.metadata(); 195*004e86ffSlogin } 196*004e86ffSlogin 197*004e86ffSlogin #[inline] 198*004e86ffSlogin fn set_metadata(&self, metadata: &super::Metadata) -> Result<(), i32> { 199*004e86ffSlogin return self.inner_inode.set_metadata(metadata); 200*004e86ffSlogin } 201*004e86ffSlogin 202*004e86ffSlogin #[inline] 203*004e86ffSlogin fn resize(&self, len: usize) -> Result<(), i32> { 204*004e86ffSlogin return self.inner_inode.resize(len); 205*004e86ffSlogin } 206*004e86ffSlogin 207*004e86ffSlogin #[inline] 208*004e86ffSlogin fn create( 209*004e86ffSlogin &self, 210*004e86ffSlogin name: &str, 211*004e86ffSlogin file_type: FileType, 212*004e86ffSlogin mode: u32, 213*004e86ffSlogin ) -> Result<Arc<dyn IndexNode>, i32> { 214*004e86ffSlogin return Ok(MountFSInode { 215*004e86ffSlogin inner_inode: self.inner_inode.create(name, file_type, mode)?, 216*004e86ffSlogin mount_fs: self.mount_fs.clone(), 217*004e86ffSlogin self_ref: Weak::default(), 218*004e86ffSlogin } 219*004e86ffSlogin .wrap()); 220*004e86ffSlogin } 221*004e86ffSlogin 222*004e86ffSlogin fn link(&self, name: &str, other: &Arc<dyn IndexNode>) -> Result<(), i32> { 223*004e86ffSlogin return self.inner_inode.link(name, other); 224*004e86ffSlogin } 225*004e86ffSlogin 226*004e86ffSlogin /// @brief 在挂载文件系统中删除文件/文件夹 227*004e86ffSlogin #[inline] 228*004e86ffSlogin fn unlink(&self, name: &str) -> Result<(), i32> { 229*004e86ffSlogin let inode_id = self.inner_inode.find(name)?.metadata()?.inode_id; 230*004e86ffSlogin 231*004e86ffSlogin // 先检查这个inode是否为一个挂载点,如果当前inode是一个挂载点,那么就不能删除这个inode 232*004e86ffSlogin if self.mount_fs.mountpoints.lock().contains_key(&inode_id) { 233*004e86ffSlogin return Err(-(EBUSY as i32)); 234*004e86ffSlogin } 235*004e86ffSlogin // 调用内层的inode的方法来删除这个inode 236*004e86ffSlogin return self.inner_inode.unlink(name); 237*004e86ffSlogin } 238*004e86ffSlogin 239*004e86ffSlogin #[inline] 240*004e86ffSlogin fn rmdir(&self, name: &str) ->Result<(), i32> { 241*004e86ffSlogin let inode_id = self.inner_inode.find(name)?.metadata()?.inode_id; 242*004e86ffSlogin kdebug!("rmdir {name}"); 243*004e86ffSlogin // 先检查这个inode是否为一个挂载点,如果当前inode是一个挂载点,那么就不能删除这个inode 244*004e86ffSlogin if self.mount_fs.mountpoints.lock().contains_key(&inode_id) { 245*004e86ffSlogin return Err(-(EBUSY as i32)); 246*004e86ffSlogin } 247*004e86ffSlogin // 调用内层的rmdir的方法来删除这个inode 248*004e86ffSlogin let r = self.inner_inode.rmdir(name); 249*004e86ffSlogin kdebug!("r={r:?}"); 250*004e86ffSlogin return r; 251*004e86ffSlogin } 252*004e86ffSlogin 253*004e86ffSlogin #[inline] 254*004e86ffSlogin fn move_( 255*004e86ffSlogin &self, 256*004e86ffSlogin old_name: &str, 257*004e86ffSlogin target: &Arc<dyn IndexNode>, 258*004e86ffSlogin new_name: &str, 259*004e86ffSlogin ) -> Result<(), i32> { 260*004e86ffSlogin return self.inner_inode.move_(old_name, target, new_name); 261*004e86ffSlogin } 262*004e86ffSlogin 263*004e86ffSlogin fn find(&self, name: &str) -> Result<Arc<dyn IndexNode>, i32> { 264*004e86ffSlogin match name { 265*004e86ffSlogin // 查找的是当前目录 266*004e86ffSlogin "" | "." => return Ok(self.self_ref.upgrade().unwrap()), 267*004e86ffSlogin // 往父级查找 268*004e86ffSlogin ".." => { 269*004e86ffSlogin if self.is_mountpoint_root()? { 270*004e86ffSlogin // 当前inode是它所在的文件系统的root inode 271*004e86ffSlogin match &self.mount_fs.self_mountpoint { 272*004e86ffSlogin Some(inode) => { 273*004e86ffSlogin return inode.find(name); 274*004e86ffSlogin } 275*004e86ffSlogin None => { 276*004e86ffSlogin return Ok(self.self_ref.upgrade().unwrap()); 277*004e86ffSlogin } 278*004e86ffSlogin } 279*004e86ffSlogin } else { 280*004e86ffSlogin // 向上查找时,不会跨过文件系统的边界,因此直接调用当前inode所在的文件系统的find方法进行查找 281*004e86ffSlogin return Ok(MountFSInode { 282*004e86ffSlogin inner_inode: self.inner_inode.find(name)?, 283*004e86ffSlogin mount_fs: self.mount_fs.clone(), 284*004e86ffSlogin self_ref: Weak::default(), 285*004e86ffSlogin } 286*004e86ffSlogin .wrap()); 287*004e86ffSlogin } 288*004e86ffSlogin } 289*004e86ffSlogin // 在当前目录下查找 290*004e86ffSlogin _ => { 291*004e86ffSlogin // 直接调用当前inode所在的文件系统的find方法进行查找 292*004e86ffSlogin // 由于向下查找可能会跨越文件系统的边界,因此需要尝试替换inode 293*004e86ffSlogin return Ok(MountFSInode { 294*004e86ffSlogin inner_inode: self.inner_inode.find(name)?, 295*004e86ffSlogin mount_fs: self.mount_fs.clone(), 296*004e86ffSlogin self_ref: Weak::default(), 297*004e86ffSlogin } 298*004e86ffSlogin .wrap() 299*004e86ffSlogin .overlaid_inode()); 300*004e86ffSlogin } 301*004e86ffSlogin } 302*004e86ffSlogin } 303*004e86ffSlogin 304*004e86ffSlogin #[inline] 305*004e86ffSlogin fn get_entry_name(&self, ino: InodeId) -> Result<alloc::string::String, i32> { 306*004e86ffSlogin return self.inner_inode.get_entry_name(ino); 307*004e86ffSlogin } 308*004e86ffSlogin 309*004e86ffSlogin #[inline] 310*004e86ffSlogin fn get_entry_name_and_metadata( 311*004e86ffSlogin &self, 312*004e86ffSlogin ino: InodeId, 313*004e86ffSlogin ) -> Result<(alloc::string::String, super::Metadata), i32> { 314*004e86ffSlogin return self.inner_inode.get_entry_name_and_metadata(ino); 315*004e86ffSlogin } 316*004e86ffSlogin 317*004e86ffSlogin #[inline] 318*004e86ffSlogin fn ioctl(&self, cmd: u32, data: usize) -> Result<usize, i32> { 319*004e86ffSlogin return self.inner_inode.ioctl(cmd, data); 320*004e86ffSlogin } 321*004e86ffSlogin 322*004e86ffSlogin #[inline] 323*004e86ffSlogin fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, i32> { 324*004e86ffSlogin return self.inner_inode.list(); 325*004e86ffSlogin } 326*004e86ffSlogin 327*004e86ffSlogin /// @brief 在当前inode下,挂载一个文件系统 328*004e86ffSlogin /// 329*004e86ffSlogin /// @return Ok(Arc<MountFS>) 挂载成功,返回指向MountFS的指针 330*004e86ffSlogin fn mount(&self, fs: Arc<dyn FileSystem>) -> Result<Arc<MountFS>, i32> { 331*004e86ffSlogin let metadata = self.inner_inode.metadata()?; 332*004e86ffSlogin if metadata.file_type != FileType::Dir { 333*004e86ffSlogin return Err(-(ENOTDIR as i32)); 334*004e86ffSlogin } 335*004e86ffSlogin 336*004e86ffSlogin // 为新的挂载点创建挂载文件系统 337*004e86ffSlogin let new_mount_fs: Arc<MountFS> = MountFS::new(fs, Some(self.self_ref.upgrade().unwrap())); 338*004e86ffSlogin // 将新的挂载点-挂载文件系统添加到父级的挂载树 339*004e86ffSlogin self.mount_fs 340*004e86ffSlogin .mountpoints 341*004e86ffSlogin .lock() 342*004e86ffSlogin .insert(metadata.inode_id, new_mount_fs.clone()); 343*004e86ffSlogin return Ok(new_mount_fs); 344*004e86ffSlogin } 345*004e86ffSlogin } 346*004e86ffSlogin 347*004e86ffSlogin impl FileSystem for MountFS { 348*004e86ffSlogin fn root_inode(&self) -> Arc<dyn IndexNode> { 349*004e86ffSlogin match &self.self_mountpoint { 350*004e86ffSlogin Some(inode) => return inode.mount_fs.root_inode(), 351*004e86ffSlogin // 当前文件系统是rootfs 352*004e86ffSlogin None => self.mountpoint_root_inode(), 353*004e86ffSlogin } 354*004e86ffSlogin } 355*004e86ffSlogin 356*004e86ffSlogin fn info(&self) -> super::FsInfo { 357*004e86ffSlogin return self.inner_filesystem.info(); 358*004e86ffSlogin } 359*004e86ffSlogin 360*004e86ffSlogin /// @brief 本函数用于实现动态转换。 361*004e86ffSlogin /// 具体的文件系统在实现本函数时,最简单的方式就是:直接返回self 362*004e86ffSlogin fn as_any_ref(&self) -> &dyn Any { 363*004e86ffSlogin self 364*004e86ffSlogin } 365*004e86ffSlogin } 366