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