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