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