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