Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Makes errno fully derivable #683

Merged
merged 8 commits into from
Feb 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/kernel/src/errno.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::convert::Infallible;
use std::error::Error;
use std::num::NonZeroI32;

// This file contains errno used in a PS4 system. The value of each errno must be the same as the
// PS4.

Expand Down
12 changes: 2 additions & 10 deletions src/kernel/src/fs/dev/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use crate::errno::{Errno, EEXIST, ENOENT, EOPNOTSUPP};
use crate::ucred::{Gid, Ucred, Uid};
use bitflags::bitflags;
use macros::Errno;
use std::num::NonZeroI32;
use std::sync::atomic::{AtomicU32, AtomicUsize, Ordering};
use std::sync::{Arc, Mutex, RwLock};
use thiserror::Error;
Expand Down Expand Up @@ -310,20 +309,13 @@ impl Devices {
}

/// Represents an error when [`make_dev()`] is failed.
#[derive(Debug, Error)]
#[derive(Debug, Error, Errno)]
pub enum MakeDevError {
#[error("the device with the same name already exist")]
#[errno(EEXIST)]
AlreadyExist(String),
}

impl Errno for MakeDevError {
fn errno(&self) -> NonZeroI32 {
match self {
Self::AlreadyExist(_) => EEXIST,
}
}
}

