[XFS] Remove xfs_macros.c, xfs_macros.h, rework headers a whole lot.
[safe/jmp/linux-2.6] / fs / xfs / xfs_bmap_btree.h
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 #ifndef XFS_NATIVE_HOST
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 /* XFS_NATIVE_HOST */
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
118 #define ISNULLSTARTBLOCK(x)     isnullstartblock(x)
119 static inline int isnullstartblock(xfs_fsblock_t x)
120 {
121         return ((x) & STARTBLOCKMASK) == STARTBLOCKMASK;
122 }
123
124 #define ISNULLDSTARTBLOCK(x)    isnulldstartblock(x)
125 static inline int isnulldstartblock(xfs_dfsbno_t x)
126 {
127         return ((x) & DSTARTBLOCKMASK) == DSTARTBLOCKMASK;
128 }
129
130 #define NULLSTARTBLOCK(k)       nullstartblock(k)
131 static inline xfs_fsblock_t nullstartblock(int k)
132 {
133         ASSERT(k < (1 << STARTBLOCKVALBITS));
134         return STARTBLOCKMASK | (k);
135 }
136
137 #define STARTBLOCKVAL(x)        startblockval(x)
138 static inline xfs_filblks_t startblockval(xfs_fsblock_t x)
139 {
140         return (xfs_filblks_t)((x) & ~STARTBLOCKMASK);
141 }
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 #define XFS_EXTFMT_INODE(x)     \
163         (XFS_SB_VERSION_HASEXTFLGBIT(&((x)->i_mount->m_sb)) ? \
164                 XFS_EXTFMT_HASSTATE : XFS_EXTFMT_NOSTATE)
165 #define ISUNWRITTEN(x)  ((x)->br_state == XFS_EXT_UNWRITTEN)
166
167 /*
168  * Incore version of above.
169  */
170 typedef struct xfs_bmbt_irec
171 {
172         xfs_fileoff_t   br_startoff;    /* starting file offset */
173         xfs_fsblock_t   br_startblock;  /* starting block number */
174         xfs_filblks_t   br_blockcount;  /* number of blocks */
175         xfs_exntst_t    br_state;       /* extent state */
176 } xfs_bmbt_irec_t;
177
178 /*
179  * Key structure for non-leaf levels of the tree.
180  */
181 typedef struct xfs_bmbt_key
182 {
183         xfs_dfiloff_t   br_startoff;    /* starting file offset */
184 } xfs_bmbt_key_t, xfs_bmdr_key_t;
185
186 typedef xfs_dfsbno_t xfs_bmbt_ptr_t, xfs_bmdr_ptr_t;    /* btree pointer type */
187                                         /* btree block header type */
188 typedef struct xfs_btree_lblock xfs_bmbt_block_t;
189
190 #define XFS_BUF_TO_BMBT_BLOCK(bp)       ((xfs_bmbt_block_t *)XFS_BUF_PTR(bp))
191
192 #define XFS_BMAP_IBLOCK_SIZE(lev,cur)   (1 << (cur)->bc_blocklog)
193 #define XFS_BMAP_RBLOCK_DSIZE(lev,cur)  ((cur)->bc_private.b.forksize)
194 #define XFS_BMAP_RBLOCK_ISIZE(lev,cur)  \
195         ((int)XFS_IFORK_PTR((cur)->bc_private.b.ip, \
196                     (cur)->bc_private.b.whichfork)->if_broot_bytes)
197
198 #define XFS_BMAP_BLOCK_DSIZE(lev,cur)   \
199         (((lev) == (cur)->bc_nlevels - 1 ? \
200                 XFS_BMAP_RBLOCK_DSIZE(lev,cur) : XFS_BMAP_IBLOCK_SIZE(lev,cur)))
201 #define XFS_BMAP_BLOCK_ISIZE(lev,cur)   \
202         (((lev) == (cur)->bc_nlevels - 1 ? \
203                 XFS_BMAP_RBLOCK_ISIZE(lev,cur) : XFS_BMAP_IBLOCK_SIZE(lev,cur)))
204
205 #define XFS_BMAP_BLOCK_DMAXRECS(lev,cur) \
206         (((lev) == (cur)->bc_nlevels - 1 ? \
207                 XFS_BTREE_BLOCK_MAXRECS(XFS_BMAP_RBLOCK_DSIZE(lev,cur), \
208                         xfs_bmdr, (lev) == 0) : \
209                 ((cur)->bc_mp->m_bmap_dmxr[(lev) != 0])))
210 #define XFS_BMAP_BLOCK_IMAXRECS(lev,cur) \
211         (((lev) == (cur)->bc_nlevels - 1 ? \
212                         XFS_BTREE_BLOCK_MAXRECS(XFS_BMAP_RBLOCK_ISIZE(lev,cur),\
213                                 xfs_bmbt, (lev) == 0) : \
214                         ((cur)->bc_mp->m_bmap_dmxr[(lev) != 0])))
215
216 #define XFS_BMAP_BLOCK_DMINRECS(lev,cur) \
217         (((lev) == (cur)->bc_nlevels - 1 ? \
218                         XFS_BTREE_BLOCK_MINRECS(XFS_BMAP_RBLOCK_DSIZE(lev,cur),\
219                                 xfs_bmdr, (lev) == 0) : \
220                         ((cur)->bc_mp->m_bmap_dmnr[(lev) != 0])))
221 #define XFS_BMAP_BLOCK_IMINRECS(lev,cur) \
222         (((lev) == (cur)->bc_nlevels - 1 ? \
223                         XFS_BTREE_BLOCK_MINRECS(XFS_BMAP_RBLOCK_ISIZE(lev,cur),\
224                                 xfs_bmbt, (lev) == 0) : \
225                         ((cur)->bc_mp->m_bmap_dmnr[(lev) != 0])))
226
227 #define XFS_BMAP_REC_DADDR(bb,i,cur)    \
228         (XFS_BTREE_REC_ADDR(XFS_BMAP_BLOCK_DSIZE(                       \
229                         INT_GET((bb)->bb_level, ARCH_CONVERT), cur),    \
230                         xfs_bmbt, bb, i, XFS_BMAP_BLOCK_DMAXRECS(       \
231                                 INT_GET((bb)->bb_level, ARCH_CONVERT), cur)))
232 #define XFS_BMAP_REC_IADDR(bb,i,cur)    \
233         (XFS_BTREE_REC_ADDR(XFS_BMAP_BLOCK_ISIZE(                       \
234                         INT_GET((bb)->bb_level, ARCH_CONVERT), cur),    \
235                         xfs_bmbt, bb, i, XFS_BMAP_BLOCK_IMAXRECS(       \
236                                 INT_GET((bb)->bb_level, ARCH_CONVERT), cur)))
237
238 #define XFS_BMAP_KEY_DADDR(bb,i,cur)    \
239         (XFS_BTREE_KEY_ADDR(XFS_BMAP_BLOCK_DSIZE(                       \
240                         INT_GET((bb)->bb_level, ARCH_CONVERT), cur),    \
241                         xfs_bmbt, bb, i, XFS_BMAP_BLOCK_DMAXRECS(       \
242                                 INT_GET((bb)->bb_level, ARCH_CONVERT), cur)))
243 #define XFS_BMAP_KEY_IADDR(bb,i,cur)    \
244         (XFS_BTREE_KEY_ADDR(XFS_BMAP_BLOCK_ISIZE(                       \
245                         INT_GET((bb)->bb_level, ARCH_CONVERT), cur),    \
246                         xfs_bmbt, bb, i, XFS_BMAP_BLOCK_IMAXRECS(       \
247                                 INT_GET((bb)->bb_level, ARCH_CONVERT), cur)))
248
249 #define XFS_BMAP_PTR_DADDR(bb,i,cur)    \
250         (XFS_BTREE_PTR_ADDR(XFS_BMAP_BLOCK_DSIZE(                       \
251                         INT_GET((bb)->bb_level, ARCH_CONVERT), cur),    \
252                         xfs_bmbt, bb, i, XFS_BMAP_BLOCK_DMAXRECS(       \
253                                 INT_GET((bb)->bb_level, ARCH_CONVERT), cur)))
254 #define XFS_BMAP_PTR_IADDR(bb,i,cur)    \
255         (XFS_BTREE_PTR_ADDR(XFS_BMAP_BLOCK_ISIZE(                       \
256                         INT_GET((bb)->bb_level, ARCH_CONVERT), cur),    \
257                         xfs_bmbt, bb, i, XFS_BMAP_BLOCK_IMAXRECS(       \
258                                 INT_GET((bb)->bb_level, ARCH_CONVERT), cur)))
259
260 /*
261  * These are to be used when we know the size of the block and
262  * we don't have a cursor.
263  */
264 #define XFS_BMAP_BROOT_REC_ADDR(bb,i,sz) \
265         (XFS_BTREE_REC_ADDR(sz,xfs_bmbt,bb,i,XFS_BMAP_BROOT_MAXRECS(sz)))
266 #define XFS_BMAP_BROOT_KEY_ADDR(bb,i,sz) \
267         (XFS_BTREE_KEY_ADDR(sz,xfs_bmbt,bb,i,XFS_BMAP_BROOT_MAXRECS(sz)))
268 #define XFS_BMAP_BROOT_PTR_ADDR(bb,i,sz) \
269         (XFS_BTREE_PTR_ADDR(sz,xfs_bmbt,bb,i,XFS_BMAP_BROOT_MAXRECS(sz)))
270
271 #define XFS_BMAP_BROOT_NUMRECS(bb)      INT_GET((bb)->bb_numrecs, ARCH_CONVERT)
272 #define XFS_BMAP_BROOT_MAXRECS(sz)      XFS_BTREE_BLOCK_MAXRECS(sz,xfs_bmbt,0)
273
274 #define XFS_BMAP_BROOT_SPACE_CALC(nrecs) \
275         (int)(sizeof(xfs_bmbt_block_t) + \
276                ((nrecs) * (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t))))
277
278 #define XFS_BMAP_BROOT_SPACE(bb) \
279         (XFS_BMAP_BROOT_SPACE_CALC(INT_GET((bb)->bb_numrecs, ARCH_CONVERT)))
280 #define XFS_BMDR_SPACE_CALC(nrecs) \
281         (int)(sizeof(xfs_bmdr_block_t) + \
282                ((nrecs) * (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t))))
283
284 /*
285  * Maximum number of bmap btree levels.
286  */
287 #define XFS_BM_MAXLEVELS(mp,w)          ((mp)->m_bm_maxlevels[(w)])
288
289 #define XFS_BMAP_SANITY_CHECK(mp,bb,level) \
290         (INT_GET((bb)->bb_magic, ARCH_CONVERT) == XFS_BMAP_MAGIC && \
291          INT_GET((bb)->bb_level, ARCH_CONVERT) == level && \
292          INT_GET((bb)->bb_numrecs, ARCH_CONVERT) > 0 && \
293          INT_GET((bb)->bb_numrecs, ARCH_CONVERT) <= \
294                          (mp)->m_bmap_dmxr[(level) != 0])
295
296
297 #ifdef __KERNEL__
298
299 #if defined(XFS_BMBT_TRACE)
300 /*
301  * Trace buffer entry types.
302  */
303 #define XFS_BMBT_KTRACE_ARGBI   1
304 #define XFS_BMBT_KTRACE_ARGBII  2
305 #define XFS_BMBT_KTRACE_ARGFFFI 3
306 #define XFS_BMBT_KTRACE_ARGI    4
307 #define XFS_BMBT_KTRACE_ARGIFK  5
308 #define XFS_BMBT_KTRACE_ARGIFR  6
309 #define XFS_BMBT_KTRACE_ARGIK   7
310 #define XFS_BMBT_KTRACE_CUR     8
311
312 #define XFS_BMBT_TRACE_SIZE     4096    /* size of global trace buffer */
313 #define XFS_BMBT_KTRACE_SIZE    32      /* size of per-inode trace buffer */
314 extern ktrace_t *xfs_bmbt_trace_buf;
315 #endif
316
317 /*
318  * Prototypes for xfs_bmap.c to call.
319  */
320 extern void xfs_bmdr_to_bmbt(xfs_bmdr_block_t *, int, xfs_bmbt_block_t *, int);
321 extern int xfs_bmbt_decrement(struct xfs_btree_cur *, int, int *);
322 extern int xfs_bmbt_delete(struct xfs_btree_cur *, int *);
323 extern void xfs_bmbt_get_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s);
324 extern xfs_bmbt_block_t *xfs_bmbt_get_block(struct xfs_btree_cur *cur,
325                                                 int, struct xfs_buf **bpp);
326 extern xfs_filblks_t xfs_bmbt_get_blockcount(xfs_bmbt_rec_t *r);
327 extern xfs_fsblock_t xfs_bmbt_get_startblock(xfs_bmbt_rec_t *r);
328 extern xfs_fileoff_t xfs_bmbt_get_startoff(xfs_bmbt_rec_t *r);
329 extern xfs_exntst_t xfs_bmbt_get_state(xfs_bmbt_rec_t *r);
330
331 #ifndef XFS_NATIVE_HOST
332 extern void xfs_bmbt_disk_get_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s);
333 extern xfs_exntst_t xfs_bmbt_disk_get_state(xfs_bmbt_rec_t *r);
334 extern xfs_filblks_t xfs_bmbt_disk_get_blockcount(xfs_bmbt_rec_t *r);
335 extern xfs_fsblock_t xfs_bmbt_disk_get_startblock(xfs_bmbt_rec_t *r);
336 extern xfs_fileoff_t xfs_bmbt_disk_get_startoff(xfs_bmbt_rec_t *r);
337 #else
338 #define xfs_bmbt_disk_get_all(r, s)     xfs_bmbt_get_all(r, s)
339 #define xfs_bmbt_disk_get_state(r)      xfs_bmbt_get_state(r)
340 #define xfs_bmbt_disk_get_blockcount(r) xfs_bmbt_get_blockcount(r)
341 #define xfs_bmbt_disk_get_startblock(r) xfs_bmbt_get_blockcount(r)
342 #define xfs_bmbt_disk_get_startoff(r)   xfs_bmbt_get_startoff(r)
343 #endif /* XFS_NATIVE_HOST */
344
345 extern int xfs_bmbt_increment(struct xfs_btree_cur *, int, int *);
346 extern int xfs_bmbt_insert(struct xfs_btree_cur *, int *);
347 extern void xfs_bmbt_log_block(struct xfs_btree_cur *, struct xfs_buf *, int);
348 extern void xfs_bmbt_log_recs(struct xfs_btree_cur *, struct xfs_buf *, int,
349                                 int);
350 extern int xfs_bmbt_lookup_eq(struct xfs_btree_cur *, xfs_fileoff_t,
351                                 xfs_fsblock_t, xfs_filblks_t, int *);
352 extern int xfs_bmbt_lookup_ge(struct xfs_btree_cur *, xfs_fileoff_t,
353                                 xfs_fsblock_t, xfs_filblks_t, int *);
354
355 /*
356  * Give the bmap btree a new root block.  Copy the old broot contents
357  * down into a real block and make the broot point to it.
358  */
359 extern int xfs_bmbt_newroot(struct xfs_btree_cur *cur, int *lflags, int *stat);
360
361 extern void xfs_bmbt_set_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s);
362 extern void xfs_bmbt_set_allf(xfs_bmbt_rec_t *r, xfs_fileoff_t o,
363                         xfs_fsblock_t b, xfs_filblks_t c, xfs_exntst_t v);
364 extern void xfs_bmbt_set_blockcount(xfs_bmbt_rec_t *r, xfs_filblks_t v);
365 extern void xfs_bmbt_set_startblock(xfs_bmbt_rec_t *r, xfs_fsblock_t v);
366 extern void xfs_bmbt_set_startoff(xfs_bmbt_rec_t *r, xfs_fileoff_t v);
367 extern void xfs_bmbt_set_state(xfs_bmbt_rec_t *r, xfs_exntst_t v);
368
369 #ifndef XFS_NATIVE_HOST
370 extern void xfs_bmbt_disk_set_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s);
371 extern void xfs_bmbt_disk_set_allf(xfs_bmbt_rec_t *r, xfs_fileoff_t o,
372                         xfs_fsblock_t b, xfs_filblks_t c, xfs_exntst_t v);
373 #else
374 #define xfs_bmbt_disk_set_all(r, s)             xfs_bmbt_set_all(r, s)
375 #define xfs_bmbt_disk_set_allf(r, o, b, c, v)   xfs_bmbt_set_allf(r, o, b, c, v)
376 #endif /* XFS_NATIVE_HOST */
377
378 extern void xfs_bmbt_to_bmdr(xfs_bmbt_block_t *, int, xfs_bmdr_block_t *, int);
379 extern int xfs_bmbt_update(struct xfs_btree_cur *, xfs_fileoff_t,
380                                 xfs_fsblock_t, xfs_filblks_t, xfs_exntst_t);
381
382 #ifdef DEBUG
383 /*
384  * Get the data from the pointed-to record.
385  */
386 extern int xfs_bmbt_get_rec(struct xfs_btree_cur *, xfs_fileoff_t *,
387                                 xfs_fsblock_t *, xfs_filblks_t *,
388                                 xfs_exntst_t *, int *);
389 #endif
390
391 /*
392  * Search an extent list for the extent which includes block
393  * bno.
394  */
395 xfs_bmbt_rec_t *xfs_bmap_do_search_extents(xfs_bmbt_rec_t *,
396                         xfs_extnum_t, xfs_extnum_t, xfs_fileoff_t, int *,
397                         xfs_extnum_t *, xfs_bmbt_irec_t *, xfs_bmbt_irec_t *);
398
399 #endif  /* __KERNEL__ */
400
401 #endif  /* __XFS_BMAP_BTREE_H__ */