kernel/block/mq/
tag_set.rs1use core::pin::Pin;
8
9use crate::{
10 bindings,
11 block::mq::{operations::OperationsVTable, request::RequestDataWrapper, Operations},
12 error::{self, Result},
13 prelude::try_pin_init,
14 types::Opaque,
15};
16use core::{convert::TryInto, marker::PhantomData};
17use pin_init::{pin_data, pinned_drop, PinInit};
18
19#[pin_data(PinnedDrop)]
27#[repr(transparent)]
28pub struct TagSet<T: Operations> {
29 #[pin]
30 inner: Opaque<bindings::blk_mq_tag_set>,
31 _p: PhantomData<T>,
32}
33
34impl<T: Operations> TagSet<T> {
35 pub fn new(
37 nr_hw_queues: u32,
38 num_tags: u32,
39 num_maps: u32,
40 ) -> impl PinInit<Self, error::Error> {
41 let tag_set: bindings::blk_mq_tag_set = unsafe { core::mem::zeroed() };
44 let tag_set: Result<_> = core::mem::size_of::<RequestDataWrapper>()
45 .try_into()
46 .map(|cmd_size| {
47 bindings::blk_mq_tag_set {
48 ops: OperationsVTable::<T>::build(),
49 nr_hw_queues,
50 timeout: 0, numa_node: bindings::NUMA_NO_NODE,
52 queue_depth: num_tags,
53 cmd_size,
54 flags: 0,
55 driver_data: core::ptr::null_mut::<crate::ffi::c_void>(),
56 nr_maps: num_maps,
57 ..tag_set
58 }
59 })
60 .map(Opaque::new)
61 .map_err(|e| e.into());
62
63 try_pin_init!(TagSet {
64 inner <- tag_set.pin_chain(|tag_set| {
65 let tag_set: &mut Opaque<_> = unsafe { Pin::get_unchecked_mut(tag_set) };
67 error::to_result( unsafe { bindings::blk_mq_alloc_tag_set(tag_set.get())})
69 }),
70 _p: PhantomData,
71 })
72 }
73
74 pub(crate) fn raw_tag_set(&self) -> *mut bindings::blk_mq_tag_set {
76 self.inner.get()
77 }
78}
79
80#[pinned_drop]
81impl<T: Operations> PinnedDrop for TagSet<T> {
82 fn drop(self: Pin<&mut Self>) {
83 unsafe { bindings::blk_mq_free_tag_set(self.inner.get()) };
86 }
87}