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