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