xref: /DragonOS/kernel/src/filesystem/kernfs/mod.rs (revision 06d5e247267cb65b84a80f219853ccd0f384b16e)
1 use core::{fmt::Debug, intrinsics::unlikely};
2 
3 use alloc::{
4     string::String,
5     sync::{Arc, Weak},
6     vec::Vec,
7 };
8 use hashbrown::HashMap;
9 
10 use crate::{
11     libs::{
12         casting::DowncastArc,
13         rwlock::RwLock,
14         spinlock::{SpinLock, SpinLockGuard},
15     },
16     syscall::SystemError,
17     time::TimeSpec,
18 };
19 
20 use self::callback::{KernCallbackData, KernFSCallback, KernInodePrivateData};
21 
22 use super::vfs::{
23     core::generate_inode_id, file::FileMode, syscall::ModeType, FilePrivateData, FileSystem,
24     FileType, FsInfo, IndexNode, InodeId, Metadata, PollStatus,
25 };
26 
27 pub mod callback;
28 
29 #[derive(Debug)]
30 pub struct KernFS {
31     root_inode: Arc<KernFSInode>,
32 }
33 
34 impl FileSystem for KernFS {
35     fn as_any_ref(&self) -> &dyn core::any::Any {
36         self
37     }
38 
39     fn info(&self) -> FsInfo {
40         return FsInfo {
41             blk_dev_id: 0,
42             max_name_len: KernFS::MAX_NAMELEN,
43         };
44     }
45 
46     fn root_inode(&self) -> Arc<dyn IndexNode> {
47         return self.root_inode.clone();
48     }
49 }
50 
51 impl KernFS {
52     pub const MAX_NAMELEN: usize = 4096;
53 
54     #[allow(dead_code)]
55     pub fn new() -> Arc<Self> {
56         let root_inode = Self::create_root_inode();
57         let fs = Arc::new(Self {
58             root_inode: root_inode.clone(),
59         });
60 
61         {
62             let ptr = root_inode.as_ref() as *const KernFSInode as *mut KernFSInode;
63             unsafe {
64                 (*ptr).self_ref = Arc::downgrade(&root_inode);
65             }
66         }
67         root_inode.inner.lock().parent = Arc::downgrade(&root_inode);
68         *root_inode.fs.write() = Arc::downgrade(&fs);
69         return fs;
70     }
71 
72     fn create_root_inode() -> Arc<KernFSInode> {
73         let metadata = Metadata {
74             size: 0,
75             mode: ModeType::from_bits_truncate(0o755),
76             uid: 0,
77             gid: 0,
78             blk_size: 0,
79             blocks: 0,
80             atime: TimeSpec::new(0, 0),
81             mtime: TimeSpec::new(0, 0),
82             ctime: TimeSpec::new(0, 0),
83             dev_id: 0,
84             inode_id: generate_inode_id(),
85             file_type: FileType::Dir,
86             nlinks: 1,
87             raw_dev: 0,
88         };
89         let root_inode = Arc::new(KernFSInode {
90             name: String::from(""),
91             inner: SpinLock::new(InnerKernFSInode {
92                 parent: Weak::new(),
93                 metadata,
94             }),
95             self_ref: Weak::new(),
96             fs: RwLock::new(Weak::new()),
97             private_data: SpinLock::new(None),
98             callback: None,
99             children: SpinLock::new(HashMap::new()),
100             inode_type: KernInodeType::Dir,
101         });
102 
103         return root_inode;
104     }
105 }
106 
107 #[derive(Debug)]
108 pub struct KernFSInode {
109     inner: SpinLock<InnerKernFSInode>,
110     /// 指向当前Inode所属的文件系统的弱引用
111     fs: RwLock<Weak<KernFS>>,
112     /// 指向自身的弱引用
113     self_ref: Weak<KernFSInode>,
114     /// 私有数据
115     private_data: SpinLock<Option<KernInodePrivateData>>,
116     /// 回调函数
117     callback: Option<&'static dyn KernFSCallback>,
118     /// 子Inode
119     children: SpinLock<HashMap<String, Arc<KernFSInode>>>,
120     /// Inode类型
121     inode_type: KernInodeType,
122     /// Inode名称
123     name: String,
124 }
125 
126 #[derive(Debug)]
127 pub struct InnerKernFSInode {
128     parent: Weak<KernFSInode>,
129 
130     /// 当前inode的元数据
131     metadata: Metadata,
132 }
133 
134 impl IndexNode for KernFSInode {
135     fn as_any_ref(&self) -> &dyn core::any::Any {
136         self
137     }
138 
139     fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> {
140         if let Some(callback) = self.callback {
141             let callback_data =
142                 KernCallbackData::new(self.self_ref.upgrade().unwrap(), self.private_data.lock());
143             return callback.open(callback_data);
144         }
145 
146         return Ok(());
147     }
148 
149     fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
150         return Ok(());
151     }
152 
153     fn metadata(&self) -> Result<Metadata, SystemError> {
154         return Ok(self.inner.lock().metadata.clone());
155     }
156 
157     fn set_metadata(&self, _metadata: &Metadata) -> Result<(), SystemError> {
158         // 若文件系统没有实现此方法,则返回“不支持”
159         return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
160     }
161 
162     fn resize(&self, _len: usize) -> Result<(), SystemError> {
163         return Ok(());
164     }
165 
166     fn create_with_data(
167         &self,
168         _name: &str,
169         _file_type: FileType,
170         _mode: ModeType,
171         _data: usize,
172     ) -> Result<Arc<dyn IndexNode>, SystemError> {
173         // 应当通过kernfs的其它方法来创建文件,而不能从用户态直接调用此方法。
174         return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
175     }
176 
177     fn link(&self, _name: &str, _other: &Arc<dyn IndexNode>) -> Result<(), SystemError> {
178         // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。
179         return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
180     }
181 
182     fn unlink(&self, _name: &str) -> Result<(), SystemError> {
183         // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。
184         return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
185     }
186 
187     fn rmdir(&self, _name: &str) -> Result<(), SystemError> {
188         // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。
189         return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
190     }
191 
192     fn move_(
193         &self,
194         _old_name: &str,
195         _target: &Arc<dyn IndexNode>,
196         _new_name: &str,
197     ) -> Result<(), SystemError> {
198         // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。
199         return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
200     }
201 
202     fn find(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError> {
203         if unlikely(name.len() > KernFS::MAX_NAMELEN) {
204             return Err(SystemError::ENAMETOOLONG);
205         }
206         if unlikely(self.inode_type != KernInodeType::Dir) {
207             return Err(SystemError::ENOTDIR);
208         }
209         match name {
210             "" | "." => {
211                 return Ok(self.self_ref.upgrade().ok_or(SystemError::ENOENT)?);
212             }
213 
214             ".." => {
215                 return Ok(self
216                     .inner
217                     .lock()
218                     .parent
219                     .upgrade()
220                     .ok_or(SystemError::ENOENT)?);
221             }
222             name => {
223                 // 在子目录项中查找
224                 return Ok(self
225                     .children
226                     .lock()
227                     .get(name)
228                     .ok_or(SystemError::ENOENT)?
229                     .clone());
230             }
231         }
232     }
233 
234     fn get_entry_name(&self, ino: InodeId) -> Result<String, SystemError> {
235         if self.inode_type != KernInodeType::Dir {
236             return Err(SystemError::ENOTDIR);
237         }
238 
239         let children = self.children.lock();
240         let r = children
241             .iter()
242             .find(|(_, v)| v.metadata().unwrap().inode_id == ino)
243             .map(|(k, _)| k.clone());
244 
245         return r.ok_or(SystemError::ENOENT);
246     }
247 
248     fn get_entry_name_and_metadata(&self, ino: InodeId) -> Result<(String, Metadata), SystemError> {
249         // 如果有条件,请在文件系统中使用高效的方式实现本接口,而不是依赖这个低效率的默认实现。
250         let name = self.get_entry_name(ino)?;
251         let entry = self.find(&name)?;
252         return Ok((name, entry.metadata()?));
253     }
254 
255     fn ioctl(&self, _cmd: u32, _data: usize) -> Result<usize, SystemError> {
256         // 若文件系统没有实现此方法,则返回“不支持”
257         return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
258     }
259 
260     fn truncate(&self, _len: usize) -> Result<(), SystemError> {
261         // 应当通过kernfs的其它方法来操作文件,而不能从用户态直接调用此方法。
262         return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
263     }
264 
265     fn sync(&self) -> Result<(), SystemError> {
266         return Ok(());
267     }
268 
269     fn fs(&self) -> Arc<dyn FileSystem> {
270         return self.fs.read().upgrade().unwrap();
271     }
272 
273     fn list(&self) -> Result<Vec<String>, SystemError> {
274         let info = self.metadata()?;
275         if info.file_type != FileType::Dir {
276             return Err(SystemError::ENOTDIR);
277         }
278 
279         let mut keys: Vec<String> = Vec::new();
280         keys.push(String::from("."));
281         keys.push(String::from(".."));
282         self.children
283             .lock()
284             .keys()
285             .into_iter()
286             .for_each(|x| keys.push(x.clone()));
287 
288         return Ok(keys);
289     }
290 
291     fn poll(&self) -> Result<PollStatus, SystemError> {
292         // todo: 根据inode的具体attribute,返回PollStatus
293         return Ok(PollStatus::READ | PollStatus::WRITE);
294     }
295 
296     fn read_at(
297         &self,
298         offset: usize,
299         len: usize,
300         buf: &mut [u8],
301         _data: &mut FilePrivateData,
302     ) -> Result<usize, SystemError> {
303         if self.inode_type != KernInodeType::File {
304             return Err(SystemError::EISDIR);
305         }
306 
307         if self.callback.is_none() {
308             kwarn!("kernfs: callback is none");
309             return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
310         }
311 
312         let callback_data =
313             KernCallbackData::new(self.self_ref.upgrade().unwrap(), self.private_data.lock());
314         return self
315             .callback
316             .as_ref()
317             .unwrap()
318             .read(callback_data, &mut buf[..len], offset);
319     }
320 
321     fn write_at(
322         &self,
323         offset: usize,
324         len: usize,
325         buf: &[u8],
326         _data: &mut FilePrivateData,
327     ) -> Result<usize, SystemError> {
328         if self.inode_type != KernInodeType::File {
329             return Err(SystemError::EISDIR);
330         }
331 
332         if self.callback.is_none() {
333             return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
334         }
335 
336         let callback_data =
337             KernCallbackData::new(self.self_ref.upgrade().unwrap(), self.private_data.lock());
338         return self
339             .callback
340             .as_ref()
341             .unwrap()
342             .write(callback_data, &buf[..len], offset);
343     }
344 }
345 
346 impl KernFSInode {
347     /// 在当前inode下增加子目录
348     ///
349     /// ## 参数
350     ///
351     /// - `name`:子目录名称
352     /// - `mode`:子目录权限
353     /// - `private_data`:子目录私有数据
354     /// - `callback`:子目录回调函数
355     ///
356     /// ## 返回值
357     ///
358     /// - 成功:子目录inode
359     /// - 失败:错误码
360     #[allow(dead_code)]
361     #[inline]
362     pub fn add_dir(
363         &self,
364         name: String,
365         mode: ModeType,
366         private_data: Option<KernInodePrivateData>,
367         callback: Option<&'static dyn KernFSCallback>,
368     ) -> Result<Arc<KernFSInode>, SystemError> {
369         if unlikely(self.inode_type != KernInodeType::Dir) {
370             return Err(SystemError::ENOTDIR);
371         }
372 
373         return self.inner_create(name, KernInodeType::Dir, mode, private_data, callback);
374     }
375 
376     /// 在当前inode下增加文件
377     ///
378     /// ## 参数
379     ///
380     /// - `name`:文件名称
381     /// - `mode`:文件权限
382     /// - `private_data`:文件私有数据
383     /// - `callback`:文件回调函数
384     ///
385     /// ## 返回值
386     ///
387     /// - 成功:文件inode
388     /// - 失败:错误码
389     #[allow(dead_code)]
390     #[inline]
391     pub fn add_file(
392         &self,
393         name: String,
394         mode: ModeType,
395         private_data: Option<KernInodePrivateData>,
396         callback: Option<&'static dyn KernFSCallback>,
397     ) -> Result<Arc<KernFSInode>, SystemError> {
398         if unlikely(self.inode_type != KernInodeType::Dir) {
399             return Err(SystemError::ENOTDIR);
400         }
401 
402         return self.inner_create(name, KernInodeType::File, mode, private_data, callback);
403     }
404 
405     fn inner_create(
406         &self,
407         name: String,
408         file_type: KernInodeType,
409         mode: ModeType,
410         private_data: Option<KernInodePrivateData>,
411         callback: Option<&'static dyn KernFSCallback>,
412     ) -> Result<Arc<KernFSInode>, SystemError> {
413         let size = if file_type == KernInodeType::File {
414             4096
415         } else {
416             0
417         };
418 
419         let metadata = Metadata {
420             size,
421             mode,
422             uid: 0,
423             gid: 0,
424             blk_size: 0,
425             blocks: 0,
426             atime: TimeSpec::new(0, 0),
427             mtime: TimeSpec::new(0, 0),
428             ctime: TimeSpec::new(0, 0),
429             dev_id: 0,
430             inode_id: generate_inode_id(),
431             file_type: file_type.into(),
432             nlinks: 1,
433             raw_dev: 0,
434         };
435 
436         let new_inode: Arc<KernFSInode> = Self::new(
437             Some(self.self_ref.upgrade().unwrap()),
438             name.clone(),
439             metadata,
440             file_type,
441             private_data,
442             callback,
443         );
444 
445         self.children.lock().insert(name, new_inode.clone());
446 
447         return Ok(new_inode);
448     }
449 
450     /// 在当前inode下删除子目录或者文件
451     ///
452     /// 如果要删除的是子目录,且子目录不为空,则返回ENOTEMPTY
453     ///
454     /// ## 参数
455     ///
456     /// - `name`:子目录或者文件名称
457     ///
458     /// ## 返回值
459     ///
460     /// - 成功:()
461     /// - 失败:错误码
462     #[allow(dead_code)]
463     pub fn remove(&self, name: &str) -> Result<(), SystemError> {
464         if unlikely(self.inode_type != KernInodeType::Dir) {
465             return Err(SystemError::ENOTDIR);
466         }
467 
468         let mut children = self.children.lock();
469         let inode = children.get(name).ok_or(SystemError::ENOENT)?;
470         if inode.children.lock().is_empty() {
471             children.remove(name);
472             return Ok(());
473         } else {
474             return Err(SystemError::ENOTEMPTY);
475         }
476     }
477 
478     pub fn new(
479         parent: Option<Arc<KernFSInode>>,
480         name: String,
481         mut metadata: Metadata,
482         inode_type: KernInodeType,
483         private_data: Option<KernInodePrivateData>,
484         callback: Option<&'static dyn KernFSCallback>,
485     ) -> Arc<KernFSInode> {
486         metadata.file_type = inode_type.into();
487         let parent: Weak<KernFSInode> = parent.map(|x| Arc::downgrade(&x)).unwrap_or_default();
488 
489         let inode = Arc::new(KernFSInode {
490             name,
491             inner: SpinLock::new(InnerKernFSInode {
492                 parent: parent.clone(),
493                 metadata,
494             }),
495             self_ref: Weak::new(),
496             fs: RwLock::new(Weak::new()),
497             private_data: SpinLock::new(private_data),
498             callback,
499             children: SpinLock::new(HashMap::new()),
500             inode_type,
501         });
502 
503         {
504             let ptr = inode.as_ref() as *const KernFSInode as *mut KernFSInode;
505             unsafe {
506                 (*ptr).self_ref = Arc::downgrade(&inode);
507             }
508         }
509         if parent.strong_count() > 0 {
510             let kernfs = parent
511                 .upgrade()
512                 .unwrap()
513                 .fs()
514                 .downcast_arc::<KernFS>()
515                 .expect("KernFSInode::new: parent is not a KernFS instance");
516             *inode.fs.write() = Arc::downgrade(&kernfs);
517         }
518         return inode;
519     }
520 
521     pub fn name(&self) -> &str {
522         return &self.name;
523     }
524 
525     pub fn parent(&self) -> Option<Arc<KernFSInode>> {
526         return self.inner.lock().parent.upgrade();
527     }
528 
529     pub fn private_data_mut(&self) -> SpinLockGuard<Option<KernInodePrivateData>> {
530         return self.private_data.lock();
531     }
532 
533     /// remove a kernfs_node recursively
534     pub fn remove_recursive(&self) {
535         let mut children = self.children.lock().drain().collect::<Vec<_>>();
536         while let Some((_, child)) = children.pop() {
537             children.append(&mut child.children.lock().drain().collect::<Vec<_>>());
538         }
539     }
540 
541     /// 删除当前的inode(包括其自身、子目录和子文件)
542     #[allow(dead_code)]
543     pub fn remove_inode_include_self(&self) {
544         let parent = self.parent();
545         if let Some(parent) = parent {
546             parent.children.lock().remove(self.name());
547         }
548         self.remove_recursive();
549     }
550 }
551 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
552 pub enum KernInodeType {
553     Dir,
554     File,
555 }
556 
557 impl Into<FileType> for KernInodeType {
558     fn into(self) -> FileType {
559         match self {
560             KernInodeType::Dir => FileType::Dir,
561             KernInodeType::File => FileType::File,
562         }
563     }
564 }
565