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