1use crate::{ExtentDataRef, SharedDataRef};
2use num_enum::{IntoPrimitive, TryFromPrimitive};
3use static_assertions::{const_assert, const_assert_eq};
4use strum::EnumIter;
5use zerocopy::little_endian::U64 as U64LE;
6use zerocopy_derive::*;
7
8#[derive(Copy, Clone, Debug, Hash, TryFromBytes, IntoBytes, Unaligned, KnownLayout, Immutable)]
17#[repr(C, packed)]
18pub struct ExtentInlineRefHeader {
19 pub ref_type: ExtentInlineRefType,
25
26 pub offset: U64LE,
30}
31const_assert_eq!(core::mem::size_of::<ExtentInlineRefHeader>(), 9);
32
33#[derive(Copy, Clone, TryFromBytes, Unaligned, KnownLayout, Immutable)]
39#[repr(C, packed)]
40pub struct ExtentInlineRefFull {
41 pub ref_type: ExtentInlineRefType,
43
44 pub tail: ExtentInlineRefTail,
48}
49const_assert_eq!(core::mem::size_of::<ExtentInlineRefFull>(), 29);
50
51impl ExtentInlineRefFull {
52 pub fn offset(&self) -> Option<u64> {
56 match self.ref_type {
57 ExtentInlineRefType::TreeBlockRef | ExtentInlineRefType::SharedBlockRef => {
58 Some(unsafe { self.tail.offset.get() })
59 }
60 ExtentInlineRefType::SharedDataRef => {
61 Some(unsafe { self.tail.shared_data_tail.offset.get() })
62 }
63 _ => None,
64 }
65 }
66
67 pub fn extent_data_ref(&self) -> Option<ExtentDataRef> {
70 if self.ref_type == ExtentInlineRefType::ExtentDataRef {
71 Some(unsafe { self.tail.extent_data_ref })
72 } else {
73 None
74 }
75 }
76
77 pub fn shared_data_tail(&self) -> Option<ExtentInlineRefSharedDataTail> {
80 if self.ref_type == ExtentInlineRefType::SharedDataRef {
81 Some(unsafe { self.tail.shared_data_tail })
82 } else {
83 None
84 }
85 }
86
87 pub fn as_tree_block_ref(&self) -> Option<&ExtentInlineTreeBlockRef> {
88 const_assert!(
89 core::mem::size_of::<ExtentInlineRefFull>()
90 >= core::mem::size_of::<ExtentInlineTreeBlockRef>()
91 );
92
93 if self.ref_type == ExtentInlineRefType::TreeBlockRef {
94 Some(unsafe {
97 &*(self as *const ExtentInlineRefFull as *const ExtentInlineTreeBlockRef)
98 })
99 } else {
100 None
101 }
102 }
103
104 pub fn as_shared_block_ref(&self) -> Option<&ExtentInlineSharedBlockRef> {
105 const_assert!(
106 core::mem::size_of::<ExtentInlineRefFull>()
107 >= core::mem::size_of::<ExtentInlineSharedBlockRef>()
108 );
109
110 if self.ref_type == ExtentInlineRefType::SharedBlockRef {
111 Some(unsafe {
114 &*(self as *const ExtentInlineRefFull as *const ExtentInlineSharedBlockRef)
115 })
116 } else {
117 None
118 }
119 }
120
121 pub fn as_extent_data_ref(&self) -> Option<&ExtentInlineExtentDataRef> {
122 const_assert!(
123 core::mem::size_of::<ExtentInlineRefFull>()
124 >= core::mem::size_of::<ExtentInlineExtentDataRef>()
125 );
126
127 if self.ref_type == ExtentInlineRefType::ExtentDataRef {
128 Some(unsafe {
131 &*(self as *const ExtentInlineRefFull as *const ExtentInlineExtentDataRef)
132 })
133 } else {
134 None
135 }
136 }
137
138 pub fn as_shared_data_ref(&self) -> Option<&ExtentInlineSharedDataRef> {
139 const_assert!(
140 core::mem::size_of::<ExtentInlineRefFull>()
141 >= core::mem::size_of::<ExtentInlineSharedDataRef>()
142 );
143
144 if self.ref_type == ExtentInlineRefType::SharedDataRef {
145 Some(unsafe {
148 &*(self as *const ExtentInlineRefFull as *const ExtentInlineSharedDataRef)
149 })
150 } else {
151 None
152 }
153 }
154}
155
156#[derive(Copy, Clone, FromBytes, Unaligned, KnownLayout, Immutable)]
158#[repr(C, packed)]
159pub union ExtentInlineRefTail {
160 pub offset: U64LE,
161 pub extent_data_ref: ExtentDataRef,
162 pub shared_data_tail: ExtentInlineRefSharedDataTail,
163}
164
165#[derive(Copy, Clone, Debug, Hash, FromBytes, IntoBytes, Unaligned, KnownLayout, Immutable)]
167#[repr(C, packed)]
168pub struct ExtentInlineRefSharedDataTail {
169 pub offset: U64LE,
172
173 pub shared_data_ref: SharedDataRef,
175}
176
177#[derive(Copy, Clone, Debug, Hash, TryFromBytes, IntoBytes, Unaligned, KnownLayout, Immutable)]
180#[repr(C, packed)]
181pub struct ExtentInlineTreeBlockRef {
182 ref_type: ExtentInlineTreeBlockRefType,
184
185 pub offset: U64LE,
187}
188
189#[derive(Copy, Clone, Debug, Hash, PartialEq, TryFromBytes, IntoBytes, KnownLayout, Immutable)]
190#[repr(u8)]
191enum ExtentInlineTreeBlockRefType {
192 #[allow(dead_code)]
193 TreeBlockRef = ExtentInlineRefType::TreeBlockRef as u8,
194}
195const_assert_eq!(
196 core::mem::size_of::<ExtentInlineTreeBlockRefType>(),
197 core::mem::size_of::<ExtentInlineRefType>()
198);
199
200#[derive(Copy, Clone, Debug, Hash, TryFromBytes, IntoBytes, Unaligned, KnownLayout, Immutable)]
203#[repr(C, packed)]
204pub struct ExtentInlineSharedBlockRef {
205 ref_type: ExtentInlineSharedBlockRefType,
207
208 pub offset: U64LE,
210}
211
212#[derive(Copy, Clone, Debug, Hash, PartialEq, TryFromBytes, IntoBytes, KnownLayout, Immutable)]
213#[repr(u8)]
214#[allow(dead_code)]
215enum ExtentInlineSharedBlockRefType {
216 SharedBlockRef = ExtentInlineRefType::SharedBlockRef as u8,
217}
218
219#[derive(Copy, Clone, Debug, Hash, TryFromBytes, IntoBytes, Unaligned, KnownLayout, Immutable)]
222#[repr(C, packed)]
223pub struct ExtentInlineExtentDataRef {
224 ref_type: ExtentInlineExtentDataRefType,
226
227 pub extent_data_ref: ExtentDataRef,
229}
230
231#[derive(Copy, Clone, Debug, Hash, PartialEq, TryFromBytes, IntoBytes, KnownLayout, Immutable)]
232#[repr(u8)]
233enum ExtentInlineExtentDataRefType {
234 #[allow(dead_code)]
235 ExtentDataRef = ExtentInlineRefType::ExtentDataRef as u8,
236}
237const_assert_eq!(
238 core::mem::size_of::<ExtentInlineExtentDataRefType>(),
239 core::mem::size_of::<ExtentInlineRefType>()
240);
241
242#[derive(Copy, Clone, Debug, Hash, TryFromBytes, IntoBytes, Unaligned, KnownLayout, Immutable)]
245#[repr(C, packed)]
246pub struct ExtentInlineSharedDataRef {
247 ref_type: ExtentInlineSharedDataRefType,
249
250 pub shared_data_tail: ExtentInlineRefSharedDataTail,
254}
255
256#[derive(Copy, Clone, Debug, Hash, PartialEq, TryFromBytes, IntoBytes, KnownLayout, Immutable)]
257#[repr(u8)]
258enum ExtentInlineSharedDataRefType {
259 #[allow(dead_code)]
260 SharedDataRef = ExtentInlineRefType::SharedDataRef as u8,
261}
262const_assert_eq!(
263 core::mem::size_of::<ExtentInlineSharedDataRefType>(),
264 core::mem::size_of::<ExtentInlineRefType>()
265);
266
267#[derive(
272 Copy,
273 Clone,
274 Debug,
275 Hash,
276 PartialEq,
277 EnumIter,
278 IntoPrimitive,
279 TryFromPrimitive,
280 TryFromBytes,
281 IntoBytes,
282 KnownLayout,
283 Immutable,
284)]
285#[repr(u8)]
286pub enum ExtentInlineRefType {
287 TreeBlockRef = 176,
293
294 SharedBlockRef = 182,
301
302 ExtentDataRef = 178,
310
311 SharedDataRef = 184,
321}