1 /* bfs - BFS definitions and helper functions 2 * 3 * Initial version by Axel Dörfler, axeld@pinc-software.de 4 * Parts of this code is based on work previously done by Marcus Overhagen 5 * 6 * Copyright 2001-2008 pinc Software. All Rights Reserved. 7 * This file may be used under the terms of the MIT License. 8 */ 9 #ifndef BFS_H 10 #define BFS_H 11 12 13 #include <SupportDefs.h> 14 15 #if !defined(BEOS_VERSION_DANO) && !defined(__HAIKU__) 16 # define B_BAD_DATA B_ERROR 17 #endif 18 19 20 struct __attribute__((packed)) block_run { 21 int32 allocation_group; 22 uint16 start; 23 uint16 length; 24 25 inline bool operator==(const block_run &run) const; 26 inline bool operator!=(const block_run &run) const; 27 inline bool IsZero() const; 28 inline void SetTo(int32 group, uint16 start, uint16 length = 1); 29 30 inline static block_run Run(int32 group, uint16 start, uint16 length = 1); 31 }; 32 33 typedef block_run inode_addr; 34 35 //************************************** 36 37 38 #define BFS_DISK_NAME_LENGTH 32 39 40 struct __attribute__((packed)) disk_super_block 41 { 42 char name[BFS_DISK_NAME_LENGTH]; 43 int32 magic1; 44 int32 fs_byte_order; 45 uint32 block_size; 46 uint32 block_shift; 47 int64 num_blocks; 48 int64 used_blocks; 49 int32 inode_size; 50 int32 magic2; 51 int32 blocks_per_ag; 52 int32 ag_shift; 53 int32 num_ags; 54 int32 flags; 55 block_run log_blocks; 56 int64 log_start; 57 int64 log_end; 58 int32 magic3; 59 inode_addr root_dir; 60 inode_addr indices; 61 int32 pad[8]; 62 }; 63 64 #define SUPER_BLOCK_FS_LENDIAN 'BIGE' /* BIGE */ 65 66 #define SUPER_BLOCK_MAGIC1 'BFS1' /* BFS1 */ 67 #define SUPER_BLOCK_MAGIC2 0xdd121031 68 #define SUPER_BLOCK_MAGIC3 0x15b6830e 69 70 #define SUPER_BLOCK_CLEAN 'CLEN' /* CLEN */ 71 #define SUPER_BLOCK_DIRTY 'DIRT' /* DIRT */ 72 73 //************************************** 74 75 #define NUM_DIRECT_BLOCKS 12 76 77 struct __attribute__((packed)) data_stream 78 { 79 block_run direct[NUM_DIRECT_BLOCKS]; 80 int64 max_direct_range; 81 block_run indirect; 82 int64 max_indirect_range; 83 block_run double_indirect; 84 int64 max_double_indirect_range; 85 int64 size; 86 }; 87 88 // ************************************** 89 90 struct bfs_inode; 91 92 struct __attribute__((packed)) small_data 93 { 94 uint32 type; 95 uint16 name_size; 96 uint16 data_size; 97 char name[0]; // name_size long, followed by data 98 99 inline char *Name(); 100 inline uint8 *Data(); 101 inline small_data *Next(); 102 inline bool IsLast(bfs_inode *inode); 103 }; 104 105 // the file name is part of the small_data structure 106 #define FILE_NAME_TYPE 'CSTR' 107 #define FILE_NAME_NAME 0x13 108 #define FILE_NAME_NAME_LENGTH 1 109 110 // ************************************** 111 112 #define SHORT_SYMLINK_NAME_LENGTH 144 // length incl. terminating '\0' 113 114 struct __attribute__((packed)) bfs_inode 115 { 116 int32 magic1; 117 inode_addr inode_num; 118 int32 uid; 119 int32 gid; 120 int32 mode; // see sys/stat.h 121 int32 flags; 122 int64 create_time; 123 int64 last_modified_time; 124 inode_addr parent; 125 inode_addr attributes; 126 uint32 type; // attribute type 127 128 int32 inode_size; 129 uint32 etc; // for in-memory structures (unused in Haiku' fs) 130 131 union __attribute__((packed)) { 132 data_stream data; 133 char short_symlink[SHORT_SYMLINK_NAME_LENGTH]; 134 }; 135 int32 pad[4]; 136 small_data small_data_start[0]; 137 }; 138 139 #define INODE_MAGIC1 0x3bbe0ad9 140 #define INODE_TIME_SHIFT 16 141 #define INODE_FILE_NAME_LENGTH 256 142 143 enum inode_flags 144 { 145 INODE_IN_USE = 0x00000001, // always set 146 INODE_ATTR_INODE = 0x00000004, 147 INODE_LOGGED = 0x00000008, // log changes to the data stream 148 INODE_DELETED = 0x00000010, 149 INODE_EMPTY = 0x00000020, 150 INODE_LONG_SYMLINK = 0x00000040, // symlink in data stream 151 152 INODE_PERMANENT_FLAGS = 0x0000ffff, 153 154 INODE_NO_CACHE = 0x00010000, 155 INODE_WAS_WRITTEN = 0x00020000, 156 INODE_NO_TRANSACTION = 0x00040000 157 }; 158 159 //************************************** 160 161 162 inline int32 163 divide_roundup(int32 num,int32 divisor) 164 { 165 return (num + divisor - 1) / divisor; 166 } 167 168 inline int64 169 divide_roundup(int64 num,int32 divisor) 170 { 171 return (num + divisor - 1) / divisor; 172 } 173 174 inline int 175 get_shift(uint64 i) 176 { 177 int c; 178 c = 0; 179 while (i > 1) { 180 i >>= 1; 181 c++; 182 } 183 return c; 184 } 185 186 inline int32 187 round_up(uint32 data) 188 { 189 // rounds up to the next off_t boundary 190 return (data + sizeof(off_t) - 1) & ~(sizeof(off_t) - 1); 191 } 192 193 /************************ block_run inline functions ************************/ 194 // #pragma mark - 195 196 197 inline bool block_run::operator==(const block_run &run) const 198 { 199 return allocation_group == run.allocation_group 200 && start == run.start 201 && length == run.length; 202 } 203 204 inline bool block_run::operator!=(const block_run &run) const 205 { 206 return allocation_group != run.allocation_group 207 || start != run.start 208 || length != run.length; 209 } 210 211 inline bool block_run::IsZero() const 212 { 213 return allocation_group == 0 && start == 0 && length == 0; 214 } 215 216 inline void block_run::SetTo(int32 _group,uint16 _start,uint16 _length) 217 { 218 allocation_group = _group; 219 start = _start; 220 length = _length; 221 } 222 223 inline block_run block_run::Run(int32 group, uint16 start, uint16 length) 224 { 225 block_run run; 226 run.allocation_group = group; 227 run.start = start; 228 run.length = length; 229 return run; 230 } 231 232 233 /************************ small_data inline functions ************************/ 234 // #pragma mark - 235 236 237 inline char *small_data::Name() 238 { 239 return name; 240 } 241 242 inline uint8 *small_data::Data() 243 { 244 return (uint8 *)name + name_size + 3; 245 } 246 247 inline small_data *small_data::Next() 248 { 249 return (small_data *)((uint8 *)(this + 1) + name_size + 3 + data_size + 1); 250 } 251 252 inline bool small_data::IsLast(bfs_inode *inode) 253 { 254 return (addr_t)this > (addr_t)inode + inode->inode_size - sizeof(small_data) 255 || name_size == 0; 256 } 257 258 #endif /* BFS_H */ 259