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