|  | #[repr(C, packed)] | 
|  | #[derive(Debug, Copy, Clone, Default)] | 
|  | pub struct Superblock { | 
|  | pub magic0: u64, | 
|  | pub magic1: u64, | 
|  | pub version: u32, | 
|  | pub flags: u32, | 
|  | pub block_size: u32, | 
|  | pub unused: u32, | 
|  | pub data_block_count: u64, | 
|  | pub journal_block_count: u64, | 
|  | pub inode_count: u64, | 
|  | pub alloc_block_count: u64, | 
|  | pub alloc_inode_count: u64, | 
|  | } | 
|  |  | 
|  | #[repr(C, packed)] | 
|  | #[derive(Debug, Copy, Clone, Default)] | 
|  | pub struct Extent { | 
|  | pub size: u16, | 
|  | pub offset_hi: u16, | 
|  | pub offset_lo: u32, | 
|  | } | 
|  |  | 
|  | impl Extent { | 
|  | pub fn offset(&self) -> usize { | 
|  | //let hi = self.offset_hi as usize; | 
|  | //let lo = self.offset_lo as usize; | 
|  | //return (hi << 32) | lo; | 
|  | return self.offset_lo as usize; | 
|  | } | 
|  | } | 
|  |  | 
|  | #[repr(C, packed)] | 
|  | #[derive(Debug, Copy, Clone, Default)] | 
|  | pub struct NodeHeader { | 
|  | pub flags: u16, | 
|  | pub version: u16, | 
|  | pub next_node: u32, | 
|  | } | 
|  |  | 
|  | impl NodeHeader { | 
|  | pub const FLAG_INODE: u16 = 0b0000000000000001; | 
|  | pub const FLAG_EXTENT: u16 = 0b0000000000000010; | 
|  | } | 
|  |  | 
|  | #[repr(C, packed)] | 
|  | #[derive(Debug, Copy, Clone, Default)] | 
|  | pub struct Inode { | 
|  | pub header: NodeHeader, | 
|  | pub hash0: u64, | 
|  | pub hash1: u64, | 
|  | pub hash2: u64, | 
|  | pub hash3: u64, | 
|  | pub blob_size: u64, | 
|  | pub block_count: u32, | 
|  | pub extent_count: u16, | 
|  | pub padding: u16, | 
|  | pub inline_extent: Extent, | 
|  | } | 
|  |  | 
|  | #[repr(C, packed)] | 
|  | #[derive(Debug, Copy, Clone)] | 
|  | pub struct ExtentContainer { | 
|  | pub header: NodeHeader, | 
|  | pub previous_node: u32, | 
|  | pub extent_count: u16, | 
|  | pub reserved: u16, | 
|  | pub extents: [Extent; 6], | 
|  | } | 
|  |  | 
|  | #[repr(C, packed)] | 
|  | #[derive(Debug, Copy, Clone)] | 
|  | pub struct Transaction { | 
|  | pub op: u16, | 
|  | pub size: u16, | 
|  | pub addr: u32, | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn size_check() { | 
|  | use core::mem::*; | 
|  | assert_eq!(size_of::<Extent>(), 8); | 
|  | assert_eq!(size_of::<Inode>(), 64); | 
|  | assert_eq!(size_of::<ExtentContainer>(), 64); | 
|  | } |