1 /// 导出devfs的模块 2 pub mod null_dev; 3 pub mod zero_dev; 4 5 use super::vfs::{ 6 core::{generate_inode_id, ROOT_INODE}, 7 file::FileMode, 8 syscall::ModeType, 9 FileSystem, FileType, FsInfo, IndexNode, Metadata, 10 }; 11 use crate::{ 12 kerror, kinfo, 13 libs::{ 14 once::Once, 15 spinlock::{SpinLock, SpinLockGuard}, 16 }, 17 syscall::SystemError, 18 time::TimeSpec, 19 }; 20 use alloc::{ 21 collections::BTreeMap, 22 string::{String, ToString}, 23 sync::{Arc, Weak}, 24 vec::Vec, 25 }; 26 27 const DEVFS_MAX_NAMELEN: usize = 64; 28 29 /// @brief dev文件系统 30 #[derive(Debug)] 31 pub struct DevFS { 32 // 文件系统根节点 33 root_inode: Arc<LockedDevFSInode>, 34 } 35 36 impl FileSystem for DevFS { 37 fn as_any_ref(&self) -> &dyn core::any::Any { 38 self 39 } 40 41 fn root_inode(&self) -> Arc<dyn super::vfs::IndexNode> { 42 return self.root_inode.clone(); 43 } 44 45 fn info(&self) -> super::vfs::FsInfo { 46 return FsInfo { 47 blk_dev_id: 0, 48 max_name_len: DEVFS_MAX_NAMELEN, 49 }; 50 } 51 } 52 53 impl DevFS { 54 pub fn new() -> Arc<Self> { 55 // 初始化root inode 56 let root: Arc<LockedDevFSInode> = Arc::new(LockedDevFSInode(SpinLock::new( 57 // /dev 的权限设置为 读+执行,root 可以读写 58 // root 的 parent 是空指针 59 DevFSInode::new(FileType::Dir, ModeType::from_bits_truncate(0o755), 0), 60 ))); 61 62 let devfs: Arc<DevFS> = Arc::new(DevFS { root_inode: root }); 63 64 // 对root inode加锁,并继续完成初始化工作 65 let mut root_guard: SpinLockGuard<DevFSInode> = devfs.root_inode.0.lock(); 66 root_guard.parent = Arc::downgrade(&devfs.root_inode); 67 root_guard.self_ref = Arc::downgrade(&devfs.root_inode); 68 root_guard.fs = Arc::downgrade(&devfs); 69 // 释放锁 70 drop(root_guard); 71 72 // 创建文件夹 73 let root: &Arc<LockedDevFSInode> = &devfs.root_inode; 74 root.add_dir("char") 75 .expect("DevFS: Failed to create /dev/char"); 76 77 root.add_dir("block") 78 .expect("DevFS: Failed to create /dev/block"); 79 devfs.register_bultinin_device(); 80 81 // kdebug!("ls /dev: {:?}", root.list()); 82 return devfs; 83 } 84 85 /// @brief 注册系统内部自带的设备 86 fn register_bultinin_device(&self) { 87 use null_dev::LockedNullInode; 88 use zero_dev::LockedZeroInode; 89 let dev_root: Arc<LockedDevFSInode> = self.root_inode.clone(); 90 dev_root 91 .add_dev("null", LockedNullInode::new()) 92 .expect("DevFS: Failed to register /dev/null"); 93 dev_root 94 .add_dev("zero", LockedZeroInode::new()) 95 .expect("DevFS: Failed to register /dev/zero"); 96 } 97 98 /// @brief 在devfs内注册设备 99 /// 100 /// @param name 设备名称 101 /// @param device 设备节点的结构体 102 pub fn register_device<T: DeviceINode>( 103 &self, 104 name: &str, 105 device: Arc<T>, 106 ) -> Result<(), SystemError> { 107 let dev_root_inode: Arc<LockedDevFSInode> = self.root_inode.clone(); 108 let metadata = device.metadata()?; 109 match metadata.file_type { 110 // 字节设备挂载在 /dev/char 111 FileType::CharDevice => { 112 if let Err(_) = dev_root_inode.find("char") { 113 dev_root_inode.create( 114 "char", 115 FileType::Dir, 116 ModeType::from_bits_truncate(0o755), 117 )?; 118 } 119 120 let any_char_inode = dev_root_inode.find("char")?; 121 let dev_char_inode: &LockedDevFSInode = any_char_inode 122 .as_any_ref() 123 .downcast_ref::<LockedDevFSInode>() 124 .unwrap(); 125 // 在 /dev/char 下创建设备节点 126 dev_char_inode.add_dev(name, device.clone())?; 127 128 // 特殊处理 tty 设备,挂载在 /dev 下 129 if name.starts_with("tty") && name.len() > 3 { 130 dev_root_inode.add_dev(name, device.clone())?; 131 } 132 device.set_fs(dev_char_inode.0.lock().fs.clone()); 133 } 134 FileType::BlockDevice => { 135 if let Err(_) = dev_root_inode.find("block") { 136 dev_root_inode.create( 137 "block", 138 FileType::Dir, 139 ModeType::from_bits_truncate(0o755), 140 )?; 141 } 142 143 let any_block_inode = dev_root_inode.find("block")?; 144 let dev_block_inode: &LockedDevFSInode = any_block_inode 145 .as_any_ref() 146 .downcast_ref::<LockedDevFSInode>() 147 .unwrap(); 148 149 dev_block_inode.add_dev(name, device.clone())?; 150 device.set_fs(dev_block_inode.0.lock().fs.clone()); 151 } 152 FileType::KvmDevice => { 153 dev_root_inode 154 .add_dev(name, device.clone()) 155 .expect("DevFS: Failed to register /dev/kvm"); 156 } 157 _ => { 158 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 159 } 160 } 161 162 return Ok(()); 163 } 164 165 /// @brief 卸载设备 166 pub fn unregister_device<T: DeviceINode>( 167 &self, 168 name: &str, 169 device: Arc<T>, 170 ) -> Result<(), SystemError> { 171 let dev_root_inode: Arc<LockedDevFSInode> = self.root_inode.clone(); 172 match device.metadata().unwrap().file_type { 173 // 字节设备挂载在 /dev/char 174 FileType::CharDevice => { 175 if let Err(_) = dev_root_inode.find("char") { 176 return Err(SystemError::ENOENT); 177 } 178 179 let any_char_inode = dev_root_inode.find("char")?; 180 let dev_char_inode = any_char_inode 181 .as_any_ref() 182 .downcast_ref::<LockedDevFSInode>() 183 .unwrap(); 184 // TODO: 调用设备的卸载接口(当引入卸载接口之后) 185 dev_char_inode.remove(name)?; 186 } 187 FileType::BlockDevice => { 188 if let Err(_) = dev_root_inode.find("block") { 189 return Err(SystemError::ENOENT); 190 } 191 192 let any_block_inode = dev_root_inode.find("block")?; 193 let dev_block_inode = any_block_inode 194 .as_any_ref() 195 .downcast_ref::<LockedDevFSInode>() 196 .unwrap(); 197 198 dev_block_inode.remove(name)?; 199 } 200 _ => { 201 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 202 } 203 } 204 205 return Ok(()); 206 } 207 } 208 209 /// @brief dev文件i节点(锁) 210 #[derive(Debug)] 211 pub struct LockedDevFSInode(SpinLock<DevFSInode>); 212 213 /// @brief dev文件i节点(无锁) 214 #[derive(Debug)] 215 pub struct DevFSInode { 216 /// 指向父Inode的弱引用 217 parent: Weak<LockedDevFSInode>, 218 /// 指向自身的弱引用 219 self_ref: Weak<LockedDevFSInode>, 220 /// 子Inode的B树 221 children: BTreeMap<String, Arc<dyn IndexNode>>, 222 /// 指向inode所在的文件系统对象的指针 223 fs: Weak<DevFS>, 224 /// INode 元数据 225 metadata: Metadata, 226 } 227 228 impl DevFSInode { 229 pub fn new(dev_type_: FileType, mode: ModeType, data_: usize) -> Self { 230 return Self::new_with_parent(Weak::default(), dev_type_, mode, data_); 231 } 232 233 pub fn new_with_parent( 234 parent: Weak<LockedDevFSInode>, 235 dev_type_: FileType, 236 mode: ModeType, 237 data_: usize, 238 ) -> Self { 239 return DevFSInode { 240 parent: parent, 241 self_ref: Weak::default(), 242 children: BTreeMap::new(), 243 metadata: Metadata { 244 dev_id: 1, 245 inode_id: generate_inode_id(), 246 size: 0, 247 blk_size: 0, 248 blocks: 0, 249 atime: TimeSpec::default(), 250 mtime: TimeSpec::default(), 251 ctime: TimeSpec::default(), 252 file_type: dev_type_, // 文件夹 253 mode, 254 nlinks: 1, 255 uid: 0, 256 gid: 0, 257 raw_dev: data_, 258 }, 259 fs: Weak::default(), 260 }; 261 } 262 } 263 264 impl LockedDevFSInode { 265 pub fn add_dir(&self, name: &str) -> Result<(), SystemError> { 266 let guard: SpinLockGuard<DevFSInode> = self.0.lock(); 267 268 if guard.children.contains_key(name) { 269 return Err(SystemError::EEXIST); 270 } 271 272 match self.do_create_with_data( 273 guard, 274 name, 275 FileType::Dir, 276 ModeType::from_bits_truncate(0o755), 277 0, 278 ) { 279 Ok(inode) => inode, 280 Err(err) => { 281 return Err(err); 282 } 283 }; 284 285 return Ok(()); 286 } 287 288 pub fn add_dev(&self, name: &str, dev: Arc<dyn IndexNode>) -> Result<(), SystemError> { 289 let mut this = self.0.lock(); 290 291 if this.children.contains_key(name) { 292 return Err(SystemError::EEXIST); 293 } 294 295 this.children.insert(name.to_string(), dev); 296 return Ok(()); 297 } 298 299 pub fn remove(&self, name: &str) -> Result<(), SystemError> { 300 let x = self 301 .0 302 .lock() 303 .children 304 .remove(name) 305 .ok_or(SystemError::ENOENT)?; 306 307 drop(x); 308 return Ok(()); 309 } 310 311 fn do_create_with_data( 312 &self, 313 mut guard: SpinLockGuard<DevFSInode>, 314 name: &str, 315 file_type: FileType, 316 mode: ModeType, 317 data: usize, 318 ) -> Result<Arc<dyn IndexNode>, SystemError> { 319 if guard.metadata.file_type != FileType::Dir { 320 return Err(SystemError::ENOTDIR); 321 } 322 323 // 如果有重名的,则返回 324 if guard.children.contains_key(name) { 325 return Err(SystemError::EEXIST); 326 } 327 328 // 创建inode 329 let result: Arc<LockedDevFSInode> = Arc::new(LockedDevFSInode(SpinLock::new(DevFSInode { 330 parent: guard.self_ref.clone(), 331 self_ref: Weak::default(), 332 children: BTreeMap::new(), 333 metadata: Metadata { 334 dev_id: 0, 335 inode_id: generate_inode_id(), 336 size: 0, 337 blk_size: 0, 338 blocks: 0, 339 atime: TimeSpec::default(), 340 mtime: TimeSpec::default(), 341 ctime: TimeSpec::default(), 342 file_type, 343 mode, 344 nlinks: 1, 345 uid: 0, 346 gid: 0, 347 raw_dev: data, 348 }, 349 fs: guard.fs.clone(), 350 }))); 351 352 // 初始化inode的自引用的weak指针 353 result.0.lock().self_ref = Arc::downgrade(&result); 354 355 // 将子inode插入父inode的B树中 356 guard.children.insert(String::from(name), result.clone()); 357 return Ok(result); 358 } 359 } 360 361 impl IndexNode for LockedDevFSInode { 362 fn as_any_ref(&self) -> &dyn core::any::Any { 363 self 364 } 365 366 fn open( 367 &self, 368 _data: &mut super::vfs::FilePrivateData, 369 _mode: &FileMode, 370 ) -> Result<(), SystemError> { 371 return Ok(()); 372 } 373 374 fn close(&self, _data: &mut super::vfs::FilePrivateData) -> Result<(), SystemError> { 375 return Ok(()); 376 } 377 378 fn create_with_data( 379 &self, 380 name: &str, 381 file_type: FileType, 382 mode: ModeType, 383 data: usize, 384 ) -> Result<Arc<dyn IndexNode>, SystemError> { 385 // 获取当前inode 386 let guard: SpinLockGuard<DevFSInode> = self.0.lock(); 387 // 如果当前inode不是文件夹,则返回 388 return self.do_create_with_data(guard, name, file_type, mode, data); 389 } 390 391 fn find(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError> { 392 let inode = self.0.lock(); 393 394 if inode.metadata.file_type != FileType::Dir { 395 return Err(SystemError::ENOTDIR); 396 } 397 398 match name { 399 "" | "." => { 400 return Ok(inode.self_ref.upgrade().ok_or(SystemError::ENOENT)?); 401 } 402 ".." => { 403 return Ok(inode.parent.upgrade().ok_or(SystemError::ENOENT)?); 404 } 405 name => { 406 // 在子目录项中查找 407 return Ok(inode.children.get(name).ok_or(SystemError::ENOENT)?.clone()); 408 } 409 } 410 } 411 412 fn fs(&self) -> Arc<dyn FileSystem> { 413 return self.0.lock().fs.upgrade().unwrap(); 414 } 415 416 fn get_entry_name(&self, ino: super::vfs::InodeId) -> Result<String, SystemError> { 417 let inode: SpinLockGuard<DevFSInode> = self.0.lock(); 418 if inode.metadata.file_type != FileType::Dir { 419 return Err(SystemError::ENOTDIR); 420 } 421 422 match ino.into() { 423 0 => { 424 return Ok(String::from(".")); 425 } 426 1 => { 427 return Ok(String::from("..")); 428 } 429 ino => { 430 // 暴力遍历所有的children,判断inode id是否相同 431 // TODO: 优化这里,这个地方性能很差! 432 let mut key: Vec<String> = inode 433 .children 434 .keys() 435 .filter(|k| { 436 inode 437 .children 438 .get(*k) 439 .unwrap() 440 .metadata() 441 .unwrap() 442 .inode_id 443 .into() 444 == ino 445 }) 446 .cloned() 447 .collect(); 448 449 match key.len() { 450 0=>{return Err(SystemError::ENOENT);} 451 1=>{return Ok(key.remove(0));} 452 _ => panic!("Devfs get_entry_name: key.len()={key_len}>1, current inode_id={inode_id:?}, to find={to_find:?}", key_len=key.len(), inode_id = inode.metadata.inode_id, to_find=ino) 453 } 454 } 455 } 456 } 457 458 fn ioctl(&self, _cmd: u32, _data: usize) -> Result<usize, SystemError> { 459 Err(SystemError::EOPNOTSUPP_OR_ENOTSUP) 460 } 461 462 fn list(&self) -> Result<Vec<String>, SystemError> { 463 let info = self.metadata()?; 464 if info.file_type != FileType::Dir { 465 return Err(SystemError::ENOTDIR); 466 } 467 468 let mut keys: Vec<String> = Vec::new(); 469 keys.push(String::from(".")); 470 keys.push(String::from("..")); 471 keys.append(&mut self.0.lock().children.keys().cloned().collect()); 472 473 return Ok(keys); 474 } 475 476 fn metadata(&self) -> Result<Metadata, SystemError> { 477 return Ok(self.0.lock().metadata.clone()); 478 } 479 480 fn set_metadata(&self, metadata: &Metadata) -> Result<(), SystemError> { 481 let mut inode = self.0.lock(); 482 inode.metadata.atime = metadata.atime; 483 inode.metadata.mtime = metadata.mtime; 484 inode.metadata.ctime = metadata.ctime; 485 inode.metadata.mode = metadata.mode; 486 inode.metadata.uid = metadata.uid; 487 inode.metadata.gid = metadata.gid; 488 489 return Ok(()); 490 } 491 492 /// 读设备 - 应该调用设备的函数读写,而不是通过文件系统读写 493 fn read_at( 494 &self, 495 _offset: usize, 496 _len: usize, 497 _buf: &mut [u8], 498 _data: &mut super::vfs::file::FilePrivateData, 499 ) -> Result<usize, SystemError> { 500 kerror!("DevFS: read_at is not supported!"); 501 Err(SystemError::EOPNOTSUPP_OR_ENOTSUP) 502 } 503 504 /// 写设备 - 应该调用设备的函数读写,而不是通过文件系统读写 505 fn write_at( 506 &self, 507 _offset: usize, 508 _len: usize, 509 _buf: &[u8], 510 _data: &mut super::vfs::file::FilePrivateData, 511 ) -> Result<usize, SystemError> { 512 Err(SystemError::EOPNOTSUPP_OR_ENOTSUP) 513 } 514 } 515 516 /// @brief 所有的设备INode都需要额外实现这个trait 517 pub trait DeviceINode: IndexNode { 518 fn set_fs(&self, fs: Weak<DevFS>); 519 // TODO: 增加 unregister 方法 520 } 521 522 /// @brief 获取devfs实例的强类型不可变引用 523 macro_rules! devfs_exact_ref { 524 () => {{ 525 let devfs_inode: Result<Arc<dyn IndexNode>, SystemError> = ROOT_INODE().find("dev"); 526 if let Err(e) = devfs_inode { 527 kerror!("failed to get DevFS ref. errcode = {:?}", e); 528 return Err(SystemError::ENOENT); 529 } 530 531 let binding = devfs_inode.unwrap(); 532 let devfs_inode: &LockedDevFSInode = binding 533 .as_any_ref() 534 .downcast_ref::<LockedDevFSInode>() 535 .unwrap(); 536 let binding = devfs_inode.fs(); 537 binding 538 } 539 .as_any_ref() 540 .downcast_ref::<DevFS>() 541 .unwrap()}; 542 } 543 /// @brief devfs的设备注册函数 544 pub fn devfs_register<T: DeviceINode>(name: &str, device: Arc<T>) -> Result<(), SystemError> { 545 return devfs_exact_ref!().register_device(name, device); 546 } 547 548 /// @brief devfs的设备卸载函数 549 #[allow(dead_code)] 550 pub fn devfs_unregister<T: DeviceINode>(name: &str, device: Arc<T>) -> Result<(), SystemError> { 551 return devfs_exact_ref!().unregister_device(name, device); 552 } 553 554 pub fn devfs_init() -> Result<(), SystemError> { 555 static INIT: Once = Once::new(); 556 let mut result = None; 557 INIT.call_once(|| { 558 kinfo!("Initializing DevFS..."); 559 // 创建 devfs 实例 560 let devfs: Arc<DevFS> = DevFS::new(); 561 // devfs 挂载 562 let _t = ROOT_INODE() 563 .find("dev") 564 .expect("Cannot find /dev") 565 .mount(devfs) 566 .expect("Failed to mount devfs"); 567 kinfo!("DevFS mounted."); 568 result = Some(Ok(())); 569 }); 570 571 return result.unwrap(); 572 } 573