Browse Source

实现pty,附带测试程序 (#685)

* 实现pty,附带测试程序

* fmt ** clippy

* 将file层的锁粒度缩小,从而不使用no_preempt。更改pipe在sleep部分的bug

* 修复拼写错误
GnoCiYeH 11 months ago
parent
commit
dfe53cf087
49 changed files with 1691 additions and 384 deletions
  1. 6 0
      kernel/src/driver/base/device/device_number.rs
  2. 11 6
      kernel/src/driver/disk/ahci/ahci_inode.rs
  3. 5 5
      kernel/src/driver/input/ps2_mouse/ps_mouse_device.rs
  4. 13 5
      kernel/src/driver/keyboard/ps2_keyboard.rs
  5. 7 1
      kernel/src/driver/tty/kthread.rs
  6. 1 0
      kernel/src/driver/tty/mod.rs
  7. 288 0
      kernel/src/driver/tty/pty/mod.rs
  8. 222 0
      kernel/src/driver/tty/pty/unix98pty.rs
  9. 76 7
      kernel/src/driver/tty/tty_core.rs
  10. 80 22
      kernel/src/driver/tty/tty_device.rs
  11. 96 42
      kernel/src/driver/tty/tty_driver.rs
  12. 12 3
      kernel/src/driver/tty/tty_ldisc/mod.rs
  13. 52 4
      kernel/src/driver/tty/tty_ldisc/ntty.rs
  14. 28 26
      kernel/src/driver/tty/tty_port.rs
  15. 19 3
      kernel/src/driver/tty/virtual_terminal/mod.rs
  16. 14 1
      kernel/src/driver/tty/virtual_terminal/virtual_console.rs
  17. 8 4
      kernel/src/driver/video/fbdev/base/fbmem.rs
  18. 8 4
      kernel/src/filesystem/devfs/mod.rs
  19. 9 4
      kernel/src/filesystem/devfs/null_dev.rs
  20. 9 4
      kernel/src/filesystem/devfs/zero_dev.rs
  21. 290 0
      kernel/src/filesystem/devpts/mod.rs
  22. 8 4
      kernel/src/filesystem/fat/fs.rs
  23. 8 4
      kernel/src/filesystem/kernfs/mod.rs
  24. 1 0
      kernel/src/filesystem/mod.rs
  25. 16 8
      kernel/src/filesystem/procfs/mod.rs
  26. 4 4
      kernel/src/filesystem/ramfs/mod.rs
  27. 4 3
      kernel/src/filesystem/vfs/core.rs
  28. 85 70
      kernel/src/filesystem/vfs/file.rs
  29. 20 7
      kernel/src/filesystem/vfs/mod.rs
  30. 37 10
      kernel/src/filesystem/vfs/mount.rs
  31. 1 1
      kernel/src/filesystem/vfs/open.rs
  32. 22 29
      kernel/src/filesystem/vfs/syscall.rs
  33. 2 3
      kernel/src/filesystem/vfs/utils.rs
  34. 43 45
      kernel/src/ipc/pipe.rs
  35. 6 4
      kernel/src/ipc/syscall.rs
  36. 3 3
      kernel/src/libs/lib_ui/textui.rs
  37. 3 3
      kernel/src/libs/printk.rs
  38. 7 1
      kernel/src/libs/wait_queue.rs
  39. 23 23
      kernel/src/net/event_poll/mod.rs
  40. 8 4
      kernel/src/net/socket/mod.rs
  41. 1 2
      kernel/src/net/syscall.rs
  42. 2 3
      kernel/src/process/mod.rs
  43. 14 0
      kernel/src/syscall/mod.rs
  44. 9 4
      kernel/src/virt/kvm/kvm_dev.rs
  45. 9 4
      kernel/src/virt/kvm/vcpu_dev.rs
  46. 9 4
      kernel/src/virt/kvm/vm_dev.rs
  47. 20 0
      user/apps/test_pty/Makefile
  48. 49 0
      user/apps/test_pty/test_pty.c
  49. 23 0
      user/dadk/config/test_pty-0.1.0.dadk

+ 6 - 0
kernel/src/driver/base/device/device_number.rs

@@ -18,6 +18,12 @@ impl Major {
     /// /dev/fb* framebuffers
     pub const FB_MAJOR: Self = Self::new(29);
 
+    /// Pty
+    pub const UNIX98_PTY_MASTER_MAJOR: Self = Self::new(128);
+    pub const UNIX98_PTY_MAJOR_COUNT: Self = Self::new(8);
+    pub const UNIX98_PTY_SLAVE_MAJOR: Self =
+        Self::new(Self::UNIX98_PTY_MASTER_MAJOR.0 + Self::UNIX98_PTY_MAJOR_COUNT.0);
+
     pub const fn new(x: u32) -> Self {
         Major(x)
     }

+ 11 - 6
kernel/src/driver/disk/ahci/ahci_inode.rs

@@ -6,6 +6,7 @@ use crate::filesystem::vfs::syscall::ModeType;
 use crate::filesystem::vfs::{
     core::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata,
 };
+use crate::libs::spinlock::SpinLockGuard;
 use crate::{libs::spinlock::SpinLock, time::TimeSpec};
 use alloc::{
     string::String,
@@ -76,11 +77,15 @@ impl IndexNode for LockedAhciInode {
         self
     }
 
-    fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> {
+    fn open(
+        &self,
+        _data: SpinLockGuard<FilePrivateData>,
+        _mode: &FileMode,
+    ) -> Result<(), SystemError> {
         Err(SystemError::EOPNOTSUPP_OR_ENOTSUP)
     }
 
-    fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
+    fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
         Err(SystemError::EOPNOTSUPP_OR_ENOTSUP)
     }
 
@@ -114,13 +119,13 @@ impl IndexNode for LockedAhciInode {
         offset: usize, // lba地址
         len: usize,
         buf: &mut [u8],
-        data: &mut FilePrivateData,
+        data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         if buf.len() < len {
             return Err(SystemError::EINVAL);
         }
 
-        if let FilePrivateData::Unused = data {
+        if let FilePrivateData::Unused = *data {
             return self.0.lock().disk.read_at_bytes(offset, len, buf);
         }
 
@@ -133,13 +138,13 @@ impl IndexNode for LockedAhciInode {
         offset: usize, // lba地址
         len: usize,
         buf: &[u8],
-        data: &mut FilePrivateData,
+        data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         if buf.len() < len {
             return Err(SystemError::EINVAL);
         }
 
-        if let FilePrivateData::Unused = data {
+        if let FilePrivateData::Unused = *data {
             return self.0.lock().disk.write_at_bytes(offset, len, buf);
         }
 

+ 5 - 5
kernel/src/driver/input/ps2_mouse/ps_mouse_device.rs

@@ -36,7 +36,7 @@ use crate::{
     },
     libs::{
         rwlock::{RwLockReadGuard, RwLockWriteGuard},
-        spinlock::SpinLock,
+        spinlock::{SpinLock, SpinLockGuard},
     },
     time::TimeSpec,
 };
@@ -587,7 +587,7 @@ impl DeviceINode for Ps2MouseDevice {
 impl IndexNode for Ps2MouseDevice {
     fn open(
         &self,
-        _data: &mut FilePrivateData,
+        _data: SpinLockGuard<FilePrivateData>,
         _mode: &crate::filesystem::vfs::file::FileMode,
     ) -> Result<(), SystemError> {
         let mut guard = self.inner.lock_irqsave();
@@ -595,7 +595,7 @@ impl IndexNode for Ps2MouseDevice {
         Ok(())
     }
 
-    fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
+    fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
         let mut guard = self.inner.lock_irqsave();
         guard.buf.clear();
         Ok(())
@@ -606,7 +606,7 @@ impl IndexNode for Ps2MouseDevice {
         _offset: usize,
         _len: usize,
         buf: &mut [u8],
-        _data: &mut FilePrivateData,
+        _data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         let mut guard = self.inner.lock_irqsave();
 
@@ -625,7 +625,7 @@ impl IndexNode for Ps2MouseDevice {
         _offset: usize,
         _len: usize,
         _buf: &[u8],
-        _data: &mut FilePrivateData,
+        _data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
     }

+ 13 - 5
kernel/src/driver/keyboard/ps2_keyboard.rs

@@ -27,7 +27,11 @@ use crate::{
         },
     },
     init::initcall::INITCALL_DEVICE,
-    libs::{keyboard_parser::TypeOneFSM, rwlock::RwLock, spinlock::SpinLock},
+    libs::{
+        keyboard_parser::TypeOneFSM,
+        rwlock::RwLock,
+        spinlock::{SpinLock, SpinLockGuard},
+    },
     time::TimeSpec,
 };
 use system_error::SystemError;
@@ -115,7 +119,7 @@ impl IndexNode for LockedPS2KeyBoardInode {
         _offset: usize,
         _len: usize,
         _buf: &mut [u8],
-        _data: &mut FilePrivateData,
+        _data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         return Err(SystemError::ENOSYS);
     }
@@ -125,16 +129,20 @@ impl IndexNode for LockedPS2KeyBoardInode {
         _offset: usize,
         _len: usize,
         _buf: &[u8],
-        _data: &mut FilePrivateData,
+        _data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         return Err(SystemError::ENOSYS);
     }
 
-    fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> {
+    fn open(
+        &self,
+        _data: SpinLockGuard<FilePrivateData>,
+        _mode: &FileMode,
+    ) -> Result<(), SystemError> {
         return Ok(());
     }
 
-    fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
+    fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
         return Ok(());
     }
 

+ 7 - 1
kernel/src/driver/tty/kthread.rs

@@ -5,6 +5,7 @@ use kdepends::thingbuf::StaticThingBuf;
 
 use crate::{
     arch::sched::sched,
+    driver::tty::virtual_terminal::virtual_console::CURRENT_VCNUM,
     process::{
         kthread::{KernelThreadClosure, KernelThreadMechanism},
         ProcessControlBlock, ProcessFlags,
@@ -54,7 +55,12 @@ fn tty_refresh_thread() -> i32 {
             *item = KEYBUF.pop().unwrap();
         }
 
-        let _ = current_tty_port().receive_buf(&data[0..to_dequeue], &[], to_dequeue);
+        if CURRENT_VCNUM.load(core::sync::atomic::Ordering::SeqCst) != -1 {
+            let _ = current_tty_port().receive_buf(&data[0..to_dequeue], &[], to_dequeue);
+        } else {
+            // 这里由于stdio未初始化,所以无法找到port
+            // TODO: 考虑改用双端队列,能够将丢失的输入插回
+        }
     }
 }
 

+ 1 - 0
kernel/src/driver/tty/mod.rs

@@ -2,6 +2,7 @@ use alloc::vec::Vec;
 
 pub mod console;
 pub mod kthread;
+pub mod pty;
 mod sysfs;
 pub mod termios;
 pub mod tty_core;

+ 288 - 0
kernel/src/driver/tty/pty/mod.rs

@@ -0,0 +1,288 @@
+use alloc::{
+    string::{String, ToString},
+    sync::Arc,
+};
+use system_error::SystemError;
+use unified_init::macros::unified_init;
+
+use crate::{
+    driver::base::device::{
+        device_number::{DeviceNumber, Major},
+        device_register, IdTable,
+    },
+    filesystem::devfs::devfs_register,
+    init::initcall::INITCALL_DEVICE,
+    libs::lazy_init::Lazy,
+    mm::VirtAddr,
+    syscall::user_access::{UserBufferReader, UserBufferWriter},
+};
+
+use self::unix98pty::{Unix98PtyDriverInner, NR_UNIX98_PTY_MAX};
+
+use super::{
+    termios::{ControlMode, InputMode, LocalMode, OutputMode, TTY_STD_TERMIOS},
+    tty_core::{TtyCore, TtyCoreData, TtyFlag, TtyPacketStatus},
+    tty_device::{TtyDevice, TtyType},
+    tty_driver::{TtyDriver, TtyDriverManager, TtyDriverSubType, TtyDriverType, TTY_DRIVERS},
+    tty_port::{DefaultTtyPort, TtyPort},
+};
+
+pub mod unix98pty;
+
+static PTM_DRIVER: Lazy<Arc<TtyDriver>> = Lazy::new();
+static PTS_DRIVER: Lazy<Arc<TtyDriver>> = Lazy::new();
+
+pub(super) fn ptm_driver() -> Arc<TtyDriver> {
+    PTM_DRIVER.ensure();
+    PTM_DRIVER.get().clone()
+}
+
+pub(super) fn pts_driver() -> Arc<TtyDriver> {
+    PTS_DRIVER.ensure();
+    PTS_DRIVER.get().clone()
+}
+
+// lazy_static! {
+//     pub static ref PTM_DRIVER: Arc<TtyDriver> = {
+//         let mut ptm_driver = TtyDriver::new(
+//             NR_UNIX98_PTY_MAX,
+//             "ptm",
+//             0,
+//             Major::UNIX98_PTY_MASTER_MAJOR,
+//             0,
+//             TtyDriverType::Pty,
+//             *TTY_STD_TERMIOS,
+//             Arc::new(Unix98PtyDriverInner::new()),
+//         );
+
+//         ptm_driver.set_subtype(TtyDriverSubType::PtyMaster);
+//         let term = ptm_driver.init_termios_mut();
+//         term.input_mode = InputMode::empty();
+//         term.output_mode = OutputMode::empty();
+//         term.control_mode = ControlMode::B38400 | ControlMode::CS8 | ControlMode::CREAD;
+//         term.local_mode = LocalMode::empty();
+//         term.input_speed = 38400;
+//         term.output_speed = 38400;
+//         TtyDriverManager::tty_register_driver(ptm_driver).unwrap()
+//     };
+//     pub static ref PTS_DRIVER: Arc<TtyDriver> = {
+//         let mut pts_driver = TtyDriver::new(
+//             NR_UNIX98_PTY_MAX,
+//             "pts",
+//             0,
+//             Major::UNIX98_PTY_SLAVE_MAJOR,
+//             0,
+//             TtyDriverType::Pty,
+//             *TTY_STD_TERMIOS,
+//             Arc::new(Unix98PtyDriverInner::new()),
+//         );
+
+//         pts_driver.set_subtype(TtyDriverSubType::PtySlave);
+//         let term = pts_driver.init_termios_mut();
+//         term.input_mode = InputMode::empty();
+//         term.output_mode = OutputMode::empty();
+//         term.control_mode = ControlMode::B38400 | ControlMode::CS8 | ControlMode::CREAD;
+//         term.local_mode = LocalMode::empty();
+//         term.input_speed = 38400;
+//         term.output_speed = 38400;
+//         TtyDriverManager::tty_register_driver(pts_driver).unwrap()
+//     };
+// }
+
+pub struct PtyCommon;
+
+impl PtyCommon {
+    pub fn pty_common_install(
+        driver: Arc<TtyDriver>,
+        tty: Arc<TtyCore>,
+        legacy: bool,
+    ) -> Result<(), SystemError> {
+        let core = tty.core();
+        let other_driver = driver.other_pty_driver().unwrap();
+        let other_tty = TtyCore::new(other_driver.clone(), core.index());
+        other_driver.add_tty(other_tty.clone());
+
+        let port0: Arc<dyn TtyPort> = Arc::new(DefaultTtyPort::new());
+        let port1: Arc<dyn TtyPort> = Arc::new(DefaultTtyPort::new());
+
+        let o_core = other_tty.core();
+
+        if legacy {
+            core.init_termios();
+            o_core.init_termios();
+
+            driver
+                .other_pty_driver()
+                .unwrap()
+                .ttys()
+                .insert(core.index(), other_tty.clone());
+            driver.ttys().insert(core.index(), tty.clone());
+        } else {
+            *core.termios_write() = driver.init_termios();
+            *o_core.termios_write() = driver.other_pty_driver().unwrap().init_termios();
+        }
+
+        core.set_link(Arc::downgrade(&other_tty));
+        o_core.set_link(Arc::downgrade(&tty));
+
+        port0.setup_internal_tty(Arc::downgrade(&other_tty));
+        port1.setup_internal_tty(Arc::downgrade(&tty));
+        other_tty.set_port(port0);
+        tty.set_port(port1);
+
+        core.add_count();
+        o_core.add_count();
+
+        // 将pts加入pts Driver管理队列
+        PTS_DRIVER.ttys().insert(core.index(), other_tty);
+
+        Ok(())
+    }
+
+    pub fn pty_common_open(core: &TtyCoreData) -> Result<(), SystemError> {
+        if let Some(link) = core.link() {
+            let link_core = link.core();
+
+            if core.flags().contains(TtyFlag::OTHER_CLOSED) {
+                core.flags_write().insert(TtyFlag::IO_ERROR);
+                return Err(SystemError::EIO);
+            }
+
+            if link_core.flags().contains(TtyFlag::PTY_LOCK) {
+                core.flags_write().insert(TtyFlag::IO_ERROR);
+                return Err(SystemError::EIO);
+            }
+
+            if core.driver().tty_driver_sub_type() == TtyDriverSubType::PtySlave
+                && link_core.count() != 1
+            {
+                // 只能有一个master,如果当前为slave,则link的count必须为1
+                core.flags_write().insert(TtyFlag::IO_ERROR);
+                return Err(SystemError::EIO);
+            }
+
+            core.flags_write().remove(TtyFlag::IO_ERROR);
+            link_core.flags_write().remove(TtyFlag::OTHER_CLOSED);
+            core.flags_write().insert(TtyFlag::THROTTLED);
+
+            return Ok(());
+        }
+        return Err(SystemError::ENODEV);
+    }
+
+    pub fn pty_set_lock(tty: &TtyCoreData, arg: VirtAddr) -> Result<(), SystemError> {
+        let user_reader =
+            UserBufferReader::new(arg.as_ptr::<i32>(), core::mem::size_of::<i32>(), true)?;
+
+        if *user_reader.read_one_from_user::<i32>(0)? != 0 {
+            tty.flags_write().insert(TtyFlag::PTY_LOCK);
+        } else {
+            tty.flags_write().remove(TtyFlag::PTY_LOCK);
+        }
+
+        Ok(())
+    }
+
+    pub fn pty_get_lock(tty: &TtyCoreData, arg: VirtAddr) -> Result<(), SystemError> {
+        let mut user_writer =
+            UserBufferWriter::new(arg.as_ptr::<i32>(), core::mem::size_of::<i32>(), true)?;
+        user_writer.copy_one_to_user(&tty.flags().contains(TtyFlag::PTY_LOCK), 0)?;
+        Ok(())
+    }
+
+    pub fn pty_set_packet_mode(tty: &TtyCoreData, arg: VirtAddr) -> Result<(), SystemError> {
+        let user_reader =
+            UserBufferReader::new(arg.as_ptr::<i32>(), core::mem::size_of::<i32>(), true)?;
+
+        let mut ctrl = tty.contorl_info_irqsave();
+        if *user_reader.read_one_from_user::<i32>(0)? != 0 {
+            if !ctrl.packet {
+                tty.link().unwrap().core().contorl_info_irqsave().pktstatus =
+                    TtyPacketStatus::empty();
+                ctrl.packet = true;
+            }
+        } else {
+            ctrl.packet = false;
+        }
+        Ok(())
+    }
+
+    pub fn pty_get_packet_mode(tty: &TtyCoreData, arg: VirtAddr) -> Result<(), SystemError> {
+        let mut user_writer =
+            UserBufferWriter::new(arg.as_ptr::<i32>(), core::mem::size_of::<i32>(), true)?;
+        user_writer.copy_one_to_user(&tty.contorl_info_irqsave().packet, 0)?;
+        Ok(())
+    }
+
+    pub fn unix98pty_init() -> Result<(), SystemError> {
+        let ptm_driver = ptm_driver();
+        let pts_driver = pts_driver();
+        ptm_driver.set_other_pty_driver(Arc::downgrade(&pts_driver));
+        pts_driver.set_other_pty_driver(Arc::downgrade(&ptm_driver));
+
+        let idt = IdTable::new(
+            String::from("ptmx"),
+            Some(DeviceNumber::new(Major::TTYAUX_MAJOR, 2)),
+        );
+        let ptmx_dev = TtyDevice::new(
+            "ptmx".to_string(),
+            idt.clone(),
+            TtyType::Pty(super::tty_device::PtyType::Ptm),
+        );
+
+        ptmx_dev.inner_write().metadata_mut().raw_dev = idt.device_number();
+        device_register(ptmx_dev.clone())?;
+        devfs_register("ptmx", ptmx_dev)?;
+
+        TTY_DRIVERS.lock().push(ptm_driver);
+        TTY_DRIVERS.lock().push(pts_driver);
+
+        Ok(())
+    }
+}
+
+#[unified_init(INITCALL_DEVICE)]
+#[inline(never)]
+pub fn pty_init() -> Result<(), SystemError> {
+    let mut ptm_driver = TtyDriver::new(
+        NR_UNIX98_PTY_MAX,
+        "ptm",
+        0,
+        Major::UNIX98_PTY_MASTER_MAJOR,
+        0,
+        TtyDriverType::Pty,
+        *TTY_STD_TERMIOS,
+        Arc::new(Unix98PtyDriverInner::new()),
+    );
+    ptm_driver.set_subtype(TtyDriverSubType::PtyMaster);
+    let term = ptm_driver.init_termios_mut();
+    term.input_mode = InputMode::empty();
+    term.output_mode = OutputMode::empty();
+    term.control_mode = ControlMode::B38400 | ControlMode::CS8 | ControlMode::CREAD;
+    term.local_mode = LocalMode::empty();
+    term.input_speed = 38400;
+    term.output_speed = 38400;
+    PTM_DRIVER.init(TtyDriverManager::tty_register_driver(ptm_driver).unwrap());
+
+    let mut pts_driver = TtyDriver::new(
+        NR_UNIX98_PTY_MAX,
+        "pts",
+        0,
+        Major::UNIX98_PTY_SLAVE_MAJOR,
+        0,
+        TtyDriverType::Pty,
+        *TTY_STD_TERMIOS,
+        Arc::new(Unix98PtyDriverInner::new()),
+    );
+    pts_driver.set_subtype(TtyDriverSubType::PtySlave);
+    let term = pts_driver.init_termios_mut();
+    term.input_mode = InputMode::empty();
+    term.output_mode = OutputMode::empty();
+    term.control_mode = ControlMode::B38400 | ControlMode::CS8 | ControlMode::CREAD;
+    term.local_mode = LocalMode::empty();
+    term.input_speed = 38400;
+    term.output_speed = 38400;
+    PTS_DRIVER.init(TtyDriverManager::tty_register_driver(pts_driver).unwrap());
+
+    return PtyCommon::unix98pty_init();
+}

+ 222 - 0
kernel/src/driver/tty/pty/unix98pty.rs

@@ -0,0 +1,222 @@
+use alloc::{string::ToString, sync::Arc};
+use system_error::SystemError;
+
+use crate::{
+    driver::tty::{
+        termios::Termios,
+        tty_core::{TtyCore, TtyCoreData, TtyFlag, TtyIoctlCmd, TtyPacketStatus},
+        tty_device::TtyFilePrivateData,
+        tty_driver::{TtyDriver, TtyDriverPrivateData, TtyDriverSubType, TtyOperation},
+    },
+    filesystem::{
+        devpts::DevPtsFs,
+        vfs::{
+            file::FileMode, syscall::ModeType, FilePrivateData, FileType, MountFS, ROOT_INODE,
+            VFS_MAX_FOLLOW_SYMLINK_TIMES,
+        },
+    },
+    libs::spinlock::SpinLockGuard,
+    mm::VirtAddr,
+    net::event_poll::EPollEventType,
+    syscall::user_access::UserBufferWriter,
+};
+
+use super::{ptm_driver, pts_driver, PtyCommon};
+
+pub const NR_UNIX98_PTY_MAX: u32 = 128;
+
+#[derive(Debug)]
+pub struct Unix98PtyDriverInner;
+
+impl Unix98PtyDriverInner {
+    pub fn new() -> Self {
+        Self
+    }
+}
+
+impl TtyOperation for Unix98PtyDriverInner {
+    fn install(&self, driver: Arc<TtyDriver>, tty: Arc<TtyCore>) -> Result<(), SystemError> {
+        PtyCommon::pty_common_install(driver, tty, false)
+    }
+
+    fn open(&self, tty: &TtyCoreData) -> Result<(), SystemError> {
+        PtyCommon::pty_common_open(tty)
+    }
+
+    fn write(&self, tty: &TtyCoreData, buf: &[u8], nr: usize) -> Result<usize, SystemError> {
+        let to = tty.checked_link()?;
+
+        if nr == 0 || tty.flow_irqsave().stopped {
+            return Ok(0);
+        }
+
+        to.core().port().unwrap().receive_buf(buf, &[], nr)
+    }
+
+    fn write_room(&self, tty: &TtyCoreData) -> usize {
+        // TODO 暂时
+        if tty.flow_irqsave().stopped {
+            return 0;
+        }
+
+        8192
+    }
+
+    fn flush_buffer(&self, tty: &TtyCoreData) -> Result<(), SystemError> {
+        let to = tty.checked_link()?;
+
+        let mut ctrl = to.core().contorl_info_irqsave();
+        ctrl.pktstatus.insert(TtyPacketStatus::TIOCPKT_FLUSHWRITE);
+
+        to.core().read_wq().wakeup_all();
+
+        Ok(())
+    }
+
+    fn ioctl(&self, tty: Arc<TtyCore>, cmd: u32, arg: usize) -> Result<(), SystemError> {
+        let core = tty.core();
+        if core.driver().tty_driver_sub_type() != TtyDriverSubType::PtyMaster {
+            return Err(SystemError::ENOSYS);
+        }
+
+        match cmd {
+            TtyIoctlCmd::TIOCSPTLCK => {
+                return PtyCommon::pty_set_lock(core, VirtAddr::new(arg));
+            }
+            TtyIoctlCmd::TIOCGPTLCK => {
+                return PtyCommon::pty_get_lock(core, VirtAddr::new(arg));
+            }
+            TtyIoctlCmd::TIOCPKT => {
+                return PtyCommon::pty_set_packet_mode(core, VirtAddr::new(arg));
+            }
+            TtyIoctlCmd::TIOCGPKT => {
+                return PtyCommon::pty_get_packet_mode(core, VirtAddr::new(arg));
+            }
+            TtyIoctlCmd::TIOCGPTN => {
+                let mut user_writer =
+                    UserBufferWriter::new(arg as *mut u32, core::mem::size_of::<u32>(), true)?;
+
+                return user_writer.copy_one_to_user(&(core.index() as u32), 0);
+            }
+            _ => {
+                return Err(SystemError::ENOIOCTLCMD);
+            }
+        }
+    }
+
+    fn set_termios(&self, tty: Arc<TtyCore>, _old_termios: Termios) -> Result<(), SystemError> {
+        let core = tty.core();
+        if core.driver().tty_driver_sub_type() != TtyDriverSubType::PtySlave {
+            return Err(SystemError::ENOSYS);
+        }
+        todo!()
+    }
+
+    fn start(&self, core: &TtyCoreData) -> Result<(), SystemError> {
+        if core.driver().tty_driver_sub_type() != TtyDriverSubType::PtySlave {
+            return Err(SystemError::ENOSYS);
+        }
+
+        let link = core.checked_link()?;
+
+        let mut ctrl = core.contorl_info_irqsave();
+        ctrl.pktstatus.remove(TtyPacketStatus::TIOCPKT_STOP);
+        ctrl.pktstatus.insert(TtyPacketStatus::TIOCPKT_START);
+
+        link.core()
+            .read_wq()
+            .wakeup_any(EPollEventType::EPOLLIN.bits() as u64);
+
+        Ok(())
+    }
+
+    fn stop(&self, core: &TtyCoreData) -> Result<(), SystemError> {
+        if core.driver().tty_driver_sub_type() != TtyDriverSubType::PtySlave {
+            return Err(SystemError::ENOSYS);
+        }
+
+        let link = core.checked_link()?;
+
+        let mut ctrl = core.contorl_info_irqsave();
+        ctrl.pktstatus.remove(TtyPacketStatus::TIOCPKT_START);
+        ctrl.pktstatus.insert(TtyPacketStatus::TIOCPKT_STOP);
+
+        link.core()
+            .read_wq()
+            .wakeup_any(EPollEventType::EPOLLIN.bits() as u64);
+
+        Ok(())
+    }
+
+    fn flush_chars(&self, _tty: &TtyCoreData) {
+        // 不做处理
+    }
+
+    fn lookup(
+        &self,
+        index: usize,
+        priv_data: TtyDriverPrivateData,
+    ) -> Result<Arc<TtyCore>, SystemError> {
+        if let TtyDriverPrivateData::Pty(false) = priv_data {
+            return pts_driver()
+                .ttys()
+                .get(&index)
+                .cloned()
+                .ok_or(SystemError::ENODEV);
+        }
+
+        return Err(SystemError::ENOSYS);
+    }
+
+    fn close(&self, tty: Arc<TtyCore>) -> Result<(), SystemError> {
+        let driver = tty.core().driver();
+
+        driver.ttys().remove(&tty.core().index());
+        if tty.core().driver().tty_driver_sub_type() == TtyDriverSubType::PtySlave {
+            let pts_root_inode =
+                ROOT_INODE().lookup_follow_symlink("/dev/pts", VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
+            let _ = pts_root_inode.unlink(&tty.core().index().to_string());
+        }
+
+        Ok(())
+    }
+}
+
+pub fn ptmx_open(
+    mut data: SpinLockGuard<FilePrivateData>,
+    mode: &FileMode,
+) -> Result<(), SystemError> {
+    let pts_root_inode =
+        ROOT_INODE().lookup_follow_symlink("/dev/pts", VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
+
+    let fs = pts_root_inode
+        .fs()
+        .as_any_ref()
+        .downcast_ref::<MountFS>()
+        .unwrap()
+        .inner_filesystem();
+    let fsinfo = fs.as_any_ref().downcast_ref::<DevPtsFs>().unwrap();
+
+    let index = fsinfo.alloc_index()?;
+
+    let tty = TtyDriver::init_tty_device(ptm_driver(), index)?;
+
+    // 设置privdata
+    *data = FilePrivateData::Tty(TtyFilePrivateData {
+        tty: tty.clone(),
+        mode: *mode,
+    });
+
+    let core = tty.core();
+    core.flags_write().insert(TtyFlag::PTY_LOCK);
+
+    let _ = pts_root_inode.create(
+        &index.to_string(),
+        FileType::CharDevice,
+        ModeType::from_bits_truncate(0x666),
+    )?;
+
+    ptm_driver().driver_funcs().open(core)?;
+
+    Ok(())
+}

+ 76 - 7
kernel/src/driver/tty/tty_core.rs

@@ -1,9 +1,14 @@
 use core::{
     fmt::Debug,
-    sync::atomic::{AtomicBool, AtomicUsize},
+    sync::atomic::{AtomicBool, AtomicUsize, Ordering},
 };
 
-use alloc::{collections::LinkedList, string::String, sync::Arc, vec::Vec};
+use alloc::{
+    collections::LinkedList,
+    string::String,
+    sync::{Arc, Weak},
+    vec::Vec,
+};
 use system_error::SystemError;
 
 use crate::{
@@ -55,7 +60,7 @@ impl TtyCore {
             ctrl: SpinLock::new(TtyContorlInfo::default()),
             closing: AtomicBool::new(false),
             flow: SpinLock::new(TtyFlowState::default()),
-            link: None,
+            link: RwLock::default(),
             epitems: SpinLock::new(LinkedList::new()),
         };
 
@@ -138,7 +143,7 @@ impl TtyCore {
 
         self.core()
             .write_wq
-            .wakeup(EPollEventType::EPOLLOUT.bits() as u64);
+            .wakeup_any(EPollEventType::EPOLLOUT.bits() as u64);
     }
 
     pub fn tty_mode_ioctl(tty: Arc<TtyCore>, cmd: u32, arg: usize) -> Result<usize, SystemError> {
@@ -252,7 +257,7 @@ pub struct TtyContorlInfo {
     pub pgid: Option<Pid>,
 
     /// packet模式下使用,目前未用到
-    pub pktstatus: u8,
+    pub pktstatus: TtyPacketStatus,
     pub packet: bool,
 }
 
@@ -296,7 +301,7 @@ pub struct TtyCoreData {
     /// 流控状态
     flow: SpinLock<TtyFlowState>,
     /// 链接tty
-    link: Option<Arc<TtyCore>>,
+    link: RwLock<Weak<TtyCore>>,
     /// epitems
     epitems: SpinLock<LinkedList<Arc<EPollItem>>>,
 }
@@ -332,6 +337,11 @@ impl TtyCoreData {
         *self.flags.read_irqsave()
     }
 
+    #[inline]
+    pub fn flags_write(&self) -> RwLockWriteGuard<'_, TtyFlag> {
+        self.flags.write_irqsave()
+    }
+
     #[inline]
     pub fn termios(&self) -> RwLockReadGuard<'_, Termios> {
         self.termios.read_irqsave()
@@ -348,6 +358,11 @@ impl TtyCoreData {
         *termios_guard = termios;
     }
 
+    #[inline]
+    pub fn count(&self) -> usize {
+        self.count.load(Ordering::SeqCst)
+    }
+
     #[inline]
     pub fn add_count(&self) {
         self.count
@@ -391,7 +406,36 @@ impl TtyCoreData {
 
     #[inline]
     pub fn link(&self) -> Option<Arc<TtyCore>> {
-        self.link.clone()
+        self.link.read().upgrade()
+    }
+
+    pub fn checked_link(&self) -> Result<Arc<TtyCore>, SystemError> {
+        if let Some(link) = self.link() {
+            return Ok(link);
+        }
+        return Err(SystemError::ENODEV);
+    }
+
+    pub fn set_link(&self, link: Weak<TtyCore>) {
+        *self.link.write() = link;
+    }
+
+    pub fn init_termios(&self) {
+        let tty_index = self.index();
+        let driver = self.driver();
+        // 初始化termios
+        if !driver
+            .flags()
+            .contains(super::tty_driver::TtyDriverFlag::TTY_DRIVER_RESET_TERMIOS)
+        {
+            // 先查看是否有已经保存的termios
+            if let Some(t) = driver.saved_termios().get(tty_index) {
+                let mut termios = *t;
+                termios.line = driver.init_termios().line;
+                self.set_termios(termios);
+            }
+        }
+        // TODO:设置termios波特率?
     }
 
     #[inline]
@@ -463,6 +507,10 @@ impl TtyOperation for TtyCore {
             .driver_funcs()
             .set_termios(tty, old_termios);
     }
+
+    fn close(&self, tty: Arc<TtyCore>) -> Result<(), SystemError> {
+        self.core().tty_driver.driver_funcs().close(tty)
+    }
 }
 
 bitflags! {
@@ -492,6 +540,19 @@ bitflags! {
         /// 终端线路驱动程序已停止
         const LDISC_HALTED	= 1 << 22;
     }
+
+    #[derive(Default)]
+    pub struct TtyPacketStatus: u8 {
+        /* Used for packet mode */
+        const TIOCPKT_DATA		=  0;
+        const TIOCPKT_FLUSHREAD	=  1;
+        const TIOCPKT_FLUSHWRITE	=  2;
+        const TIOCPKT_STOP		=  4;
+        const TIOCPKT_START		=  8;
+        const TIOCPKT_NOSTOP		= 16;
+        const TIOCPKT_DOSTOP		= 32;
+        const TIOCPKT_IOCTL		= 64;
+    }
 }
 
 #[derive(Debug, PartialEq)]
@@ -614,4 +675,12 @@ impl TtyIoctlCmd {
     pub const TIOCCBRK: u32 = 0x5428;
     /// Return the session ID of FD
     pub const TIOCGSID: u32 = 0x5429;
+    /// 设置ptl锁标记
+    pub const TIOCSPTLCK: u32 = 0x40045431;
+    /// 获取ptl锁标记
+    pub const TIOCGPTLCK: u32 = 0x80045439;
+    /// 获取packet标记
+    pub const TIOCGPKT: u32 = 0x80045438;
+    /// 获取pts index
+    pub const TIOCGPTN: u32 = 0x80045430;
 }

+ 80 - 22
kernel/src/driver/tty/tty_device.rs

@@ -29,7 +29,10 @@ use crate::{
         vfs::{file::FileMode, syscall::ModeType, FilePrivateData, FileType, IndexNode, Metadata},
     },
     init::initcall::INITCALL_DEVICE,
-    libs::rwlock::RwLock,
+    libs::{
+        rwlock::{RwLock, RwLockWriteGuard},
+        spinlock::SpinLockGuard,
+    },
     mm::VirtAddr,
     net::event_poll::{EPollItem, EventPoll},
     process::ProcessManager,
@@ -38,10 +41,11 @@ use crate::{
 
 use super::{
     kthread::tty_flush_thread_init,
+    pty::unix98pty::ptmx_open,
     sysfs::sys_class_tty_instance,
     termios::WindowSize,
     tty_core::{TtyCore, TtyFlag, TtyIoctlCmd},
-    tty_driver::{TtyDriver, TtyDriverSubType, TtyDriverType, TtyOperation},
+    tty_driver::{TtyDriver, TtyDriverManager, TtyDriverSubType, TtyDriverType, TtyOperation},
     tty_job_control::TtyJobCtrlManager,
     virtual_terminal::vty_init,
 };
@@ -72,13 +76,30 @@ impl InnerTtyDevice {
             metadata: Metadata::new(FileType::CharDevice, ModeType::from_bits_truncate(0o755)),
         }
     }
+
+    pub fn metadata_mut(&mut self) -> &mut Metadata {
+        &mut self.metadata
+    }
+}
+
+#[derive(Debug, PartialEq)]
+pub enum TtyType {
+    Tty,
+    Pty(PtyType),
+}
+
+#[derive(Debug, PartialEq)]
+pub enum PtyType {
+    Ptm,
+    Pts,
 }
 
 #[derive(Debug)]
 #[cast_to([sync] Device)]
 pub struct TtyDevice {
-    name: &'static str,
+    name: String,
     id_table: IdTable,
+    tty_type: TtyType,
     inner: RwLock<InnerTtyDevice>,
     kobj_state: LockedKObjectState,
     /// TTY所属的文件系统
@@ -86,7 +107,7 @@ pub struct TtyDevice {
 }
 
 impl TtyDevice {
-    pub fn new(name: &'static str, id_table: IdTable) -> Arc<TtyDevice> {
+    pub fn new(name: String, id_table: IdTable, tty_type: TtyType) -> Arc<TtyDevice> {
         let dev_num = id_table.device_number();
         let dev = TtyDevice {
             name,
@@ -94,23 +115,37 @@ impl TtyDevice {
             inner: RwLock::new(InnerTtyDevice::new()),
             kobj_state: LockedKObjectState::new(None),
             fs: RwLock::new(Weak::default()),
+            tty_type,
         };
 
         dev.inner.write().metadata.raw_dev = dev_num;
 
         Arc::new(dev)
     }
+
+    pub fn inner_write(&self) -> RwLockWriteGuard<InnerTtyDevice> {
+        self.inner.write()
+    }
 }
 
 impl IndexNode for TtyDevice {
     fn open(
         &self,
-        data: &mut crate::filesystem::vfs::FilePrivateData,
+        mut data: SpinLockGuard<FilePrivateData>,
         mode: &crate::filesystem::vfs::file::FileMode,
     ) -> Result<(), SystemError> {
+        if self.tty_type == TtyType::Pty(PtyType::Ptm) {
+            if let FilePrivateData::Tty(_) = &*data {
+                return Ok(());
+            }
+            return ptmx_open(data, mode);
+        }
         let dev_num = self.metadata()?.raw_dev;
 
-        let tty = TtyDriver::open_tty(dev_num)?;
+        let (index, driver) =
+            TtyDriverManager::lookup_tty_driver(dev_num).ok_or(SystemError::ENODEV)?;
+
+        let tty = TtyDriver::open_tty(index, driver)?;
 
         // 设置privdata
         *data = FilePrivateData::Tty(TtyFilePrivateData {
@@ -148,14 +183,16 @@ impl IndexNode for TtyDevice {
         _offset: usize,
         len: usize,
         buf: &mut [u8],
-        data: &mut crate::filesystem::vfs::FilePrivateData,
+        data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, system_error::SystemError> {
-        let (tty, mode) = if let FilePrivateData::Tty(tty_priv) = data {
-            (tty_priv.tty.clone(), tty_priv.mode)
+        let (tty, mode) = if let FilePrivateData::Tty(tty_priv) = &*data {
+            (tty_priv.tty(), tty_priv.mode)
         } else {
             return Err(SystemError::EIO);
         };
 
+        drop(data);
+
         let ld = tty.ldisc();
         let mut offset = 0;
         let mut cookie = false;
@@ -188,15 +225,15 @@ impl IndexNode for TtyDevice {
         _offset: usize,
         len: usize,
         buf: &[u8],
-        data: &mut crate::filesystem::vfs::FilePrivateData,
+        data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, system_error::SystemError> {
         let mut count = len;
-        let (tty, mode) = if let FilePrivateData::Tty(tty_priv) = data {
-            (tty_priv.tty.clone(), tty_priv.mode)
+        let (tty, mode) = if let FilePrivateData::Tty(tty_priv) = &*data {
+            (tty_priv.tty(), tty_priv.mode)
         } else {
             return Err(SystemError::EIO);
         };
-
+        drop(data);
         let ld = tty.ldisc();
         let core = tty.core();
         let mut chunk = 2048;
@@ -239,7 +276,7 @@ impl IndexNode for TtyDevice {
     }
 
     fn as_any_ref(&self) -> &dyn core::any::Any {
-        todo!()
+        self
     }
 
     fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, system_error::SystemError> {
@@ -250,17 +287,30 @@ impl IndexNode for TtyDevice {
         Ok(self.inner.read().metadata.clone())
     }
 
-    fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
+    fn set_metadata(&self, metadata: &Metadata) -> Result<(), SystemError> {
+        let mut guard = self.inner_write();
+        guard.metadata = metadata.clone();
+
         Ok(())
     }
 
+    fn close(&self, data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
+        let (tty, _mode) = if let FilePrivateData::Tty(tty_priv) = &*data {
+            (tty_priv.tty(), tty_priv.mode)
+        } else {
+            return Err(SystemError::EIO);
+        };
+        drop(data);
+        tty.close(tty.clone())
+    }
+
     fn resize(&self, _len: usize) -> Result<(), SystemError> {
         Ok(())
     }
 
     fn ioctl(&self, cmd: u32, arg: usize, data: &FilePrivateData) -> Result<usize, SystemError> {
         let (tty, _) = if let FilePrivateData::Tty(tty_priv) = data {
-            (tty_priv.tty.clone(), tty_priv.mode)
+            (tty_priv.tty(), tty_priv.mode)
         } else {
             return Err(SystemError::EIO);
         };
@@ -485,8 +535,14 @@ impl CharDevice for TtyDevice {
 
 #[derive(Debug, Clone)]
 pub struct TtyFilePrivateData {
-    tty: Arc<TtyCore>,
-    mode: FileMode,
+    pub tty: Arc<TtyCore>,
+    pub mode: FileMode,
+}
+
+impl TtyFilePrivateData {
+    pub fn tty(&self) -> Arc<TtyCore> {
+        self.tty.clone()
+    }
 }
 
 /// 初始化tty设备和console子设备
@@ -494,19 +550,21 @@ pub struct TtyFilePrivateData {
 #[inline(never)]
 pub fn tty_init() -> Result<(), SystemError> {
     let tty = TtyDevice::new(
-        "tty0",
+        "tty0".to_string(),
         IdTable::new(
             String::from("tty0"),
             Some(DeviceNumber::new(Major::TTY_MAJOR, 0)),
         ),
+        TtyType::Tty,
     );
 
     let console = TtyDevice::new(
-        "console",
+        "console".to_string(),
         IdTable::new(
             String::from("console"),
             Some(DeviceNumber::new(Major::TTYAUX_MAJOR, 1)),
         ),
+        TtyType::Tty,
     );
 
     // 注册tty设备
@@ -536,8 +594,8 @@ pub fn tty_init() -> Result<(), SystemError> {
     // 将这两个设备注册到devfs,TODO:这里console设备应该与tty在一个设备group里面
     device_register(tty.clone())?;
     device_register(console.clone())?;
-    devfs_register(tty.name, tty)?;
-    devfs_register(console.name, console)?;
+    devfs_register(&tty.name.clone(), tty)?;
+    devfs_register(&console.name.clone(), console)?;
 
     serial_init()?;
 

+ 96 - 42
kernel/src/driver/tty/tty_driver.rs

@@ -1,8 +1,8 @@
-use core::{fmt::Debug, sync::atomic::Ordering};
+use core::fmt::Debug;
 
 use alloc::{
     string::{String, ToString},
-    sync::Arc,
+    sync::{Arc, Weak},
     vec::Vec,
 };
 use hashbrown::HashMap;
@@ -20,38 +20,46 @@ use crate::{
         },
         tty::tty_port::TtyPortState,
     },
-    libs::spinlock::SpinLock,
+    libs::{
+        rwlock::RwLock,
+        spinlock::{SpinLock, SpinLockGuard},
+    },
 };
 
 use super::{
     termios::Termios,
     tty_core::{TtyCore, TtyCoreData},
     tty_ldisc::TtyLdiscManager,
-    tty_port::TTY_PORTS,
-    virtual_terminal::virtual_console::CURRENT_VCNUM,
+    tty_port::{DefaultTtyPort, TtyPort},
 };
 
 lazy_static! {
-    static ref TTY_DRIVERS: SpinLock<Vec<Arc<TtyDriver>>> = SpinLock::new(Vec::new());
+    pub static ref TTY_DRIVERS: SpinLock<Vec<Arc<TtyDriver>>> = SpinLock::new(Vec::new());
+}
+
+pub enum TtyDriverPrivateData {
+    Unused,
+    /// true表示主设备 false表示从设备
+    Pty(bool),
 }
 
 pub struct TtyDriverManager;
 impl TtyDriverManager {
     pub fn lookup_tty_driver(dev_num: DeviceNumber) -> Option<(usize, Arc<TtyDriver>)> {
         let drivers_guard = TTY_DRIVERS.lock();
-        for (index, driver) in drivers_guard.iter().enumerate() {
+        for driver in drivers_guard.iter() {
             let base = DeviceNumber::new(driver.major, driver.minor_start);
             if dev_num < base || dev_num.data() > base.data() + driver.device_count {
                 continue;
             }
-            return Some((index, driver.clone()));
+            return Some(((dev_num.data() - base.data()) as usize, driver.clone()));
         }
 
         None
     }
 
     /// ## 注册驱动
-    pub fn tty_register_driver(mut driver: TtyDriver) -> Result<(), SystemError> {
+    pub fn tty_register_driver(mut driver: TtyDriver) -> Result<Arc<TtyDriver>, SystemError> {
         // 查看是否注册设备号
         if driver.major == Major::UNNAMED_MAJOR {
             let dev_num = CharDevOps::alloc_chardev_region(
@@ -69,11 +77,12 @@ impl TtyDriverManager {
         driver.flags |= TtyDriverFlag::TTY_DRIVER_INSTALLED;
 
         // 加入全局TtyDriver表
-        TTY_DRIVERS.lock().push(Arc::new(driver));
+        let driver = Arc::new(driver);
+        TTY_DRIVERS.lock().push(driver.clone());
 
         // TODO: 加入procfs?
 
-        Ok(())
+        Ok(driver)
     }
 }
 
@@ -104,11 +113,13 @@ pub struct TtyDriver {
     /// 驱动程序标志
     flags: TtyDriverFlag,
     /// pty链接此driver的入口
-    pty: Option<Arc<TtyDriver>>,
+    other_pty_driver: RwLock<Weak<TtyDriver>>,
     /// 具体类型的tty驱动方法
     driver_funcs: Arc<dyn TtyOperation>,
     /// 管理的tty设备列表
     ttys: SpinLock<HashMap<usize, Arc<TtyCore>>>,
+    /// 管理的端口列表
+    ports: RwLock<Vec<Arc<dyn TtyPort>>>,
     // procfs入口?
 }
 
@@ -124,6 +135,10 @@ impl TtyDriver {
         default_termios: Termios,
         driver_funcs: Arc<dyn TtyOperation>,
     ) -> Self {
+        let mut ports: Vec<Arc<dyn TtyPort>> = Vec::with_capacity(count as usize);
+        for _ in 0..count {
+            ports.push(Arc::new(DefaultTtyPort::new()))
+        }
         TtyDriver {
             driver_name: Default::default(),
             name: node_name,
@@ -135,10 +150,11 @@ impl TtyDriver {
             tty_driver_sub_type: Default::default(),
             init_termios: default_termios,
             flags: TtyDriverFlag::empty(),
-            pty: Default::default(),
+            other_pty_driver: Default::default(),
             driver_funcs,
             ttys: SpinLock::new(HashMap::new()),
             saved_termios: Vec::with_capacity(count as usize),
+            ports: RwLock::new(ports),
         }
     }
 
@@ -162,34 +178,65 @@ impl TtyDriver {
         self.driver_funcs.clone()
     }
 
+    #[inline]
+    pub fn init_termios(&self) -> Termios {
+        self.init_termios
+    }
+
+    #[inline]
+    pub fn init_termios_mut(&mut self) -> &mut Termios {
+        &mut self.init_termios
+    }
+
+    #[inline]
+    pub fn other_pty_driver(&self) -> Option<Arc<TtyDriver>> {
+        self.other_pty_driver.read().upgrade()
+    }
+
+    pub fn set_other_pty_driver(&self, driver: Weak<TtyDriver>) {
+        *self.other_pty_driver.write() = driver
+    }
+
+    #[inline]
+    pub fn set_subtype(&mut self, tp: TtyDriverSubType) {
+        self.tty_driver_sub_type = tp;
+    }
+
+    #[inline]
+    pub fn ttys(&self) -> SpinLockGuard<HashMap<usize, Arc<TtyCore>>> {
+        self.ttys.lock()
+    }
+
+    #[inline]
+    pub fn saved_termios(&self) -> &Vec<Termios> {
+        &self.saved_termios
+    }
+
     #[inline]
     pub fn flags(&self) -> TtyDriverFlag {
         self.flags
     }
 
     #[inline]
-    fn lockup_tty(&self, index: usize) -> Option<Arc<TtyCore>> {
-        let device_guard = self.ttys.lock();
-        return device_guard.get(&index).cloned();
+    fn lookup_tty(&self, index: usize) -> Option<Arc<TtyCore>> {
+        let ret = self
+            .driver_funcs()
+            .lookup(index, TtyDriverPrivateData::Unused);
+        if let Err(SystemError::ENOSYS) = ret {
+            let device_guard = self.ttys.lock();
+            return device_guard.get(&index).cloned();
+        }
+        ret.ok()
     }
 
     fn standard_install(&self, tty_core: Arc<TtyCore>) -> Result<(), SystemError> {
         let tty = tty_core.core();
-        let tty_index = tty.index();
-        // 初始化termios
-        if !self.flags.contains(TtyDriverFlag::TTY_DRIVER_RESET_TERMIOS) {
-            // 先查看是否有已经保存的termios
-            if let Some(t) = self.saved_termios.get(tty_index) {
-                let mut termios = *t;
-                termios.line = self.init_termios.line;
-                tty.set_termios(termios);
-            }
-        }
+        tty.init_termios();
         // TODO:设置termios波特率?
 
         tty.add_count();
 
-        self.ttys.lock().insert(tty_index, tty_core);
+        self.ttys.lock().insert(tty.index(), tty_core);
 
         Ok(())
     }
@@ -210,7 +257,10 @@ impl TtyDriver {
         Ok(())
     }
 
-    fn init_tty_device(driver: Arc<TtyDriver>, index: usize) -> Result<Arc<TtyCore>, SystemError> {
+    pub fn init_tty_device(
+        driver: Arc<TtyDriver>,
+        index: usize,
+    ) -> Result<Arc<TtyCore>, SystemError> {
         let tty = TtyCore::new(driver.clone(), index);
 
         Self::driver_install_tty(driver.clone(), tty.clone())?;
@@ -218,8 +268,9 @@ impl TtyDriver {
         let core = tty.core();
 
         if core.port().is_none() {
-            TTY_PORTS[core.index()].setup_tty(Arc::downgrade(&tty));
-            tty.set_port(TTY_PORTS[core.index()].clone());
+            let ports = driver.ports.read();
+            ports[core.index()].setup_internal_tty(Arc::downgrade(&tty));
+            tty.set_port(ports[core.index()].clone());
         }
 
         TtyLdiscManager::ldisc_setup(tty.clone(), None)?;
@@ -228,11 +279,8 @@ impl TtyDriver {
     }
 
     /// ## 通过设备号找到对应驱动并且初始化Tty
-    pub fn open_tty(dev_num: DeviceNumber) -> Result<Arc<TtyCore>, SystemError> {
-        let (index, driver) =
-            TtyDriverManager::lookup_tty_driver(dev_num).ok_or(SystemError::ENODEV)?;
-
-        let tty = match driver.lockup_tty(index) {
+    pub fn open_tty(index: usize, driver: Arc<TtyDriver>) -> Result<Arc<TtyCore>, SystemError> {
+        let tty = match driver.lookup_tty(index) {
             Some(tty) => {
                 // TODO: 暂时这么写,因为还没写TtyPort
                 if tty.core().port().is_none() {
@@ -247,8 +295,6 @@ impl TtyDriver {
             None => Self::init_tty_device(driver, index)?,
         };
 
-        CURRENT_VCNUM.store(index as isize, Ordering::SeqCst);
-
         return Ok(tty);
     }
 
@@ -259,10 +305,6 @@ impl TtyDriver {
     pub fn tty_driver_sub_type(&self) -> TtyDriverSubType {
         self.tty_driver_sub_type
     }
-
-    pub fn init_termios(&self) -> Termios {
-        self.init_termios
-    }
 }
 
 impl KObject for TtyDriver {
@@ -368,7 +410,9 @@ pub trait TtyOperation: Sync + Send + Debug {
 
     fn flush_chars(&self, tty: &TtyCoreData);
 
-    fn put_char(&self, tty: &TtyCoreData, ch: u8) -> Result<(), SystemError>;
+    fn put_char(&self, _tty: &TtyCoreData, _ch: u8) -> Result<(), SystemError> {
+        Err(SystemError::ENOSYS)
+    }
 
     fn start(&self, _tty: &TtyCoreData) -> Result<(), SystemError> {
         Err(SystemError::ENOSYS)
@@ -391,6 +435,16 @@ pub trait TtyOperation: Sync + Send + Debug {
     fn set_termios(&self, _tty: Arc<TtyCore>, _old_termios: Termios) -> Result<(), SystemError> {
         Err(SystemError::ENOSYS)
     }
+
+    fn lookup(
+        &self,
+        _index: usize,
+        _priv_data: TtyDriverPrivateData,
+    ) -> Result<Arc<TtyCore>, SystemError> {
+        Err(SystemError::ENOSYS)
+    }
+
+    fn close(&self, tty: Arc<TtyCore>) -> Result<(), SystemError>;
 }
 
 #[allow(dead_code)]

+ 12 - 3
kernel/src/driver/tty/tty_ldisc/mod.rs

@@ -7,7 +7,7 @@ use crate::filesystem::vfs::file::FileMode;
 
 use super::{
     termios::Termios,
-    tty_core::{TtyCore, TtyCoreData},
+    tty_core::{TtyCore, TtyCoreData, TtyFlag},
 };
 
 pub mod ntty;
@@ -99,7 +99,7 @@ impl TtyLdiscManager {
     /// ### 参数
     /// - tty:需要设置的tty
     /// - o_tty: other tty 用于pty pair
-    pub fn ldisc_setup(tty: Arc<TtyCore>, _o_tty: Option<Arc<TtyCore>>) -> Result<(), SystemError> {
+    pub fn ldisc_setup(tty: Arc<TtyCore>, o_tty: Option<Arc<TtyCore>>) -> Result<(), SystemError> {
         let ld = tty.ldisc();
 
         let ret = ld.open(tty);
@@ -109,7 +109,16 @@ impl TtyLdiscManager {
             }
         }
 
-        // TODO: 处理PTY
+        // 处理PTY
+        if let Some(o_tty) = o_tty {
+            let ld = o_tty.ldisc();
+
+            let ret: Result<(), SystemError> = ld.open(o_tty.clone());
+            if ret.is_err() {
+                o_tty.core().flags_write().remove(TtyFlag::LDISC_OPEN);
+                let _ = ld.close(o_tty.clone());
+            }
+        }
 
         Ok(())
     }

+ 52 - 4
kernel/src/driver/tty/tty_ldisc/ntty.rs

@@ -10,7 +10,7 @@ use crate::{
     arch::ipc::signal::Signal,
     driver::tty::{
         termios::{ControlCharIndex, InputMode, LocalMode, OutputMode, Termios},
-        tty_core::{EchoOperation, TtyCore, TtyCoreData, TtyFlag, TtyIoctlCmd},
+        tty_core::{EchoOperation, TtyCore, TtyCoreData, TtyFlag, TtyIoctlCmd, TtyPacketStatus},
         tty_driver::{TtyDriverFlag, TtyOperation},
         tty_job_control::TtyJobCtrlManager,
     },
@@ -812,6 +812,10 @@ impl NTtyData {
             self.read_flags.set_all(false);
             self.pushing = false;
             self.lookahead_count = 0;
+
+            if tty.core().link().is_some() {
+                self.packet_mode_flush(tty.core());
+            }
         }
     }
 
@@ -1521,6 +1525,17 @@ impl NTtyData {
         }
         Ok(1)
     }
+
+    fn packet_mode_flush(&self, tty: &TtyCoreData) {
+        let link = tty.link().unwrap();
+        if link.core().contorl_info_irqsave().packet {
+            tty.contorl_info_irqsave()
+                .pktstatus
+                .insert(TtyPacketStatus::TIOCPKT_FLUSHREAD);
+
+            link.core().read_wq().wakeup_all();
+        }
+    }
 }
 
 impl TtyLineDiscipline for NTtyLinediscipline {
@@ -1551,7 +1566,10 @@ impl TtyLineDiscipline for NTtyLinediscipline {
         ldata.lookahead_count = 0;
 
         // todo: kick worker?
-        // todo: packet mode?
+        // packet mode?
+        if core.link().is_some() {
+            ldata.packet_mode_flush(core);
+        }
 
         Ok(())
     }
@@ -1618,12 +1636,31 @@ impl TtyLineDiscipline for NTtyLinediscipline {
             }
         }
 
+        let packet = core.contorl_info_irqsave().packet;
         let mut ret: Result<usize, SystemError> = Ok(0);
         // 记录读取前 的tail
         let tail = ldata.read_tail;
         drop(ldata);
         while nr != 0 {
             // todo: 处理packet模式
+            if packet {
+                let link = core.link().unwrap();
+                let link = link.core();
+                let mut ctrl = link.contorl_info_irqsave();
+                if !ctrl.pktstatus.is_empty() {
+                    if offset != 0 {
+                        break;
+                    }
+                    let cs = ctrl.pktstatus;
+                    ctrl.pktstatus = TtyPacketStatus::empty();
+
+                    buf[offset] = cs.bits();
+                    offset += 1;
+                    // nr -= 1;
+                    break;
+                }
+            }
+
             let mut ldata = self.disc_data();
 
             let core = tty.core();
@@ -1676,7 +1713,11 @@ impl TtyLineDiscipline for NTtyLinediscipline {
             } else {
                 // 非标准模式
                 // todo: 处理packet模式
-
+                if packet && offset == 0 {
+                    buf[offset] = TtyPacketStatus::TIOCPKT_DATA.bits();
+                    offset += 1;
+                    nr -= 1;
+                }
                 // 拷贝数据
                 if ldata.copy_from_read_buf(core.termios(), buf, &mut nr, &mut offset)?
                     && offset >= minimum
@@ -2025,7 +2066,14 @@ impl TtyLineDiscipline for NTtyLinediscipline {
 
         if core.contorl_info_irqsave().packet {
             let link = core.link();
-            if link.is_some() && link.unwrap().core().contorl_info_irqsave().pktstatus != 0 {
+            if link.is_some()
+                && !link
+                    .unwrap()
+                    .core()
+                    .contorl_info_irqsave()
+                    .pktstatus
+                    .is_empty()
+            {
                 event.insert(
                     EPollEventType::EPOLLPRI
                         | EPollEventType::EPOLLIN

+ 28 - 26
kernel/src/driver/tty/tty_port.rs

@@ -1,36 +1,29 @@
 use core::{fmt::Debug, sync::atomic::Ordering};
 
-use alloc::{
-    sync::{Arc, Weak},
-    vec::Vec,
-};
+use alloc::sync::{Arc, Weak};
 use kdepends::thingbuf::mpsc;
 use system_error::SystemError;
 
-use crate::{
-    driver::tty::virtual_terminal::MAX_NR_CONSOLES,
-    libs::spinlock::{SpinLock, SpinLockGuard},
-};
+use crate::libs::spinlock::{SpinLock, SpinLockGuard};
 
-use super::{tty_core::TtyCore, virtual_terminal::virtual_console::CURRENT_VCNUM};
+use super::{
+    tty_core::TtyCore,
+    virtual_terminal::{virtual_console::CURRENT_VCNUM, VIRT_CONSOLES},
+};
 
 const TTY_PORT_BUFSIZE: usize = 4096;
 
-lazy_static! {
-    pub static ref TTY_PORTS: Vec<Arc<dyn TtyPort>> = {
-        let mut v: Vec<Arc<dyn TtyPort>> = Vec::with_capacity(MAX_NR_CONSOLES as usize);
-        for _ in 0..MAX_NR_CONSOLES as usize {
-            v.push(Arc::new(DefaultTtyPort::new()))
-        }
-
-        v
-    };
-}
-
 /// 获取当前tty port
 #[inline]
 pub fn current_tty_port() -> Arc<dyn TtyPort> {
-    TTY_PORTS[CURRENT_VCNUM.load(Ordering::SeqCst) as usize].clone()
+    VIRT_CONSOLES[CURRENT_VCNUM.load(Ordering::SeqCst) as usize]
+        .lock_irqsave()
+        .port()
+}
+
+#[inline]
+pub fn tty_port(index: usize) -> Arc<dyn TtyPort> {
+    VIRT_CONSOLES[index].lock_irqsave().port()
 }
 
 #[allow(dead_code)]
@@ -41,6 +34,14 @@ pub struct TtyPortData {
     sender: mpsc::Sender<u8>,
     receiver: mpsc::Receiver<u8>,
     tty: Weak<TtyCore>,
+    /// 内部tty,即与port直接相连的
+    internal_tty: Weak<TtyCore>,
+}
+
+impl Default for TtyPortData {
+    fn default() -> Self {
+        Self::new()
+    }
 }
 
 impl TtyPortData {
@@ -52,11 +53,12 @@ impl TtyPortData {
             sender,
             receiver,
             tty: Weak::new(),
+            internal_tty: Weak::new(),
         }
     }
 
-    pub fn tty(&self) -> Option<Arc<TtyCore>> {
-        self.tty.upgrade()
+    pub fn internal_tty(&self) -> Option<Arc<TtyCore>> {
+        self.internal_tty.upgrade()
     }
 }
 
@@ -80,13 +82,13 @@ pub trait TtyPort: Sync + Send + Debug {
     }
 
     /// 为port设置tty
-    fn setup_tty(&self, tty: Weak<TtyCore>) {
-        self.port_data().tty = tty;
+    fn setup_internal_tty(&self, tty: Weak<TtyCore>) {
+        self.port_data().internal_tty = tty;
     }
 
     /// 作为客户端的tty ports接收数据
     fn receive_buf(&self, buf: &[u8], _flags: &[u8], count: usize) -> Result<usize, SystemError> {
-        let tty = self.port_data().tty.upgrade().unwrap();
+        let tty = self.port_data().internal_tty().unwrap();
 
         let ld = tty.ldisc();
 

+ 19 - 3
kernel/src/driver/tty/virtual_terminal/mod.rs

@@ -1,6 +1,10 @@
 use core::sync::atomic::Ordering;
 
-use alloc::{string::String, sync::Arc, vec::Vec};
+use alloc::{
+    string::{String, ToString},
+    sync::Arc,
+    vec::Vec,
+};
 use system_error::SystemError;
 
 use crate::{
@@ -21,7 +25,7 @@ use super::{
     console::ConsoleSwitch,
     termios::{InputMode, TTY_STD_TERMIOS},
     tty_core::{TtyCore, TtyCoreData},
-    tty_device::TtyDevice,
+    tty_device::{TtyDevice, TtyType},
     tty_driver::{TtyDriver, TtyDriverManager, TtyDriverType, TtyOperation},
 };
 
@@ -191,8 +195,12 @@ impl TtyOperation for TtyConsoleDriverInner {
             tty_core.termios_write().input_mode.remove(InputMode::IUTF8);
         }
 
+        // 设置tty的端口为vc端口
+        vc_data.port().setup_internal_tty(Arc::downgrade(&tty));
+        tty.set_port(vc_data.port());
         // 加入sysfs?
 
+        CURRENT_VCNUM.store(tty_core.index() as isize, Ordering::SeqCst);
         Ok(())
     }
 
@@ -207,6 +215,9 @@ impl TtyOperation for TtyConsoleDriverInner {
     /// 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/tty/vt/vt.c#2894
     #[inline(never)]
     fn write(&self, tty: &TtyCoreData, buf: &[u8], nr: usize) -> Result<usize, SystemError> {
+        // if String::from_utf8_lossy(buf) == "Hello world!\n" {
+        //     loop {}
+        // }
         let ret = self.do_write(tty, buf, nr);
         self.flush_chars(tty);
         ret
@@ -227,6 +238,10 @@ impl TtyOperation for TtyConsoleDriverInner {
         // TODO
         Err(SystemError::ENOIOCTLCMD)
     }
+
+    fn close(&self, _tty: Arc<TtyCore>) -> Result<(), SystemError> {
+        Ok(())
+    }
 }
 
 #[derive(Debug, Clone)]
@@ -264,11 +279,12 @@ pub struct DrawRegion {
 pub fn vty_init() -> Result<(), SystemError> {
     // 注册虚拟终端设备并将虚拟终端设备加入到文件系统
     let vc0 = TtyDevice::new(
-        "vc0",
+        "vc0".to_string(),
         IdTable::new(
             String::from("vc0"),
             Some(DeviceNumber::new(Major::TTY_MAJOR, 0)),
         ),
+        TtyType::Tty,
     );
     // 注册tty设备
     // CharDevOps::cdev_add(

+ 14 - 1
kernel/src/driver/tty/virtual_terminal/virtual_console.rs

@@ -9,7 +9,11 @@ use bitmap::{traits::BitMapOps, StaticBitmap};
 use crate::{
     driver::{
         serial::serial8250::send_to_default_serial8250_port,
-        tty::{console::ConsoleSwitch, ConsoleFont, KDMode},
+        tty::{
+            console::ConsoleSwitch,
+            tty_port::{DefaultTtyPort, TtyPort},
+            ConsoleFont, KDMode,
+        },
     },
     libs::{font::FontDesc, rwlock::RwLock},
     process::Pid,
@@ -142,6 +146,9 @@ pub struct VirtualConsoleData {
 
     /// 对应的Console Driver funcs
     driver_funcs: Option<Weak<dyn ConsoleSwitch>>,
+
+    /// 对应端口
+    port: Arc<dyn TtyPort>,
 }
 
 impl VirtualConsoleData {
@@ -204,9 +211,15 @@ impl VirtualConsoleData {
             driver_funcs: None,
             cursor_type: VcCursor::empty(),
             num,
+            port: Arc::new(DefaultTtyPort::new()),
         }
     }
 
+    #[inline]
+    pub fn port(&self) -> Arc<dyn TtyPort> {
+        self.port.clone()
+    }
+
     pub(super) fn init(&mut self, rows: Option<usize>, cols: Option<usize>, clear: bool) {
         if let Some(rows) = rows {
             self.rows = rows;

+ 8 - 4
kernel/src/driver/video/fbdev/base/fbmem.rs

@@ -383,11 +383,15 @@ impl DeviceINode for FbDevice {
 }
 
 impl IndexNode for FbDevice {
-    fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> {
+    fn open(
+        &self,
+        _data: SpinLockGuard<FilePrivateData>,
+        _mode: &FileMode,
+    ) -> Result<(), SystemError> {
         Ok(())
     }
 
-    fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
+    fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
         Ok(())
     }
     fn read_at(
@@ -395,7 +399,7 @@ impl IndexNode for FbDevice {
         offset: usize,
         len: usize,
         buf: &mut [u8],
-        _data: &mut FilePrivateData,
+        _data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         let fb = self.inner.lock().fb.upgrade().unwrap();
         return fb.fb_read(&mut buf[0..len], offset);
@@ -406,7 +410,7 @@ impl IndexNode for FbDevice {
         offset: usize,
         len: usize,
         buf: &[u8],
-        _data: &mut FilePrivateData,
+        _data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         let fb = self.inner.lock().fb.upgrade().unwrap();
         return fb.fb_write(&buf[0..len], offset);

+ 8 - 4
kernel/src/filesystem/devfs/mod.rs

@@ -147,6 +147,10 @@ impl DevFS {
                 if name.starts_with("tty") && name.len() > 3 {
                     dev_root_inode.add_dev(name, device.clone())?;
                 }
+                // ptmx设备
+                if name == "ptmx" {
+                    dev_root_inode.add_dev(name, device.clone())?;
+                }
                 device.set_fs(dev_char_inode.0.lock().fs.clone());
             }
             FileType::BlockDevice => {
@@ -388,13 +392,13 @@ impl IndexNode for LockedDevFSInode {
 
     fn open(
         &self,
-        _data: &mut super::vfs::FilePrivateData,
+        _data: SpinLockGuard<FilePrivateData>,
         _mode: &FileMode,
     ) -> Result<(), SystemError> {
         return Ok(());
     }
 
-    fn close(&self, _data: &mut super::vfs::FilePrivateData) -> Result<(), SystemError> {
+    fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
         return Ok(());
     }
 
@@ -523,7 +527,7 @@ impl IndexNode for LockedDevFSInode {
         _offset: usize,
         _len: usize,
         _buf: &mut [u8],
-        _data: &mut super::vfs::file::FilePrivateData,
+        _data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         kerror!("DevFS: read_at is not supported!");
         Err(SystemError::EOPNOTSUPP_OR_ENOTSUP)
@@ -535,7 +539,7 @@ impl IndexNode for LockedDevFSInode {
         _offset: usize,
         _len: usize,
         _buf: &[u8],
-        _data: &mut super::vfs::file::FilePrivateData,
+        _data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         Err(SystemError::EOPNOTSUPP_OR_ENOTSUP)
     }

+ 9 - 4
kernel/src/filesystem/devfs/null_dev.rs

@@ -4,6 +4,7 @@ use crate::filesystem::vfs::syscall::ModeType;
 use crate::filesystem::vfs::{
     core::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata,
 };
+use crate::libs::spinlock::SpinLockGuard;
 use crate::{libs::spinlock::SpinLock, time::TimeSpec};
 use alloc::{
     string::String,
@@ -71,11 +72,15 @@ impl IndexNode for LockedNullInode {
         self
     }
 
-    fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> {
+    fn open(
+        &self,
+        _data: SpinLockGuard<FilePrivateData>,
+        _mode: &FileMode,
+    ) -> Result<(), SystemError> {
         return Ok(());
     }
 
-    fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
+    fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
         return Ok(());
     }
 
@@ -109,7 +114,7 @@ impl IndexNode for LockedNullInode {
         _offset: usize,
         _len: usize,
         _buf: &mut [u8],
-        _data: &mut FilePrivateData,
+        _data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         return Ok(0);
     }
@@ -120,7 +125,7 @@ impl IndexNode for LockedNullInode {
         _offset: usize,
         len: usize,
         buf: &[u8],
-        _data: &mut FilePrivateData,
+        _data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         if buf.len() < len {
             return Err(SystemError::EINVAL);

+ 9 - 4
kernel/src/filesystem/devfs/zero_dev.rs

@@ -4,6 +4,7 @@ use crate::filesystem::vfs::syscall::ModeType;
 use crate::filesystem::vfs::{
     core::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata,
 };
+use crate::libs::spinlock::SpinLockGuard;
 use crate::{libs::spinlock::SpinLock, time::TimeSpec};
 use alloc::{
     string::String,
@@ -71,11 +72,15 @@ impl IndexNode for LockedZeroInode {
         self
     }
 
-    fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> {
+    fn open(
+        &self,
+        _data: SpinLockGuard<FilePrivateData>,
+        _mode: &FileMode,
+    ) -> Result<(), SystemError> {
         return Ok(());
     }
 
-    fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
+    fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
         return Ok(());
     }
 
@@ -109,7 +114,7 @@ impl IndexNode for LockedZeroInode {
         _offset: usize,
         len: usize,
         buf: &mut [u8],
-        _data: &mut FilePrivateData,
+        _data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         if buf.len() < len {
             return Err(SystemError::EINVAL);
@@ -128,7 +133,7 @@ impl IndexNode for LockedZeroInode {
         _offset: usize,
         len: usize,
         buf: &[u8],
-        _data: &mut FilePrivateData,
+        _data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         if buf.len() < len {
             return Err(SystemError::EINVAL);

+ 290 - 0
kernel/src/filesystem/devpts/mod.rs

@@ -0,0 +1,290 @@
+use core::sync::atomic::{AtomicU32, Ordering};
+
+use alloc::{
+    collections::BTreeMap,
+    string::{String, ToString},
+    sync::{Arc, Weak},
+    vec::Vec,
+};
+use ida::IdAllocator;
+use system_error::SystemError;
+use unified_init::macros::unified_init;
+
+use crate::{
+    driver::{
+        base::device::{
+            device_number::{DeviceNumber, Major},
+            IdTable,
+        },
+        tty::{
+            pty::unix98pty::NR_UNIX98_PTY_MAX,
+            tty_device::{PtyType, TtyDevice, TtyType},
+        },
+    },
+    filesystem::vfs::{syscall::ModeType, FileType, ROOT_INODE},
+    init::initcall::INITCALL_FS,
+    libs::spinlock::{SpinLock, SpinLockGuard},
+    time::TimeSpec,
+};
+
+use super::vfs::{
+    core::generate_inode_id, FilePrivateData, FileSystem, FsInfo, IndexNode, Metadata,
+};
+
+const DEV_PTYFS_MAX_NAMELEN: usize = 16;
+
+#[allow(dead_code)]
+const PTY_NR_LIMIT: usize = 4096;
+
+#[derive(Debug)]
+pub struct DevPtsFs {
+    /// 根节点
+    root_inode: Arc<LockedDevPtsFSInode>,
+    pts_ida: IdAllocator,
+    pts_count: AtomicU32,
+}
+
+impl DevPtsFs {
+    pub fn new() -> Arc<Self> {
+        let root_inode = Arc::new(LockedDevPtsFSInode::new());
+        let ret = Arc::new(Self {
+            root_inode,
+            pts_ida: IdAllocator::new(1, NR_UNIX98_PTY_MAX as usize),
+            pts_count: AtomicU32::new(0),
+        });
+
+        ret.root_inode.set_fs(Arc::downgrade(&ret));
+
+        ret
+    }
+
+    pub fn alloc_index(&self) -> Result<usize, SystemError> {
+        self.pts_ida.alloc().ok_or(SystemError::ENOSPC)
+    }
+}
+
+impl FileSystem for DevPtsFs {
+    fn root_inode(&self) -> Arc<dyn IndexNode> {
+        self.root_inode.clone()
+    }
+
+    fn info(&self) -> super::vfs::FsInfo {
+        return FsInfo {
+            blk_dev_id: 0,
+            max_name_len: DEV_PTYFS_MAX_NAMELEN,
+        };
+    }
+
+    fn as_any_ref(&self) -> &dyn core::any::Any {
+        self
+    }
+
+    fn name(&self) -> &str {
+        "devpts"
+    }
+
+    fn super_block(&self) -> super::vfs::SuperBlock {
+        todo!()
+    }
+}
+
+#[derive(Debug)]
+pub struct LockedDevPtsFSInode {
+    inner: SpinLock<PtsDevInode>,
+}
+
+impl LockedDevPtsFSInode {
+    pub fn new() -> Self {
+        Self {
+            inner: SpinLock::new(PtsDevInode {
+                fs: Weak::new(),
+                children: Some(BTreeMap::new()),
+                metadata: Metadata {
+                    dev_id: 0,
+                    inode_id: generate_inode_id(),
+                    size: 0,
+                    blk_size: 0,
+                    blocks: 0,
+                    atime: TimeSpec::default(),
+                    mtime: TimeSpec::default(),
+                    ctime: TimeSpec::default(),
+                    file_type: FileType::Dir,
+                    mode: ModeType::from_bits_truncate(0x777),
+                    nlinks: 1,
+                    uid: 0,
+                    gid: 0,
+                    raw_dev: DeviceNumber::default(),
+                },
+            }),
+        }
+    }
+
+    pub fn set_fs(&self, fs: Weak<DevPtsFs>) {
+        self.inner.lock().fs = fs;
+    }
+}
+
+#[derive(Debug)]
+pub struct PtsDevInode {
+    fs: Weak<DevPtsFs>,
+    children: Option<BTreeMap<String, Arc<TtyDevice>>>,
+    metadata: Metadata,
+}
+
+impl PtsDevInode {
+    pub fn children_unchecked(&self) -> &BTreeMap<String, Arc<TtyDevice>> {
+        self.children.as_ref().unwrap()
+    }
+
+    pub fn children_unchecked_mut(&mut self) -> &mut BTreeMap<String, Arc<TtyDevice>> {
+        self.children.as_mut().unwrap()
+    }
+}
+
+impl IndexNode for LockedDevPtsFSInode {
+    fn open(
+        &self,
+        _data: SpinLockGuard<FilePrivateData>,
+        _mode: &super::vfs::file::FileMode,
+    ) -> Result<(), SystemError> {
+        Ok(())
+    }
+
+    fn metadata(&self) -> Result<super::vfs::Metadata, SystemError> {
+        let inode = self.inner.lock();
+        let metadata = inode.metadata.clone();
+
+        return Ok(metadata);
+    }
+
+    fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
+        // TODO: 回收
+        Ok(())
+    }
+
+    fn read_at(
+        &self,
+        _offset: usize,
+        _len: usize,
+        _buf: &mut [u8],
+        _data: SpinLockGuard<FilePrivateData>,
+    ) -> Result<usize, system_error::SystemError> {
+        todo!()
+    }
+
+    fn write_at(
+        &self,
+        _offset: usize,
+        _len: usize,
+        _buf: &[u8],
+        _data: SpinLockGuard<FilePrivateData>,
+    ) -> Result<usize, system_error::SystemError> {
+        todo!()
+    }
+
+    fn fs(&self) -> alloc::sync::Arc<dyn super::vfs::FileSystem> {
+        self.inner.lock().fs.upgrade().unwrap()
+    }
+
+    fn as_any_ref(&self) -> &dyn core::any::Any {
+        todo!()
+    }
+
+    fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, system_error::SystemError> {
+        let info = self.metadata()?;
+        if info.file_type != FileType::Dir {
+            return Err(SystemError::ENOTDIR);
+        }
+
+        let mut keys: Vec<String> = Vec::new();
+        keys.push(String::from("."));
+        keys.push(String::from(".."));
+        keys.append(
+            &mut self
+                .inner
+                .lock()
+                .children_unchecked()
+                .keys()
+                .cloned()
+                .collect(),
+        );
+
+        return Ok(keys);
+    }
+
+    fn create_with_data(
+        &self,
+        name: &str,
+        file_type: FileType,
+        _mode: super::vfs::syscall::ModeType,
+        _data: usize,
+    ) -> Result<Arc<dyn IndexNode>, SystemError> {
+        if file_type != FileType::CharDevice {
+            return Err(SystemError::ENOSYS);
+        }
+
+        let mut guard = self.inner.lock();
+
+        if guard.children_unchecked_mut().contains_key(name) {
+            return Err(SystemError::EEXIST);
+        }
+
+        let fs = guard.fs.upgrade().unwrap();
+
+        let result = TtyDevice::new(
+            name.to_string(),
+            IdTable::new(name.to_string(), None),
+            TtyType::Pty(PtyType::Pts),
+        );
+
+        let mut metadata = result.metadata()?;
+
+        metadata.mode.insert(ModeType::S_IFCHR);
+        metadata.raw_dev =
+            DeviceNumber::new(Major::UNIX98_PTY_SLAVE_MAJOR, name.parse::<u32>().unwrap());
+
+        result.set_metadata(&metadata)?;
+
+        guard
+            .children_unchecked_mut()
+            .insert(name.to_string(), result.clone());
+
+        fs.pts_count.fetch_add(1, Ordering::SeqCst);
+
+        Ok(result)
+    }
+
+    fn find(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError> {
+        let guard = self.inner.lock();
+
+        if let Some(dev) = guard.children_unchecked().get(name) {
+            Ok(dev.clone() as Arc<dyn IndexNode>)
+        } else {
+            Err(SystemError::ENOENT)
+        }
+    }
+
+    fn unlink(&self, name: &str) -> Result<(), SystemError> {
+        let mut guard = self.inner.lock();
+        guard.children_unchecked_mut().remove(name);
+        Ok(())
+    }
+}
+
+#[unified_init(INITCALL_FS)]
+#[inline(never)]
+pub fn devpts_init() -> Result<(), SystemError> {
+    let dev_inode = ROOT_INODE().find("dev")?;
+
+    let pts_inode = dev_inode.create("pts", FileType::Dir, ModeType::from_bits_truncate(0o755))?;
+
+    // 创建 devptsfs 实例
+    let ptsfs: Arc<DevPtsFs> = DevPtsFs::new();
+
+    // let mountfs = dev_inode.mount(ptsfs).expect("Failed to mount DevPtsFS");
+
+    pts_inode.mount(ptsfs).expect("Failed to mount DevPtsFS");
+    kinfo!("DevPtsFs mounted.");
+
+    Ok(())
+}

+ 8 - 4
kernel/src/filesystem/fat/fs.rs

@@ -1369,7 +1369,7 @@ impl IndexNode for LockedFATInode {
         offset: usize,
         len: usize,
         buf: &mut [u8],
-        _data: &mut FilePrivateData,
+        _data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         let mut guard: SpinLockGuard<FATInode> = self.0.lock();
         match &guard.inode_type {
@@ -1397,7 +1397,7 @@ impl IndexNode for LockedFATInode {
         offset: usize,
         len: usize,
         buf: &[u8],
-        _data: &mut FilePrivateData,
+        _data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         let mut guard: SpinLockGuard<FATInode> = self.0.lock();
         let fs: &Arc<FATFileSystem> = &guard.fs.upgrade().unwrap();
@@ -1566,11 +1566,15 @@ impl IndexNode for LockedFATInode {
         return Ok(target);
     }
 
-    fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> {
+    fn open(
+        &self,
+        _data: SpinLockGuard<FilePrivateData>,
+        _mode: &FileMode,
+    ) -> Result<(), SystemError> {
         return Ok(());
     }
 
-    fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
+    fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
         return Ok(());
     }
 

+ 8 - 4
kernel/src/filesystem/kernfs/mod.rs

@@ -154,7 +154,11 @@ impl IndexNode for KernFSInode {
         self
     }
 
-    fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> {
+    fn open(
+        &self,
+        _data: SpinLockGuard<FilePrivateData>,
+        _mode: &FileMode,
+    ) -> Result<(), SystemError> {
         if let Some(callback) = self.callback {
             let callback_data =
                 KernCallbackData::new(self.self_ref.upgrade().unwrap(), self.private_data.lock());
@@ -164,7 +168,7 @@ impl IndexNode for KernFSInode {
         return Ok(());
     }
 
-    fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
+    fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
         return Ok(());
     }
 
@@ -315,7 +319,7 @@ impl IndexNode for KernFSInode {
         offset: usize,
         len: usize,
         buf: &mut [u8],
-        _data: &mut FilePrivateData,
+        _data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         if self.inode_type == KernInodeType::SymLink {
             let inner = self.inner.read();
@@ -359,7 +363,7 @@ impl IndexNode for KernFSInode {
         offset: usize,
         len: usize,
         buf: &[u8],
-        _data: &mut FilePrivateData,
+        _data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         if self.inode_type != KernInodeType::File {
             return Err(SystemError::EISDIR);

+ 1 - 0
kernel/src/filesystem/mod.rs

@@ -1,4 +1,5 @@
 pub mod devfs;
+pub mod devpts;
 pub mod fat;
 pub mod kernfs;
 pub mod mbr;

+ 16 - 8
kernel/src/filesystem/procfs/mod.rs

@@ -433,7 +433,11 @@ impl ProcFS {
 }
 
 impl IndexNode for LockedProcFSInode {
-    fn open(&self, data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> {
+    fn open(
+        &self,
+        mut data: SpinLockGuard<FilePrivateData>,
+        _mode: &FileMode,
+    ) -> Result<(), SystemError> {
         // 加锁
         let mut inode: SpinLockGuard<ProcFSInode> = self.0.lock();
 
@@ -457,7 +461,7 @@ impl IndexNode for LockedProcFSInode {
         return Ok(());
     }
 
-    fn close(&self, data: &mut FilePrivateData) -> Result<(), SystemError> {
+    fn close(&self, mut data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
         let guard: SpinLockGuard<ProcFSInode> = self.0.lock();
         // 如果inode类型为文件夹,则直接返回成功
         if let FileType::Dir = guard.metadata.file_type {
@@ -474,7 +478,7 @@ impl IndexNode for LockedProcFSInode {
         offset: usize,
         len: usize,
         buf: &mut [u8],
-        data: &mut FilePrivateData,
+        data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         if buf.len() < len {
             return Err(SystemError::EINVAL);
@@ -488,8 +492,8 @@ impl IndexNode for LockedProcFSInode {
         }
 
         // 获取数据信息
-        let private_data = match data {
-            FilePrivateData::Procfs(p) => p,
+        let mut private_data = match &*data {
+            FilePrivateData::Procfs(p) => p.clone(),
             _ => {
                 panic!("ProcFS: FilePrivateData mismatch!");
             }
@@ -497,8 +501,12 @@ impl IndexNode for LockedProcFSInode {
 
         // 根据文件类型读取相应数据
         match inode.fdata.ftype {
-            ProcFileType::ProcStatus => return inode.proc_read(offset, len, buf, private_data),
-            ProcFileType::ProcMeminfo => return inode.proc_read(offset, len, buf, private_data),
+            ProcFileType::ProcStatus => {
+                return inode.proc_read(offset, len, buf, &mut private_data)
+            }
+            ProcFileType::ProcMeminfo => {
+                return inode.proc_read(offset, len, buf, &mut private_data)
+            }
             ProcFileType::ProcKmsg => (),
             ProcFileType::Default => (),
         };
@@ -523,7 +531,7 @@ impl IndexNode for LockedProcFSInode {
         _offset: usize,
         _len: usize,
         _buf: &[u8],
-        _data: &mut FilePrivateData,
+        _data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
     }

+ 4 - 4
kernel/src/filesystem/ramfs/mod.rs

@@ -167,13 +167,13 @@ impl IndexNode for LockedRamFSInode {
         return Ok(());
     }
 
-    fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
+    fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
         return Ok(());
     }
 
     fn open(
         &self,
-        _data: &mut FilePrivateData,
+        _data: SpinLockGuard<FilePrivateData>,
         _mode: &super::vfs::file::FileMode,
     ) -> Result<(), SystemError> {
         return Ok(());
@@ -184,7 +184,7 @@ impl IndexNode for LockedRamFSInode {
         offset: usize,
         len: usize,
         buf: &mut [u8],
-        _data: &mut FilePrivateData,
+        _data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         if buf.len() < len {
             return Err(SystemError::EINVAL);
@@ -216,7 +216,7 @@ impl IndexNode for LockedRamFSInode {
         offset: usize,
         len: usize,
         buf: &[u8],
-        _data: &mut FilePrivateData,
+        _data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         if buf.len() < len {
             return Err(SystemError::EINVAL);

+ 4 - 3
kernel/src/filesystem/vfs/core.rs

@@ -19,6 +19,7 @@ use crate::{
 
 use super::{
     file::FileMode,
+    mount::MountFSInode,
     utils::{rsplit_path, user_path_at},
     IndexNode, InodeId, VFS_MAX_FOLLOW_SYMLINK_TIMES,
 };
@@ -103,9 +104,9 @@ fn do_migrate(
             .unwrap_or_else(|_| panic!("Failed to create '/{mountpoint_name}' in migrating"))
     };
     // 迁移挂载点
-    mountpoint
-        .mount(fs.inner_filesystem())
-        .unwrap_or_else(|_| panic!("Failed to migrate {mountpoint_name} "));
+    let inode = mountpoint.arc_any().downcast::<MountFSInode>().unwrap();
+    inode.do_mount(inode.inode_id(), fs.self_ref())?;
+
     return Ok(());
 }
 

+ 85 - 70
kernel/src/filesystem/vfs/file.rs

@@ -1,3 +1,5 @@
+use core::sync::atomic::{AtomicUsize, Ordering};
+
 use alloc::{
     string::String,
     sync::{Arc, Weak},
@@ -13,7 +15,7 @@ use crate::{
     filesystem::procfs::ProcfsFilePrivateData,
     ipc::pipe::{LockedPipeInode, PipeFsPrivateData},
     kerror,
-    libs::spinlock::SpinLock,
+    libs::{rwlock::RwLock, spinlock::SpinLock},
     net::{
         event_poll::{EPollItem, EPollPrivateData, EventPoll},
         socket::SocketInode,
@@ -121,14 +123,14 @@ impl FileMode {
 pub struct File {
     inode: Arc<dyn IndexNode>,
     /// 对于文件,表示字节偏移量;对于文件夹,表示当前操作的子目录项偏移量
-    offset: usize,
+    offset: AtomicUsize,
     /// 文件的打开模式
-    mode: FileMode,
+    mode: RwLock<FileMode>,
     /// 文件类型
     file_type: FileType,
     /// readdir时候用的,暂存的本次循环中,所有子目录项的名字的数组
-    readdir_subdirs_name: Vec<String>,
-    pub private_data: FilePrivateData,
+    readdir_subdirs_name: SpinLock<Vec<String>>,
+    pub private_data: SpinLock<FilePrivateData>,
 }
 
 impl File {
@@ -145,16 +147,16 @@ impl File {
             }
         }
 
-        let mut f = File {
+        let f = File {
             inode,
-            offset: 0,
-            mode,
+            offset: AtomicUsize::new(0),
+            mode: RwLock::new(mode),
             file_type,
-            readdir_subdirs_name: Vec::new(),
-            private_data: FilePrivateData::default(),
+            readdir_subdirs_name: SpinLock::new(Vec::default()),
+            private_data: SpinLock::new(FilePrivateData::default()),
         };
         // kdebug!("inode:{:?}",f.inode);
-        f.inode.open(&mut f.private_data, &mode)?;
+        f.inode.open(f.private_data.lock(), &mode)?;
 
         return Ok(f);
     }
@@ -166,8 +168,13 @@ impl File {
     ///
     /// @return Ok(usize) 成功读取的字节数
     /// @return Err(SystemError) 错误码
-    pub fn read(&mut self, len: usize, buf: &mut [u8]) -> Result<usize, SystemError> {
-        self.do_read(self.offset, len, buf, true)
+    pub fn read(&self, len: usize, buf: &mut [u8]) -> Result<usize, SystemError> {
+        self.do_read(
+            self.offset.load(core::sync::atomic::Ordering::SeqCst),
+            len,
+            buf,
+            true,
+        )
     }
 
     /// @brief 从buffer向文件写入指定的字节数的数据
@@ -177,8 +184,13 @@ impl File {
     ///
     /// @return Ok(usize) 成功写入的字节数
     /// @return Err(SystemError) 错误码
-    pub fn write(&mut self, len: usize, buf: &[u8]) -> Result<usize, SystemError> {
-        self.do_write(self.offset, len, buf, true)
+    pub fn write(&self, len: usize, buf: &[u8]) -> Result<usize, SystemError> {
+        self.do_write(
+            self.offset.load(core::sync::atomic::Ordering::SeqCst),
+            len,
+            buf,
+            true,
+        )
     }
 
     /// ## 从文件中指定的偏移处读取指定的字节数到buf中
@@ -190,12 +202,7 @@ impl File {
     ///
     /// ### 返回值
     /// - `Ok(usize)`: 成功读取的字节数
-    pub fn pread(
-        &mut self,
-        offset: usize,
-        len: usize,
-        buf: &mut [u8],
-    ) -> Result<usize, SystemError> {
+    pub fn pread(&self, offset: usize, len: usize, buf: &mut [u8]) -> Result<usize, SystemError> {
         self.do_read(offset, len, buf, false)
     }
 
@@ -208,12 +215,12 @@ impl File {
     ///
     /// ### 返回值
     /// - `Ok(usize)`: 成功写入的字节数
-    pub fn pwrite(&mut self, offset: usize, len: usize, buf: &[u8]) -> Result<usize, SystemError> {
+    pub fn pwrite(&self, offset: usize, len: usize, buf: &[u8]) -> Result<usize, SystemError> {
         self.do_write(offset, len, buf, false)
     }
 
     fn do_read(
-        &mut self,
+        &self,
         offset: usize,
         len: usize,
         buf: &mut [u8],
@@ -227,17 +234,18 @@ impl File {
 
         let len = self
             .inode
-            .read_at(offset, len, buf, &mut self.private_data)?;
+            .read_at(offset, len, buf, self.private_data.lock())?;
 
         if update_offset {
-            self.offset += len;
+            self.offset
+                .fetch_add(len, core::sync::atomic::Ordering::SeqCst);
         }
 
         Ok(len)
     }
 
     fn do_write(
-        &mut self,
+        &self,
         offset: usize,
         len: usize,
         buf: &[u8],
@@ -255,10 +263,11 @@ impl File {
         }
         let len = self
             .inode
-            .write_at(offset, len, buf, &mut self.private_data)?;
+            .write_at(offset, len, buf, self.private_data.lock())?;
 
         if update_offset {
-            self.offset += len;
+            self.offset
+                .fetch_add(len, core::sync::atomic::Ordering::SeqCst);
         }
 
         Ok(len)
@@ -278,7 +287,7 @@ impl File {
     /// @brief 调整文件操作指针的位置
     ///
     /// @param origin 调整的起始位置
-    pub fn lseek(&mut self, origin: SeekFrom) -> Result<usize, SystemError> {
+    pub fn lseek(&self, origin: SeekFrom) -> Result<usize, SystemError> {
         let file_type = self.inode.metadata()?.file_type;
         match file_type {
             FileType::Pipe | FileType::CharDevice => {
@@ -289,7 +298,7 @@ impl File {
 
         let pos: i64 = match origin {
             SeekFrom::SeekSet(offset) => offset,
-            SeekFrom::SeekCurrent(offset) => self.offset as i64 + offset,
+            SeekFrom::SeekCurrent(offset) => self.offset.load(Ordering::SeqCst) as i64 + offset,
             SeekFrom::SeekEnd(offset) => {
                 let metadata = self.metadata()?;
                 metadata.size + offset
@@ -303,15 +312,15 @@ impl File {
         if pos < 0 {
             return Err(SystemError::EOVERFLOW);
         }
-        self.offset = pos as usize;
-        return Ok(self.offset);
+        self.offset.store(pos as usize, Ordering::SeqCst);
+        return Ok(pos as usize);
     }
 
     /// @brief 判断当前文件是否可读
     #[inline]
     pub fn readable(&self) -> Result<(), SystemError> {
         // 暂时认为只要不是write only, 就可读
-        if self.mode == FileMode::O_WRONLY {
+        if *self.mode.read() == FileMode::O_WRONLY {
             return Err(SystemError::EPERM);
         }
 
@@ -322,7 +331,7 @@ impl File {
     #[inline]
     pub fn writeable(&self) -> Result<(), SystemError> {
         // 暂时认为只要不是read only, 就可写
-        if self.mode == FileMode::O_RDONLY {
+        if *self.mode.read() == FileMode::O_RDONLY {
             return Err(SystemError::EPERM);
         }
 
@@ -331,23 +340,24 @@ impl File {
 
     /// @biref 充填dirent结构体
     /// @return 返回dirent结构体的大小
-    pub fn readdir(&mut self, dirent: &mut Dirent) -> Result<u64, SystemError> {
+    pub fn readdir(&self, dirent: &mut Dirent) -> Result<u64, SystemError> {
         let inode: &Arc<dyn IndexNode> = &self.inode;
-
+        let mut readdir_subdirs_name = self.readdir_subdirs_name.lock();
+        let offset = self.offset.load(Ordering::SeqCst);
         // 如果偏移量为0
-        if self.offset == 0 {
+        if offset == 0 {
             // 通过list更新readdir_subdirs_name
-            self.readdir_subdirs_name = inode.list()?;
-            self.readdir_subdirs_name.sort();
+            *readdir_subdirs_name = inode.list()?;
+            readdir_subdirs_name.sort();
         }
         // kdebug!("sub_entries={sub_entries:?}");
 
         // 已经读到末尾
-        if self.offset == self.readdir_subdirs_name.len() {
-            self.offset = 0;
+        if offset == readdir_subdirs_name.len() {
+            self.offset.store(0, Ordering::SeqCst);
             return Ok(0);
         }
-        let name = &self.readdir_subdirs_name[self.offset];
+        let name = &readdir_subdirs_name[offset];
         let sub_inode: Arc<dyn IndexNode> = match inode.find(name) {
             Ok(i) => i,
             Err(e) => {
@@ -370,7 +380,7 @@ impl File {
             buf[name_bytes.len()] = 0;
         }
 
-        self.offset += 1;
+        self.offset.fetch_add(1, Ordering::SeqCst);
         dirent.d_ino = sub_inode.metadata().unwrap().inode_id.into() as u64;
         dirent.d_type = sub_inode.metadata().unwrap().file_type.get_file_type_num() as u8;
 
@@ -392,16 +402,20 @@ impl File {
     ///
     /// @return Option<File> 克隆后的文件结构体。如果克隆失败,返回None
     pub fn try_clone(&self) -> Option<File> {
-        let mut res = Self {
+        let res = Self {
             inode: self.inode.clone(),
-            offset: self.offset,
-            mode: self.mode,
+            offset: AtomicUsize::new(self.offset.load(Ordering::SeqCst)),
+            mode: RwLock::new(self.mode()),
             file_type: self.file_type,
-            readdir_subdirs_name: self.readdir_subdirs_name.clone(),
-            private_data: self.private_data.clone(),
+            readdir_subdirs_name: SpinLock::new(self.readdir_subdirs_name.lock().clone()),
+            private_data: SpinLock::new(self.private_data.lock().clone()),
         };
         // 调用inode的open方法,让inode知道有新的文件打开了这个inode
-        if self.inode.open(&mut res.private_data, &res.mode).is_err() {
+        if self
+            .inode
+            .open(res.private_data.lock(), &res.mode())
+            .is_err()
+        {
             return None;
         }
 
@@ -417,32 +431,33 @@ impl File {
     /// @brief 获取文件的打开模式
     #[inline]
     pub fn mode(&self) -> FileMode {
-        return self.mode;
+        return *self.mode.read();
     }
 
     /// 获取文件是否在execve时关闭
     #[inline]
     pub fn close_on_exec(&self) -> bool {
-        return self.mode.contains(FileMode::O_CLOEXEC);
+        return self.mode().contains(FileMode::O_CLOEXEC);
     }
 
     /// 设置文件是否在execve时关闭
     #[inline]
-    pub fn set_close_on_exec(&mut self, close_on_exec: bool) {
+    pub fn set_close_on_exec(&self, close_on_exec: bool) {
+        let mut mode_guard = self.mode.write();
         if close_on_exec {
-            self.mode.insert(FileMode::O_CLOEXEC);
+            mode_guard.insert(FileMode::O_CLOEXEC);
         } else {
-            self.mode.remove(FileMode::O_CLOEXEC);
+            mode_guard.remove(FileMode::O_CLOEXEC);
         }
     }
 
-    pub fn set_mode(&mut self, mode: FileMode) -> Result<(), SystemError> {
+    pub fn set_mode(&self, mode: FileMode) -> Result<(), SystemError> {
         // todo: 是否需要调用inode的open方法,以更新private data(假如它与mode有关的话)?
         // 也许需要加个更好的设计,让inode知晓文件的打开模式发生了变化,让它自己决定是否需要更新private data
 
         // 直接修改文件的打开模式
-        self.mode = mode;
-        self.private_data.update_mode(mode);
+        *self.mode.write() = mode;
+        self.private_data.lock().update_mode(mode);
         return Ok(());
     }
 
@@ -465,7 +480,7 @@ impl File {
     /// ## 向该文件添加一个EPollItem对象
     ///
     /// 在文件状态发生变化时,需要向epoll通知
-    pub fn add_epoll(&mut self, epitem: Arc<EPollItem>) -> Result<(), SystemError> {
+    pub fn add_epoll(&self, epitem: Arc<EPollItem>) -> Result<(), SystemError> {
         match self.file_type {
             FileType::Socket => {
                 let inode = self.inode.downcast_ref::<SocketInode>().unwrap();
@@ -481,7 +496,7 @@ impl File {
                 let r = self.inode.ioctl(
                     EventPoll::ADD_EPOLLITEM,
                     &epitem as *const Arc<EPollItem> as usize,
-                    &self.private_data,
+                    &self.private_data.lock(),
                 );
                 if r.is_err() {
                     return Err(SystemError::ENOSYS);
@@ -493,7 +508,7 @@ impl File {
     }
 
     /// ## 删除一个绑定的epoll
-    pub fn remove_epoll(&mut self, epoll: &Weak<SpinLock<EventPoll>>) -> Result<(), SystemError> {
+    pub fn remove_epoll(&self, epoll: &Weak<SpinLock<EventPoll>>) -> Result<(), SystemError> {
         match self.file_type {
             FileType::Socket => {
                 let inode = self.inode.downcast_ref::<SocketInode>().unwrap();
@@ -506,13 +521,13 @@ impl File {
     }
 
     pub fn poll(&self) -> Result<usize, SystemError> {
-        self.inode.poll(&self.private_data)
+        self.inode.poll(&self.private_data.lock())
     }
 }
 
 impl Drop for File {
     fn drop(&mut self) {
-        let r: Result<(), SystemError> = self.inode.close(&mut self.private_data);
+        let r: Result<(), SystemError> = self.inode.close(self.private_data.lock());
         // 打印错误信息
         if r.is_err() {
             kerror!(
@@ -529,7 +544,7 @@ impl Drop for File {
 #[derive(Debug)]
 pub struct FileDescriptorVec {
     /// 当前进程打开的文件描述符
-    fds: Vec<Option<Arc<SpinLock<File>>>>,
+    fds: Vec<Option<Arc<File>>>,
 }
 
 impl FileDescriptorVec {
@@ -551,8 +566,8 @@ impl FileDescriptorVec {
         let mut res = FileDescriptorVec::new();
         for i in 0..FileDescriptorVec::PROCESS_MAX_FD {
             if let Some(file) = &self.fds[i] {
-                if let Some(file) = file.lock().try_clone() {
-                    res.fds[i] = Some(Arc::new(SpinLock::new(file)));
+                if let Some(file) = file.try_clone() {
+                    res.fds[i] = Some(Arc::new(file));
                 }
             }
         }
@@ -584,7 +599,7 @@ impl FileDescriptorVec {
         if let Some(new_fd) = fd {
             let x = &mut self.fds[new_fd as usize];
             if x.is_none() {
-                *x = Some(Arc::new(SpinLock::new(file)));
+                *x = Some(Arc::new(file));
                 return Ok(new_fd);
             } else {
                 return Err(SystemError::EBADF);
@@ -593,7 +608,7 @@ impl FileDescriptorVec {
             // 没有指定要申请的文件描述符编号
             for i in 0..FileDescriptorVec::PROCESS_MAX_FD {
                 if self.fds[i].is_none() {
-                    self.fds[i] = Some(Arc::new(SpinLock::new(file)));
+                    self.fds[i] = Some(Arc::new(file));
                     return Ok(i as i32);
                 }
             }
@@ -606,7 +621,7 @@ impl FileDescriptorVec {
     /// ## 参数
     ///
     /// - `fd` 文件描述符序号
-    pub fn get_file_by_fd(&self, fd: i32) -> Option<Arc<SpinLock<File>>> {
+    pub fn get_file_by_fd(&self, fd: i32) -> Option<Arc<File>> {
         if !FileDescriptorVec::validate_fd(fd) {
             return None;
         }
@@ -641,7 +656,7 @@ impl FileDescriptorVec {
     pub fn close_on_exec(&mut self) {
         for i in 0..FileDescriptorVec::PROCESS_MAX_FD {
             if let Some(file) = &self.fds[i] {
-                let to_drop = file.lock().close_on_exec();
+                let to_drop = file.close_on_exec();
                 if to_drop {
                     if let Err(r) = self.drop_fd(i as i32) {
                         kerror!(
@@ -670,7 +685,7 @@ impl<'a> FileDescriptorIterator<'a> {
 }
 
 impl<'a> Iterator for FileDescriptorIterator<'a> {
-    type Item = (i32, Arc<SpinLock<File>>);
+    type Item = (i32, Arc<File>);
 
     fn next(&mut self) -> Option<Self::Item> {
         while self.index < FileDescriptorVec::PROCESS_MAX_FD {

+ 20 - 7
kernel/src/filesystem/vfs/mod.rs

@@ -8,6 +8,7 @@ mod utils;
 
 use ::core::{any::Any, fmt::Debug, sync::atomic::AtomicUsize};
 use alloc::{string::String, sync::Arc, vec::Vec};
+use intertrait::CastFromSync;
 use system_error::SystemError;
 
 use crate::{
@@ -15,7 +16,10 @@ use crate::{
         block::block_device::BlockDevice, char::CharDevice, device::device_number::DeviceNumber,
     },
     ipc::pipe::LockedPipeInode,
-    libs::casting::DowncastArc,
+    libs::{
+        casting::DowncastArc,
+        spinlock::{SpinLock, SpinLockGuard},
+    },
     time::TimeSpec,
 };
 
@@ -114,12 +118,16 @@ bitflags! {
     }
 }
 
-pub trait IndexNode: Any + Sync + Send + Debug {
+pub trait IndexNode: Any + Sync + Send + Debug + CastFromSync {
     /// @brief 打开文件
     ///
     /// @return 成功:Ok()
     ///         失败:Err(错误码)
-    fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> {
+    fn open(
+        &self,
+        _data: SpinLockGuard<FilePrivateData>,
+        _mode: &FileMode,
+    ) -> Result<(), SystemError> {
         // 若文件系统没有实现此方法,则返回“不支持”
         return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
     }
@@ -128,7 +136,7 @@ pub trait IndexNode: Any + Sync + Send + Debug {
     ///
     /// @return 成功:Ok()
     ///         失败:Err(错误码)
-    fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
+    fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
         // 若文件系统没有实现此方法,则返回“不支持”
         return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
     }
@@ -147,7 +155,7 @@ pub trait IndexNode: Any + Sync + Send + Debug {
         offset: usize,
         len: usize,
         buf: &mut [u8],
-        _data: &mut FilePrivateData,
+        _data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError>;
 
     /// @brief 在inode的指定偏移量开始,写入指定大小的数据(从buf的第0byte开始写入)
@@ -164,7 +172,7 @@ pub trait IndexNode: Any + Sync + Send + Debug {
         offset: usize,
         len: usize,
         buf: &[u8],
-        _data: &mut FilePrivateData,
+        _data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError>;
 
     /// @brief 获取当前inode的状态。
@@ -494,7 +502,12 @@ impl dyn IndexNode {
             if inode.metadata()?.file_type == FileType::SymLink && max_follow_times > 0 {
                 let mut content = [0u8; 256];
                 // 读取符号链接
-                let len = inode.read_at(0, 256, &mut content, &mut FilePrivateData::Unused)?;
+                let len = inode.read_at(
+                    0,
+                    256,
+                    &mut content,
+                    SpinLock::new(FilePrivateData::Unused).lock(),
+                )?;
 
                 // 将读到的数据转换为utf8字符串(先转为str,再转为String)
                 let link_path = String::from(

+ 37 - 10
kernel/src/filesystem/vfs/mount.rs

@@ -9,7 +9,10 @@ use alloc::{
 };
 use system_error::SystemError;
 
-use crate::{driver::base::device::device_number::DeviceNumber, libs::spinlock::SpinLock};
+use crate::{
+    driver::base::device::device_number::DeviceNumber,
+    libs::spinlock::{SpinLock, SpinLockGuard},
+};
 
 use super::{
     file::FileMode, syscall::ModeType, FilePrivateData, FileSystem, FileType, IndexNode, InodeId,
@@ -34,6 +37,7 @@ pub struct MountFS {
 
 /// @brief MountFS的Index Node 注意,这个IndexNode只是一个中间层。它的目的是将具体文件系统的Inode与挂载机制连接在一起。
 #[derive(Debug)]
+#[cast_to([sync] IndexNode)]
 pub struct MountFSInode {
     /// 当前挂载点对应到具体的文件系统的Inode
     inner_inode: Arc<dyn IndexNode>,
@@ -88,6 +92,10 @@ impl MountFS {
     pub fn inner_filesystem(&self) -> Arc<dyn FileSystem> {
         return self.inner_filesystem.clone();
     }
+
+    pub fn self_ref(&self) -> Arc<Self> {
+        self.self_ref.upgrade().unwrap()
+    }
 }
 
 impl MountFSInode {
@@ -132,14 +140,37 @@ impl MountFSInode {
             return self.self_ref.upgrade().unwrap();
         }
     }
+
+    /// 将新的挂载点-挂载文件系统添加到父级的挂载树
+    pub(super) fn do_mount(
+        &self,
+        inode_id: InodeId,
+        new_mount_fs: Arc<MountFS>,
+    ) -> Result<(), SystemError> {
+        let mut guard = self.mount_fs.mountpoints.lock();
+        if guard.contains_key(&inode_id) {
+            return Err(SystemError::EBUSY);
+        }
+        guard.insert(inode_id, new_mount_fs);
+
+        return Ok(());
+    }
+
+    pub(super) fn inode_id(&self) -> InodeId {
+        self.metadata().map(|x| x.inode_id).unwrap()
+    }
 }
 
 impl IndexNode for MountFSInode {
-    fn open(&self, data: &mut FilePrivateData, mode: &FileMode) -> Result<(), SystemError> {
+    fn open(
+        &self,
+        data: SpinLockGuard<FilePrivateData>,
+        mode: &FileMode,
+    ) -> Result<(), SystemError> {
         return self.inner_inode.open(data, mode);
     }
 
-    fn close(&self, data: &mut FilePrivateData) -> Result<(), SystemError> {
+    fn close(&self, data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
         return self.inner_inode.close(data);
     }
 
@@ -169,7 +200,7 @@ impl IndexNode for MountFSInode {
         offset: usize,
         len: usize,
         buf: &mut [u8],
-        data: &mut FilePrivateData,
+        data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         return self.inner_inode.read_at(offset, len, buf, data);
     }
@@ -179,7 +210,7 @@ impl IndexNode for MountFSInode {
         offset: usize,
         len: usize,
         buf: &[u8],
-        data: &mut FilePrivateData,
+        data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         return self.inner_inode.write_at(offset, len, buf, data);
     }
@@ -345,11 +376,7 @@ impl IndexNode for MountFSInode {
 
         // 为新的挂载点创建挂载文件系统
         let new_mount_fs: Arc<MountFS> = MountFS::new(fs, Some(self.self_ref.upgrade().unwrap()));
-        // 将新的挂载点-挂载文件系统添加到父级的挂载树
-        self.mount_fs
-            .mountpoints
-            .lock()
-            .insert(metadata.inode_id, new_mount_fs.clone());
+        self.do_mount(metadata.inode_id, new_mount_fs.clone())?;
         return Ok(new_mount_fs);
     }
 

+ 1 - 1
kernel/src/filesystem/vfs/open.rs

@@ -123,7 +123,7 @@ fn do_sys_openat2(
 
     // 创建文件对象
 
-    let mut file: File = File::new(inode, how.o_flags)?;
+    let file: File = File::new(inode, how.o_flags)?;
 
     // 打开模式为“追加”
     if how.o_flags.contains(FileMode::O_APPEND) {

+ 22 - 29
kernel/src/filesystem/vfs/syscall.rs

@@ -519,8 +519,7 @@ impl Syscall {
 
         // drop guard 以避免无法调度的问题
         drop(fd_table_guard);
-        let file = file.lock_no_preempt();
-        let r = file.inode().ioctl(cmd, data, &file.private_data);
+        let r = file.inode().ioctl(cmd, data, &file.private_data.lock());
         return r;
     }
 
@@ -543,7 +542,7 @@ impl Syscall {
         drop(fd_table_guard);
         let file = file.unwrap();
 
-        return file.lock_no_preempt().read(buf.len(), buf);
+        return file.read(buf.len(), buf);
     }
 
     /// @brief 根据文件描述符,向文件写入数据。尝试写入的数据长度与buf的长度相同。
@@ -563,7 +562,7 @@ impl Syscall {
 
         // drop guard 以避免无法调度的问题
         drop(fd_table_guard);
-        return file.lock_no_preempt().write(buf.len(), buf);
+        return file.write(buf.len(), buf);
     }
 
     /// @brief 调整文件操作指针的位置
@@ -590,7 +589,7 @@ impl Syscall {
 
         // drop guard 以避免无法调度的问题
         drop(fd_table_guard);
-        return file.lock_no_preempt().lseek(seek);
+        return file.lseek(seek);
     }
 
     /// # sys_pread64 系统调用的实际执行函数
@@ -612,7 +611,7 @@ impl Syscall {
         drop(fd_table_guard);
         let file = file.unwrap();
 
-        return file.lock_no_preempt().pread(offset, len, buf);
+        return file.pread(offset, len, buf);
     }
 
     /// # sys_pwrite64 系统调用的实际执行函数
@@ -634,7 +633,7 @@ impl Syscall {
         drop(fd_table_guard);
         let file = file.unwrap();
 
-        return file.lock_no_preempt().pwrite(offset, len, buf);
+        return file.pwrite(offset, len, buf);
     }
 
     /// @brief 切换工作目录
@@ -757,7 +756,7 @@ impl Syscall {
         // drop guard 以避免无法调度的问题
         drop(fd_table_guard);
 
-        let res = file.lock_no_preempt().readdir(dirent).map(|x| x as usize);
+        let res = file.readdir(dirent).map(|x| x as usize);
 
         return res;
     }
@@ -811,7 +810,7 @@ impl Syscall {
                 let file = fd_table_guard
                     .get_file_by_fd(oldfd)
                     .ok_or(SystemError::EBADF)?;
-                let old_inode = file.lock().inode();
+                let old_inode = file.inode();
                 old_inode
             } else {
                 return Err(SystemError::ENONET);
@@ -978,10 +977,7 @@ impl Syscall {
             .get_file_by_fd(oldfd)
             .ok_or(SystemError::EBADF)?;
 
-        let new_file = old_file
-            .lock_no_preempt()
-            .try_clone()
-            .ok_or(SystemError::EBADF)?;
+        let new_file = old_file.try_clone().ok_or(SystemError::EBADF)?;
         // 申请文件描述符,并把文件对象存入其中
         let res = fd_table_guard.alloc_fd(new_file, None).map(|x| x as usize);
         return res;
@@ -1032,10 +1028,7 @@ impl Syscall {
         let old_file = fd_table_guard
             .get_file_by_fd(oldfd)
             .ok_or(SystemError::EBADF)?;
-        let new_file = old_file
-            .lock_no_preempt()
-            .try_clone()
-            .ok_or(SystemError::EBADF)?;
+        let new_file = old_file.try_clone().ok_or(SystemError::EBADF)?;
         // 申请文件描述符,并把文件对象存入其中
         let res = fd_table_guard
             .alloc_fd(new_file, Some(newfd))
@@ -1074,7 +1067,7 @@ impl Syscall {
                     // drop guard 以避免无法调度的问题
                     drop(fd_table_guard);
 
-                    if file.lock().close_on_exec() {
+                    if file.close_on_exec() {
                         return Ok(FD_CLOEXEC as usize);
                     }
                 }
@@ -1090,9 +1083,9 @@ impl Syscall {
                     drop(fd_table_guard);
                     let arg = arg as u32;
                     if arg & FD_CLOEXEC != 0 {
-                        file.lock().set_close_on_exec(true);
+                        file.set_close_on_exec(true);
                     } else {
-                        file.lock().set_close_on_exec(false);
+                        file.set_close_on_exec(false);
                     }
                     return Ok(0);
                 }
@@ -1107,7 +1100,7 @@ impl Syscall {
                 if let Some(file) = fd_table_guard.get_file_by_fd(fd) {
                     // drop guard 以避免无法调度的问题
                     drop(fd_table_guard);
-                    return Ok(file.lock_no_preempt().mode().bits() as usize);
+                    return Ok(file.mode().bits() as usize);
                 }
 
                 return Err(SystemError::EBADF);
@@ -1122,7 +1115,7 @@ impl Syscall {
                     let mode = FileMode::from_bits(arg).ok_or(SystemError::EINVAL)?;
                     // drop guard 以避免无法调度的问题
                     drop(fd_table_guard);
-                    file.lock_no_preempt().set_mode(mode)?;
+                    file.set_mode(mode)?;
                     return Ok(0);
                 }
 
@@ -1161,7 +1154,7 @@ impl Syscall {
         if let Some(file) = fd_table_guard.get_file_by_fd(fd) {
             // drop guard 以避免无法调度的问题
             drop(fd_table_guard);
-            let r = file.lock_no_preempt().ftruncate(len).map(|_| 0);
+            let r = file.ftruncate(len).map(|_| 0);
             return r;
         }
 
@@ -1179,7 +1172,7 @@ impl Syscall {
 
         let mut kstat = PosixKstat::new();
         // 获取文件信息
-        let metadata = file.lock().metadata()?;
+        let metadata = file.metadata()?;
         kstat.size = metadata.size;
         kstat.dev_id = metadata.dev_id as u64;
         kstat.inode = metadata.inode_id.into() as u64;
@@ -1198,7 +1191,7 @@ impl Syscall {
         kstat.gid = metadata.gid as i32;
         kstat.rdev = metadata.raw_dev.data() as i64;
         kstat.mode = metadata.mode;
-        match file.lock().file_type() {
+        match file.file_type() {
             FileType::File => kstat.mode.insert(ModeType::S_IFREG),
             FileType::Dir => kstat.mode.insert(ModeType::S_IFDIR),
             FileType::BlockDevice => kstat.mode.insert(ModeType::S_IFBLK),
@@ -1270,7 +1263,7 @@ impl Syscall {
             .get_file_by_fd(fd)
             .ok_or(SystemError::EBADF)?;
         drop(fd_table_guard);
-        let statfs = PosixStatfs::from(file.lock().inode().fs().super_block());
+        let statfs = PosixStatfs::from(file.inode().fs().super_block());
         writer.copy_one_to_user(&statfs, 0)?;
         return Ok(0);
     }
@@ -1305,7 +1298,7 @@ impl Syscall {
         let mut writer = UserBufferWriter::new(usr_kstat, size_of::<PosixStatx>(), true)?;
         let mut tmp: PosixStatx = PosixStatx::new();
         // 获取文件信息
-        let metadata = file.lock().metadata()?;
+        let metadata = file.metadata()?;
 
         tmp.stx_mask |= PosixStatxMask::STATX_BASIC_STATS;
         tmp.stx_blksize = metadata.blk_size as u32;
@@ -1366,7 +1359,7 @@ impl Syscall {
             tmp.stx_dio_offset_align = 0;
         }
 
-        match file.lock().file_type() {
+        match file.file_type() {
             FileType::File => tmp.stx_mode.insert(ModeType::S_IFREG),
             FileType::Dir => tmp.stx_mode.insert(ModeType::S_IFDIR),
             FileType::BlockDevice => tmp.stx_mode.insert(ModeType::S_IFBLK),
@@ -1450,7 +1443,7 @@ impl Syscall {
 
         let ubuf = user_buf.buffer::<u8>(0).unwrap();
 
-        let mut file = File::new(inode, FileMode::O_RDONLY)?;
+        let file = File::new(inode, FileMode::O_RDONLY)?;
 
         let len = file.read(buf_size, ubuf)?;
 

+ 2 - 3
kernel/src/filesystem/vfs/utils.rs

@@ -53,13 +53,12 @@ pub fn user_path_at(
             // drop guard 以避免无法调度的问题
             drop(fd_table_guard);
 
-            let file_guard = file.lock();
             // 如果dirfd不是目录,则返回错误码ENOTDIR
-            if file_guard.file_type() != FileType::Dir {
+            if file.file_type() != FileType::Dir {
                 return Err(SystemError::ENOTDIR);
             }
 
-            inode = file_guard.inode();
+            inode = file.inode();
             ret_path = String::from(path);
         } else {
             let mut cwd = pcb.basic().cwd();

+ 43 - 45
kernel/src/ipc/pipe.rs

@@ -5,7 +5,10 @@ use crate::{
         core::generate_inode_id, file::FileMode, syscall::ModeType, FilePrivateData, FileSystem,
         FileType, IndexNode, Metadata,
     },
-    libs::{spinlock::SpinLock, wait_queue::WaitQueue},
+    libs::{
+        spinlock::{SpinLock, SpinLockGuard},
+        wait_queue::WaitQueue,
+    },
     net::event_poll::{EPollEventType, EPollItem, EventPoll},
     process::ProcessState,
     time::TimeSpec,
@@ -37,7 +40,11 @@ impl PipeFsPrivateData {
 
 /// @brief 管道文件i节点(锁)
 #[derive(Debug)]
-pub struct LockedPipeInode(SpinLock<InnerPipeInode>);
+pub struct LockedPipeInode {
+    inner: SpinLock<InnerPipeInode>,
+    read_wait_queue: WaitQueue,
+    write_wait_queue: WaitQueue,
+}
 
 /// @brief 管道文件i节点(无锁)
 #[derive(Debug)]
@@ -47,8 +54,6 @@ pub struct InnerPipeInode {
     valid_cnt: i32,
     read_pos: i32,
     write_pos: i32,
-    read_wait_queue: WaitQueue,
-    write_wait_queue: WaitQueue,
     data: [u8; PIPE_BUFF_SIZE],
     /// INode 元数据
     metadata: Metadata,
@@ -107,8 +112,6 @@ impl LockedPipeInode {
             valid_cnt: 0,
             read_pos: 0,
             write_pos: 0,
-            read_wait_queue: WaitQueue::default(),
-            write_wait_queue: WaitQueue::default(),
             data: [0; PIPE_BUFF_SIZE],
 
             metadata: Metadata {
@@ -131,8 +134,12 @@ impl LockedPipeInode {
             writer: 0,
             epitems: SpinLock::new(LinkedList::new()),
         };
-        let result = Arc::new(Self(SpinLock::new(inner)));
-        let mut guard = result.0.lock();
+        let result = Arc::new(Self {
+            inner: SpinLock::new(inner),
+            read_wait_queue: WaitQueue::default(),
+            write_wait_queue: WaitQueue::default(),
+        });
+        let mut guard = result.inner.lock();
         guard.self_ref = Arc::downgrade(&result);
         // 释放锁
         drop(guard); //这一步其实不需要,只要离开作用域,guard生命周期结束,自会解锁
@@ -140,7 +147,7 @@ impl LockedPipeInode {
     }
 
     pub fn inner(&self) -> &SpinLock<InnerPipeInode> {
-        &self.0
+        &self.inner
     }
 }
 
@@ -150,11 +157,11 @@ impl IndexNode for LockedPipeInode {
         _offset: usize,
         len: usize,
         buf: &mut [u8],
-        data: &mut FilePrivateData,
+        data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         // 获取mode
         let mode: FileMode;
-        if let FilePrivateData::Pipefs(pdata) = data {
+        if let FilePrivateData::Pipefs(pdata) = &*data {
             mode = pdata.mode;
         } else {
             return Err(SystemError::EBADF);
@@ -164,7 +171,7 @@ impl IndexNode for LockedPipeInode {
             return Err(SystemError::EINVAL);
         }
         // 加锁
-        let mut inode = self.0.lock();
+        let mut inode = self.inner.lock();
 
         // 如果管道里面没有数据,则唤醒写端,
         while inode.valid_cnt == 0 {
@@ -173,8 +180,7 @@ impl IndexNode for LockedPipeInode {
                 return Ok(0);
             }
 
-            inode
-                .write_wait_queue
+            self.write_wait_queue
                 .wakeup(Some(ProcessState::Blocked(true)));
 
             // 如果为非阻塞管道,直接返回错误
@@ -187,13 +193,12 @@ impl IndexNode for LockedPipeInode {
             unsafe {
                 let irq_guard = CurrentIrqArch::save_and_disable_irq();
 
-                inode.read_wait_queue.sleep_without_schedule();
                 drop(inode);
-
+                self.read_wait_queue.sleep_without_schedule();
                 drop(irq_guard);
             }
             sched();
-            inode = self.0.lock();
+            inode = self.inner.lock();
         }
 
         let mut num = inode.valid_cnt as usize;
@@ -222,17 +227,15 @@ impl IndexNode for LockedPipeInode {
 
         // 读完以后如果未读完,则唤醒下一个读者
         if inode.valid_cnt > 0 {
-            inode
-                .read_wait_queue
+            self.read_wait_queue
                 .wakeup(Some(ProcessState::Blocked(true)));
         }
 
         //读完后解锁并唤醒等待在写等待队列中的进程
-        inode
-            .write_wait_queue
+        self.write_wait_queue
             .wakeup(Some(ProcessState::Blocked(true)));
 
-        let pollflag = EPollEventType::from_bits_truncate(inode.poll(data)? as u32);
+        let pollflag = EPollEventType::from_bits_truncate(inode.poll(&data)? as u32);
         // 唤醒epoll中等待的进程
         EventPoll::wakeup_epoll(&inode.epitems, pollflag)?;
 
@@ -242,10 +245,10 @@ impl IndexNode for LockedPipeInode {
 
     fn open(
         &self,
-        data: &mut FilePrivateData,
+        mut data: SpinLockGuard<FilePrivateData>,
         mode: &crate::filesystem::vfs::file::FileMode,
     ) -> Result<(), SystemError> {
-        let mut guard = self.0.lock();
+        let mut guard = self.inner.lock();
         // 不能以读写方式打开管道
         if mode.contains(FileMode::O_RDWR) {
             return Err(SystemError::EACCES);
@@ -264,21 +267,21 @@ impl IndexNode for LockedPipeInode {
     }
 
     fn metadata(&self) -> Result<crate::filesystem::vfs::Metadata, SystemError> {
-        let inode = self.0.lock();
+        let inode = self.inner.lock();
         let mut metadata = inode.metadata.clone();
         metadata.size = inode.data.len() as i64;
 
         return Ok(metadata);
     }
 
-    fn close(&self, data: &mut FilePrivateData) -> Result<(), SystemError> {
+    fn close(&self, data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
         let mode: FileMode;
-        if let FilePrivateData::Pipefs(pipe_data) = data {
+        if let FilePrivateData::Pipefs(pipe_data) = &*data {
             mode = pipe_data.mode;
         } else {
             return Err(SystemError::EBADF);
         }
-        let mut guard = self.0.lock();
+        let mut guard = self.inner.lock();
 
         // 写端关闭
         if mode.contains(FileMode::O_WRONLY) {
@@ -286,8 +289,7 @@ impl IndexNode for LockedPipeInode {
             guard.writer -= 1;
             // 如果已经没有写端了,则唤醒读端
             if guard.writer == 0 {
-                guard
-                    .read_wait_queue
+                self.read_wait_queue
                     .wakeup_all(Some(ProcessState::Blocked(true)));
             }
         }
@@ -298,8 +300,7 @@ impl IndexNode for LockedPipeInode {
             guard.reader -= 1;
             // 如果已经没有写端了,则唤醒读端
             if guard.reader == 0 {
-                guard
-                    .write_wait_queue
+                self.write_wait_queue
                     .wakeup_all(Some(ProcessState::Blocked(true)));
             }
         }
@@ -312,11 +313,11 @@ impl IndexNode for LockedPipeInode {
         _offset: usize,
         len: usize,
         buf: &[u8],
-        data: &mut FilePrivateData,
+        data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         // 获取mode
         let mode: FileMode;
-        if let FilePrivateData::Pipefs(pdata) = data {
+        if let FilePrivateData::Pipefs(pdata) = &*data {
             mode = pdata.mode;
         } else {
             return Err(SystemError::EBADF);
@@ -327,7 +328,7 @@ impl IndexNode for LockedPipeInode {
         }
         // 加锁
 
-        let mut inode = self.0.lock();
+        let mut inode = self.inner.lock();
 
         if inode.reader == 0 {
             // TODO: 如果已经没有读端存在了,则向写端进程发送SIGPIPE信号
@@ -337,8 +338,7 @@ impl IndexNode for LockedPipeInode {
 
         while len + inode.valid_cnt as usize > PIPE_BUFF_SIZE {
             // 唤醒读端
-            inode
-                .read_wait_queue
+            self.read_wait_queue
                 .wakeup(Some(ProcessState::Blocked(true)));
 
             // 如果为非阻塞管道,直接返回错误
@@ -350,12 +350,12 @@ impl IndexNode for LockedPipeInode {
             // 解锁并睡眠
             unsafe {
                 let irq_guard = CurrentIrqArch::save_and_disable_irq();
-                inode.write_wait_queue.sleep_without_schedule();
                 drop(inode);
+                self.write_wait_queue.sleep_without_schedule();
                 drop(irq_guard);
             }
             sched();
-            inode = self.0.lock();
+            inode = self.inner.lock();
         }
 
         // 决定要输入的字节
@@ -375,17 +375,15 @@ impl IndexNode for LockedPipeInode {
 
         // 写完后还有位置,则唤醒下一个写者
         if (inode.valid_cnt as usize) < PIPE_BUFF_SIZE {
-            inode
-                .write_wait_queue
+            self.write_wait_queue
                 .wakeup(Some(ProcessState::Blocked(true)));
         }
 
         // 读完后解锁并唤醒等待在读等待队列中的进程
-        inode
-            .read_wait_queue
+        self.read_wait_queue
             .wakeup(Some(ProcessState::Blocked(true)));
 
-        let pollflag = EPollEventType::from_bits_truncate(inode.poll(data)? as u32);
+        let pollflag = EPollEventType::from_bits_truncate(inode.poll(&data)? as u32);
         // 唤醒epoll中等待的进程
         EventPoll::wakeup_epoll(&inode.epitems, pollflag)?;
 
@@ -416,6 +414,6 @@ impl IndexNode for LockedPipeInode {
     }
 
     fn poll(&self, private_data: &FilePrivateData) -> Result<usize, SystemError> {
-        return self.0.lock().poll(private_data);
+        return self.inner.lock().poll(private_data);
     }
 }

+ 6 - 4
kernel/src/ipc/syscall.rs

@@ -12,6 +12,7 @@ use crate::{
         FilePrivateData,
     },
     kerror, kwarn,
+    libs::spinlock::SpinLock,
     mm::VirtAddr,
     process::{Pid, ProcessManager},
     syscall::{user_access::UserBufferWriter, Syscall},
@@ -48,16 +49,17 @@ impl Syscall {
             pipe_ptr.clone(),
             FileMode::O_RDONLY | (flags & FileMode::O_NONBLOCK),
         )?;
-        read_file.private_data =
-            FilePrivateData::Pipefs(PipeFsPrivateData::new(FileMode::O_RDONLY));
+        read_file.private_data = SpinLock::new(FilePrivateData::Pipefs(PipeFsPrivateData::new(
+            FileMode::O_RDONLY,
+        )));
 
         let mut write_file = File::new(
             pipe_ptr.clone(),
             FileMode::O_WRONLY | (flags & (FileMode::O_NONBLOCK | FileMode::O_DIRECT)),
         )?;
-        write_file.private_data = FilePrivateData::Pipefs(PipeFsPrivateData::new(
+        write_file.private_data = SpinLock::new(FilePrivateData::Pipefs(PipeFsPrivateData::new(
             FileMode::O_WRONLY | (flags & (FileMode::O_NONBLOCK | FileMode::O_DIRECT)),
-        ));
+        )));
 
         if flags.contains(FileMode::O_CLOEXEC) {
             read_file.set_close_on_exec(true);

+ 3 - 3
kernel/src/libs/lib_ui/textui.rs

@@ -1,7 +1,7 @@
 use crate::{
     driver::{
         serial::serial8250::send_to_default_serial8250_port,
-        tty::{tty_port::TTY_PORTS, virtual_terminal::virtual_console::CURRENT_VCNUM},
+        tty::{tty_port::tty_port, virtual_terminal::virtual_console::CURRENT_VCNUM},
         video::video_refresh_manager,
     },
     kdebug, kinfo,
@@ -1046,8 +1046,8 @@ pub extern "C" fn rs_textui_putchar(character: u8, fr_color: u32, bk_color: u32)
             "\x1B[38;2;{fr};{fg};{fb};48;2;{br};{bg};{bb}m{}\x1B[0m",
             character as char
         );
-        let port = TTY_PORTS[current_vcnum as usize].clone();
-        let tty = port.port_data().tty();
+        let port = tty_port(current_vcnum as usize);
+        let tty = port.port_data().internal_tty();
         if let Some(tty) = tty {
             send_to_default_serial8250_port(&[character]);
             return tty

+ 3 - 3
kernel/src/libs/printk.rs

@@ -9,7 +9,7 @@ use super::lib_ui::textui::{textui_putstr, FontColor};
 
 use crate::{
     driver::tty::{
-        tty_driver::TtyOperation, tty_port::TTY_PORTS,
+        tty_driver::TtyOperation, tty_port::tty_port,
         virtual_terminal::virtual_console::CURRENT_VCNUM,
     },
     filesystem::procfs::{
@@ -89,8 +89,8 @@ impl PrintkWriter {
         let current_vcnum = CURRENT_VCNUM.load(Ordering::SeqCst);
         if current_vcnum != -1 {
             // tty已经初始化了之后才输出到屏幕
-            let port = TTY_PORTS[current_vcnum as usize].clone();
-            let tty = port.port_data().tty();
+            let port = tty_port(current_vcnum as usize);
+            let tty = port.port_data().internal_tty();
             if let Some(tty) = tty {
                 let _ = tty.write(tty.core(), s.as_bytes(), s.len());
             } else {

+ 7 - 1
kernel/src/libs/wait_queue.rs

@@ -278,11 +278,17 @@ pub struct EventWaitQueue {
     wait_list: SpinLock<Vec<(u64, Arc<ProcessControlBlock>)>>,
 }
 
+impl Default for EventWaitQueue {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
 #[allow(dead_code)]
 impl EventWaitQueue {
     pub fn new() -> Self {
         Self {
-            wait_list: SpinLock::new(Vec::new()),
+            wait_list: SpinLock::new(Default::default()),
         }
     }
 

+ 23 - 23
kernel/src/net/event_poll/mod.rs

@@ -82,7 +82,7 @@ pub struct EPollItem {
     /// 监听的描述符
     fd: i32,
     /// 对应的文件
-    file: Weak<SpinLock<File>>,
+    file: Weak<File>,
 }
 
 impl EPollItem {
@@ -90,7 +90,7 @@ impl EPollItem {
         epoll: Weak<SpinLock<EventPoll>>,
         events: EPollEvent,
         fd: i32,
-        file: Weak<SpinLock<File>>,
+        file: Weak<File>,
     ) -> Self {
         Self {
             epoll,
@@ -108,7 +108,7 @@ impl EPollItem {
         &self.event
     }
 
-    pub fn file(&self) -> Weak<SpinLock<File>> {
+    pub fn file(&self) -> Weak<File> {
         self.file.clone()
     }
 
@@ -122,7 +122,7 @@ impl EPollItem {
         if file.is_none() {
             return EPollEventType::empty();
         }
-        if let Ok(events) = file.unwrap().lock_irqsave().poll() {
+        if let Ok(events) = file.unwrap().poll() {
             let events = events as u32 & self.event.read().events;
             return EPollEventType::from_bits_truncate(events);
         }
@@ -154,7 +154,7 @@ impl IndexNode for EPollInode {
         _offset: usize,
         _len: usize,
         _buf: &mut [u8],
-        _data: &mut crate::filesystem::vfs::FilePrivateData,
+        _data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         Err(SystemError::ENOSYS)
     }
@@ -164,7 +164,7 @@ impl IndexNode for EPollInode {
         _offset: usize,
         _len: usize,
         _buf: &[u8],
-        _data: &mut crate::filesystem::vfs::FilePrivateData,
+        _data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         Err(SystemError::ENOSYS)
     }
@@ -190,7 +190,7 @@ impl IndexNode for EPollInode {
         Ok(Metadata::default())
     }
 
-    fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
+    fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
         // 释放资源
         let mut epoll = self.epoll.0.lock_irqsave();
 
@@ -208,9 +208,7 @@ impl IndexNode for EPollInode {
                 .get_file_by_fd(fd);
 
             if file.is_some() {
-                file.unwrap()
-                    .lock_irqsave()
-                    .remove_epoll(&Arc::downgrade(&self.epoll.0))?;
+                file.unwrap().remove_epoll(&Arc::downgrade(&self.epoll.0))?;
             }
 
             epoll.ep_items.remove(&fd);
@@ -219,7 +217,11 @@ impl IndexNode for EPollInode {
         Ok(())
     }
 
-    fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> {
+    fn open(
+        &self,
+        _data: SpinLockGuard<FilePrivateData>,
+        _mode: &FileMode,
+    ) -> Result<(), SystemError> {
         Ok(())
     }
 }
@@ -250,7 +252,7 @@ impl EventPoll {
         )?;
 
         // 设置ep_file的FilePrivateData
-        ep_file.private_data = FilePrivateData::EPoll(EPollPrivateData { epoll });
+        ep_file.private_data = SpinLock::new(FilePrivateData::EPoll(EPollPrivateData { epoll }));
 
         let current_pcb = ProcessManager::current_pcb();
         let fd_table = current_pcb.fd_table();
@@ -321,7 +323,7 @@ impl EventPoll {
         }
 
         // 从FilePrivateData获取到epoll
-        if let FilePrivateData::EPoll(epoll_data) = &ep_file.lock_irqsave().private_data {
+        if let FilePrivateData::EPoll(epoll_data) = &*ep_file.private_data.lock() {
             let mut epoll_guard = {
                 if nonblock {
                     // 如果设置非阻塞,则尝试获取一次锁
@@ -412,7 +414,7 @@ impl EventPoll {
 
         // 从epoll文件获取到epoll
         let mut epolldata = None;
-        if let FilePrivateData::EPoll(epoll_data) = &ep_file.lock_irqsave().private_data {
+        if let FilePrivateData::EPoll(epoll_data) = &*ep_file.private_data.lock() {
             epolldata = Some(epoll_data.clone())
         }
         if let Some(epoll_data) = epolldata {
@@ -583,8 +585,8 @@ impl EventPoll {
     }
 
     // ### 查看文件是否为epoll文件
-    fn is_epoll_file(file: &Arc<SpinLock<File>>) -> bool {
-        if let FilePrivateData::EPoll(_) = file.lock_irqsave().private_data {
+    fn is_epoll_file(file: &Arc<File>) -> bool {
+        if let FilePrivateData::EPoll(_) = *file.private_data.lock() {
             return true;
         }
         return false;
@@ -592,7 +594,7 @@ impl EventPoll {
 
     fn ep_insert(
         epoll_guard: &mut SpinLockGuard<EventPoll>,
-        dst_file: Arc<SpinLock<File>>,
+        dst_file: Arc<File>,
         epitem: Arc<EPollItem>,
     ) -> Result<(), SystemError> {
         if Self::is_epoll_file(&dst_file) {
@@ -600,7 +602,7 @@ impl EventPoll {
             // TODO:现在的实现先不考虑嵌套其它类型的文件(暂时只针对socket),这里的嵌套指epoll/select/poll
         }
 
-        let test_poll = dst_file.lock_irqsave().poll();
+        let test_poll = dst_file.poll();
         if test_poll.is_err() && test_poll.unwrap_err() == SystemError::EOPNOTSUPP_OR_ENOTSUP {
             // 如果目标文件不支持poll
             return Err(SystemError::ENOSYS);
@@ -624,19 +626,17 @@ impl EventPoll {
             return Err(SystemError::ENOSYS);
         }
 
-        dst_file.lock_irqsave().add_epoll(epitem.clone())?;
+        dst_file.add_epoll(epitem.clone())?;
         Ok(())
     }
 
     pub fn ep_remove(
         epoll: &mut SpinLockGuard<EventPoll>,
         fd: i32,
-        dst_file: Option<Arc<SpinLock<File>>>,
+        dst_file: Option<Arc<File>>,
     ) -> Result<(), SystemError> {
         if let Some(dst_file) = dst_file {
-            let mut file_guard = dst_file.lock_irqsave();
-
-            file_guard.remove_epoll(epoll.self_ref.as_ref().unwrap())?;
+            dst_file.remove_epoll(epoll.self_ref.as_ref().unwrap())?;
         }
 
         let epitem = epoll.ep_items.remove(&fd).unwrap();

+ 8 - 4
kernel/src/net/socket/mod.rs

@@ -299,12 +299,16 @@ impl SocketInode {
 }
 
 impl IndexNode for SocketInode {
-    fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> {
+    fn open(
+        &self,
+        _data: SpinLockGuard<FilePrivateData>,
+        _mode: &FileMode,
+    ) -> Result<(), SystemError> {
         self.1.fetch_add(1, core::sync::atomic::Ordering::SeqCst);
         Ok(())
     }
 
-    fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
+    fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
         let prev_ref_count = self.1.fetch_sub(1, core::sync::atomic::Ordering::SeqCst);
         if prev_ref_count == 1 {
             // 最后一次关闭,需要释放
@@ -333,7 +337,7 @@ impl IndexNode for SocketInode {
         _offset: usize,
         len: usize,
         buf: &mut [u8],
-        _data: &mut FilePrivateData,
+        _data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         self.0.lock_no_preempt().read(&mut buf[0..len]).0
     }
@@ -343,7 +347,7 @@ impl IndexNode for SocketInode {
         _offset: usize,
         len: usize,
         buf: &[u8],
-        _data: &mut FilePrivateData,
+        _data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         self.0.lock_no_preempt().write(&buf[0..len], None)
     }

+ 1 - 2
kernel/src/net/syscall.rs

@@ -603,8 +603,7 @@ impl SockAddr {
                     let binding = ProcessManager::current_pcb().fd_table();
                     let fd_table_guard = binding.read();
 
-                    let binding = fd_table_guard.get_file_by_fd(fd as i32).unwrap();
-                    let file = binding.lock();
+                    let file = fd_table_guard.get_file_by_fd(fd as i32).unwrap();
                     if file.file_type() != FileType::Socket {
                         return Err(SystemError::ENOTSOCK);
                     }

+ 2 - 3
kernel/src/process/mod.rs

@@ -822,11 +822,10 @@ impl ProcessControlBlock {
         let f = fd_table_guard.get_file_by_fd(fd)?;
         drop(fd_table_guard);
 
-        let guard = f.lock();
-        if guard.file_type() != FileType::Socket {
+        if f.file_type() != FileType::Socket {
             return None;
         }
-        let socket: Arc<SocketInode> = guard
+        let socket: Arc<SocketInode> = f
             .inode()
             .downcast_arc::<SocketInode>()
             .expect("Not a socket inode");

+ 14 - 0
kernel/src/syscall/mod.rs

@@ -862,6 +862,10 @@ impl Syscall {
                 kwarn!("SYS_SETGID has not yet been implemented");
                 Ok(0)
             }
+            SYS_SETSID => {
+                kwarn!("SYS_SETSID has not yet been implemented");
+                Ok(0)
+            }
             SYS_GETEUID => Self::geteuid(),
             SYS_GETEGID => Self::getegid(),
             SYS_GETRUSAGE => {
@@ -944,6 +948,16 @@ impl Syscall {
                 Ok(0)
             }
 
+            SYS_SET_ROBUST_LIST => {
+                kwarn!("SYS_SET_ROBUST_LIST has not yet been implemented");
+                Ok(0)
+            }
+
+            SYS_RSEQ => {
+                kwarn!("SYS_RSEQ has not yet been implemented");
+                Ok(0)
+            }
+
             #[cfg(target_arch = "x86_64")]
             SYS_CHMOD => {
                 let pathname = args[0] as *const u8;

+ 9 - 4
kernel/src/virt/kvm/kvm_dev.rs

@@ -5,6 +5,7 @@ use crate::filesystem::vfs::{
     file::{File, FileMode},
     FilePrivateData, FileSystem, FileType, IndexNode, Metadata,
 };
+use crate::libs::spinlock::SpinLockGuard;
 use crate::process::ProcessManager;
 use crate::{arch::KVMArch, libs::spinlock::SpinLock, time::TimeSpec};
 use crate::{filesystem, kdebug};
@@ -88,12 +89,16 @@ impl IndexNode for LockedKvmInode {
         self
     }
 
-    fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> {
+    fn open(
+        &self,
+        _data: SpinLockGuard<FilePrivateData>,
+        _mode: &FileMode,
+    ) -> Result<(), SystemError> {
         kdebug!("file private data:{:?}", _data);
         return Ok(());
     }
 
-    fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
+    fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
         return Ok(());
     }
 
@@ -158,7 +163,7 @@ impl IndexNode for LockedKvmInode {
         _offset: usize,
         _len: usize,
         _buf: &mut [u8],
-        _data: &mut FilePrivateData,
+        _data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         Err(SystemError::EOPNOTSUPP_OR_ENOTSUP)
     }
@@ -169,7 +174,7 @@ impl IndexNode for LockedKvmInode {
         _offset: usize,
         _len: usize,
         _buf: &[u8],
-        _data: &mut FilePrivateData,
+        _data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         Err(SystemError::EOPNOTSUPP_OR_ENOTSUP)
     }

+ 9 - 4
kernel/src/virt/kvm/vcpu_dev.rs

@@ -6,6 +6,7 @@ use crate::filesystem::vfs::{
     core::generate_inode_id, file::FileMode, FilePrivateData, FileSystem, FileType, IndexNode,
     Metadata,
 };
+use crate::libs::spinlock::SpinLockGuard;
 use crate::mm::VirtAddr;
 use crate::syscall::user_access::copy_from_user;
 use crate::virt::kvm::vcpu::Vcpu;
@@ -96,12 +97,16 @@ impl IndexNode for LockedVcpuInode {
         self
     }
 
-    fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> {
+    fn open(
+        &self,
+        _data: SpinLockGuard<FilePrivateData>,
+        _mode: &FileMode,
+    ) -> Result<(), SystemError> {
         kdebug!("file private data:{:?}", _data);
         return Ok(());
     }
 
-    fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
+    fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
         return Ok(());
     }
 
@@ -197,7 +202,7 @@ impl IndexNode for LockedVcpuInode {
         _offset: usize,
         _len: usize,
         _buf: &mut [u8],
-        _data: &mut FilePrivateData,
+        _data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         Err(SystemError::EOPNOTSUPP_OR_ENOTSUP)
     }
@@ -208,7 +213,7 @@ impl IndexNode for LockedVcpuInode {
         _offset: usize,
         _len: usize,
         _buf: &[u8],
-        _data: &mut FilePrivateData,
+        _data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         Err(SystemError::EOPNOTSUPP_OR_ENOTSUP)
     }

+ 9 - 4
kernel/src/virt/kvm/vm_dev.rs

@@ -5,6 +5,7 @@ use crate::filesystem::vfs::{
     file::{File, FileMode},
     FilePrivateData, FileSystem, FileType, IndexNode, Metadata,
 };
+use crate::libs::spinlock::SpinLockGuard;
 use crate::mm::VirtAddr;
 use crate::process::ProcessManager;
 use crate::syscall::user_access::copy_from_user;
@@ -94,12 +95,16 @@ impl IndexNode for LockedVmInode {
         self
     }
 
-    fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> {
+    fn open(
+        &self,
+        _data: SpinLockGuard<FilePrivateData>,
+        _mode: &FileMode,
+    ) -> Result<(), SystemError> {
         kdebug!("file private data:{:?}", _data);
         return Ok(());
     }
 
-    fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
+    fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
         return Ok(());
     }
 
@@ -190,7 +195,7 @@ impl IndexNode for LockedVmInode {
         _offset: usize,
         _len: usize,
         _buf: &mut [u8],
-        _data: &mut FilePrivateData,
+        _data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         Err(SystemError::EOPNOTSUPP_OR_ENOTSUP)
     }
@@ -201,7 +206,7 @@ impl IndexNode for LockedVmInode {
         _offset: usize,
         _len: usize,
         _buf: &[u8],
-        _data: &mut FilePrivateData,
+        _data: SpinLockGuard<FilePrivateData>,
     ) -> Result<usize, SystemError> {
         Err(SystemError::EOPNOTSUPP_OR_ENOTSUP)
     }

+ 20 - 0
user/apps/test_pty/Makefile

@@ -0,0 +1,20 @@
+ifeq ($(ARCH), x86_64)
+	CROSS_COMPILE=x86_64-linux-musl-
+else ifeq ($(ARCH), riscv64)
+	CROSS_COMPILE=riscv64-linux-musl-
+endif
+
+CC=$(CROSS_COMPILE)gcc
+
+
+all:
+	$(CC) -static -o test_pty test_pty.c
+
+.PHONY: install clean
+install: all
+	mv test_pty $(DADK_CURRENT_BUILD_DIR)/test_pty
+
+clean:
+	rm test_pty *.o
+
+fmt:

+ 49 - 0
user/apps/test_pty/test_pty.c

@@ -0,0 +1,49 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <termios.h>
+#include <pty.h>
+
+int main()
+{
+	int ptm, pts;
+	char name[256];
+	struct termios term;
+
+	if (openpty(&ptm, &pts, name, NULL, NULL) == -1) {
+		perror("openpty");
+		exit(EXIT_FAILURE);
+	}
+
+	printf("slave name: %s fd: %d\n", name,pts);
+
+	tcgetattr(pts, &term);
+	term.c_lflag &= ~(ICANON | ECHO);
+	term.c_cc[VMIN] = 1;
+	term.c_cc[VTIME] = 0;
+	tcsetattr(pts, TCSANOW, &term);
+	
+	printf("before print to pty slave\n");
+
+	dprintf(pts, "Hello world!\n");
+
+	char buf[256];
+	ssize_t n = read(ptm, buf, sizeof(buf));
+	if (n > 0) {
+		printf("read %ld bytes from slave: %.*s", n, (int)n, buf);
+	}
+
+	dprintf(ptm, "hello world from master\n");
+
+	char nbuf[256];
+	ssize_t nn = read(pts, nbuf, sizeof(nbuf));
+	if (nn > 0) {
+		printf("read %ld bytes from master: %.*s", nn, (int)nn, nbuf);
+	}
+
+	close(ptm);
+	close(pts);
+
+	return 0;
+}

+ 23 - 0
user/dadk/config/test_pty-0.1.0.dadk

@@ -0,0 +1,23 @@
+{
+  "name": "test_pty",
+  "version": "0.1.0",
+  "description": "简单的pty测试程序",
+  "task_type": {
+    "BuildFromSource": {
+      "Local": {
+        "path": "apps/test_pty"
+      }
+    }
+  },
+  "depends": [],
+  "build": {
+    "build_command": "make install -j $(nproc)"
+  },
+  "install": {
+    "in_dragonos_path": "/bin"
+  },
+  "clean": {
+    "clean_command": "make clean"
+  },
+  "envs": []
+}