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