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