2 * linux/fs/hfs/hfs_btree.h
4 * Copyright (C) 1995-1997 Paul H. Hargrove
5 * This file may be distributed under the terms of the GNU Public License.
7 * This file contains the declarations of the private B-tree
8 * structures and functions.
10 * "XXX" in a comment is a note to myself to consider changing something.
18 /*================ Variable-like macros ================*/
20 /* The stickiness of a (struct hfs_bnode) */
21 #define HFS_NOT_STICKY 0
24 /* The number of hash buckets in a B-tree's bnode cache */
25 #define HFS_CACHELEN 17 /* primes are best? */
28 * Legal values for the 'ndType' field of a (struct NodeDescriptor)
30 * Reference: _Inside Macintosh: Files_ p. 2-65
32 #define ndIndxNode 0x00 /* An internal (index) node */
33 #define ndHdrNode 0x01 /* The tree header node (node 0) */
34 #define ndMapNode 0x02 /* Holds part of the bitmap of used nodes */
35 #define ndLeafNode 0xFF /* A leaf (ndNHeight==1) node */
37 /*================ Function-like macros ================*/
39 /* Access the cache slot which should contain the desired node */
40 #define bhash(tree, node) ((tree)->cache[(node) % HFS_CACHELEN])
42 /* round up to multiple of sizeof(hfs_u16) */
43 #define ROUND(X) ((X + sizeof(hfs_u16) - 1) & ~(sizeof(hfs_u16)-1))
45 /* Refer to the (base-1) array of offsets in a bnode */
47 (((hfs_u16 *)(hfs_buffer_data((X)->buf)+HFS_SECTOR_SIZE))-(N))
49 /*================ Private data types ================*/
54 * The B-tree header record
56 * This data structure is stored in the first node (512-byte block) of
57 * each B-tree file. It contains important information about the
58 * B-tree. Most fields vary over the life of the tree and are
59 * indicated by a 'V' in the comments. The other fields are fixed for
60 * the life of the tree and are indicated by a 'F'.
62 * Reference: _Inside Macintosh: Files_ pp. 2-68 through 2-69 */
64 hfs_word_t bthDepth
; /* (V) The number of levels in this B-tree */
65 hfs_lword_t bthRoot
; /* (V) The node number of the root node */
66 hfs_lword_t bthNRecs
; /* (V) The number of leaf records */
67 hfs_lword_t bthFNode
; /* (V) The number of the first leaf node */
68 hfs_lword_t bthLNode
; /* (V) The number of the last leaf node */
69 hfs_word_t bthNodeSize
; /* (F) The number of bytes in a node (=512) */
70 hfs_word_t bthKeyLen
; /* (F) The length of a key in an index node */
71 hfs_lword_t bthNNodes
; /* (V) The total number of nodes */
72 hfs_lword_t bthFree
; /* (V) The number of unused nodes */
73 hfs_byte_t bthResv
[76]; /* Reserved */
77 * struct NodeDescriptor
79 * The B-tree node descriptor.
81 * This structure begins each node in the B-tree file. It contains
82 * important information about the node's contents. 'V' and 'F' in
83 * the comments indicate fields that are variable or fixed over the
84 * life of a node, where the 'life' of a node is defined as the period
85 * between leaving and reentering the free pool.
87 * Reference: _Inside Macintosh: Files_ p. 2-64
89 struct NodeDescriptor
{
90 hfs_lword_t ndFLink
; /* (V) Number of the next node at this level */
91 hfs_lword_t ndBLink
; /* (V) Number of the prev node at this level */
92 hfs_byte_t ndType
; /* (F) The type of node */
93 hfs_byte_t ndNHeight
; /* (F) The level of this node (leaves=1) */
94 hfs_word_t ndNRecs
; /* (V) The number of records in this node */
95 hfs_word_t ndResv2
; /* Reserved */
101 * The type 'hfs_cmpfn' is a comparison function taking 2 keys and
102 * returning a positive, negative or zero integer according to the
103 * ordering of the two keys (just like strcmp() does for strings).
105 typedef int (*hfs_cmpfn
)(const void *, const void *);
110 * An in-core B-tree node
112 * This structure holds information from the NodeDescriptor in native
113 * byte-order, a pointer to the buffer which contains the actual
114 * node and fields necessary for locking access to the node during
115 * updates. The use of the locking fields is explained with the
119 int magic
; /* Magic number to guard against
121 hfs_buffer buf
; /* The buffer containing the
123 struct hfs_btree
*tree
; /* The tree to which this node
125 struct hfs_bnode
*prev
; /* Next node in this hash bucket */
126 struct hfs_bnode
*next
; /* Previous node in this hash
128 int sticky
; /* Boolean: non-zero means keep
129 this node in-core (set for
131 hfs_u32 node
; /* Node number */
132 /* locking related fields: */
133 hfs_wait_queue wqueue
; /* Wait queue for write access */
134 hfs_wait_queue rqueue
; /* Wait queue for read or reserve
136 int count
; /* Number of processes accessing
138 int resrv
; /* Boolean, true means a process
139 had placed a 'reservation' on
141 int lock
; /* Boolean, true means some
142 process has exclusive access,
144 /* fields from the NodeDescriptor in native byte-order: */
157 * This structure holds information from the BTHdrRec, MDB
158 * (superblock) and other information needed to work with the B-tree.
161 int magic
; /* Magic number to
164 hfs_cmpfn compare
; /* Comparison function
166 struct hfs_bnode head
; /* in-core copy of node 0 */
167 struct hfs_bnode
*root
; /* Pointer to the in-core
168 copy of the root node */
169 hfs_sysmdb sys_mdb
; /* The "device" holding
171 int reserved
; /* bnodes claimed but
173 struct hfs_bnode
/* The bnode cache */
174 *cache
[HFS_CACHELEN
];
175 struct hfs_cat_entry entry
; /* Fake catalog entry */
179 /* Fields from the BTHdrRec in native byte-order: */
190 /*================ Global functions ================*/
192 /* Convert a (struct hfs_bnode *) and an index to the value of the
193 n-th offset in the bnode (N >= 1) to the offset */
194 extern inline hfs_u16
bnode_offset(const struct hfs_bnode
*bnode
, int n
)
195 { return hfs_get_hs(RECTBL(bnode
,n
)); }
197 /* Convert a (struct hfs_bnode *) and an index to the size of the
198 n-th record in the bnode (N >= 1) */
199 extern inline hfs_u16
bnode_rsize(const struct hfs_bnode
*bnode
, int n
)
200 { return bnode_offset(bnode
, n
+1) - bnode_offset(bnode
, n
); }
202 /* Convert a (struct hfs_bnode *) to the offset of the empty part */
203 extern inline hfs_u16
bnode_end(const struct hfs_bnode
*bnode
)
204 { return bnode_offset(bnode
, bnode
->ndNRecs
+ 1); }
206 /* Convert a (struct hfs_bnode *) to the number of free bytes it contains */
207 extern inline hfs_u16
bnode_freespace(const struct hfs_bnode
*bnode
)
208 { return HFS_SECTOR_SIZE
- bnode_end(bnode
)
209 - (bnode
->ndNRecs
+ 1)*sizeof(hfs_u16
); }
211 /* Convert a (struct hfs_bnode *) X and an index N to
212 the address of the record N in the bnode (N >= 1) */
213 extern inline void *bnode_datastart(const struct hfs_bnode
*bnode
)
214 { return (void *)(hfs_buffer_data(bnode
->buf
)+sizeof(struct NodeDescriptor
)); }
216 /* Convert a (struct hfs_bnode *) to the address of the empty part */
217 extern inline void *bnode_dataend(const struct hfs_bnode
*bnode
)
218 { return (void *)(hfs_buffer_data(bnode
->buf
) + bnode_end(bnode
)); }
220 /* Convert various pointers to address of record's key */
221 extern inline void *bnode_key(const struct hfs_bnode
*bnode
, int n
)
222 { return (void *)(hfs_buffer_data(bnode
->buf
) + bnode_offset(bnode
, n
)); }
223 extern inline void *belem_key(const struct hfs_belem
*elem
)
224 { return bnode_key(elem
->bnr
.bn
, elem
->record
); }
225 extern inline void *brec_key(const struct hfs_brec
*brec
)
226 { return belem_key(brec
->bottom
); }
228 /* Convert various pointers to the address of a record */
229 extern inline void *bkey_record(const struct hfs_bkey
*key
)
230 { return (void *)key
+ ROUND(key
->KeyLen
+ 1); }
231 extern inline void *bnode_record(const struct hfs_bnode
*bnode
, int n
)
232 { return bkey_record(bnode_key(bnode
, n
)); }
233 extern inline void *belem_record(const struct hfs_belem
*elem
)
234 { return bkey_record(belem_key(elem
)); }
235 extern inline void *brec_record(const struct hfs_brec
*brec
)
236 { return bkey_record(brec_key(brec
)); }
238 /*================ Function Prototypes ================*/
241 extern int hfs_bnode_bitop(struct hfs_btree
*, hfs_u32
, int);
242 extern struct hfs_bnode_ref
hfs_bnode_alloc(struct hfs_btree
*);
243 extern int hfs_bnode_free(struct hfs_bnode_ref
*);
244 extern void hfs_btree_extend(struct hfs_btree
*);
247 extern void hfs_bnode_update_key(struct hfs_brec
*, struct hfs_belem
*,
248 struct hfs_bnode
*, int);
249 extern void hfs_bnode_shift_right(struct hfs_bnode
*, struct hfs_bnode
*, int);
250 extern void hfs_bnode_shift_left(struct hfs_bnode
*, struct hfs_bnode
*, int);
251 extern int hfs_bnode_in_brec(hfs_u32 node
, const struct hfs_brec
*brec
);
254 extern void hfs_bnode_read(struct hfs_bnode
*, struct hfs_btree
*,
256 extern void hfs_bnode_relse(struct hfs_bnode_ref
*);
257 extern struct hfs_bnode_ref
hfs_bnode_find(struct hfs_btree
*, hfs_u32
, int);
258 extern void hfs_bnode_lock(struct hfs_bnode_ref
*, int);
259 extern void hfs_bnode_delete(struct hfs_bnode
*);
260 extern void hfs_bnode_commit(struct hfs_bnode
*);
263 extern void hfs_brec_lock(struct hfs_brec
*, struct hfs_belem
*);
264 extern struct hfs_belem
*hfs_brec_init(struct hfs_brec
*, struct hfs_btree
*,
266 extern struct hfs_belem
*hfs_brec_next(struct hfs_brec
*);