1/*
2 * Copyright 2011, J��r��me Duval, korli@users.berlios.de.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef BTRFS_H
6#define BTRFS_H
7
8
9#include <sys/stat.h>
10
11#include <ByteOrder.h>
12#include <fs_interface.h>
13#include <KernelExport.h>
14
15
16typedef uint64 fileblock_t;		// file block number
17typedef uint64 fsblock_t;		// filesystem block number
18
19
20#define BTRFS_SUPER_BLOCK_OFFSET	0x10000
21
22struct btrfs_key {
23	uint64	object_id;
24	uint8	type;
25	uint64	offset;
26
27	uint64	ObjectID() const { return B_LENDIAN_TO_HOST_INT64(object_id); }
28	uint8	Type() const { return type; }
29	uint64	Offset() const { return B_LENDIAN_TO_HOST_INT64(offset); }
30	void SetObjectID(uint64 id) { object_id = B_HOST_TO_LENDIAN_INT64(id); }
31	void SetType(uint8 key_type) { type = key_type; }
32	void SetOffset(uint64 off) { offset = B_HOST_TO_LENDIAN_INT64(off); }
33} _PACKED;
34
35struct btrfs_timespec {
36	uint64	seconds;
37	uint32	nanoseconds;
38} _PACKED;
39
40struct btrfs_header {
41	uint8	checksum[32];
42	uint8	fsid[16];
43	uint64	blocknum;
44	uint64	flags;
45	uint8	chunk_tree_uuid[16];
46	uint64	generation;
47	uint64	owner;
48	uint32	item_count;
49	uint8	level;
50	uint64 BlockNum() const { return B_LENDIAN_TO_HOST_INT64(blocknum); }
51	uint64 Flags() const { return B_LENDIAN_TO_HOST_INT64(flags); }
52	uint64 Generation() const {
53		return B_LENDIAN_TO_HOST_INT64(generation); }
54	uint64 Owner() const {
55		return B_LENDIAN_TO_HOST_INT64(owner); }
56	uint32 ItemCount() const {
57		return B_LENDIAN_TO_HOST_INT32(item_count); }
58	uint8 Level() const { return level; }
59} _PACKED;
60
61struct btrfs_index {
62	btrfs_key key;
63	uint64	blocknum;
64	uint64	generation;
65	uint64 BlockNum() const { return B_LENDIAN_TO_HOST_INT64(blocknum); }
66	uint64 Generation() const {
67		return B_LENDIAN_TO_HOST_INT64(generation); }
68} _PACKED;
69
70struct btrfs_entry {
71	btrfs_key key;
72	uint32 offset;
73	uint32 size;
74	uint32 Offset() const {
75		return B_LENDIAN_TO_HOST_INT32(offset); }
76	uint32 Size() const {
77		return B_LENDIAN_TO_HOST_INT32(size); }
78} _PACKED;
79
80struct btrfs_stream {
81	btrfs_header header;
82	union {
83		btrfs_entry entries[0];
84		btrfs_index index[0];
85	};
86} _PACKED;
87
88struct btrfs_stripe {
89	uint64	device_id;
90	uint64	offset;
91	uint8	device_uuid[16];
92	uint64	DeviceID() const { return B_LENDIAN_TO_HOST_INT64(device_id); }
93	uint64	Offset() const { return B_LENDIAN_TO_HOST_INT64(offset); }
94} _PACKED;
95
96struct btrfs_chunk {
97	uint64	length;
98	uint64	owner;
99	uint64	stripe_length;
100	uint64	type;
101	uint32	io_align;
102	uint32	io_width;
103	uint32	sector_size;
104	uint16	stripe_count;
105	uint16	sub_stripes;
106	struct btrfs_stripe stripes[0];
107	uint64 Length() const { return B_LENDIAN_TO_HOST_INT64(length); }
108	uint64 Owner() const { return B_LENDIAN_TO_HOST_INT64(owner); }
109	uint64 StripeLength() const
110		{ return B_LENDIAN_TO_HOST_INT64(stripe_length); }
111	uint64 Type() const { return B_LENDIAN_TO_HOST_INT64(type); }
112	uint32 IOAlign() const { return B_LENDIAN_TO_HOST_INT32(io_align); }
113	uint32 IOWidth() const { return B_LENDIAN_TO_HOST_INT32(io_width); }
114	uint32 SectorSize() const
115		{ return B_LENDIAN_TO_HOST_INT32(sector_size); }
116	uint16 StripeCount() const
117		{ return B_LENDIAN_TO_HOST_INT16(stripe_count); }
118	uint16 SubStripes() const
119		{ return B_LENDIAN_TO_HOST_INT16(sub_stripes); }
120} _PACKED;
121
122struct btrfs_device {
123	uint64	id;
124	uint64	total_size;
125	uint64	used_size;
126	uint32	io_align;
127	uint32	io_width;
128	uint32	sector_size;
129	uint64	type;
130	uint64	generation;
131	uint64	start_offset;
132	uint32	group;
133	uint8	seek_speed;
134	uint8	bandwidth;
135	uint8	uuid[16];
136	uint8	fsid[16];
137} _PACKED;
138
139
140struct btrfs_super_block {
141	uint8	checksum[32];
142	uint8	fsid[16];
143	uint64	blocknum;
144	uint64	flags;
145	char	magic[8];
146	uint64	generation;
147	uint64	root;
148	uint64	chunk_root;
149	uint64	log_root;
150	uint64	log_root_transaction_id;
151	uint64	total_size;
152	uint64	used_size;
153	uint64	root_dir_object_id;
154	uint64	num_devices;
155	uint32	sector_size;
156	uint32	node_size;
157	uint32	leaf_size;
158	uint32	stripe_size;
159	uint32	system_chunk_array_size;
160	uint64	chunk_root_generation;
161	uint64	compat_flags;
162	uint64	readonly_flags;
163	uint64	incompat_flags;
164	uint16	checksum_type;
165	uint8	root_level;
166	uint8	chunk_root_level;
167	uint8	log_root_level;
168	struct btrfs_device device;
169	char	label[256];
170	uint64	reserved[32];
171	uint8	system_chunk_array[2048];
172
173	bool IsValid();
174		// implemented in Volume.cpp
175	uint64 TotalSize() const { return B_LENDIAN_TO_HOST_INT64(total_size); }
176	uint32 BlockSize() const { return B_LENDIAN_TO_HOST_INT32(sector_size); }
177	uint64 RootDirObjectID() const {
178		return B_LENDIAN_TO_HOST_INT64(root_dir_object_id); }
179	uint64 Generation() const {
180		return B_LENDIAN_TO_HOST_INT64(generation); }
181	uint64 Root() const {
182		return B_LENDIAN_TO_HOST_INT64(root); }
183	uint64 ChunkRoot() const {
184		return B_LENDIAN_TO_HOST_INT64(chunk_root); }
185	uint64 LogRoot() const {
186		return B_LENDIAN_TO_HOST_INT64(log_root); }
187	uint8 ChunkRootLevel() const { return chunk_root_level; }
188} _PACKED;
189
190struct btrfs_inode {
191	uint64	generation;
192	uint64	transaction_id;
193	uint64	size;
194	uint64	nbytes;
195	uint64	blockgroup;
196	uint32	num_links;
197	uint32	uid;
198	uint32	gid;
199	uint32	mode;
200	uint64	rdev;
201	uint64	flags;
202	uint64	sequence;
203	uint64	reserved[4];
204	struct btrfs_timespec access_time;
205	struct btrfs_timespec change_time;
206	struct btrfs_timespec modification_time;
207	struct btrfs_timespec creation_time;
208	uint64 Generation() const { return B_LENDIAN_TO_HOST_INT64(generation); }
209	uint64 Size() const { return B_LENDIAN_TO_HOST_INT64(size); }
210	uint32 UserID() const { return B_LENDIAN_TO_HOST_INT32(uid); }
211	uint32 GroupID() const { return B_LENDIAN_TO_HOST_INT32(gid); }
212	uint32 Mode() const { return B_LENDIAN_TO_HOST_INT32(mode); }
213	uint64 Flags() const { return B_LENDIAN_TO_HOST_INT64(flags); }
214	uint64 Sequence() const { return B_LENDIAN_TO_HOST_INT64(sequence); }
215	static void _DecodeTime(struct timespec &timespec,
216		const struct btrfs_timespec &time)
217	{
218		timespec.tv_sec = B_LENDIAN_TO_HOST_INT64(time.seconds);
219		timespec.tv_nsec = B_LENDIAN_TO_HOST_INT32(time.nanoseconds);
220	}
221	void GetAccessTime(struct timespec &timespec) const
222		{ _DecodeTime(timespec, access_time); }
223	void GetChangeTime(struct timespec &timespec) const
224		{ _DecodeTime(timespec, change_time); }
225	void GetModificationTime(struct timespec &timespec) const
226		{ _DecodeTime(timespec, modification_time); }
227	void GetCreationTime(struct timespec &timespec) const
228		{ _DecodeTime(timespec, creation_time); }
229} _PACKED;
230
231struct btrfs_root {
232	btrfs_inode inode;
233	uint64	generation;
234	uint64	root_dirid;
235	uint64	blocknum;
236	uint64	limit_bytes;
237	uint64	used_bytes;
238	uint64	last_snapshot;
239	uint64	flags;
240	uint32	refs;
241	btrfs_key drop_progress;
242	uint8	drop_level;
243	uint8	level;
244	uint64 Generation() const {
245		return B_LENDIAN_TO_HOST_INT64(generation); }
246	uint64 BlockNum() const { return B_LENDIAN_TO_HOST_INT64(blocknum); }
247} _PACKED;
248
249struct btrfs_dir_entry {
250	btrfs_key location;
251	uint64	transaction_id;
252	uint16	data_length;
253	uint16	name_length;
254	uint8	type;
255	uint16 DataLength() const { return B_LENDIAN_TO_HOST_INT16(data_length); }
256	uint16 NameLength() const { return B_LENDIAN_TO_HOST_INT16(name_length); }
257	ino_t InodeID() const { return location.ObjectID(); }
258	uint16 Length() const
259		{ return sizeof(*this) + NameLength() + DataLength(); }
260} _PACKED;
261
262struct btrfs_extent_data {
263	uint64	generation;
264	uint64	memory_size;
265	uint8	compression;
266	uint8	encryption;
267	uint16	reserved;
268	uint8	type;
269	union {
270		struct {
271			uint64	disk_offset;
272			uint64	disk_size;
273			uint64	extent_offset;
274			uint64	size;
275		};
276		uint8 inline_data[0];
277	};
278	uint64 Generation() const {
279		return B_LENDIAN_TO_HOST_INT64(generation); }
280	uint64 MemoryBytes() const {
281		return B_LENDIAN_TO_HOST_INT64(memory_size); }
282	uint8 Compression() const { return compression; }
283	uint8 Type() const { return type; }
284	uint64 DiskOffset() const {
285		return B_LENDIAN_TO_HOST_INT64(disk_offset); }
286	uint64 DiskSize() const {
287		return B_LENDIAN_TO_HOST_INT64(disk_size); }
288	uint64 ExtentOffset() const {
289		return B_LENDIAN_TO_HOST_INT64(extent_offset); }
290	uint64 Size() const {
291		return B_LENDIAN_TO_HOST_INT64(size); }
292} _PACKED;
293
294
295#define BTRFS_SUPER_BLOCK_MAGIC			"_BHRfS_M"
296
297#define BTRFS_OBJECT_ID_ROOT_TREE		1
298#define BTRFS_OBJECT_ID_EXTENT_TREE		2
299#define BTRFS_OBJECT_ID_DEV_TREE		4
300#define BTRFS_OBJECT_ID_FS_TREE			5
301#define BTRFS_OBJECT_ID_ROOT_TREE_DIR	6
302#define BTRFS_OBJECT_ID_CHECKSUM_TREE	7
303#define BTRFS_OBJECT_ID_CHUNK_TREE		256
304
305#define BTRFS_KEY_TYPE_CHUNK_ITEM		228
306#define BTRFS_KEY_TYPE_DIR_ITEM			84
307#define BTRFS_KEY_TYPE_DIR_INDEX		96
308#define BTRFS_KEY_TYPE_EXTENT_DATA		108
309#define BTRFS_KEY_TYPE_INODE_ITEM		1
310#define BTRFS_KEY_TYPE_INODE_REF		12
311#define BTRFS_KEY_TYPE_ROOT_ITEM		132
312#define BTRFS_KEY_TYPE_XATTR_ITEM		24
313
314#define BTRFS_EXTENT_COMPRESS_NONE		0
315#define BTRFS_EXTENT_COMPRESS_ZLIB		1
316#define BTRFS_EXTENT_COMPRESS_LZO		2
317
318#define BTRFS_EXTENT_DATA_INLINE		0
319#define BTRFS_EXTENT_DATA_REGULAR		1
320#define BTRFS_EXTENT_DATA_PRE			2
321
322
323struct file_cookie {
324	bigtime_t	last_notification;
325	off_t		last_size;
326	int			open_mode;
327};
328
329#define BTRFS_OPEN_MODE_USER_MASK		0x7fffffff
330
331extern fs_volume_ops gBtrfsVolumeOps;
332extern fs_vnode_ops gBtrfsVnodeOps;
333
334#endif	// BTRFS_H
335