From bbfc2cd12db35cdf72f1cac61cc0320d4284c136 Mon Sep 17 00:00:00 2001 From: Ruihan Li Date: Mon, 2 Sep 2024 14:31:20 +0800 Subject: [PATCH] Make `FileIo` pollable --- kernel/src/device/null.rs | 19 ++++++---- kernel/src/device/pty/pty.rs | 50 ++++++++++++++------------ kernel/src/device/random.rs | 14 ++++---- kernel/src/device/tdxguest/mod.rs | 12 ++++--- kernel/src/device/tty/device.rs | 12 ++++--- kernel/src/device/tty/mod.rs | 12 ++++--- kernel/src/device/urandom.rs | 14 ++++---- kernel/src/device/zero.rs | 19 ++++++---- kernel/src/fs/device.rs | 2 +- kernel/src/fs/devpts/ptmx.rs | 16 ++++++--- kernel/src/fs/devpts/slave.rs | 5 ++- kernel/src/fs/inode_handle/mod.rs | 9 ++--- kernel/src/process/process/terminal.rs | 2 +- 13 files changed, 112 insertions(+), 74 deletions(-) diff --git a/kernel/src/device/null.rs b/kernel/src/device/null.rs index 697303561..abdde9411 100644 --- a/kernel/src/device/null.rs +++ b/kernel/src/device/null.rs @@ -3,7 +3,12 @@ #![allow(unused_variables)] use super::*; -use crate::{events::IoEvents, fs::inode_handle::FileIo, prelude::*, process::signal::Poller}; +use crate::{ + events::IoEvents, + fs::inode_handle::FileIo, + prelude::*, + process::signal::{Pollable, Poller}, +}; pub struct Null; @@ -22,6 +27,13 @@ impl Device for Null { } } +impl Pollable for Null { + fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents { + let events = IoEvents::IN | IoEvents::OUT; + events & mask + } +} + impl FileIo for Null { fn read(&self, _writer: &mut VmWriter) -> Result { Ok(0) @@ -30,9 +42,4 @@ impl FileIo for Null { fn write(&self, reader: &mut VmReader) -> Result { Ok(reader.remain()) } - - fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents { - let events = IoEvents::IN | IoEvents::OUT; - events & mask - } } diff --git a/kernel/src/device/pty/pty.rs b/kernel/src/device/pty/pty.rs index 58b5216ea..4ffb74402 100644 --- a/kernel/src/device/pty/pty.rs +++ b/kernel/src/device/pty/pty.rs @@ -16,7 +16,7 @@ use crate::{ get_current_userspace, prelude::*, process::{ - signal::{Pollee, Poller}, + signal::{Pollable, Pollee, Poller}, JobControl, Terminal, }, util::ring_buffer::RingBuffer, @@ -98,6 +98,26 @@ impl PtyMaster { } } +impl Pollable for PtyMaster { + fn poll(&self, mask: IoEvents, mut poller: Option<&mut Poller>) -> IoEvents { + let mut poll_status = IoEvents::empty(); + + let poll_in_mask = mask & IoEvents::IN; + if !poll_in_mask.is_empty() { + let poll_in_status = self.pollee.poll(poll_in_mask, poller.as_deref_mut()); + poll_status |= poll_in_status; + } + + let poll_out_mask = mask & IoEvents::OUT; + if !poll_out_mask.is_empty() { + let poll_out_status = self.output.poll(poll_out_mask, poller); + poll_status |= poll_out_status; + } + + poll_status + } +} + impl FileIo for PtyMaster { fn read(&self, writer: &mut VmWriter) -> Result { let read_len = writer.avail(); @@ -245,24 +265,6 @@ impl FileIo for PtyMaster { _ => Ok(0), } } - - fn poll(&self, mask: IoEvents, mut poller: Option<&mut Poller>) -> IoEvents { - let mut poll_status = IoEvents::empty(); - - let poll_in_mask = mask & IoEvents::IN; - if !poll_in_mask.is_empty() { - let poll_in_status = self.pollee.poll(poll_in_mask, poller.as_deref_mut()); - poll_status |= poll_in_status; - } - - let poll_out_mask = mask & IoEvents::OUT; - if !poll_out_mask.is_empty() { - let poll_out_status = self.output.poll(poll_out_mask, poller); - poll_status |= poll_out_status; - } - - poll_status - } } impl Terminal for PtyMaster { @@ -329,6 +331,12 @@ impl Terminal for PtySlave { } } +impl Pollable for PtySlave { + fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents { + self.master().slave_poll(mask, poller) + } +} + impl FileIo for PtySlave { fn read(&self, writer: &mut VmWriter) -> Result { let mut buf = vec![0u8; writer.avail()]; @@ -354,10 +362,6 @@ impl FileIo for PtySlave { Ok(write_len) } - fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents { - self.master().slave_poll(mask, poller) - } - fn ioctl(&self, cmd: IoctlCmd, arg: usize) -> Result { match cmd { IoctlCmd::TCGETS diff --git a/kernel/src/device/random.rs b/kernel/src/device/random.rs index 0065ee631..c11f29368 100644 --- a/kernel/src/device/random.rs +++ b/kernel/src/device/random.rs @@ -9,7 +9,7 @@ use crate::{ inode_handle::FileIo, }, prelude::*, - process::signal::Poller, + process::signal::{Pollable, Poller}, util::random::getrandom, }; @@ -37,6 +37,13 @@ impl Device for Random { } } +impl Pollable for Random { + fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents { + let events = IoEvents::IN | IoEvents::OUT; + events & mask + } +} + impl FileIo for Random { fn read(&self, writer: &mut VmWriter) -> Result { let mut buf = vec![0; writer.avail()]; @@ -46,9 +53,4 @@ impl FileIo for Random { fn write(&self, reader: &mut VmReader) -> Result { Ok(reader.remain()) } - - fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents { - let events = IoEvents::IN | IoEvents::OUT; - events & mask - } } diff --git a/kernel/src/device/tdxguest/mod.rs b/kernel/src/device/tdxguest/mod.rs index aa4bcd980..d8f80b129 100644 --- a/kernel/src/device/tdxguest/mod.rs +++ b/kernel/src/device/tdxguest/mod.rs @@ -57,6 +57,13 @@ impl From for Error { } } +impl Pollable for TdxGuest { + fn poll(&self, mask: IoEvents, _poller: Option<&mut Poller>) -> IoEvents { + let events = IoEvents::IN | IoEvents::OUT; + events & mask + } +} + impl FileIo for TdxGuest { fn read(&self, _writer: &mut VmWriter) -> Result { return_errno_with_message!(Errno::EPERM, "Read operation not supported") @@ -72,11 +79,6 @@ impl FileIo for TdxGuest { _ => return_errno_with_message!(Errno::EPERM, "Unsupported ioctl"), } } - - fn poll(&self, mask: IoEvents, _poller: Option<&mut Poller>) -> IoEvents { - let events = IoEvents::IN | IoEvents::OUT; - events & mask - } } fn handle_get_report(arg: usize) -> Result { diff --git a/kernel/src/device/tty/device.rs b/kernel/src/device/tty/device.rs index 106ad864b..ec9f1ba8e 100644 --- a/kernel/src/device/tty/device.rs +++ b/kernel/src/device/tty/device.rs @@ -9,7 +9,7 @@ use crate::{ inode_handle::FileIo, }, prelude::*, - process::signal::Poller, + process::signal::{Pollable, Poller}, }; /// Corresponds to `/dev/tty` in the file system. This device represents the controlling terminal @@ -40,6 +40,12 @@ impl Device for TtyDevice { } } +impl Pollable for TtyDevice { + fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents { + IoEvents::empty() + } +} + impl FileIo for TtyDevice { fn read(&self, writer: &mut VmWriter) -> Result { return_errno_with_message!(Errno::EINVAL, "cannot read tty device"); @@ -48,8 +54,4 @@ impl FileIo for TtyDevice { fn write(&self, reader: &mut VmReader) -> Result { return_errno_with_message!(Errno::EINVAL, "cannot write tty device"); } - - fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents { - IoEvents::empty() - } } diff --git a/kernel/src/device/tty/mod.rs b/kernel/src/device/tty/mod.rs index 5b0d2a72b..cf2be1e6e 100644 --- a/kernel/src/device/tty/mod.rs +++ b/kernel/src/device/tty/mod.rs @@ -16,7 +16,7 @@ use crate::{ get_current_userspace, prelude::*, process::{ - signal::{signals::kernel::KernelSignal, Poller}, + signal::{signals::kernel::KernelSignal, Pollable, Poller}, JobControl, Process, Terminal, }, }; @@ -72,6 +72,12 @@ impl Tty { } } +impl Pollable for Tty { + fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents { + self.ldisc.poll(mask, poller) + } +} + impl FileIo for Tty { fn read(&self, writer: &mut VmWriter) -> Result { let mut buf = vec![0; writer.avail()]; @@ -91,10 +97,6 @@ impl FileIo for Tty { Ok(buf.len()) } - fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents { - self.ldisc.poll(mask, poller) - } - fn ioctl(&self, cmd: IoctlCmd, arg: usize) -> Result { match cmd { IoctlCmd::TCGETS => { diff --git a/kernel/src/device/urandom.rs b/kernel/src/device/urandom.rs index c3b4d8aa4..08e97665e 100644 --- a/kernel/src/device/urandom.rs +++ b/kernel/src/device/urandom.rs @@ -9,7 +9,7 @@ use crate::{ inode_handle::FileIo, }, prelude::*, - process::signal::Poller, + process::signal::{Pollable, Poller}, util::random::getrandom, }; @@ -37,6 +37,13 @@ impl Device for Urandom { } } +impl Pollable for Urandom { + fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents { + let events = IoEvents::IN | IoEvents::OUT; + events & mask + } +} + impl FileIo for Urandom { fn read(&self, writer: &mut VmWriter) -> Result { let mut buf = vec![0; writer.avail()]; @@ -46,9 +53,4 @@ impl FileIo for Urandom { fn write(&self, reader: &mut VmReader) -> Result { Ok(reader.remain()) } - - fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents { - let events = IoEvents::IN | IoEvents::OUT; - events & mask - } } diff --git a/kernel/src/device/zero.rs b/kernel/src/device/zero.rs index bd038edaf..46afa495f 100644 --- a/kernel/src/device/zero.rs +++ b/kernel/src/device/zero.rs @@ -3,7 +3,12 @@ #![allow(unused_variables)] use super::*; -use crate::{events::IoEvents, fs::inode_handle::FileIo, prelude::*, process::signal::Poller}; +use crate::{ + events::IoEvents, + fs::inode_handle::FileIo, + prelude::*, + process::signal::{Pollable, Poller}, +}; pub struct Zero; @@ -22,6 +27,13 @@ impl Device for Zero { } } +impl Pollable for Zero { + fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents { + let events = IoEvents::IN | IoEvents::OUT; + events & mask + } +} + impl FileIo for Zero { fn read(&self, writer: &mut VmWriter) -> Result { let read_len = writer.fill_zeros(writer.avail())?; @@ -31,9 +43,4 @@ impl FileIo for Zero { fn write(&self, reader: &mut VmReader) -> Result { Ok(reader.remain()) } - - fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents { - let events = IoEvents::IN | IoEvents::OUT; - events & mask - } } diff --git a/kernel/src/fs/device.rs b/kernel/src/fs/device.rs index 8aa9e1315..6a6a7bdc6 100644 --- a/kernel/src/fs/device.rs +++ b/kernel/src/fs/device.rs @@ -11,7 +11,7 @@ use crate::{ }; /// The abstract of device -pub trait Device: Sync + Send + FileIo { +pub trait Device: FileIo { /// Return the device type. fn type_(&self) -> DeviceType; diff --git a/kernel/src/fs/devpts/ptmx.rs b/kernel/src/fs/devpts/ptmx.rs index 6c83447b7..30397c8c2 100644 --- a/kernel/src/fs/devpts/ptmx.rs +++ b/kernel/src/fs/devpts/ptmx.rs @@ -4,7 +4,11 @@ #![allow(unused_variables)] use super::*; -use crate::{events::IoEvents, fs::inode_handle::FileIo, process::signal::Poller}; +use crate::{ + events::IoEvents, + fs::inode_handle::FileIo, + process::signal::{Pollable, Poller}, +}; /// Same major number with Linux. const PTMX_MAJOR_NUM: u32 = 5; @@ -177,6 +181,12 @@ impl Device for Inner { } } +impl Pollable for Inner { + fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents { + IoEvents::empty() + } +} + impl FileIo for Inner { fn read(&self, writer: &mut VmWriter) -> Result { return_errno_with_message!(Errno::EINVAL, "cannot read ptmx"); @@ -185,8 +195,4 @@ impl FileIo for Inner { fn write(&self, reader: &mut VmReader) -> Result { return_errno_with_message!(Errno::EINVAL, "cannot write ptmx"); } - - fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents { - IoEvents::empty() - } } diff --git a/kernel/src/fs/devpts/slave.rs b/kernel/src/fs/devpts/slave.rs index 282564db1..12f2f8959 100644 --- a/kernel/src/fs/devpts/slave.rs +++ b/kernel/src/fs/devpts/slave.rs @@ -5,7 +5,10 @@ use super::*; use crate::{ - device::PtySlave, events::IoEvents, fs::inode_handle::FileIo, process::signal::Poller, + device::PtySlave, + events::IoEvents, + fs::inode_handle::FileIo, + process::signal::{Pollable, Poller}, }; /// Same major number with Linux, the minor number is the index of slave. diff --git a/kernel/src/fs/inode_handle/mod.rs b/kernel/src/fs/inode_handle/mod.rs index 6d759f9aa..5ae6f16bd 100644 --- a/kernel/src/fs/inode_handle/mod.rs +++ b/kernel/src/fs/inode_handle/mod.rs @@ -25,7 +25,10 @@ use crate::{ }, }, prelude::*, - process::{signal::Poller, Gid, Uid}, + process::{ + signal::{Pollable, Poller}, + Gid, Uid, + }, }; #[derive(Debug)] @@ -389,13 +392,11 @@ impl Drop for InodeHandle { } } -pub trait FileIo: Send + Sync + 'static { +pub trait FileIo: Pollable + Send + Sync + 'static { fn read(&self, writer: &mut VmWriter) -> Result; fn write(&self, reader: &mut VmReader) -> Result; - fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents; - fn ioctl(&self, cmd: IoctlCmd, arg: usize) -> Result { return_errno_with_message!(Errno::EINVAL, "ioctl is not supported"); } diff --git a/kernel/src/process/process/terminal.rs b/kernel/src/process/process/terminal.rs index bd1c2e489..9c9172866 100644 --- a/kernel/src/process/process/terminal.rs +++ b/kernel/src/process/process/terminal.rs @@ -11,7 +11,7 @@ use crate::{ /// job control. /// /// We currently support two kinds of terminal, the tty and pty. -pub trait Terminal: Send + Sync + FileIo { +pub trait Terminal: FileIo { // *************** Foreground *************** /// Returns the foreground process group