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 16 typedef uint64 fileblock_t; // file block number 17 typedef uint64 fsblock_t; // filesystem block number 18 19 20 #define BTRFS_SUPER_BLOCK_OFFSET 0x10000 21 22 struct 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 35 struct btrfs_timespec { 36 uint64 seconds; 37 uint32 nanoseconds; 38 } _PACKED; 39 40 struct 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 61 struct 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 70 struct 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 80 struct btrfs_stream { 81 btrfs_header header; 82 union { 83 btrfs_entry entries[0]; 84 btrfs_index index[0]; 85 }; 86 } _PACKED; 87 88 struct 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 96 struct 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 122 struct 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 140 struct 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 190 struct 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 231 struct 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 249 struct 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 262 struct 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 323 struct 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 331 extern fs_volume_ops gBtrfsVolumeOps; 332 extern fs_vnode_ops gBtrfsVnodeOps; 333 334 #endif // BTRFS_H 335