rust/kernel/error.rs
Source file repositories/reference/linux-study-clean/rust/kernel/error.rs
File Facts
- System
- Linux kernel
- Corpus path
rust/kernel/error.rs- Extension
.rs- Size
- 19837 bytes
- Lines
- 562
- Domain
- Rust Kernel Layer
- Bucket
- Rust API Membrane
- Inferred role
- Rust Kernel Layer: implementation source
- Status
- source implementation candidate
Why This File Exists
Rust-side wrappers and abstractions around kernel C APIs, ownership contracts, allocation, synchronization, and module integration.
- Rust-side wrappers and abstractions around kernel C APIs, ownership contracts, allocation, synchronization, and module integration.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
- No C-style include directives detected by the generator.
Detected Declarations
function from_errnofunction Somefunction f
Annotated Snippet
if let Some(error) = Self::try_from_errno(errno) {
error
} else {
// TODO: Make it a `WARN_ONCE` once available.
crate::pr_warn!(
"attempted to create `Error` with out of range `errno`: {}\n",
errno
);
code::EINVAL
}
}
/// Creates an [`Error`] from a kernel error code.
///
/// Returns [`None`] if `errno` is out-of-range.
const fn try_from_errno(errno: crate::ffi::c_int) -> Option<Error> {
if errno < -(bindings::MAX_ERRNO as i32) || errno >= 0 {
return None;
}
// SAFETY: `errno` is checked above to be in a valid range.
Some(unsafe { Error::from_errno_unchecked(errno) })
}
/// Creates an [`Error`] from a kernel error code.
///
/// # Safety
///
/// `errno` must be within error code range (i.e. `>= -MAX_ERRNO && < 0`).
const unsafe fn from_errno_unchecked(errno: crate::ffi::c_int) -> Error {
// INVARIANT: The contract ensures the type invariant
// will hold.
// SAFETY: The caller guarantees `errno` is non-zero.
Error(unsafe { NonZeroI32::new_unchecked(errno) })
}
/// Returns the kernel error code.
pub fn to_errno(self) -> crate::ffi::c_int {
self.0.get()
}
#[cfg(CONFIG_BLOCK)]
pub(crate) fn to_blk_status(self) -> bindings::blk_status_t {
// SAFETY: `self.0` is a valid error due to its invariant.
unsafe { bindings::errno_to_blk_status(self.0.get()) }
}
/// Returns the error encoded as a pointer.
pub fn to_ptr<T>(self) -> *mut T {
// SAFETY: `self.0` is a valid error due to its invariant.
unsafe { bindings::ERR_PTR(self.0.get() as crate::ffi::c_long).cast() }
}
/// Returns a string representing the error, if one exists.
#[cfg(not(testlib))]
pub fn name(&self) -> Option<&'static CStr> {
// SAFETY: Just an FFI call, there are no extra safety requirements.
let ptr = unsafe { bindings::errname(-self.0.get()) };
if ptr.is_null() {
None
} else {
use crate::str::CStrExt as _;
// SAFETY: The string returned by `errname` is static and `NUL`-terminated.
Some(unsafe { CStr::from_char_ptr(ptr) })
}
}
/// Returns a string representing the error, if one exists.
///
/// When `testlib` is configured, this always returns `None` to avoid the dependency on a
/// kernel function so that tests that use this (e.g., by calling [`Result::unwrap`]) can still
/// run in userspace.
#[cfg(testlib)]
pub fn name(&self) -> Option<&'static CStr> {
None
}
}
impl fmt::Debug for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.name() {
// Print out number if no name can be found.
None => f.debug_tuple("Error").field(&-self.0).finish(),
Some(name) => f
.debug_tuple(
// SAFETY: These strings are ASCII-only.
unsafe { core::str::from_utf8_unchecked(name.to_bytes()) },
)
.finish(),
Annotation
- Detected declarations: `function from_errno`, `function Some`, `function f`.
- Atlas domain: Rust Kernel Layer / Rust API Membrane.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.