1 use core::{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.lock().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: SpinLock::new(InnerKernFSInode { 92 parent: Weak::new(), 93 metadata, 94 }), 95 self_ref: Weak::new(), 96 fs: RwLock::new(Weak::new()), 97 private_data: SpinLock::new(None), 98 callback: None, 99 children: SpinLock::new(HashMap::new()), 100 inode_type: KernInodeType::Dir, 101 }); 102 103 return root_inode; 104 } 105 } 106 107 #[derive(Debug)] 108 pub struct KernFSInode { 109 inner: SpinLock<InnerKernFSInode>, 110 /// 指向当前Inode所属的文件系统的弱引用 111 fs: RwLock<Weak<KernFS>>, 112 /// 指向自身的弱引用 113 self_ref: Weak<KernFSInode>, 114 /// 私有数据 115 private_data: SpinLock<Option<KernInodePrivateData>>, 116 /// 回调函数 117 callback: Option<&'static dyn KernFSCallback>, 118 /// 子Inode 119 children: SpinLock<HashMap<String, Arc<KernFSInode>>>, 120 /// Inode类型 121 inode_type: KernInodeType, 122 /// Inode名称 123 name: String, 124 } 125 126 #[derive(Debug)] 127 pub struct InnerKernFSInode { 128 parent: Weak<KernFSInode>, 129 130 /// 当前inode的元数据 131 metadata: Metadata, 132 } 133 134 impl IndexNode for KernFSInode { 135 fn as_any_ref(&self) -> &dyn core::any::Any { 136 self 137 } 138 139 fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> { 140 if let Some(callback) = self.callback { 141 let callback_data = 142 KernCallbackData::new(self.self_ref.upgrade().unwrap(), self.private_data.lock()); 143 return callback.open(callback_data); 144 } 145 146 return Ok(()); 147 } 148 149 fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> { 150 return Ok(()); 151 } 152 153 fn metadata(&self) -> Result<Metadata, SystemError> { 154 return Ok(self.inner.lock().metadata.clone()); 155 } 156 157 fn set_metadata(&self, _metadata: &Metadata) -> Result<(), SystemError> { 158 // 若文件系统没有实现此方法,则返回“不支持” 159 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 160 } 161 162 fn resize(&self, _len: usize) -> Result<(), SystemError> { 163 return Ok(()); 164 } 165 166 fn create_with_data( 167 &self, 168 _name: &str, 169 _file_type: FileType, 170 _mode: ModeType, 171 _data: usize, 172 ) -> Result<Arc<dyn IndexNode>, SystemError> { 173 // 应当通过kernfs的其它方法来创建文件,而不能从用户态直接调用此方法。 174 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 175 } 176 177 fn link(&self, _name: &str, _other: &Arc<dyn IndexNode>) -> Result<(), SystemError> { 178 // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。 179 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 180 } 181 182 fn unlink(&self, _name: &str) -> Result<(), SystemError> { 183 // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。 184 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 185 } 186 187 fn rmdir(&self, _name: &str) -> Result<(), SystemError> { 188 // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。 189 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 190 } 191 192 fn move_( 193 &self, 194 _old_name: &str, 195 _target: &Arc<dyn IndexNode>, 196 _new_name: &str, 197 ) -> Result<(), SystemError> { 198 // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。 199 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 200 } 201 202 fn find(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError> { 203 if unlikely(name.len() > KernFS::MAX_NAMELEN) { 204 return Err(SystemError::ENAMETOOLONG); 205 } 206 if unlikely(self.inode_type != KernInodeType::Dir) { 207 return Err(SystemError::ENOTDIR); 208 } 209 match name { 210 "" | "." => { 211 return Ok(self.self_ref.upgrade().ok_or(SystemError::ENOENT)?); 212 } 213 214 ".." => { 215 return Ok(self 216 .inner 217 .lock() 218 .parent 219 .upgrade() 220 .ok_or(SystemError::ENOENT)?); 221 } 222 name => { 223 // 在子目录项中查找 224 return Ok(self 225 .children 226 .lock() 227 .get(name) 228 .ok_or(SystemError::ENOENT)? 229 .clone()); 230 } 231 } 232 } 233 234 fn get_entry_name(&self, ino: InodeId) -> Result<String, SystemError> { 235 if self.inode_type != KernInodeType::Dir { 236 return Err(SystemError::ENOTDIR); 237 } 238 239 let children = self.children.lock(); 240 let r = children 241 .iter() 242 .find(|(_, v)| v.metadata().unwrap().inode_id == ino) 243 .map(|(k, _)| k.clone()); 244 245 return r.ok_or(SystemError::ENOENT); 246 } 247 248 fn get_entry_name_and_metadata(&self, ino: InodeId) -> Result<(String, Metadata), SystemError> { 249 // 如果有条件,请在文件系统中使用高效的方式实现本接口,而不是依赖这个低效率的默认实现。 250 let name = self.get_entry_name(ino)?; 251 let entry = self.find(&name)?; 252 return Ok((name, entry.metadata()?)); 253 } 254 255 fn ioctl(&self, _cmd: u32, _data: usize) -> Result<usize, SystemError> { 256 // 若文件系统没有实现此方法,则返回“不支持” 257 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 258 } 259 260 fn truncate(&self, _len: usize) -> Result<(), SystemError> { 261 // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。 262 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 263 } 264 265 fn sync(&self) -> Result<(), SystemError> { 266 return Ok(()); 267 } 268 269 fn fs(&self) -> Arc<dyn FileSystem> { 270 return self.fs.read().upgrade().unwrap(); 271 } 272 273 fn list(&self) -> Result<Vec<String>, SystemError> { 274 let info = self.metadata()?; 275 if info.file_type != FileType::Dir { 276 return Err(SystemError::ENOTDIR); 277 } 278 279 let mut keys: Vec<String> = Vec::new(); 280 keys.push(String::from(".")); 281 keys.push(String::from("..")); 282 self.children 283 .lock() 284 .keys() 285 .into_iter() 286 .for_each(|x| keys.push(x.clone())); 287 288 return Ok(keys); 289 } 290 291 fn poll(&self) -> Result<PollStatus, SystemError> { 292 // todo: 根据inode的具体attribute,返回PollStatus 293 return Ok(PollStatus::READ | PollStatus::WRITE); 294 } 295 296 fn read_at( 297 &self, 298 offset: usize, 299 len: usize, 300 buf: &mut [u8], 301 _data: &mut FilePrivateData, 302 ) -> Result<usize, SystemError> { 303 if self.inode_type != KernInodeType::File { 304 return Err(SystemError::EISDIR); 305 } 306 307 if self.callback.is_none() { 308 kwarn!("kernfs: callback is none"); 309 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 310 } 311 312 let callback_data = 313 KernCallbackData::new(self.self_ref.upgrade().unwrap(), self.private_data.lock()); 314 return self 315 .callback 316 .as_ref() 317 .unwrap() 318 .read(callback_data, &mut buf[..len], offset); 319 } 320 321 fn write_at( 322 &self, 323 offset: usize, 324 len: usize, 325 buf: &[u8], 326 _data: &mut FilePrivateData, 327 ) -> Result<usize, SystemError> { 328 if self.inode_type != KernInodeType::File { 329 return Err(SystemError::EISDIR); 330 } 331 332 if self.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 .write(callback_data, &buf[..len], offset); 343 } 344 } 345 346 impl KernFSInode { 347 /// 在当前inode下增加子目录 348 /// 349 /// ## 参数 350 /// 351 /// - `name`:子目录名称 352 /// - `mode`:子目录权限 353 /// - `private_data`:子目录私有数据 354 /// - `callback`:子目录回调函数 355 /// 356 /// ## 返回值 357 /// 358 /// - 成功:子目录inode 359 /// - 失败:错误码 360 #[allow(dead_code)] 361 #[inline] 362 pub fn add_dir( 363 &self, 364 name: String, 365 mode: ModeType, 366 private_data: Option<KernInodePrivateData>, 367 callback: Option<&'static dyn KernFSCallback>, 368 ) -> Result<Arc<KernFSInode>, SystemError> { 369 if unlikely(self.inode_type != KernInodeType::Dir) { 370 return Err(SystemError::ENOTDIR); 371 } 372 373 return self.inner_create(name, KernInodeType::Dir, mode, private_data, callback); 374 } 375 376 /// 在当前inode下增加文件 377 /// 378 /// ## 参数 379 /// 380 /// - `name`:文件名称 381 /// - `mode`:文件权限 382 /// - `private_data`:文件私有数据 383 /// - `callback`:文件回调函数 384 /// 385 /// ## 返回值 386 /// 387 /// - 成功:文件inode 388 /// - 失败:错误码 389 #[allow(dead_code)] 390 #[inline] 391 pub fn add_file( 392 &self, 393 name: String, 394 mode: ModeType, 395 private_data: Option<KernInodePrivateData>, 396 callback: Option<&'static dyn KernFSCallback>, 397 ) -> Result<Arc<KernFSInode>, SystemError> { 398 if unlikely(self.inode_type != KernInodeType::Dir) { 399 return Err(SystemError::ENOTDIR); 400 } 401 402 return self.inner_create(name, KernInodeType::File, mode, private_data, callback); 403 } 404 405 fn inner_create( 406 &self, 407 name: String, 408 file_type: KernInodeType, 409 mode: ModeType, 410 private_data: Option<KernInodePrivateData>, 411 callback: Option<&'static dyn KernFSCallback>, 412 ) -> Result<Arc<KernFSInode>, SystemError> { 413 let size = if file_type == KernInodeType::File { 414 4096 415 } else { 416 0 417 }; 418 419 let metadata = Metadata { 420 size, 421 mode, 422 uid: 0, 423 gid: 0, 424 blk_size: 0, 425 blocks: 0, 426 atime: TimeSpec::new(0, 0), 427 mtime: TimeSpec::new(0, 0), 428 ctime: TimeSpec::new(0, 0), 429 dev_id: 0, 430 inode_id: generate_inode_id(), 431 file_type: file_type.into(), 432 nlinks: 1, 433 raw_dev: 0, 434 }; 435 436 let new_inode: Arc<KernFSInode> = Self::new( 437 Some(self.self_ref.upgrade().unwrap()), 438 name.clone(), 439 metadata, 440 file_type, 441 private_data, 442 callback, 443 ); 444 445 self.children.lock().insert(name, new_inode.clone()); 446 447 return Ok(new_inode); 448 } 449 450 /// 在当前inode下删除子目录或者文件 451 /// 452 /// 如果要删除的是子目录,且子目录不为空,则返回ENOTEMPTY 453 /// 454 /// ## 参数 455 /// 456 /// - `name`:子目录或者文件名称 457 /// 458 /// ## 返回值 459 /// 460 /// - 成功:() 461 /// - 失败:错误码 462 #[allow(dead_code)] 463 pub fn remove(&self, name: &str) -> Result<(), SystemError> { 464 if unlikely(self.inode_type != KernInodeType::Dir) { 465 return Err(SystemError::ENOTDIR); 466 } 467 468 let mut children = self.children.lock(); 469 let inode = children.get(name).ok_or(SystemError::ENOENT)?; 470 if inode.children.lock().is_empty() { 471 children.remove(name); 472 return Ok(()); 473 } else { 474 return Err(SystemError::ENOTEMPTY); 475 } 476 } 477 478 pub fn new( 479 parent: Option<Arc<KernFSInode>>, 480 name: String, 481 mut metadata: Metadata, 482 inode_type: KernInodeType, 483 private_data: Option<KernInodePrivateData>, 484 callback: Option<&'static dyn KernFSCallback>, 485 ) -> Arc<KernFSInode> { 486 metadata.file_type = inode_type.into(); 487 let parent: Weak<KernFSInode> = parent.map(|x| Arc::downgrade(&x)).unwrap_or_default(); 488 489 let inode = Arc::new(KernFSInode { 490 name, 491 inner: SpinLock::new(InnerKernFSInode { 492 parent: parent.clone(), 493 metadata, 494 }), 495 self_ref: Weak::new(), 496 fs: RwLock::new(Weak::new()), 497 private_data: SpinLock::new(private_data), 498 callback, 499 children: SpinLock::new(HashMap::new()), 500 inode_type, 501 }); 502 503 { 504 let ptr = inode.as_ref() as *const KernFSInode as *mut KernFSInode; 505 unsafe { 506 (*ptr).self_ref = Arc::downgrade(&inode); 507 } 508 } 509 if parent.strong_count() > 0 { 510 let kernfs = parent 511 .upgrade() 512 .unwrap() 513 .fs() 514 .downcast_arc::<KernFS>() 515 .expect("KernFSInode::new: parent is not a KernFS instance"); 516 *inode.fs.write() = Arc::downgrade(&kernfs); 517 } 518 return inode; 519 } 520 521 pub fn name(&self) -> &str { 522 return &self.name; 523 } 524 525 pub fn parent(&self) -> Option<Arc<KernFSInode>> { 526 return self.inner.lock().parent.upgrade(); 527 } 528 529 pub fn private_data_mut(&self) -> SpinLockGuard<Option<KernInodePrivateData>> { 530 return self.private_data.lock(); 531 } 532 533 /// remove a kernfs_node recursively 534 pub fn remove_recursive(&self) { 535 let mut children = self.children.lock().drain().collect::<Vec<_>>(); 536 while let Some((_, child)) = children.pop() { 537 children.append(&mut child.children.lock().drain().collect::<Vec<_>>()); 538 } 539 } 540 541 /// 删除当前的inode(包括其自身、子目录和子文件) 542 #[allow(dead_code)] 543 pub fn remove_inode_include_self(&self) { 544 let parent = self.parent(); 545 if let Some(parent) = parent { 546 parent.children.lock().remove(self.name()); 547 } 548 self.remove_recursive(); 549 } 550 } 551 #[derive(Debug, Clone, Copy, PartialEq, Eq)] 552 pub enum KernInodeType { 553 Dir, 554 File, 555 } 556 557 impl Into<FileType> for KernInodeType { 558 fn into(self) -> FileType { 559 match self { 560 KernInodeType::Dir => FileType::Dir, 561 KernInodeType::File => FileType::File, 562 } 563 } 564 } 565