xref: /DragonOS/kernel/src/filesystem/procfs/mod.rs (revision fba5623183378da6b120caafca120615328efa2e)
1 use core::intrinsics::size_of;
2 
3 use alloc::{
4     borrow::ToOwned,
5     collections::BTreeMap,
6     format,
7     string::String,
8     sync::{Arc, Weak},
9     vec::Vec,
10 };
11 
12 use crate::{
13     filesystem::vfs::{
14         core::{generate_inode_id, ROOT_INODE},
15         FileType,
16     },
17     kerror, kinfo,
18     libs::{
19         once::Once,
20         spinlock::{SpinLock, SpinLockGuard},
21     },
22     process::{Pid, ProcessManager},
23     syscall::SystemError,
24     time::TimeSpec,
25 };
26 
27 use super::vfs::{
28     file::{FileMode, FilePrivateData},
29     syscall::ModeType,
30     FileSystem, FsInfo, IndexNode, InodeId, Metadata, PollStatus,
31 };
32 
33 /// @brief 进程文件类型
34 /// @usage 用于定义进程文件夹下的各类文件类型
35 #[derive(Debug)]
36 #[repr(u8)]
37 pub enum ProcFileType {
38     ///展示进程状态信息
39     ProcStatus = 0,
40     //todo: 其他文件类型
41     ///默认文件类型
42     Default,
43 }
44 
45 impl From<u8> for ProcFileType {
46     fn from(value: u8) -> Self {
47         match value {
48             0 => ProcFileType::ProcStatus,
49             _ => ProcFileType::Default,
50         }
51     }
52 }
53 /// @brief 节点私有信息结构体
54 /// @usage 用于传入各类文件所需的信息
55 #[derive(Debug)]
56 pub struct InodeInfo {
57     ///进程的pid
58     pid: Pid,
59     ///文件类型
60     ftype: ProcFileType,
61     //其他需要传入的信息在此定义
62 }
63 
64 /// @brief procfs的inode名称的最大长度
65 const PROCFS_MAX_NAMELEN: usize = 64;
66 
67 /// @brief procfs文件系统的Inode结构体
68 #[derive(Debug)]
69 pub struct LockedProcFSInode(SpinLock<ProcFSInode>);
70 
71 /// @brief procfs文件系统结构体
72 #[derive(Debug)]
73 pub struct ProcFS {
74     /// procfs的root inode
75     root_inode: Arc<LockedProcFSInode>,
76 }
77 
78 #[derive(Debug, Clone)]
79 pub struct ProcfsFilePrivateData {
80     data: Vec<u8>,
81 }
82 
83 impl ProcfsFilePrivateData {
84     pub fn new() -> Self {
85         return ProcfsFilePrivateData { data: Vec::new() };
86     }
87 }
88 
89 /// @brief procfs文件系统的Inode结构体(不包含锁)
90 #[derive(Debug)]
91 pub struct ProcFSInode {
92     /// 指向父Inode的弱引用
93     parent: Weak<LockedProcFSInode>,
94     /// 指向自身的弱引用
95     self_ref: Weak<LockedProcFSInode>,
96     /// 子Inode的B树
97     children: BTreeMap<String, Arc<LockedProcFSInode>>,
98     /// 当前inode的数据部分
99     data: Vec<u8>,
100     /// 当前inode的元数据
101     metadata: Metadata,
102     /// 指向inode所在的文件系统对象的指针
103     fs: Weak<ProcFS>,
104     /// 储存私有信息
105     fdata: InodeInfo,
106 }
107 
108 /// 对ProcFSInode实现获取各类文件信息的函数
109 impl ProcFSInode {
110     /// @brief 去除Vec中所有的\0,并在结尾添加\0
111     #[inline]
112     fn trim_string(&self, data: &mut Vec<u8>) {
113         data.drain_filter(|x: &mut u8| *x == 0);
114         data.push(0);
115     }
116     // todo:其他数据获取函数实现
117 
118     /// @brief 打开status文件
119     ///
120     fn open_status(&self, pdata: &mut ProcfsFilePrivateData) -> Result<i64, SystemError> {
121         // 获取该pid对应的pcb结构体
122         let pid = self.fdata.pid;
123         let pcb = ProcessManager::find(pid);
124         let pcb = if pcb.is_none() {
125             kerror!(
126                 "ProcFS: Cannot find pcb for pid {:?} when opening its 'status' file.",
127                 pid
128             );
129             return Err(SystemError::ESRCH);
130         } else {
131             pcb.unwrap()
132         };
133         // 传入数据
134         let pdata: &mut Vec<u8> = &mut pdata.data;
135 
136         pdata.append(
137             &mut format!("Name:\t{}", pcb.basic().name())
138                 .as_bytes()
139                 .to_owned(),
140         );
141 
142         let sched_info_guard = pcb.sched_info();
143         let state = sched_info_guard.state();
144         let cpu_id = sched_info_guard
145             .on_cpu()
146             .map(|cpu| cpu as i32)
147             .unwrap_or(-1);
148 
149         let priority = sched_info_guard.priority();
150         let vrtime = sched_info_guard.virtual_runtime();
151 
152         drop(sched_info_guard);
153 
154         pdata.append(&mut format!("\nState:\t{:?}", state).as_bytes().to_owned());
155         pdata.append(
156             &mut format!("\nPid:\t{}", pcb.pid().into())
157                 .as_bytes()
158                 .to_owned(),
159         );
160         pdata.append(
161             &mut format!("\nPpid:\t{}", pcb.basic().ppid().into())
162                 .as_bytes()
163                 .to_owned(),
164         );
165         pdata.append(&mut format!("\ncpu_id:\t{}", cpu_id).as_bytes().to_owned());
166         pdata.append(
167             &mut format!("\npriority:\t{}", priority.data())
168                 .as_bytes()
169                 .to_owned(),
170         );
171         pdata.append(
172             &mut format!("\npreempt:\t{}", pcb.preempt_count())
173                 .as_bytes()
174                 .to_owned(),
175         );
176         pdata.append(&mut format!("\nvrtime:\t{}", vrtime).as_bytes().to_owned());
177 
178         let binding = pcb.basic().user_vm().unwrap();
179         let address_space_guard = binding.read();
180         // todo: 当前进程运行过程中占用内存的峰值
181         let hiwater_vm: u64 = 0;
182         // 进程代码段的大小
183         let text = (address_space_guard.end_code - address_space_guard.start_code) / 1024;
184         // 进程数据段的大小
185         let data = (address_space_guard.end_data - address_space_guard.start_data) / 1024;
186         drop(address_space_guard);
187 
188         pdata.append(
189             &mut format!("\nVmPeak:\t{} kB", hiwater_vm)
190                 .as_bytes()
191                 .to_owned(),
192         );
193         pdata.append(&mut format!("\nVmData:\t{} kB", data).as_bytes().to_owned());
194         pdata.append(&mut format!("\nVmExe:\t{} kB", text).as_bytes().to_owned());
195         pdata.append(
196             &mut format!("\nflags: {:?}\n", pcb.flags().clone())
197                 .as_bytes()
198                 .to_owned(),
199         );
200 
201         // 去除多余的\0
202         self.trim_string(pdata);
203 
204         return Ok((pdata.len() * size_of::<u8>()) as i64);
205     }
206 
207     /// status文件读取函数
208     fn read_status(
209         &self,
210         offset: usize,
211         len: usize,
212         buf: &mut [u8],
213         _pdata: &mut ProcfsFilePrivateData,
214     ) -> Result<usize, SystemError> {
215         let start = _pdata.data.len().min(offset);
216         let end = _pdata.data.len().min(offset + len);
217 
218         // buffer空间不足
219         if buf.len() < (end - start) {
220             return Err(SystemError::ENOBUFS);
221         }
222 
223         // 拷贝数据
224         let src = &_pdata.data[start..end];
225         buf[0..src.len()].copy_from_slice(src);
226         return Ok(src.len());
227     }
228 }
229 
230 impl FileSystem for ProcFS {
231     fn root_inode(&self) -> Arc<dyn super::vfs::IndexNode> {
232         return self.root_inode.clone();
233     }
234 
235     fn info(&self) -> FsInfo {
236         return FsInfo {
237             blk_dev_id: 0,
238             max_name_len: PROCFS_MAX_NAMELEN,
239         };
240     }
241 
242     fn as_any_ref(&self) -> &dyn core::any::Any {
243         self
244     }
245 }
246 
247 impl ProcFS {
248     pub fn new() -> Arc<Self> {
249         // 初始化root inode
250         let root: Arc<LockedProcFSInode> =
251             Arc::new(LockedProcFSInode(SpinLock::new(ProcFSInode {
252                 parent: Weak::default(),
253                 self_ref: Weak::default(),
254                 children: BTreeMap::new(),
255                 data: Vec::new(),
256                 metadata: Metadata {
257                     dev_id: 0,
258                     inode_id: generate_inode_id(),
259                     size: 0,
260                     blk_size: 0,
261                     blocks: 0,
262                     atime: TimeSpec::default(),
263                     mtime: TimeSpec::default(),
264                     ctime: TimeSpec::default(),
265                     file_type: FileType::Dir,
266                     mode: ModeType::from_bits_truncate(0o777),
267                     nlinks: 1,
268                     uid: 0,
269                     gid: 0,
270                     raw_dev: 0,
271                 },
272                 fs: Weak::default(),
273                 fdata: InodeInfo {
274                     pid: Pid::new(0),
275                     ftype: ProcFileType::Default,
276                 },
277             })));
278 
279         let result: Arc<ProcFS> = Arc::new(ProcFS { root_inode: root });
280 
281         // 对root inode加锁,并继续完成初始化工作
282         let mut root_guard: SpinLockGuard<ProcFSInode> = result.root_inode.0.lock();
283         root_guard.parent = Arc::downgrade(&result.root_inode);
284         root_guard.self_ref = Arc::downgrade(&result.root_inode);
285         root_guard.fs = Arc::downgrade(&result);
286         // 释放锁
287         drop(root_guard);
288 
289         return result;
290     }
291 
292     /// @brief 进程注册函数
293     /// @usage 在进程中调用并创建进程对应文件
294     pub fn register_pid(&self, pid: Pid) -> Result<(), SystemError> {
295         // 获取当前inode
296         let proc: Arc<dyn IndexNode> = self.root_inode();
297         // 创建对应进程文件夹
298         let _pf: Arc<dyn IndexNode> = proc.create(
299             &pid.to_string(),
300             FileType::Dir,
301             ModeType::from_bits_truncate(0o777),
302         )?;
303         // 创建相关文件
304         // status文件
305         let binding: Arc<dyn IndexNode> = _pf.create(
306             "status",
307             FileType::File,
308             ModeType::from_bits_truncate(0o777),
309         )?;
310         let _sf: &LockedProcFSInode = binding
311             .as_any_ref()
312             .downcast_ref::<LockedProcFSInode>()
313             .unwrap();
314         _sf.0.lock().fdata.pid = pid;
315         _sf.0.lock().fdata.ftype = ProcFileType::ProcStatus;
316 
317         //todo: 创建其他文件
318 
319         return Ok(());
320     }
321 
322     /// @brief 解除进程注册
323     ///
324     pub fn unregister_pid(&self, pid: Pid) -> Result<(), SystemError> {
325         // 获取当前inode
326         let proc: Arc<dyn IndexNode> = self.root_inode();
327         // 获取进程文件夹
328         let pid_dir: Arc<dyn IndexNode> = proc.find(&pid.to_string())?;
329         // 删除进程文件夹下文件
330         pid_dir.unlink("status")?;
331 
332         // 查看进程文件是否还存在
333         // let pf= pid_dir.find("status").expect("Cannot find status");
334 
335         // 删除进程文件夹
336         proc.unlink(&pid.to_string())?;
337 
338         return Ok(());
339     }
340 }
341 
342 impl IndexNode for LockedProcFSInode {
343     fn open(&self, data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> {
344         // 加锁
345         let mut inode: SpinLockGuard<ProcFSInode> = self.0.lock();
346 
347         // 如果inode类型为文件夹,则直接返回成功
348         if let FileType::Dir = inode.metadata.file_type {
349             return Ok(());
350         }
351         let mut private_data = ProcfsFilePrivateData::new();
352         // 根据文件类型获取相应数据
353         let file_size = match inode.fdata.ftype {
354             ProcFileType::ProcStatus => inode.open_status(&mut private_data)?,
355             _ => {
356                 todo!()
357             }
358         };
359         *data = FilePrivateData::Procfs(private_data);
360         // 更新metadata里面的文件大小数值
361         inode.metadata.size = file_size;
362 
363         return Ok(());
364     }
365 
366     fn close(&self, data: &mut FilePrivateData) -> Result<(), SystemError> {
367         let guard: SpinLockGuard<ProcFSInode> = self.0.lock();
368         // 如果inode类型为文件夹,则直接返回成功
369         if let FileType::Dir = guard.metadata.file_type {
370             return Ok(());
371         }
372         // 获取数据信息
373         let private_data = match data {
374             FilePrivateData::Procfs(p) => p,
375             _ => {
376                 panic!("ProcFS: FilePrivateData mismatch!");
377             }
378         };
379         // 释放资源
380         drop(private_data);
381         return Ok(());
382     }
383 
384     fn read_at(
385         &self,
386         offset: usize,
387         len: usize,
388         buf: &mut [u8],
389         data: &mut FilePrivateData,
390     ) -> Result<usize, SystemError> {
391         if buf.len() < len {
392             return Err(SystemError::EINVAL);
393         }
394         // 加锁
395         let inode: SpinLockGuard<ProcFSInode> = self.0.lock();
396 
397         // 检查当前inode是否为一个文件夹,如果是的话,就返回错误
398         if inode.metadata.file_type == FileType::Dir {
399             return Err(SystemError::EISDIR);
400         }
401 
402         // 获取数据信息
403         let private_data = match data {
404             FilePrivateData::Procfs(p) => p,
405             _ => {
406                 panic!("ProcFS: FilePrivateData mismatch!");
407             }
408         };
409 
410         // 根据文件类型读取相应数据
411         match inode.fdata.ftype {
412             ProcFileType::ProcStatus => return inode.read_status(offset, len, buf, private_data),
413             ProcFileType::Default => (),
414         };
415 
416         // 默认读取
417         let start = inode.data.len().min(offset);
418         let end = inode.data.len().min(offset + len);
419 
420         // buffer空间不足
421         if buf.len() < (end - start) {
422             return Err(SystemError::ENOBUFS);
423         }
424 
425         // 拷贝数据
426         let src = &inode.data[start..end];
427         buf[0..src.len()].copy_from_slice(src);
428         return Ok(src.len());
429     }
430 
431     fn write_at(
432         &self,
433         _offset: usize,
434         _len: usize,
435         _buf: &[u8],
436         _data: &mut FilePrivateData,
437     ) -> Result<usize, SystemError> {
438         return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
439     }
440 
441     fn poll(&self) -> Result<PollStatus, SystemError> {
442         // 加锁
443         let inode: SpinLockGuard<ProcFSInode> = self.0.lock();
444 
445         // 检查当前inode是否为一个文件夹,如果是的话,就返回错误
446         if inode.metadata.file_type == FileType::Dir {
447             return Err(SystemError::EISDIR);
448         }
449 
450         return Ok(PollStatus::READ);
451     }
452 
453     fn fs(&self) -> Arc<dyn FileSystem> {
454         return self.0.lock().fs.upgrade().unwrap();
455     }
456 
457     fn as_any_ref(&self) -> &dyn core::any::Any {
458         self
459     }
460 
461     fn metadata(&self) -> Result<Metadata, SystemError> {
462         let inode = self.0.lock();
463         let metadata = inode.metadata.clone();
464 
465         return Ok(metadata);
466     }
467 
468     fn set_metadata(&self, metadata: &Metadata) -> Result<(), SystemError> {
469         let mut inode = self.0.lock();
470         inode.metadata.atime = metadata.atime;
471         inode.metadata.mtime = metadata.mtime;
472         inode.metadata.ctime = metadata.ctime;
473         inode.metadata.mode = metadata.mode;
474         inode.metadata.uid = metadata.uid;
475         inode.metadata.gid = metadata.gid;
476 
477         return Ok(());
478     }
479 
480     fn resize(&self, len: usize) -> Result<(), SystemError> {
481         let mut inode = self.0.lock();
482         if inode.metadata.file_type == FileType::File {
483             inode.data.resize(len, 0);
484             return Ok(());
485         } else {
486             return Err(SystemError::EINVAL);
487         }
488     }
489 
490     fn create_with_data(
491         &self,
492         name: &str,
493         file_type: FileType,
494         mode: ModeType,
495         data: usize,
496     ) -> Result<Arc<dyn IndexNode>, SystemError> {
497         // 获取当前inode
498         let mut inode = self.0.lock();
499         // 如果当前inode不是文件夹,则返回
500         if inode.metadata.file_type != FileType::Dir {
501             return Err(SystemError::ENOTDIR);
502         }
503         // 如果有重名的,则返回
504         if inode.children.contains_key(name) {
505             return Err(SystemError::EEXIST);
506         }
507 
508         // 创建inode
509         let result: Arc<LockedProcFSInode> =
510             Arc::new(LockedProcFSInode(SpinLock::new(ProcFSInode {
511                 parent: inode.self_ref.clone(),
512                 self_ref: Weak::default(),
513                 children: BTreeMap::new(),
514                 data: Vec::new(),
515                 metadata: Metadata {
516                     dev_id: 0,
517                     inode_id: generate_inode_id(),
518                     size: 0,
519                     blk_size: 0,
520                     blocks: 0,
521                     atime: TimeSpec::default(),
522                     mtime: TimeSpec::default(),
523                     ctime: TimeSpec::default(),
524                     file_type: file_type,
525                     mode: mode,
526                     nlinks: 1,
527                     uid: 0,
528                     gid: 0,
529                     raw_dev: data,
530                 },
531                 fs: inode.fs.clone(),
532                 fdata: InodeInfo {
533                     pid: Pid::new(0),
534                     ftype: ProcFileType::Default,
535                 },
536             })));
537 
538         // 初始化inode的自引用的weak指针
539         result.0.lock().self_ref = Arc::downgrade(&result);
540 
541         // 将子inode插入父inode的B树中
542         inode.children.insert(String::from(name), result.clone());
543 
544         return Ok(result);
545     }
546 
547     fn link(&self, name: &str, other: &Arc<dyn IndexNode>) -> Result<(), SystemError> {
548         let other: &LockedProcFSInode = other
549             .downcast_ref::<LockedProcFSInode>()
550             .ok_or(SystemError::EPERM)?;
551         let mut inode: SpinLockGuard<ProcFSInode> = self.0.lock();
552         let mut other_locked: SpinLockGuard<ProcFSInode> = other.0.lock();
553 
554         // 如果当前inode不是文件夹,那么报错
555         if inode.metadata.file_type != FileType::Dir {
556             return Err(SystemError::ENOTDIR);
557         }
558 
559         // 如果另一个inode是文件夹,那么也报错
560         if other_locked.metadata.file_type == FileType::Dir {
561             return Err(SystemError::EISDIR);
562         }
563 
564         // 如果当前文件夹下已经有同名文件,也报错。
565         if inode.children.contains_key(name) {
566             return Err(SystemError::EEXIST);
567         }
568 
569         inode
570             .children
571             .insert(String::from(name), other_locked.self_ref.upgrade().unwrap());
572 
573         // 增加硬链接计数
574         other_locked.metadata.nlinks += 1;
575         return Ok(());
576     }
577 
578     fn unlink(&self, name: &str) -> Result<(), SystemError> {
579         let mut inode: SpinLockGuard<ProcFSInode> = self.0.lock();
580         // 如果当前inode不是目录,那么也没有子目录/文件的概念了,因此要求当前inode的类型是目录
581         if inode.metadata.file_type != FileType::Dir {
582             return Err(SystemError::ENOTDIR);
583         }
584         // 不允许删除当前文件夹,也不允许删除上一个目录
585         if name == "." || name == ".." {
586             return Err(SystemError::ENOTEMPTY);
587         }
588 
589         // 获得要删除的文件的inode
590         let to_delete = inode.children.get(name).ok_or(SystemError::ENOENT)?;
591         // 减少硬链接计数
592         to_delete.0.lock().metadata.nlinks -= 1;
593         // 在当前目录中删除这个子目录项
594         inode.children.remove(name);
595         return Ok(());
596     }
597 
598     fn move_(
599         &self,
600         _old_name: &str,
601         _target: &Arc<dyn IndexNode>,
602         _new_name: &str,
603     ) -> Result<(), SystemError> {
604         return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
605     }
606 
607     fn find(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError> {
608         let inode = self.0.lock();
609 
610         if inode.metadata.file_type != FileType::Dir {
611             return Err(SystemError::ENOTDIR);
612         }
613 
614         match name {
615             "" | "." => {
616                 return Ok(inode.self_ref.upgrade().ok_or(SystemError::ENOENT)?);
617             }
618 
619             ".." => {
620                 return Ok(inode.parent.upgrade().ok_or(SystemError::ENOENT)?);
621             }
622             name => {
623                 // 在子目录项中查找
624                 return Ok(inode.children.get(name).ok_or(SystemError::ENOENT)?.clone());
625             }
626         }
627     }
628 
629     fn get_entry_name(&self, ino: InodeId) -> Result<String, SystemError> {
630         let inode: SpinLockGuard<ProcFSInode> = self.0.lock();
631         if inode.metadata.file_type != FileType::Dir {
632             return Err(SystemError::ENOTDIR);
633         }
634 
635         match ino.into() {
636             0 => {
637                 return Ok(String::from("."));
638             }
639             1 => {
640                 return Ok(String::from(".."));
641             }
642             ino => {
643                 // 暴力遍历所有的children,判断inode id是否相同
644                 // TODO: 优化这里,这个地方性能很差!
645                 let mut key: Vec<String> = inode
646                     .children
647                     .keys()
648                     .filter(|k| {
649                         inode
650                             .children
651                             .get(*k)
652                             .unwrap()
653                             .0
654                             .lock()
655                             .metadata
656                             .inode_id
657                             .into()
658                             == ino
659                     })
660                     .cloned()
661                     .collect();
662 
663                 match key.len() {
664                         0=>{return Err(SystemError::ENOENT);}
665                         1=>{return Ok(key.remove(0));}
666                         _ => panic!("Procfs 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)
667                     }
668             }
669         }
670     }
671 
672     fn list(&self) -> Result<Vec<String>, SystemError> {
673         let info = self.metadata()?;
674         if info.file_type != FileType::Dir {
675             return Err(SystemError::ENOTDIR);
676         }
677 
678         let mut keys: Vec<String> = Vec::new();
679         keys.push(String::from("."));
680         keys.push(String::from(".."));
681         keys.append(&mut self.0.lock().children.keys().cloned().collect());
682 
683         return Ok(keys);
684     }
685 }
686 
687 /// @brief 向procfs注册进程
688 pub fn procfs_register_pid(pid: Pid) -> Result<(), SystemError> {
689     let procfs_inode = ROOT_INODE().find("proc")?;
690 
691     let procfs_inode = procfs_inode
692         .downcast_ref::<LockedProcFSInode>()
693         .expect("Failed to find procfs' root inode");
694     let fs = procfs_inode.fs();
695     let procfs: &ProcFS = fs.as_any_ref().downcast_ref::<ProcFS>().unwrap();
696 
697     // 调用注册函数
698     procfs.register_pid(pid)?;
699 
700     return Ok(());
701 }
702 
703 /// @brief 在ProcFS中,解除进程的注册
704 pub fn procfs_unregister_pid(pid: Pid) -> Result<(), SystemError> {
705     // 获取procfs实例
706     let procfs_inode: Arc<dyn IndexNode> = ROOT_INODE().find("proc")?;
707 
708     let procfs_inode: &LockedProcFSInode = procfs_inode
709         .downcast_ref::<LockedProcFSInode>()
710         .expect("Failed to find procfs' root inode");
711     let fs: Arc<dyn FileSystem> = procfs_inode.fs();
712     let procfs: &ProcFS = fs.as_any_ref().downcast_ref::<ProcFS>().unwrap();
713 
714     // 调用解除注册函数
715     return procfs.unregister_pid(pid);
716 }
717 
718 pub fn procfs_init() -> Result<(), SystemError> {
719     static INIT: Once = Once::new();
720     let mut result = None;
721     INIT.call_once(|| {
722         kinfo!("Initializing ProcFS...");
723         // 创建 sysfs 实例
724         let procfs: Arc<ProcFS> = ProcFS::new();
725 
726         // sysfs 挂载
727         let _t = ROOT_INODE()
728             .find("proc")
729             .expect("Cannot find /proc")
730             .mount(procfs)
731             .expect("Failed to mount proc");
732         kinfo!("ProcFS mounted.");
733         result = Some(Ok(()));
734     });
735 
736     return result.unwrap();
737 }
738