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 FileSystem, FileType, FsInfo, IndexNode, Metadata, PollStatus, 8 }; 9 use crate::{ 10 include::bindings::bindings::{EEXIST, EISDIR, ENOENT, ENOTDIR, ENOTSUP}, 11 kdebug, kerror, 12 libs::spinlock::{SpinLock, SpinLockGuard}, 13 time::TimeSpec, 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<(), i32> { 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(-(ENOTSUP as i32)); 131 } 132 } 133 134 return Ok(()); 135 } 136 137 /// @brief 卸载设备 138 pub fn unregister_device<T: DeviceINode>(&self, name: &str, device: Arc<T>) -> Result<(), i32> { 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(-(ENOENT as i32)); 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(-(ENOENT as i32)); 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(-(ENOTSUP as i32)); 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<(), i32> { 234 let guard:SpinLockGuard<DevFSInode> = self.0.lock(); 235 236 if guard.children.contains_key(name) { 237 return Err(-(EEXIST as i32)); 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<(), i32> { 251 let mut this = self.0.lock(); 252 253 if this.children.contains_key(name) { 254 return Err(-(EEXIST as i32)); 255 } 256 257 this.children.insert(name.to_string(), dev); 258 return Ok(()); 259 } 260 261 pub fn remove(&self, name: &str) -> Result<(), i32> { 262 let x = self 263 .0 264 .lock() 265 .children 266 .remove(name) 267 .ok_or(-(ENOENT as i32))?; 268 269 drop(x); 270 return Ok(()); 271 } 272 273 fn do_create_with_data(&self, mut guard: SpinLockGuard<DevFSInode>,_name: &str, 274 _file_type: FileType, 275 _mode: u32, 276 _data: usize,) -> Result<Arc<dyn IndexNode>, i32>{ 277 if guard.metadata.file_type != FileType::Dir { 278 return Err(-(ENOTDIR as i32)); 279 } 280 281 // 如果有重名的,则返回 282 if guard.children.contains_key(_name) { 283 return Err(-(EEXIST as i32)); 284 } 285 286 // 创建inode 287 let result: Arc<LockedDevFSInode> = Arc::new(LockedDevFSInode(SpinLock::new(DevFSInode { 288 parent: guard.self_ref.clone(), 289 self_ref: Weak::default(), 290 children: BTreeMap::new(), 291 metadata: Metadata { 292 dev_id: 0, 293 inode_id: generate_inode_id(), 294 size: 0, 295 blk_size: 0, 296 blocks: 0, 297 atime: TimeSpec::default(), 298 mtime: TimeSpec::default(), 299 ctime: TimeSpec::default(), 300 file_type: _file_type, 301 mode: _mode, 302 nlinks: 1, 303 uid: 0, 304 gid: 0, 305 raw_dev: _data, 306 }, 307 fs: guard.fs.clone(), 308 }))); 309 310 // 初始化inode的自引用的weak指针 311 result.0.lock().self_ref = Arc::downgrade(&result); 312 313 // 将子inode插入父inode的B树中 314 guard.children.insert(String::from(_name), result.clone()); 315 return Ok(result); 316 317 } 318 } 319 320 impl IndexNode for LockedDevFSInode { 321 fn as_any_ref(&self) -> &dyn core::any::Any { 322 self 323 } 324 325 fn open(&self, _data: &mut super::vfs::FilePrivateData) -> Result<(), i32> { 326 return Ok(()); 327 } 328 329 fn close(&self, _data: &mut super::vfs::FilePrivateData) -> Result<(), i32> { 330 return Ok(()); 331 } 332 333 fn create_with_data( 334 &self, 335 name: &str, 336 file_type: FileType, 337 mode: u32, 338 data: usize, 339 ) -> Result<Arc<dyn IndexNode>, i32> { 340 // 获取当前inode 341 let guard:SpinLockGuard<DevFSInode> = self.0.lock(); 342 // 如果当前inode不是文件夹,则返回 343 return self.do_create_with_data(guard, name, file_type, mode, data); 344 } 345 346 fn find(&self, name: &str) -> Result<Arc<dyn IndexNode>, i32> { 347 let inode = self.0.lock(); 348 349 if inode.metadata.file_type != FileType::Dir { 350 return Err(-(ENOTDIR as i32)); 351 } 352 353 match name { 354 "" | "." => { 355 return Ok(inode.self_ref.upgrade().ok_or(-(ENOENT as i32))?); 356 } 357 ".." => { 358 return Ok(inode.parent.upgrade().ok_or(-(ENOENT as i32))?); 359 } 360 name => { 361 // 在子目录项中查找 362 return Ok(inode.children.get(name).ok_or(-(ENOENT as i32))?.clone()); 363 } 364 } 365 } 366 367 fn fs(&self) -> Arc<dyn FileSystem> { 368 return self.0.lock().fs.upgrade().unwrap(); 369 } 370 371 fn get_entry_name(&self, ino: super::vfs::InodeId) -> Result<String, i32> { 372 let inode: SpinLockGuard<DevFSInode> = self.0.lock(); 373 if inode.metadata.file_type != FileType::Dir { 374 return Err(-(ENOTDIR as i32)); 375 } 376 377 match ino { 378 0 => { 379 return Ok(String::from(".")); 380 } 381 1 => { 382 return Ok(String::from("..")); 383 } 384 ino => { 385 // 暴力遍历所有的children,判断inode id是否相同 386 // TODO: 优化这里,这个地方性能很差! 387 let mut key: Vec<String> = inode 388 .children 389 .keys() 390 .filter(|k| inode.children.get(*k).unwrap().metadata().unwrap().inode_id == ino) 391 .cloned() 392 .collect(); 393 394 match key.len() { 395 0=>{return Err(-(ENOENT as i32));} 396 1=>{return Ok(key.remove(0));} 397 _ => 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) 398 } 399 } 400 } 401 } 402 403 fn ioctl(&self, _cmd: u32, _data: usize) -> Result<usize, i32> { 404 Err(-(ENOTSUP as i32)) 405 } 406 407 fn list(&self) -> Result<Vec<String>, i32> { 408 let info = self.metadata()?; 409 if info.file_type != FileType::Dir { 410 return Err(-(ENOTDIR as i32)); 411 } 412 413 let mut keys: Vec<String> = Vec::new(); 414 keys.push(String::from(".")); 415 keys.push(String::from("..")); 416 keys.append(&mut self.0.lock().children.keys().cloned().collect()); 417 418 return Ok(keys); 419 } 420 421 fn metadata(&self) -> Result<Metadata, i32> { 422 return Ok(self.0.lock().metadata.clone()); 423 } 424 425 fn set_metadata(&self, metadata: &Metadata) -> Result<(), i32> { 426 let mut inode = self.0.lock(); 427 inode.metadata.atime = metadata.atime; 428 inode.metadata.mtime = metadata.mtime; 429 inode.metadata.ctime = metadata.ctime; 430 inode.metadata.mode = metadata.mode; 431 inode.metadata.uid = metadata.uid; 432 inode.metadata.gid = metadata.gid; 433 434 return Ok(()); 435 } 436 437 fn poll(&self) -> Result<super::vfs::PollStatus, i32> { 438 // 加锁 439 let inode: SpinLockGuard<DevFSInode> = self.0.lock(); 440 441 // 检查当前inode是否为一个文件夹,如果是的话,就返回错误 442 if inode.metadata.file_type == FileType::Dir { 443 return Err(-(EISDIR as i32)); 444 } 445 446 return Ok(PollStatus { 447 flags: PollStatus::READ_MASK | PollStatus::WRITE_MASK, 448 }); 449 } 450 451 /// 读设备 - 应该调用设备的函数读写,而不是通过文件系统读写 452 fn read_at( 453 &self, 454 _offset: usize, 455 _len: usize, 456 _buf: &mut [u8], 457 _data: &mut super::vfs::file::FilePrivateData, 458 ) -> Result<usize, i32> { 459 Err(-(ENOTSUP as i32)) 460 } 461 462 /// 写设备 - 应该调用设备的函数读写,而不是通过文件系统读写 463 fn write_at( 464 &self, 465 _offset: usize, 466 _len: usize, 467 _buf: &[u8], 468 _data: &mut super::vfs::file::FilePrivateData, 469 ) -> Result<usize, i32> { 470 Err(-(ENOTSUP as i32)) 471 } 472 } 473 474 /// @brief 所有的设备INode都需要额外实现这个trait 475 pub trait DeviceINode: IndexNode { 476 fn set_fs(&self, fs: Weak<DevFS>); 477 // TODO: 增加 unregister 方法 478 } 479 480 /// @brief 获取devfs实例的强类型不可变引用 481 macro_rules! devfs_exact_ref { 482 () => {{ 483 let devfs_inode: Result<Arc<dyn IndexNode>, i32> = ROOT_INODE().find("dev"); 484 if let Err(e) = devfs_inode { 485 kerror!("failed to get DevFS ref. errcode = {e}"); 486 return Err(-(ENOENT as i32)); 487 } 488 489 let binding = devfs_inode.unwrap(); 490 let devfs_inode: &LockedDevFSInode = binding 491 .as_any_ref() 492 .downcast_ref::<LockedDevFSInode>() 493 .unwrap(); 494 let binding = devfs_inode.fs(); 495 binding 496 } 497 .as_any_ref() 498 .downcast_ref::<DevFS>() 499 .unwrap()}; 500 } 501 /// @brief devfs的设备注册函数 502 pub fn devfs_register<T: DeviceINode>(name: &str, device: Arc<T>) -> Result<(), i32> { 503 return devfs_exact_ref!().register_device(name, device); 504 } 505 506 /// @brief devfs的设备卸载函数 507 #[allow(dead_code)] 508 pub fn devfs_unregister<T: DeviceINode>(name: &str, device: Arc<T>) -> Result<(), i32> { 509 return devfs_exact_ref!().unregister_device(name, device); 510 } 511