blob: 843ff12b4bf22307d6f5db24b64051c3efaef7b1 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
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
37struct xfs_btree_cur;
38struct xfs_btree_lblock;
39struct xfs_mount;
40struct xfs_inode;
41
42/*
43 * Bmap root header, on-disk form only.
44 */
45typedef 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
95typedef struct xfs_bmbt_rec_32
96{
97 __uint32_t l0, l1, l2, l3;
98} xfs_bmbt_rec_32_t;
99typedef struct xfs_bmbt_rec_64
100{
101 __uint64_t l0, l1;
102} xfs_bmbt_rec_64_t;
103
104typedef __uint64_t xfs_bmbt_rec_base_t; /* use this for casts */
105typedef 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)
118int 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)
124int 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)
130xfs_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)
137xfs_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 */
146typedef enum {
147 XFS_EXTFMT_NOSTATE = 0,
148 XFS_EXTFMT_HASSTATE
149} xfs_exntfmt_t;
150
151/*
152 * Possible extent states.
153 */
154typedef 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 )
163xfs_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 */
175typedef 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 */
186typedef struct xfs_bmbt_key
187{
188 xfs_dfiloff_t br_startoff; /* starting file offset */
189} xfs_bmbt_key_t, xfs_bmdr_key_t;
190
191typedef xfs_dfsbno_t xfs_bmbt_ptr_t, xfs_bmdr_ptr_t; /* btree pointer type */
192 /* btree block header type */
193typedef struct xfs_btree_lblock xfs_bmbt_block_t;
194
195#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BUF_TO_BMBT_BLOCK)
196xfs_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)
203int 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)
209int 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)
217int 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)
224int 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)
233int 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)
243int 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)
253int 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)
264int 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)
274int 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)
285xfs_bmbt_rec_t *
286xfs_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)
296xfs_bmbt_rec_t *
297xfs_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)
308xfs_bmbt_key_t *
309xfs_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)
319xfs_bmbt_key_t *
320xfs_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)
331xfs_bmbt_ptr_t *
332xfs_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)
342xfs_bmbt_ptr_t *
343xfs_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)
358xfs_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)
365xfs_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)
372xfs_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)
380int 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)
386int 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)
392int 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)
400int 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)
407int 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)
419int 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)
426int 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 */
456extern ktrace_t *xfs_bmbt_trace_buf;
457#endif
458
459/*
460 * Prototypes for xfs_bmap.c to call.
461 */
462
463void
464xfs_bmdr_to_bmbt(
465 xfs_bmdr_block_t *,
466 int,
467 xfs_bmbt_block_t *,
468 int);
469
470int
471xfs_bmbt_decrement(
472 struct xfs_btree_cur *,
473 int,
474 int *);
475
476int
477xfs_bmbt_delete(
478 struct xfs_btree_cur *,
479 int *);
480
481void
482xfs_bmbt_get_all(
483 xfs_bmbt_rec_t *r,
484 xfs_bmbt_irec_t *s);
485
486xfs_bmbt_block_t *
487xfs_bmbt_get_block(
488 struct xfs_btree_cur *cur,
489 int level,
490 struct xfs_buf **bpp);
491
492xfs_filblks_t
493xfs_bmbt_get_blockcount(
494 xfs_bmbt_rec_t *r);
495
496xfs_fsblock_t
497xfs_bmbt_get_startblock(
498 xfs_bmbt_rec_t *r);
499
500xfs_fileoff_t
501xfs_bmbt_get_startoff(
502 xfs_bmbt_rec_t *r);
503
504xfs_exntst_t
505xfs_bmbt_get_state(
506 xfs_bmbt_rec_t *r);
507
508#if __BYTE_ORDER != __BIG_ENDIAN
509void
510xfs_bmbt_disk_get_all(
511 xfs_bmbt_rec_t *r,
512 xfs_bmbt_irec_t *s);
513
514xfs_exntst_t
515xfs_bmbt_disk_get_state(
516 xfs_bmbt_rec_t *r);
517
518xfs_filblks_t
519xfs_bmbt_disk_get_blockcount(
520 xfs_bmbt_rec_t *r);
521
522xfs_fsblock_t
523xfs_bmbt_disk_get_startblock(
524 xfs_bmbt_rec_t *r);
525
526xfs_fileoff_t
527xfs_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
543int
544xfs_bmbt_increment(
545 struct xfs_btree_cur *,
546 int,
547 int *);
548
549int
550xfs_bmbt_insert(
551 struct xfs_btree_cur *,
552 int *);
553
554void
555xfs_bmbt_log_block(
556 struct xfs_btree_cur *,
557 struct xfs_buf *,
558 int);
559
560void
561xfs_bmbt_log_recs(
562 struct xfs_btree_cur *,
563 struct xfs_buf *,
564 int,
565 int);
566
567int
568xfs_bmbt_lookup_eq(
569 struct xfs_btree_cur *,
570 xfs_fileoff_t,
571 xfs_fsblock_t,
572 xfs_filblks_t,
573 int *);
574
575int
576xfs_bmbt_lookup_ge(
577 struct xfs_btree_cur *,
578 xfs_fileoff_t,
579 xfs_fsblock_t,
580 xfs_filblks_t,
581 int *);
582
583int
584xfs_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 */
595int /* error */
596xfs_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
601void
602xfs_bmbt_set_all(
603 xfs_bmbt_rec_t *r,
604 xfs_bmbt_irec_t *s);
605
606void
607xfs_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
614void
615xfs_bmbt_set_blockcount(
616 xfs_bmbt_rec_t *r,
617 xfs_filblks_t v);
618
619void
620xfs_bmbt_set_startblock(
621 xfs_bmbt_rec_t *r,
622 xfs_fsblock_t v);
623
624void
625xfs_bmbt_set_startoff(
626 xfs_bmbt_rec_t *r,
627 xfs_fileoff_t v);
628
629void
630xfs_bmbt_set_state(
631 xfs_bmbt_rec_t *r,
632 xfs_exntst_t v);
633
634#if __BYTE_ORDER != __BIG_ENDIAN
635void
636xfs_bmbt_disk_set_all(
637 xfs_bmbt_rec_t *r,
638 xfs_bmbt_irec_t *s);
639
640void
641xfs_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
654void
655xfs_bmbt_to_bmdr(
656 xfs_bmbt_block_t *,
657 int,
658 xfs_bmdr_block_t *,
659 int);
660
661int
662xfs_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 */
673int
674xfs_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 */
688xfs_bmbt_rec_t *
689xfs_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__ */