1#![allow(non_camel_case_types)]
6#![allow(non_snake_case)]
7#![allow(dead_code)]
8
9use std::os::raw::{c_char, c_int, c_void};
10
11pub const UUID_SIZE: usize = 16;
13
14pub const F_SET_EXT2: c_int = 2;
16pub const F_SET_EXT3: c_int = 3;
17pub const F_SET_EXT4: c_int = 4;
18
19#[repr(C)]
21pub struct ext4_bcache {
22 _opaque: [u8; 0],
23}
24
25#[repr(C)]
27pub struct ext4_fs {
28 _opaque: [u8; 0],
29}
30
31#[repr(C)]
33pub struct ext4_blockdev_iface {
34 pub open: Option<unsafe extern "C" fn(bdev: *mut ext4_blockdev) -> c_int>,
36
37 pub bread: Option<
39 unsafe extern "C" fn(
40 bdev: *mut ext4_blockdev,
41 buf: *mut c_void,
42 blk_id: u64,
43 blk_cnt: u32,
44 ) -> c_int,
45 >,
46
47 pub bwrite: Option<
49 unsafe extern "C" fn(
50 bdev: *mut ext4_blockdev,
51 buf: *const c_void,
52 blk_id: u64,
53 blk_cnt: u32,
54 ) -> c_int,
55 >,
56
57 pub close: Option<unsafe extern "C" fn(bdev: *mut ext4_blockdev) -> c_int>,
59
60 pub lock: Option<unsafe extern "C" fn(bdev: *mut ext4_blockdev) -> c_int>,
62
63 pub unlock: Option<unsafe extern "C" fn(bdev: *mut ext4_blockdev) -> c_int>,
65
66 pub ph_bsize: u32,
68
69 pub ph_bcnt: u64,
71
72 pub ph_bbuf: *mut u8,
74
75 pub ph_refctr: u32,
77
78 pub bread_ctr: u32,
80
81 pub bwrite_ctr: u32,
83
84 pub p_user: *mut c_void,
86}
87
88#[repr(C)]
90pub struct ext4_blockdev {
91 pub bdif: *mut ext4_blockdev_iface,
93
94 pub part_offset: u64,
96
97 pub part_size: u64,
99
100 pub bc: *mut ext4_bcache,
102
103 pub lg_bsize: u32,
105
106 pub lg_bcnt: u64,
108
109 pub cache_write_back: u32,
111
112 pub fs: *mut ext4_fs,
114
115 pub journal: *mut c_void,
117}
118
119#[repr(C)]
121pub struct ext4_mkfs_info {
122 pub len: u64,
124
125 pub block_size: u32,
127
128 pub blocks_per_group: u32,
130
131 pub inodes_per_group: u32,
133
134 pub inode_size: u32,
136
137 pub inodes: u32,
139
140 pub journal_blocks: u32,
142
143 pub feat_ro_compat: u32,
145
146 pub feat_compat: u32,
148
149 pub feat_incompat: u32,
151
152 pub bg_desc_reserve_blocks: u32,
154
155 pub dsc_size: u16,
157
158 pub uuid: [u8; UUID_SIZE],
160
161 pub journal: bool,
163
164 pub label: *const c_char,
166}
167
168extern "C" {
169 pub fn ext4_block_init(bdev: *mut ext4_blockdev) -> c_int;
171
172 pub fn ext4_block_fini(bdev: *mut ext4_blockdev) -> c_int;
174
175 pub fn ext4_block_bind_bcache(bdev: *mut ext4_blockdev, bc: *mut ext4_bcache) -> c_int;
177
178 pub fn ext4_bcache_init_dynamic(bc: *mut ext4_bcache, cnt: u32, itemsize: u32) -> c_int;
180
181 pub fn ext4_bcache_fini_dynamic(bc: *mut ext4_bcache) -> c_int;
183
184 pub fn ext4_mkfs_read_info(bdev: *mut ext4_blockdev, info: *mut ext4_mkfs_info) -> c_int;
186
187 pub fn ext4_mkfs(
189 fs: *mut ext4_fs,
190 bd: *mut ext4_blockdev,
191 info: *mut ext4_mkfs_info,
192 fs_type: c_int,
193 ) -> c_int;
194}
195
196impl Default for ext4_blockdev_iface {
197 fn default() -> Self {
198 Self {
199 open: None,
200 bread: None,
201 bwrite: None,
202 close: None,
203 lock: None,
204 unlock: None,
205 ph_bsize: 0,
206 ph_bcnt: 0,
207 ph_bbuf: std::ptr::null_mut(),
208 ph_refctr: 0,
209 bread_ctr: 0,
210 bwrite_ctr: 0,
211 p_user: std::ptr::null_mut(),
212 }
213 }
214}
215
216impl Default for ext4_blockdev {
217 fn default() -> Self {
218 Self {
219 bdif: std::ptr::null_mut(),
220 part_offset: 0,
221 part_size: 0,
222 bc: std::ptr::null_mut(),
223 lg_bsize: 0,
224 lg_bcnt: 0,
225 cache_write_back: 0,
226 fs: std::ptr::null_mut(),
227 journal: std::ptr::null_mut(),
228 }
229 }
230}
231
232impl Default for ext4_mkfs_info {
233 fn default() -> Self {
234 Self {
235 len: 0,
236 block_size: 4096,
237 blocks_per_group: 0,
238 inodes_per_group: 0,
239 inode_size: 256,
240 inodes: 0,
241 journal_blocks: 0,
242 feat_ro_compat: 0,
243 feat_compat: 0,
244 feat_incompat: 0,
245 bg_desc_reserve_blocks: 0,
246 dsc_size: 0,
247 uuid: [0u8; UUID_SIZE],
248 journal: false,
249 label: std::ptr::null(),
250 }
251 }
252}
253
254#[cfg(test)]
255mod tests {
256 use super::*;
257
258 #[test]
259 fn test_struct_default_construction() {
260 let _iface = ext4_blockdev_iface::default();
262 let _bdev = ext4_blockdev::default();
263 let _info = ext4_mkfs_info::default();
264 }
265
266 #[test]
267 fn test_constants() {
268 assert_eq!(UUID_SIZE, 16);
269 assert_eq!(F_SET_EXT2, 2);
270 assert_eq!(F_SET_EXT3, 3);
271 assert_eq!(F_SET_EXT4, 4);
272 }
273
274 #[test]
275 fn test_blockdev_iface_default_values() {
276 let iface = ext4_blockdev_iface::default();
277
278 assert!(iface.open.is_none());
279 assert!(iface.bread.is_none());
280 assert!(iface.bwrite.is_none());
281 assert!(iface.close.is_none());
282 assert!(iface.lock.is_none());
283 assert!(iface.unlock.is_none());
284 assert_eq!(iface.ph_bsize, 0);
285 assert_eq!(iface.ph_bcnt, 0);
286 assert!(iface.ph_bbuf.is_null());
287 assert_eq!(iface.ph_refctr, 0);
288 assert_eq!(iface.bread_ctr, 0);
289 assert_eq!(iface.bwrite_ctr, 0);
290 assert!(iface.p_user.is_null());
291 }
292
293 #[test]
294 fn test_blockdev_default_values() {
295 let bdev = ext4_blockdev::default();
296
297 assert!(bdev.bdif.is_null());
298 assert_eq!(bdev.part_offset, 0);
299 assert_eq!(bdev.part_size, 0);
300 assert!(bdev.bc.is_null());
301 assert_eq!(bdev.lg_bsize, 0);
302 assert_eq!(bdev.lg_bcnt, 0);
303 assert_eq!(bdev.cache_write_back, 0);
304 assert!(bdev.fs.is_null());
305 assert!(bdev.journal.is_null());
306 }
307
308 #[test]
309 fn test_mkfs_info_default_values() {
310 let info = ext4_mkfs_info::default();
311
312 assert_eq!(info.len, 0);
313 assert_eq!(info.block_size, 4096);
314 assert_eq!(info.blocks_per_group, 0);
315 assert_eq!(info.inodes_per_group, 0);
316 assert_eq!(info.inode_size, 256);
317 assert_eq!(info.inodes, 0);
318 assert_eq!(info.journal_blocks, 0);
319 assert_eq!(info.feat_ro_compat, 0);
320 assert_eq!(info.feat_compat, 0);
321 assert_eq!(info.feat_incompat, 0);
322 assert_eq!(info.bg_desc_reserve_blocks, 0);
323 assert_eq!(info.dsc_size, 0);
324 assert_eq!(info.uuid, [0u8; UUID_SIZE]);
325 assert!(!info.journal);
326 assert!(info.label.is_null());
327 }
328
329 #[test]
330 fn test_blockdev_iface_custom_values() {
331 let mut buffer = vec![0u8; 512];
332 let mut iface = ext4_blockdev_iface::default();
333
334 iface.ph_bsize = 512;
335 iface.ph_bcnt = 1024;
336 iface.ph_bbuf = buffer.as_mut_ptr();
337
338 assert_eq!(iface.ph_bsize, 512);
339 assert_eq!(iface.ph_bcnt, 1024);
340 assert!(!iface.ph_bbuf.is_null());
341 }
342
343 #[test]
344 fn test_mkfs_info_custom_values() {
345 let mut info = ext4_mkfs_info::default();
346
347 info.len = 10 * 1024 * 1024; info.block_size = 1024;
349 info.inode_size = 128;
350 info.uuid = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
351 info.journal = true;
352
353 assert_eq!(info.len, 10 * 1024 * 1024);
354 assert_eq!(info.block_size, 1024);
355 assert_eq!(info.inode_size, 128);
356 assert_eq!(info.uuid[0], 1);
357 assert_eq!(info.uuid[15], 16);
358 assert!(info.journal);
359 }
360}