[XFS] cleanup btree record / key / ptr addressing macros.
[safe/jmp/linux-2.6] / fs / xfs / xfs_bmap_btree.h
1 /*
2  * Copyright (c) 2000,2002-2005 Silicon Graphics, Inc.
3  * All Rights Reserved.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it would be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write the Free Software Foundation,
16  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18 #ifndef __XFS_BMAP_BTREE_H__
19 #define __XFS_BMAP_BTREE_H__
20
21 #define XFS_BMAP_MAGIC  0x424d4150      /* 'BMAP' */
22
23 struct xfs_btree_cur;
24 struct xfs_btree_block;
25 struct xfs_btree_lblock;
26 struct xfs_mount;
27 struct xfs_inode;
28 struct xfs_trans;
29
30 /*
31  * Bmap root header, on-disk form only.
32  */
33 typedef struct xfs_bmdr_block {
34         __be16          bb_level;       /* 0 is a leaf */
35         __be16          bb_numrecs;     /* current # of data records */
36 } xfs_bmdr_block_t;
37
38 /*
39  * Bmap btree record and extent descriptor.
40  *  l0:63 is an extent flag (value 1 indicates non-normal).
41  *  l0:9-62 are startoff.
42  *  l0:0-8 and l1:21-63 are startblock.
43  *  l1:0-20 are blockcount.
44  */
45 #define BMBT_EXNTFLAG_BITLEN    1
46 #define BMBT_STARTOFF_BITLEN    54
47 #define BMBT_STARTBLOCK_BITLEN  52
48 #define BMBT_BLOCKCOUNT_BITLEN  21
49
50
51 #define BMBT_USE_64     1
52
53 typedef struct xfs_bmbt_rec_32
54 {
55         __uint32_t              l0, l1, l2, l3;
56 } xfs_bmbt_rec_32_t;
57 typedef struct xfs_bmbt_rec_64
58 {
59         __be64                  l0, l1;
60 } xfs_bmbt_rec_64_t;
61
62 typedef __uint64_t      xfs_bmbt_rec_base_t;    /* use this for casts */
63 typedef xfs_bmbt_rec_64_t xfs_bmbt_rec_t, xfs_bmdr_rec_t;
64
65 typedef struct xfs_bmbt_rec_host {
66         __uint64_t              l0, l1;
67 } xfs_bmbt_rec_host_t;
68
69 /*
70  * Values and macros for delayed-allocation startblock fields.
71  */
72 #define STARTBLOCKVALBITS       17
73 #define STARTBLOCKMASKBITS      (15 + XFS_BIG_BLKNOS * 20)
74 #define DSTARTBLOCKMASKBITS     (15 + 20)
75 #define STARTBLOCKMASK          \
76         (((((xfs_fsblock_t)1) << STARTBLOCKMASKBITS) - 1) << STARTBLOCKVALBITS)
77 #define DSTARTBLOCKMASK         \
78         (((((xfs_dfsbno_t)1) << DSTARTBLOCKMASKBITS) - 1) << STARTBLOCKVALBITS)
79
80 #define ISNULLSTARTBLOCK(x)     isnullstartblock(x)
81 static inline int isnullstartblock(xfs_fsblock_t x)
82 {
83         return ((x) & STARTBLOCKMASK) == STARTBLOCKMASK;
84 }
85
86 #define ISNULLDSTARTBLOCK(x)    isnulldstartblock(x)
87 static inline int isnulldstartblock(xfs_dfsbno_t x)
88 {
89         return ((x) & DSTARTBLOCKMASK) == DSTARTBLOCKMASK;
90 }
91
92 #define NULLSTARTBLOCK(k)       nullstartblock(k)
93 static inline xfs_fsblock_t nullstartblock(int k)
94 {
95         ASSERT(k < (1 << STARTBLOCKVALBITS));
96         return STARTBLOCKMASK | (k);
97 }
98
99 #define STARTBLOCKVAL(x)        startblockval(x)
100 static inline xfs_filblks_t startblockval(xfs_fsblock_t x)
101 {
102         return (xfs_filblks_t)((x) & ~STARTBLOCKMASK);
103 }
104
105 /*
106  * Possible extent formats.
107  */
108 typedef enum {
109         XFS_EXTFMT_NOSTATE = 0,
110         XFS_EXTFMT_HASSTATE
111 } xfs_exntfmt_t;
112
113 /*
114  * Possible extent states.
115  */
116 typedef enum {
117         XFS_EXT_NORM, XFS_EXT_UNWRITTEN,
118         XFS_EXT_DMAPI_OFFLINE, XFS_EXT_INVALID
119 } xfs_exntst_t;
120
121 /*
122  * Extent state and extent format macros.
123  */
124 #define XFS_EXTFMT_INODE(x)     \
125         (xfs_sb_version_hasextflgbit(&((x)->i_mount->m_sb)) ? \
126                 XFS_EXTFMT_HASSTATE : XFS_EXTFMT_NOSTATE)
127 #define ISUNWRITTEN(x)  ((x)->br_state == XFS_EXT_UNWRITTEN)
128
129 /*
130  * Incore version of above.
131  */
132 typedef struct xfs_bmbt_irec
133 {
134         xfs_fileoff_t   br_startoff;    /* starting file offset */
135         xfs_fsblock_t   br_startblock;  /* starting block number */
136         xfs_filblks_t   br_blockcount;  /* number of blocks */
137         xfs_exntst_t    br_state;       /* extent state */
138 } xfs_bmbt_irec_t;
139
140 /*
141  * Key structure for non-leaf levels of the tree.
142  */
143 typedef struct xfs_bmbt_key {
144         __be64          br_startoff;    /* starting file offset */
145 } xfs_bmbt_key_t, xfs_bmdr_key_t;
146
147 /* btree pointer type */
148 typedef __be64 xfs_bmbt_ptr_t, xfs_bmdr_ptr_t;
149
150 /* btree block header type */
151 typedef struct xfs_btree_lblock xfs_bmbt_block_t;
152
153 #define XFS_BUF_TO_BMBT_BLOCK(bp)       ((xfs_bmbt_block_t *)XFS_BUF_PTR(bp))
154
155 #define XFS_BMBT_REC_ADDR(mp, block, index) \
156         ((xfs_bmbt_rec_t *) \
157                 ((char *)(block) + \
158                  sizeof(struct xfs_btree_lblock) + \
159                  ((index) - 1) * sizeof(xfs_bmbt_rec_t)))
160
161 #define XFS_BMBT_KEY_ADDR(mp, block, index) \
162         ((xfs_bmbt_key_t *) \
163                 ((char *)(block) + \
164                  sizeof(struct xfs_btree_lblock) + \
165                  ((index) - 1) * sizeof(xfs_bmbt_key_t)))
166
167 #define XFS_BMBT_PTR_ADDR(mp, block, index, maxrecs) \
168         ((xfs_bmbt_ptr_t *) \
169                 ((char *)(block) + \
170                  sizeof(struct xfs_btree_lblock) + \
171                  (maxrecs) * sizeof(xfs_bmbt_key_t) + \
172                  ((index) - 1) * sizeof(xfs_bmbt_ptr_t)))
173
174 #define XFS_BMDR_REC_ADDR(block, index) \
175         ((xfs_bmdr_rec_t *) \
176                 ((char *)(block) + \
177                  sizeof(struct xfs_bmdr_block) + \
178                  ((index) - 1) * sizeof(xfs_bmdr_rec_t)))
179
180 #define XFS_BMDR_KEY_ADDR(block, index) \
181         ((xfs_bmdr_key_t *) \
182                 ((char *)(block) + \
183                  sizeof(struct xfs_bmdr_block) + \
184                  ((index) - 1) * sizeof(xfs_bmdr_key_t)))
185
186 #define XFS_BMDR_PTR_ADDR(block, index, maxrecs) \
187         ((xfs_bmdr_ptr_t *) \
188                 ((char *)(block) + \
189                  sizeof(struct xfs_bmdr_block) + \
190                  (maxrecs) * sizeof(xfs_bmdr_key_t) + \
191                  ((index) - 1) * sizeof(xfs_bmdr_ptr_t)))
192
193 /*
194  * These are to be used when we know the size of the block and
195  * we don't have a cursor.
196  */
197 #define XFS_BMAP_BROOT_PTR_ADDR(mp, bb, i, sz) \
198         XFS_BMBT_PTR_ADDR(mp, bb, i, xfs_bmbt_maxrecs(mp, sz, 0))
199
200 #define XFS_BMAP_BROOT_SPACE_CALC(nrecs) \
201         (int)(sizeof(xfs_bmbt_block_t) + \
202                ((nrecs) * (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t))))
203
204 #define XFS_BMAP_BROOT_SPACE(bb) \
205         (XFS_BMAP_BROOT_SPACE_CALC(be16_to_cpu((bb)->bb_numrecs)))
206 #define XFS_BMDR_SPACE_CALC(nrecs) \
207         (int)(sizeof(xfs_bmdr_block_t) + \
208                ((nrecs) * (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t))))
209
210 /*
211  * Maximum number of bmap btree levels.
212  */
213 #define XFS_BM_MAXLEVELS(mp,w)          ((mp)->m_bm_maxlevels[(w)])
214
215 #define XFS_BMAP_SANITY_CHECK(mp,bb,level) \
216         (be32_to_cpu((bb)->bb_magic) == XFS_BMAP_MAGIC && \
217          be16_to_cpu((bb)->bb_level) == level && \
218          be16_to_cpu((bb)->bb_numrecs) > 0 && \
219          be16_to_cpu((bb)->bb_numrecs) <= (mp)->m_bmap_dmxr[(level) != 0])
220
221
222 /*
223  * Prototypes for xfs_bmap.c to call.
224  */
225 extern void xfs_bmdr_to_bmbt(struct xfs_mount *, xfs_bmdr_block_t *, int,
226                         xfs_bmbt_block_t *, int);
227 extern void xfs_bmbt_get_all(xfs_bmbt_rec_host_t *r, xfs_bmbt_irec_t *s);
228 extern xfs_filblks_t xfs_bmbt_get_blockcount(xfs_bmbt_rec_host_t *r);
229 extern xfs_fsblock_t xfs_bmbt_get_startblock(xfs_bmbt_rec_host_t *r);
230 extern xfs_fileoff_t xfs_bmbt_get_startoff(xfs_bmbt_rec_host_t *r);
231 extern xfs_exntst_t xfs_bmbt_get_state(xfs_bmbt_rec_host_t *r);
232
233 extern void xfs_bmbt_disk_get_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s);
234 extern xfs_filblks_t xfs_bmbt_disk_get_blockcount(xfs_bmbt_rec_t *r);
235 extern xfs_fileoff_t xfs_bmbt_disk_get_startoff(xfs_bmbt_rec_t *r);
236
237 extern void xfs_bmbt_set_all(xfs_bmbt_rec_host_t *r, xfs_bmbt_irec_t *s);
238 extern void xfs_bmbt_set_allf(xfs_bmbt_rec_host_t *r, xfs_fileoff_t o,
239                         xfs_fsblock_t b, xfs_filblks_t c, xfs_exntst_t v);
240 extern void xfs_bmbt_set_blockcount(xfs_bmbt_rec_host_t *r, xfs_filblks_t v);
241 extern void xfs_bmbt_set_startblock(xfs_bmbt_rec_host_t *r, xfs_fsblock_t v);
242 extern void xfs_bmbt_set_startoff(xfs_bmbt_rec_host_t *r, xfs_fileoff_t v);
243 extern void xfs_bmbt_set_state(xfs_bmbt_rec_host_t *r, xfs_exntst_t v);
244
245 extern void xfs_bmbt_disk_set_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s);
246 extern void xfs_bmbt_disk_set_allf(xfs_bmbt_rec_t *r, xfs_fileoff_t o,
247                         xfs_fsblock_t b, xfs_filblks_t c, xfs_exntst_t v);
248
249 extern void xfs_bmbt_to_bmdr(struct xfs_mount *, xfs_bmbt_block_t *, int,
250                         xfs_bmdr_block_t *, int);
251
252 extern int xfs_bmbt_get_maxrecs(struct xfs_btree_cur *, int level);
253 extern int xfs_bmdr_maxrecs(struct xfs_mount *, int blocklen, int leaf);
254 extern int xfs_bmbt_maxrecs(struct xfs_mount *, int blocklen, int leaf);
255
256 extern struct xfs_btree_cur *xfs_bmbt_init_cursor(struct xfs_mount *,
257                 struct xfs_trans *, struct xfs_inode *, int);
258
259
260 #endif  /* __XFS_BMAP_BTREE_H__ */