Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * Copyright (c) 2000 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_IALLOC_BTREE_H__ | |
33 | #define __XFS_IALLOC_BTREE_H__ | |
34 | ||
35 | /* | |
36 | * Inode map on-disk structures | |
37 | */ | |
38 | ||
39 | struct xfs_buf; | |
40 | struct xfs_btree_cur; | |
41 | struct xfs_btree_sblock; | |
42 | struct xfs_mount; | |
43 | ||
44 | /* | |
45 | * There is a btree for the inode map per allocation group. | |
46 | */ | |
47 | #define XFS_IBT_MAGIC 0x49414254 /* 'IABT' */ | |
48 | ||
49 | typedef __uint64_t xfs_inofree_t; | |
50 | #define XFS_INODES_PER_CHUNK (NBBY * sizeof(xfs_inofree_t)) | |
51 | #define XFS_INODES_PER_CHUNK_LOG (XFS_NBBYLOG + 3) | |
52 | #define XFS_INOBT_ALL_FREE ((xfs_inofree_t)-1) | |
53 | ||
54 | #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INOBT_MASKN) | |
55 | xfs_inofree_t xfs_inobt_maskn(int i, int n); | |
56 | #define XFS_INOBT_MASKN(i,n) xfs_inobt_maskn(i,n) | |
57 | #else | |
58 | #define XFS_INOBT_MASKN(i,n) \ | |
59 | ((((n) >= XFS_INODES_PER_CHUNK ? \ | |
60 | (xfs_inofree_t)0 : ((xfs_inofree_t)1 << (n))) - 1) << (i)) | |
61 | #endif | |
62 | ||
63 | /* | |
64 | * Data record structure | |
65 | */ | |
66 | typedef struct xfs_inobt_rec | |
67 | { | |
68 | xfs_agino_t ir_startino; /* starting inode number */ | |
69 | __int32_t ir_freecount; /* count of free inodes (set bits) */ | |
70 | xfs_inofree_t ir_free; /* free inode mask */ | |
71 | } xfs_inobt_rec_t; | |
72 | ||
73 | /* | |
74 | * Key structure | |
75 | */ | |
76 | typedef struct xfs_inobt_key | |
77 | { | |
78 | xfs_agino_t ir_startino; /* starting inode number */ | |
79 | } xfs_inobt_key_t; | |
80 | ||
81 | typedef xfs_agblock_t xfs_inobt_ptr_t; /* btree pointer type */ | |
82 | /* btree block header type */ | |
83 | typedef struct xfs_btree_sblock xfs_inobt_block_t; | |
84 | ||
85 | #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BUF_TO_INOBT_BLOCK) | |
86 | xfs_inobt_block_t *xfs_buf_to_inobt_block(struct xfs_buf *bp); | |
87 | #define XFS_BUF_TO_INOBT_BLOCK(bp) xfs_buf_to_inobt_block(bp) | |
88 | #else | |
89 | #define XFS_BUF_TO_INOBT_BLOCK(bp) ((xfs_inobt_block_t *)(XFS_BUF_PTR(bp))) | |
90 | #endif | |
91 | ||
92 | /* | |
93 | * Bit manipulations for ir_free. | |
94 | */ | |
95 | #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INOBT_MASK) | |
96 | xfs_inofree_t xfs_inobt_mask(int i); | |
97 | #define XFS_INOBT_MASK(i) xfs_inobt_mask(i) | |
98 | #else | |
99 | #define XFS_INOBT_MASK(i) ((xfs_inofree_t)1 << (i)) | |
100 | #endif | |
101 | #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INOBT_IS_FREE) | |
102 | int xfs_inobt_is_free(xfs_inobt_rec_t *rp, int i); | |
103 | #define XFS_INOBT_IS_FREE(rp,i) xfs_inobt_is_free(rp,i) | |
104 | #else | |
105 | #define XFS_INOBT_IS_FREE(rp,i) (((rp)->ir_free & XFS_INOBT_MASK(i)) != 0) | |
106 | #endif | |
107 | #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INOBT_SET_FREE) | |
108 | void xfs_inobt_set_free(xfs_inobt_rec_t *rp, int i); | |
109 | #define XFS_INOBT_SET_FREE(rp,i) xfs_inobt_set_free(rp,i) | |
110 | #else | |
111 | #define XFS_INOBT_SET_FREE(rp,i) ((rp)->ir_free |= XFS_INOBT_MASK(i)) | |
112 | #endif | |
113 | #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INOBT_CLR_FREE) | |
114 | void xfs_inobt_clr_free(xfs_inobt_rec_t *rp, int i); | |
115 | #define XFS_INOBT_CLR_FREE(rp,i) xfs_inobt_clr_free(rp,i) | |
116 | #else | |
117 | #define XFS_INOBT_CLR_FREE(rp,i) ((rp)->ir_free &= ~XFS_INOBT_MASK(i)) | |
118 | #endif | |
119 | ||
120 | /* | |
121 | * Real block structures have a size equal to the disk block size. | |
122 | */ | |
123 | #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INOBT_BLOCK_SIZE) | |
124 | int xfs_inobt_block_size(int lev, struct xfs_btree_cur *cur); | |
125 | #define XFS_INOBT_BLOCK_SIZE(lev,cur) xfs_inobt_block_size(lev,cur) | |
126 | #else | |
127 | #define XFS_INOBT_BLOCK_SIZE(lev,cur) (1 << (cur)->bc_blocklog) | |
128 | #endif | |
129 | ||
130 | #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INOBT_BLOCK_MAXRECS) | |
131 | int xfs_inobt_block_maxrecs(int lev, struct xfs_btree_cur *cur); | |
132 | #define XFS_INOBT_BLOCK_MAXRECS(lev,cur) xfs_inobt_block_maxrecs(lev,cur) | |
133 | #else | |
134 | #define XFS_INOBT_BLOCK_MAXRECS(lev,cur) \ | |
135 | ((cur)->bc_mp->m_inobt_mxr[lev != 0]) | |
136 | #endif | |
137 | #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INOBT_BLOCK_MINRECS) | |
138 | int xfs_inobt_block_minrecs(int lev, struct xfs_btree_cur *cur); | |
139 | #define XFS_INOBT_BLOCK_MINRECS(lev,cur) xfs_inobt_block_minrecs(lev,cur) | |
140 | #else | |
141 | #define XFS_INOBT_BLOCK_MINRECS(lev,cur) \ | |
142 | ((cur)->bc_mp->m_inobt_mnr[lev != 0]) | |
143 | #endif | |
144 | ||
145 | #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INOBT_IS_LAST_REC) | |
146 | int xfs_inobt_is_last_rec(struct xfs_btree_cur *cur); | |
147 | #define XFS_INOBT_IS_LAST_REC(cur) xfs_inobt_is_last_rec(cur) | |
148 | #else | |
149 | #define XFS_INOBT_IS_LAST_REC(cur) \ | |
150 | ((cur)->bc_ptrs[0] == \ | |
151 | INT_GET(XFS_BUF_TO_INOBT_BLOCK((cur)->bc_bufs[0])->bb_numrecs, ARCH_CONVERT)) | |
152 | #endif | |
153 | ||
154 | /* | |
155 | * Maximum number of inode btree levels. | |
156 | */ | |
157 | #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_IN_MAXLEVELS) | |
158 | int xfs_in_maxlevels(struct xfs_mount *mp); | |
159 | #define XFS_IN_MAXLEVELS(mp) xfs_in_maxlevels(mp) | |
160 | #else | |
161 | #define XFS_IN_MAXLEVELS(mp) ((mp)->m_in_maxlevels) | |
162 | #endif | |
163 | ||
164 | /* | |
165 | * block numbers in the AG. | |
166 | */ | |
167 | #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_IBT_BLOCK) | |
168 | xfs_agblock_t xfs_ibt_block(struct xfs_mount *mp); | |
169 | #define XFS_IBT_BLOCK(mp) xfs_ibt_block(mp) | |
170 | #else | |
171 | #define XFS_IBT_BLOCK(mp) ((xfs_agblock_t)(XFS_CNT_BLOCK(mp) + 1)) | |
172 | #endif | |
173 | #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_PREALLOC_BLOCKS) | |
174 | xfs_agblock_t xfs_prealloc_blocks(struct xfs_mount *mp); | |
175 | #define XFS_PREALLOC_BLOCKS(mp) xfs_prealloc_blocks(mp) | |
176 | #else | |
177 | #define XFS_PREALLOC_BLOCKS(mp) ((xfs_agblock_t)(XFS_IBT_BLOCK(mp) + 1)) | |
178 | #endif | |
179 | ||
180 | /* | |
181 | * Record, key, and pointer address macros for btree blocks. | |
182 | */ | |
183 | #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INOBT_REC_ADDR) | |
184 | xfs_inobt_rec_t * | |
185 | xfs_inobt_rec_addr(xfs_inobt_block_t *bb, int i, struct xfs_btree_cur *cur); | |
186 | #define XFS_INOBT_REC_ADDR(bb,i,cur) xfs_inobt_rec_addr(bb,i,cur) | |
187 | #else | |
188 | #define XFS_INOBT_REC_ADDR(bb,i,cur) \ | |
189 | XFS_BTREE_REC_ADDR(XFS_INOBT_BLOCK_SIZE(0,cur), xfs_inobt, bb, i, \ | |
190 | XFS_INOBT_BLOCK_MAXRECS(0, cur)) | |
191 | #endif | |
192 | ||
193 | #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INOBT_KEY_ADDR) | |
194 | xfs_inobt_key_t * | |
195 | xfs_inobt_key_addr(xfs_inobt_block_t *bb, int i, struct xfs_btree_cur *cur); | |
196 | #define XFS_INOBT_KEY_ADDR(bb,i,cur) xfs_inobt_key_addr(bb,i,cur) | |
197 | #else | |
198 | #define XFS_INOBT_KEY_ADDR(bb,i,cur) \ | |
199 | XFS_BTREE_KEY_ADDR(XFS_INOBT_BLOCK_SIZE(1,cur), xfs_inobt, bb, i, \ | |
200 | XFS_INOBT_BLOCK_MAXRECS(1, cur)) | |
201 | #endif | |
202 | ||
203 | #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INOBT_PTR_ADDR) | |
204 | xfs_inobt_ptr_t * | |
205 | xfs_inobt_ptr_addr(xfs_inobt_block_t *bb, int i, struct xfs_btree_cur *cur); | |
206 | #define XFS_INOBT_PTR_ADDR(bb,i,cur) xfs_inobt_ptr_addr(bb,i,cur) | |
207 | #else | |
208 | #define XFS_INOBT_PTR_ADDR(bb,i,cur) \ | |
209 | XFS_BTREE_PTR_ADDR(XFS_INOBT_BLOCK_SIZE(1,cur), xfs_inobt, bb, i, \ | |
210 | XFS_INOBT_BLOCK_MAXRECS(1, cur)) | |
211 | #endif | |
212 | ||
213 | /* | |
214 | * Prototypes for externally visible routines. | |
215 | */ | |
216 | ||
217 | /* | |
218 | * Decrement cursor by one record at the level. | |
219 | * For nonzero levels the leaf-ward information is untouched. | |
220 | */ | |
221 | int /* error */ | |
222 | xfs_inobt_decrement( | |
223 | struct xfs_btree_cur *cur, /* btree cursor */ | |
224 | int level, /* level in btree, 0 is leaf */ | |
225 | int *stat); /* success/failure */ | |
226 | ||
227 | /* | |
228 | * Delete the record pointed to by cur. | |
229 | * The cursor refers to the place where the record was (could be inserted) | |
230 | * when the operation returns. | |
231 | */ | |
232 | int /* error */ | |
233 | xfs_inobt_delete( | |
234 | struct xfs_btree_cur *cur, /* btree cursor */ | |
235 | int *stat); /* success/failure */ | |
236 | ||
237 | /* | |
238 | * Get the data from the pointed-to record. | |
239 | */ | |
240 | int /* error */ | |
241 | xfs_inobt_get_rec( | |
242 | struct xfs_btree_cur *cur, /* btree cursor */ | |
243 | xfs_agino_t *ino, /* output: starting inode of chunk */ | |
244 | __int32_t *fcnt, /* output: number of free inodes */ | |
245 | xfs_inofree_t *free, /* output: free inode mask */ | |
246 | int *stat); /* output: success/failure */ | |
247 | ||
248 | /* | |
249 | * Increment cursor by one record at the level. | |
250 | * For nonzero levels the leaf-ward information is untouched. | |
251 | */ | |
252 | int /* error */ | |
253 | xfs_inobt_increment( | |
254 | struct xfs_btree_cur *cur, /* btree cursor */ | |
255 | int level, /* level in btree, 0 is leaf */ | |
256 | int *stat); /* success/failure */ | |
257 | ||
258 | /* | |
259 | * Insert the current record at the point referenced by cur. | |
260 | * The cursor may be inconsistent on return if splits have been done. | |
261 | */ | |
262 | int /* error */ | |
263 | xfs_inobt_insert( | |
264 | struct xfs_btree_cur *cur, /* btree cursor */ | |
265 | int *stat); /* success/failure */ | |
266 | ||
267 | /* | |
268 | * Lookup the record equal to ino in the btree given by cur. | |
269 | */ | |
270 | int /* error */ | |
271 | xfs_inobt_lookup_eq( | |
272 | struct xfs_btree_cur *cur, /* btree cursor */ | |
273 | xfs_agino_t ino, /* starting inode of chunk */ | |
274 | __int32_t fcnt, /* free inode count */ | |
275 | xfs_inofree_t free, /* free inode mask */ | |
276 | int *stat); /* success/failure */ | |
277 | ||
278 | /* | |
279 | * Lookup the first record greater than or equal to ino | |
280 | * in the btree given by cur. | |
281 | */ | |
282 | int /* error */ | |
283 | xfs_inobt_lookup_ge( | |
284 | struct xfs_btree_cur *cur, /* btree cursor */ | |
285 | xfs_agino_t ino, /* starting inode of chunk */ | |
286 | __int32_t fcnt, /* free inode count */ | |
287 | xfs_inofree_t free, /* free inode mask */ | |
288 | int *stat); /* success/failure */ | |
289 | ||
290 | /* | |
291 | * Lookup the first record less than or equal to ino | |
292 | * in the btree given by cur. | |
293 | */ | |
294 | int /* error */ | |
295 | xfs_inobt_lookup_le( | |
296 | struct xfs_btree_cur *cur, /* btree cursor */ | |
297 | xfs_agino_t ino, /* starting inode of chunk */ | |
298 | __int32_t fcnt, /* free inode count */ | |
299 | xfs_inofree_t free, /* free inode mask */ | |
300 | int *stat); /* success/failure */ | |
301 | ||
302 | /* | |
303 | * Update the record referred to by cur, to the value given | |
304 | * by [ino, fcnt, free]. | |
305 | * This either works (return 0) or gets an EFSCORRUPTED error. | |
306 | */ | |
307 | int /* error */ | |
308 | xfs_inobt_update( | |
309 | struct xfs_btree_cur *cur, /* btree cursor */ | |
310 | xfs_agino_t ino, /* starting inode of chunk */ | |
311 | __int32_t fcnt, /* free inode count */ | |
312 | xfs_inofree_t free); /* free inode mask */ | |
313 | ||
314 | #endif /* __XFS_IALLOC_BTREE_H__ */ |