1 /*
2  * Copyright (c) 2000,2002-2004 Silicon Graphics, Inc.  All Rights Reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of version 2 of the GNU General Public License as
6  * published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it would be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11  *
12  * Further, this software is distributed without any warranty that it is
13  * free of the rightful claim of any third person regarding infringement
14  * or the like.	 Any license provided herein, whether implied or
15  * otherwise, applies only to this software file.  Patent licenses, if
16  * any, provided herein do not apply to combinations of this program with
17  * other software, or any other product whatsoever.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write the Free Software Foundation, Inc., 59
21  * Temple Place - Suite 330, Boston MA 02111-1307, USA.
22  *
23  * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24  * Mountain View, CA  94043, or:
25  *
26  * http://www.sgi.com
27  *
28  * For further information regarding this notice, see:
29  *
30  * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31  */
32 #ifndef __XFS_BMAP_BTREE_H__
33 #define __XFS_BMAP_BTREE_H__
34 
35 #define XFS_BMAP_MAGIC	0x424d4150	/* 'BMAP' */
36 
37 struct xfs_btree_cur;
38 struct xfs_btree_lblock;
39 struct xfs_mount;
40 struct xfs_inode;
41 
42 /*
43  * Bmap root header, on-disk form only.
44  */
45 typedef struct xfs_bmdr_block
46 {
47 	__uint16_t	bb_level;	/* 0 is a leaf */
48 	__uint16_t	bb_numrecs;	/* current # of data records */
49 } xfs_bmdr_block_t;
50 
51 /*
52  * Bmap btree record and extent descriptor.
53  * For 32-bit kernels,
54  *  l0:31 is an extent flag (value 1 indicates non-normal).
55  *  l0:0-30 and l1:9-31 are startoff.
56  *  l1:0-8, l2:0-31, and l3:21-31 are startblock.
57  *  l3:0-20 are blockcount.
58  * For 64-bit kernels,
59  *  l0:63 is an extent flag (value 1 indicates non-normal).
60  *  l0:9-62 are startoff.
61  *  l0:0-8 and l1:21-63 are startblock.
62  *  l1:0-20 are blockcount.
63  */
64 
65 #if __BYTE_ORDER == __LITTLE_ENDIAN
66 
67 #define BMBT_TOTAL_BITLEN	128	/* 128 bits, 16 bytes */
68 #define BMBT_EXNTFLAG_BITOFF	0
69 #define BMBT_EXNTFLAG_BITLEN	1
70 #define BMBT_STARTOFF_BITOFF	(BMBT_EXNTFLAG_BITOFF + BMBT_EXNTFLAG_BITLEN)
71 #define BMBT_STARTOFF_BITLEN	54
72 #define BMBT_STARTBLOCK_BITOFF	(BMBT_STARTOFF_BITOFF + BMBT_STARTOFF_BITLEN)
73 #define BMBT_STARTBLOCK_BITLEN	52
74 #define BMBT_BLOCKCOUNT_BITOFF	\
75 	(BMBT_STARTBLOCK_BITOFF + BMBT_STARTBLOCK_BITLEN)
76 #define BMBT_BLOCKCOUNT_BITLEN	(BMBT_TOTAL_BITLEN - BMBT_BLOCKCOUNT_BITOFF)
77 
78 #else
79 
80 #define BMBT_TOTAL_BITLEN	128	/* 128 bits, 16 bytes */
81 #define BMBT_EXNTFLAG_BITOFF	63
82 #define BMBT_EXNTFLAG_BITLEN	1
83 #define BMBT_STARTOFF_BITOFF	(BMBT_EXNTFLAG_BITOFF - BMBT_STARTOFF_BITLEN)
84 #define BMBT_STARTOFF_BITLEN	54
85 #define BMBT_STARTBLOCK_BITOFF	85 /* 128 - 43 (other 9 is in first word) */
86 #define BMBT_STARTBLOCK_BITLEN	52
87 #define BMBT_BLOCKCOUNT_BITOFF	64 /* Start of second 64 bit container */
88 #define BMBT_BLOCKCOUNT_BITLEN	21
89 
90 #endif
91 
92 
93 #define BMBT_USE_64	1
94 
95 typedef struct xfs_bmbt_rec_32
96 {
97 	__uint32_t		l0, l1, l2, l3;
98 } xfs_bmbt_rec_32_t;
99 typedef struct xfs_bmbt_rec_64
100 {
101 	__uint64_t		l0, l1;
102 } xfs_bmbt_rec_64_t;
103 
104 typedef __uint64_t	xfs_bmbt_rec_base_t;	/* use this for casts */
105 typedef xfs_bmbt_rec_64_t xfs_bmbt_rec_t, xfs_bmdr_rec_t;
106 
107 /*
108  * Values and macros for delayed-allocation startblock fields.
109  */
110 #define STARTBLOCKVALBITS	17
111 #define STARTBLOCKMASKBITS	(15 + XFS_BIG_BLKNOS * 20)
112 #define DSTARTBLOCKMASKBITS	(15 + 20)
113 #define STARTBLOCKMASK		\
114 	(((((xfs_fsblock_t)1) << STARTBLOCKMASKBITS) - 1) << STARTBLOCKVALBITS)
115 #define DSTARTBLOCKMASK		\
116 	(((((xfs_dfsbno_t)1) << DSTARTBLOCKMASKBITS) - 1) << STARTBLOCKVALBITS)
117 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_ISNULLSTARTBLOCK)
118 int isnullstartblock(xfs_fsblock_t x);
119 #define ISNULLSTARTBLOCK(x)	isnullstartblock(x)
120 #else
121 #define ISNULLSTARTBLOCK(x)	(((x) & STARTBLOCKMASK) == STARTBLOCKMASK)
122 #endif
123 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_ISNULLDSTARTBLOCK)
124 int isnulldstartblock(xfs_dfsbno_t x);
125 #define ISNULLDSTARTBLOCK(x)	isnulldstartblock(x)
126 #else
127 #define ISNULLDSTARTBLOCK(x)	(((x) & DSTARTBLOCKMASK) == DSTARTBLOCKMASK)
128 #endif
129 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_NULLSTARTBLOCK)
130 xfs_fsblock_t nullstartblock(int k);
131 #define NULLSTARTBLOCK(k)	nullstartblock(k)
132 #else
133 #define NULLSTARTBLOCK(k)	\
134 	((ASSERT(k < (1 << STARTBLOCKVALBITS))), (STARTBLOCKMASK | (k)))
135 #endif
136 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_STARTBLOCKVAL)
137 xfs_filblks_t startblockval(xfs_fsblock_t x);
138 #define STARTBLOCKVAL(x)	startblockval(x)
139 #else
140 #define STARTBLOCKVAL(x)	((xfs_filblks_t)((x) & ~STARTBLOCKMASK))
141 #endif
142 
143 /*
144  * Possible extent formats.
145  */
146 typedef enum {
147 	XFS_EXTFMT_NOSTATE = 0,
148 	XFS_EXTFMT_HASSTATE
149 } xfs_exntfmt_t;
150 
151 /*
152  * Possible extent states.
153  */
154 typedef enum {
155 	XFS_EXT_NORM, XFS_EXT_UNWRITTEN,
156 	XFS_EXT_DMAPI_OFFLINE, XFS_EXT_INVALID
157 } xfs_exntst_t;
158 
159 /*
160  * Extent state and extent format macros.
161  */
162 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_EXTFMT_INODE )
163 xfs_exntfmt_t xfs_extfmt_inode(struct xfs_inode *ip);
164 #define XFS_EXTFMT_INODE(x)	xfs_extfmt_inode(x)
165 #else
166 #define XFS_EXTFMT_INODE(x) \
167   (XFS_SB_VERSION_HASEXTFLGBIT(&((x)->i_mount->m_sb)) ? \
168 	XFS_EXTFMT_HASSTATE : XFS_EXTFMT_NOSTATE)
169 #endif
170 #define ISUNWRITTEN(x)	((x)->br_state == XFS_EXT_UNWRITTEN)
171 
172 /*
173  * Incore version of above.
174  */
175 typedef struct xfs_bmbt_irec
176 {
177 	xfs_fileoff_t	br_startoff;	/* starting file offset */
178 	xfs_fsblock_t	br_startblock;	/* starting block number */
179 	xfs_filblks_t	br_blockcount;	/* number of blocks */
180 	xfs_exntst_t	br_state;	/* extent state */
181 } xfs_bmbt_irec_t;
182 
183 /*
184  * Key structure for non-leaf levels of the tree.
185  */
186 typedef struct xfs_bmbt_key
187 {
188 	xfs_dfiloff_t	br_startoff;	/* starting file offset */
189 } xfs_bmbt_key_t, xfs_bmdr_key_t;
190 
191 typedef xfs_dfsbno_t xfs_bmbt_ptr_t, xfs_bmdr_ptr_t;	/* btree pointer type */
192 					/* btree block header type */
193 typedef struct xfs_btree_lblock xfs_bmbt_block_t;
194 
195 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BUF_TO_BMBT_BLOCK)
196 xfs_bmbt_block_t *xfs_buf_to_bmbt_block(struct xfs_buf *bp);
197 #define XFS_BUF_TO_BMBT_BLOCK(bp)		xfs_buf_to_bmbt_block(bp)
198 #else
199 #define XFS_BUF_TO_BMBT_BLOCK(bp) ((xfs_bmbt_block_t *)(XFS_BUF_PTR(bp)))
200 #endif
201 
202 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_RBLOCK_DSIZE)
203 int xfs_bmap_rblock_dsize(int lev, struct xfs_btree_cur *cur);
204 #define XFS_BMAP_RBLOCK_DSIZE(lev,cur)		xfs_bmap_rblock_dsize(lev,cur)
205 #else
206 #define XFS_BMAP_RBLOCK_DSIZE(lev,cur) ((cur)->bc_private.b.forksize)
207 #endif
208 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_RBLOCK_ISIZE)
209 int xfs_bmap_rblock_isize(int lev, struct xfs_btree_cur *cur);
210 #define XFS_BMAP_RBLOCK_ISIZE(lev,cur)		xfs_bmap_rblock_isize(lev,cur)
211 #else
212 #define XFS_BMAP_RBLOCK_ISIZE(lev,cur) \
213 	((int)XFS_IFORK_PTR((cur)->bc_private.b.ip, \
214 			    (cur)->bc_private.b.whichfork)->if_broot_bytes)
215 #endif
216 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_IBLOCK_SIZE)
217 int xfs_bmap_iblock_size(int lev, struct xfs_btree_cur *cur);
218 #define XFS_BMAP_IBLOCK_SIZE(lev,cur)		xfs_bmap_iblock_size(lev,cur)
219 #else
220 #define XFS_BMAP_IBLOCK_SIZE(lev,cur) (1 << (cur)->bc_blocklog)
221 #endif
222 
223 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BLOCK_DSIZE)
224 int xfs_bmap_block_dsize(int lev, struct xfs_btree_cur *cur);
225 #define XFS_BMAP_BLOCK_DSIZE(lev,cur)		xfs_bmap_block_dsize(lev,cur)
226 #else
227 #define XFS_BMAP_BLOCK_DSIZE(lev,cur) \
228 	((lev) == (cur)->bc_nlevels - 1 ? \
229 		XFS_BMAP_RBLOCK_DSIZE(lev,cur) : \
230 		XFS_BMAP_IBLOCK_SIZE(lev,cur))
231 #endif
232 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BLOCK_ISIZE)
233 int xfs_bmap_block_isize(int lev, struct xfs_btree_cur *cur);
234 #define XFS_BMAP_BLOCK_ISIZE(lev,cur)		xfs_bmap_block_isize(lev,cur)
235 #else
236 #define XFS_BMAP_BLOCK_ISIZE(lev,cur) \
237 	((lev) == (cur)->bc_nlevels - 1 ? \
238 		XFS_BMAP_RBLOCK_ISIZE(lev,cur) : \
239 		XFS_BMAP_IBLOCK_SIZE(lev,cur))
240 #endif
241 
242 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BLOCK_DMAXRECS)
243 int xfs_bmap_block_dmaxrecs(int lev, struct xfs_btree_cur *cur);
244 #define XFS_BMAP_BLOCK_DMAXRECS(lev,cur)	xfs_bmap_block_dmaxrecs(lev,cur)
245 #else
246 #define XFS_BMAP_BLOCK_DMAXRECS(lev,cur) \
247 	((lev) == (cur)->bc_nlevels - 1 ? \
248 		XFS_BTREE_BLOCK_MAXRECS(XFS_BMAP_RBLOCK_DSIZE(lev,cur), \
249 			xfs_bmdr, (lev) == 0) : \
250 		((cur)->bc_mp->m_bmap_dmxr[(lev) != 0]))
251 #endif
252 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BLOCK_IMAXRECS)
253 int xfs_bmap_block_imaxrecs(int lev, struct xfs_btree_cur *cur);
254 #define XFS_BMAP_BLOCK_IMAXRECS(lev,cur)	xfs_bmap_block_imaxrecs(lev,cur)
255 #else
256 #define XFS_BMAP_BLOCK_IMAXRECS(lev,cur) \
257 	((lev) == (cur)->bc_nlevels - 1 ? \
258 		XFS_BTREE_BLOCK_MAXRECS(XFS_BMAP_RBLOCK_ISIZE(lev,cur), \
259 			xfs_bmbt, (lev) == 0) : \
260 		((cur)->bc_mp->m_bmap_dmxr[(lev) != 0]))
261 #endif
262 
263 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BLOCK_DMINRECS)
264 int xfs_bmap_block_dminrecs(int lev, struct xfs_btree_cur *cur);
265 #define XFS_BMAP_BLOCK_DMINRECS(lev,cur)	xfs_bmap_block_dminrecs(lev,cur)
266 #else
267 #define XFS_BMAP_BLOCK_DMINRECS(lev,cur) \
268 	((lev) == (cur)->bc_nlevels - 1 ? \
269 		XFS_BTREE_BLOCK_MINRECS(XFS_BMAP_RBLOCK_DSIZE(lev,cur), \
270 			xfs_bmdr, (lev) == 0) : \
271 		((cur)->bc_mp->m_bmap_dmnr[(lev) != 0]))
272 #endif
273 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BLOCK_IMINRECS)
274 int xfs_bmap_block_iminrecs(int lev, struct xfs_btree_cur *cur);
275 #define XFS_BMAP_BLOCK_IMINRECS(lev,cur)	xfs_bmap_block_iminrecs(lev,cur)
276 #else
277 #define XFS_BMAP_BLOCK_IMINRECS(lev,cur) \
278 	((lev) == (cur)->bc_nlevels - 1 ? \
279 		XFS_BTREE_BLOCK_MINRECS(XFS_BMAP_RBLOCK_ISIZE(lev,cur), \
280 			xfs_bmbt, (lev) == 0) : \
281 		((cur)->bc_mp->m_bmap_dmnr[(lev) != 0]))
282 #endif
283 
284 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_REC_DADDR)
285 xfs_bmbt_rec_t *
286 xfs_bmap_rec_daddr(xfs_bmbt_block_t *bb, int i, struct xfs_btree_cur *cur);
287 #define XFS_BMAP_REC_DADDR(bb,i,cur)		xfs_bmap_rec_daddr(bb,i,cur)
288 #else
289 #define XFS_BMAP_REC_DADDR(bb,i,cur) \
290 	XFS_BTREE_REC_ADDR(XFS_BMAP_BLOCK_DSIZE(		\
291 		INT_GET((bb)->bb_level, ARCH_CONVERT), cur),	\
292 		xfs_bmbt, bb, i, XFS_BMAP_BLOCK_DMAXRECS(	\
293 			INT_GET((bb)->bb_level, ARCH_CONVERT), cur))
294 #endif
295 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_REC_IADDR)
296 xfs_bmbt_rec_t *
297 xfs_bmap_rec_iaddr(xfs_bmbt_block_t *bb, int i, struct xfs_btree_cur *cur);
298 #define XFS_BMAP_REC_IADDR(bb,i,cur)		xfs_bmap_rec_iaddr(bb,i,cur)
299 #else
300 #define XFS_BMAP_REC_IADDR(bb,i,cur) \
301 	XFS_BTREE_REC_ADDR(XFS_BMAP_BLOCK_ISIZE(		\
302 		INT_GET((bb)->bb_level, ARCH_CONVERT), cur),	\
303 		xfs_bmbt, bb, i, XFS_BMAP_BLOCK_IMAXRECS(	\
304 			INT_GET((bb)->bb_level, ARCH_CONVERT), cur))
305 #endif
306 
307 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_KEY_DADDR)
308 xfs_bmbt_key_t *
309 xfs_bmap_key_daddr(xfs_bmbt_block_t *bb, int i, struct xfs_btree_cur *cur);
310 #define XFS_BMAP_KEY_DADDR(bb,i,cur)		xfs_bmap_key_daddr(bb,i,cur)
311 #else
312 #define XFS_BMAP_KEY_DADDR(bb,i,cur) \
313 	XFS_BTREE_KEY_ADDR(XFS_BMAP_BLOCK_DSIZE(		\
314 		INT_GET((bb)->bb_level, ARCH_CONVERT), cur),	\
315 		xfs_bmbt, bb, i, XFS_BMAP_BLOCK_DMAXRECS(	\
316 			INT_GET((bb)->bb_level, ARCH_CONVERT), cur))
317 #endif
318 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_KEY_IADDR)
319 xfs_bmbt_key_t *
320 xfs_bmap_key_iaddr(xfs_bmbt_block_t *bb, int i, struct xfs_btree_cur *cur);
321 #define XFS_BMAP_KEY_IADDR(bb,i,cur)		xfs_bmap_key_iaddr(bb,i,cur)
322 #else
323 #define XFS_BMAP_KEY_IADDR(bb,i,cur) \
324 	XFS_BTREE_KEY_ADDR(XFS_BMAP_BLOCK_ISIZE(		\
325 		INT_GET((bb)->bb_level, ARCH_CONVERT), cur),	\
326 		xfs_bmbt, bb, i, XFS_BMAP_BLOCK_IMAXRECS(	\
327 			INT_GET((bb)->bb_level, ARCH_CONVERT), cur))
328 #endif
329 
330 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_PTR_DADDR)
331 xfs_bmbt_ptr_t *
332 xfs_bmap_ptr_daddr(xfs_bmbt_block_t *bb, int i, struct xfs_btree_cur *cur);
333 #define XFS_BMAP_PTR_DADDR(bb,i,cur)		xfs_bmap_ptr_daddr(bb,i,cur)
334 #else
335 #define XFS_BMAP_PTR_DADDR(bb,i,cur) \
336 	XFS_BTREE_PTR_ADDR(XFS_BMAP_BLOCK_DSIZE(		\
337 		INT_GET((bb)->bb_level, ARCH_CONVERT), cur),	\
338 		xfs_bmbt, bb, i, XFS_BMAP_BLOCK_DMAXRECS(	\
339 			INT_GET((bb)->bb_level, ARCH_CONVERT), cur))
340 #endif
341 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_PTR_IADDR)
342 xfs_bmbt_ptr_t *
343 xfs_bmap_ptr_iaddr(xfs_bmbt_block_t *bb, int i, struct xfs_btree_cur *cur);
344 #define XFS_BMAP_PTR_IADDR(bb,i,cur)		xfs_bmap_ptr_iaddr(bb,i,cur)
345 #else
346 #define XFS_BMAP_PTR_IADDR(bb,i,cur) \
347 	XFS_BTREE_PTR_ADDR(XFS_BMAP_BLOCK_ISIZE(		\
348 		INT_GET((bb)->bb_level, ARCH_CONVERT), cur),	\
349 		xfs_bmbt, bb, i, XFS_BMAP_BLOCK_IMAXRECS(	\
350 			INT_GET((bb)->bb_level, ARCH_CONVERT), cur))
351 #endif
352 
353 /*
354  * These are to be used when we know the size of the block and
355  * we don't have a cursor.
356  */
357 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BROOT_REC_ADDR)
358 xfs_bmbt_rec_t *xfs_bmap_broot_rec_addr(xfs_bmbt_block_t *bb, int i, int sz);
359 #define XFS_BMAP_BROOT_REC_ADDR(bb,i,sz)	xfs_bmap_broot_rec_addr(bb,i,sz)
360 #else
361 #define XFS_BMAP_BROOT_REC_ADDR(bb,i,sz) \
362 	XFS_BTREE_REC_ADDR(sz,xfs_bmbt,bb,i,XFS_BMAP_BROOT_MAXRECS(sz))
363 #endif
364 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BROOT_KEY_ADDR)
365 xfs_bmbt_key_t *xfs_bmap_broot_key_addr(xfs_bmbt_block_t *bb, int i, int sz);
366 #define XFS_BMAP_BROOT_KEY_ADDR(bb,i,sz)	xfs_bmap_broot_key_addr(bb,i,sz)
367 #else
368 #define XFS_BMAP_BROOT_KEY_ADDR(bb,i,sz) \
369 	XFS_BTREE_KEY_ADDR(sz,xfs_bmbt,bb,i,XFS_BMAP_BROOT_MAXRECS(sz))
370 #endif
371 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BROOT_PTR_ADDR)
372 xfs_bmbt_ptr_t *xfs_bmap_broot_ptr_addr(xfs_bmbt_block_t *bb, int i, int sz);
373 #define XFS_BMAP_BROOT_PTR_ADDR(bb,i,sz)	xfs_bmap_broot_ptr_addr(bb,i,sz)
374 #else
375 #define XFS_BMAP_BROOT_PTR_ADDR(bb,i,sz) \
376 	XFS_BTREE_PTR_ADDR(sz,xfs_bmbt,bb,i,XFS_BMAP_BROOT_MAXRECS(sz))
377 #endif
378 
379 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BROOT_NUMRECS)
380 int xfs_bmap_broot_numrecs(xfs_bmdr_block_t *bb);
381 #define XFS_BMAP_BROOT_NUMRECS(bb)		xfs_bmap_broot_numrecs(bb)
382 #else
383 #define XFS_BMAP_BROOT_NUMRECS(bb) (INT_GET((bb)->bb_numrecs, ARCH_CONVERT))
384 #endif
385 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BROOT_MAXRECS)
386 int xfs_bmap_broot_maxrecs(int sz);
387 #define XFS_BMAP_BROOT_MAXRECS(sz)		xfs_bmap_broot_maxrecs(sz)
388 #else
389 #define XFS_BMAP_BROOT_MAXRECS(sz) XFS_BTREE_BLOCK_MAXRECS(sz,xfs_bmbt,0)
390 #endif
391 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BROOT_SPACE_CALC)
392 int xfs_bmap_broot_space_calc(int nrecs);
393 #define XFS_BMAP_BROOT_SPACE_CALC(nrecs)	xfs_bmap_broot_space_calc(nrecs)
394 #else
395 #define XFS_BMAP_BROOT_SPACE_CALC(nrecs) \
396 	((int)(sizeof(xfs_bmbt_block_t) + \
397 	       ((nrecs) * (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t)))))
398 #endif
399 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BROOT_SPACE)
400 int xfs_bmap_broot_space(xfs_bmdr_block_t *bb);
401 #define XFS_BMAP_BROOT_SPACE(bb)		xfs_bmap_broot_space(bb)
402 #else
403 #define XFS_BMAP_BROOT_SPACE(bb) \
404 	XFS_BMAP_BROOT_SPACE_CALC(INT_GET((bb)->bb_numrecs, ARCH_CONVERT))
405 #endif
406 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMDR_SPACE_CALC)
407 int xfs_bmdr_space_calc(int nrecs);
408 #define XFS_BMDR_SPACE_CALC(nrecs)		xfs_bmdr_space_calc(nrecs)
409 #else
410 #define XFS_BMDR_SPACE_CALC(nrecs)	\
411 	((int)(sizeof(xfs_bmdr_block_t) + \
412 	       ((nrecs) * (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t)))))
413 #endif
414 
415 /*
416  * Maximum number of bmap btree levels.
417  */
418 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BM_MAXLEVELS)
419 int xfs_bm_maxlevels(struct xfs_mount *mp, int w);
420 #define XFS_BM_MAXLEVELS(mp,w)			xfs_bm_maxlevels(mp,w)
421 #else
422 #define XFS_BM_MAXLEVELS(mp,w)		((mp)->m_bm_maxlevels[w])
423 #endif
424 
425 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_SANITY_CHECK)
426 int xfs_bmap_sanity_check(struct xfs_mount *mp, xfs_bmbt_block_t *bb,
427 	int level);
428 #define XFS_BMAP_SANITY_CHECK(mp,bb,level)	\
429 	xfs_bmap_sanity_check(mp,bb,level)
430 #else
431 #define XFS_BMAP_SANITY_CHECK(mp,bb,level)	\
432 	(INT_GET((bb)->bb_magic, ARCH_CONVERT) == XFS_BMAP_MAGIC && \
433 	 INT_GET((bb)->bb_level, ARCH_CONVERT) == level && \
434 	 INT_GET((bb)->bb_numrecs, ARCH_CONVERT) > 0 && \
435 	 INT_GET((bb)->bb_numrecs, ARCH_CONVERT) <= (mp)->m_bmap_dmxr[(level) != 0])
436 #endif
437 
438 
439 #ifdef __KERNEL__
440 
441 #if defined(XFS_BMBT_TRACE)
442 /*
443  * Trace buffer entry types.
444  */
445 #define XFS_BMBT_KTRACE_ARGBI	1
446 #define XFS_BMBT_KTRACE_ARGBII	2
447 #define XFS_BMBT_KTRACE_ARGFFFI 3
448 #define XFS_BMBT_KTRACE_ARGI	4
449 #define XFS_BMBT_KTRACE_ARGIFK	5
450 #define XFS_BMBT_KTRACE_ARGIFR	6
451 #define XFS_BMBT_KTRACE_ARGIK	7
452 #define XFS_BMBT_KTRACE_CUR	8
453 
454 #define XFS_BMBT_TRACE_SIZE	4096	/* size of global trace buffer */
455 #define XFS_BMBT_KTRACE_SIZE	32	/* size of per-inode trace buffer */
456 extern ktrace_t	*xfs_bmbt_trace_buf;
457 #endif
458 
459 /*
460  * Prototypes for xfs_bmap.c to call.
461  */
462 
463 void
464 xfs_bmdr_to_bmbt(
465 	xfs_bmdr_block_t *,
466 	int,
467 	xfs_bmbt_block_t *,
468 	int);
469 
470 int
471 xfs_bmbt_decrement(
472 	struct xfs_btree_cur *,
473 	int,
474 	int *);
475 
476 int
477 xfs_bmbt_delete(
478 	struct xfs_btree_cur *,
479 	int *);
480 
481 void
482 xfs_bmbt_get_all(
483 	xfs_bmbt_rec_t	*r,
484 	xfs_bmbt_irec_t *s);
485 
486 xfs_bmbt_block_t *
487 xfs_bmbt_get_block(
488 	struct xfs_btree_cur	*cur,
489 	int			level,
490 	struct xfs_buf		**bpp);
491 
492 xfs_filblks_t
493 xfs_bmbt_get_blockcount(
494 	xfs_bmbt_rec_t	*r);
495 
496 xfs_fsblock_t
497 xfs_bmbt_get_startblock(
498 	xfs_bmbt_rec_t	*r);
499 
500 xfs_fileoff_t
501 xfs_bmbt_get_startoff(
502 	xfs_bmbt_rec_t	*r);
503 
504 xfs_exntst_t
505 xfs_bmbt_get_state(
506 	xfs_bmbt_rec_t	*r);
507 
508 #if ARCH_CONVERT != ARCH_NOCONVERT
509 void
510 xfs_bmbt_disk_get_all(
511 	xfs_bmbt_rec_t	*r,
512 	xfs_bmbt_irec_t *s);
513 
514 xfs_exntst_t
515 xfs_bmbt_disk_get_state(
516 	xfs_bmbt_rec_t	*r);
517 
518 xfs_filblks_t
519 xfs_bmbt_disk_get_blockcount(
520 	xfs_bmbt_rec_t	*r);
521 
522 xfs_fsblock_t
523 xfs_bmbt_disk_get_startblock(
524 	xfs_bmbt_rec_t	*r);
525 
526 xfs_fileoff_t
527 xfs_bmbt_disk_get_startoff(
528 	xfs_bmbt_rec_t	*r);
529 
530 #else
531 #define xfs_bmbt_disk_get_all(r, s) \
532 	xfs_bmbt_get_all(r, s)
533 #define xfs_bmbt_disk_get_state(r) \
534 	xfs_bmbt_get_state(r)
535 #define xfs_bmbt_disk_get_blockcount(r) \
536 	xfs_bmbt_get_blockcount(r)
537 #define xfs_bmbt_disk_get_startblock(r) \
538 	xfs_bmbt_get_blockcount(r)
539 #define xfs_bmbt_disk_get_startoff(r) \
540 	xfs_bmbt_get_startoff(r)
541 #endif
542 
543 int
544 xfs_bmbt_increment(
545 	struct xfs_btree_cur *,
546 	int,
547 	int *);
548 
549 int
550 xfs_bmbt_insert(
551 	struct xfs_btree_cur *,
552 	int *);
553 
554 void
555 xfs_bmbt_log_block(
556 	struct xfs_btree_cur *,
557 	struct xfs_buf *,
558 	int);
559 
560 void
561 xfs_bmbt_log_recs(
562 	struct xfs_btree_cur *,
563 	struct xfs_buf *,
564 	int,
565 	int);
566 
567 int
568 xfs_bmbt_lookup_eq(
569 	struct xfs_btree_cur *,
570 	xfs_fileoff_t,
571 	xfs_fsblock_t,
572 	xfs_filblks_t,
573 	int *);
574 
575 int
576 xfs_bmbt_lookup_ge(
577 	struct xfs_btree_cur *,
578 	xfs_fileoff_t,
579 	xfs_fsblock_t,
580 	xfs_filblks_t,
581 	int *);
582 
583 int
584 xfs_bmbt_lookup_le(
585 	struct xfs_btree_cur *,
586 	xfs_fileoff_t,
587 	xfs_fsblock_t,
588 	xfs_filblks_t,
589 	int *);
590 
591 /*
592  * Give the bmap btree a new root block.  Copy the old broot contents
593  * down into a real block and make the broot point to it.
594  */
595 int						/* error */
596 xfs_bmbt_newroot(
597 	struct xfs_btree_cur	*cur,		/* btree cursor */
598 	int			*logflags,	/* logging flags for inode */
599 	int			*stat);		/* return status - 0 fail */
600 
601 void
602 xfs_bmbt_set_all(
603 	xfs_bmbt_rec_t	*r,
604 	xfs_bmbt_irec_t *s);
605 
606 void
607 xfs_bmbt_set_allf(
608 	xfs_bmbt_rec_t	*r,
609 	xfs_fileoff_t	o,
610 	xfs_fsblock_t	b,
611 	xfs_filblks_t	c,
612 	xfs_exntst_t	v);
613 
614 void
615 xfs_bmbt_set_blockcount(
616 	xfs_bmbt_rec_t	*r,
617 	xfs_filblks_t	v);
618 
619 void
620 xfs_bmbt_set_startblock(
621 	xfs_bmbt_rec_t	*r,
622 	xfs_fsblock_t	v);
623 
624 void
625 xfs_bmbt_set_startoff(
626 	xfs_bmbt_rec_t	*r,
627 	xfs_fileoff_t	v);
628 
629 void
630 xfs_bmbt_set_state(
631 	xfs_bmbt_rec_t	*r,
632 	xfs_exntst_t	v);
633 
634 #if ARCH_CONVERT != ARCH_NOCONVERT
635 void
636 xfs_bmbt_disk_set_all(
637 	xfs_bmbt_rec_t	*r,
638 	xfs_bmbt_irec_t *s);
639 
640 void
641 xfs_bmbt_disk_set_allf(
642 	xfs_bmbt_rec_t	*r,
643 	xfs_fileoff_t	o,
644 	xfs_fsblock_t	b,
645 	xfs_filblks_t	c,
646 	xfs_exntst_t	v);
647 #else
648 #define xfs_bmbt_disk_set_all(r, s) \
649 	xfs_bmbt_set_all(r, s)
650 #define xfs_bmbt_disk_set_allf(r, o, b, c, v) \
651 	xfs_bmbt_set_allf(r, o, b, c, v)
652 #endif
653 
654 void
655 xfs_bmbt_to_bmdr(
656 	xfs_bmbt_block_t *,
657 	int,
658 	xfs_bmdr_block_t *,
659 	int);
660 
661 int
662 xfs_bmbt_update(
663 	struct xfs_btree_cur *,
664 	xfs_fileoff_t,
665 	xfs_fsblock_t,
666 	xfs_filblks_t,
667 	xfs_exntst_t);
668 
669 #ifdef DEBUG
670 /*
671  * Get the data from the pointed-to record.
672  */
673 int
674 xfs_bmbt_get_rec(
675 	struct xfs_btree_cur *,
676 	xfs_fileoff_t *,
677 	xfs_fsblock_t *,
678 	xfs_filblks_t *,
679 	xfs_exntst_t *,
680 	int *);
681 #endif
682 
683 
684 /*
685  * Search an extent list for the extent which includes block
686  * bno.
687  */
688 xfs_bmbt_rec_t *
689 xfs_bmap_do_search_extents(
690 	xfs_bmbt_rec_t *,
691 	xfs_extnum_t,
692 	xfs_extnum_t,
693 	xfs_fileoff_t,
694 	int *,
695 	xfs_extnum_t *,
696 	xfs_bmbt_irec_t *,
697 	xfs_bmbt_irec_t *);
698 
699 #endif	/* __KERNEL__ */
700 
701 #endif	/* __XFS_BMAP_BTREE_H__ */
702