Skip to content

Commit

Permalink
traits for devices as a replacement for cdevsw
Browse files Browse the repository at this point in the history
  • Loading branch information
tompro committed Feb 17, 2024
1 parent 5d3eb17 commit 09626de
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 14 deletions.
51 changes: 50 additions & 1 deletion src/kernel/src/fs/dev/cdev.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use super::dirent::Dirent;
use crate::errno::Errno;
use crate::errno::ENODEV;
use crate::fs::{IoCmd, Mode, OpenFlags, VFile};
use crate::fs::Uio;
use crate::fs::{FileBackend, IoCmd, Mode, OpenFlags, Stat, TruncateLength, UioMut, VFile};
use crate::process::VThread;
use crate::time::TimeSpec;
use crate::ucred::{Gid, Ucred, Uid};
Expand Down Expand Up @@ -102,6 +103,53 @@ impl Cdev {
}
}

impl FileBackend for Cdev {
#[allow(unused_variables)] // TODO: remove when implementing
fn read(
self: &Arc<Self>,
file: &VFile,
buf: &mut UioMut,
td: Option<&VThread>,
) -> Result<usize, Box<dyn Errno>> {
todo!()
}

#[allow(unused_variables)] // TODO: remove when implementing
fn write(
self: &Arc<Self>,
file: &VFile,
buf: &mut Uio,
td: Option<&VThread>,
) -> Result<usize, Box<dyn Errno>> {
todo!()
}

#[allow(unused_variables)] // TODO: remove when implementing
fn ioctl(
self: &Arc<Self>,
file: &VFile,
cmd: IoCmd,
td: Option<&VThread>,
) -> Result<(), Box<dyn Errno>> {
todo!()
}

#[allow(unused_variables)] // TODO: remove when implementing
fn stat(self: &Arc<Self>, file: &VFile, td: Option<&VThread>) -> Result<Stat, Box<dyn Errno>> {
todo!()
}

#[allow(unused_variables)] // TODO: remove when implementing
fn truncate(
self: &Arc<Self>,
file: &VFile,
length: TruncateLength,
td: Option<&VThread>,
) -> Result<(), Box<dyn Errno>> {
todo!()
}
}

