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