xref: /DragonOS/kernel/src/filesystem/devpts/mod.rs (revision dfe53cf087ef4c7b6db63d992906b062dc63e93f)
1*dfe53cf0SGnoCiYeH use core::sync::atomic::{AtomicU32, Ordering};
2*dfe53cf0SGnoCiYeH 
3*dfe53cf0SGnoCiYeH use alloc::{
4*dfe53cf0SGnoCiYeH     collections::BTreeMap,
5*dfe53cf0SGnoCiYeH     string::{String, ToString},
6*dfe53cf0SGnoCiYeH     sync::{Arc, Weak},
7*dfe53cf0SGnoCiYeH     vec::Vec,
8*dfe53cf0SGnoCiYeH };
9*dfe53cf0SGnoCiYeH use ida::IdAllocator;
10*dfe53cf0SGnoCiYeH use system_error::SystemError;
11*dfe53cf0SGnoCiYeH use unified_init::macros::unified_init;
12*dfe53cf0SGnoCiYeH 
13*dfe53cf0SGnoCiYeH use crate::{
14*dfe53cf0SGnoCiYeH     driver::{
15*dfe53cf0SGnoCiYeH         base::device::{
16*dfe53cf0SGnoCiYeH             device_number::{DeviceNumber, Major},
17*dfe53cf0SGnoCiYeH             IdTable,
18*dfe53cf0SGnoCiYeH         },
19*dfe53cf0SGnoCiYeH         tty::{
20*dfe53cf0SGnoCiYeH             pty::unix98pty::NR_UNIX98_PTY_MAX,
21*dfe53cf0SGnoCiYeH             tty_device::{PtyType, TtyDevice, TtyType},
22*dfe53cf0SGnoCiYeH         },
23*dfe53cf0SGnoCiYeH     },
24*dfe53cf0SGnoCiYeH     filesystem::vfs::{syscall::ModeType, FileType, ROOT_INODE},
25*dfe53cf0SGnoCiYeH     init::initcall::INITCALL_FS,
26*dfe53cf0SGnoCiYeH     libs::spinlock::{SpinLock, SpinLockGuard},
27*dfe53cf0SGnoCiYeH     time::TimeSpec,
28*dfe53cf0SGnoCiYeH };
29*dfe53cf0SGnoCiYeH 
30*dfe53cf0SGnoCiYeH use super::vfs::{
31*dfe53cf0SGnoCiYeH     core::generate_inode_id, FilePrivateData, FileSystem, FsInfo, IndexNode, Metadata,
32*dfe53cf0SGnoCiYeH };
33*dfe53cf0SGnoCiYeH 
34*dfe53cf0SGnoCiYeH const DEV_PTYFS_MAX_NAMELEN: usize = 16;
35*dfe53cf0SGnoCiYeH 
36*dfe53cf0SGnoCiYeH #[allow(dead_code)]
37*dfe53cf0SGnoCiYeH const PTY_NR_LIMIT: usize = 4096;
38*dfe53cf0SGnoCiYeH 
39*dfe53cf0SGnoCiYeH #[derive(Debug)]
40*dfe53cf0SGnoCiYeH pub struct DevPtsFs {
41*dfe53cf0SGnoCiYeH     /// 根节点
42*dfe53cf0SGnoCiYeH     root_inode: Arc<LockedDevPtsFSInode>,
43*dfe53cf0SGnoCiYeH     pts_ida: IdAllocator,
44*dfe53cf0SGnoCiYeH     pts_count: AtomicU32,
45*dfe53cf0SGnoCiYeH }
46*dfe53cf0SGnoCiYeH 
47*dfe53cf0SGnoCiYeH impl DevPtsFs {
48*dfe53cf0SGnoCiYeH     pub fn new() -> Arc<Self> {
49*dfe53cf0SGnoCiYeH         let root_inode = Arc::new(LockedDevPtsFSInode::new());
50*dfe53cf0SGnoCiYeH         let ret = Arc::new(Self {
51*dfe53cf0SGnoCiYeH             root_inode,
52*dfe53cf0SGnoCiYeH             pts_ida: IdAllocator::new(1, NR_UNIX98_PTY_MAX as usize),
53*dfe53cf0SGnoCiYeH             pts_count: AtomicU32::new(0),
54*dfe53cf0SGnoCiYeH         });
55*dfe53cf0SGnoCiYeH 
56*dfe53cf0SGnoCiYeH         ret.root_inode.set_fs(Arc::downgrade(&ret));
57*dfe53cf0SGnoCiYeH 
58*dfe53cf0SGnoCiYeH         ret
59*dfe53cf0SGnoCiYeH     }
60*dfe53cf0SGnoCiYeH 
61*dfe53cf0SGnoCiYeH     pub fn alloc_index(&self) -> Result<usize, SystemError> {
62*dfe53cf0SGnoCiYeH         self.pts_ida.alloc().ok_or(SystemError::ENOSPC)
63*dfe53cf0SGnoCiYeH     }
64*dfe53cf0SGnoCiYeH }
65*dfe53cf0SGnoCiYeH 
66*dfe53cf0SGnoCiYeH impl FileSystem for DevPtsFs {
67*dfe53cf0SGnoCiYeH     fn root_inode(&self) -> Arc<dyn IndexNode> {
68*dfe53cf0SGnoCiYeH         self.root_inode.clone()
69*dfe53cf0SGnoCiYeH     }
70*dfe53cf0SGnoCiYeH 
71*dfe53cf0SGnoCiYeH     fn info(&self) -> super::vfs::FsInfo {
72*dfe53cf0SGnoCiYeH         return FsInfo {
73*dfe53cf0SGnoCiYeH             blk_dev_id: 0,
74*dfe53cf0SGnoCiYeH             max_name_len: DEV_PTYFS_MAX_NAMELEN,
75*dfe53cf0SGnoCiYeH         };
76*dfe53cf0SGnoCiYeH     }
77*dfe53cf0SGnoCiYeH 
78*dfe53cf0SGnoCiYeH     fn as_any_ref(&self) -> &dyn core::any::Any {
79*dfe53cf0SGnoCiYeH         self
80*dfe53cf0SGnoCiYeH     }
81*dfe53cf0SGnoCiYeH 
82*dfe53cf0SGnoCiYeH     fn name(&self) -> &str {
83*dfe53cf0SGnoCiYeH         "devpts"
84*dfe53cf0SGnoCiYeH     }
85*dfe53cf0SGnoCiYeH 
86*dfe53cf0SGnoCiYeH     fn super_block(&self) -> super::vfs::SuperBlock {
87*dfe53cf0SGnoCiYeH         todo!()
88*dfe53cf0SGnoCiYeH     }
89*dfe53cf0SGnoCiYeH }
90*dfe53cf0SGnoCiYeH 
91*dfe53cf0SGnoCiYeH #[derive(Debug)]
92*dfe53cf0SGnoCiYeH pub struct LockedDevPtsFSInode {
93*dfe53cf0SGnoCiYeH     inner: SpinLock<PtsDevInode>,
94*dfe53cf0SGnoCiYeH }
95*dfe53cf0SGnoCiYeH 
96*dfe53cf0SGnoCiYeH impl LockedDevPtsFSInode {
97*dfe53cf0SGnoCiYeH     pub fn new() -> Self {
98*dfe53cf0SGnoCiYeH         Self {
99*dfe53cf0SGnoCiYeH             inner: SpinLock::new(PtsDevInode {
100*dfe53cf0SGnoCiYeH                 fs: Weak::new(),
101*dfe53cf0SGnoCiYeH                 children: Some(BTreeMap::new()),
102*dfe53cf0SGnoCiYeH                 metadata: Metadata {
103*dfe53cf0SGnoCiYeH                     dev_id: 0,
104*dfe53cf0SGnoCiYeH                     inode_id: generate_inode_id(),
105*dfe53cf0SGnoCiYeH                     size: 0,
106*dfe53cf0SGnoCiYeH                     blk_size: 0,
107*dfe53cf0SGnoCiYeH                     blocks: 0,
108*dfe53cf0SGnoCiYeH                     atime: TimeSpec::default(),
109*dfe53cf0SGnoCiYeH                     mtime: TimeSpec::default(),
110*dfe53cf0SGnoCiYeH                     ctime: TimeSpec::default(),
111*dfe53cf0SGnoCiYeH                     file_type: FileType::Dir,
112*dfe53cf0SGnoCiYeH                     mode: ModeType::from_bits_truncate(0x777),
113*dfe53cf0SGnoCiYeH                     nlinks: 1,
114*dfe53cf0SGnoCiYeH                     uid: 0,
115*dfe53cf0SGnoCiYeH                     gid: 0,
116*dfe53cf0SGnoCiYeH                     raw_dev: DeviceNumber::default(),
117*dfe53cf0SGnoCiYeH                 },
118*dfe53cf0SGnoCiYeH             }),
119*dfe53cf0SGnoCiYeH         }
120*dfe53cf0SGnoCiYeH     }
121*dfe53cf0SGnoCiYeH 
122*dfe53cf0SGnoCiYeH     pub fn set_fs(&self, fs: Weak<DevPtsFs>) {
123*dfe53cf0SGnoCiYeH         self.inner.lock().fs = fs;
124*dfe53cf0SGnoCiYeH     }
125*dfe53cf0SGnoCiYeH }
126*dfe53cf0SGnoCiYeH 
127*dfe53cf0SGnoCiYeH #[derive(Debug)]
128*dfe53cf0SGnoCiYeH pub struct PtsDevInode {
129*dfe53cf0SGnoCiYeH     fs: Weak<DevPtsFs>,
130*dfe53cf0SGnoCiYeH     children: Option<BTreeMap<String, Arc<TtyDevice>>>,
131*dfe53cf0SGnoCiYeH     metadata: Metadata,
132*dfe53cf0SGnoCiYeH }
133*dfe53cf0SGnoCiYeH 
134*dfe53cf0SGnoCiYeH impl PtsDevInode {
135*dfe53cf0SGnoCiYeH     pub fn children_unchecked(&self) -> &BTreeMap<String, Arc<TtyDevice>> {
136*dfe53cf0SGnoCiYeH         self.children.as_ref().unwrap()
137*dfe53cf0SGnoCiYeH     }
138*dfe53cf0SGnoCiYeH 
139*dfe53cf0SGnoCiYeH     pub fn children_unchecked_mut(&mut self) -> &mut BTreeMap<String, Arc<TtyDevice>> {
140*dfe53cf0SGnoCiYeH         self.children.as_mut().unwrap()
141*dfe53cf0SGnoCiYeH     }
142*dfe53cf0SGnoCiYeH }
143*dfe53cf0SGnoCiYeH 
144*dfe53cf0SGnoCiYeH impl IndexNode for LockedDevPtsFSInode {
145*dfe53cf0SGnoCiYeH     fn open(
146*dfe53cf0SGnoCiYeH         &self,
147*dfe53cf0SGnoCiYeH         _data: SpinLockGuard<FilePrivateData>,
148*dfe53cf0SGnoCiYeH         _mode: &super::vfs::file::FileMode,
149*dfe53cf0SGnoCiYeH     ) -> Result<(), SystemError> {
150*dfe53cf0SGnoCiYeH         Ok(())
151*dfe53cf0SGnoCiYeH     }
152*dfe53cf0SGnoCiYeH 
153*dfe53cf0SGnoCiYeH     fn metadata(&self) -> Result<super::vfs::Metadata, SystemError> {
154*dfe53cf0SGnoCiYeH         let inode = self.inner.lock();
155*dfe53cf0SGnoCiYeH         let metadata = inode.metadata.clone();
156*dfe53cf0SGnoCiYeH 
157*dfe53cf0SGnoCiYeH         return Ok(metadata);
158*dfe53cf0SGnoCiYeH     }
159*dfe53cf0SGnoCiYeH 
160*dfe53cf0SGnoCiYeH     fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
161*dfe53cf0SGnoCiYeH         // TODO: 回收
162*dfe53cf0SGnoCiYeH         Ok(())
163*dfe53cf0SGnoCiYeH     }
164*dfe53cf0SGnoCiYeH 
165*dfe53cf0SGnoCiYeH     fn read_at(
166*dfe53cf0SGnoCiYeH         &self,
167*dfe53cf0SGnoCiYeH         _offset: usize,
168*dfe53cf0SGnoCiYeH         _len: usize,
169*dfe53cf0SGnoCiYeH         _buf: &mut [u8],
170*dfe53cf0SGnoCiYeH         _data: SpinLockGuard<FilePrivateData>,
171*dfe53cf0SGnoCiYeH     ) -> Result<usize, system_error::SystemError> {
172*dfe53cf0SGnoCiYeH         todo!()
173*dfe53cf0SGnoCiYeH     }
174*dfe53cf0SGnoCiYeH 
175*dfe53cf0SGnoCiYeH     fn write_at(
176*dfe53cf0SGnoCiYeH         &self,
177*dfe53cf0SGnoCiYeH         _offset: usize,
178*dfe53cf0SGnoCiYeH         _len: usize,
179*dfe53cf0SGnoCiYeH         _buf: &[u8],
180*dfe53cf0SGnoCiYeH         _data: SpinLockGuard<FilePrivateData>,
181*dfe53cf0SGnoCiYeH     ) -> Result<usize, system_error::SystemError> {
182*dfe53cf0SGnoCiYeH         todo!()
183*dfe53cf0SGnoCiYeH     }
184*dfe53cf0SGnoCiYeH 
185*dfe53cf0SGnoCiYeH     fn fs(&self) -> alloc::sync::Arc<dyn super::vfs::FileSystem> {
186*dfe53cf0SGnoCiYeH         self.inner.lock().fs.upgrade().unwrap()
187*dfe53cf0SGnoCiYeH     }
188*dfe53cf0SGnoCiYeH 
189*dfe53cf0SGnoCiYeH     fn as_any_ref(&self) -> &dyn core::any::Any {
190*dfe53cf0SGnoCiYeH         todo!()
191*dfe53cf0SGnoCiYeH     }
192*dfe53cf0SGnoCiYeH 
193*dfe53cf0SGnoCiYeH     fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, system_error::SystemError> {
194*dfe53cf0SGnoCiYeH         let info = self.metadata()?;
195*dfe53cf0SGnoCiYeH         if info.file_type != FileType::Dir {
196*dfe53cf0SGnoCiYeH             return Err(SystemError::ENOTDIR);
197*dfe53cf0SGnoCiYeH         }
198*dfe53cf0SGnoCiYeH 
199*dfe53cf0SGnoCiYeH         let mut keys: Vec<String> = Vec::new();
200*dfe53cf0SGnoCiYeH         keys.push(String::from("."));
201*dfe53cf0SGnoCiYeH         keys.push(String::from(".."));
202*dfe53cf0SGnoCiYeH         keys.append(
203*dfe53cf0SGnoCiYeH             &mut self
204*dfe53cf0SGnoCiYeH                 .inner
205*dfe53cf0SGnoCiYeH                 .lock()
206*dfe53cf0SGnoCiYeH                 .children_unchecked()
207*dfe53cf0SGnoCiYeH                 .keys()
208*dfe53cf0SGnoCiYeH                 .cloned()
209*dfe53cf0SGnoCiYeH                 .collect(),
210*dfe53cf0SGnoCiYeH         );
211*dfe53cf0SGnoCiYeH 
212*dfe53cf0SGnoCiYeH         return Ok(keys);
213*dfe53cf0SGnoCiYeH     }
214*dfe53cf0SGnoCiYeH 
215*dfe53cf0SGnoCiYeH     fn create_with_data(
216*dfe53cf0SGnoCiYeH         &self,
217*dfe53cf0SGnoCiYeH         name: &str,
218*dfe53cf0SGnoCiYeH         file_type: FileType,
219*dfe53cf0SGnoCiYeH         _mode: super::vfs::syscall::ModeType,
220*dfe53cf0SGnoCiYeH         _data: usize,
221*dfe53cf0SGnoCiYeH     ) -> Result<Arc<dyn IndexNode>, SystemError> {
222*dfe53cf0SGnoCiYeH         if file_type != FileType::CharDevice {
223*dfe53cf0SGnoCiYeH             return Err(SystemError::ENOSYS);
224*dfe53cf0SGnoCiYeH         }
225*dfe53cf0SGnoCiYeH 
226*dfe53cf0SGnoCiYeH         let mut guard = self.inner.lock();
227*dfe53cf0SGnoCiYeH 
228*dfe53cf0SGnoCiYeH         if guard.children_unchecked_mut().contains_key(name) {
229*dfe53cf0SGnoCiYeH             return Err(SystemError::EEXIST);
230*dfe53cf0SGnoCiYeH         }
231*dfe53cf0SGnoCiYeH 
232*dfe53cf0SGnoCiYeH         let fs = guard.fs.upgrade().unwrap();
233*dfe53cf0SGnoCiYeH 
234*dfe53cf0SGnoCiYeH         let result = TtyDevice::new(
235*dfe53cf0SGnoCiYeH             name.to_string(),
236*dfe53cf0SGnoCiYeH             IdTable::new(name.to_string(), None),
237*dfe53cf0SGnoCiYeH             TtyType::Pty(PtyType::Pts),
238*dfe53cf0SGnoCiYeH         );
239*dfe53cf0SGnoCiYeH 
240*dfe53cf0SGnoCiYeH         let mut metadata = result.metadata()?;
241*dfe53cf0SGnoCiYeH 
242*dfe53cf0SGnoCiYeH         metadata.mode.insert(ModeType::S_IFCHR);
243*dfe53cf0SGnoCiYeH         metadata.raw_dev =
244*dfe53cf0SGnoCiYeH             DeviceNumber::new(Major::UNIX98_PTY_SLAVE_MAJOR, name.parse::<u32>().unwrap());
245*dfe53cf0SGnoCiYeH 
246*dfe53cf0SGnoCiYeH         result.set_metadata(&metadata)?;
247*dfe53cf0SGnoCiYeH 
248*dfe53cf0SGnoCiYeH         guard
249*dfe53cf0SGnoCiYeH             .children_unchecked_mut()
250*dfe53cf0SGnoCiYeH             .insert(name.to_string(), result.clone());
251*dfe53cf0SGnoCiYeH 
252*dfe53cf0SGnoCiYeH         fs.pts_count.fetch_add(1, Ordering::SeqCst);
253*dfe53cf0SGnoCiYeH 
254*dfe53cf0SGnoCiYeH         Ok(result)
255*dfe53cf0SGnoCiYeH     }
256*dfe53cf0SGnoCiYeH 
257*dfe53cf0SGnoCiYeH     fn find(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError> {
258*dfe53cf0SGnoCiYeH         let guard = self.inner.lock();
259*dfe53cf0SGnoCiYeH 
260*dfe53cf0SGnoCiYeH         if let Some(dev) = guard.children_unchecked().get(name) {
261*dfe53cf0SGnoCiYeH             Ok(dev.clone() as Arc<dyn IndexNode>)
262*dfe53cf0SGnoCiYeH         } else {
263*dfe53cf0SGnoCiYeH             Err(SystemError::ENOENT)
264*dfe53cf0SGnoCiYeH         }
265*dfe53cf0SGnoCiYeH     }
266*dfe53cf0SGnoCiYeH 
267*dfe53cf0SGnoCiYeH     fn unlink(&self, name: &str) -> Result<(), SystemError> {
268*dfe53cf0SGnoCiYeH         let mut guard = self.inner.lock();
269*dfe53cf0SGnoCiYeH         guard.children_unchecked_mut().remove(name);
270*dfe53cf0SGnoCiYeH         Ok(())
271*dfe53cf0SGnoCiYeH     }
272*dfe53cf0SGnoCiYeH }
273*dfe53cf0SGnoCiYeH 
274*dfe53cf0SGnoCiYeH #[unified_init(INITCALL_FS)]
275*dfe53cf0SGnoCiYeH #[inline(never)]
276*dfe53cf0SGnoCiYeH pub fn devpts_init() -> Result<(), SystemError> {
277*dfe53cf0SGnoCiYeH     let dev_inode = ROOT_INODE().find("dev")?;
278*dfe53cf0SGnoCiYeH 
279*dfe53cf0SGnoCiYeH     let pts_inode = dev_inode.create("pts", FileType::Dir, ModeType::from_bits_truncate(0o755))?;
280*dfe53cf0SGnoCiYeH 
281*dfe53cf0SGnoCiYeH     // 创建 devptsfs 实例
282*dfe53cf0SGnoCiYeH     let ptsfs: Arc<DevPtsFs> = DevPtsFs::new();
283*dfe53cf0SGnoCiYeH 
284*dfe53cf0SGnoCiYeH     // let mountfs = dev_inode.mount(ptsfs).expect("Failed to mount DevPtsFS");
285*dfe53cf0SGnoCiYeH 
286*dfe53cf0SGnoCiYeH     pts_inode.mount(ptsfs).expect("Failed to mount DevPtsFS");
287*dfe53cf0SGnoCiYeH     kinfo!("DevPtsFs mounted.");
288*dfe53cf0SGnoCiYeH 
289*dfe53cf0SGnoCiYeH     Ok(())
290*dfe53cf0SGnoCiYeH }
291