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