xref: /DragonOS/kernel/src/filesystem/sysfs/mod.rs (revision 7ae679ddd6481897a86523a52fad3b060254fa5b)
1 use super::vfs::{
2     core::generate_inode_id, file::FileMode, FileSystem, FileType, FsInfo, IndexNode, Metadata,
3     PollStatus,
4 };
5 use crate::{
6     driver::base::platform::platform_bus_init,
7     filesystem::{sysfs::bus::sys_bus_init, vfs::ROOT_INODE},
8     kdebug, kinfo,
9     libs::{
10         once::Once,
11         spinlock::{SpinLock, SpinLockGuard},
12     },
13     syscall::SystemError,
14     time::TimeSpec,
15 };
16 use alloc::{
17     boxed::Box,
18     collections::BTreeMap,
19     string::{String, ToString},
20     sync::{Arc, Weak},
21     vec::Vec,
22 };
23 use core::ptr::null_mut;
24 
25 pub mod bus;
26 pub mod class;
27 pub mod devices;
28 pub mod fs;
29 
30 const SYSFS_MAX_NAMELEN: usize = 64;
31 
32 static mut __SYS_DEVICES_INODE: *mut Arc<dyn IndexNode> = null_mut();
33 static mut __SYS_BUS_INODE: *mut Arc<dyn IndexNode> = null_mut();
34 static mut __SYS_CLASS_INODE: *mut Arc<dyn IndexNode> = null_mut();
35 static mut __SYS_FS_INODE: *mut Arc<dyn IndexNode> = null_mut();
36 
37 /// @brief 获取全局的sys/devices节点
38 #[inline(always)]
39 #[allow(non_snake_case)]
40 pub fn SYS_DEVICES_INODE() -> Arc<dyn IndexNode> {
41     unsafe {
42         return __SYS_DEVICES_INODE.as_ref().unwrap().clone();
43     }
44 }
45 
46 /// @brief 获取全局的sys/bus节点
47 #[inline(always)]
48 #[allow(non_snake_case)]
49 pub fn SYS_BUS_INODE() -> Arc<dyn IndexNode> {
50     unsafe {
51         return __SYS_BUS_INODE.as_ref().unwrap().clone();
52     }
53 }
54 
55 /// @brief 获取全局的sys/class节点
56 #[inline(always)]
57 #[allow(non_snake_case)]
58 pub fn SYS_CLASS_INODE() -> Arc<dyn IndexNode> {
59     unsafe {
60         return __SYS_CLASS_INODE.as_ref().unwrap().clone();
61     }
62 }
63 
64 /// @brief 获取全局的sys/fs节点
65 #[inline(always)]
66 #[allow(non_snake_case)]
67 pub fn SYS_FS_INODE() -> Arc<dyn IndexNode> {
68     unsafe {
69         return __SYS_FS_INODE.as_ref().unwrap().clone();
70     }
71 }
72 
73 /// @brief dev文件系统
74 #[derive(Debug)]
75 pub struct SysFS {
76     // 文件系统根节点
77     root_inode: Arc<LockedSysFSInode>,
78 }
79 
80 impl FileSystem for SysFS {
81     fn as_any_ref(&self) -> &dyn core::any::Any {
82         self
83     }
84 
85     fn root_inode(&self) -> Arc<dyn super::vfs::IndexNode> {
86         return self.root_inode.clone();
87     }
88 
89     fn info(&self) -> super::vfs::FsInfo {
90         return FsInfo {
91             blk_dev_id: 0,
92             max_name_len: SYSFS_MAX_NAMELEN,
93         };
94     }
95 }
96 
97 impl SysFS {
98     pub fn new() -> Arc<Self> {
99         // 初始化root inode
100         let root: Arc<LockedSysFSInode> = Arc::new(LockedSysFSInode(SpinLock::new(
101             // /sys 的权限设置为 读+执行,root 可以读写
102             // root 的 parent 是空指针
103             SysFSInode::new(FileType::Dir, 0o755 as u32, 0),
104         )));
105 
106         let sysfs: Arc<SysFS> = Arc::new(SysFS { root_inode: root });
107 
108         // 对root inode加锁,并继续完成初始化工作
109         let mut root_guard: SpinLockGuard<SysFSInode> = sysfs.root_inode.0.lock();
110         root_guard.parent = Arc::downgrade(&sysfs.root_inode);
111         root_guard.self_ref = Arc::downgrade(&sysfs.root_inode);
112         root_guard.fs = Arc::downgrade(&sysfs);
113         // 释放锁
114         drop(root_guard);
115 
116         // 创建文件夹
117         let root: &Arc<LockedSysFSInode> = &sysfs.root_inode;
118         match root.add_dir("devices") {
119             Ok(devices) => unsafe {
120                 __SYS_DEVICES_INODE = Box::leak(Box::new(devices));
121             },
122             Err(_) => panic!("SysFS: Failed to create /sys/devices"),
123         }
124 
125         match root.add_dir("bus") {
126             Ok(bus) => unsafe {
127                 __SYS_BUS_INODE = Box::leak(Box::new(bus));
128             },
129             Err(_) => panic!("SysFS: Failed to create /sys/bus"),
130         }
131 
132         match root.add_dir("class") {
133             Ok(class) => unsafe {
134                 __SYS_CLASS_INODE = Box::leak(Box::new(class));
135             },
136             Err(_) => panic!("SysFS: Failed to create /sys/class"),
137         }
138 
139         match root.add_dir("fs") {
140             Ok(fs) => unsafe {
141                 __SYS_FS_INODE = Box::leak(Box::new(fs));
142             },
143             Err(_) => panic!("SysFS: Failed to create /sys/fs"),
144         }
145 
146         return sysfs;
147     }
148 }
149 
150 /// @brief sys文件i节点(锁)
151 #[derive(Debug)]
152 pub struct LockedSysFSInode(SpinLock<SysFSInode>);
153 
154 impl IndexNode for LockedSysFSInode {
155     fn as_any_ref(&self) -> &dyn core::any::Any {
156         self
157     }
158 
159     fn open(
160         &self,
161         _data: &mut super::vfs::FilePrivateData,
162         _mode: &FileMode,
163     ) -> Result<(), SystemError> {
164         return Ok(());
165     }
166 
167     fn close(&self, _data: &mut super::vfs::FilePrivateData) -> Result<(), SystemError> {
168         return Ok(());
169     }
170 
171     fn read_at(
172         &self,
173         _offset: usize,
174         _len: usize,
175         _buf: &mut [u8],
176         _data: &mut super::vfs::FilePrivateData,
177     ) -> Result<usize, SystemError> {
178         return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
179     }
180 
181     fn write_at(
182         &self,
183         _offset: usize,
184         _len: usize,
185         _buf: &[u8],
186         _data: &mut super::vfs::FilePrivateData,
187     ) -> Result<usize, SystemError> {
188         return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
189     }
190 
191     fn poll(&self) -> Result<super::vfs::PollStatus, SystemError> {
192         // 加锁
193         let inode: SpinLockGuard<SysFSInode> = self.0.lock();
194 
195         // 检查当前inode是否为一个文件夹,如果是的话,就返回错误
196         if inode.metadata.file_type == FileType::Dir {
197             return Err(SystemError::EISDIR);
198         }
199 
200         return Ok(PollStatus::READ | PollStatus::WRITE);
201     }
202 
203     fn metadata(&self) -> Result<Metadata, SystemError> {
204         return Ok(self.0.lock().metadata.clone());
205     }
206 
207     fn fs(&self) -> Arc<dyn FileSystem> {
208         return self.0.lock().fs.upgrade().unwrap();
209     }
210 
211     fn get_entry_name(&self, ino: super::vfs::InodeId) -> Result<String, SystemError> {
212         let inode: SpinLockGuard<SysFSInode> = self.0.lock();
213         if inode.metadata.file_type != FileType::Dir {
214             return Err(SystemError::ENOTDIR);
215         }
216 
217         match ino {
218             0 => {
219                 return Ok(String::from("."));
220             }
221             1 => {
222                 return Ok(String::from(".."));
223             }
224             ino => {
225                 // 暴力遍历所有的children,判断inode id是否相同
226                 // TODO: 优化这里,这个地方性能很差!
227                 let mut key: Vec<String> = inode
228                     .children
229                     .keys()
230                     .filter(|k| inode.children.get(*k).unwrap().metadata().unwrap().inode_id == ino)
231                     .cloned()
232                     .collect();
233 
234                 match key.len() {
235                     0=>{return Err(SystemError::ENOENT);}
236                     1=>{return Ok(key.remove(0));}
237                     _ => panic!("Sysfs 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)
238                 }
239             }
240         }
241     }
242 
243     fn find(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError> {
244         let inode = self.0.lock();
245 
246         if inode.metadata.file_type != FileType::Dir {
247             return Err(SystemError::ENOTDIR);
248         }
249 
250         match name {
251             "" | "." => {
252                 return Ok(inode.self_ref.upgrade().ok_or(SystemError::ENOENT)?);
253             }
254             ".." => {
255                 return Ok(inode.parent.upgrade().ok_or(SystemError::ENOENT)?);
256             }
257             name => {
258                 // 在子目录项中查找
259                 // match inode.children.get(name) {
260                 //     Some(_) => {}
261                 //     None => kdebug!("Sysfs find {} error", name),
262                 // }
263                 return Ok(inode.children.get(name).ok_or(SystemError::ENOENT)?.clone());
264             }
265         }
266     }
267 
268     fn ioctl(&self, _cmd: u32, _data: usize) -> Result<usize, SystemError> {
269         Err(SystemError::EOPNOTSUPP_OR_ENOTSUP)
270     }
271 
272     fn list(&self) -> Result<Vec<String>, SystemError> {
273         let info = self.metadata()?;
274         if info.file_type != FileType::Dir {
275             return Err(SystemError::ENOTDIR);
276         }
277 
278         let mut keys: Vec<String> = Vec::new();
279         keys.push(String::from("."));
280         keys.push(String::from(".."));
281         keys.append(&mut self.0.lock().children.keys().cloned().collect());
282 
283         return Ok(keys);
284     }
285 }
286 
287 impl LockedSysFSInode {
288     fn do_create_with_data(
289         &self,
290         mut guard: SpinLockGuard<SysFSInode>,
291         _name: &str,
292         _file_type: FileType,
293         _mode: u32,
294         _data: usize,
295     ) -> Result<Arc<dyn IndexNode>, SystemError> {
296         if guard.metadata.file_type != FileType::Dir {
297             return Err(SystemError::ENOTDIR);
298         }
299 
300         // 如果有重名的,则返回
301         if guard.children.contains_key(_name) {
302             return Err(SystemError::EEXIST);
303         }
304 
305         // 创建inode
306         let result: Arc<LockedSysFSInode> = Arc::new(LockedSysFSInode(SpinLock::new(SysFSInode {
307             parent: guard.self_ref.clone(),
308             self_ref: Weak::default(),
309             children: BTreeMap::new(),
310             metadata: Metadata {
311                 dev_id: 0,
312                 inode_id: generate_inode_id(),
313                 size: 0,
314                 blk_size: 0,
315                 blocks: 0,
316                 atime: TimeSpec::default(),
317                 mtime: TimeSpec::default(),
318                 ctime: TimeSpec::default(),
319                 file_type: _file_type,
320                 mode: _mode,
321                 nlinks: 1,
322                 uid: 0,
323                 gid: 0,
324                 raw_dev: _data,
325             },
326             fs: guard.fs.clone(),
327         })));
328 
329         // 初始化inode的自引用的weak指针
330         result.0.lock().self_ref = Arc::downgrade(&result);
331 
332         // 将子inode插入父inode的B树中
333         guard.children.insert(String::from(_name), result.clone());
334         return Ok(result);
335     }
336 
337     /// @brief 在当前目录下,创建一个目录
338     /// @param name: 目录名
339     /// @return 成功返回目录inode, 失败返回Err(错误码)
340     #[inline]
341     #[allow(dead_code)]
342     pub fn add_dir(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError> {
343         let guard: SpinLockGuard<SysFSInode> = self.0.lock();
344 
345         if guard.children.contains_key(name) {
346             return Err(SystemError::EEXIST);
347         }
348 
349         match self.do_create_with_data(guard, name, FileType::Dir, 0o755 as u32, 0) {
350             Ok(inode) => return Ok(inode),
351             Err(err) => {
352                 return Err(err);
353             }
354         };
355     }
356 
357     /// @brief 在当前目录下,创建一个二进制文件
358     /// @param name: 文件名
359     /// @return 成功返回Ok(()), 失败返回Err(错误码)
360     #[inline]
361     #[allow(dead_code)]
362     pub fn add_file(&self, name: &str, file: Arc<dyn IndexNode>) -> Result<(), SystemError> {
363         let mut this = self.0.lock();
364 
365         if this.children.contains_key(name) {
366             return Err(SystemError::EEXIST);
367         }
368 
369         this.children.insert(name.to_string(), file);
370         return Ok(());
371     }
372 
373     /// @brief 为该inode创建硬链接
374     /// @param None
375     /// @return 当前inode强引用
376     #[inline]
377     #[allow(dead_code)]
378     pub fn link(&self) -> Arc<dyn IndexNode> {
379         return self
380             .0
381             .lock()
382             .self_ref
383             .clone()
384             .upgrade()
385             .ok_or(SystemError::E2BIG)
386             .unwrap();
387     }
388 
389     pub fn remove(&self, name: &str) -> Result<(), SystemError> {
390         let x = self
391             .0
392             .lock()
393             .children
394             .remove(name)
395             .ok_or(SystemError::ENOENT)?;
396 
397         drop(x);
398         return Ok(());
399     }
400 }
401 
402 /// @brief sys文件i节点(无锁)
403 #[derive(Debug)]
404 pub struct SysFSInode {
405     /// 指向父Inode的弱引用
406     parent: Weak<LockedSysFSInode>,
407     /// 指向自身的弱引用
408     self_ref: Weak<LockedSysFSInode>,
409     /// 子Inode的B树
410     children: BTreeMap<String, Arc<dyn IndexNode>>,
411     /// 指向inode所在的文件系统对象的指针
412     fs: Weak<SysFS>,
413     /// INode 元数据
414     metadata: Metadata,
415 }
416 
417 impl SysFSInode {
418     pub fn new(dev_type_: FileType, mode_: u32, data_: usize) -> Self {
419         return Self::new_with_parent(Weak::default(), dev_type_, mode_, data_);
420     }
421 
422     pub fn new_with_parent(
423         parent: Weak<LockedSysFSInode>,
424         dev_type_: FileType,
425         mode_: u32,
426         data_: usize,
427     ) -> Self {
428         return SysFSInode {
429             parent: parent,
430             self_ref: Weak::default(),
431             children: BTreeMap::new(),
432             metadata: Metadata {
433                 dev_id: 1,
434                 inode_id: generate_inode_id(),
435                 size: 0,
436                 blk_size: 0,
437                 blocks: 0,
438                 atime: TimeSpec::default(),
439                 mtime: TimeSpec::default(),
440                 ctime: TimeSpec::default(),
441                 file_type: dev_type_, // 文件夹
442                 mode: mode_,
443                 nlinks: 1,
444                 uid: 0,
445                 gid: 0,
446                 raw_dev: data_,
447             },
448             fs: Weak::default(),
449         };
450     }
451 }
452 
453 pub fn sysfs_init() -> Result<(), SystemError> {
454     static INIT: Once = Once::new();
455     let mut result = None;
456     INIT.call_once(|| {
457         kinfo!("Initializing SysFS...");
458         // 创建 sysfs 实例
459         let sysfs: Arc<SysFS> = SysFS::new();
460 
461         // sysfs 挂载
462         let _t = ROOT_INODE()
463             .find("sys")
464             .expect("Cannot find /sys")
465             .mount(sysfs)
466             .expect("Failed to mount sysfs");
467         kinfo!("SysFS mounted.");
468 
469         // 初始化platform总线
470         platform_bus_init().expect("platform bus init failed");
471 
472         sys_bus_init(&SYS_BUS_INODE()).unwrap_or_else(|err| {
473             panic!("sys_bus_init failed: {:?}", err);
474         });
475 
476         kdebug!("sys_bus_init result: {:?}", SYS_BUS_INODE().list());
477         result = Some(Ok(()));
478     });
479 
480     return result.unwrap();
481 }
482