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