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