xref: /linux-6.15/rust/kernel/error.rs (revision 46384d09)
1247b365dSWedson Almeida Filho // SPDX-License-Identifier: GPL-2.0
2247b365dSWedson Almeida Filho 
3247b365dSWedson Almeida Filho //! Kernel errors.
4247b365dSWedson Almeida Filho //!
5247b365dSWedson Almeida Filho //! C header: [`include/uapi/asm-generic/errno-base.h`](../../../include/uapi/asm-generic/errno-base.h)
6247b365dSWedson Almeida Filho 
776e2c2d9SWedson Almeida Filho use alloc::{
876e2c2d9SWedson Almeida Filho     alloc::{AllocError, LayoutError},
976e2c2d9SWedson Almeida Filho     collections::TryReserveError,
1076e2c2d9SWedson Almeida Filho };
1176e2c2d9SWedson Almeida Filho 
1276e2c2d9SWedson Almeida Filho use core::convert::From;
1376e2c2d9SWedson Almeida Filho use core::num::TryFromIntError;
1476e2c2d9SWedson Almeida Filho use core::str::Utf8Error;
15247b365dSWedson Almeida Filho 
16247b365dSWedson Almeida Filho /// Contains the C-compatible error codes.
17247b365dSWedson Almeida Filho pub mod code {
184b0c68bdSFinn Behrens     macro_rules! declare_err {
194b0c68bdSFinn Behrens         ($err:tt $(,)? $($doc:expr),+) => {
204b0c68bdSFinn Behrens             $(
214b0c68bdSFinn Behrens             #[doc = $doc]
224b0c68bdSFinn Behrens             )*
234b0c68bdSFinn Behrens             pub const $err: super::Error = super::Error(-(crate::bindings::$err as i32));
244b0c68bdSFinn Behrens         };
254b0c68bdSFinn Behrens     }
264b0c68bdSFinn Behrens 
27266def2aSViktor Garske     declare_err!(EPERM, "Operation not permitted.");
28266def2aSViktor Garske     declare_err!(ENOENT, "No such file or directory.");
29266def2aSViktor Garske     declare_err!(ESRCH, "No such process.");
30266def2aSViktor Garske     declare_err!(EINTR, "Interrupted system call.");
31266def2aSViktor Garske     declare_err!(EIO, "I/O error.");
32266def2aSViktor Garske     declare_err!(ENXIO, "No such device or address.");
33266def2aSViktor Garske     declare_err!(E2BIG, "Argument list too long.");
34266def2aSViktor Garske     declare_err!(ENOEXEC, "Exec format error.");
35266def2aSViktor Garske     declare_err!(EBADF, "Bad file number.");
36266def2aSViktor Garske     declare_err!(ECHILD, "Exec format error.");
37266def2aSViktor Garske     declare_err!(EAGAIN, "Try again.");
384b0c68bdSFinn Behrens     declare_err!(ENOMEM, "Out of memory.");
39266def2aSViktor Garske     declare_err!(EACCES, "Permission denied.");
40266def2aSViktor Garske     declare_err!(EFAULT, "Bad address.");
41266def2aSViktor Garske     declare_err!(ENOTBLK, "Block device required.");
42266def2aSViktor Garske     declare_err!(EBUSY, "Device or resource busy.");
43266def2aSViktor Garske     declare_err!(EEXIST, "File exists.");
44266def2aSViktor Garske     declare_err!(EXDEV, "Cross-device link.");
45266def2aSViktor Garske     declare_err!(ENODEV, "No such device.");
46266def2aSViktor Garske     declare_err!(ENOTDIR, "Not a directory.");
47266def2aSViktor Garske     declare_err!(EISDIR, "Is a directory.");
48266def2aSViktor Garske     declare_err!(EINVAL, "Invalid argument.");
49266def2aSViktor Garske     declare_err!(ENFILE, "File table overflow.");
50266def2aSViktor Garske     declare_err!(EMFILE, "Too many open files.");
51266def2aSViktor Garske     declare_err!(ENOTTY, "Not a typewriter.");
52266def2aSViktor Garske     declare_err!(ETXTBSY, "Text file busy.");
53266def2aSViktor Garske     declare_err!(EFBIG, "File too large.");
54266def2aSViktor Garske     declare_err!(ENOSPC, "No space left on device.");
55266def2aSViktor Garske     declare_err!(ESPIPE, "Illegal seek.");
56266def2aSViktor Garske     declare_err!(EROFS, "Read-only file system.");
57266def2aSViktor Garske     declare_err!(EMLINK, "Too many links.");
58266def2aSViktor Garske     declare_err!(EPIPE, "Broken pipe.");
59266def2aSViktor Garske     declare_err!(EDOM, "Math argument out of domain of func.");
60266def2aSViktor Garske     declare_err!(ERANGE, "Math result not representable.");
61247b365dSWedson Almeida Filho }
62247b365dSWedson Almeida Filho 
63247b365dSWedson Almeida Filho /// Generic integer kernel error.
64247b365dSWedson Almeida Filho ///
65247b365dSWedson Almeida Filho /// The kernel defines a set of integer generic error codes based on C and
66247b365dSWedson Almeida Filho /// POSIX ones. These codes may have a more specific meaning in some contexts.
67247b365dSWedson Almeida Filho ///
68247b365dSWedson Almeida Filho /// # Invariants
69247b365dSWedson Almeida Filho ///
70247b365dSWedson Almeida Filho /// The value is a valid `errno` (i.e. `>= -MAX_ERRNO && < 0`).
71247b365dSWedson Almeida Filho #[derive(Clone, Copy, PartialEq, Eq)]
72247b365dSWedson Almeida Filho pub struct Error(core::ffi::c_int);
73247b365dSWedson Almeida Filho 
74247b365dSWedson Almeida Filho impl Error {
75247b365dSWedson Almeida Filho     /// Returns the kernel error code.
76*46384d09SAsahi Lina     pub fn to_errno(self) -> core::ffi::c_int {
77247b365dSWedson Almeida Filho         self.0
78247b365dSWedson Almeida Filho     }
79247b365dSWedson Almeida Filho }
80247b365dSWedson Almeida Filho 
8176e2c2d9SWedson Almeida Filho impl From<AllocError> for Error {
8276e2c2d9SWedson Almeida Filho     fn from(_: AllocError) -> Error {
8376e2c2d9SWedson Almeida Filho         code::ENOMEM
8476e2c2d9SWedson Almeida Filho     }
8576e2c2d9SWedson Almeida Filho }
8676e2c2d9SWedson Almeida Filho 
8776e2c2d9SWedson Almeida Filho impl From<TryFromIntError> for Error {
8876e2c2d9SWedson Almeida Filho     fn from(_: TryFromIntError) -> Error {
8976e2c2d9SWedson Almeida Filho         code::EINVAL
9076e2c2d9SWedson Almeida Filho     }
9176e2c2d9SWedson Almeida Filho }
9276e2c2d9SWedson Almeida Filho 
9376e2c2d9SWedson Almeida Filho impl From<Utf8Error> for Error {
9476e2c2d9SWedson Almeida Filho     fn from(_: Utf8Error) -> Error {
9576e2c2d9SWedson Almeida Filho         code::EINVAL
9676e2c2d9SWedson Almeida Filho     }
9776e2c2d9SWedson Almeida Filho }
9876e2c2d9SWedson Almeida Filho 
99247b365dSWedson Almeida Filho impl From<TryReserveError> for Error {
100247b365dSWedson Almeida Filho     fn from(_: TryReserveError) -> Error {
101247b365dSWedson Almeida Filho         code::ENOMEM
102247b365dSWedson Almeida Filho     }
103247b365dSWedson Almeida Filho }
104247b365dSWedson Almeida Filho 
10576e2c2d9SWedson Almeida Filho impl From<LayoutError> for Error {
10676e2c2d9SWedson Almeida Filho     fn from(_: LayoutError) -> Error {
10776e2c2d9SWedson Almeida Filho         code::ENOMEM
10876e2c2d9SWedson Almeida Filho     }
10976e2c2d9SWedson Almeida Filho }
11076e2c2d9SWedson Almeida Filho 
11176e2c2d9SWedson Almeida Filho impl From<core::fmt::Error> for Error {
11276e2c2d9SWedson Almeida Filho     fn from(_: core::fmt::Error) -> Error {
11376e2c2d9SWedson Almeida Filho         code::EINVAL
11476e2c2d9SWedson Almeida Filho     }
11576e2c2d9SWedson Almeida Filho }
11676e2c2d9SWedson Almeida Filho 
11776e2c2d9SWedson Almeida Filho impl From<core::convert::Infallible> for Error {
11876e2c2d9SWedson Almeida Filho     fn from(e: core::convert::Infallible) -> Error {
11976e2c2d9SWedson Almeida Filho         match e {}
12076e2c2d9SWedson Almeida Filho     }
12176e2c2d9SWedson Almeida Filho }
12276e2c2d9SWedson Almeida Filho 
123247b365dSWedson Almeida Filho /// A [`Result`] with an [`Error`] error type.
124247b365dSWedson Almeida Filho ///
125247b365dSWedson Almeida Filho /// To be used as the return type for functions that may fail.
126247b365dSWedson Almeida Filho ///
127247b365dSWedson Almeida Filho /// # Error codes in C and Rust
128247b365dSWedson Almeida Filho ///
129247b365dSWedson Almeida Filho /// In C, it is common that functions indicate success or failure through
130247b365dSWedson Almeida Filho /// their return value; modifying or returning extra data through non-`const`
131247b365dSWedson Almeida Filho /// pointer parameters. In particular, in the kernel, functions that may fail
132247b365dSWedson Almeida Filho /// typically return an `int` that represents a generic error code. We model
133247b365dSWedson Almeida Filho /// those as [`Error`].
134247b365dSWedson Almeida Filho ///
135247b365dSWedson Almeida Filho /// In Rust, it is idiomatic to model functions that may fail as returning
136247b365dSWedson Almeida Filho /// a [`Result`]. Since in the kernel many functions return an error code,
137247b365dSWedson Almeida Filho /// [`Result`] is a type alias for a [`core::result::Result`] that uses
138247b365dSWedson Almeida Filho /// [`Error`] as its error type.
139247b365dSWedson Almeida Filho ///
140247b365dSWedson Almeida Filho /// Note that even if a function does not return anything when it succeeds,
141247b365dSWedson Almeida Filho /// it should still be modeled as returning a `Result` rather than
142247b365dSWedson Almeida Filho /// just an [`Error`].
143247b365dSWedson Almeida Filho pub type Result<T = ()> = core::result::Result<T, Error>;
144