os/fs/proc/
proc.rs

1use crate::{
2    fs::proc::ProcInode,
3    vfs::{FileMode, FileSystem, FsError, Inode, StatFs},
4};
5use alloc::sync::Arc;
6
7pub struct ProcFS {
8    root_inode: Arc<ProcInode>,
9}
10
11impl ProcFS {
12    /// 创建新的 ProcFS 实例
13    pub fn new() -> Arc<Self> {
14        // 创建根目录
15        let root = ProcInode::new_directory(FileMode::from_bits_truncate(
16            0o555 | FileMode::S_IFDIR.bits(),
17        ));
18
19        Arc::new(Self { root_inode: root })
20    }
21
22    /// 初始化 proc 文件系统树结构
23    pub fn init_tree(self: &Arc<Self>) -> Result<(), FsError> {
24        use crate::fs::proc::generators::{
25            CpuinfoGenerator, MeminfoGenerator, MountsGenerator, UptimeGenerator,
26        };
27        use crate::kernel::current_task;
28
29        let root = &self.root_inode;
30
31        // 创建 /proc/meminfo
32        let meminfo = ProcInode::new_dynamic_file(
33            "meminfo",
34            alloc::sync::Arc::new(MeminfoGenerator),
35            FileMode::from_bits_truncate(0o444), // r--r--r--
36        );
37        root.add_child("meminfo", meminfo)?;
38
39        // 创建 /proc/uptime
40        let uptime = ProcInode::new_dynamic_file(
41            "uptime",
42            alloc::sync::Arc::new(UptimeGenerator),
43            FileMode::from_bits_truncate(0o444), // r--r--r--
44        );
45        root.add_child("uptime", uptime)?;
46
47        // 创建 /proc/cpuinfo
48        let cpuinfo = ProcInode::new_dynamic_file(
49            "cpuinfo",
50            alloc::sync::Arc::new(CpuinfoGenerator),
51            FileMode::from_bits_truncate(0o444), // r--r--r--
52        );
53        root.add_child("cpuinfo", cpuinfo)?;
54
55        // 创建 /proc/mounts
56        let mounts = ProcInode::new_dynamic_file(
57            "mounts",
58            alloc::sync::Arc::new(MountsGenerator),
59            FileMode::from_bits_truncate(0o444), // r--r--r--
60        );
61        root.add_child("mounts", mounts)?;
62
63        // 创建 /proc/self - 动态符号链接,指向当前进程
64        let self_link = ProcInode::new_dynamic_symlink("self", || {
65            use alloc::string::ToString;
66            // 获取当前任务的 PID 并转换为字符串
67            let task = current_task();
68            task.lock().pid.to_string()
69        });
70        root.add_child("self", self_link)?;
71
72        Ok(())
73    }
74}
75
76impl FileSystem for ProcFS {
77    fn fs_type(&self) -> &'static str {
78        "proc"
79    }
80
81    fn root_inode(&self) -> Arc<dyn Inode> {
82        self.root_inode.clone()
83    }
84
85    fn sync(&self) -> Result<(), FsError> {
86        // proc 是纯内存文件系统,无需同步
87        Ok(())
88    }
89
90    fn statfs(&self) -> Result<StatFs, FsError> {
91        Ok(StatFs {
92            block_size: 4096,
93            total_blocks: 0,
94            free_blocks: 0,
95            available_blocks: 0,
96            total_inodes: 0,
97            free_inodes: 0,
98            fsid: 0,
99            max_filename_len: 255,
100        })
101    }
102}