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_( 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(&self, _cmd: u32, _data: usize) -> Result<usize, SystemError> { 262 // 若文件系统没有实现此方法,则返回“不支持” 263 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 264 } 265 266 fn truncate(&self, _len: usize) -> Result<(), SystemError> { 267 // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。 268 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 269 } 270 271 fn sync(&self) -> Result<(), SystemError> { 272 return Ok(()); 273 } 274 275 fn fs(&self) -> Arc<dyn FileSystem> { 276 return self.fs.read().upgrade().unwrap(); 277 } 278 279 fn list(&self) -> Result<Vec<String>, SystemError> { 280 let info = self.metadata()?; 281 if info.file_type != FileType::Dir { 282 return Err(SystemError::ENOTDIR); 283 } 284 285 let mut keys: Vec<String> = Vec::new(); 286 keys.push(String::from(".")); 287 keys.push(String::from("..")); 288 self.children 289 .lock() 290 .keys() 291 .into_iter() 292 .for_each(|x| keys.push(x.clone())); 293 294 return Ok(keys); 295 } 296 297 fn read_at( 298 &self, 299 offset: usize, 300 len: usize, 301 buf: &mut [u8], 302 _data: &mut FilePrivateData, 303 ) -> Result<usize, SystemError> { 304 if self.inode_type == KernInodeType::SymLink { 305 let inner = self.inner.read(); 306 if offset >= inner.symlink_target_absolute_path.as_ref().unwrap().len() { 307 return Ok(0); 308 } 309 let len = min(len, buf.len()); 310 let len = min( 311 len, 312 inner.symlink_target_absolute_path.as_ref().unwrap().len() - offset, 313 ); 314 buf[0..len].copy_from_slice( 315 &inner 316 .symlink_target_absolute_path 317 .as_ref() 318 .unwrap() 319 .as_bytes()[offset..offset + len], 320 ); 321 return Ok(len); 322 } 323 if self.inode_type != KernInodeType::File { 324 return Err(SystemError::EISDIR); 325 } 326 327 if self.callback.is_none() { 328 kwarn!("kernfs: callback is none"); 329 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 330 } 331 332 let callback_data = 333 KernCallbackData::new(self.self_ref.upgrade().unwrap(), self.private_data.lock()); 334 return self 335 .callback 336 .as_ref() 337 .unwrap() 338 .read(callback_data, &mut buf[..len], offset); 339 } 340 341 fn write_at( 342 &self, 343 offset: usize, 344 len: usize, 345 buf: &[u8], 346 _data: &mut FilePrivateData, 347 ) -> Result<usize, SystemError> { 348 if self.inode_type != KernInodeType::File { 349 return Err(SystemError::EISDIR); 350 } 351 352 if self.callback.is_none() { 353 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 354 } 355 356 let callback_data = 357 KernCallbackData::new(self.self_ref.upgrade().unwrap(), self.private_data.lock()); 358 return self 359 .callback 360 .as_ref() 361 .unwrap() 362 .write(callback_data, &buf[..len], offset); 363 } 364 } 365 366 impl KernFSInode { 367 pub fn new( 368 parent: Option<Arc<KernFSInode>>, 369 name: String, 370 mut metadata: Metadata, 371 inode_type: KernInodeType, 372 private_data: Option<KernInodePrivateData>, 373 callback: Option<&'static dyn KernFSCallback>, 374 ) -> Arc<KernFSInode> { 375 metadata.file_type = inode_type.into(); 376 let parent: Weak<KernFSInode> = parent.map(|x| Arc::downgrade(&x)).unwrap_or_default(); 377 378 let inode = Arc::new(KernFSInode { 379 name, 380 inner: RwLock::new(InnerKernFSInode { 381 parent: parent.clone(), 382 metadata, 383 symlink_target: None, 384 symlink_target_absolute_path: None, 385 }), 386 self_ref: Weak::new(), 387 fs: RwLock::new(Weak::new()), 388 private_data: SpinLock::new(private_data), 389 callback, 390 children: SpinLock::new(HashMap::new()), 391 inode_type, 392 }); 393 394 { 395 let ptr = inode.as_ref() as *const KernFSInode as *mut KernFSInode; 396 unsafe { 397 (*ptr).self_ref = Arc::downgrade(&inode); 398 } 399 } 400 if parent.strong_count() > 0 { 401 let kernfs = parent 402 .upgrade() 403 .unwrap() 404 .fs() 405 .downcast_arc::<KernFS>() 406 .expect("KernFSInode::new: parent is not a KernFS instance"); 407 *inode.fs.write() = Arc::downgrade(&kernfs); 408 } 409 return inode; 410 } 411 412 /// 在当前inode下增加子目录 413 /// 414 /// ## 参数 415 /// 416 /// - `name`:子目录名称 417 /// - `mode`:子目录权限 418 /// - `private_data`:子目录私有数据 419 /// - `callback`:子目录回调函数 420 /// 421 /// ## 返回值 422 /// 423 /// - 成功:子目录inode 424 /// - 失败:错误码 425 #[allow(dead_code)] 426 #[inline] 427 pub fn add_dir( 428 &self, 429 name: String, 430 mode: ModeType, 431 private_data: Option<KernInodePrivateData>, 432 callback: Option<&'static dyn KernFSCallback>, 433 ) -> Result<Arc<KernFSInode>, SystemError> { 434 if unlikely(self.inode_type != KernInodeType::Dir) { 435 return Err(SystemError::ENOTDIR); 436 } 437 438 return self.inner_create(name, KernInodeType::Dir, mode, 0, private_data, callback); 439 } 440 441 /// 在当前inode下增加文件 442 /// 443 /// ## 参数 444 /// 445 /// - `name`:文件名称 446 /// - `mode`:文件权限 447 /// - `size`:文件大小(如果不指定,则默认为4096) 448 /// - `private_data`:文件私有数据 449 /// - `callback`:文件回调函数 450 /// 451 /// 452 /// ## 返回值 453 /// 454 /// - 成功:文件inode 455 /// - 失败:错误码 456 #[allow(dead_code)] 457 #[inline] 458 pub fn add_file( 459 &self, 460 name: String, 461 mode: ModeType, 462 size: Option<usize>, 463 private_data: Option<KernInodePrivateData>, 464 callback: Option<&'static dyn KernFSCallback>, 465 ) -> Result<Arc<KernFSInode>, SystemError> { 466 if unlikely(self.inode_type != KernInodeType::Dir) { 467 return Err(SystemError::ENOTDIR); 468 } 469 470 let size = size.unwrap_or(4096); 471 return self.inner_create( 472 name, 473 KernInodeType::File, 474 mode, 475 size, 476 private_data, 477 callback, 478 ); 479 } 480 481 fn inner_create( 482 &self, 483 name: String, 484 file_type: KernInodeType, 485 mode: ModeType, 486 mut size: usize, 487 private_data: Option<KernInodePrivateData>, 488 callback: Option<&'static dyn KernFSCallback>, 489 ) -> Result<Arc<KernFSInode>, SystemError> { 490 match file_type { 491 KernInodeType::Dir | KernInodeType::SymLink => { 492 size = 0; 493 } 494 _ => {} 495 } 496 497 let metadata = Metadata { 498 size: size as i64, 499 mode, 500 uid: 0, 501 gid: 0, 502 blk_size: 0, 503 blocks: 0, 504 atime: TimeSpec::new(0, 0), 505 mtime: TimeSpec::new(0, 0), 506 ctime: TimeSpec::new(0, 0), 507 dev_id: 0, 508 inode_id: generate_inode_id(), 509 file_type: file_type.into(), 510 nlinks: 1, 511 raw_dev: DeviceNumber::default(), 512 }; 513 514 let new_inode: Arc<KernFSInode> = Self::new( 515 Some(self.self_ref.upgrade().unwrap()), 516 name.clone(), 517 metadata, 518 file_type, 519 private_data, 520 callback, 521 ); 522 523 self.children.lock().insert(name, new_inode.clone()); 524 525 return Ok(new_inode); 526 } 527 528 /// 在当前inode下删除子目录或者文件 529 /// 530 /// 如果要删除的是子目录,且子目录不为空,则返回ENOTEMPTY 531 /// 532 /// ## 参数 533 /// 534 /// - `name`:子目录或者文件名称 535 /// 536 /// ## 返回值 537 /// 538 /// - 成功:() 539 /// - 失败:错误码 540 #[allow(dead_code)] 541 pub fn remove(&self, name: &str) -> Result<(), SystemError> { 542 if unlikely(self.inode_type != KernInodeType::Dir) { 543 return Err(SystemError::ENOTDIR); 544 } 545 546 let mut children = self.children.lock(); 547 let inode = children.get(name).ok_or(SystemError::ENOENT)?; 548 if inode.children.lock().is_empty() { 549 children.remove(name); 550 return Ok(()); 551 } else { 552 return Err(SystemError::ENOTEMPTY); 553 } 554 } 555 556 /// add_link - create a symlink in kernfs 557 /// 558 /// ## 参数 559 /// 560 /// - `parent`: directory to create the symlink in 561 /// - `name`: name of the symlink 562 /// - `target`: target node for the symlink to point to 563 /// 564 /// Returns the created node on success 565 /// 566 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/fs/kernfs/symlink.c#25 567 pub fn add_link( 568 &self, 569 name: String, 570 target: &Arc<KernFSInode>, 571 target_absolute_path: String, 572 ) -> Result<Arc<KernFSInode>, SystemError> { 573 // kdebug!("kernfs add link: name:{name}, target path={target_absolute_path}"); 574 let inode = self.inner_create( 575 name, 576 KernInodeType::SymLink, 577 ModeType::S_IFLNK | ModeType::from_bits_truncate(0o777), 578 0, 579 None, 580 None, 581 )?; 582 583 inode.inner.write().symlink_target = Some(Arc::downgrade(target)); 584 inode.inner.write().symlink_target_absolute_path = Some(target_absolute_path); 585 return Ok(inode); 586 } 587 588 pub fn name(&self) -> &str { 589 return &self.name; 590 } 591 592 pub fn parent(&self) -> Option<Arc<KernFSInode>> { 593 return self.inner.read().parent.upgrade(); 594 } 595 596 pub fn private_data_mut(&self) -> SpinLockGuard<Option<KernInodePrivateData>> { 597 return self.private_data.lock(); 598 } 599 600 #[allow(dead_code)] 601 pub fn symlink_target(&self) -> Option<Arc<KernFSInode>> { 602 return self.inner.read().symlink_target.as_ref()?.upgrade(); 603 } 604 605 /// remove a kernfs_node recursively 606 pub fn remove_recursive(&self) { 607 let mut children = self.children.lock().drain().collect::<Vec<_>>(); 608 while let Some((_, child)) = children.pop() { 609 children.append(&mut child.children.lock().drain().collect::<Vec<_>>()); 610 } 611 } 612 613 /// 删除当前的inode(包括其自身、子目录和子文件) 614 #[allow(dead_code)] 615 pub fn remove_inode_include_self(&self) { 616 let parent = self.parent(); 617 if let Some(parent) = parent { 618 parent.children.lock().remove(self.name()); 619 } 620 self.remove_recursive(); 621 } 622 } 623 #[derive(Debug, Clone, Copy, PartialEq, Eq)] 624 pub enum KernInodeType { 625 Dir, 626 File, 627 SymLink, 628 } 629 630 impl Into<FileType> for KernInodeType { 631 fn into(self) -> FileType { 632 match self { 633 KernInodeType::Dir => FileType::Dir, 634 KernInodeType::File => FileType::File, 635 KernInodeType::SymLink => FileType::SymLink, 636 } 637 } 638 } 639