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