rust/kernel/maple_tree.rs
Source file repositories/reference/linux-study-clean/rust/kernel/maple_tree.rs
File Facts
- System
- Linux kernel
- Corpus path
rust/kernel/maple_tree.rs- Extension
.rs- Size
- 22029 bytes
- Lines
- 657
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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 dereffunction free_all_entriesfunction dropfunction drop
Annotated Snippet
unsafe fn free_all_entries(self: Pin<&mut Self>) {
// SAFETY: The caller provides exclusive access to the entire maple tree, so we have
// exclusive access to the entire maple tree despite not holding the lock.
let mut ma_state = unsafe { MaState::new_raw(self.into_ref().get_ref(), 0, usize::MAX) };
loop {
// This uses the raw accessor because we're destroying pointers without removing them
// from the maple tree, which is only valid because this is the destructor.
//
// Take the rcu lock because mas_find_raw() requires that you hold either the spinlock
// or the rcu read lock. This is only really required if memory reclaim might
// reallocate entries in the tree, as we otherwise have exclusive access. That feature
// doesn't exist yet, so for now, taking the rcu lock only serves the purpose of
// silencing lockdep.
let ptr = {
let _rcu = kernel::sync::rcu::Guard::new();
ma_state.mas_find_raw(usize::MAX)
};
if ptr.is_null() {
break;
}
// SAFETY: By the type invariants, this pointer references a valid value of type `T`.
// By the safety requirements, it is okay to free it without removing it from the maple
// tree.
drop(unsafe { T::from_foreign(ptr) });
}
}
}
#[pinned_drop]
impl<T: ForeignOwnable> PinnedDrop for MapleTree<T> {
#[inline]
fn drop(mut self: Pin<&mut Self>) {
// We only iterate the tree if the Rust value has a destructor.
if core::mem::needs_drop::<T>() {
// SAFETY: Other than the below `mtree_destroy` call, the tree will not be accessed
// after this call.
unsafe { self.as_mut().free_all_entries() };
}
// SAFETY: The tree is valid, and will not be accessed after this call.
unsafe { bindings::mtree_destroy(self.tree.get()) };
}
}
/// A reference to a [`MapleTree`] that owns the inner lock.
///
/// # Invariants
///
/// This guard owns the inner spinlock.
#[must_use = "if unused, the lock will be immediately unlocked"]
pub struct MapleGuard<'tree, T: ForeignOwnable>(&'tree MapleTree<T>);
impl<'tree, T: ForeignOwnable> Drop for MapleGuard<'tree, T> {
#[inline]
fn drop(&mut self) {
// SAFETY: By the type invariants, we hold this spinlock.
unsafe { bindings::spin_unlock(self.0.ma_lock()) };
}
}
impl<'tree, T: ForeignOwnable> MapleGuard<'tree, T> {
/// Create a [`MaState`] protected by this lock guard.
pub fn ma_state(&mut self, first: usize, end: usize) -> MaState<'_, T> {
// SAFETY: The `MaState` borrows this `MapleGuard`, so it can also borrow the `MapleGuard`s
// read/write permissions to the maple tree.
unsafe { MaState::new_raw(self.0, first, end) }
}
/// Load the value at the given index.
///
/// # Examples
///
/// Read the value while holding the spinlock.
///
/// ```
/// use kernel::maple_tree::MapleTree;
///
/// let tree = KBox::pin_init(MapleTree::<KBox<i32>>::new(), GFP_KERNEL)?;
///
/// let ten = KBox::new(10, GFP_KERNEL)?;
/// let twenty = KBox::new(20, GFP_KERNEL)?;
/// tree.insert(100, ten, GFP_KERNEL)?;
/// tree.insert(200, twenty, GFP_KERNEL)?;
///
/// let mut lock = tree.lock();
/// assert_eq!(lock.load(100).map(|v| *v), Some(10));
/// assert_eq!(lock.load(200).map(|v| *v), Some(20));
/// assert_eq!(lock.load(300).map(|v| *v), None);
/// # Ok::<_, Error>(())
Annotation
- Detected declarations: `function deref`, `function free_all_entries`, `function drop`, `function drop`.
- Atlas domain: Rust Kernel Layer / Rust API Membrane.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.