Skip to content

Commit d0ac814

Browse files
committed
[RFC] Rust: A fallible from_kernel_errno with Result<Error> return
Currently, from_kernel_errno is an infallible function acting as a constructor for Error. In order to achieve its type invariant, We add a check in it which will prompt a warning and return Error::EINVL when errno given is invalid. While this approach ensures type invariant, it brings great ambiguities. When Error::EINVL is returned, the caller has no way to recognize whether it is a valid errno coming from the kernel or an error issued by the check. This tricky behavior may confuse developers and introduce subtle bugs. Since Error will be used in all respects of the kernel, It's definitely not a sound solution. This RFC proposes that we make from_kernel_errno return a Result<Error>. Thus, we have an explicit, clear, and fallible version of from_kernel_errno by which callers are able to know what really happened behind the scene. And it also provides certain flexibility. We pass the power to callers, they can decide how to deal with invalid `errno` case by case.
1 parent 34658e6 commit d0ac814

File tree

1 file changed

+4
-9
lines changed

1 file changed

+4
-9
lines changed

rust/kernel/error.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,21 +62,16 @@ impl Error {
6262

6363
/// Creates an [`Error`] from a kernel error code.
6464
///
65-
/// It is a bug to pass an out-of-range `errno`. `EINVAL` would
65+
/// It is a bug to pass an out-of-range `errno`. Err(`EINVAL`) would
6666
/// be returned in such a case.
67-
pub(crate) fn from_kernel_errno(errno: c_types::c_int) -> Error {
67+
pub(crate) fn from_kernel_errno(errno: c_types::c_int) -> Result<Error> {
6868
if errno < -(bindings::MAX_ERRNO as i32) || errno >= 0 {
69-
// TODO: make it a `WARN_ONCE` once available.
70-
crate::pr_warn!(
71-
"attempted to create `Error` with out of range `errno`: {}",
72-
errno
73-
);
74-
return Error::EINVAL;
69+
return Err(Error::EINVAL);
7570
}
7671

7772
// INVARIANT: the check above ensures the type invariant
7873
// will hold.
79-
Error(errno)
74+
Ok(Error(errno))
8075
}
8176

8277
/// Creates an [`Error`] from a kernel error code.

0 commit comments

Comments
 (0)