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