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