1use alloc::string::ToString;
6use alloc::sync::Arc;
7
8use crate::vfs::{FileMode, FileSystem, FsError, Inode, StatFs};
9
10use super::inode::SysfsInode;
11
12pub struct SysFS {
14 root_inode: Arc<SysfsInode>,
15}
16
17impl SysFS {
18 pub fn new() -> Arc<Self> {
20 let root = SysfsInode::new_directory(FileMode::from_bits_truncate(
21 0o040000 | 0o555, ));
23
24 Arc::new(Self { root_inode: root })
25 }
26
27 pub fn init_tree(self: &Arc<Self>) -> Result<(), FsError> {
29 self.create_directory_structure()?;
31
32 self.build_device_trees()?;
34
35 Ok(())
36 }
37
38 fn create_directory_structure(&self) -> Result<(), FsError> {
39 let root = &self.root_inode;
40
41 let class_dir = SysfsInode::new_directory(FileMode::from_bits_truncate(0o040000 | 0o555));
43 root.add_child("class", class_dir.clone())?;
44
45 let block_dir = SysfsInode::new_directory(FileMode::from_bits_truncate(0o040000 | 0o555));
47 class_dir.add_child("block", block_dir)?;
48
49 let net_dir = SysfsInode::new_directory(FileMode::from_bits_truncate(0o040000 | 0o555));
51 class_dir.add_child("net", net_dir)?;
52
53 let tty_dir = SysfsInode::new_directory(FileMode::from_bits_truncate(0o040000 | 0o555));
55 class_dir.add_child("tty", tty_dir)?;
56
57 let input_dir = SysfsInode::new_directory(FileMode::from_bits_truncate(0o040000 | 0o555));
59 class_dir.add_child("input", input_dir)?;
60
61 let rtc_dir = SysfsInode::new_directory(FileMode::from_bits_truncate(0o040000 | 0o555));
63 class_dir.add_child("rtc", rtc_dir)?;
64
65 let kernel_dir = SysfsInode::new_directory(FileMode::from_bits_truncate(0o040000 | 0o555));
67 root.add_child("kernel", kernel_dir)?;
68
69 let devices_dir = SysfsInode::new_directory(FileMode::from_bits_truncate(0o040000 | 0o555));
71 root.add_child("devices", devices_dir)?;
72
73 let block_symlink = SysfsInode::new_symlink("class/block".to_string());
75 root.add_child("block", block_symlink)?;
76
77 Ok(())
78 }
79
80 fn build_device_trees(&self) -> Result<(), FsError> {
81 use super::builders;
82
83 builders::devices::build_platform_devices(&self.root_inode)?;
85
86 builders::block::build_block_devices(&self.root_inode)?;
88 builders::net::build_net_devices(&self.root_inode)?;
89 builders::tty::build_tty_devices(&self.root_inode)?;
90 builders::input::build_input_devices(&self.root_inode)?;
91 builders::rtc::build_rtc_devices(&self.root_inode)?;
92
93 builders::kernel::build_kernel_info(&self.root_inode)?;
95
96 Ok(())
97 }
98}
99
100impl FileSystem for SysFS {
101 fn fs_type(&self) -> &'static str {
102 "sysfs"
103 }
104
105 fn root_inode(&self) -> Arc<dyn Inode> {
106 self.root_inode.clone()
107 }
108
109 fn sync(&self) -> Result<(), FsError> {
110 Ok(())
112 }
113
114 fn statfs(&self) -> Result<StatFs, FsError> {
115 Ok(StatFs {
116 block_size: 4096,
117 total_blocks: 0,
118 free_blocks: 0,
119 available_blocks: 0,
120 total_inodes: 0,
121 free_inodes: 0,
122 fsid: 0,
123 max_filename_len: 255,
124 })
125 }
126}