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 ×pec, 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 ×pec) const 222 { _DecodeTime(timespec, access_time); } 223 void GetChangeTime(struct timespec ×pec) const 224 { _DecodeTime(timespec, change_time); } 225 void GetModificationTime(struct timespec ×pec) const 226 { _DecodeTime(timespec, modification_time); } 227 void GetCreationTime(struct timespec ×pec) 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