pub fn mount(
conf: &'static FsConfig,
cred: &Arc<Ucred>,
Expand Down
18 changes: 4 additions & 14 deletions src/kernel/src/fs/dev/vnode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use crate::fs::{
};
use crate::process::VThread;
use macros::Errno;
use std::num::NonZeroI32;
use std::sync::Arc;
use thiserror::Error;

Expand Down Expand Up @@ -209,36 +208,27 @@ impl crate::fs::VnodeBackend for VnodeBackend {
}

/// Represents an error when [`lookup()`] is failed.
#[derive(Debug, Error)]
#[derive(Debug, Error, Errno)]
enum LookupError {
#[error("file is not a directory")]
#[errno(ENOTDIR)]
NotDirectory,

#[error("cannot resolve '..' on the root directory")]
#[errno(EIO)]
DotdotOnRoot,

#[error("access denied")]
AccessDenied(#[source] Box<dyn Errno>),

#[error("file have no parent")]
#[errno(ENOENT)]
NoParent,

#[error("cannot allocate a vnode")]
AllocVnodeFailed(#[source] AllocVnodeError),
}

impl Errno for LookupError {
fn errno(&self) -> NonZeroI32 {
match self {
Self::NotDirectory => ENOTDIR,
Self::DotdotOnRoot => EIO,
Self::AccessDenied(e) => e.errno(),
Self::NoParent => ENOENT,
Self::AllocVnodeFailed(e) => e.errno(),
}
}
}

/// Represents an error when [`open()`] is failed.
#[derive(Debug, Error, Errno)]
enum OpenError {
Expand Down
19 changes: 6 additions & 13 deletions src/kernel/src/fs/host/vnode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use crate::process::VThread;
use crate::ucred::{Gid, Uid};
use macros::Errno;
use std::borrow::Cow;
use std::num::NonZeroI32;
use std::sync::Arc;
use thiserror::Error;

Expand Down Expand Up @@ -128,34 +127,28 @@ enum GetAttrError {
}

/// Represents an error when [`lookup()`] fails.
#[derive(Debug, Error)]
#[derive(Debug, Error, Errno)]
enum LookupError {
#[error("current file is not a directory")]
#[errno(ENOTDIR)]
NotDirectory,

#[error("cannot resolve '..' on the root directory")]
#[errno(EIO)]
DotdotOnRoot,

#[error("access denied")]
AccessDenied(#[source] Box<dyn Errno>),

#[error("name contains unsupported characters")]
#[errno(ENOENT)]
InvalidName,

#[error("couldn't open the specified file")]
#[errno(EIO)]
OpenFailed(#[source] std::io::Error),

#[error("cannot get vnode")]
#[errno(EIO)]
GetVnodeFailed(#[source] GetVnodeError),
}

impl Errno for LookupError {
fn errno(&self) -> NonZeroI32 {
match self {
Self::NotDirectory => ENOTDIR,
Self::DotdotOnRoot | Self::GetVnodeFailed(_) | Self::OpenFailed(_) => EIO,
Self::AccessDenied(e) => e.errno(),
Self::InvalidName => ENOENT,
}
}
}
114 changes: 19 additions & 95 deletions src/kernel/src/fs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use macros::vpath;
use macros::Errno;
use param::Param;
use std::fmt::{Display, Formatter};
use std::num::{NonZeroI32, TryFromIntError};
use std::num::TryFromIntError;
use std::path::PathBuf;
use std::sync::Arc;
use thiserror::Error;
Expand Down Expand Up @@ -1093,15 +1093,18 @@ pub enum FsInitError {
}

/// Represents an error when FS mounting fails.
#[derive(Debug, Error)]
#[derive(Debug, Error, Errno)]
pub enum MountError {
#[error("fstype is too long")]
#[errno(ENAMETOOLONG)]
FsTooLong,

#[error("fspath is too long")]
#[errno(ENAMETOOLONG)]
PathTooLong,

#[error("fstype is not valid")]
#[errno(ENODEV)]
InvalidFs,

#[error("fspath is not found")]
Expand All @@ -1111,95 +1114,51 @@ pub enum MountError {
MountFailed(#[source] Box<dyn Errno>),

#[error("fspath is already mounted")]
#[errno(EBUSY)]
PathAlreadyMounted,

#[error("cannot get root")]
GetRootFailed(#[source] Box<dyn Errno>),
}

impl Errno for MountError {
fn errno(&self) -> NonZeroI32 {
match self {
Self::FsTooLong | Self::PathTooLong => ENAMETOOLONG,
Self::InvalidFs => ENODEV,
Self::LookupPathFailed(e) => e.errno(),
Self::MountFailed(e) => e.errno(),
Self::PathAlreadyMounted => EBUSY,
Self::GetRootFailed(e) => e.errno(),
}
}
}

/// Represents an error when [`Fs::open()`] fails.
#[derive(Debug, Error)]
#[derive(Debug, Error, Errno)]
pub enum OpenError {
#[error("cannot lookup the file")]
LookupFailed(#[source] LookupError),
}

impl Errno for OpenError {
fn errno(&self) -> NonZeroI32 {
match self {
Self::LookupFailed(e) => e.errno(),
}
}
}

#[derive(Debug, Error)]
#[derive(Debug, Error, Errno)]
pub enum WriteError {}

impl Errno for WriteError {
fn errno(&self) -> NonZeroI32 {
todo!()
}
}

#[derive(Debug, Error)]
#[derive(Debug, Error, Errno)]
pub enum IoctlError {
#[error("Couldn't get file")]
FailedToGetFile(#[from] GetFileError),

#[error("Bad file flags {0:?}")]
#[errno(EBADF)]
BadFileFlags(VFileFlags),

#[error(transparent)]
FileIoctlFailed(#[from] Box<dyn Errno>),
}

impl Errno for IoctlError {
fn errno(&self) -> NonZeroI32 {
match self {
Self::FailedToGetFile(e) => e.errno(),
Self::BadFileFlags(_) => EBADF,
Self::FileIoctlFailed(e) => e.errno(),
}
}
}

/// Represents an error when [`Fs::lookup()`] fails.
#[derive(Debug, Error)]
#[derive(Debug, Error, Errno)]
pub enum LookupError {
#[error("failed to get mount root")]
GetRootFailed(#[source] Box<dyn Errno>),

#[error("no such file or directory")]
#[errno(ENOENT)]
NotFound,

#[error("cannot lookup '{1}' from component #{0}")]
LookupFailed(usize, Box<str>, #[source] Box<dyn Errno>),
}

impl Errno for LookupError {
fn errno(&self) -> NonZeroI32 {
match self {
Self::GetRootFailed(e) => e.errno(),
Self::NotFound => ENOENT,
Self::LookupFailed(_, _, e) => e.errno(),
}
}
}

#[derive(Debug, Error)]
#[derive(Debug, Error, Errno)]
pub enum RevokeError {
#[error("failed to get file attr")]
GetAttrError(#[source] Box<dyn Errno>),
Expand All @@ -1211,17 +1170,8 @@ pub enum RevokeError {
RevokeFailed(#[source] Box<dyn Errno>),
}

impl Errno for RevokeError {
fn errno(&self) -> NonZeroI32 {
match self {
Self::GetAttrError(e) => e.errno(),
Self::PrivelegeError(e) => e.errno(),
Self::RevokeFailed(e) => e.errno(),
}
}
}
/// Represents an error when one of the stat syscalls fails
#[derive(Debug, Error)]
#[derive(Debug, Error, Errno)]
pub enum StatError {
#[error("failed to get file")]
FailedToGetFile(#[from] GetFileError),
Expand All @@ -1230,65 +1180,39 @@ pub enum StatError {
GetAttrError(#[from] Box<dyn Errno>),
}

impl Errno for StatError {
fn errno(&self) -> NonZeroI32 {
match self {
Self::FailedToGetFile(e) => e.errno(),
Self::GetAttrError(e) => e.errno(),
}
}
}

#[derive(Debug, Error)]
#[derive(Debug, Error, Errno)]
pub enum TruncateError {
#[error("the provided length is invalid")]
#[errno(EINVAL)]
InvalidLength,

#[error("failed to get file")]
FailedToLookupFile(#[from] LookupError),
}

impl Errno for TruncateError {
fn errno(&self) -> NonZeroI32 {
match self {
Self::InvalidLength => EINVAL,
Self::FailedToLookupFile(e) => e.errno(),
}
}
}

impl From<TruncateLengthError> for TruncateError {
fn from(_: TruncateLengthError) -> Self {
Self::InvalidLength
}
}

#[derive(Debug, Error)]
#[derive(Debug, Error, Errno)]
pub enum FileTruncateError {
#[error("the provided length is invalid")]
#[errno(EINVAL)]
InvalidLength,

#[error("failed to get file")]
FailedToGetFile(#[from] GetFileError),

#[error("file is not writable")]
#[errno(EINVAL)]
FileNotWritable,

#[error(transparent)]
TruncateError(#[from] Box<dyn Errno>),
}

impl Errno for FileTruncateError {
fn errno(&self) -> NonZeroI32 {
match self {
Self::InvalidLength => EINVAL,
Self::FailedToGetFile(e) => e.errno(),
Self::FileNotWritable => EINVAL,
Self::TruncateError(e) => e.errno(),
}
}
}

impl From<TruncateLengthError> for FileTruncateError {
fn from(_: TruncateLengthError) -> Self {
Self::InvalidLength
Expand Down
Loading