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, PollStatus, 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 _ => { 153 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 154 } 155 } 156 157 return Ok(()); 158 } 159 160 /// @brief 卸载设备 161 pub fn unregister_device<T: DeviceINode>( 162 &self, 163 name: &str, 164 device: Arc<T>, 165 ) -> Result<(), SystemError> { 166 let dev_root_inode: Arc<LockedDevFSInode> = self.root_inode.clone(); 167 match device.metadata().unwrap().file_type { 168 // 字节设备挂载在 /dev/char 169 FileType::CharDevice => { 170 if let Err(_) = dev_root_inode.find("char") { 171 return Err(SystemError::ENOENT); 172 } 173 174 let any_char_inode = dev_root_inode.find("char")?; 175 let dev_char_inode = any_char_inode 176 .as_any_ref() 177 .downcast_ref::<LockedDevFSInode>() 178 .unwrap(); 179 // TODO: 调用设备的卸载接口(当引入卸载接口之后) 180 dev_char_inode.remove(name)?; 181 } 182 FileType::BlockDevice => { 183 if let Err(_) = dev_root_inode.find("block") { 184 return Err(SystemError::ENOENT); 185 } 186 187 let any_block_inode = dev_root_inode.find("block")?; 188 let dev_block_inode = any_block_inode 189 .as_any_ref() 190 .downcast_ref::<LockedDevFSInode>() 191 .unwrap(); 192 193 dev_block_inode.remove(name)?; 194 } 195 _ => { 196 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 197 } 198 } 199 200 return Ok(()); 201 } 202 } 203 204 /// @brief dev文件i节点(锁) 205 #[derive(Debug)] 206 pub struct LockedDevFSInode(SpinLock<DevFSInode>); 207 208 /// @brief dev文件i节点(无锁) 209 #[derive(Debug)] 210 pub struct DevFSInode { 211 /// 指向父Inode的弱引用 212 parent: Weak<LockedDevFSInode>, 213 /// 指向自身的弱引用 214 self_ref: Weak<LockedDevFSInode>, 215 /// 子Inode的B树 216 children: BTreeMap<String, Arc<dyn IndexNode>>, 217 /// 指向inode所在的文件系统对象的指针 218 fs: Weak<DevFS>, 219 /// INode 元数据 220 metadata: Metadata, 221 } 222 223 impl DevFSInode { 224 pub fn new(dev_type_: FileType, mode: ModeType, data_: usize) -> Self { 225 return Self::new_with_parent(Weak::default(), dev_type_, mode, data_); 226 } 227 228 pub fn new_with_parent( 229 parent: Weak<LockedDevFSInode>, 230 dev_type_: FileType, 231 mode: ModeType, 232 data_: usize, 233 ) -> Self { 234 return DevFSInode { 235 parent: parent, 236 self_ref: Weak::default(), 237 children: BTreeMap::new(), 238 metadata: Metadata { 239 dev_id: 1, 240 inode_id: generate_inode_id(), 241 size: 0, 242 blk_size: 0, 243 blocks: 0, 244 atime: TimeSpec::default(), 245 mtime: TimeSpec::default(), 246 ctime: TimeSpec::default(), 247 file_type: dev_type_, // 文件夹 248 mode, 249 nlinks: 1, 250 uid: 0, 251 gid: 0, 252 raw_dev: data_, 253 }, 254 fs: Weak::default(), 255 }; 256 } 257 } 258 259 impl LockedDevFSInode { 260 pub fn add_dir(&self, name: &str) -> Result<(), SystemError> { 261 let guard: SpinLockGuard<DevFSInode> = self.0.lock(); 262 263 if guard.children.contains_key(name) { 264 return Err(SystemError::EEXIST); 265 } 266 267 match self.do_create_with_data( 268 guard, 269 name, 270 FileType::Dir, 271 ModeType::from_bits_truncate(0o755), 272 0, 273 ) { 274 Ok(inode) => inode, 275 Err(err) => { 276 return Err(err); 277 } 278 }; 279 280 return Ok(()); 281 } 282 283 pub fn add_dev(&self, name: &str, dev: Arc<dyn IndexNode>) -> Result<(), SystemError> { 284 let mut this = self.0.lock(); 285 286 if this.children.contains_key(name) { 287 return Err(SystemError::EEXIST); 288 } 289 290 this.children.insert(name.to_string(), dev); 291 return Ok(()); 292 } 293 294 pub fn remove(&self, name: &str) -> Result<(), SystemError> { 295 let x = self 296 .0 297 .lock() 298 .children 299 .remove(name) 300 .ok_or(SystemError::ENOENT)?; 301 302 drop(x); 303 return Ok(()); 304 } 305 306 fn do_create_with_data( 307 &self, 308 mut guard: SpinLockGuard<DevFSInode>, 309 name: &str, 310 file_type: FileType, 311 mode: ModeType, 312 data: usize, 313 ) -> Result<Arc<dyn IndexNode>, SystemError> { 314 if guard.metadata.file_type != FileType::Dir { 315 return Err(SystemError::ENOTDIR); 316 } 317 318 // 如果有重名的,则返回 319 if guard.children.contains_key(name) { 320 return Err(SystemError::EEXIST); 321 } 322 323 // 创建inode 324 let result: Arc<LockedDevFSInode> = Arc::new(LockedDevFSInode(SpinLock::new(DevFSInode { 325 parent: guard.self_ref.clone(), 326 self_ref: Weak::default(), 327 children: BTreeMap::new(), 328 metadata: Metadata { 329 dev_id: 0, 330 inode_id: generate_inode_id(), 331 size: 0, 332 blk_size: 0, 333 blocks: 0, 334 atime: TimeSpec::default(), 335 mtime: TimeSpec::default(), 336 ctime: TimeSpec::default(), 337 file_type, 338 mode, 339 nlinks: 1, 340 uid: 0, 341 gid: 0, 342 raw_dev: data, 343 }, 344 fs: guard.fs.clone(), 345 }))); 346 347 // 初始化inode的自引用的weak指针 348 result.0.lock().self_ref = Arc::downgrade(&result); 349 350 // 将子inode插入父inode的B树中 351 guard.children.insert(String::from(name), result.clone()); 352 return Ok(result); 353 } 354 } 355 356 impl IndexNode for LockedDevFSInode { 357 fn as_any_ref(&self) -> &dyn core::any::Any { 358 self 359 } 360 361 fn open( 362 &self, 363 _data: &mut super::vfs::FilePrivateData, 364 _mode: &FileMode, 365 ) -> Result<(), SystemError> { 366 return Ok(()); 367 } 368 369 fn close(&self, _data: &mut super::vfs::FilePrivateData) -> Result<(), SystemError> { 370 return Ok(()); 371 } 372 373 fn create_with_data( 374 &self, 375 name: &str, 376 file_type: FileType, 377 mode: ModeType, 378 data: usize, 379 ) -> Result<Arc<dyn IndexNode>, SystemError> { 380 // 获取当前inode 381 let guard: SpinLockGuard<DevFSInode> = self.0.lock(); 382 // 如果当前inode不是文件夹,则返回 383 return self.do_create_with_data(guard, name, file_type, mode, data); 384 } 385 386 fn find(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError> { 387 let inode = self.0.lock(); 388 389 if inode.metadata.file_type != FileType::Dir { 390 return Err(SystemError::ENOTDIR); 391 } 392 393 match name { 394 "" | "." => { 395 return Ok(inode.self_ref.upgrade().ok_or(SystemError::ENOENT)?); 396 } 397 ".." => { 398 return Ok(inode.parent.upgrade().ok_or(SystemError::ENOENT)?); 399 } 400 name => { 401 // 在子目录项中查找 402 return Ok(inode.children.get(name).ok_or(SystemError::ENOENT)?.clone()); 403 } 404 } 405 } 406 407 fn fs(&self) -> Arc<dyn FileSystem> { 408 return self.0.lock().fs.upgrade().unwrap(); 409 } 410 411 fn get_entry_name(&self, ino: super::vfs::InodeId) -> Result<String, SystemError> { 412 let inode: SpinLockGuard<DevFSInode> = self.0.lock(); 413 if inode.metadata.file_type != FileType::Dir { 414 return Err(SystemError::ENOTDIR); 415 } 416 417 match ino.into() { 418 0 => { 419 return Ok(String::from(".")); 420 } 421 1 => { 422 return Ok(String::from("..")); 423 } 424 ino => { 425 // 暴力遍历所有的children,判断inode id是否相同 426 // TODO: 优化这里,这个地方性能很差! 427 let mut key: Vec<String> = inode 428 .children 429 .keys() 430 .filter(|k| { 431 inode 432 .children 433 .get(*k) 434 .unwrap() 435 .metadata() 436 .unwrap() 437 .inode_id 438 .into() 439 == ino 440 }) 441 .cloned() 442 .collect(); 443 444 match key.len() { 445 0=>{return Err(SystemError::ENOENT);} 446 1=>{return Ok(key.remove(0));} 447 _ => 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) 448 } 449 } 450 } 451 } 452 453 fn ioctl(&self, _cmd: u32, _data: usize) -> Result<usize, SystemError> { 454 Err(SystemError::EOPNOTSUPP_OR_ENOTSUP) 455 } 456 457 fn list(&self) -> Result<Vec<String>, SystemError> { 458 let info = self.metadata()?; 459 if info.file_type != FileType::Dir { 460 return Err(SystemError::ENOTDIR); 461 } 462 463 let mut keys: Vec<String> = Vec::new(); 464 keys.push(String::from(".")); 465 keys.push(String::from("..")); 466 keys.append(&mut self.0.lock().children.keys().cloned().collect()); 467 468 return Ok(keys); 469 } 470 471 fn metadata(&self) -> Result<Metadata, SystemError> { 472 return Ok(self.0.lock().metadata.clone()); 473 } 474 475 fn set_metadata(&self, metadata: &Metadata) -> Result<(), SystemError> { 476 let mut inode = self.0.lock(); 477 inode.metadata.atime = metadata.atime; 478 inode.metadata.mtime = metadata.mtime; 479 inode.metadata.ctime = metadata.ctime; 480 inode.metadata.mode = metadata.mode; 481 inode.metadata.uid = metadata.uid; 482 inode.metadata.gid = metadata.gid; 483 484 return Ok(()); 485 } 486 487 fn poll(&self) -> Result<super::vfs::PollStatus, SystemError> { 488 // 加锁 489 let inode: SpinLockGuard<DevFSInode> = self.0.lock(); 490 491 // 检查当前inode是否为一个文件夹,如果是的话,就返回错误 492 if inode.metadata.file_type == FileType::Dir { 493 return Err(SystemError::EISDIR); 494 } 495 496 return Ok(PollStatus::READ | PollStatus::WRITE); 497 } 498 499 /// 读设备 - 应该调用设备的函数读写,而不是通过文件系统读写 500 fn read_at( 501 &self, 502 _offset: usize, 503 _len: usize, 504 _buf: &mut [u8], 505 _data: &mut super::vfs::file::FilePrivateData, 506 ) -> Result<usize, SystemError> { 507 kerror!("DevFS: read_at is not supported!"); 508 Err(SystemError::EOPNOTSUPP_OR_ENOTSUP) 509 } 510 511 /// 写设备 - 应该调用设备的函数读写,而不是通过文件系统读写 512 fn write_at( 513 &self, 514 _offset: usize, 515 _len: usize, 516 _buf: &[u8], 517 _data: &mut super::vfs::file::FilePrivateData, 518 ) -> Result<usize, SystemError> { 519 Err(SystemError::EOPNOTSUPP_OR_ENOTSUP) 520 } 521 } 522 523 /// @brief 所有的设备INode都需要额外实现这个trait 524 pub trait DeviceINode: IndexNode { 525 fn set_fs(&self, fs: Weak<DevFS>); 526 // TODO: 增加 unregister 方法 527 } 528 529 /// @brief 获取devfs实例的强类型不可变引用 530 macro_rules! devfs_exact_ref { 531 () => {{ 532 let devfs_inode: Result<Arc<dyn IndexNode>, SystemError> = ROOT_INODE().find("dev"); 533 if let Err(e) = devfs_inode { 534 kerror!("failed to get DevFS ref. errcode = {:?}", e); 535 return Err(SystemError::ENOENT); 536 } 537 538 let binding = devfs_inode.unwrap(); 539 let devfs_inode: &LockedDevFSInode = binding 540 .as_any_ref() 541 .downcast_ref::<LockedDevFSInode>() 542 .unwrap(); 543 let binding = devfs_inode.fs(); 544 binding 545 } 546 .as_any_ref() 547 .downcast_ref::<DevFS>() 548 .unwrap()}; 549 } 550 /// @brief devfs的设备注册函数 551 pub fn devfs_register<T: DeviceINode>(name: &str, device: Arc<T>) -> Result<(), SystemError> { 552 return devfs_exact_ref!().register_device(name, device); 553 } 554 555 /// @brief devfs的设备卸载函数 556 #[allow(dead_code)] 557 pub fn devfs_unregister<T: DeviceINode>(name: &str, device: Arc<T>) -> Result<(), SystemError> { 558 return devfs_exact_ref!().unregister_device(name, device); 559 } 560 561 pub fn devfs_init() -> Result<(), SystemError> { 562 static INIT: Once = Once::new(); 563 let mut result = None; 564 INIT.call_once(|| { 565 kinfo!("Initializing DevFS..."); 566 // 创建 devfs 实例 567 let devfs: Arc<DevFS> = DevFS::new(); 568 // devfs 挂载 569 let _t = ROOT_INODE() 570 .find("dev") 571 .expect("Cannot find /dev") 572 .mount(devfs) 573 .expect("Failed to mount devfs"); 574 kinfo!("DevFS mounted."); 575 result = Some(Ok(())); 576 }); 577 578 return result.unwrap(); 579 } 580