1use serde::{Deserialize, Serialize};
2
3pub const DEFAULT_BLOCK_SIZE: usize = 65536;
5
6pub const MAX_NAME_LEN: usize = 255;
8
9pub const BLOCK_STORAGE_HEADER: u64 = 0;
11pub const BLOCK_ROOT_POINTER_A: u64 = 1;
12pub const BLOCK_ROOT_POINTER_B: u64 = 2;
13
14pub const FIRST_DATA_BLOCK: u64 = 3;
16
17#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
21#[repr(u8)]
22pub enum ObjectKind {
23 Superblock = 1,
24 RootPointer = 2,
25 Inode = 3,
26 DirectoryPage = 4,
27 ExtentMap = 5,
28 FileDataChunk = 6,
29}
30
31#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Hash)]
33pub struct ObjectRef {
34 pub block_id: u64,
36}
37
38impl ObjectRef {
39 pub fn new(block_id: u64) -> Self {
40 Self { block_id }
41 }
42
43 pub fn null() -> Self {
44 Self { block_id: u64::MAX }
45 }
46
47 pub fn is_null(&self) -> bool {
48 self.block_id == u64::MAX
49 }
50}
51
52#[derive(Debug, Clone, Serialize, Deserialize)]
56pub struct StorageHeader {
57 pub magic: [u8; 8],
58 pub version: u32,
59 pub block_size: u32,
60 pub total_blocks: u64,
61}
62
63impl StorageHeader {
64 pub const MAGIC: [u8; 8] = *b"DBLCRYPT";
65
66 pub fn new(block_size: u32, total_blocks: u64) -> Self {
67 Self {
68 magic: Self::MAGIC,
69 version: 1,
70 block_size,
71 total_blocks,
72 }
73 }
74
75 pub fn is_valid(&self) -> bool {
76 self.magic == Self::MAGIC && self.version == 1
77 }
78}
79
80#[derive(Debug, Clone, Serialize, Deserialize)]
85pub struct RootPointer {
86 pub generation: u64,
88 pub superblock_ref: ObjectRef,
90 pub checksum: [u8; 32],
92}
93
94#[derive(Debug, Clone, Serialize, Deserialize)]
98pub struct Superblock {
99 pub generation: u64,
100 pub root_inode_ref: ObjectRef,
102}
103
104#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
108#[repr(u8)]
109pub enum InodeKind {
110 File = 1,
111 Directory = 2,
112}
113
114pub type InodeId = u64;
116
117#[derive(Debug, Clone, Serialize, Deserialize)]
119pub struct Inode {
120 pub id: InodeId,
121 pub kind: InodeKind,
122 pub size: u64,
124 pub directory_page_ref: ObjectRef,
127 pub extent_map_ref: ObjectRef,
130 pub created_at: u64,
132 pub modified_at: u64,
133}
134
135#[derive(Debug, Clone, Serialize, Deserialize)]
139pub struct DirectoryEntry {
140 pub name: String,
142 pub inode_ref: ObjectRef,
144 pub inode_id: InodeId,
146 pub kind: InodeKind,
148}
149
150#[derive(Debug, Clone, Serialize, Deserialize)]
152pub struct DirectoryPage {
153 pub entries: Vec<DirectoryEntry>,
154}
155
156impl DirectoryPage {
157 pub fn new() -> Self {
158 Self {
159 entries: Vec::new(),
160 }
161 }
162}
163
164#[derive(Debug, Clone, Serialize, Deserialize)]
168pub struct ExtentEntry {
169 pub chunk_index: u64,
171 pub data_ref: ObjectRef,
173 pub plaintext_len: u32,
175}
176
177#[derive(Debug, Clone, Serialize, Deserialize)]
179pub struct ExtentMap {
180 pub entries: Vec<ExtentEntry>,
181}
182
183impl ExtentMap {
184 pub fn new() -> Self {
185 Self {
186 entries: Vec::new(),
187 }
188 }
189}
190
191#[derive(Debug, Clone, Serialize, Deserialize)]
196pub struct EncryptedObject {
197 pub kind: ObjectKind,
198 pub version: u32,
199 pub nonce: [u8; 12],
201 pub ciphertext: Vec<u8>,
203}
204
205#[derive(Debug, Clone)]
209pub struct LogicalObject {
210 pub kind: ObjectKind,
211 pub payload: Vec<u8>,
212}