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