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