2 // lf_hfs_btrees_internal.h
5 // Created by Yakov Ben Zaken on 22/03/2018.
8 #ifndef lf_hfs_btrees_internal_h
9 #define lf_hfs_btrees_internal_h
11 #include "lf_hfs_file_mgr_internal.h"
14 fsBTInvalidHeaderErr
= btBadHdr
,
15 fsBTBadRotateErr
= dsBadRotate
,
16 fsBTInvalidNodeErr
= btBadNode
,
17 fsBTRecordTooLargeErr
= btNoFit
,
18 fsBTRecordNotFoundErr
= btNotFound
,
19 fsBTDuplicateRecordErr
= btExists
,
20 fsBTFullErr
= btNoSpaceAvail
,
22 fsBTInvalidFileErr
= ERR_BASE
+ 0x0302, /* no BTreeCB has been allocated for fork*/
23 fsBTrFileAlreadyOpenErr
= ERR_BASE
+ 0x0303,
24 fsBTInvalidIteratorErr
= ERR_BASE
+ 0x0308,
25 fsBTEmptyErr
= ERR_BASE
+ 0x030A,
26 fsBTNoMoreMapNodesErr
= ERR_BASE
+ 0x030B,
27 fsBTBadNodeSize
= ERR_BASE
+ 0x030C,
28 fsBTBadNodeType
= ERR_BASE
+ 0x030D,
29 fsBTInvalidKeyLengthErr
= ERR_BASE
+ 0x030E,
30 fsBTStartOfIterationErr
= ERR_BASE
+ 0x0353,
31 fsBTEndOfIterationErr
= ERR_BASE
+ 0x0354,
32 fsBTUnknownVersionErr
= ERR_BASE
+ 0x0355,
33 fsBTTreeTooDeepErr
= ERR_BASE
+ 0x0357,
34 fsIteratorExitedScopeErr
= ERR_BASE
+ 0x0A02, /* iterator exited the scope*/
35 fsIteratorScopeExceptionErr
= ERR_BASE
+ 0x0A03, /* iterator is undefined due to error or movement of scope locality*/
36 fsUnknownIteratorMovementErr
= ERR_BASE
+ 0x0A04, /* iterator movement is not defined*/
37 fsInvalidIterationMovmentErr
= ERR_BASE
+ 0x0A05, /* iterator movement is invalid in current context*/
38 fsClientIDMismatchErr
= ERR_BASE
+ 0x0A06, /* wrong client process ID*/
39 fsEndOfIterationErr
= ERR_BASE
+ 0x0A07, /* there were no objects left to return on iteration*/
40 fsBTTimeOutErr
= ERR_BASE
+ 0x0A08 /* BTree scan interrupted -- no time left for physical I/O */
46 daddr64_t blockNum
; /* logical block number (used by hfs_swap_BTNode) */
48 Boolean blockReadFromDisk
;
49 Byte isModified
; // XXXdbg - for journaling
52 } BlockDescriptor
, *BlockDescPtr
;
60 } FSBufferDescriptor
, *FSBufferDescriptorPtr
;
64 Fork Level Access Method Block get options
67 kGetBlock
= 0x00000000,
68 kGetBlockHint
= 0x00000001, // if set, the block is being looked up using hint
69 kForceReadBlock
= 0x00000002, // how does this relate to Read/Verify? Do we need this?
70 kGetEmptyBlock
= 0x00000008
72 typedef u_int32_t GetBlockOptions
;
75 Fork Level Access Method Block release options
78 kReleaseBlock
= 0x00000000,
79 kForceWriteBlock
= 0x00000001,
80 kMarkBlockDirty
= 0x00000002,
81 kTrashBlock
= 0x00000004,
82 kLockTransaction
= 0x00000100
84 typedef u_int32_t ReleaseBlockOptions
;
86 typedef u_int64_t FSSize
;
87 typedef u_int32_t ForkBlockNumber
;
89 /*============================================================================
90 Fork Level Buffered I/O Access Method
91 ============================================================================*/
93 typedef OSStatus (* GetBlockProcPtr
) (FileReference fileRefNum
,
95 GetBlockOptions options
,
96 BlockDescriptor
*block
);
99 typedef OSStatus (* ReleaseBlockProcPtr
) (FileReference fileRefNum
,
100 BlockDescPtr blockPtr
,
101 ReleaseBlockOptions options
);
103 typedef OSStatus (* SetEndOfForkProcPtr
) (FileReference fileRefNum
,
107 typedef OSStatus (* SetBlockSizeProcPtr
) (FileReference fileRefNum
,
109 ItemCount minBlockCount
);
111 OSStatus
SetEndOfForkProc ( FileReference fileRefNum
, FSSize minEOF
, FSSize maxEOF
);
115 B*Tree Information Version
117 enum BTreeInformationVersion
{
118 kBTreeInfoVersion
= 0
122 B*Tree Iteration Operation Constants
124 enum BTreeIterationOperations
{
131 typedef u_int16_t BTreeIterationOperation
;
135 Btree types: 0 is HFS CAT/EXT file, 1~127 are AppleShare B*Tree files, 128~254 unused
136 hfsBtreeType EQU 0 ; control file
137 validBTType EQU $80 ; user btree type starts from 128
138 userBT1Type EQU $FF ; 255 is our Btree type. Used by BTInit and BTPatch
141 kHFSBTreeType
= 0, // control file
142 kUserBTreeType
= 128, // user btree type starts from 128
143 kReservedBTreeType
= 255 //
146 #define kBTreeHeaderUserBytes 128
148 /* B-tree structures */
157 u_int8_t rawData
[kMaxKeyLength
+2];
159 } BTreeKey
, *BTreeKeyPtr
;
161 /* BTNodeDescriptor -- Every B-tree node starts with these fields. */
163 u_int32_t fLink
; /* next node at this level*/
164 u_int32_t bLink
; /* previous node at this level*/
165 int8_t kind
; /* kind of node (leaf, index, header, map)*/
166 u_int8_t height
; /* zero for header, map; child is one more than parent*/
167 u_int16_t numRecords
; /* number of records in this node*/
168 u_int16_t reserved
; /* reserved - initialized as zero */
170 } __attribute__((aligned(2), packed
)) BTNodeDescriptor
;
172 /* Constants for BTNodeDescriptor kind */
180 /* BTHeaderRec -- The first record of a B-tree header node */
182 u_int16_t treeDepth
; /* maximum height (usually leaf nodes) */
183 u_int32_t rootNode
; /* node number of root node */
184 u_int32_t leafRecords
; /* number of leaf records in all leaf nodes */
185 u_int32_t firstLeafNode
; /* node number of first leaf node */
186 u_int32_t lastLeafNode
; /* node number of last leaf node */
187 u_int16_t nodeSize
; /* size of a node, in bytes */
188 u_int16_t maxKeyLength
; /* reserved */
189 u_int32_t totalNodes
; /* total number of nodes in tree */
190 u_int32_t freeNodes
; /* number of unused (free) nodes in tree */
191 u_int16_t reserved1
; /* unused */
192 u_int32_t clumpSize
; /* reserved */
193 u_int8_t btreeType
; /* reserved */
194 u_int8_t keyCompareType
; /* Key string Comparison Type */
195 u_int32_t attributes
; /* persistent attributes about the tree */
196 u_int32_t reserved3
[16]; /* reserved */
198 } __attribute__((aligned(2), packed
)) BTHeaderRec
;
200 /* Constants for BTHeaderRec attributes */
202 kBTBadCloseMask
= 0x00000001, /* reserved */
203 kBTBigKeysMask
= 0x00000002, /* key length field is 16 bits */
204 kBTVariableIndexKeysMask
= 0x00000004 /* keys in index nodes are variable length */
208 BTreeInfoRec Structure - for BTGetInformation
213 u_int16_t maxKeyLength
;
215 u_int32_t lastfsync
; /* Last time that this was fsynced */
216 ItemCount numRecords
;
218 ItemCount numFreeNodes
;
219 u_int8_t keyCompareType
;
220 u_int8_t reserved
[3];
221 } BTreeInfoRec
, *BTreeInfoRecPtr
;
224 BTreeHint can never be exported to the outside. Use u_int32_t BTreeHint[4],
225 u_int8_t BTreeHint[16], etc.
228 ItemCount writeCount
;
229 u_int32_t nodeNum
; // node the key was last seen in
230 u_int16_t index
; // index then key was last seen at
233 } BTreeHint
, *BTreeHintPtr
;
242 u_int32_t hitCount
; // Total number of leaf records hit
243 u_int32_t maxLeafRecs
; // Max leaf records over iteration
245 } BTreeIterator
, *BTreeIteratorPtr
;
248 /*============================================================================
250 ============================================================================*/
253 Key Comparison Function ProcPtr Type - for BTOpenPath
255 //typedef int32_t (* KeyCompareProcPtr)(BTreeKeyPtr a, BTreeKeyPtr b);
258 typedef int32_t (* IterateCallBackProcPtr
)(BTreeKeyPtr key
, void * record
, void * state
);
260 OSStatus
BTOpenPath (FCB
*filePtr
, KeyCompareProcPtr keyCompareProc
);
262 OSStatus
BTClosePath (FCB
*filePtr
);
265 OSStatus
BTSearchRecord (FCB
*filePtr
,
266 BTreeIterator
*searchIterator
,
267 FSBufferDescriptor
*btRecord
,
268 u_int16_t
*recordLen
,
269 BTreeIterator
*resultIterator
);
271 OSStatus
BTIterateRecord (FCB
*filePtr
,
272 BTreeIterationOperation operation
,
273 BTreeIterator
*iterator
,
274 FSBufferDescriptor
*btRecord
,
275 u_int16_t
*recordLen
);
278 OSStatus
BTIterateRecords (FCB
*filePtr
,
279 BTreeIterationOperation operation
,
280 BTreeIterator
*iterator
,
281 IterateCallBackProcPtr callBackProc
,
282 void *callBackState
);
284 OSStatus
BTInsertRecord (FCB
*filePtr
,
285 BTreeIterator
*iterator
,
286 FSBufferDescriptor
*btrecord
,
287 u_int16_t recordLen
);
289 OSStatus
BTReplaceRecord (FCB
*filePtr
,
290 BTreeIterator
*iterator
,
291 FSBufferDescriptor
*btRecord
,
292 u_int16_t recordLen
);
294 OSStatus
BTUpdateRecord (FCB
*filePtr
,
295 BTreeIterator
*iterator
,
296 IterateCallBackProcPtr callBackProc
,
297 void *callBackState
);
299 OSStatus
BTDeleteRecord (FCB
*filePtr
,
300 BTreeIterator
*iterator
);
302 OSStatus
BTGetInformation (FCB
*filePtr
,
304 BTreeInfoRec
*info
);
306 OSStatus
BTIsDirty (FCB
*filePtr
);
308 OSStatus
BTFlushPath (FCB
*filePtr
);
310 OSStatus
BTReloadData (FCB
*filePtr
);
312 OSStatus
BTInvalidateHint (BTreeIterator
*iterator
);
314 OSStatus
BTGetLastSync (FCB
*filePtr
,
315 u_int32_t
*lastfsync
);
317 OSStatus
BTSetLastSync (FCB
*filePtr
,
318 u_int32_t lastfsync
);
320 OSStatus
BTHasContiguousNodes(FCB
*filePtr
);
322 OSStatus
BTGetUserData(FCB
*filePtr
, void * dataPtr
, int dataSize
);
324 OSStatus
BTSetUserData(FCB
*filePtr
, void * dataPtr
, int dataSize
);
326 /* B-tree node reserve routines. */
327 void BTReserveSetup(void);
329 int BTReserveSpace(FCB
*file
, int operations
, void * data
);
331 int BTReleaseReserve(FCB
*file
, void * data
);
333 int BTZeroUnusedNodes(FCB
*file
);
336 #endif /* lf_hfs_btrees_internal_h */