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