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