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