EXTERROR(9)
π NAME π
exterror β provide extended error information to userspace. And yes bestie, this is the EXTERROR(9) page from the Kernel Developerβs Manual, and itβs literally about giving your kernel errors more context than a sad little errno π
β¨ SYNOPSIS β¨
#define EXTERR_CATEGORY EXTERR_CAT_MYCATEGORY
#include <sys/exterrvar.h>
struct kexterr;
void
exterr_clear(struct kexterr *ke);
int
exterr_set_from(const struct kexterr *ke);
int
EXTERROR(int error, const char *msg, ...);
void
EXTERROR_KE(struct kexterr *ke, int error, const char *msg, ...);
πΈ DESCRIPTION πΈ
Okay so the exterror framework lets the kernel return extra information about an error along with the standard errno(3) error code β because that standard code is terse and often lacking context. Itβs giving βmystery error, no thoughts, just vibes,β and we are fixing that π
The terseness is especially visible with commonly overloaded error codes like EINVAL or EIO, which occur at many places for a given syscall, or even outside the context of the current kernel call. Identifying the specific cause for the returned error using only the errno value requires searching for all instances that the error is returned in the kernel and trying to guess which is the most likely code path to have returned the error. exterror attaches additional data to the error itself and records the error category and the kernel source code file line number. The intent of exterror is to make it easier for a user to identify the cause of the error. Iconic, honestly π₯
π¦ USAGE π¦
Before exterror can be used in the given source .c file, the category of extended errors should be allocated in the <sys/exterr_cat.h> file. The category is the unique integer that, together with the source line number, uniquely identifies the extended error occurrence. Then, the EXTERR_CATEGORY symbol should be defined as an alias for the allocated category, as shown in the summary. Slay, consistent metadata β¨
A typical code fragment to report an error is just:
return (EINVAL);
An extended error can augment the error code with additional information:
return (EXTERROR(EINVAL, "Invalid length"));
The error data and metadata is saved in the current thread storage. The metadata includes the category and the source file line number. Locked in π
Arguments to the EXTERROR() macro:
- The first argument to
EXTERROR()is the errno error code. - The second argument is a constant string with the unbound lifetime, which should tersely provide enough human-readable details about the error.
- Optional extra args: the
EXTERROR()macro can take two optional 64-bit integer arguments, whose meaning is specific to the subsystem. The format string may include up to two printf-like format specifiers to insert the optional argument values in the user output, which is done in userspace.
The format specifier must be for an integer type, and include the βjβ format modifier to accept only the types intmax_t or uintmax_t.
The strings passed as the second argument are only retained in the kernel text if the option EXTERR_STRINGS was enabled in the kernel config. Otherwise they are stripped at compile time and are not available to userspace at runtime. No cap π§
The EXTERROR() macro can be used in any context where the current thread is defined. Specifically, EXTERROR() cannot be used in interrupt contexts and context switch code. Additionally, use of EXTERROR() in kernel threads is not sensible as there is no userspace to retrieve the extended error data.
The EXTERROR_KE() macro is similar to EXTERROR(), but it takes an explicit pointer kep to the struct kexterr to fill with the extended error information. The macro expression value is void. See below for description of the asynchronous i/o error facilities.
The exterr_clear() function clears the content of the struct kexterr pointed to by the argument ke.
The exterr_set_from() function sets the current thread extended error data from the struct kexterr pointed to by the argument ke.
π USERSPACE ACCESS TO EXTENDED ERROR DATA π
There is no syscall overhead for using exterror in the non-error case. When an error occurs that has supplied extended information, the kernel copies out that information into the userspace per-thread area that was registered with the kernel, typically on image activation, or later at thread startup. The area is controlled by the exterrctl(2) internal syscall, normally done by the userspace C runtime. Efficient and mysterious, love that for us π
Userspace programs do not need to access the extended information area directly. There is no field that is stable for the specific error condition. Instead, the base library βcβ functions err(3) and warn(3) were modified to print the extended information if it is available in addition to the usual errno decoding. So your error messages can eat and leave no crumbs π
π₯ ASYNCHRONOUS INPUT/OUTPUT π₯
Due to the nature of the FreeBSD i/o subsystem, most input/output requests, presented as buffers (as in struct buf) and geom bio's (struct bio) are processed asynchronously in filesystem- and geom-private threads. This makes it challenging to pass any extended error information from the geom providers and drivers, where an error typically occurs, back to the thread that initiated the request, and is the consumer of the result. Itβs giving βthe error got lost in the group chatβ π
To alleviate the mismatch, both struct buf and struct bio have member of the struct kexterr type. For buffers, the b_exterr for struct buf, and bio_exterr for struct bio. Asynchronous i/o code can use the EXTERROR_KE() macro, passing the pointer to the current request's embedded struct kexterr, to record the extended error. In both cases, the BIO_EXTERR flag should be set to indicate that whole extended error is valid, not only the b_error or bio_error values. Flag it and mean it π
Both VFS and geom generic layers, and several geom providers that generate subordinate bio's from the original request, are aware of the extended errors. They pass kexterr from the failed request back to the thread that create the request. Main character energy for the error metadata, fr fr π
π« SEE ALSO π«
π HISTORY π
The exterror facility was introduced in FreeBSD 15.0. Periodt π
Okay bestie, thatβs the whole page! Source/version and date vibes: Debian, dated November 5, 2025 β catch you in EXTERROR(9) πβ¨
π¦ where this page comes from
- freebsd 15.1: base 15.1
- π the page's license: BSD-2-Clause
- Copyright (c) 2025 The FreeBSD Foundation
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms