btrfs: [] on the end of a struct field is a variable length array.
[haiku.git] / src / add-ons / kernel / file_systems / btrfs / btrfs.h
blob3d0e7bfbc12090446bcca1a3920605f02f130dfe
1 /*
2 * Copyright 2017, Chế Vũ Gia Hy, cvghy116@gmail.com.
3 * Copyright 2011, Jérôme Duval, korli@users.berlios.de.
4 * Distributed under the terms of the MIT License.
5 */
6 #ifndef BTRFS_H
7 #define BTRFS_H
10 #include "system_dependencies.h"
13 typedef uint64 fileblock_t; // file block number
14 typedef uint64 fsblock_t; // filesystem block number
16 #define BTRFS_SUPER_BLOCK_OFFSET 0x10000
17 #define BTRFS_NUM_ROOT_BACKUPS 4
20 struct btrfs_backup_roots {
21 uint64 root;
22 uint64 root_generation;
23 uint64 chunk_root;
24 uint64 chunk_root_generation;
25 uint64 extent_root;
26 uint64 extent_root_generation;
27 uint64 fs_root;
28 uint64 fs_root_generation;
29 uint64 device_root;
30 uint64 device_root_generation;
31 uint64 csum_root;
32 uint64 csum_root_generation;
33 uint64 total_size;
34 uint64 used_size;
35 uint64 num_devices;
36 uint8 unused_1[32];
37 uint8 root_level;
38 uint8 chunk_root_level;
39 uint8 extent_root_level;
40 uint8 fs_root_level;
41 uint8 device_root_level;
42 uint8 csum_root_level;
43 uint8 unused_2[10];
45 uint64 Root() const { return B_LENDIAN_TO_HOST_INT64(root); }
46 uint64 RootGen() const
47 { return B_LENDIAN_TO_HOST_INT64(root_generation); }
48 uint64 ChunkRoot() const { return B_LENDIAN_TO_HOST_INT64(chunk_root); }
49 uint64 ChunkRootGen() const
50 { return B_LENDIAN_TO_HOST_INT64(chunk_root_generation); }
51 uint64 ExtentRoot() const { return B_LENDIAN_TO_HOST_INT64(extent_root); }
52 uint64 ExtentRootGen() const
53 { return B_LENDIAN_TO_HOST_INT64(extent_root_generation); }
54 uint64 FSRoot() const { return B_LENDIAN_TO_HOST_INT64(fs_root); }
55 uint64 FSRootGen() const
56 { return B_LENDIAN_TO_HOST_INT64(fs_root_generation); }
57 uint64 DeviceRoot() const { return B_LENDIAN_TO_HOST_INT64(device_root); }
58 uint64 DeviceRootGen() const
59 { return B_LENDIAN_TO_HOST_INT64(device_root_generation); }
60 uint64 CSumRoot() const { return B_LENDIAN_TO_HOST_INT64(csum_root); }
61 uint64 CSumRootGen() const
62 { return B_LENDIAN_TO_HOST_INT64(csum_root_generation); }
63 uint8 RootLevel() const { return root_level; }
64 uint8 ChunkRootLevel() const { return chunk_root_level; }
65 uint8 ExtentRootLevel() const { return extent_root_level; }
66 uint8 FSRootLevel() const { return fs_root_level; }
67 uint8 DeviceRootLevel() const { return device_root_level; }
68 uint8 CSumRootLevel() const { return csum_root_level; }
69 } _PACKED;
72 struct btrfs_key {
73 uint64 object_id;
74 uint8 type;
75 uint64 offset;
77 uint64 ObjectID() const { return B_LENDIAN_TO_HOST_INT64(object_id); }
78 uint8 Type() const { return type; }
79 uint64 Offset() const { return B_LENDIAN_TO_HOST_INT64(offset); }
80 void SetObjectID(uint64 id) { object_id = B_HOST_TO_LENDIAN_INT64(id); }
81 void SetType(uint8 key_type) { type = key_type; }
82 void SetOffset(uint64 off) { offset = B_HOST_TO_LENDIAN_INT64(off); }
83 int32 Compare(const btrfs_key& key) const;
84 //implemented in BTree.cpp
85 } _PACKED;
88 struct btrfs_timespec {
89 uint64 seconds;
90 uint32 nanoseconds;
91 } _PACKED;
94 struct btrfs_header {
95 uint8 checksum[32];
96 uint8 fsid[16];
97 uint64 logical_address;
98 uint64 flags;
99 uint8 chunk_tree_uuid[16];
100 uint64 generation;
101 uint64 owner;
102 uint32 item_count;
103 uint8 level;
104 uint64 LogicalAddress() const
105 { return B_LENDIAN_TO_HOST_INT64(logical_address); }
106 uint64 Flags() const { return B_LENDIAN_TO_HOST_INT64(flags); }
107 uint64 Generation() const
108 { return B_LENDIAN_TO_HOST_INT64(generation); }
109 uint64 Owner() const
110 { return B_LENDIAN_TO_HOST_INT64(owner); }
111 uint32 ItemCount() const
112 { return B_LENDIAN_TO_HOST_INT32(item_count); }
113 uint8 Level() const { return level; }
115 void SetLogicalAddress(uint64 logical)
116 { logical_address = B_HOST_TO_LENDIAN_INT64(logical); }
117 void SetGeneration(uint64 gen)
118 { generation = B_HOST_TO_LENDIAN_INT64(gen); }
119 void SetItemCount(uint32 itemCount)
120 { item_count = B_HOST_TO_LENDIAN_INT32(itemCount); }
121 } _PACKED;
124 struct btrfs_index {
125 btrfs_key key;
126 uint64 logical_address;
127 uint64 generation;
128 uint64 LogicalAddress() const
129 { return B_LENDIAN_TO_HOST_INT64(logical_address); }
130 uint64 Generation() const
131 { return B_LENDIAN_TO_HOST_INT64(generation); }
133 void SetLogicalAddress(uint64 address)
134 { logical_address = B_HOST_TO_LENDIAN_INT64(address); }
135 void SetGeneration(uint64 gen)
136 { generation = B_HOST_TO_LENDIAN_INT64(gen); }
137 } _PACKED;
140 struct btrfs_entry {
141 btrfs_key key;
142 uint32 offset;
143 uint32 size;
144 uint32 Offset() const
145 { return B_LENDIAN_TO_HOST_INT32(offset); }
146 uint32 Size() const
147 { return B_LENDIAN_TO_HOST_INT32(size); }
148 void SetOffset(uint32 off) { offset = B_HOST_TO_LENDIAN_INT32(off); }
149 void SetSize(uint32 itemSize) { size = B_HOST_TO_LENDIAN_INT32(itemSize); }
150 } _PACKED;
153 struct btrfs_stream {
154 btrfs_header header;
155 union {
156 btrfs_entry entries[0];
157 btrfs_index index[0];
159 } _PACKED;
162 struct btrfs_stripe {
163 uint64 device_id;
164 uint64 offset;
165 uint8 device_uuid[16];
166 uint64 DeviceID() const { return B_LENDIAN_TO_HOST_INT64(device_id); }
167 uint64 Offset() const { return B_LENDIAN_TO_HOST_INT64(offset); }
168 } _PACKED;
171 struct btrfs_chunk {
172 uint64 length;
173 uint64 owner;
174 uint64 stripe_length;
175 uint64 type;
176 uint32 io_align;
177 uint32 io_width;
178 uint32 sector_size;
179 uint16 stripe_count;
180 uint16 sub_stripes;
181 btrfs_stripe stripes[0];
182 uint64 Length() const { return B_LENDIAN_TO_HOST_INT64(length); }
183 uint64 Owner() const { return B_LENDIAN_TO_HOST_INT64(owner); }
184 uint64 StripeLength() const
185 { return B_LENDIAN_TO_HOST_INT64(stripe_length); }
186 uint64 Type() const { return B_LENDIAN_TO_HOST_INT64(type); }
187 uint32 IOAlign() const { return B_LENDIAN_TO_HOST_INT32(io_align); }
188 uint32 IOWidth() const { return B_LENDIAN_TO_HOST_INT32(io_width); }
189 uint32 SectorSize() const
190 { return B_LENDIAN_TO_HOST_INT32(sector_size); }
191 uint16 StripeCount() const
192 { return B_LENDIAN_TO_HOST_INT16(stripe_count); }
193 uint16 SubStripes() const
194 { return B_LENDIAN_TO_HOST_INT16(sub_stripes); }
195 } _PACKED;
198 struct btrfs_device {
199 uint64 id;
200 uint64 total_size;
201 uint64 used_size;
202 uint32 io_align;
203 uint32 io_width;
204 uint32 sector_size;
205 uint64 type;
206 uint64 generation;
207 uint64 start_offset;
208 uint32 group;
209 uint8 seek_speed;
210 uint8 bandwidth;
211 uint8 uuid[16];
212 uint8 fsid[16];
213 } _PACKED;
216 struct btrfs_super_block {
217 uint8 checksum[32];
218 uint8 fsid[16];
219 uint64 blocknum;
220 uint64 flags;
221 char magic[8];
222 uint64 generation;
223 uint64 root;
224 uint64 chunk_root;
225 uint64 log_root;
226 uint64 log_root_transaction_id;
227 uint64 total_size;
228 uint64 used_size;
229 uint64 root_dir_object_id;
230 uint64 num_devices;
231 uint32 sector_size;
232 uint32 node_size;
233 uint32 leaf_size;
234 uint32 stripe_size;
235 uint32 system_chunk_array_size;
236 uint64 chunk_root_generation;
237 uint64 compat_flags;
238 uint64 readonly_flags;
239 uint64 incompat_flags;
240 uint16 checksum_type;
241 uint8 root_level;
242 uint8 chunk_root_level;
243 uint8 log_root_level;
244 btrfs_device device;
245 char label[256];
246 uint64 reserved[32];
247 uint8 system_chunk_array[2048];
248 btrfs_backup_roots backup_roots[BTRFS_NUM_ROOT_BACKUPS];
250 bool IsValid();
251 // implemented in Volume.cpp
252 uint64 TotalSize() const { return B_LENDIAN_TO_HOST_INT64(total_size); }
253 uint32 BlockSize() const { return B_LENDIAN_TO_HOST_INT32(node_size); }
254 uint32 SectorSize() const { return B_LENDIAN_TO_HOST_INT32(sector_size); }
255 uint64 RootDirObjectID() const
256 { return B_LENDIAN_TO_HOST_INT64(root_dir_object_id); }
257 uint64 Generation() const
258 { return B_LENDIAN_TO_HOST_INT64(generation); }
259 uint64 Root() const
260 { return B_LENDIAN_TO_HOST_INT64(root); }
261 uint64 ChunkRoot() const
262 { return B_LENDIAN_TO_HOST_INT64(chunk_root); }
263 uint64 LogRoot() const
264 { return B_LENDIAN_TO_HOST_INT64(log_root); }
265 uint8 ChunkRootLevel() const { return chunk_root_level; }
266 } _PACKED;
269 struct btrfs_inode {
270 uint64 generation;
271 uint64 transaction_id;
272 uint64 size;
273 uint64 nbytes;
274 uint64 blockgroup;
275 uint32 num_links;
276 uint32 uid;
277 uint32 gid;
278 uint32 mode;
279 uint64 rdev;
280 uint64 flags;
281 uint64 sequence;
282 uint64 reserved[4];
283 btrfs_timespec access_time;
284 btrfs_timespec change_time;
285 btrfs_timespec modification_time;
286 btrfs_timespec creation_time;
287 uint64 Generation() const { return B_LENDIAN_TO_HOST_INT64(generation); }
288 uint64 Size() const { return B_LENDIAN_TO_HOST_INT64(size); }
289 uint32 UserID() const { return B_LENDIAN_TO_HOST_INT32(uid); }
290 uint32 GroupID() const { return B_LENDIAN_TO_HOST_INT32(gid); }
291 uint32 Mode() const { return B_LENDIAN_TO_HOST_INT32(mode); }
292 uint64 Flags() const { return B_LENDIAN_TO_HOST_INT64(flags); }
293 uint64 Sequence() const { return B_LENDIAN_TO_HOST_INT64(sequence); }
294 static void _DecodeTime(struct timespec& timespec,
295 const btrfs_timespec& time)
297 timespec.tv_sec = B_LENDIAN_TO_HOST_INT64(time.seconds);
298 timespec.tv_nsec = B_LENDIAN_TO_HOST_INT32(time.nanoseconds);
300 void GetAccessTime(struct timespec& timespec) const
301 { _DecodeTime(timespec, access_time); }
302 void GetChangeTime(struct timespec& timespec) const
303 { _DecodeTime(timespec, change_time); }
304 void GetModificationTime(struct timespec& timespec) const
305 { _DecodeTime(timespec, modification_time); }
306 void GetCreationTime(struct timespec& timespec) const
307 { _DecodeTime(timespec, creation_time); }
308 static void SetTime(btrfs_timespec& time, const struct timespec& timespec)
310 time.seconds = B_HOST_TO_LENDIAN_INT64(timespec.tv_sec);
311 time.nanoseconds = B_HOST_TO_LENDIAN_INT64(timespec.tv_nsec);
313 } _PACKED;
316 struct btrfs_inode_ref {
317 uint64 index;
318 uint16 name_length;
319 uint8 name[];
321 uint64 Index() const { return index; }
322 uint16 NameLength() const { return B_LENDIAN_TO_HOST_INT16(name_length); }
323 uint16 Length() const
324 { return sizeof(btrfs_inode_ref) + NameLength(); }
325 void SetName(const char* name, uint16 nameLength)
327 name_length = B_HOST_TO_LENDIAN_INT16(nameLength);
328 memcpy(this->name, name, nameLength);
330 } _PACKED;
333 struct btrfs_root {
334 btrfs_inode inode;
335 uint64 generation;
336 uint64 root_dirid;
337 uint64 logical_address;
338 uint64 limit_bytes;
339 uint64 used_bytes;
340 uint64 last_snapshot;
341 uint64 flags;
342 uint32 refs;
343 btrfs_key drop_progress;
344 uint8 drop_level;
345 uint8 level;
346 uint64 Generation() const
347 { return B_LENDIAN_TO_HOST_INT64(generation); }
348 uint64 LogicalAddress() const
349 { return B_LENDIAN_TO_HOST_INT64(logical_address); }
350 } _PACKED;
353 struct btrfs_dir_entry {
354 btrfs_key location;
355 uint64 transaction_id;
356 uint16 data_length;
357 uint16 name_length;
358 uint8 type;
359 uint8* name;
360 uint8* data; // attribute data
361 uint16 DataLength() const { return B_LENDIAN_TO_HOST_INT16(data_length); }
362 uint16 NameLength() const { return B_LENDIAN_TO_HOST_INT16(name_length); }
363 ino_t InodeID() const { return location.ObjectID(); }
364 uint16 Length() const
365 { return sizeof(*this) + NameLength() + DataLength(); }
366 void SetTransactionID(uint64 id)
367 { transaction_id = B_HOST_TO_LENDIAN_INT64(id); }
368 void SetAttributeData(void* data, uint16 dataLength)
370 data_length = B_HOST_TO_LENDIAN_INT16(dataLength);
371 if (data != NULL)
372 memcpy(this->data, data, dataLength);
374 void SetName(const char* name, uint16 nameLength)
376 name_length = B_HOST_TO_LENDIAN_INT16(nameLength);
377 memcpy(this->name, name, nameLength);
379 } _PACKED;
382 struct btrfs_extent_data {
383 uint64 generation;
384 uint64 memory_size;
385 uint8 compression;
386 uint8 encryption;
387 uint16 reserved;
388 uint8 type;
389 union {
390 struct {
391 uint64 disk_offset;
392 uint64 disk_size;
393 uint64 extent_offset;
394 uint64 size;
396 uint8 inline_data[0];
398 uint64 Generation() const
399 { return B_LENDIAN_TO_HOST_INT64(generation); }
400 uint64 MemoryBytes() const
401 { return B_LENDIAN_TO_HOST_INT64(memory_size); }
402 uint8 Compression() const { return compression; }
403 uint8 Type() const { return type; }
404 uint64 DiskOffset() const
405 { return B_LENDIAN_TO_HOST_INT64(disk_offset); }
406 uint64 DiskSize() const
407 { return B_LENDIAN_TO_HOST_INT64(disk_size); }
408 uint64 ExtentOffset() const
409 { return B_LENDIAN_TO_HOST_INT64(extent_offset); }
410 uint64 Size() const
411 { return B_LENDIAN_TO_HOST_INT64(size); }
412 } _PACKED;
415 struct btrfs_block_group {
416 uint64 used_space;
417 uint64 chunk_object_id;
418 uint64 flags;
420 uint64 UsedSpace() const { return B_LENDIAN_TO_HOST_INT64(used_space); }
421 uint64 ChunkObjectID() const
422 { return B_HOST_TO_LENDIAN_INT64(chunk_object_id); }
423 uint64 Flags() const { return B_LENDIAN_TO_HOST_INT64(flags); }
424 } _PACKED;
427 struct btrfs_extent {
428 uint64 refs;
429 uint64 generation;
430 uint64 flags;
432 uint64 RefCount() const { return B_LENDIAN_TO_HOST_INT64(refs); }
433 uint64 Generation() const { return B_LENDIAN_TO_HOST_INT64(generation); }
434 uint64 Flags() const { return B_LENDIAN_TO_HOST_INT64(flags); }
435 } _PACKED;
438 struct btrfs_extent_inline_ref {
439 uint8 type;
440 uint64 offset;
442 uint8 Type() const { return type; }
443 uint64 Offset() const { return B_LENDIAN_TO_HOST_INT64(offset); }
444 } _PACKED;
447 struct btrfs_extent_data_ref {
448 uint64 root_id;
449 uint64 inode_id;
450 uint64 offset;
451 uint32 ref_count;
453 uint64 RootID() const { return B_LENDIAN_TO_HOST_INT64(root_id); }
454 uint64 InodeID() const { return B_LENDIAN_TO_HOST_INT64(inode_id); }
455 uint64 Offset() const { return B_LENDIAN_TO_HOST_INT64(offset);}
456 uint32 RefCount() const { return B_LENDIAN_TO_HOST_INT32(ref_count); }
457 } _PACKED;
460 #define BTRFS_SUPER_BLOCK_MAGIC "_BHRfS_M"
461 #define BTRFS_FIRST_SUBVOLUME 256
463 #define BTRFS_OBJECT_ID_ROOT_TREE 1
464 #define BTRFS_OBJECT_ID_EXTENT_TREE 2
465 #define BTRFS_OBJECT_ID_CHUNK_TREE 3
466 #define BTRFS_OBJECT_ID_DEV_TREE 4
467 #define BTRFS_OBJECT_ID_FS_TREE 5
468 #define BTRFS_OBJECT_ID_ROOT_TREE_DIR 6
469 #define BTRFS_OBJECT_ID_CHECKSUM_TREE 7
470 #define BTRFS_OBJECT_ID_FIRST_CHUNK_TREE 256
472 #define BTRFS_KEY_TYPE_ANY 0
473 #define BTRFS_KEY_TYPE_INODE_ITEM 1
474 #define BTRFS_KEY_TYPE_INODE_REF 12
475 #define BTRFS_KEY_TYPE_XATTR_ITEM 24
476 #define BTRFS_KEY_TYPE_DIR_ITEM 84
477 #define BTRFS_KEY_TYPE_DIR_INDEX 96
478 #define BTRFS_KEY_TYPE_EXTENT_DATA 108
479 #define BTRFS_KEY_TYPE_ROOT_ITEM 132
480 #define BTRFS_KEY_TYPE_EXTENT_ITEM 168
481 #define BTRFS_KEY_TYPE_METADATA_ITEM 169
482 #define BTRFS_KEY_TYPE_EXTENT_DATA_REF 178
483 #define BTRFS_KEY_TYPE_BLOCKGROUP_ITEM 192
484 #define BTRFS_KEY_TYPE_CHUNK_ITEM 228
486 #define BTRFS_EXTENT_COMPRESS_NONE 0
487 #define BTRFS_EXTENT_COMPRESS_ZLIB 1
488 #define BTRFS_EXTENT_COMPRESS_LZO 2
489 #define BTRFS_EXTENT_DATA_INLINE 0
490 #define BTRFS_EXTENT_DATA_REGULAR 1
491 #define BTRFS_EXTENT_DATA_PRE 2
492 #define BTRFS_EXTENT_FLAG_DATA 1
493 #define BTRFS_EXTENT_FLAG_TREE_BLOCK 2
494 #define BTRFS_EXTENT_FLAG_ALLOCATED 4
496 #define BTRFS_BLOCKGROUP_FLAG_DATA 1
497 #define BTRFS_BLOCKGROUP_FLAG_SYSTEM 2
498 #define BTRFS_BLOCKGROUP_FLAG_METADATA 4
499 #define BTRFS_BLOCKGROUP_FLAG_RAID0 8
500 #define BTRFS_BLOCKGROUP_FLAG_RAID1 16
501 #define BTRFS_BLOCKGROUP_FLAG_DUP 32
502 #define BTRFS_BLOCKGROUP_FLAG_RAID10 64
503 #define BTRFS_BLOCKGROUP_FLAG_RAID5 128
504 #define BTRFS_BLOCKGROUP_FLAG_RAID6 256
505 #define BTRFS_BLOCKGROUP_FLAG_MASK 511
507 // d_type in struct dirent
508 #define BTRFS_FILETYPE_UNKNOWN 0
509 #define BTRFS_FILETYPE_REGULAR 1
510 #define BTRFS_FILETYPE_DIRECTORY 2
511 #define BTRFS_FILETYPE_CHRDEV 3 // character device
512 #define BTRFS_FILETYPE_BLKDEV 4 // block device
513 #define BTRFS_FILETYPE_FIFO 5 // fifo device
514 #define BTRFS_FILETYPE_SOCKET 6
515 #define BTRFS_FILETYPE_SYMLINK 7
516 #define BTRFS_FILETYPE_XATTR 8 // ondisk but not user-visible
519 struct file_cookie {
520 bigtime_t last_notification;
521 off_t last_size;
522 int open_mode;
526 #define BTRFS_OPEN_MODE_USER_MASK 0x7fffffff
528 extern fs_volume_ops gBtrfsVolumeOps;
529 extern fs_vnode_ops gBtrfsVnodeOps;
532 #endif // BTRFS_H