rust/kernel/block/mq/request.rs
Source file repositories/reference/linux-study-clean/rust/kernel/block/mq/request.rs
File Facts
- System
- Linux kernel
- Corpus path
rust/kernel/block/mq/request.rs- Extension
.rs- Size
- 10181 bytes
- Lines
- 258
- 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 pubfunction try_set_endfunction Okfunction pubfunction dec_ref
Annotated Snippet
pub(crate) unsafe fn start_unchecked(this: &ARef<Self>) {
// SAFETY: By type invariant, `self.0` is a valid `struct request` and
// we have exclusive access.
unsafe { bindings::blk_mq_start_request(this.0.get()) };
}
/// Try to take exclusive ownership of `this` by dropping the refcount to 0.
/// This fails if `this` is not the only [`ARef`] pointing to the underlying
/// [`Request`].
///
/// If the operation is successful, [`Ok`] is returned with a pointer to the
/// C [`struct request`]. If the operation fails, `this` is returned in the
/// [`Err`] variant.
///
/// [`struct request`]: srctree/include/linux/blk-mq.h
fn try_set_end(this: ARef<Self>) -> Result<*mut bindings::request, ARef<Self>> {
// To hand back the ownership, we need the current refcount to be 2.
// Since we can race with `TagSet::tag_to_rq`, this needs to atomically reduce
// refcount to 0. `Refcount` does not provide a way to do this, so use the underlying
// atomics directly.
if let Err(_old) = this
.wrapper_ref()
.refcount()
.as_atomic()
.cmpxchg(2, 0, Relaxed)
{
return Err(this);
}
let request_ptr = this.0.get();
core::mem::forget(this);
Ok(request_ptr)
}
/// Notify the block layer that the request has been completed without errors.
///
/// This function will return [`Err`] if `this` is not the only [`ARef`]
/// referencing the request.
pub fn end_ok(this: ARef<Self>) -> Result<(), ARef<Self>> {
let request_ptr = Self::try_set_end(this)?;
// SAFETY: By type invariant, `this.0` was a valid `struct request`. The
// success of the call to `try_set_end` guarantees that there are no
// `ARef`s pointing to this request. Therefore it is safe to hand it
// back to the block layer.
unsafe {
bindings::blk_mq_end_request(
request_ptr,
bindings::BLK_STS_OK as bindings::blk_status_t,
)
};
Ok(())
}
/// Complete the request by scheduling `Operations::complete` for
/// execution.
///
/// The function may be scheduled locally, via SoftIRQ or remotely via IPMI.
/// See `blk_mq_complete_request_remote` in [`blk-mq.c`] for details.
///
/// [`blk-mq.c`]: srctree/block/blk-mq.c
pub fn complete(this: ARef<Self>) {
let ptr = ARef::into_raw(this).cast::<bindings::request>().as_ptr();
// SAFETY: By type invariant, `self.0` is a valid `struct request`
if !unsafe { bindings::blk_mq_complete_request_remote(ptr) } {
// SAFETY: We released a refcount above that we can reclaim here.
let this = unsafe { Request::aref_from_raw(ptr) };
T::complete(this);
}
}
/// Return a pointer to the [`RequestDataWrapper`] stored in the private area
/// of the request structure.
///
/// # Safety
///
/// - `this` must point to a valid allocation of size at least size of
/// [`Self`] plus size of [`RequestDataWrapper`].
pub(crate) unsafe fn wrapper_ptr(this: *mut Self) -> NonNull<RequestDataWrapper> {
let request_ptr = this.cast::<bindings::request>();
// SAFETY: By safety requirements for this function, `this` is a
// valid allocation.
let wrapper_ptr =
unsafe { bindings::blk_mq_rq_to_pdu(request_ptr).cast::<RequestDataWrapper>() };
// SAFETY: By C API contract, `wrapper_ptr` points to a valid allocation
// and is not null.
unsafe { NonNull::new_unchecked(wrapper_ptr) }
}
Annotation
- Detected declarations: `function pub`, `function try_set_end`, `function Ok`, `function pub`, `function dec_ref`.
- 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.