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