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