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