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 return sysfs;
142 }
143 }
144
145 /// @brief sys文件i节点(锁)
146 #[derive(Debug)]
147 pub struct LockedSysFSInode(SpinLock<SysFSInode>);
148
149 impl IndexNode for LockedSysFSInode {
as_any_ref(&self) -> &dyn core::any::Any150 fn as_any_ref(&self) -> &dyn core::any::Any {
151 self
152 }
153
open( &self, _data: &mut super::vfs::FilePrivateData, _mode: &FileMode, ) -> Result<(), SystemError>154 fn open(
155 &self,
156 _data: &mut super::vfs::FilePrivateData,
157 _mode: &FileMode,
158 ) -> Result<(), SystemError> {
159 return Ok(());
160 }
161
close(&self, _data: &mut super::vfs::FilePrivateData) -> Result<(), SystemError>162 fn close(&self, _data: &mut super::vfs::FilePrivateData) -> Result<(), SystemError> {
163 return Ok(());
164 }
165
read_at( &self, _offset: usize, _len: usize, _buf: &mut [u8], _data: &mut super::vfs::FilePrivateData, ) -> Result<usize, SystemError>166 fn read_at(
167 &self,
168 _offset: usize,
169 _len: usize,
170 _buf: &mut [u8],
171 _data: &mut super::vfs::FilePrivateData,
172 ) -> Result<usize, SystemError> {
173 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
174 }
175
write_at( &self, _offset: usize, _len: usize, _buf: &[u8], _data: &mut super::vfs::FilePrivateData, ) -> Result<usize, SystemError>176 fn write_at(
177 &self,
178 _offset: usize,
179 _len: usize,
180 _buf: &[u8],
181 _data: &mut super::vfs::FilePrivateData,
182 ) -> Result<usize, SystemError> {
183 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
184 }
185
poll(&self) -> Result<super::vfs::PollStatus, SystemError>186 fn poll(&self) -> Result<super::vfs::PollStatus, SystemError> {
187 // 加锁
188 let inode: SpinLockGuard<SysFSInode> = self.0.lock();
189
190 // 检查当前inode是否为一个文件夹,如果是的话,就返回错误
191 if inode.metadata.file_type == FileType::Dir {
192 return Err(SystemError::EISDIR);
193 }
194
195 return Ok(PollStatus::READ | PollStatus::WRITE);
196 }
197
metadata(&self) -> Result<Metadata, SystemError>198 fn metadata(&self) -> Result<Metadata, SystemError> {
199 return Ok(self.0.lock().metadata.clone());
200 }
201
fs(&self) -> Arc<dyn FileSystem>202 fn fs(&self) -> Arc<dyn FileSystem> {
203 return self.0.lock().fs.upgrade().unwrap();
204 }
205
get_entry_name(&self, ino: super::vfs::InodeId) -> Result<String, SystemError>206 fn get_entry_name(&self, ino: super::vfs::InodeId) -> Result<String, SystemError> {
207 let inode: SpinLockGuard<SysFSInode> = self.0.lock();
208 if inode.metadata.file_type != FileType::Dir {
209 return Err(SystemError::ENOTDIR);
210 }
211
212 match ino {
213 0 => {
214 return Ok(String::from("."));
215 }
216 1 => {
217 return Ok(String::from(".."));
218 }
219 ino => {
220 // 暴力遍历所有的children,判断inode id是否相同
221 // TODO: 优化这里,这个地方性能很差!
222 let mut key: Vec<String> = inode
223 .children
224 .keys()
225 .filter(|k| inode.children.get(*k).unwrap().metadata().unwrap().inode_id == ino)
226 .cloned()
227 .collect();
228
229 match key.len() {
230 0=>{return Err(SystemError::ENOENT);}
231 1=>{return Ok(key.remove(0));}
232 _ => 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)
233 }
234 }
235 }
236 }
237
find(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError>238 fn find(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError> {
239 let inode = self.0.lock();
240
241 if inode.metadata.file_type != FileType::Dir {
242 return Err(SystemError::ENOTDIR);
243 }
244
245 match name {
246 "" | "." => {
247 return Ok(inode.self_ref.upgrade().ok_or(SystemError::ENOENT)?);
248 }
249 ".." => {
250 return Ok(inode.parent.upgrade().ok_or(SystemError::ENOENT)?);
251 }
252 name => {
253 // 在子目录项中查找
254 // match inode.children.get(name) {
255 // Some(_) => {}
256 // None => kdebug!("Sysfs find {} error", name),
257 // }
258 return Ok(inode.children.get(name).ok_or(SystemError::ENOENT)?.clone());
259 }
260 }
261 }
262
ioctl(&self, _cmd: u32, _data: usize) -> Result<usize, SystemError>263 fn ioctl(&self, _cmd: u32, _data: usize) -> Result<usize, SystemError> {
264 Err(SystemError::EOPNOTSUPP_OR_ENOTSUP)
265 }
266
list(&self) -> Result<Vec<String>, SystemError>267 fn list(&self) -> Result<Vec<String>, SystemError> {
268 let info = self.metadata()?;
269 if info.file_type != FileType::Dir {
270 return Err(SystemError::ENOTDIR);
271 }
272
273 let mut keys: Vec<String> = Vec::new();
274 keys.push(String::from("."));
275 keys.push(String::from(".."));
276 keys.append(&mut self.0.lock().children.keys().cloned().collect());
277
278 return Ok(keys);
279 }
280 }
281
282 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>283 fn do_create_with_data(
284 &self,
285 mut guard: SpinLockGuard<SysFSInode>,
286 _name: &str,
287 _file_type: FileType,
288 _mode: u32,
289 _data: usize,
290 ) -> Result<Arc<dyn IndexNode>, SystemError> {
291 if guard.metadata.file_type != FileType::Dir {
292 return Err(SystemError::ENOTDIR);
293 }
294
295 // 如果有重名的,则返回
296 if guard.children.contains_key(_name) {
297 return Err(SystemError::EEXIST);
298 }
299
300 // 创建inode
301 let result: Arc<LockedSysFSInode> = Arc::new(LockedSysFSInode(SpinLock::new(SysFSInode {
302 parent: guard.self_ref.clone(),
303 self_ref: Weak::default(),
304 children: BTreeMap::new(),
305 metadata: Metadata {
306 dev_id: 0,
307 inode_id: generate_inode_id(),
308 size: 0,
309 blk_size: 0,
310 blocks: 0,
311 atime: TimeSpec::default(),
312 mtime: TimeSpec::default(),
313 ctime: TimeSpec::default(),
314 file_type: _file_type,
315 mode: _mode,
316 nlinks: 1,
317 uid: 0,
318 gid: 0,
319 raw_dev: _data,
320 },
321 fs: guard.fs.clone(),
322 })));
323
324 // 初始化inode的自引用的weak指针
325 result.0.lock().self_ref = Arc::downgrade(&result);
326
327 // 将子inode插入父inode的B树中
328 guard.children.insert(String::from(_name), result.clone());
329 return Ok(result);
330 }
331
332 /// @brief 在当前目录下,创建一个目录
333 /// @param name: 目录名
334 /// @return 成功返回目录inode, 失败返回Err(错误码)
335 #[inline]
336 #[allow(dead_code)]
add_dir(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError>337 pub fn add_dir(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError> {
338 let guard: SpinLockGuard<SysFSInode> = self.0.lock();
339
340 if guard.children.contains_key(name) {
341 return Err(SystemError::EEXIST);
342 }
343
344 match self.do_create_with_data(guard, name, FileType::Dir, 0o755 as u32, 0) {
345 Ok(inode) => return Ok(inode),
346 Err(err) => {
347 return Err(err);
348 }
349 };
350 }
351
352 /// @brief 在当前目录下,创建一个二进制文件
353 /// @param name: 文件名
354 /// @return 成功返回Ok(()), 失败返回Err(错误码)
355 #[inline]
356 #[allow(dead_code)]
add_file(&self, name: &str, file: Arc<dyn IndexNode>) -> Result<(), SystemError>357 pub fn add_file(&self, name: &str, file: Arc<dyn IndexNode>) -> Result<(), SystemError> {
358 let mut this = self.0.lock();
359
360 if this.children.contains_key(name) {
361 return Err(SystemError::EEXIST);
362 }
363
364 this.children.insert(name.to_string(), file);
365 return Ok(());
366 }
367
368 /// @brief 为该inode创建硬链接
369 /// @param None
370 /// @return 当前inode强引用
371 #[inline]
372 #[allow(dead_code)]
link(&self) -> Arc<dyn IndexNode>373 pub fn link(&self) -> Arc<dyn IndexNode> {
374 return self
375 .0
376 .lock()
377 .self_ref
378 .clone()
379 .upgrade()
380 .ok_or(SystemError::E2BIG)
381 .unwrap();
382 }
383
remove(&self, name: &str) -> Result<(), SystemError>384 pub fn remove(&self, name: &str) -> Result<(), SystemError> {
385 let x = self
386 .0
387 .lock()
388 .children
389 .remove(name)
390 .ok_or(SystemError::ENOENT)?;
391
392 drop(x);
393 return Ok(());
394 }
395 }
396
397 /// @brief sys文件i节点(无锁)
398 #[derive(Debug)]
399 pub struct SysFSInode {
400 /// 指向父Inode的弱引用
401 parent: Weak<LockedSysFSInode>,
402 /// 指向自身的弱引用
403 self_ref: Weak<LockedSysFSInode>,
404 /// 子Inode的B树
405 children: BTreeMap<String, Arc<dyn IndexNode>>,
406 /// 指向inode所在的文件系统对象的指针
407 fs: Weak<SysFS>,
408 /// INode 元数据
409 metadata: Metadata,
410 }
411
412 impl SysFSInode {
new(dev_type_: FileType, mode_: u32, data_: usize) -> Self413 pub fn new(dev_type_: FileType, mode_: u32, data_: usize) -> Self {
414 return Self::new_with_parent(Weak::default(), dev_type_, mode_, data_);
415 }
416
new_with_parent( parent: Weak<LockedSysFSInode>, dev_type_: FileType, mode_: u32, data_: usize, ) -> Self417 pub fn new_with_parent(
418 parent: Weak<LockedSysFSInode>,
419 dev_type_: FileType,
420 mode_: u32,
421 data_: usize,
422 ) -> Self {
423 return SysFSInode {
424 parent: parent,
425 self_ref: Weak::default(),
426 children: BTreeMap::new(),
427 metadata: Metadata {
428 dev_id: 1,
429 inode_id: generate_inode_id(),
430 size: 0,
431 blk_size: 0,
432 blocks: 0,
433 atime: TimeSpec::default(),
434 mtime: TimeSpec::default(),
435 ctime: TimeSpec::default(),
436 file_type: dev_type_, // 文件夹
437 mode: mode_,
438 nlinks: 1,
439 uid: 0,
440 gid: 0,
441 raw_dev: data_,
442 },
443 fs: Weak::default(),
444 };
445 }
446 }
447