1 use core::any::Any; 2 use core::intrinsics::unlikely; 3 4 use crate::filesystem::vfs::FSMAKER; 5 use crate::libs::rwlock::RwLock; 6 use crate::{ 7 driver::base::device::device_number::DeviceNumber, 8 filesystem::vfs::{core::generate_inode_id, FileType}, 9 ipc::pipe::LockedPipeInode, 10 libs::casting::DowncastArc, 11 libs::spinlock::{SpinLock, SpinLockGuard}, 12 time::TimeSpec, 13 }; 14 15 use alloc::{ 16 collections::BTreeMap, 17 string::String, 18 sync::{Arc, Weak}, 19 vec::Vec, 20 }; 21 use system_error::SystemError; 22 23 use super::vfs::{ 24 file::FilePrivateData, syscall::ModeType, FileSystem, FileSystemMaker, FsInfo, IndexNode, 25 InodeId, Metadata, SpecialNodeData, 26 }; 27 use super::vfs::{Magic, SuperBlock}; 28 29 /// RamFS的inode名称的最大长度 30 const RAMFS_MAX_NAMELEN: usize = 64; 31 const RAMFS_BLOCK_SIZE: u64 = 512; 32 /// @brief 内存文件系统的Inode结构体 33 #[derive(Debug)] 34 struct LockedRamFSInode(SpinLock<RamFSInode>); 35 36 /// @brief 内存文件系统结构体 37 #[derive(Debug)] 38 pub struct RamFS { 39 /// RamFS的root inode 40 root_inode: Arc<LockedRamFSInode>, 41 super_block: RwLock<SuperBlock>, 42 } 43 44 /// @brief 内存文件系统的Inode结构体(不包含锁) 45 #[derive(Debug)] 46 pub struct RamFSInode { 47 // parent变量目前只在find函数中使用到 48 // 所以只有当inode是文件夹的时候,parent才会生效 49 // 对于文件来说,parent就没什么作用了 50 // 关于parent的说明: 目录不允许有硬链接 51 /// 指向父Inode的弱引用 52 parent: Weak<LockedRamFSInode>, 53 /// 指向自身的弱引用 54 self_ref: Weak<LockedRamFSInode>, 55 /// 子Inode的B树 56 children: BTreeMap<String, Arc<LockedRamFSInode>>, 57 /// 当前inode的数据部分 58 data: Vec<u8>, 59 /// 当前inode的元数据 60 metadata: Metadata, 61 /// 指向inode所在的文件系统对象的指针 62 fs: Weak<RamFS>, 63 /// 指向特殊节点 64 special_node: Option<SpecialNodeData>, 65 } 66 67 impl FileSystem for RamFS { 68 fn root_inode(&self) -> Arc<dyn super::vfs::IndexNode> { 69 return self.root_inode.clone(); 70 } 71 72 fn info(&self) -> FsInfo { 73 return FsInfo { 74 blk_dev_id: 0, 75 max_name_len: RAMFS_MAX_NAMELEN, 76 }; 77 } 78 79 /// @brief 本函数用于实现动态转换。 80 /// 具体的文件系统在实现本函数时,最简单的方式就是:直接返回self 81 fn as_any_ref(&self) -> &dyn Any { 82 self 83 } 84 85 fn name(&self) -> &str { 86 "ramfs" 87 } 88 89 fn super_block(&self) -> SuperBlock { 90 self.super_block.read().clone() 91 } 92 } 93 94 impl RamFS { 95 pub fn new() -> Arc<Self> { 96 let super_block = SuperBlock::new( 97 Magic::RAMFS_MAGIC, 98 RAMFS_BLOCK_SIZE, 99 RAMFS_MAX_NAMELEN as u64, 100 ); 101 // 初始化root inode 102 let root: Arc<LockedRamFSInode> = Arc::new(LockedRamFSInode(SpinLock::new(RamFSInode { 103 parent: Weak::default(), 104 self_ref: Weak::default(), 105 children: BTreeMap::new(), 106 data: Vec::new(), 107 metadata: Metadata { 108 dev_id: 0, 109 inode_id: generate_inode_id(), 110 size: 0, 111 blk_size: 0, 112 blocks: 0, 113 atime: TimeSpec::default(), 114 mtime: TimeSpec::default(), 115 ctime: TimeSpec::default(), 116 file_type: FileType::Dir, 117 mode: ModeType::from_bits_truncate(0o777), 118 nlinks: 1, 119 uid: 0, 120 gid: 0, 121 raw_dev: DeviceNumber::default(), 122 }, 123 fs: Weak::default(), 124 special_node: None, 125 }))); 126 127 let result: Arc<RamFS> = Arc::new(RamFS { 128 root_inode: root, 129 super_block: RwLock::new(super_block), 130 }); 131 132 // 对root inode加锁,并继续完成初始化工作 133 let mut root_guard: SpinLockGuard<RamFSInode> = result.root_inode.0.lock(); 134 root_guard.parent = Arc::downgrade(&result.root_inode); 135 root_guard.self_ref = Arc::downgrade(&result.root_inode); 136 root_guard.fs = Arc::downgrade(&result); 137 // 释放锁 138 drop(root_guard); 139 140 return result; 141 } 142 143 pub fn make_ramfs() -> Result<Arc<dyn FileSystem + 'static>, SystemError> { 144 let fs = RamFS::new(); 145 return Ok(fs); 146 } 147 } 148 #[distributed_slice(FSMAKER)] 149 static RAMFSMAKER: FileSystemMaker = FileSystemMaker::new( 150 "ramfs", 151 &(RamFS::make_ramfs as fn() -> Result<Arc<dyn FileSystem + 'static>, SystemError>), 152 ); 153 154 impl IndexNode for LockedRamFSInode { 155 fn truncate(&self, len: usize) -> Result<(), SystemError> { 156 let mut inode = self.0.lock(); 157 158 //如果是文件夹,则报错 159 if inode.metadata.file_type == FileType::Dir { 160 return Err(SystemError::EINVAL); 161 } 162 163 //当前文件长度大于_len才进行截断,否则不操作 164 if inode.data.len() > len { 165 inode.data.resize(len, 0); 166 } 167 return Ok(()); 168 } 169 170 fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> { 171 return Ok(()); 172 } 173 174 fn open( 175 &self, 176 _data: &mut FilePrivateData, 177 _mode: &super::vfs::file::FileMode, 178 ) -> Result<(), SystemError> { 179 return Ok(()); 180 } 181 182 fn read_at( 183 &self, 184 offset: usize, 185 len: usize, 186 buf: &mut [u8], 187 _data: &mut FilePrivateData, 188 ) -> Result<usize, SystemError> { 189 if buf.len() < len { 190 return Err(SystemError::EINVAL); 191 } 192 // 加锁 193 let inode: SpinLockGuard<RamFSInode> = self.0.lock(); 194 195 // 检查当前inode是否为一个文件夹,如果是的话,就返回错误 196 if inode.metadata.file_type == FileType::Dir { 197 return Err(SystemError::EISDIR); 198 } 199 200 let start = inode.data.len().min(offset); 201 let end = inode.data.len().min(offset + len); 202 203 // buffer空间不足 204 if buf.len() < (end - start) { 205 return Err(SystemError::ENOBUFS); 206 } 207 208 // 拷贝数据 209 let src = &inode.data[start..end]; 210 buf[0..src.len()].copy_from_slice(src); 211 return Ok(src.len()); 212 } 213 214 fn write_at( 215 &self, 216 offset: usize, 217 len: usize, 218 buf: &[u8], 219 _data: &mut FilePrivateData, 220 ) -> Result<usize, SystemError> { 221 if buf.len() < len { 222 return Err(SystemError::EINVAL); 223 } 224 225 // 加锁 226 let mut inode: SpinLockGuard<RamFSInode> = self.0.lock(); 227 228 // 检查当前inode是否为一个文件夹,如果是的话,就返回错误 229 if inode.metadata.file_type == FileType::Dir { 230 return Err(SystemError::EISDIR); 231 } 232 233 let data: &mut Vec<u8> = &mut inode.data; 234 235 // 如果文件大小比原来的大,那就resize这个数组 236 if offset + len > data.len() { 237 data.resize(offset + len, 0); 238 } 239 240 let target = &mut data[offset..offset + len]; 241 target.copy_from_slice(&buf[0..len]); 242 return Ok(len); 243 } 244 245 fn fs(&self) -> Arc<dyn FileSystem> { 246 return self.0.lock().fs.upgrade().unwrap(); 247 } 248 249 fn as_any_ref(&self) -> &dyn core::any::Any { 250 self 251 } 252 253 fn metadata(&self) -> Result<Metadata, SystemError> { 254 let inode = self.0.lock(); 255 let mut metadata = inode.metadata.clone(); 256 metadata.size = inode.data.len() as i64; 257 258 return Ok(metadata); 259 } 260 261 fn set_metadata(&self, metadata: &Metadata) -> Result<(), SystemError> { 262 let mut inode = self.0.lock(); 263 inode.metadata.atime = metadata.atime; 264 inode.metadata.mtime = metadata.mtime; 265 inode.metadata.ctime = metadata.ctime; 266 inode.metadata.mode = metadata.mode; 267 inode.metadata.uid = metadata.uid; 268 inode.metadata.gid = metadata.gid; 269 270 return Ok(()); 271 } 272 273 fn resize(&self, len: usize) -> Result<(), SystemError> { 274 let mut inode = self.0.lock(); 275 if inode.metadata.file_type == FileType::File { 276 inode.data.resize(len, 0); 277 return Ok(()); 278 } else { 279 return Err(SystemError::EINVAL); 280 } 281 } 282 283 fn create_with_data( 284 &self, 285 name: &str, 286 file_type: FileType, 287 mode: ModeType, 288 data: usize, 289 ) -> Result<Arc<dyn IndexNode>, SystemError> { 290 // 获取当前inode 291 let mut inode = self.0.lock(); 292 // 如果当前inode不是文件夹,则返回 293 if inode.metadata.file_type != FileType::Dir { 294 return Err(SystemError::ENOTDIR); 295 } 296 // 如果有重名的,则返回 297 if inode.children.contains_key(name) { 298 return Err(SystemError::EEXIST); 299 } 300 301 // 创建inode 302 let result: Arc<LockedRamFSInode> = Arc::new(LockedRamFSInode(SpinLock::new(RamFSInode { 303 parent: inode.self_ref.clone(), 304 self_ref: Weak::default(), 305 children: BTreeMap::new(), 306 data: Vec::new(), 307 metadata: Metadata { 308 dev_id: 0, 309 inode_id: generate_inode_id(), 310 size: 0, 311 blk_size: 0, 312 blocks: 0, 313 atime: TimeSpec::default(), 314 mtime: TimeSpec::default(), 315 ctime: TimeSpec::default(), 316 file_type, 317 mode, 318 nlinks: 1, 319 uid: 0, 320 gid: 0, 321 raw_dev: DeviceNumber::from(data as u32), 322 }, 323 fs: inode.fs.clone(), 324 special_node: None, 325 }))); 326 327 // 初始化inode的自引用的weak指针 328 result.0.lock().self_ref = Arc::downgrade(&result); 329 330 // 将子inode插入父inode的B树中 331 inode.children.insert(String::from(name), result.clone()); 332 333 return Ok(result); 334 } 335 336 fn link(&self, name: &str, other: &Arc<dyn IndexNode>) -> Result<(), SystemError> { 337 let other: &LockedRamFSInode = other 338 .downcast_ref::<LockedRamFSInode>() 339 .ok_or(SystemError::EPERM)?; 340 let mut inode: SpinLockGuard<RamFSInode> = self.0.lock(); 341 let mut other_locked: SpinLockGuard<RamFSInode> = other.0.lock(); 342 343 // 如果当前inode不是文件夹,那么报错 344 if inode.metadata.file_type != FileType::Dir { 345 return Err(SystemError::ENOTDIR); 346 } 347 348 // 如果另一个inode是文件夹,那么也报错 349 if other_locked.metadata.file_type == FileType::Dir { 350 return Err(SystemError::EISDIR); 351 } 352 353 // 如果当前文件夹下已经有同名文件,也报错。 354 if inode.children.contains_key(name) { 355 return Err(SystemError::EEXIST); 356 } 357 358 inode 359 .children 360 .insert(String::from(name), other_locked.self_ref.upgrade().unwrap()); 361 362 // 增加硬链接计数 363 other_locked.metadata.nlinks += 1; 364 return Ok(()); 365 } 366 367 fn unlink(&self, name: &str) -> Result<(), SystemError> { 368 let mut inode: SpinLockGuard<RamFSInode> = self.0.lock(); 369 // 如果当前inode不是目录,那么也没有子目录/文件的概念了,因此要求当前inode的类型是目录 370 if inode.metadata.file_type != FileType::Dir { 371 return Err(SystemError::ENOTDIR); 372 } 373 // 不允许删除当前文件夹,也不允许删除上一个目录 374 if name == "." || name == ".." { 375 return Err(SystemError::ENOTEMPTY); 376 } 377 378 // 获得要删除的文件的inode 379 let to_delete = inode.children.get(name).ok_or(SystemError::ENOENT)?; 380 if to_delete.0.lock().metadata.file_type == FileType::Dir { 381 return Err(SystemError::EPERM); 382 } 383 // 减少硬链接计数 384 to_delete.0.lock().metadata.nlinks -= 1; 385 // 在当前目录中删除这个子目录项 386 inode.children.remove(name); 387 return Ok(()); 388 } 389 390 fn rmdir(&self, name: &str) -> Result<(), SystemError> { 391 let mut inode: SpinLockGuard<RamFSInode> = self.0.lock(); 392 // 如果当前inode不是目录,那么也没有子目录/文件的概念了,因此要求当前inode的类型是目录 393 if inode.metadata.file_type != FileType::Dir { 394 return Err(SystemError::ENOTDIR); 395 } 396 // 获得要删除的文件夹的inode 397 let to_delete = inode.children.get(name).ok_or(SystemError::ENOENT)?; 398 if to_delete.0.lock().metadata.file_type != FileType::Dir { 399 return Err(SystemError::ENOTDIR); 400 } 401 402 to_delete.0.lock().metadata.nlinks -= 1; 403 // 在当前目录中删除这个子目录项 404 inode.children.remove(name); 405 return Ok(()); 406 } 407 408 fn move_to( 409 &self, 410 old_name: &str, 411 target: &Arc<dyn IndexNode>, 412 new_name: &str, 413 ) -> Result<(), SystemError> { 414 let inode: Arc<dyn IndexNode> = self.find(old_name)?; 415 // 修改其对父节点的引用 416 inode 417 .downcast_ref::<LockedRamFSInode>() 418 .ok_or(SystemError::EPERM)? 419 .0 420 .lock() 421 .parent = Arc::downgrade( 422 &target 423 .clone() 424 .downcast_arc::<LockedRamFSInode>() 425 .ok_or(SystemError::EPERM)?, 426 ); 427 428 // 在新的目录下创建一个硬链接 429 target.link(new_name, &inode)?; 430 431 // 取消现有的目录下的这个硬链接 432 if let Err(e) = self.unlink(old_name) { 433 // 当操作失败时回退操作 434 target.unlink(new_name)?; 435 return Err(e); 436 } 437 438 return Ok(()); 439 } 440 441 fn find(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError> { 442 let inode = self.0.lock(); 443 444 if inode.metadata.file_type != FileType::Dir { 445 return Err(SystemError::ENOTDIR); 446 } 447 448 match name { 449 "" | "." => { 450 return Ok(inode.self_ref.upgrade().ok_or(SystemError::ENOENT)?); 451 } 452 453 ".." => { 454 return Ok(inode.parent.upgrade().ok_or(SystemError::ENOENT)?); 455 } 456 name => { 457 // 在子目录项中查找 458 return Ok(inode.children.get(name).ok_or(SystemError::ENOENT)?.clone()); 459 } 460 } 461 } 462 463 fn get_entry_name(&self, ino: InodeId) -> Result<String, SystemError> { 464 let inode: SpinLockGuard<RamFSInode> = self.0.lock(); 465 if inode.metadata.file_type != FileType::Dir { 466 return Err(SystemError::ENOTDIR); 467 } 468 469 match ino.into() { 470 0 => { 471 return Ok(String::from(".")); 472 } 473 1 => { 474 return Ok(String::from("..")); 475 } 476 ino => { 477 // 暴力遍历所有的children,判断inode id是否相同 478 // TODO: 优化这里,这个地方性能很差! 479 let mut key: Vec<String> = inode 480 .children 481 .keys() 482 .filter(|k| { 483 inode 484 .children 485 .get(*k) 486 .unwrap() 487 .0 488 .lock() 489 .metadata 490 .inode_id 491 .into() 492 == ino 493 }) 494 .cloned() 495 .collect(); 496 497 match key.len() { 498 0=>{return Err(SystemError::ENOENT);} 499 1=>{return Ok(key.remove(0));} 500 _ => panic!("Ramfs get_entry_name: key.len()={key_len}>1, current inode_id={inode_id:?}, to find={to_find:?}", key_len=key.len(), inode_id = inode.metadata.inode_id, to_find=ino) 501 } 502 } 503 } 504 } 505 506 fn list(&self) -> Result<Vec<String>, SystemError> { 507 let info = self.metadata()?; 508 if info.file_type != FileType::Dir { 509 return Err(SystemError::ENOTDIR); 510 } 511 512 let mut keys: Vec<String> = Vec::new(); 513 keys.push(String::from(".")); 514 keys.push(String::from("..")); 515 keys.append(&mut self.0.lock().children.keys().cloned().collect()); 516 517 return Ok(keys); 518 } 519 520 fn mknod( 521 &self, 522 filename: &str, 523 mode: ModeType, 524 _dev_t: DeviceNumber, 525 ) -> Result<Arc<dyn IndexNode>, SystemError> { 526 let mut inode = self.0.lock(); 527 if inode.metadata.file_type != FileType::Dir { 528 return Err(SystemError::ENOTDIR); 529 } 530 531 // 判断需要创建的类型 532 if unlikely(mode.contains(ModeType::S_IFREG)) { 533 // 普通文件 534 return self.create(filename, FileType::File, mode); 535 } 536 537 let nod = Arc::new(LockedRamFSInode(SpinLock::new(RamFSInode { 538 parent: inode.self_ref.clone(), 539 self_ref: Weak::default(), 540 children: BTreeMap::new(), 541 data: Vec::new(), 542 metadata: Metadata { 543 dev_id: 0, 544 inode_id: generate_inode_id(), 545 size: 0, 546 blk_size: 0, 547 blocks: 0, 548 atime: TimeSpec::default(), 549 mtime: TimeSpec::default(), 550 ctime: TimeSpec::default(), 551 file_type: FileType::Pipe, 552 mode, 553 nlinks: 1, 554 uid: 0, 555 gid: 0, 556 raw_dev: DeviceNumber::default(), 557 }, 558 fs: inode.fs.clone(), 559 special_node: None, 560 }))); 561 562 nod.0.lock().self_ref = Arc::downgrade(&nod); 563 564 if mode.contains(ModeType::S_IFIFO) { 565 nod.0.lock().metadata.file_type = FileType::Pipe; 566 // 创建pipe文件 567 let pipe_inode = LockedPipeInode::new(); 568 // 设置special_node 569 nod.0.lock().special_node = Some(SpecialNodeData::Pipe(pipe_inode)); 570 } else if mode.contains(ModeType::S_IFBLK) { 571 nod.0.lock().metadata.file_type = FileType::BlockDevice; 572 unimplemented!() 573 } else if mode.contains(ModeType::S_IFCHR) { 574 nod.0.lock().metadata.file_type = FileType::CharDevice; 575 unimplemented!() 576 } 577 578 inode 579 .children 580 .insert(String::from(filename).to_uppercase(), nod.clone()); 581 Ok(nod) 582 } 583 584 fn special_node(&self) -> Option<super::vfs::SpecialNodeData> { 585 return self.0.lock().special_node.clone(); 586 } 587 588 /// # 用于重命名内存中的文件或目录 589 fn rename(&self, _old_name: &str, _new_name: &str) -> Result<(), SystemError> { 590 let old_inode: Arc<dyn IndexNode> = self.find(_old_name)?; 591 // 在新的目录下创建一个硬链接 592 self.link(_new_name, &old_inode)?; 593 594 // 取消现有的目录下的这个硬链接 595 if let Err(err) = self.unlink(_old_name) { 596 // 如果取消失败,那就取消新的目录下的硬链接 597 self.unlink(_new_name)?; 598 return Err(err); 599 } 600 601 return Ok(()); 602 } 603 } 604