| 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | |
| 3 | //! Kernel errors. |
| 4 | //! |
| 5 | //! C header: [`include/uapi/asm-generic/errno-base.h`](srctree/include/uapi/asm-generic/errno-base.h) |
| 6 | |
| 7 | use crate::{ |
| 8 | alloc::{layout::LayoutError, AllocError}, |
| 9 | str::CStr, |
| 10 | }; |
| 11 | |
| 12 | use core::fmt; |
| 13 | use core::num::NonZeroI32; |
| 14 | use core::num::TryFromIntError; |
| 15 | use core::str::Utf8Error; |
| 16 | |
| 17 | /// Contains the C-compatible error codes. |
| 18 | #[rustfmt::skip] |
| 19 | pub mod code { |
| 20 | macro_rules! declare_err { |
| 21 | ($err:tt $(,)? $($doc:expr),+) => { |
| 22 | $( |
| 23 | #[doc = $doc] |
| 24 | )* |
| 25 | pub const $err: super::Error = |
| 26 | match super::Error::try_from_errno(-(crate::bindings::$err as i32)) { |
| 27 | Some(err) => err, |
| 28 | None => panic!("Invalid errno in `declare_err!`" ), |
| 29 | }; |
| 30 | }; |
| 31 | } |
| 32 | |
| 33 | declare_err!(EPERM, "Operation not permitted." ); |
| 34 | declare_err!(ENOENT, "No such file or directory." ); |
| 35 | declare_err!(ESRCH, "No such process." ); |
| 36 | declare_err!(EINTR, "Interrupted system call." ); |
| 37 | declare_err!(EIO, "I/O error." ); |
| 38 | declare_err!(ENXIO, "No such device or address." ); |
| 39 | declare_err!(E2BIG, "Argument list too long." ); |
| 40 | declare_err!(ENOEXEC, "Exec format error." ); |
| 41 | declare_err!(EBADF, "Bad file number." ); |
| 42 | declare_err!(ECHILD, "No child processes." ); |
| 43 | declare_err!(EAGAIN, "Try again." ); |
| 44 | declare_err!(ENOMEM, "Out of memory." ); |
| 45 | declare_err!(EACCES, "Permission denied." ); |
| 46 | declare_err!(EFAULT, "Bad address." ); |
| 47 | declare_err!(ENOTBLK, "Block device required." ); |
| 48 | declare_err!(EBUSY, "Device or resource busy." ); |
| 49 | declare_err!(EEXIST, "File exists." ); |
| 50 | declare_err!(EXDEV, "Cross-device link." ); |
| 51 | declare_err!(ENODEV, "No such device." ); |
| 52 | declare_err!(ENOTDIR, "Not a directory." ); |
| 53 | declare_err!(EISDIR, "Is a directory." ); |
| 54 | declare_err!(EINVAL, "Invalid argument." ); |
| 55 | declare_err!(ENFILE, "File table overflow." ); |
| 56 | declare_err!(EMFILE, "Too many open files." ); |
| 57 | declare_err!(ENOTTY, "Not a typewriter." ); |
| 58 | declare_err!(ETXTBSY, "Text file busy." ); |
| 59 | declare_err!(EFBIG, "File too large." ); |
| 60 | declare_err!(ENOSPC, "No space left on device." ); |
| 61 | declare_err!(ESPIPE, "Illegal seek." ); |
| 62 | declare_err!(EROFS, "Read-only file system." ); |
| 63 | declare_err!(EMLINK, "Too many links." ); |
| 64 | declare_err!(EPIPE, "Broken pipe." ); |
| 65 | declare_err!(EDOM, "Math argument out of domain of func." ); |
| 66 | declare_err!(ERANGE, "Math result not representable." ); |
| 67 | declare_err!(EOVERFLOW, "Value too large for defined data type." ); |
| 68 | declare_err!(ERESTARTSYS, "Restart the system call." ); |
| 69 | declare_err!(ERESTARTNOINTR, "System call was interrupted by a signal and will be restarted." ); |
| 70 | declare_err!(ERESTARTNOHAND, "Restart if no handler." ); |
| 71 | declare_err!(ENOIOCTLCMD, "No ioctl command." ); |
| 72 | declare_err!(ERESTART_RESTARTBLOCK, "Restart by calling sys_restart_syscall." ); |
| 73 | declare_err!(EPROBE_DEFER, "Driver requests probe retry." ); |
| 74 | declare_err!(EOPENSTALE, "Open found a stale dentry." ); |
| 75 | declare_err!(ENOPARAM, "Parameter not supported." ); |
| 76 | declare_err!(EBADHANDLE, "Illegal NFS file handle." ); |
| 77 | declare_err!(ENOTSYNC, "Update synchronization mismatch." ); |
| 78 | declare_err!(EBADCOOKIE, "Cookie is stale." ); |
| 79 | declare_err!(ENOTSUPP, "Operation is not supported." ); |
| 80 | declare_err!(ETOOSMALL, "Buffer or request is too small." ); |
| 81 | declare_err!(ESERVERFAULT, "An untranslatable error occurred." ); |
| 82 | declare_err!(EBADTYPE, "Type not supported by server." ); |
| 83 | declare_err!(EJUKEBOX, "Request initiated, but will not complete before timeout." ); |
| 84 | declare_err!(EIOCBQUEUED, "iocb queued, will get completion event." ); |
| 85 | declare_err!(ERECALLCONFLICT, "Conflict with recalled state." ); |
| 86 | declare_err!(ENOGRACE, "NFS file lock reclaim refused." ); |
| 87 | } |
| 88 | |
| 89 | /// Generic integer kernel error. |
| 90 | /// |
| 91 | /// The kernel defines a set of integer generic error codes based on C and |
| 92 | /// POSIX ones. These codes may have a more specific meaning in some contexts. |
| 93 | /// |
| 94 | /// # Invariants |
| 95 | /// |
| 96 | /// The value is a valid `errno` (i.e. `>= -MAX_ERRNO && < 0`). |
| 97 | #[derive(Clone, Copy, PartialEq, Eq)] |
| 98 | pub struct Error(NonZeroI32); |
| 99 | |
| 100 | impl Error { |
| 101 | /// Creates an [`Error`] from a kernel error code. |
| 102 | /// |
| 103 | /// It is a bug to pass an out-of-range `errno`. `EINVAL` would |
| 104 | /// be returned in such a case. |
| 105 | pub fn from_errno(errno: crate::ffi::c_int) -> Error { |
| 106 | if let Some(error) = Self::try_from_errno(errno) { |
| 107 | error |
| 108 | } else { |
| 109 | // TODO: Make it a `WARN_ONCE` once available. |
| 110 | crate::pr_warn!( |
| 111 | "attempted to create `Error` with out of range `errno`: {}\n" , |
| 112 | errno |
| 113 | ); |
| 114 | code::EINVAL |
| 115 | } |
| 116 | } |
| 117 | |
| 118 | /// Creates an [`Error`] from a kernel error code. |
| 119 | /// |
| 120 | /// Returns [`None`] if `errno` is out-of-range. |
| 121 | const fn try_from_errno(errno: crate::ffi::c_int) -> Option<Error> { |
| 122 | if errno < -(bindings::MAX_ERRNO as i32) || errno >= 0 { |
| 123 | return None; |
| 124 | } |
| 125 | |
| 126 | // SAFETY: `errno` is checked above to be in a valid range. |
| 127 | Some(unsafe { Error::from_errno_unchecked(errno) }) |
| 128 | } |
| 129 | |
| 130 | /// Creates an [`Error`] from a kernel error code. |
| 131 | /// |
| 132 | /// # Safety |
| 133 | /// |
| 134 | /// `errno` must be within error code range (i.e. `>= -MAX_ERRNO && < 0`). |
| 135 | const unsafe fn from_errno_unchecked(errno: crate::ffi::c_int) -> Error { |
| 136 | // INVARIANT: The contract ensures the type invariant |
| 137 | // will hold. |
| 138 | // SAFETY: The caller guarantees `errno` is non-zero. |
| 139 | Error(unsafe { NonZeroI32::new_unchecked(errno) }) |
| 140 | } |
| 141 | |
| 142 | /// Returns the kernel error code. |
| 143 | pub fn to_errno(self) -> crate::ffi::c_int { |
| 144 | self.0.get() |
| 145 | } |
| 146 | |
| 147 | #[cfg(CONFIG_BLOCK)] |
| 148 | pub(crate) fn to_blk_status(self) -> bindings::blk_status_t { |
| 149 | // SAFETY: `self.0` is a valid error due to its invariant. |
| 150 | unsafe { bindings::errno_to_blk_status(self.0.get()) } |
| 151 | } |
| 152 | |
| 153 | /// Returns the error encoded as a pointer. |
| 154 | pub fn to_ptr<T>(self) -> *mut T { |
| 155 | // SAFETY: `self.0` is a valid error due to its invariant. |
| 156 | unsafe { bindings::ERR_PTR(self.0.get() as _) as *mut _ } |
| 157 | } |
| 158 | |
| 159 | /// Returns a string representing the error, if one exists. |
| 160 | #[cfg(not(any(test, testlib)))] |
| 161 | pub fn name(&self) -> Option<&'static CStr> { |
| 162 | // SAFETY: Just an FFI call, there are no extra safety requirements. |
| 163 | let ptr = unsafe { bindings::errname(-self.0.get()) }; |
| 164 | if ptr.is_null() { |
| 165 | None |
| 166 | } else { |
| 167 | // SAFETY: The string returned by `errname` is static and `NUL`-terminated. |
| 168 | Some(unsafe { CStr::from_char_ptr(ptr) }) |
| 169 | } |
| 170 | } |
| 171 | |
| 172 | /// Returns a string representing the error, if one exists. |
| 173 | /// |
| 174 | /// When `testlib` is configured, this always returns `None` to avoid the dependency on a |
| 175 | /// kernel function so that tests that use this (e.g., by calling [`Result::unwrap`]) can still |
| 176 | /// run in userspace. |
| 177 | #[cfg(any(test, testlib))] |
| 178 | pub fn name(&self) -> Option<&'static CStr> { |
| 179 | None |
| 180 | } |
| 181 | } |
| 182 | |
| 183 | impl fmt::Debug for Error { |
| 184 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 185 | match self.name() { |
| 186 | // Print out number if no name can be found. |
| 187 | None => f.debug_tuple("Error" ).field(&-self.0).finish(), |
| 188 | Some(name) => f |
| 189 | .debug_tuple( |
| 190 | // SAFETY: These strings are ASCII-only. |
| 191 | unsafe { core::str::from_utf8_unchecked(name) }, |
| 192 | ) |
| 193 | .finish(), |
| 194 | } |
| 195 | } |
| 196 | } |
| 197 | |
| 198 | impl From<AllocError> for Error { |
| 199 | fn from(_: AllocError) -> Error { |
| 200 | code::ENOMEM |
| 201 | } |
| 202 | } |
| 203 | |
| 204 | impl From<TryFromIntError> for Error { |
| 205 | fn from(_: TryFromIntError) -> Error { |
| 206 | code::EINVAL |
| 207 | } |
| 208 | } |
| 209 | |
| 210 | impl From<Utf8Error> for Error { |
| 211 | fn from(_: Utf8Error) -> Error { |
| 212 | code::EINVAL |
| 213 | } |
| 214 | } |
| 215 | |
| 216 | impl From<LayoutError> for Error { |
| 217 | fn from(_: LayoutError) -> Error { |
| 218 | code::ENOMEM |
| 219 | } |
| 220 | } |
| 221 | |
| 222 | impl From<core::fmt::Error> for Error { |
| 223 | fn from(_: core::fmt::Error) -> Error { |
| 224 | code::EINVAL |
| 225 | } |
| 226 | } |
| 227 | |
| 228 | impl From<core::convert::Infallible> for Error { |
| 229 | fn from(e: core::convert::Infallible) -> Error { |
| 230 | match e {} |
| 231 | } |
| 232 | } |
| 233 | |
| 234 | /// A [`Result`] with an [`Error`] error type. |
| 235 | /// |
| 236 | /// To be used as the return type for functions that may fail. |
| 237 | /// |
| 238 | /// # Error codes in C and Rust |
| 239 | /// |
| 240 | /// In C, it is common that functions indicate success or failure through |
| 241 | /// their return value; modifying or returning extra data through non-`const` |
| 242 | /// pointer parameters. In particular, in the kernel, functions that may fail |
| 243 | /// typically return an `int` that represents a generic error code. We model |
| 244 | /// those as [`Error`]. |
| 245 | /// |
| 246 | /// In Rust, it is idiomatic to model functions that may fail as returning |
| 247 | /// a [`Result`]. Since in the kernel many functions return an error code, |
| 248 | /// [`Result`] is a type alias for a [`core::result::Result`] that uses |
| 249 | /// [`Error`] as its error type. |
| 250 | /// |
| 251 | /// Note that even if a function does not return anything when it succeeds, |
| 252 | /// it should still be modeled as returning a [`Result`] rather than |
| 253 | /// just an [`Error`]. |
| 254 | /// |
| 255 | /// Calling a function that returns [`Result`] forces the caller to handle |
| 256 | /// the returned [`Result`]. |
| 257 | /// |
| 258 | /// This can be done "manually" by using [`match`]. Using [`match`] to decode |
| 259 | /// the [`Result`] is similar to C where all the return value decoding and the |
| 260 | /// error handling is done explicitly by writing handling code for each |
| 261 | /// error to cover. Using [`match`] the error and success handling can be |
| 262 | /// implemented in all detail as required. For example (inspired by |
| 263 | /// [`samples/rust/rust_minimal.rs`]): |
| 264 | /// |
| 265 | /// ``` |
| 266 | /// # #[allow(clippy::single_match)] |
| 267 | /// fn example() -> Result { |
| 268 | /// let mut numbers = KVec::new(); |
| 269 | /// |
| 270 | /// match numbers.push(72, GFP_KERNEL) { |
| 271 | /// Err(e) => { |
| 272 | /// pr_err!("Error pushing 72: {e:?}"); |
| 273 | /// return Err(e.into()); |
| 274 | /// } |
| 275 | /// // Do nothing, continue. |
| 276 | /// Ok(()) => (), |
| 277 | /// } |
| 278 | /// |
| 279 | /// match numbers.push(108, GFP_KERNEL) { |
| 280 | /// Err(e) => { |
| 281 | /// pr_err!("Error pushing 108: {e:?}"); |
| 282 | /// return Err(e.into()); |
| 283 | /// } |
| 284 | /// // Do nothing, continue. |
| 285 | /// Ok(()) => (), |
| 286 | /// } |
| 287 | /// |
| 288 | /// match numbers.push(200, GFP_KERNEL) { |
| 289 | /// Err(e) => { |
| 290 | /// pr_err!("Error pushing 200: {e:?}"); |
| 291 | /// return Err(e.into()); |
| 292 | /// } |
| 293 | /// // Do nothing, continue. |
| 294 | /// Ok(()) => (), |
| 295 | /// } |
| 296 | /// |
| 297 | /// Ok(()) |
| 298 | /// } |
| 299 | /// # example()?; |
| 300 | /// # Ok::<(), Error>(()) |
| 301 | /// ``` |
| 302 | /// |
| 303 | /// An alternative to be more concise is the [`if let`] syntax: |
| 304 | /// |
| 305 | /// ``` |
| 306 | /// fn example() -> Result { |
| 307 | /// let mut numbers = KVec::new(); |
| 308 | /// |
| 309 | /// if let Err(e) = numbers.push(72, GFP_KERNEL) { |
| 310 | /// pr_err!("Error pushing 72: {e:?}"); |
| 311 | /// return Err(e.into()); |
| 312 | /// } |
| 313 | /// |
| 314 | /// if let Err(e) = numbers.push(108, GFP_KERNEL) { |
| 315 | /// pr_err!("Error pushing 108: {e:?}"); |
| 316 | /// return Err(e.into()); |
| 317 | /// } |
| 318 | /// |
| 319 | /// if let Err(e) = numbers.push(200, GFP_KERNEL) { |
| 320 | /// pr_err!("Error pushing 200: {e:?}"); |
| 321 | /// return Err(e.into()); |
| 322 | /// } |
| 323 | /// |
| 324 | /// Ok(()) |
| 325 | /// } |
| 326 | /// # example()?; |
| 327 | /// # Ok::<(), Error>(()) |
| 328 | /// ``` |
| 329 | /// |
| 330 | /// Instead of these verbose [`match`]/[`if let`], the [`?`] operator can |
| 331 | /// be used to handle the [`Result`]. Using the [`?`] operator is often |
| 332 | /// the best choice to handle [`Result`] in a non-verbose way as done in |
| 333 | /// [`samples/rust/rust_minimal.rs`]: |
| 334 | /// |
| 335 | /// ``` |
| 336 | /// fn example() -> Result { |
| 337 | /// let mut numbers = KVec::new(); |
| 338 | /// |
| 339 | /// numbers.push(72, GFP_KERNEL)?; |
| 340 | /// numbers.push(108, GFP_KERNEL)?; |
| 341 | /// numbers.push(200, GFP_KERNEL)?; |
| 342 | /// |
| 343 | /// Ok(()) |
| 344 | /// } |
| 345 | /// # example()?; |
| 346 | /// # Ok::<(), Error>(()) |
| 347 | /// ``` |
| 348 | /// |
| 349 | /// Another possibility is to call [`unwrap()`](Result::unwrap) or |
| 350 | /// [`expect()`](Result::expect). However, use of these functions is |
| 351 | /// *heavily discouraged* in the kernel because they trigger a Rust |
| 352 | /// [`panic!`] if an error happens, which may destabilize the system or |
| 353 | /// entirely break it as a result -- just like the C [`BUG()`] macro. |
| 354 | /// Please see the documentation for the C macro [`BUG()`] for guidance |
| 355 | /// on when to use these functions. |
| 356 | /// |
| 357 | /// Alternatively, depending on the use case, using [`unwrap_or()`], |
| 358 | /// [`unwrap_or_else()`], [`unwrap_or_default()`] or [`unwrap_unchecked()`] |
| 359 | /// might be an option, as well. |
| 360 | /// |
| 361 | /// For even more details, please see the [Rust documentation]. |
| 362 | /// |
| 363 | /// [`match`]: https://doc.rust-lang.org/reference/expressions/match-expr.html |
| 364 | /// [`samples/rust/rust_minimal.rs`]: srctree/samples/rust/rust_minimal.rs |
| 365 | /// [`if let`]: https://doc.rust-lang.org/reference/expressions/if-expr.html#if-let-expressions |
| 366 | /// [`?`]: https://doc.rust-lang.org/reference/expressions/operator-expr.html#the-question-mark-operator |
| 367 | /// [`unwrap()`]: Result::unwrap |
| 368 | /// [`expect()`]: Result::expect |
| 369 | /// [`BUG()`]: https://docs.kernel.org/process/deprecated.html#bug-and-bug-on |
| 370 | /// [`unwrap_or()`]: Result::unwrap_or |
| 371 | /// [`unwrap_or_else()`]: Result::unwrap_or_else |
| 372 | /// [`unwrap_or_default()`]: Result::unwrap_or_default |
| 373 | /// [`unwrap_unchecked()`]: Result::unwrap_unchecked |
| 374 | /// [Rust documentation]: https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html |
| 375 | pub type Result<T = (), E = Error> = core::result::Result<T, E>; |
| 376 | |
| 377 | /// Converts an integer as returned by a C kernel function to an error if it's negative, and |
| 378 | /// `Ok(())` otherwise. |
| 379 | pub fn to_result(err: crate::ffi::c_int) -> Result { |
| 380 | if err < 0 { |
| 381 | Err(Error::from_errno(err)) |
| 382 | } else { |
| 383 | Ok(()) |
| 384 | } |
| 385 | } |
| 386 | |
| 387 | /// Transform a kernel "error pointer" to a normal pointer. |
| 388 | /// |
| 389 | /// Some kernel C API functions return an "error pointer" which optionally |
| 390 | /// embeds an `errno`. Callers are supposed to check the returned pointer |
| 391 | /// for errors. This function performs the check and converts the "error pointer" |
| 392 | /// to a normal pointer in an idiomatic fashion. |
| 393 | /// |
| 394 | /// # Examples |
| 395 | /// |
| 396 | /// ```ignore |
| 397 | /// # use kernel::from_err_ptr; |
| 398 | /// # use kernel::bindings; |
| 399 | /// fn devm_platform_ioremap_resource( |
| 400 | /// pdev: &mut PlatformDevice, |
| 401 | /// index: u32, |
| 402 | /// ) -> Result<*mut kernel::ffi::c_void> { |
| 403 | /// // SAFETY: `pdev` points to a valid platform device. There are no safety requirements |
| 404 | /// // on `index`. |
| 405 | /// from_err_ptr(unsafe { bindings::devm_platform_ioremap_resource(pdev.to_ptr(), index) }) |
| 406 | /// } |
| 407 | /// ``` |
| 408 | pub fn from_err_ptr<T>(ptr: *mut T) -> Result<*mut T> { |
| 409 | // CAST: Casting a pointer to `*const crate::ffi::c_void` is always valid. |
| 410 | let const_ptr: *const crate::ffi::c_void = ptr.cast(); |
| 411 | // SAFETY: The FFI function does not deref the pointer. |
| 412 | if unsafe { bindings::IS_ERR(const_ptr) } { |
| 413 | // SAFETY: The FFI function does not deref the pointer. |
| 414 | let err = unsafe { bindings::PTR_ERR(const_ptr) }; |
| 415 | |
| 416 | #[allow(clippy::unnecessary_cast)] |
| 417 | // CAST: If `IS_ERR()` returns `true`, |
| 418 | // then `PTR_ERR()` is guaranteed to return a |
| 419 | // negative value greater-or-equal to `-bindings::MAX_ERRNO`, |
| 420 | // which always fits in an `i16`, as per the invariant above. |
| 421 | // And an `i16` always fits in an `i32`. So casting `err` to |
| 422 | // an `i32` can never overflow, and is always valid. |
| 423 | // |
| 424 | // SAFETY: `IS_ERR()` ensures `err` is a |
| 425 | // negative value greater-or-equal to `-bindings::MAX_ERRNO`. |
| 426 | return Err(unsafe { Error::from_errno_unchecked(err as crate::ffi::c_int) }); |
| 427 | } |
| 428 | Ok(ptr) |
| 429 | } |
| 430 | |
| 431 | /// Calls a closure returning a [`crate::error::Result<T>`] and converts the result to |
| 432 | /// a C integer result. |
| 433 | /// |
| 434 | /// This is useful when calling Rust functions that return [`crate::error::Result<T>`] |
| 435 | /// from inside `extern "C"` functions that need to return an integer error result. |
| 436 | /// |
| 437 | /// `T` should be convertible from an `i16` via `From<i16>`. |
| 438 | /// |
| 439 | /// # Examples |
| 440 | /// |
| 441 | /// ```ignore |
| 442 | /// # use kernel::from_result; |
| 443 | /// # use kernel::bindings; |
| 444 | /// unsafe extern "C" fn probe_callback( |
| 445 | /// pdev: *mut bindings::platform_device, |
| 446 | /// ) -> kernel::ffi::c_int { |
| 447 | /// from_result(|| { |
| 448 | /// let ptr = devm_alloc(pdev)?; |
| 449 | /// bindings::platform_set_drvdata(pdev, ptr); |
| 450 | /// Ok(0) |
| 451 | /// }) |
| 452 | /// } |
| 453 | /// ``` |
| 454 | pub fn from_result<T, F>(f: F) -> T |
| 455 | where |
| 456 | T: From<i16>, |
| 457 | F: FnOnce() -> Result<T>, |
| 458 | { |
| 459 | match f() { |
| 460 | Ok(v) => v, |
| 461 | // NO-OVERFLOW: negative `errno`s are no smaller than `-bindings::MAX_ERRNO`, |
| 462 | // `-bindings::MAX_ERRNO` fits in an `i16` as per invariant above, |
| 463 | // therefore a negative `errno` always fits in an `i16` and will not overflow. |
| 464 | Err(e) => T::from(e.to_errno() as i16), |
| 465 | } |
| 466 | } |
| 467 | |
| 468 | /// Error message for calling a default function of a [`#[vtable]`](macros::vtable) trait. |
| 469 | pub const VTABLE_DEFAULT_ERROR: &str = |
| 470 | "This function must not be called, see the #[vtable] documentation." ; |
| 471 | |