bitflags! {
/// Flags for [`Cdev`].
#[derive(Debug, Clone, Copy)]
Expand Down Expand Up @@ -154,6 +202,7 @@ pub type CdevOpen = fn(&Arc<Cdev>, OpenFlags, i32, Option<&VThread>) -> Result<(
pub type CdevFd =
fn(&Arc<Cdev>, OpenFlags, Option<&VThread>, Option<&mut VFile>) -> Result<(), Box<dyn Errno>>;

/// An implementation of the `cdevsw` structure.
pub(super) trait Device: Debug + Sync + Send + 'static {
#[allow(unused_variables)]
fn read(
Expand Down
28 changes: 17 additions & 11 deletions src/kernel/src/fs/file.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{IoCmd, Offset, Stat, TruncateLength, Uio, UioMut, Vnode};
use super::{Cdev, IoCmd, Offset, Stat, TruncateLength, Uio, UioMut, Vnode};
use crate::dmem::BlockPool;
use crate::errno::Errno;
use crate::errno::{EINVAL, ENOTTY, ENXIO, EOPNOTSUPP};
Expand All @@ -16,14 +16,14 @@ use thiserror::Error;
/// An implementation of `file` structure.
#[derive(Debug)]
pub struct VFile {
backend: VFileType, // f_type
flags: VFileFlags, // f_flag
ty: VFileType, // f_type
flags: VFileFlags, // f_flag
}

impl VFile {
pub(super) fn new(backend: VFileType) -> Self {
pub(super) fn new(ty: VFileType) -> Self {
Self {
backend,
ty,
flags: VFileFlags::empty(),
}
}
Expand Down Expand Up @@ -82,42 +82,46 @@ impl VFile {
}

fn read(&self, buf: &mut UioMut, td: Option<&VThread>) -> Result<usize, Box<dyn Errno>> {
match &self.backend {
match &self.ty {
VFileType::Vnode(vn) => vn.read(self, buf, td),
VFileType::Socket(so) | VFileType::IpcSocket(so) => so.read(self, buf, td),
VFileType::KernelQueue(kq) => kq.read(self, buf, td),
VFileType::SharedMemory(shm) => shm.read(self, buf, td),
VFileType::Device(dev) => dev.read(self, buf, td),
VFileType::Blockpool(bp) => bp.read(self, buf, td),
}
}

fn write(&self, buf: &mut Uio, td: Option<&VThread>) -> Result<usize, Box<dyn Errno>> {
match &self.backend {
match &self.ty {
VFileType::Vnode(vn) => vn.write(self, buf, td),
VFileType::Socket(so) | VFileType::IpcSocket(so) => so.write(self, buf, td),
VFileType::KernelQueue(kq) => kq.write(self, buf, td),
VFileType::SharedMemory(shm) => shm.write(self, buf, td),
VFileType::Device(dev) => dev.write(self, buf, td),
VFileType::Blockpool(bp) => bp.write(self, buf, td),
}
}

/// See `fo_ioctl` on the PS4 for a reference.
pub fn ioctl(&self, cmd: IoCmd, td: Option<&VThread>) -> Result<(), Box<dyn Errno>> {
match &self.backend {
match &self.ty {
VFileType::Vnode(vn) => vn.ioctl(self, cmd, td),
VFileType::Socket(so) | VFileType::IpcSocket(so) => so.ioctl(self, cmd, td),
VFileType::KernelQueue(kq) => kq.ioctl(self, cmd, td),
VFileType::SharedMemory(shm) => shm.ioctl(self, cmd, td),
VFileType::Device(dev) => dev.ioctl(self, cmd, td),
VFileType::Blockpool(bp) => bp.ioctl(self, cmd, td),
}
}

pub fn stat(&self, td: Option<&VThread>) -> Result<Stat, Box<dyn Errno>> {
match &self.backend {
match &self.ty {
VFileType::Vnode(vn) => vn.stat(self, td),
VFileType::Socket(so) | VFileType::IpcSocket(so) => so.stat(self, td),
VFileType::KernelQueue(kq) => kq.stat(self, td),
VFileType::SharedMemory(shm) => shm.stat(self, td),
VFileType::Device(dev) => dev.stat(self, td),
VFileType::Blockpool(bp) => bp.stat(self, td),
}
}
Expand All @@ -127,17 +131,18 @@ impl VFile {
length: TruncateLength,
td: Option<&VThread>,
) -> Result<(), Box<dyn Errno>> {
match &self.backend {
match &self.ty {
VFileType::Vnode(vn) => vn.truncate(self, length, td),
VFileType::Socket(so) | VFileType::IpcSocket(so) => so.truncate(self, length, td),
VFileType::KernelQueue(kq) => kq.truncate(self, length, td),
VFileType::SharedMemory(shm) => shm.truncate(self, length, td),
VFileType::Device(dev) => dev.truncate(self, length, td),
VFileType::Blockpool(bp) => bp.truncate(self, length, td),
}
}

pub fn is_seekable(&self) -> bool {
matches!(self.backend, VFileType::Vnode(_))
matches!(self.ty, VFileType::Vnode(_) | VFileType::Device(_))
}
}

Expand Down Expand Up @@ -170,6 +175,7 @@ pub enum VFileType {
Socket(Arc<Socket>), // DTYPE_SOCKET = 2,
KernelQueue(Arc<KernelQueue>), // DTYPE_KQUEUE = 5,
SharedMemory(Arc<Shm>), // DTYPE_SHM = 8,
Device(Arc<Cdev>), // DTYPE_DEV = 11,
IpcSocket(Arc<Socket>), // DTYPE_IPCSOCKET = 15,
Blockpool(Arc<BlockPool>), // DTYPE_BLOCKPOOL = 17,
}
Expand Down
4 changes: 2 additions & 2 deletions src/kernel/src/fs/vnode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ impl Vnode {
fs: &Arc<Mount>,
ty: VnodeType,
tag: &'static str,
backend: impl VnodeBackend + 'static,
backend: impl VnodeBackend,
) -> Arc<Self> {
let gg = GutexGroup::new();

Expand Down Expand Up @@ -191,7 +191,7 @@ pub enum VnodeType {
/// `vop_bypass` because it required the return type for all operations to be the same.
///
/// All default implementation here are the implementation of `default_vnodeops`.
pub(super) trait VnodeBackend: Debug + Send + Sync {
pub(super) trait VnodeBackend: Debug + Send + Sync + 'static {
/// An implementation of `vop_access`.
fn access(
self: Arc<Self>,
Expand Down

0 comments on commit 09626de

Please sign in to comment.