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