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