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