1 use core::{cmp::min, fmt::Debug, intrinsics::unlikely}; 2 3 use alloc::{ 4 string::String, 5 sync::{Arc, Weak}, 6 vec::Vec, 7 }; 8 use hashbrown::HashMap; 9 use system_error::SystemError; 10 11 use crate::{ 12 driver::base::device::device_number::DeviceNumber, 13 libs::{ 14 casting::DowncastArc, 15 rwlock::RwLock, 16 spinlock::{SpinLock, SpinLockGuard}, 17 }, 18 time::TimeSpec, 19 }; 20 21 use self::callback::{KernCallbackData, KernFSCallback, KernInodePrivateData}; 22 23 use super::vfs::{ 24 core::generate_inode_id, file::FileMode, syscall::ModeType, FilePrivateData, FileSystem, 25 FileType, FsInfo, IndexNode, InodeId, Magic, Metadata, SuperBlock, 26 }; 27 28 pub mod callback; 29 30 #[derive(Debug)] 31 pub struct KernFS { 32 root_inode: Arc<KernFSInode>, 33 } 34 35 impl FileSystem for KernFS { 36 fn as_any_ref(&self) -> &dyn core::any::Any { 37 self 38 } 39 40 fn info(&self) -> FsInfo { 41 return FsInfo { 42 blk_dev_id: 0, 43 max_name_len: KernFS::MAX_NAMELEN, 44 }; 45 } 46 47 fn root_inode(&self) -> Arc<dyn IndexNode> { 48 return self.root_inode.clone(); 49 } 50 51 fn name(&self) -> &str { 52 "kernfs" 53 } 54 55 fn super_block(&self) -> SuperBlock { 56 SuperBlock::new( 57 Magic::KER_MAGIC, 58 KernFS::KERNFS_BLOCK_SIZE, 59 KernFS::MAX_NAMELEN as u64, 60 ) 61 } 62 } 63 64 impl KernFS { 65 pub const MAX_NAMELEN: usize = 4096; 66 pub const KERNFS_BLOCK_SIZE: u64 = 512; 67 #[allow(dead_code)] 68 pub fn new() -> Arc<Self> { 69 let root_inode = Self::create_root_inode(); 70 let fs = Arc::new(Self { 71 root_inode: root_inode.clone(), 72 }); 73 74 { 75 let ptr = root_inode.as_ref() as *const KernFSInode as *mut KernFSInode; 76 unsafe { 77 (*ptr).self_ref = Arc::downgrade(&root_inode); 78 } 79 } 80 root_inode.inner.write().parent = Arc::downgrade(&root_inode); 81 *root_inode.fs.write() = Arc::downgrade(&fs); 82 return fs; 83 } 84 85 fn create_root_inode() -> Arc<KernFSInode> { 86 let metadata = Metadata { 87 size: 0, 88 mode: ModeType::from_bits_truncate(0o755), 89 uid: 0, 90 gid: 0, 91 blk_size: 0, 92 blocks: 0, 93 atime: TimeSpec::new(0, 0), 94 mtime: TimeSpec::new(0, 0), 95 ctime: TimeSpec::new(0, 0), 96 dev_id: 0, 97 inode_id: generate_inode_id(), 98 file_type: FileType::Dir, 99 nlinks: 1, 100 raw_dev: DeviceNumber::default(), 101 }; 102 let root_inode = Arc::new(KernFSInode { 103 name: String::from(""), 104 inner: RwLock::new(InnerKernFSInode { 105 parent: Weak::new(), 106 metadata, 107 symlink_target: None, 108 symlink_target_absolute_path: None, 109 }), 110 self_ref: Weak::new(), 111 fs: RwLock::new(Weak::new()), 112 private_data: SpinLock::new(None), 113 callback: None, 114 children: SpinLock::new(HashMap::new()), 115 inode_type: KernInodeType::Dir, 116 }); 117 118 return root_inode; 119 } 120 } 121 122 #[derive(Debug)] 123 pub struct KernFSInode { 124 inner: RwLock<InnerKernFSInode>, 125 /// 指向当前Inode所属的文件系统的弱引用 126 fs: RwLock<Weak<KernFS>>, 127 /// 指向自身的弱引用 128 self_ref: Weak<KernFSInode>, 129 /// 私有数据 130 private_data: SpinLock<Option<KernInodePrivateData>>, 131 /// 回调函数 132 callback: Option<&'static dyn KernFSCallback>, 133 /// 子Inode 134 children: SpinLock<HashMap<String, Arc<KernFSInode>>>, 135 /// Inode类型 136 inode_type: KernInodeType, 137 /// Inode名称 138 name: String, 139 } 140 141 #[derive(Debug)] 142 pub struct InnerKernFSInode { 143 parent: Weak<KernFSInode>, 144 145 /// 当前inode的元数据 146 metadata: Metadata, 147 /// 符号链接指向的inode(仅当inode_type为SymLink时有效) 148 symlink_target: Option<Weak<KernFSInode>>, 149 symlink_target_absolute_path: Option<String>, 150 } 151 152 impl IndexNode for KernFSInode { 153 fn as_any_ref(&self) -> &dyn core::any::Any { 154 self 155 } 156 157 fn open( 158 &self, 159 _data: SpinLockGuard<FilePrivateData>, 160 _mode: &FileMode, 161 ) -> Result<(), SystemError> { 162 if let Some(callback) = self.callback { 163 let callback_data = 164 KernCallbackData::new(self.self_ref.upgrade().unwrap(), self.private_data.lock()); 165 return callback.open(callback_data); 166 } 167 168 return Ok(()); 169 } 170 171 fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> { 172 return Ok(()); 173 } 174 175 fn metadata(&self) -> Result<Metadata, SystemError> { 176 return Ok(self.inner.read().metadata.clone()); 177 } 178 179 fn set_metadata(&self, _metadata: &Metadata) -> Result<(), SystemError> { 180 // 若文件系统没有实现此方法,则返回“不支持” 181 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 182 } 183 184 fn resize(&self, _len: usize) -> Result<(), SystemError> { 185 return Ok(()); 186 } 187 188 fn create_with_data( 189 &self, 190 _name: &str, 191 _file_type: FileType, 192 _mode: ModeType, 193 _data: usize, 194 ) -> Result<Arc<dyn IndexNode>, SystemError> { 195 // 应当通过kernfs的其它方法来创建文件,而不能从用户态直接调用此方法。 196 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 197 } 198 199 fn link(&self, _name: &str, _other: &Arc<dyn IndexNode>) -> Result<(), SystemError> { 200 // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。 201 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 202 } 203 204 fn unlink(&self, _name: &str) -> Result<(), SystemError> { 205 // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。 206 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 207 } 208 209 fn rmdir(&self, _name: &str) -> Result<(), SystemError> { 210 // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。 211 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 212 } 213 214 fn move_to( 215 &self, 216 _old_name: &str, 217 _target: &Arc<dyn IndexNode>, 218 _new_name: &str, 219 ) -> Result<(), SystemError> { 220 // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。 221 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 222 } 223 224 fn find(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError> { 225 if unlikely(name.len() > KernFS::MAX_NAMELEN) { 226 return Err(SystemError::ENAMETOOLONG); 227 } 228 if unlikely(self.inode_type != KernInodeType::Dir) { 229 return Err(SystemError::ENOTDIR); 230 } 231 match name { 232 "" | "." => { 233 return Ok(self.self_ref.upgrade().ok_or(SystemError::ENOENT)?); 234 } 235 236 ".." => { 237 return Ok(self 238 .inner 239 .read() 240 .parent 241 .upgrade() 242 .ok_or(SystemError::ENOENT)?); 243 } 244 name => { 245 // 在子目录项中查找 246 return Ok(self 247 .children 248 .lock() 249 .get(name) 250 .ok_or(SystemError::ENOENT)? 251 .clone()); 252 } 253 } 254 } 255 256 fn get_entry_name(&self, ino: InodeId) -> Result<String, SystemError> { 257 if self.inode_type != KernInodeType::Dir { 258 return Err(SystemError::ENOTDIR); 259 } 260 261 let children = self.children.lock(); 262 let r = children 263 .iter() 264 .find(|(_, v)| v.metadata().unwrap().inode_id == ino) 265 .map(|(k, _)| k.clone()); 266 267 return r.ok_or(SystemError::ENOENT); 268 } 269 270 fn get_entry_name_and_metadata(&self, ino: InodeId) -> Result<(String, Metadata), SystemError> { 271 // 如果有条件,请在文件系统中使用高效的方式实现本接口,而不是依赖这个低效率的默认实现。 272 let name = self.get_entry_name(ino)?; 273 let entry = self.find(&name)?; 274 return Ok((name, entry.metadata()?)); 275 } 276 277 fn ioctl( 278 &self, 279 _cmd: u32, 280 _data: usize, 281 _private_data: &FilePrivateData, 282 ) -> Result<usize, SystemError> { 283 // 若文件系统没有实现此方法,则返回“不支持” 284 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 285 } 286 287 fn truncate(&self, _len: usize) -> Result<(), SystemError> { 288 // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。 289 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 290 } 291 292 fn sync(&self) -> Result<(), SystemError> { 293 return Ok(()); 294 } 295 296 fn fs(&self) -> Arc<dyn FileSystem> { 297 return self.fs.read().upgrade().unwrap(); 298 } 299 300 fn list(&self) -> Result<Vec<String>, SystemError> { 301 let info = self.metadata()?; 302 if info.file_type != FileType::Dir { 303 return Err(SystemError::ENOTDIR); 304 } 305 306 let mut keys: Vec<String> = Vec::new(); 307 keys.push(String::from(".")); 308 keys.push(String::from("..")); 309 self.children 310 .lock() 311 .keys() 312 .for_each(|x| keys.push(x.clone())); 313 314 return Ok(keys); 315 } 316 317 fn read_at( 318 &self, 319 offset: usize, 320 len: usize, 321 buf: &mut [u8], 322 _data: SpinLockGuard<FilePrivateData>, 323 ) -> Result<usize, SystemError> { 324 if self.inode_type == KernInodeType::SymLink { 325 let inner = self.inner.read(); 326 if offset >= inner.symlink_target_absolute_path.as_ref().unwrap().len() { 327 return Ok(0); 328 } 329 let len = min(len, buf.len()); 330 let len = min( 331 len, 332 inner.symlink_target_absolute_path.as_ref().unwrap().len() - offset, 333 ); 334 buf[0..len].copy_from_slice( 335 &inner 336 .symlink_target_absolute_path 337 .as_ref() 338 .unwrap() 339 .as_bytes()[offset..offset + len], 340 ); 341 return Ok(len); 342 } 343 if self.inode_type != KernInodeType::File { 344 return Err(SystemError::EISDIR); 345 } 346 347 if self.callback.is_none() { 348 kwarn!("kernfs: callback is none"); 349 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 350 } 351 352 let callback_data = 353 KernCallbackData::new(self.self_ref.upgrade().unwrap(), self.private_data.lock()); 354 return self 355 .callback 356 .as_ref() 357 .unwrap() 358 .read(callback_data, &mut buf[..len], offset); 359 } 360 361 fn write_at( 362 &self, 363 offset: usize, 364 len: usize, 365 buf: &[u8], 366 _data: SpinLockGuard<FilePrivateData>, 367 ) -> Result<usize, SystemError> { 368 if self.inode_type != KernInodeType::File { 369 return Err(SystemError::EISDIR); 370 } 371 372 if self.callback.is_none() { 373 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 374 } 375 376 let callback_data = 377 KernCallbackData::new(self.self_ref.upgrade().unwrap(), self.private_data.lock()); 378 return self 379 .callback 380 .as_ref() 381 .unwrap() 382 .write(callback_data, &buf[..len], offset); 383 } 384 385 fn rename(&self, _old_name: &str, _new_name: &str) -> Result<(), SystemError> { 386 // 待实现 387 Err(SystemError::ENOSYS) 388 } 389 } 390 391 impl KernFSInode { 392 pub fn new( 393 parent: Option<Arc<KernFSInode>>, 394 name: String, 395 mut metadata: Metadata, 396 inode_type: KernInodeType, 397 private_data: Option<KernInodePrivateData>, 398 callback: Option<&'static dyn KernFSCallback>, 399 ) -> Arc<KernFSInode> { 400 metadata.file_type = inode_type.into(); 401 let parent: Weak<KernFSInode> = parent.map(|x| Arc::downgrade(&x)).unwrap_or_default(); 402 403 let inode = Arc::new(KernFSInode { 404 name, 405 inner: RwLock::new(InnerKernFSInode { 406 parent: parent.clone(), 407 metadata, 408 symlink_target: None, 409 symlink_target_absolute_path: None, 410 }), 411 self_ref: Weak::new(), 412 fs: RwLock::new(Weak::new()), 413 private_data: SpinLock::new(private_data), 414 callback, 415 children: SpinLock::new(HashMap::new()), 416 inode_type, 417 }); 418 419 { 420 let ptr = inode.as_ref() as *const KernFSInode as *mut KernFSInode; 421 unsafe { 422 (*ptr).self_ref = Arc::downgrade(&inode); 423 } 424 } 425 if parent.strong_count() > 0 { 426 let kernfs = parent 427 .upgrade() 428 .unwrap() 429 .fs() 430 .downcast_arc::<KernFS>() 431 .expect("KernFSInode::new: parent is not a KernFS instance"); 432 *inode.fs.write() = Arc::downgrade(&kernfs); 433 } 434 return inode; 435 } 436 437 /// 在当前inode下增加子目录 438 /// 439 /// ## 参数 440 /// 441 /// - `name`:子目录名称 442 /// - `mode`:子目录权限 443 /// - `private_data`:子目录私有数据 444 /// - `callback`:子目录回调函数 445 /// 446 /// ## 返回值 447 /// 448 /// - 成功:子目录inode 449 /// - 失败:错误码 450 #[allow(dead_code)] 451 #[inline] 452 pub fn add_dir( 453 &self, 454 name: String, 455 mode: ModeType, 456 private_data: Option<KernInodePrivateData>, 457 callback: Option<&'static dyn KernFSCallback>, 458 ) -> Result<Arc<KernFSInode>, SystemError> { 459 if unlikely(self.inode_type != KernInodeType::Dir) { 460 return Err(SystemError::ENOTDIR); 461 } 462 463 return self.inner_create(name, KernInodeType::Dir, mode, 0, private_data, callback); 464 } 465 466 /// 在当前inode下增加文件 467 /// 468 /// ## 参数 469 /// 470 /// - `name`:文件名称 471 /// - `mode`:文件权限 472 /// - `size`:文件大小(如果不指定,则默认为4096) 473 /// - `private_data`:文件私有数据 474 /// - `callback`:文件回调函数 475 /// 476 /// 477 /// ## 返回值 478 /// 479 /// - 成功:文件inode 480 /// - 失败:错误码 481 #[allow(dead_code)] 482 #[inline] 483 pub fn add_file( 484 &self, 485 name: String, 486 mode: ModeType, 487 size: Option<usize>, 488 private_data: Option<KernInodePrivateData>, 489 callback: Option<&'static dyn KernFSCallback>, 490 ) -> Result<Arc<KernFSInode>, SystemError> { 491 if unlikely(self.inode_type != KernInodeType::Dir) { 492 return Err(SystemError::ENOTDIR); 493 } 494 495 let size = size.unwrap_or(4096); 496 return self.inner_create( 497 name, 498 KernInodeType::File, 499 mode, 500 size, 501 private_data, 502 callback, 503 ); 504 } 505 506 fn inner_create( 507 &self, 508 name: String, 509 file_type: KernInodeType, 510 mode: ModeType, 511 mut size: usize, 512 private_data: Option<KernInodePrivateData>, 513 callback: Option<&'static dyn KernFSCallback>, 514 ) -> Result<Arc<KernFSInode>, SystemError> { 515 match file_type { 516 KernInodeType::Dir | KernInodeType::SymLink => { 517 size = 0; 518 } 519 _ => {} 520 } 521 522 let metadata = Metadata { 523 size: size as i64, 524 mode, 525 uid: 0, 526 gid: 0, 527 blk_size: 0, 528 blocks: 0, 529 atime: TimeSpec::new(0, 0), 530 mtime: TimeSpec::new(0, 0), 531 ctime: TimeSpec::new(0, 0), 532 dev_id: 0, 533 inode_id: generate_inode_id(), 534 file_type: file_type.into(), 535 nlinks: 1, 536 raw_dev: DeviceNumber::default(), 537 }; 538 539 let new_inode: Arc<KernFSInode> = Self::new( 540 Some(self.self_ref.upgrade().unwrap()), 541 name.clone(), 542 metadata, 543 file_type, 544 private_data, 545 callback, 546 ); 547 548 self.children.lock().insert(name, new_inode.clone()); 549 550 return Ok(new_inode); 551 } 552 553 /// 在当前inode下删除子目录或者文件 554 /// 555 /// 如果要删除的是子目录,且子目录不为空,则返回ENOTEMPTY 556 /// 557 /// ## 参数 558 /// 559 /// - `name`:子目录或者文件名称 560 /// 561 /// ## 返回值 562 /// 563 /// - 成功:() 564 /// - 失败:错误码 565 #[allow(dead_code)] 566 pub fn remove(&self, name: &str) -> Result<(), SystemError> { 567 if unlikely(self.inode_type != KernInodeType::Dir) { 568 return Err(SystemError::ENOTDIR); 569 } 570 571 let mut children = self.children.lock(); 572 let inode = children.get(name).ok_or(SystemError::ENOENT)?; 573 if inode.children.lock().is_empty() { 574 children.remove(name); 575 return Ok(()); 576 } else { 577 return Err(SystemError::ENOTEMPTY); 578 } 579 } 580 581 /// add_link - create a symlink in kernfs 582 /// 583 /// ## 参数 584 /// 585 /// - `parent`: directory to create the symlink in 586 /// - `name`: name of the symlink 587 /// - `target`: target node for the symlink to point to 588 /// 589 /// Returns the created node on success 590 /// 591 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/fs/kernfs/symlink.c#25 592 pub fn add_link( 593 &self, 594 name: String, 595 target: &Arc<KernFSInode>, 596 target_absolute_path: String, 597 ) -> Result<Arc<KernFSInode>, SystemError> { 598 // kdebug!("kernfs add link: name:{name}, target path={target_absolute_path}"); 599 let inode = self.inner_create( 600 name, 601 KernInodeType::SymLink, 602 ModeType::S_IFLNK | ModeType::from_bits_truncate(0o777), 603 0, 604 None, 605 None, 606 )?; 607 608 inode.inner.write().symlink_target = Some(Arc::downgrade(target)); 609 inode.inner.write().symlink_target_absolute_path = Some(target_absolute_path); 610 return Ok(inode); 611 } 612 613 pub fn name(&self) -> &str { 614 return &self.name; 615 } 616 617 pub fn parent(&self) -> Option<Arc<KernFSInode>> { 618 return self.inner.read().parent.upgrade(); 619 } 620 621 pub fn private_data_mut(&self) -> SpinLockGuard<Option<KernInodePrivateData>> { 622 return self.private_data.lock(); 623 } 624 625 #[allow(dead_code)] 626 pub fn symlink_target(&self) -> Option<Arc<KernFSInode>> { 627 return self.inner.read().symlink_target.as_ref()?.upgrade(); 628 } 629 630 /// remove a kernfs_node recursively 631 pub fn remove_recursive(&self) { 632 let mut children = self.children.lock().drain().collect::<Vec<_>>(); 633 while let Some((_, child)) = children.pop() { 634 children.append(&mut child.children.lock().drain().collect::<Vec<_>>()); 635 } 636 } 637 638 /// 删除当前的inode(包括其自身、子目录和子文件) 639 #[allow(dead_code)] 640 pub fn remove_inode_include_self(&self) { 641 let parent = self.parent(); 642 if let Some(parent) = parent { 643 parent.children.lock().remove(self.name()); 644 } 645 self.remove_recursive(); 646 } 647 } 648 #[derive(Debug, Clone, Copy, PartialEq, Eq)] 649 pub enum KernInodeType { 650 Dir, 651 File, 652 SymLink, 653 } 654 655 impl From<KernInodeType> for FileType { 656 fn from(val: KernInodeType) -> Self { 657 match val { 658 KernInodeType::Dir => FileType::Dir, 659 KernInodeType::File => FileType::File, 660 KernInodeType::SymLink => FileType::SymLink, 661 } 662 } 663 } 664