xfs_bmap_btree.h revision 153323
1272343Sngie/*
2272343Sngie * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
3272343Sngie *
4272343Sngie * This program is free software; you can redistribute it and/or modify it
5272343Sngie * under the terms of version 2 of the GNU General Public License as
6272343Sngie * published by the Free Software Foundation.
7272343Sngie *
8272343Sngie * This program is distributed in the hope that it would be useful, but
9272343Sngie * WITHOUT ANY WARRANTY; without even the implied warranty of
10272343Sngie * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11272343Sngie *
12272343Sngie * Further, this software is distributed without any warranty that it is
13272343Sngie * free of the rightful claim of any third person regarding infringement
14272343Sngie * or the like.	 Any license provided herein, whether implied or
15272343Sngie * otherwise, applies only to this software file.  Patent licenses, if
16272343Sngie * any, provided herein do not apply to combinations of this program with
17272343Sngie * other software, or any other product whatsoever.
18272343Sngie *
19272343Sngie * You should have received a copy of the GNU General Public License along
20272343Sngie * with this program; if not, write the Free Software Foundation, Inc., 59
21272343Sngie * Temple Place - Suite 330, Boston MA 02111-1307, USA.
22272343Sngie *
23272343Sngie * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24272343Sngie * Mountain View, CA  94043, or:
25272343Sngie *
26272343Sngie * http://www.sgi.com
27272343Sngie *
28272343Sngie * For further information regarding this notice, see:
29272343Sngie *
30272343Sngie * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31272343Sngie */
32272343Sngie#ifndef __XFS_BMAP_BTREE_H__
33272343Sngie#define __XFS_BMAP_BTREE_H__
34272343Sngie
35272343Sngie#define XFS_BMAP_MAGIC	0x424d4150	/* 'BMAP' */
36272343Sngie
37272343Sngiestruct xfs_btree_cur;
38272343Sngiestruct xfs_btree_lblock;
39272343Sngiestruct xfs_mount;
40272343Sngiestruct xfs_inode;
41272343Sngie
42272343Sngie/*
43272343Sngie * Bmap root header, on-disk form only.
44272343Sngie */
45272343Sngietypedef struct xfs_bmdr_block
46272343Sngie{
47289487Sngie	__uint16_t	bb_level;	/* 0 is a leaf */
48289487Sngie	__uint16_t	bb_numrecs;	/* current # of data records */
49289487Sngie} xfs_bmdr_block_t;
50289487Sngie
51289487Sngie/*
52289487Sngie * Bmap btree record and extent descriptor.
53272343Sngie * For 32-bit kernels,
54272343Sngie *  l0:31 is an extent flag (value 1 indicates non-normal).
55272343Sngie *  l0:0-30 and l1:9-31 are startoff.
56272343Sngie *  l1:0-8, l2:0-31, and l3:21-31 are startblock.
57272343Sngie *  l3:0-20 are blockcount.
58272343Sngie * For 64-bit kernels,
59272343Sngie *  l0:63 is an extent flag (value 1 indicates non-normal).
60272343Sngie *  l0:9-62 are startoff.
61272343Sngie *  l0:0-8 and l1:21-63 are startblock.
62272343Sngie *  l1:0-20 are blockcount.
63272343Sngie */
64272343Sngie
65272343Sngie#if __BYTE_ORDER == __LITTLE_ENDIAN
66272343Sngie
67272343Sngie#define BMBT_TOTAL_BITLEN	128	/* 128 bits, 16 bytes */
68272343Sngie#define BMBT_EXNTFLAG_BITOFF	0
69272343Sngie#define BMBT_EXNTFLAG_BITLEN	1
70272343Sngie#define BMBT_STARTOFF_BITOFF	(BMBT_EXNTFLAG_BITOFF + BMBT_EXNTFLAG_BITLEN)
71272343Sngie#define BMBT_STARTOFF_BITLEN	54
72272343Sngie#define BMBT_STARTBLOCK_BITOFF	(BMBT_STARTOFF_BITOFF + BMBT_STARTOFF_BITLEN)
73272343Sngie#define BMBT_STARTBLOCK_BITLEN	52
74272343Sngie#define BMBT_BLOCKCOUNT_BITOFF	\
75272343Sngie	(BMBT_STARTBLOCK_BITOFF + BMBT_STARTBLOCK_BITLEN)
76272343Sngie#define BMBT_BLOCKCOUNT_BITLEN	(BMBT_TOTAL_BITLEN - BMBT_BLOCKCOUNT_BITOFF)
77272343Sngie
78272343Sngie#else
79272343Sngie
80272343Sngie#define BMBT_TOTAL_BITLEN	128	/* 128 bits, 16 bytes */
81272343Sngie#define BMBT_EXNTFLAG_BITOFF	63
82272343Sngie#define BMBT_EXNTFLAG_BITLEN	1
83272343Sngie#define BMBT_STARTOFF_BITOFF	(BMBT_EXNTFLAG_BITOFF - BMBT_STARTOFF_BITLEN)
84272343Sngie#define BMBT_STARTOFF_BITLEN	54
85272343Sngie#define BMBT_STARTBLOCK_BITOFF	85 /* 128 - 43 (other 9 is in first word) */
86272343Sngie#define BMBT_STARTBLOCK_BITLEN	52
87272343Sngie#define BMBT_BLOCKCOUNT_BITOFF	64 /* Start of second 64 bit container */
88272343Sngie#define BMBT_BLOCKCOUNT_BITLEN	21
89272343Sngie
90272343Sngie#endif
91272343Sngie
92272343Sngie
93272343Sngie#define BMBT_USE_64	1
94272343Sngie
95272343Sngietypedef struct xfs_bmbt_rec_32
96272343Sngie{
97272343Sngie	__uint32_t		l0, l1, l2, l3;
98272343Sngie} xfs_bmbt_rec_32_t;
99272343Sngietypedef struct xfs_bmbt_rec_64
100272343Sngie{
101272343Sngie	__uint64_t		l0, l1;
102272343Sngie} xfs_bmbt_rec_64_t;
103272343Sngie
104272343Sngietypedef __uint64_t	xfs_bmbt_rec_base_t;	/* use this for casts */
105272343Sngietypedef xfs_bmbt_rec_64_t xfs_bmbt_rec_t, xfs_bmdr_rec_t;
106272343Sngie
107272343Sngie/*
108272343Sngie * Values and macros for delayed-allocation startblock fields.
109272343Sngie */
110272343Sngie#define STARTBLOCKVALBITS	17
111272343Sngie#define STARTBLOCKMASKBITS	(15 + XFS_BIG_BLKNOS * 20)
112272343Sngie#define DSTARTBLOCKMASKBITS	(15 + 20)
113272343Sngie#define STARTBLOCKMASK		\
114272343Sngie	(((((xfs_fsblock_t)1) << STARTBLOCKMASKBITS) - 1) << STARTBLOCKVALBITS)
115272343Sngie#define DSTARTBLOCKMASK		\
116272343Sngie	(((((xfs_dfsbno_t)1) << DSTARTBLOCKMASKBITS) - 1) << STARTBLOCKVALBITS)
117272343Sngie
118272343Sngie#if XFS_WANT_FUNCS || XFS_WANT_FUNCS_C || (XFS_WANT_SPACE && XFSSO_ISNULLSTARTBLOCK)
119272343Sngieint isnullstartblock(xfs_fsblock_t x);
120272343Sngie#endif
121272343Sngie
122272343Sngie#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_ISNULLSTARTBLOCK)
123272343Sngie#define ISNULLSTARTBLOCK(x)	isnullstartblock(x)
124272343Sngie#else
125272343Sngie#define ISNULLSTARTBLOCK(x)	(((x) & STARTBLOCKMASK) == STARTBLOCKMASK)
126272343Sngie#endif
127272343Sngie
128272343Sngie#if XFS_WANT_FUNCS || XFS_WANT_FUNCS_C || (XFS_WANT_SPACE && XFSSO_ISNULLDSTARTBLOCK)
129272343Sngieint isnulldstartblock(xfs_dfsbno_t x);
130272343Sngie#endif
131272343Sngie
132272343Sngie#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_ISNULLDSTARTBLOCK)
133272343Sngie#define ISNULLDSTARTBLOCK(x)	isnulldstartblock(x)
134272343Sngie#else
135272343Sngie#define ISNULLDSTARTBLOCK(x)	(((x) & DSTARTBLOCKMASK) == DSTARTBLOCKMASK)
136272343Sngie#endif
137
138#if XFS_WANT_FUNCS || XFS_WANT_FUNCS_C || (XFS_WANT_SPACE && XFSSO_NULLSTARTBLOCK)
139xfs_fsblock_t nullstartblock(int k);
140#endif
141
142#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_NULLSTARTBLOCK)
143#define NULLSTARTBLOCK(k)	nullstartblock(k)
144#else
145#define NULLSTARTBLOCK(k)	\
146	((ASSERT(k < (1 << STARTBLOCKVALBITS))), (STARTBLOCKMASK | (k)))
147#endif
148
149#if XFS_WANT_FUNCS || XFS_WANT_FUNCS_C || (XFS_WANT_SPACE && XFSSO_STARTBLOCKVAL)
150xfs_filblks_t startblockval(xfs_fsblock_t x);
151#endif
152
153#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_STARTBLOCKVAL)
154#define STARTBLOCKVAL(x)	startblockval(x)
155#else
156#define STARTBLOCKVAL(x)	((xfs_filblks_t)((x) & ~STARTBLOCKMASK))
157#endif
158
159/*
160 * Possible extent formats.
161 */
162typedef enum {
163	XFS_EXTFMT_NOSTATE = 0,
164	XFS_EXTFMT_HASSTATE
165} xfs_exntfmt_t;
166
167/*
168 * Possible extent states.
169 */
170typedef enum {
171	XFS_EXT_NORM, XFS_EXT_UNWRITTEN,
172	XFS_EXT_DMAPI_OFFLINE
173} xfs_exntst_t;
174
175/*
176 * Extent state and extent format macros.
177 */
178#if XFS_WANT_FUNCS || XFS_WANT_FUNCS_C || (XFS_WANT_SPACE && XFSSO_XFS_EXTFMT_INODE )
179xfs_exntfmt_t xfs_extfmt_inode(struct xfs_inode *ip);
180#endif
181
182#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_EXTFMT_INODE )
183#define XFS_EXTFMT_INODE(x)	xfs_extfmt_inode(x)
184#else
185#define XFS_EXTFMT_INODE(x) \
186  (XFS_SB_VERSION_HASEXTFLGBIT(&((x)->i_mount->m_sb)) ? \
187	XFS_EXTFMT_HASSTATE : XFS_EXTFMT_NOSTATE)
188#endif
189#define ISUNWRITTEN(x)	((x)->br_state == XFS_EXT_UNWRITTEN)
190
191/*
192 * Incore version of above.
193 */
194typedef struct xfs_bmbt_irec
195{
196	xfs_fileoff_t	br_startoff;	/* starting file offset */
197	xfs_fsblock_t	br_startblock;	/* starting block number */
198	xfs_filblks_t	br_blockcount;	/* number of blocks */
199	xfs_exntst_t	br_state;	/* extent state */
200} xfs_bmbt_irec_t;
201
202/*
203 * Key structure for non-leaf levels of the tree.
204 */
205typedef struct xfs_bmbt_key
206{
207	xfs_dfiloff_t	br_startoff;	/* starting file offset */
208} xfs_bmbt_key_t, xfs_bmdr_key_t;
209
210typedef xfs_dfsbno_t xfs_bmbt_ptr_t, xfs_bmdr_ptr_t;	/* btree pointer type */
211					/* btree block header type */
212typedef struct xfs_btree_lblock xfs_bmbt_block_t;
213
214#if XFS_WANT_FUNCS || XFS_WANT_FUNCS_C || (XFS_WANT_SPACE && XFSSO_XFS_BUF_TO_BMBT_BLOCK)
215xfs_bmbt_block_t *xfs_buf_to_bmbt_block(struct xfs_buf *bp);
216#endif
217
218#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BUF_TO_BMBT_BLOCK)
219#define XFS_BUF_TO_BMBT_BLOCK(bp)		xfs_buf_to_bmbt_block(bp)
220#else
221#define XFS_BUF_TO_BMBT_BLOCK(bp) ((xfs_bmbt_block_t *)(XFS_BUF_PTR(bp)))
222#endif
223
224#if XFS_WANT_FUNCS || XFS_WANT_FUNCS_C || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_RBLOCK_DSIZE)
225int xfs_bmap_rblock_dsize(int lev, struct xfs_btree_cur *cur);
226#endif
227
228#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_RBLOCK_DSIZE)
229#define XFS_BMAP_RBLOCK_DSIZE(lev,cur)		xfs_bmap_rblock_dsize(lev,cur)
230#else
231#define XFS_BMAP_RBLOCK_DSIZE(lev,cur) ((cur)->bc_private.b.forksize)
232#endif
233
234#if XFS_WANT_FUNCS || XFS_WANT_FUNCS_C || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_RBLOCK_ISIZE)
235int xfs_bmap_rblock_isize(int lev, struct xfs_btree_cur *cur);
236#endif
237
238#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_RBLOCK_ISIZE)
239#define XFS_BMAP_RBLOCK_ISIZE(lev,cur)		xfs_bmap_rblock_isize(lev,cur)
240#else
241#define XFS_BMAP_RBLOCK_ISIZE(lev,cur) \
242	((int)XFS_IFORK_PTR((cur)->bc_private.b.ip, \
243			    (cur)->bc_private.b.whichfork)->if_broot_bytes)
244#endif
245
246#if XFS_WANT_FUNCS || XFS_WANT_FUNCS_C || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_IBLOCK_SIZE)
247int xfs_bmap_iblock_size(int lev, struct xfs_btree_cur *cur);
248#endif
249
250#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_IBLOCK_SIZE)
251#define XFS_BMAP_IBLOCK_SIZE(lev,cur)		xfs_bmap_iblock_size(lev,cur)
252#else
253#define XFS_BMAP_IBLOCK_SIZE(lev,cur) (1 << (cur)->bc_blocklog)
254#endif
255
256#if XFS_WANT_FUNCS || XFS_WANT_FUNCS_C || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BLOCK_DSIZE)
257int xfs_bmap_block_dsize(int lev, struct xfs_btree_cur *cur);
258#endif
259
260#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BLOCK_DSIZE)
261#define XFS_BMAP_BLOCK_DSIZE(lev,cur)		xfs_bmap_block_dsize(lev,cur)
262#else
263#define XFS_BMAP_BLOCK_DSIZE(lev,cur) \
264	((lev) == (cur)->bc_nlevels - 1 ? \
265		XFS_BMAP_RBLOCK_DSIZE(lev,cur) : \
266		XFS_BMAP_IBLOCK_SIZE(lev,cur))
267#endif
268
269#if XFS_WANT_FUNCS || XFS_WANT_FUNCS_C || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BLOCK_ISIZE)
270int xfs_bmap_block_isize(int lev, struct xfs_btree_cur *cur);
271#endif
272
273#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BLOCK_ISIZE)
274#define XFS_BMAP_BLOCK_ISIZE(lev,cur)		xfs_bmap_block_isize(lev,cur)
275#else
276#define XFS_BMAP_BLOCK_ISIZE(lev,cur) \
277	((lev) == (cur)->bc_nlevels - 1 ? \
278		XFS_BMAP_RBLOCK_ISIZE(lev,cur) : \
279		XFS_BMAP_IBLOCK_SIZE(lev,cur))
280#endif
281
282#if XFS_WANT_FUNCS || XFS_WANT_FUNCS_C || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BLOCK_DMAXRECS)
283int xfs_bmap_block_dmaxrecs(int lev, struct xfs_btree_cur *cur);
284#endif
285
286#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BLOCK_DMAXRECS)
287#define XFS_BMAP_BLOCK_DMAXRECS(lev,cur)	xfs_bmap_block_dmaxrecs(lev,cur)
288#else
289#define XFS_BMAP_BLOCK_DMAXRECS(lev,cur) \
290	((lev) == (cur)->bc_nlevels - 1 ? \
291		XFS_BTREE_BLOCK_MAXRECS(XFS_BMAP_RBLOCK_DSIZE(lev,cur), \
292			xfs_bmdr, (lev) == 0) : \
293		((cur)->bc_mp->m_bmap_dmxr[(lev) != 0]))
294#endif
295
296#if XFS_WANT_FUNCS || XFS_WANT_FUNCS_C || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BLOCK_IMAXRECS)
297int xfs_bmap_block_imaxrecs(int lev, struct xfs_btree_cur *cur);
298#endif
299
300#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BLOCK_IMAXRECS)
301#define XFS_BMAP_BLOCK_IMAXRECS(lev,cur)	xfs_bmap_block_imaxrecs(lev,cur)
302#else
303#define XFS_BMAP_BLOCK_IMAXRECS(lev,cur) \
304	((lev) == (cur)->bc_nlevels - 1 ? \
305		XFS_BTREE_BLOCK_MAXRECS(XFS_BMAP_RBLOCK_ISIZE(lev,cur), \
306			xfs_bmbt, (lev) == 0) : \
307		((cur)->bc_mp->m_bmap_dmxr[(lev) != 0]))
308#endif
309
310#if XFS_WANT_FUNCS || XFS_WANT_FUNCS_C || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BLOCK_DMINRECS)
311int xfs_bmap_block_dminrecs(int lev, struct xfs_btree_cur *cur);
312#endif
313
314#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BLOCK_DMINRECS)
315#define XFS_BMAP_BLOCK_DMINRECS(lev,cur)	xfs_bmap_block_dminrecs(lev,cur)
316#else
317#define XFS_BMAP_BLOCK_DMINRECS(lev,cur) \
318	((lev) == (cur)->bc_nlevels - 1 ? \
319		XFS_BTREE_BLOCK_MINRECS(XFS_BMAP_RBLOCK_DSIZE(lev,cur), \
320			xfs_bmdr, (lev) == 0) : \
321		((cur)->bc_mp->m_bmap_dmnr[(lev) != 0]))
322#endif
323
324#if XFS_WANT_FUNCS || XFS_WANT_FUNCS_C || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BLOCK_IMINRECS)
325int xfs_bmap_block_iminrecs(int lev, struct xfs_btree_cur *cur);
326#endif
327
328#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BLOCK_IMINRECS)
329#define XFS_BMAP_BLOCK_IMINRECS(lev,cur)	xfs_bmap_block_iminrecs(lev,cur)
330#else
331#define XFS_BMAP_BLOCK_IMINRECS(lev,cur) \
332	((lev) == (cur)->bc_nlevels - 1 ? \
333		XFS_BTREE_BLOCK_MINRECS(XFS_BMAP_RBLOCK_ISIZE(lev,cur), \
334			xfs_bmbt, (lev) == 0) : \
335		((cur)->bc_mp->m_bmap_dmnr[(lev) != 0]))
336#endif
337
338#if XFS_WANT_FUNCS || XFS_WANT_FUNCS_C || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_REC_DADDR)
339xfs_bmbt_rec_t *
340xfs_bmap_rec_daddr(xfs_bmbt_block_t *bb, int i, struct xfs_btree_cur *cur);
341#endif
342
343#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_REC_DADDR)
344#define XFS_BMAP_REC_DADDR(bb,i,cur)		xfs_bmap_rec_daddr(bb,i,cur)
345#else
346#define XFS_BMAP_REC_DADDR(bb,i,cur) \
347	XFS_BTREE_REC_ADDR(XFS_BMAP_BLOCK_DSIZE(		\
348		INT_GET((bb)->bb_level, ARCH_CONVERT), cur),	\
349		xfs_bmbt, bb, i, XFS_BMAP_BLOCK_DMAXRECS(	\
350			INT_GET((bb)->bb_level, ARCH_CONVERT), cur))
351#endif
352
353#if XFS_WANT_FUNCS || XFS_WANT_FUNCS_C || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_REC_IADDR)
354xfs_bmbt_rec_t *
355xfs_bmap_rec_iaddr(xfs_bmbt_block_t *bb, int i, struct xfs_btree_cur *cur);
356#endif
357
358#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_REC_IADDR)
359#define XFS_BMAP_REC_IADDR(bb,i,cur)		xfs_bmap_rec_iaddr(bb,i,cur)
360#else
361#define XFS_BMAP_REC_IADDR(bb,i,cur) \
362	XFS_BTREE_REC_ADDR(XFS_BMAP_BLOCK_ISIZE(		\
363		INT_GET((bb)->bb_level, ARCH_CONVERT), cur),	\
364		xfs_bmbt, bb, i, XFS_BMAP_BLOCK_IMAXRECS(	\
365			INT_GET((bb)->bb_level, ARCH_CONVERT), cur))
366#endif
367
368#if XFS_WANT_FUNCS || XFS_WANT_FUNCS_C || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_KEY_DADDR)
369xfs_bmbt_key_t *
370xfs_bmap_key_daddr(xfs_bmbt_block_t *bb, int i, struct xfs_btree_cur *cur);
371#endif
372
373#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_KEY_DADDR)
374#define XFS_BMAP_KEY_DADDR(bb,i,cur)		xfs_bmap_key_daddr(bb,i,cur)
375#else
376#define XFS_BMAP_KEY_DADDR(bb,i,cur) \
377	XFS_BTREE_KEY_ADDR(XFS_BMAP_BLOCK_DSIZE(		\
378		INT_GET((bb)->bb_level, ARCH_CONVERT), cur),	\
379		xfs_bmbt, bb, i, XFS_BMAP_BLOCK_DMAXRECS(	\
380			INT_GET((bb)->bb_level, ARCH_CONVERT), cur))
381#endif
382
383#if XFS_WANT_FUNCS || XFS_WANT_FUNCS_C || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_KEY_IADDR)
384xfs_bmbt_key_t *
385xfs_bmap_key_iaddr(xfs_bmbt_block_t *bb, int i, struct xfs_btree_cur *cur);
386#endif
387
388#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_KEY_IADDR)
389#define XFS_BMAP_KEY_IADDR(bb,i,cur)		xfs_bmap_key_iaddr(bb,i,cur)
390#else
391#define XFS_BMAP_KEY_IADDR(bb,i,cur) \
392	XFS_BTREE_KEY_ADDR(XFS_BMAP_BLOCK_ISIZE(		\
393		INT_GET((bb)->bb_level, ARCH_CONVERT), cur),	\
394		xfs_bmbt, bb, i, XFS_BMAP_BLOCK_IMAXRECS(	\
395			INT_GET((bb)->bb_level, ARCH_CONVERT), cur))
396#endif
397
398#if XFS_WANT_FUNCS || XFS_WANT_FUNCS_C || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_PTR_DADDR)
399xfs_bmbt_ptr_t *
400xfs_bmap_ptr_daddr(xfs_bmbt_block_t *bb, int i, struct xfs_btree_cur *cur);
401#endif
402
403#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_PTR_DADDR)
404#define XFS_BMAP_PTR_DADDR(bb,i,cur)		xfs_bmap_ptr_daddr(bb,i,cur)
405#else
406#define XFS_BMAP_PTR_DADDR(bb,i,cur) \
407	XFS_BTREE_PTR_ADDR(XFS_BMAP_BLOCK_DSIZE(		\
408		INT_GET((bb)->bb_level, ARCH_CONVERT), cur),	\
409		xfs_bmbt, bb, i, XFS_BMAP_BLOCK_DMAXRECS(	\
410			INT_GET((bb)->bb_level, ARCH_CONVERT), cur))
411#endif
412
413#if XFS_WANT_FUNCS || XFS_WANT_FUNCS_C || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_PTR_IADDR)
414xfs_bmbt_ptr_t *
415xfs_bmap_ptr_iaddr(xfs_bmbt_block_t *bb, int i, struct xfs_btree_cur *cur);
416#endif
417
418#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_PTR_IADDR)
419#define XFS_BMAP_PTR_IADDR(bb,i,cur)		xfs_bmap_ptr_iaddr(bb,i,cur)
420#else
421#define XFS_BMAP_PTR_IADDR(bb,i,cur) \
422	XFS_BTREE_PTR_ADDR(XFS_BMAP_BLOCK_ISIZE(		\
423		INT_GET((bb)->bb_level, ARCH_CONVERT), cur),	\
424		xfs_bmbt, bb, i, XFS_BMAP_BLOCK_IMAXRECS(	\
425			INT_GET((bb)->bb_level, ARCH_CONVERT), cur))
426#endif
427
428/*
429 * These are to be used when we know the size of the block and
430 * we don't have a cursor.
431 */
432#if XFS_WANT_FUNCS || XFS_WANT_FUNCS_C || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BROOT_REC_ADDR)
433xfs_bmbt_rec_t *xfs_bmap_broot_rec_addr(xfs_bmbt_block_t *bb, int i, int sz);
434#endif
435
436#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BROOT_REC_ADDR)
437#define XFS_BMAP_BROOT_REC_ADDR(bb,i,sz)	xfs_bmap_broot_rec_addr(bb,i,sz)
438#else
439#define XFS_BMAP_BROOT_REC_ADDR(bb,i,sz) \
440	XFS_BTREE_REC_ADDR(sz,xfs_bmbt,bb,i,XFS_BMAP_BROOT_MAXRECS(sz))
441#endif
442
443#if XFS_WANT_FUNCS || XFS_WANT_FUNCS_C || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BROOT_KEY_ADDR)
444xfs_bmbt_key_t *xfs_bmap_broot_key_addr(xfs_bmbt_block_t *bb, int i, int sz);
445#endif
446
447#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BROOT_KEY_ADDR)
448#define XFS_BMAP_BROOT_KEY_ADDR(bb,i,sz)	xfs_bmap_broot_key_addr(bb,i,sz)
449#else
450#define XFS_BMAP_BROOT_KEY_ADDR(bb,i,sz) \
451	XFS_BTREE_KEY_ADDR(sz,xfs_bmbt,bb,i,XFS_BMAP_BROOT_MAXRECS(sz))
452#endif
453
454#if XFS_WANT_FUNCS || XFS_WANT_FUNCS_C || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BROOT_PTR_ADDR)
455xfs_bmbt_ptr_t *xfs_bmap_broot_ptr_addr(xfs_bmbt_block_t *bb, int i, int sz);
456#endif
457
458#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BROOT_PTR_ADDR)
459#define XFS_BMAP_BROOT_PTR_ADDR(bb,i,sz)	xfs_bmap_broot_ptr_addr(bb,i,sz)
460#else
461#define XFS_BMAP_BROOT_PTR_ADDR(bb,i,sz) \
462	XFS_BTREE_PTR_ADDR(sz,xfs_bmbt,bb,i,XFS_BMAP_BROOT_MAXRECS(sz))
463#endif
464
465#if XFS_WANT_FUNCS || XFS_WANT_FUNCS_C || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BROOT_NUMRECS)
466int xfs_bmap_broot_numrecs(xfs_bmdr_block_t *bb);
467#endif
468
469#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BROOT_NUMRECS)
470#define XFS_BMAP_BROOT_NUMRECS(bb)		xfs_bmap_broot_numrecs(bb)
471#else
472#define XFS_BMAP_BROOT_NUMRECS(bb) (INT_GET((bb)->bb_numrecs, ARCH_CONVERT))
473#endif
474
475#if XFS_WANT_FUNCS || XFS_WANT_FUNCS_C || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BROOT_MAXRECS)
476int xfs_bmap_broot_maxrecs(int sz);
477#endif
478
479#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BROOT_MAXRECS)
480#define XFS_BMAP_BROOT_MAXRECS(sz)		xfs_bmap_broot_maxrecs(sz)
481#else
482#define XFS_BMAP_BROOT_MAXRECS(sz) XFS_BTREE_BLOCK_MAXRECS(sz,xfs_bmbt,0)
483#endif
484
485#if XFS_WANT_FUNCS || XFS_WANT_FUNCS_C || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BROOT_SPACE_CALC)
486int xfs_bmap_broot_space_calc(int nrecs);
487#endif
488
489#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BROOT_SPACE_CALC)
490#define XFS_BMAP_BROOT_SPACE_CALC(nrecs)	xfs_bmap_broot_space_calc(nrecs)
491#else
492#define XFS_BMAP_BROOT_SPACE_CALC(nrecs) \
493	((int)(sizeof(xfs_bmbt_block_t) + \
494	       ((nrecs) * (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t)))))
495#endif
496
497#if XFS_WANT_FUNCS || XFS_WANT_FUNCS_C || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BROOT_SPACE)
498int xfs_bmap_broot_space(xfs_bmdr_block_t *bb);
499#endif
500
501#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_BROOT_SPACE)
502#define XFS_BMAP_BROOT_SPACE(bb)		xfs_bmap_broot_space(bb)
503#else
504#define XFS_BMAP_BROOT_SPACE(bb) \
505	XFS_BMAP_BROOT_SPACE_CALC(INT_GET((bb)->bb_numrecs, ARCH_CONVERT))
506#endif
507
508#if XFS_WANT_FUNCS || XFS_WANT_FUNCS_C || (XFS_WANT_SPACE && XFSSO_XFS_BMDR_SPACE_CALC)
509int xfs_bmdr_space_calc(int nrecs);
510#endif
511
512#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMDR_SPACE_CALC)
513#define XFS_BMDR_SPACE_CALC(nrecs)		xfs_bmdr_space_calc(nrecs)
514#else
515#define XFS_BMDR_SPACE_CALC(nrecs)	\
516	((int)(sizeof(xfs_bmdr_block_t) + \
517	       ((nrecs) * (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t)))))
518#endif
519
520/*
521 * Maximum number of bmap btree levels.
522 */
523#if XFS_WANT_FUNCS || XFS_WANT_FUNCS_C || (XFS_WANT_SPACE && XFSSO_XFS_BM_MAXLEVELS)
524int xfs_bm_maxlevels(struct xfs_mount *mp, int w);
525#endif
526
527#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BM_MAXLEVELS)
528#define XFS_BM_MAXLEVELS(mp,w)			xfs_bm_maxlevels(mp,w)
529#else
530#define XFS_BM_MAXLEVELS(mp,w)		((mp)->m_bm_maxlevels[w])
531#endif
532
533#if XFS_WANT_FUNCS || XFS_WANT_FUNCS_C || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_SANITY_CHECK)
534int xfs_bmap_sanity_check(struct xfs_mount *mp, xfs_bmbt_block_t *bb,
535	int level);
536#endif
537
538#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_SANITY_CHECK)
539#define XFS_BMAP_SANITY_CHECK(mp,bb,level)	\
540	xfs_bmap_sanity_check(mp,bb,level)
541#else
542#define XFS_BMAP_SANITY_CHECK(mp,bb,level)	\
543	(INT_GET((bb)->bb_magic, ARCH_CONVERT) == XFS_BMAP_MAGIC && \
544	 INT_GET((bb)->bb_level, ARCH_CONVERT) == level && \
545	 INT_GET((bb)->bb_numrecs, ARCH_CONVERT) > 0 && \
546	 INT_GET((bb)->bb_numrecs, ARCH_CONVERT) <= (mp)->m_bmap_dmxr[(level) != 0])
547#endif
548
549
550#ifdef __KERNEL__
551
552#if defined(XFS_BMBT_TRACE)
553/*
554 * Trace buffer entry types.
555 */
556#define XFS_BMBT_KTRACE_ARGBI	1
557#define XFS_BMBT_KTRACE_ARGBII	2
558#define XFS_BMBT_KTRACE_ARGFFFI 3
559#define XFS_BMBT_KTRACE_ARGI	4
560#define XFS_BMBT_KTRACE_ARGIFK	5
561#define XFS_BMBT_KTRACE_ARGIFR	6
562#define XFS_BMBT_KTRACE_ARGIK	7
563#define XFS_BMBT_KTRACE_CUR	8
564
565#define XFS_BMBT_TRACE_SIZE	4096	/* size of global trace buffer */
566#define XFS_BMBT_KTRACE_SIZE	32	/* size of per-inode trace buffer */
567extern ktrace_t	*xfs_bmbt_trace_buf;
568#endif
569
570/*
571 * Prototypes for xfs_bmap.c to call.
572 */
573
574void
575xfs_bmdr_to_bmbt(
576	xfs_bmdr_block_t *,
577	int,
578	xfs_bmbt_block_t *,
579	int);
580
581int
582xfs_bmbt_decrement(
583	struct xfs_btree_cur *,
584	int,
585	int *);
586
587int
588xfs_bmbt_delete(
589	struct xfs_btree_cur *,
590	int *);
591
592void
593xfs_bmbt_get_all(
594	xfs_bmbt_rec_t	*r,
595	xfs_bmbt_irec_t *s);
596
597xfs_bmbt_block_t *
598xfs_bmbt_get_block(
599	struct xfs_btree_cur	*cur,
600	int			level,
601	struct xfs_buf		**bpp);
602
603xfs_filblks_t
604xfs_bmbt_get_blockcount(
605	xfs_bmbt_rec_t	*r);
606
607xfs_fsblock_t
608xfs_bmbt_get_startblock(
609	xfs_bmbt_rec_t	*r);
610
611xfs_fileoff_t
612xfs_bmbt_get_startoff(
613	xfs_bmbt_rec_t	*r);
614
615xfs_exntst_t
616xfs_bmbt_get_state(
617	xfs_bmbt_rec_t	*r);
618
619#if ARCH_CONVERT != ARCH_NOCONVERT
620void
621xfs_bmbt_disk_get_all(
622	xfs_bmbt_rec_t	*r,
623	xfs_bmbt_irec_t *s);
624
625xfs_exntst_t
626xfs_bmbt_disk_get_state(
627	xfs_bmbt_rec_t	*r);
628
629xfs_filblks_t
630xfs_bmbt_disk_get_blockcount(
631	xfs_bmbt_rec_t	*r);
632
633xfs_fsblock_t
634xfs_bmbt_disk_get_startblock(
635	xfs_bmbt_rec_t	*r);
636
637xfs_fileoff_t
638xfs_bmbt_disk_get_startoff(
639	xfs_bmbt_rec_t	*r);
640
641#else
642#define xfs_bmbt_disk_get_all(r, s) \
643	xfs_bmbt_get_all(r, s)
644#define xfs_bmbt_disk_get_state(r) \
645	xfs_bmbt_get_state(r)
646#define xfs_bmbt_disk_get_blockcount(r) \
647	xfs_bmbt_get_blockcount(r)
648#define xfs_bmbt_disk_get_startblock(r) \
649	xfs_bmbt_get_blockcount(r)
650#define xfs_bmbt_disk_get_startoff(r) \
651	xfs_bmbt_get_startoff(r)
652#endif
653
654int
655xfs_bmbt_increment(
656	struct xfs_btree_cur *,
657	int,
658	int *);
659
660int
661xfs_bmbt_insert(
662	struct xfs_btree_cur *,
663	int *);
664
665int
666xfs_bmbt_insert_many(
667	struct xfs_btree_cur *,
668	int,
669	xfs_bmbt_rec_t *,
670	int *);
671
672void
673xfs_bmbt_log_block(
674	struct xfs_btree_cur *,
675	struct xfs_buf *,
676	int);
677
678void
679xfs_bmbt_log_recs(
680	struct xfs_btree_cur *,
681	struct xfs_buf *,
682	int,
683	int);
684
685int
686xfs_bmbt_lookup_eq(
687	struct xfs_btree_cur *,
688	xfs_fileoff_t,
689	xfs_fsblock_t,
690	xfs_filblks_t,
691	int *);
692
693int
694xfs_bmbt_lookup_ge(
695	struct xfs_btree_cur *,
696	xfs_fileoff_t,
697	xfs_fsblock_t,
698	xfs_filblks_t,
699	int *);
700
701int
702xfs_bmbt_lookup_le(
703	struct xfs_btree_cur *,
704	xfs_fileoff_t,
705	xfs_fsblock_t,
706	xfs_filblks_t,
707	int *);
708
709/*
710 * Give the bmap btree a new root block.  Copy the old broot contents
711 * down into a real block and make the broot point to it.
712 */
713int						/* error */
714xfs_bmbt_newroot(
715	struct xfs_btree_cur	*cur,		/* btree cursor */
716	int			*logflags,	/* logging flags for inode */
717	int			*stat);		/* return status - 0 fail */
718
719void
720xfs_bmbt_set_all(
721	xfs_bmbt_rec_t	*r,
722	xfs_bmbt_irec_t *s);
723
724void
725xfs_bmbt_set_allf(
726	xfs_bmbt_rec_t	*r,
727	xfs_fileoff_t	o,
728	xfs_fsblock_t	b,
729	xfs_filblks_t	c,
730	xfs_exntst_t	v);
731
732void
733xfs_bmbt_set_blockcount(
734	xfs_bmbt_rec_t	*r,
735	xfs_filblks_t	v);
736
737void
738xfs_bmbt_set_startblock(
739	xfs_bmbt_rec_t	*r,
740	xfs_fsblock_t	v);
741
742void
743xfs_bmbt_set_startoff(
744	xfs_bmbt_rec_t	*r,
745	xfs_fileoff_t	v);
746
747void
748xfs_bmbt_set_state(
749	xfs_bmbt_rec_t	*r,
750	xfs_exntst_t	v);
751
752#if ARCH_CONVERT != ARCH_NOCONVERT
753void
754xfs_bmbt_disk_set_all(
755	xfs_bmbt_rec_t	*r,
756	xfs_bmbt_irec_t *s);
757
758void
759xfs_bmbt_disk_set_allf(
760	xfs_bmbt_rec_t	*r,
761	xfs_fileoff_t	o,
762	xfs_fsblock_t	b,
763	xfs_filblks_t	c,
764	xfs_exntst_t	v);
765#else
766#define xfs_bmbt_disk_set_all(r, s) \
767	xfs_bmbt_set_all(r, s)
768#define xfs_bmbt_disk_set_allf(r, o, b, c, v) \
769	xfs_bmbt_set_allf(r, o, b, c, v)
770#endif
771
772void
773xfs_bmbt_to_bmdr(
774	xfs_bmbt_block_t *,
775	int,
776	xfs_bmdr_block_t *,
777	int);
778
779int
780xfs_bmbt_update(
781	struct xfs_btree_cur *,
782	xfs_fileoff_t,
783	xfs_fsblock_t,
784	xfs_filblks_t,
785	xfs_exntst_t);
786
787#ifdef XFSDEBUG
788/*
789 * Get the data from the pointed-to record.
790 */
791int
792xfs_bmbt_get_rec(
793	struct xfs_btree_cur *,
794	xfs_fileoff_t *,
795	xfs_fsblock_t *,
796	xfs_filblks_t *,
797	xfs_exntst_t *,
798	int *);
799#endif
800
801
802/*
803 * Search an extent list for the extent which includes block
804 * bno.
805 */
806xfs_bmbt_rec_t *
807xfs_bmap_do_search_extents(
808	xfs_bmbt_rec_t *,
809	xfs_extnum_t,
810	xfs_extnum_t,
811	xfs_fileoff_t,
812	int *,
813	xfs_extnum_t *,
814	xfs_bmbt_irec_t *,
815	xfs_bmbt_irec_t *);
816
817#endif	/* __KERNEL__ */
818
819#endif	/* __XFS_BMAP_BTREE_H__ */
820