@@ -16,50 +16,55 @@ use core::{
16
16
sync:: atomic:: { AtomicU64 , Ordering } ,
17
17
} ;
18
18
19
- /// A wrapper around a blk-mq `struct request`. This represents an IO request.
19
+ /// A wrapper around a blk-mq [ `struct request`] . This represents an IO request.
20
20
///
21
21
/// # Implementation details
22
22
///
23
23
/// There are four states for a request that the Rust bindings care about:
24
24
///
25
- /// A) Request is owned by block layer (refcount 0)
26
- /// B) Request is owned by driver but with zero `ARef`s in existence
27
- /// (refcount 1)
28
- /// C) Request is owned by driver with exactly one `ARef` in existence
29
- /// (refcount 2)
30
- /// D) Request is owned by driver with more than one `ARef` in existence
31
- /// (refcount > 2)
25
+ /// 1. Request is owned by block layer (refcount 0).
26
+ /// 2. Request is owned by driver but with zero [ `ARef`] s in existence
27
+ /// (refcount 1).
28
+ /// 3. Request is owned by driver with exactly one [ `ARef`] in existence
29
+ /// (refcount 2).
30
+ /// 4. Request is owned by driver with more than one [ `ARef`] in existence
31
+ /// (refcount > 2).
32
32
///
33
33
///
34
- /// We need to track A and B to ensure we fail tag to request conversions for
34
+ /// We need to track 1 and 2 to ensure we fail tag to request conversions for
35
35
/// requests that are not owned by the driver.
36
36
///
37
- /// We need to track C and D to ensure that it is safe to end the request and hand
37
+ /// We need to track 3 and 4 to ensure that it is safe to end the request and hand
38
38
/// back ownership to the block layer.
39
39
///
40
40
/// The states are tracked through the private `refcount` field of
41
41
/// `RequestDataWrapper`. This structure lives in the private data area of the C
42
- /// `struct request`.
42
+ /// [ `struct request`] .
43
43
///
44
44
/// # Invariants
45
45
///
46
- /// * `self.0` is a valid `struct request` created by the C portion of the kernel.
46
+ /// * `self.0` is a valid [`struct request`] created by the C portion of the
47
+ /// kernel.
47
48
/// * The private data area associated with this request must be an initialized
48
49
/// and valid `RequestDataWrapper<T>`.
49
50
/// * `self` is reference counted by atomic modification of
50
- /// self.wrapper_ref().refcount().
51
+ /// `self.wrapper_ref().refcount()`.
52
+ ///
53
+ /// [`struct request`]: srctree/include/linux/blk-mq.h
51
54
///
52
55
#[ repr( transparent) ]
53
56
pub struct Request < T : Operations > ( Opaque < bindings:: request > , PhantomData < T > ) ;
54
57
55
58
impl < T : Operations > Request < T > {
56
- /// Create an `ARef<Request>` from a `struct request` pointer.
59
+ /// Create an [ `ARef<Request>`] from a [ `struct request`] pointer.
57
60
///
58
61
/// # Safety
59
62
///
60
63
/// * The caller must own a refcount on `ptr` that is transferred to the
61
- /// returned `ARef`.
62
- /// * The type invariants for `Request` must hold for the pointee of `ptr`.
64
+ /// returned [`ARef`].
65
+ /// * The type invariants for [`Request`] must hold for the pointee of `ptr`.
66
+ ///
67
+ /// [`struct request`]: srctree/include/linux/blk-mq.h
63
68
pub ( crate ) unsafe fn aref_from_raw ( ptr : * mut bindings:: request ) -> ARef < Self > {
64
69
// INVARIANT: By the safety requirements of this function, invariants are upheld.
65
70
// SAFETY: By the safety requirement of this function, we own a
@@ -84,12 +89,14 @@ impl<T: Operations> Request<T> {
84
89
}
85
90
86
91
/// Try to take exclusive ownership of `this` by dropping the refcount to 0.
87
- /// This fails if `this` is not the only `ARef` pointing to the underlying
88
- /// `Request`.
92
+ /// This fails if `this` is not the only [ `ARef`] pointing to the underlying
93
+ /// [ `Request`] .
89
94
///
90
- /// If the operation is successful, `Ok` is returned with a pointer to the
91
- /// C `struct request`. If the operation fails, `this` is returned in the
92
- /// `Err` variant.
95
+ /// If the operation is successful, [`Ok`] is returned with a pointer to the
96
+ /// C [`struct request`]. If the operation fails, `this` is returned in the
97
+ /// [`Err`] variant.
98
+ ///
99
+ /// [`struct request`]: srctree/include/linux/blk-mq.h
93
100
fn try_set_end ( this : ARef < Self > ) -> Result < * mut bindings:: request , ARef < Self > > {
94
101
// We can race with `TagSet::tag_to_rq`
95
102
if let Err ( _old) = this. wrapper_ref ( ) . refcount ( ) . compare_exchange (
@@ -109,7 +116,7 @@ impl<T: Operations> Request<T> {
109
116
110
117
/// Notify the block layer that the request has been completed without errors.
111
118
///
112
- /// This function will return `Err` if `this` is not the only `ARef`
119
+ /// This function will return [ `Err`] if `this` is not the only [ `ARef`]
113
120
/// referencing the request.
114
121
pub fn end_ok ( this : ARef < Self > ) -> Result < ( ) , ARef < Self > > {
115
122
let request_ptr = Self :: try_set_end ( this) ?;
@@ -123,13 +130,13 @@ impl<T: Operations> Request<T> {
123
130
Ok ( ( ) )
124
131
}
125
132
126
- /// Return a pointer to the `RequestDataWrapper` stored in the private area
133
+ /// Return a pointer to the [ `RequestDataWrapper`] stored in the private area
127
134
/// of the request structure.
128
135
///
129
136
/// # Safety
130
137
///
131
138
/// - `this` must point to a valid allocation of size at least size of
132
- /// `Self` plus size of `RequestDataWrapper`.
139
+ /// [ `Self`] plus size of [ `RequestDataWrapper`] .
133
140
pub ( crate ) unsafe fn wrapper_ptr ( this : * mut Self ) -> NonNull < RequestDataWrapper > {
134
141
let request_ptr = this. cast :: < bindings:: request > ( ) ;
135
142
// SAFETY: By safety requirements for this function, `this` is a
@@ -141,7 +148,7 @@ impl<T: Operations> Request<T> {
141
148
unsafe { NonNull :: new_unchecked ( wrapper_ptr) }
142
149
}
143
150
144
- /// Return a reference to the `RequestDataWrapper` stored in the private
151
+ /// Return a reference to the [ `RequestDataWrapper`] stored in the private
145
152
/// area of the request structure.
146
153
pub ( crate ) fn wrapper_ref ( & self ) -> & RequestDataWrapper {
147
154
// SAFETY: By type invariant, `self.0` is a valid allocation. Further,
@@ -152,13 +159,15 @@ impl<T: Operations> Request<T> {
152
159
}
153
160
}
154
161
155
- /// A wrapper around data stored in the private area of the C `struct request`.
162
+ /// A wrapper around data stored in the private area of the C [`struct request`].
163
+ ///
164
+ /// [`struct request`]: srctree/include/linux/blk-mq.h
156
165
pub ( crate ) struct RequestDataWrapper {
157
166
/// The Rust request refcount has the following states:
158
167
///
159
168
/// - 0: The request is owned by C block layer.
160
- /// - 1: The request is owned by Rust abstractions but there are no ARef references to it.
161
- /// - 2+: There are `ARef` references to the request.
169
+ /// - 1: The request is owned by Rust abstractions but there are no [` ARef`] references to it.
170
+ /// - 2+: There are [ `ARef`] references to the request.
162
171
refcount : AtomicU64 ,
163
172
}
164
173
@@ -204,7 +213,7 @@ fn atomic_relaxed_op_return(target: &AtomicU64, op: impl Fn(u64) -> u64) -> u64
204
213
}
205
214
206
215
/// Store the result of `op(target.load)` in `target` if `target.load() !=
207
- /// pred`, returning true if the target was updated.
216
+ /// pred`, returning [` true`] if the target was updated.
208
217
fn atomic_relaxed_op_unless ( target : & AtomicU64 , op : impl Fn ( u64 ) -> u64 , pred : u64 ) -> bool {
209
218
target
210
219
. fetch_update ( Ordering :: Relaxed , Ordering :: Relaxed , |x| {
0 commit comments