Skip to content

Commit

Permalink
Implements devfs_populate (#535)
Browse files Browse the repository at this point in the history
  • Loading branch information
ultimaweapon authored Dec 29, 2023
1 parent 1660e54 commit 901c7eb
Show file tree
Hide file tree
Showing 10 changed files with 306 additions and 55 deletions.
6 changes: 5 additions & 1 deletion src/kernel/src/errno.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,11 @@ pub trait Errno: Error {
fn errno(&self) -> NonZeroI32;
}

impl Error for Box<dyn Errno> {}
impl Error for Box<dyn Errno> {
fn source(&self) -> Option<&(dyn Error + 'static)> {
self.as_ref().source()
}
}

/// Get human readable text.
pub fn strerror(num: NonZeroI32) -> &'static str {
Expand Down
60 changes: 45 additions & 15 deletions src/kernel/src/fs/cdev.rs → src/kernel/src/fs/dev/cdev.rs
Original file line number Diff line number Diff line change
@@ -1,38 +1,42 @@
use super::dirent::Dirent;
use crate::ucred::Ucred;
use bitflags::bitflags;
use std::sync::Arc;
use gmtx::{Gutex, GutexGroup, GutexReadGuard, GutexWriteGuard};
use std::sync::{Arc, Weak};
use std::time::SystemTime;

/// An implementation of `cdev` and `cdev_priv` structures.
#[derive(Debug)]
pub struct Cdev {
sw: Arc<CdevSw>, // si_devsw
inode: u32, // cdp_inode
unit: i32, // si_drv0
name: String, // si_name
uid: i32, // si_uid
gid: i32, // si_gid
mode: u16, // si_mode
ctime: SystemTime, // si_ctime
atime: SystemTime, // si_atime
mtime: SystemTime, // si_mtime
cred: Option<Arc<Ucred>>, // si_cred
flags: DeviceFlags, // si_flags
sw: Arc<CdevSw>, // si_devsw
unit: i32, // si_drv0
name: String, // si_name
uid: i32, // si_uid
gid: i32, // si_gid
mode: u16, // si_mode
ctime: SystemTime, // si_ctime
atime: SystemTime, // si_atime
mtime: SystemTime, // si_mtime
cred: Option<Arc<Ucred>>, // si_cred
flags: DeviceFlags, // si_flags
inode: i32, // cdp_inode
dirents: Gutex<Vec<Option<Weak<Dirent>>>>, // cdp_dirents + cdp_maxdirent
}

impl Cdev {
/// See `devfs_alloc` on the PS4 for a reference.
pub(super) fn new<N: Into<String>>(
sw: &Arc<CdevSw>,
inode: u32,
unit: i32,
name: N,
uid: i32,
gid: i32,
mode: u16,
cred: Option<Arc<Ucred>>,
flags: DeviceFlags,
inode: i32,
) -> Self {
let gg = GutexGroup::new();
let now = SystemTime::now();

Self {
Expand All @@ -48,23 +52,49 @@ impl Cdev {
mtime: now,
cred,
flags,
dirents: gg.spawn(vec![None]),
}
}

pub fn name(&self) -> &str {
self.name.as_ref()
}

pub fn uid(&self) -> i32 {
self.uid
}

pub fn gid(&self) -> i32 {
self.gid
}

pub fn mode(&self) -> u16 {
self.mode
}

pub fn flags(&self) -> DeviceFlags {
self.flags
}

pub(super) fn inode(&self) -> i32 {
self.inode
}

pub(super) fn dirents(&self) -> GutexReadGuard<Vec<Option<Weak<Dirent>>>> {
self.dirents.read()
}

pub(super) fn dirents_mut(&self) -> GutexWriteGuard<Vec<Option<Weak<Dirent>>>> {
self.dirents.write()
}
}

bitflags! {
/// Flags for [`Cdev`].
#[derive(Debug, Clone, Copy)]
pub struct DeviceFlags: u32 {
const SI_ETERNAL = 0x0001;
const SI_ETERNAL = 0x01;
const SI_ALIAS = 0x02;
}
}

Expand Down
30 changes: 30 additions & 0 deletions src/kernel/src/fs/dev/dirent.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
use crate::fs::{DirentType, Vnode};
use bitflags::bitflags;
use gmtx::{Gutex, GutexGroup, GutexWriteGuard};
use std::ops::Deref;
use std::sync::{Arc, Weak};
use std::time::SystemTime;

/// An implementation of `devfs_dirent` structure.
pub struct Dirent {
inode: i32, // de_inode
uid: Gutex<i32>, // de_uid
gid: Gutex<i32>, // de_gid
mode: Gutex<u16>, // de_mode
dir: Option<Weak<Self>>, // de_dir
children: Gutex<Vec<Arc<Self>>>, // de_dlist
Expand All @@ -22,6 +25,8 @@ impl Dirent {
pub fn new<N>(
ty: DirentType,
inode: i32,
uid: i32,
gid: i32,
mode: u16,
dir: Option<Weak<Self>>,
flags: DirentFlags,
Expand All @@ -35,6 +40,8 @@ impl Dirent {

Self {
inode,
uid: gg.spawn(uid),
gid: gg.spawn(gid),
mode: gg.spawn(mode),
dir,
children: gg.spawn(Vec::new()),
Expand Down Expand Up @@ -66,6 +73,29 @@ impl Dirent {
pub fn dirent(&self) -> &crate::fs::Dirent {
&self.dirent
}

/// See `devfs_find` on the PS4 for a reference.
pub fn find<N: AsRef<str>>(&self, name: N, ty: Option<DirentType>) -> Option<Arc<Self>> {
let name = name.as_ref();

for child in self.children.read().deref() {
// Check name.
if child.dirent.name() != name {
continue;
}

// Check type.
if let Some(ty) = ty {
if child.dirent.ty() != ty {
continue;
}
}

return Some(child.clone());
}

None
}
}

bitflags! {
Expand Down
Loading

0 comments on commit 901c7eb

Please sign in to comment.