xref: /reactos/boot/freeldr/freeldr/include/fs/btrfs.h (revision 94dab57e)
1 /*
2  * PROJECT:     FreeLoader
3  * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE:     BTRFS support for FreeLoader
5  * COPYRIGHT:   Copyright 2018 Victor Perevertkin (victor@perevertkin.ru)
6  */
7 
8 /* Structures were taken from u-boot, https://github.com/u-boot/u-boot/tree/master/fs/btrfs */
9 
10 #pragma once
11 
12 typedef UCHAR u8;
13 typedef USHORT u16;
14 typedef ULONG32 u32;
15 typedef ULONG64 u64;
16 /* type that store on disk, but it is same as cpu type for i386 arch */
17 typedef u8 __u8;
18 typedef u16 __u16;
19 typedef u32 __u32;
20 typedef u64 __u64;
21 
22 #include <fs/crc32c.h>
23 #define btrfs_crc32c(name, len) crc32c_le((u32)~1, name, len)
24 
25 #define BTRFS_SUPER_INFO_OFFSET (64 * 1024)
26 #define BTRFS_SUPER_INFO_SIZE 4096
27 #define BTRFS_MAX_LEAF_SIZE 4096
28 #define BTRFS_BLOCK_SHIFT 12
29 #define BTRFS_BLOCK_SIZE  (1 << BTRFS_BLOCK_SHIFT)
30 
31 #define BTRFS_SUPER_MIRROR_MAX   3
32 #define BTRFS_SUPER_MIRROR_SHIFT 12
33 #define BTRFS_CSUM_SIZE 32
34 #define BTRFS_FSID_SIZE 16
35 #define BTRFS_LABEL_SIZE 256
36 #define BTRFS_SYSTEM_CHUNK_ARRAY_SIZE 2048
37 #define BTRFS_UUID_SIZE 16
38 
39 #define BTRFS_VOL_NAME_MAX 255
40 #define BTRFS_NAME_MAX 255
41 
42 #define BTRFS_MAGIC "_BHRfS_M"
43 #define BTRFS_MAGIC_L 8
44 #define BTRFS_MAGIC_N 0x4d5f53665248425fULL
45 
46 #define BTRFS_SUPER_FLAG_METADUMP   (1ULL << 33)
47 
48 #define BTRFS_DEV_ITEM_KEY      216
49 #define BTRFS_CHUNK_ITEM_KEY    228
50 #define BTRFS_ROOT_REF_KEY      156
51 #define BTRFS_ROOT_ITEM_KEY     132
52 #define BTRFS_EXTENT_DATA_KEY   108
53 #define BTRFS_DIR_ITEM_KEY      84
54 #define BTRFS_DIR_INDEX_KEY     96
55 #define BTRFS_INODE_ITEM_KEY    1
56 #define BTRFS_INODE_REF_KEY     12
57 
58 #define BTRFS_EXTENT_TREE_OBJECTID 2ULL
59 #define BTRFS_FS_TREE_OBJECTID 5ULL
60 
61 #define BTRFS_FIRST_FREE_OBJECTID 256ULL
62 #define BTRFS_LAST_FREE_OBJECTID -256ULL
63 #define BTRFS_FIRST_CHUNK_TREE_OBJECTID 256ULL
64 
65 #define BTRFS_FILE_EXTENT_INLINE 0
66 #define BTRFS_FILE_EXTENT_REG 1
67 #define BTRFS_FILE_EXTENT_PREALLOC 2
68 
69 #define BTRFS_MAX_LEVEL 8
70 #define BTRFS_MAX_CHUNK_ENTRIES 256
71 
72 #define BTRFS_DEV_ITEMS_OBJECTID 1ULL
73 
74 #define BTRFS_FT_REG_FILE   1
75 #define BTRFS_FT_DIR        2
76 #define BTRFS_FT_SYMLINK    7
77 #define BTRFS_FT_XATTR      8
78 #define BTRFS_FT_MAX        9
79 
80 #define BTRFS_COMPRESS_NONE  0
81 #define BTRFS_COMPRESS_ZLIB  1
82 #define BTRFS_COMPRESS_LZO   2
83 
84 #define ROOT_DIR_WORD 0x002f
85 
86 #include <pshpack1.h>
87 
88 struct btrfs_disk_key {
89     __u64 objectid;
90     __u8 type;
91     __u64 offset;
92 };
93 
94 struct btrfs_header {
95     /* these first four must match the super block */
96     __u8 csum[BTRFS_CSUM_SIZE];
97     __u8 fsid[BTRFS_FSID_SIZE]; /* FS specific uuid */
98     __u64 bytenr; /* which block this node is supposed to live in */
99     __u64 flags;
100 
101     /* allowed to be different from the super from here on down */
102     __u8 chunk_tree_uuid[BTRFS_UUID_SIZE];
103     __u64 generation;
104     __u64 owner;
105     __u32 nritems;
106     __u8 level;
107 };
108 
109 struct btrfs_item {
110     struct btrfs_disk_key key;
111     __u32 offset;
112     __u32 size;
113 };
114 
115 struct btrfs_leaf {
116     struct btrfs_header header;
117     struct btrfs_item items[];
118 };
119 
120 struct btrfs_key_ptr {
121     struct btrfs_disk_key key;
122     __u64 blockptr;
123     __u64 generation;
124 };
125 
126 struct btrfs_node {
127     struct btrfs_header header;
128     struct btrfs_key_ptr ptrs[];
129 };
130 
131 struct btrfs_dev_item {
132     /* the internal btrfs device id */
133     __u64 devid;
134 
135     /* size of the device */
136     __u64 total_bytes;
137 
138     /* bytes used */
139     __u64 bytes_used;
140 
141     /* optimal io alignment for this device */
142     __u32 io_align;
143 
144     /* optimal io width for this device */
145     __u32 io_width;
146 
147     /* minimal io size for this device */
148     __u32 sector_size;
149 
150     /* type and info about this device */
151     __u64 type;
152 
153     /* expected generation for this device */
154     __u64 generation;
155 
156     /*
157      * starting byte of this partition on the device,
158      * to allow for stripe alignment in the future
159      */
160     __u64 start_offset;
161 
162     /* grouping information for allocation decisions */
163     __u32 dev_group;
164 
165     /* seek speed 0-100 where 100 is fastest */
166     __u8 seek_speed;
167 
168     /* bandwidth 0-100 where 100 is fastest */
169     __u8 bandwidth;
170 
171     /* btrfs generated uuid for this device */
172     __u8 uuid[BTRFS_UUID_SIZE];
173 
174     /* uuid of FS who owns this device */
175     __u8 fsid[BTRFS_UUID_SIZE];
176 };
177 
178 struct btrfs_stripe {
179     __u64 devid;
180     __u64 offset;
181     __u8 dev_uuid[BTRFS_UUID_SIZE];
182 };
183 
184 struct btrfs_chunk {
185     /* size of this chunk in bytes */
186     __u64 length;
187 
188     /* objectid of the root referencing this chunk */
189     __u64 owner;
190 
191     __u64 stripe_len;
192     __u64 type;
193 
194     /* optimal io alignment for this chunk */
195     __u32 io_align;
196 
197     /* optimal io width for this chunk */
198     __u32 io_width;
199 
200     /* minimal io size for this chunk */
201     __u32 sector_size;
202 
203     /* 2^16 stripes is quite a lot, a second limit is the size of a single
204      * item in the btree
205      */
206     __u16 num_stripes;
207 
208     /* sub stripes only matter for raid10 */
209     __u16 sub_stripes;
210     struct btrfs_stripe stripe;
211     /* additional stripes go here */
212 };
213 
214 struct btrfs_inode_ref {
215     __u64 index;
216     __u16 name_len;
217     /* name goes here */
218 };
219 
220 struct btrfs_timespec {
221     __u64 sec;
222     __u32 nsec;
223 };
224 
225 struct btrfs_inode_item {
226     /* nfs style generation number */
227     __u64 generation;
228     /* transid that last touched this inode */
229     __u64 transid;
230     __u64 size;
231     __u64 nbytes;
232     __u64 block_group;
233     __u32 nlink;
234     __u32 uid;
235     __u32 gid;
236     __u32 mode;
237     __u64 rdev;
238     __u64 flags;
239 
240     /* modification sequence number for NFS */
241     __u64 sequence;
242 
243     /*
244      * a little future expansion, for more than this we can
245      * just grow the inode item and version it
246      */
247     __u64 reserved[4];
248     struct btrfs_timespec atime;
249     struct btrfs_timespec ctime;
250     struct btrfs_timespec mtime;
251     struct btrfs_timespec otime;
252 };
253 
254 
255 struct btrfs_dir_item {
256     struct btrfs_disk_key location;
257     __u64 transid;
258     __u16 data_len;
259     __u16 name_len;
260     __u8 type;
261 };
262 
263 struct btrfs_root_item {
264     struct btrfs_inode_item inode;
265     __u64 generation;
266     __u64 root_dirid;
267     __u64 bytenr;
268     __u64 byte_limit;
269     __u64 bytes_used;
270     __u64 last_snapshot;
271     __u64 flags;
272     __u32 refs;
273     struct btrfs_disk_key drop_progress;
274     __u8 drop_level;
275     __u8 level;
276 };
277 
278 struct btrfs_root_ref {
279     __u64 dirid;
280     __u64 sequence;
281     __u16 name_len;
282 };
283 
284 struct btrfs_file_extent_item {
285     /*
286      * transaction id that created this extent
287      */
288     __u64 generation;
289     /*
290      * max number of bytes to hold this extent in ram
291      * when we split a compressed extent we can't know how big
292      * each of the resulting pieces will be.  So, this is
293      * an upper limit on the size of the extent in ram instead of
294      * an exact limit.
295      */
296     __u64 ram_bytes;
297 
298     /*
299      * 32 bits for the various ways we might encode the data,
300      * including compression and encryption.  If any of these
301      * are set to something a given disk format doesn't understand
302      * it is treated like an incompat flag for reading and writing,
303      * but not for stat.
304      */
305     __u8 compression;
306     __u8 encryption;
307     __u16 other_encoding; /* spare for later use */
308 
309     /* are we inline data or a real extent? */
310     __u8 type;
311 
312     /*
313      * disk space consumed by the extent, checksum blocks are included
314      * in these numbers
315      *
316      * At this offset in the structure, the inline extent data start.
317      */
318     __u64 disk_bytenr;
319     __u64 disk_num_bytes;
320     /*
321      * the logical offset in file blocks (no csums)
322      * this extent record is for.  This allows a file extent to point
323      * into the middle of an existing extent on disk, sharing it
324      * between two snapshots (useful if some bytes in the middle of the
325      * extent have changed
326      */
327     __u64 offset;
328     /*
329      * the logical number of file blocks (no csums included).  This
330      * always reflects the size uncompressed and without encoding.
331      */
332     __u64 num_bytes;
333 
334 };
335 
336 struct btrfs_super_block {
337     __u8 csum[BTRFS_CSUM_SIZE];
338     /* the first 4 fields must match struct btrfs_header */
339     __u8 fsid[BTRFS_FSID_SIZE];    /* FS specific uuid */
340     __u64 bytenr; /* this block number */
341     __u64 flags;
342 
343     /* allowed to be different from the btrfs_header from here own down */
344     __u64 magic;
345     __u64 generation;
346     __u64 root;
347     __u64 chunk_root;
348     __u64 log_root;
349 
350     /* this will help find the new super based on the log root */
351     __u64 log_root_transid;
352     __u64 total_bytes;
353     __u64 bytes_used;
354     __u64 root_dir_objectid;
355     __u64 num_devices;
356     __u32 sectorsize;
357     __u32 nodesize;
358     __u32 __unused_leafsize;
359     __u32 stripesize;
360     __u32 sys_chunk_array_size;
361     __u64 chunk_root_generation;
362     __u64 compat_flags;
363     __u64 compat_ro_flags;
364     __u64 incompat_flags;
365     __u16 csum_type;
366     __u8 root_level;
367     __u8 chunk_root_level;
368     __u8 log_root_level;
369     struct btrfs_dev_item dev_item;
370 
371     char label[BTRFS_LABEL_SIZE];
372 
373     __u64 cache_generation;
374     __u64 uuid_tree_generation;
375 
376     /* future expansion */
377     __u64 reserved[30];
378     __u8 sys_chunk_array[BTRFS_SYSTEM_CHUNK_ARRAY_SIZE];
379 };
380 
381 #include <poppack.h>
382 
383 union tree_buf {
384     struct btrfs_header header;
385     struct btrfs_node node;
386     struct btrfs_leaf leaf;
387 };
388 
389 /* remember how we get to a node/leaf */
390 struct btrfs_path {
391     u64 offsets[BTRFS_MAX_LEVEL];
392     int itemsnr[BTRFS_MAX_LEVEL];
393     int slots[BTRFS_MAX_LEVEL];
394     /* remember whole last leaf */
395     union tree_buf *tree_buf;
396 };
397 
398 /* store logical offset to physical offset mapping */
399 struct btrfs_chunk_map_item {
400     u64 logical;
401     u64 length;
402     u64 devid;
403     u64 physical;
404 };
405 
406 struct btrfs_chunk_map {
407     struct btrfs_chunk_map_item *map;
408     u32 map_length;
409     u32 cur_length;
410 };
411 
412 typedef struct _BTRFS_INFO *PBTRFS_INFO;
413 
414 typedef struct {
415     u64 inr;
416     u64 position;
417     struct btrfs_inode_item inode;
418     PBTRFS_INFO Volume;
419 } btrfs_file_info, * pbtrfs_file_info;
420 
421 const DEVVTBL* BtrFsMount(ULONG DeviceId);
422