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