xref: /DragonOS/kernel/src/filesystem/devfs/null_dev.rs (revision 45b8371173b070028457f7ee64be33f68b4f9ada)
1 use crate::filesystem::vfs::file::FileMode;
2 use crate::filesystem::vfs::make_rawdev;
3 use crate::filesystem::vfs::{
4     core::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata, PollStatus,
5 };
6 use crate::{
7     include::bindings::bindings::{EINVAL, ENOTSUP},
8     libs::spinlock::SpinLock,
9     time::TimeSpec,
10 };
11 use alloc::{
12     string::String,
13     sync::{Arc, Weak},
14     vec::Vec,
15 };
16 // use uuid::{uuid, Uuid};
17 use super::{DevFS, DeviceINode};
18 
19 #[derive(Debug)]
20 pub struct NullInode {
21     /// uuid 暂时不知道有什么用(x
22     // uuid: Uuid,
23     /// 指向自身的弱引用
24     self_ref: Weak<LockedNullInode>,
25     /// 指向inode所在的文件系统对象的指针
26     fs: Weak<DevFS>,
27     /// INode 元数据
28     metadata: Metadata,
29 }
30 
31 #[derive(Debug)]
32 pub struct LockedNullInode(SpinLock<NullInode>);
33 
34 impl LockedNullInode {
35     pub fn new() -> Arc<Self> {
36         let inode = NullInode {
37             // uuid: Uuid::new_v5(),
38             self_ref: Weak::default(),
39             fs: Weak::default(),
40             metadata: Metadata {
41                 dev_id: 1,
42                 inode_id: generate_inode_id(),
43                 size: 0,
44                 blk_size: 0,
45                 blocks: 0,
46                 atime: TimeSpec::default(),
47                 mtime: TimeSpec::default(),
48                 ctime: TimeSpec::default(),
49                 file_type: FileType::CharDevice, // 文件夹,block设备,char设备
50                 mode: 0o666,
51                 nlinks: 1,
52                 uid: 0,
53                 gid: 0,
54                 raw_dev: make_rawdev(1, 3), // 这里用来作为device number
55             },
56         };
57 
58         let result = Arc::new(LockedNullInode(SpinLock::new(inode)));
59         result.0.lock().self_ref = Arc::downgrade(&result);
60 
61         return result;
62     }
63 }
64 
65 impl DeviceINode for LockedNullInode {
66     fn set_fs(&self, fs: Weak<DevFS>) {
67         self.0.lock().fs = fs;
68     }
69 }
70 
71 impl IndexNode for LockedNullInode {
72     fn as_any_ref(&self) -> &dyn core::any::Any {
73         self
74     }
75 
76     fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), i32> {
77         Err(-(ENOTSUP as i32))
78     }
79 
80     fn close(&self, _data: &mut FilePrivateData) -> Result<(), i32> {
81         Err(-(ENOTSUP as i32))
82     }
83 
84     fn metadata(&self) -> Result<Metadata, i32> {
85         return Ok(self.0.lock().metadata.clone());
86     }
87 
88     fn fs(&self) -> Arc<dyn FileSystem> {
89         return self.0.lock().fs.upgrade().unwrap();
90     }
91 
92     fn list(&self) -> Result<Vec<String>, i32> {
93         Err(-(ENOTSUP as i32))
94     }
95 
96     fn set_metadata(&self, metadata: &Metadata) -> Result<(), i32> {
97         let mut inode = self.0.lock();
98         inode.metadata.atime = metadata.atime;
99         inode.metadata.mtime = metadata.mtime;
100         inode.metadata.ctime = metadata.ctime;
101         inode.metadata.mode = metadata.mode;
102         inode.metadata.uid = metadata.uid;
103         inode.metadata.gid = metadata.gid;
104 
105         return Ok(());
106     }
107 
108     fn poll(&self) -> Result<PollStatus, i32> {
109         return Ok(PollStatus {
110             flags: PollStatus::READ_MASK | PollStatus::WRITE_MASK,
111         });
112     }
113 
114     /// 读设备 - 应该调用设备的函数读写,而不是通过文件系统读写
115     fn read_at(
116         &self,
117         _offset: usize,
118         len: usize,
119         buf: &mut [u8],
120         _data: &mut FilePrivateData,
121     ) -> Result<usize, i32> {
122         if buf.len() < len {
123             return Err(-(EINVAL as i32));
124         }
125 
126         for i in 0..len {
127             buf[i] = 0;
128         }
129 
130         return Ok(len);
131     }
132 
133     /// 写设备 - 应该调用设备的函数读写,而不是通过文件系统读写
134     fn write_at(
135         &self,
136         _offset: usize,
137         len: usize,
138         buf: &[u8],
139         _data: &mut FilePrivateData,
140     ) -> Result<usize, i32> {
141         if buf.len() < len {
142             return Err(-(EINVAL as i32));
143         }
144 
145         Ok(len)
146     }
147 }
148