]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - db/btblock.c
cbd299062833d463eb8b38035bfd2b60d0f2d3ea
[thirdparty/xfsprogs-dev.git] / db / btblock.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
4 * All Rights Reserved.
5 */
6
7 #include "libxfs.h"
8 #include "type.h"
9 #include "faddr.h"
10 #include "fprint.h"
11 #include "field.h"
12 #include "btblock.h"
13 #include "print.h"
14 #include "bit.h"
15 #include "init.h"
16 #include "io.h"
17 #include "output.h"
18
19 /*
20 * Definition of the possible btree block layouts.
21 */
22 struct xfs_db_btree {
23 uint32_t magic;
24 size_t block_len;
25 size_t key_len;
26 size_t rec_len;
27 size_t ptr_len;
28 } btrees[] = {
29 { XFS_BMAP_MAGIC,
30 XFS_BTREE_LBLOCK_LEN,
31 sizeof(xfs_bmbt_key_t),
32 sizeof(xfs_bmbt_rec_t),
33 sizeof(__be64),
34 },
35 { XFS_ABTB_MAGIC,
36 XFS_BTREE_SBLOCK_LEN,
37 sizeof(xfs_alloc_key_t),
38 sizeof(xfs_alloc_rec_t),
39 sizeof(__be32),
40 },
41 { XFS_ABTC_MAGIC,
42 XFS_BTREE_SBLOCK_LEN,
43 sizeof(xfs_alloc_key_t),
44 sizeof(xfs_alloc_rec_t),
45 sizeof(__be32),
46 },
47 { XFS_IBT_MAGIC,
48 XFS_BTREE_SBLOCK_LEN,
49 sizeof(xfs_inobt_key_t),
50 sizeof(xfs_inobt_rec_t),
51 sizeof(__be32),
52 },
53 { XFS_FIBT_MAGIC,
54 XFS_BTREE_SBLOCK_LEN,
55 sizeof(xfs_inobt_key_t),
56 sizeof(xfs_inobt_rec_t),
57 sizeof(__be32),
58 },
59 { XFS_BMAP_CRC_MAGIC,
60 XFS_BTREE_LBLOCK_CRC_LEN,
61 sizeof(xfs_bmbt_key_t),
62 sizeof(xfs_bmbt_rec_t),
63 sizeof(__be64),
64 },
65 { XFS_ABTB_CRC_MAGIC,
66 XFS_BTREE_SBLOCK_CRC_LEN,
67 sizeof(xfs_alloc_key_t),
68 sizeof(xfs_alloc_rec_t),
69 sizeof(__be32),
70 },
71 { XFS_ABTC_CRC_MAGIC,
72 XFS_BTREE_SBLOCK_CRC_LEN,
73 sizeof(xfs_alloc_key_t),
74 sizeof(xfs_alloc_rec_t),
75 sizeof(__be32),
76 },
77 { XFS_IBT_CRC_MAGIC,
78 XFS_BTREE_SBLOCK_CRC_LEN,
79 sizeof(xfs_inobt_key_t),
80 sizeof(xfs_inobt_rec_t),
81 sizeof(__be32),
82 },
83 { XFS_FIBT_CRC_MAGIC,
84 XFS_BTREE_SBLOCK_CRC_LEN,
85 sizeof(xfs_inobt_key_t),
86 sizeof(xfs_inobt_rec_t),
87 sizeof(__be32),
88 },
89 { XFS_RMAP_CRC_MAGIC,
90 XFS_BTREE_SBLOCK_CRC_LEN,
91 2 * sizeof(struct xfs_rmap_key),
92 sizeof(struct xfs_rmap_rec),
93 sizeof(__be32),
94 },
95 { XFS_REFC_CRC_MAGIC,
96 XFS_BTREE_SBLOCK_CRC_LEN,
97 sizeof(struct xfs_refcount_key),
98 sizeof(struct xfs_refcount_rec),
99 sizeof(__be32),
100 },
101 { 0,
102 },
103 };
104
105 /*
106 * Find the right block definition for a given ondisk block.
107 */
108 static struct xfs_db_btree *
109 block_to_bt(
110 struct xfs_btree_block *bb)
111 {
112 struct xfs_db_btree *btp;
113 uint32_t magic;
114 bool crc;
115
116 magic = be32_to_cpu((bb)->bb_magic);
117 for (btp = &btrees[0]; btp->magic != 0; btp++) {
118 if (magic == btp->magic)
119 return btp;
120 }
121
122 /* Magic is invalid/unknown. Guess based on iocur type */
123 crc = xfs_sb_version_hascrc(&mp->m_sb);
124 switch (iocur_top->typ->typnm) {
125 case TYP_BMAPBTA:
126 case TYP_BMAPBTD:
127 magic = crc ? XFS_BMAP_CRC_MAGIC : XFS_BMAP_MAGIC;
128 break;
129 case TYP_BNOBT:
130 magic = crc ? XFS_ABTB_CRC_MAGIC : XFS_ABTB_MAGIC;
131 break;
132 case TYP_CNTBT:
133 magic = crc ? XFS_ABTC_CRC_MAGIC : XFS_ABTC_MAGIC;
134 break;
135 case TYP_INOBT:
136 magic = crc ? XFS_IBT_CRC_MAGIC : XFS_IBT_MAGIC;
137 break;
138 case TYP_FINOBT:
139 magic = crc ? XFS_FIBT_CRC_MAGIC : XFS_FIBT_MAGIC;
140 break;
141 case TYP_RMAPBT:
142 magic = crc ? XFS_RMAP_CRC_MAGIC : 0;
143 break;
144 case TYP_REFCBT:
145 magic = crc ? XFS_REFC_CRC_MAGIC : 0;
146 break;
147 default:
148 ASSERT(0);
149 }
150
151 ASSERT(magic);
152 dbprintf(_("Bad btree magic 0x%x; coercing to %s.\n"),
153 be32_to_cpu((bb)->bb_magic),
154 iocur_top->typ->name);
155
156 for (btp = &btrees[0]; btp->magic != 0; btp++) {
157 if (magic == btp->magic)
158 return btp;
159 }
160
161 return NULL;
162 }
163
164 /* calculate max records. Only for non-leaves. */
165 static int
166 btblock_maxrecs(struct xfs_db_btree *bt, int blocksize)
167 {
168 blocksize -= bt->block_len;
169
170 return blocksize / (bt->key_len + bt->ptr_len);
171 }
172
173 /*
174 * Get the number of keys in a btree block.
175 *
176 * Note: can also be used to get the number of ptrs because there are
177 * always the same number of keys and ptrs in a block.
178 */
179 static int
180 btblock_key_count(
181 void *obj,
182 int startoff)
183 {
184 struct xfs_btree_block *block = obj;
185
186 ASSERT(startoff == 0);
187
188 if (block->bb_level == 0)
189 return 0;
190 return be16_to_cpu(block->bb_numrecs);
191 }
192
193 /*
194 * Get the number of keys in a btree block.
195 */
196 static int
197 btblock_rec_count(
198 void *obj,
199 int startoff)
200 {
201 struct xfs_btree_block *block = obj;
202
203 ASSERT(startoff == 0);
204
205 if (block->bb_level != 0)
206 return 0;
207 return be16_to_cpu(block->bb_numrecs);
208 }
209
210 /*
211 * Get the offset of the key at idx in a btree block.
212 */
213 static int
214 btblock_key_offset(
215 void *obj,
216 int startoff,
217 int idx)
218 {
219 struct xfs_btree_block *block = obj;
220 struct xfs_db_btree *bt = block_to_bt(block);
221 int offset;
222
223 ASSERT(startoff == 0);
224 ASSERT(block->bb_level != 0);
225
226 offset = bt->block_len + (idx - 1) * bt->key_len;
227 return bitize(offset);
228 }
229
230 /*
231 * Get the offset of the ptr at idx in a btree block.
232 */
233 static int
234 btblock_ptr_offset(
235 void *obj,
236 int startoff,
237 int idx)
238 {
239 struct xfs_btree_block *block = obj;
240 struct xfs_db_btree *bt = block_to_bt(block);
241 int offset;
242 int maxrecs;
243
244 ASSERT(startoff == 0);
245 ASSERT(block->bb_level != 0);
246
247 maxrecs = btblock_maxrecs(bt, mp->m_sb.sb_blocksize);
248 offset = bt->block_len +
249 maxrecs * bt->key_len +
250 (idx - 1) * bt->ptr_len;
251
252 return bitize(offset);
253 }
254
255 /*
256 * Get the offset of the record at idx in a btree block.
257 */
258 static int
259 btblock_rec_offset(
260 void *obj,
261 int startoff,
262 int idx)
263 {
264 struct xfs_btree_block *block = obj;
265 struct xfs_db_btree *bt = block_to_bt(block);
266 int offset;
267
268 ASSERT(startoff == 0);
269 ASSERT(block->bb_level == 0);
270
271 offset = bt->block_len + (idx - 1) * bt->rec_len;
272 return bitize(offset);
273 }
274
275 /*
276 * Get the size of a btree block.
277 */
278 int
279 btblock_size(
280 void *obj,
281 int startoff,
282 int idx)
283 {
284 return bitize(mp->m_sb.sb_blocksize);
285 }
286
287
288 /*
289 * Bmap btree.
290 */
291
292 const field_t bmapbta_hfld[] = {
293 { "", FLDT_BMAPBTA, OI(0), C1, 0, TYP_NONE },
294 { NULL }
295 };
296 const field_t bmapbtd_hfld[] = {
297 { "", FLDT_BMAPBTD, OI(0), C1, 0, TYP_NONE },
298 { NULL }
299 };
300
301 const field_t bmapbta_crc_hfld[] = {
302 { "", FLDT_BMAPBTA_CRC, OI(0), C1, 0, TYP_NONE },
303 { NULL }
304 };
305 const field_t bmapbtd_crc_hfld[] = {
306 { "", FLDT_BMAPBTD_CRC, OI(0), C1, 0, TYP_NONE },
307 { NULL }
308 };
309
310 #define OFF(f) bitize(offsetof(struct xfs_btree_block, bb_ ## f))
311 const field_t bmapbta_flds[] = {
312 { "magic", FLDT_UINT32X, OI(OFF(magic)), C1, 0, TYP_NONE },
313 { "level", FLDT_UINT16D, OI(OFF(level)), C1, 0, TYP_NONE },
314 { "numrecs", FLDT_UINT16D, OI(OFF(numrecs)), C1, 0, TYP_NONE },
315 { "leftsib", FLDT_DFSBNO, OI(OFF(u.l.bb_leftsib)), C1, 0, TYP_BMAPBTA },
316 { "rightsib", FLDT_DFSBNO, OI(OFF(u.l.bb_rightsib)), C1, 0, TYP_BMAPBTA },
317 { "recs", FLDT_BMAPBTAREC, btblock_rec_offset, btblock_rec_count,
318 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE },
319 { "keys", FLDT_BMAPBTAKEY, btblock_key_offset, btblock_key_count,
320 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE },
321 { "ptrs", FLDT_BMAPBTAPTR, btblock_ptr_offset, btblock_key_count,
322 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_BMAPBTA },
323 { NULL }
324 };
325 const field_t bmapbtd_flds[] = {
326 { "magic", FLDT_UINT32X, OI(OFF(magic)), C1, 0, TYP_NONE },
327 { "level", FLDT_UINT16D, OI(OFF(level)), C1, 0, TYP_NONE },
328 { "numrecs", FLDT_UINT16D, OI(OFF(numrecs)), C1, 0, TYP_NONE },
329 { "leftsib", FLDT_DFSBNO, OI(OFF(u.l.bb_leftsib)), C1, 0, TYP_BMAPBTD },
330 { "rightsib", FLDT_DFSBNO, OI(OFF(u.l.bb_rightsib)), C1, 0, TYP_BMAPBTD },
331 { "recs", FLDT_BMAPBTDREC, btblock_rec_offset, btblock_rec_count,
332 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE },
333 { "keys", FLDT_BMAPBTDKEY, btblock_key_offset, btblock_key_count,
334 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE },
335 { "ptrs", FLDT_BMAPBTDPTR, btblock_ptr_offset, btblock_key_count,
336 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_BMAPBTD },
337 { NULL }
338 };
339 /* crc enabled versions */
340 const field_t bmapbta_crc_flds[] = {
341 { "magic", FLDT_UINT32X, OI(OFF(magic)), C1, 0, TYP_NONE },
342 { "level", FLDT_UINT16D, OI(OFF(level)), C1, 0, TYP_NONE },
343 { "numrecs", FLDT_UINT16D, OI(OFF(numrecs)), C1, 0, TYP_NONE },
344 { "leftsib", FLDT_DFSBNO, OI(OFF(u.l.bb_leftsib)), C1, 0, TYP_BMAPBTA },
345 { "rightsib", FLDT_DFSBNO, OI(OFF(u.l.bb_rightsib)), C1, 0, TYP_BMAPBTA },
346 { "bno", FLDT_DFSBNO, OI(OFF(u.l.bb_blkno)), C1, 0, TYP_BMAPBTD },
347 { "lsn", FLDT_UINT64X, OI(OFF(u.l.bb_lsn)), C1, 0, TYP_NONE },
348 { "uuid", FLDT_UUID, OI(OFF(u.l.bb_uuid)), C1, 0, TYP_NONE },
349 { "owner", FLDT_INO, OI(OFF(u.l.bb_owner)), C1, 0, TYP_NONE },
350 { "crc", FLDT_CRC, OI(OFF(u.l.bb_crc)), C1, 0, TYP_NONE },
351 { "recs", FLDT_BMAPBTAREC, btblock_rec_offset, btblock_rec_count,
352 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE },
353 { "keys", FLDT_BMAPBTAKEY, btblock_key_offset, btblock_key_count,
354 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE },
355 { "ptrs", FLDT_BMAPBTAPTR, btblock_ptr_offset, btblock_key_count,
356 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_BMAPBTA },
357 { NULL }
358 };
359 const field_t bmapbtd_crc_flds[] = {
360 { "magic", FLDT_UINT32X, OI(OFF(magic)), C1, 0, TYP_NONE },
361 { "level", FLDT_UINT16D, OI(OFF(level)), C1, 0, TYP_NONE },
362 { "numrecs", FLDT_UINT16D, OI(OFF(numrecs)), C1, 0, TYP_NONE },
363 { "leftsib", FLDT_DFSBNO, OI(OFF(u.l.bb_leftsib)), C1, 0, TYP_BMAPBTD },
364 { "rightsib", FLDT_DFSBNO, OI(OFF(u.l.bb_rightsib)), C1, 0, TYP_BMAPBTD },
365 { "bno", FLDT_DFSBNO, OI(OFF(u.l.bb_blkno)), C1, 0, TYP_BMAPBTD },
366 { "lsn", FLDT_UINT64X, OI(OFF(u.l.bb_lsn)), C1, 0, TYP_NONE },
367 { "uuid", FLDT_UUID, OI(OFF(u.l.bb_uuid)), C1, 0, TYP_NONE },
368 { "owner", FLDT_INO, OI(OFF(u.l.bb_owner)), C1, 0, TYP_NONE },
369 { "crc", FLDT_CRC, OI(OFF(u.l.bb_crc)), C1, 0, TYP_NONE },
370 { "recs", FLDT_BMAPBTDREC, btblock_rec_offset, btblock_rec_count,
371 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE },
372 { "keys", FLDT_BMAPBTDKEY, btblock_key_offset, btblock_key_count,
373 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE },
374 { "ptrs", FLDT_BMAPBTDPTR, btblock_ptr_offset, btblock_key_count,
375 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_BMAPBTD },
376 { NULL }
377 };
378 #undef OFF
379
380 #define KOFF(f) bitize(offsetof(xfs_bmbt_key_t, br_ ## f))
381 const field_t bmapbta_key_flds[] = {
382 { "startoff", FLDT_DFILOFFA, OI(KOFF(startoff)), C1, 0, TYP_ATTR },
383 { NULL }
384 };
385 const field_t bmapbtd_key_flds[] = {
386 { "startoff", FLDT_DFILOFFD, OI(KOFF(startoff)), C1, 0, TYP_INODATA },
387 { NULL }
388 };
389 #undef KOFF
390
391 #define BMBT_EXNTFLAG_BITOFF 0
392 #define BMBT_STARTOFF_BITOFF (BMBT_EXNTFLAG_BITOFF + BMBT_EXNTFLAG_BITLEN)
393 #define BMBT_STARTBLOCK_BITOFF (BMBT_STARTOFF_BITOFF + BMBT_STARTOFF_BITLEN)
394 #define BMBT_BLOCKCOUNT_BITOFF \
395 (BMBT_STARTBLOCK_BITOFF + BMBT_STARTBLOCK_BITLEN)
396
397 const field_t bmapbta_rec_flds[] = {
398 { "startoff", FLDT_CFILEOFFA, OI(BMBT_STARTOFF_BITOFF), C1, 0,
399 TYP_ATTR },
400 { "startblock", FLDT_CFSBLOCK, OI(BMBT_STARTBLOCK_BITOFF), C1, 0,
401 TYP_ATTR },
402 { "blockcount", FLDT_CEXTLEN, OI(BMBT_BLOCKCOUNT_BITOFF), C1, 0,
403 TYP_NONE },
404 { "extentflag", FLDT_CEXTFLG, OI(BMBT_EXNTFLAG_BITOFF), C1, 0,
405 TYP_NONE },
406 { NULL }
407 };
408 const field_t bmapbtd_rec_flds[] = {
409 { "startoff", FLDT_CFILEOFFD, OI(BMBT_STARTOFF_BITOFF), C1, 0,
410 TYP_INODATA },
411 { "startblock", FLDT_CFSBLOCK, OI(BMBT_STARTBLOCK_BITOFF), C1, 0,
412 TYP_INODATA },
413 { "blockcount", FLDT_CEXTLEN, OI(BMBT_BLOCKCOUNT_BITOFF), C1, 0,
414 TYP_NONE },
415 { "extentflag", FLDT_CEXTFLG, OI(BMBT_EXNTFLAG_BITOFF), C1, 0,
416 TYP_NONE },
417 { NULL }
418 };
419
420
421 /*
422 * Inode allocation btree.
423 */
424
425 const field_t inobt_hfld[] = {
426 { "", FLDT_INOBT, OI(0), C1, 0, TYP_NONE },
427 { NULL }
428 };
429
430 const field_t inobt_crc_hfld[] = {
431 { "", FLDT_INOBT_CRC, OI(0), C1, 0, TYP_NONE },
432 { NULL }
433 };
434
435 const field_t inobt_spcrc_hfld[] = {
436 { "", FLDT_INOBT_SPCRC, OI(0), C1, 0, TYP_NONE },
437 { NULL }
438 };
439
440 #define OFF(f) bitize(offsetof(struct xfs_btree_block, bb_ ## f))
441 const field_t inobt_flds[] = {
442 { "magic", FLDT_UINT32X, OI(OFF(magic)), C1, 0, TYP_NONE },
443 { "level", FLDT_UINT16D, OI(OFF(level)), C1, 0, TYP_NONE },
444 { "numrecs", FLDT_UINT16D, OI(OFF(numrecs)), C1, 0, TYP_NONE },
445 { "leftsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_leftsib)), C1, 0, TYP_INOBT },
446 { "rightsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_rightsib)), C1, 0, TYP_INOBT },
447 { "recs", FLDT_INOBTREC, btblock_rec_offset, btblock_rec_count,
448 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE },
449 { "keys", FLDT_INOBTKEY, btblock_key_offset, btblock_key_count,
450 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE },
451 { "ptrs", FLDT_INOBTPTR, btblock_ptr_offset, btblock_key_count,
452 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_INOBT },
453 { NULL }
454 };
455 const field_t inobt_crc_flds[] = {
456 { "magic", FLDT_UINT32X, OI(OFF(magic)), C1, 0, TYP_NONE },
457 { "level", FLDT_UINT16D, OI(OFF(level)), C1, 0, TYP_NONE },
458 { "numrecs", FLDT_UINT16D, OI(OFF(numrecs)), C1, 0, TYP_NONE },
459 { "leftsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_leftsib)), C1, 0, TYP_INOBT },
460 { "rightsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_rightsib)), C1, 0, TYP_INOBT },
461 { "bno", FLDT_DFSBNO, OI(OFF(u.s.bb_blkno)), C1, 0, TYP_INOBT },
462 { "lsn", FLDT_UINT64X, OI(OFF(u.s.bb_lsn)), C1, 0, TYP_NONE },
463 { "uuid", FLDT_UUID, OI(OFF(u.s.bb_uuid)), C1, 0, TYP_NONE },
464 { "owner", FLDT_AGNUMBER, OI(OFF(u.s.bb_owner)), C1, 0, TYP_NONE },
465 { "crc", FLDT_CRC, OI(OFF(u.s.bb_crc)), C1, 0, TYP_NONE },
466 { "recs", FLDT_INOBTREC, btblock_rec_offset, btblock_rec_count,
467 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE },
468 { "keys", FLDT_INOBTKEY, btblock_key_offset, btblock_key_count,
469 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE },
470 { "ptrs", FLDT_INOBTPTR, btblock_ptr_offset, btblock_key_count,
471 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_INOBT },
472 { NULL }
473 };
474 const field_t inobt_spcrc_flds[] = {
475 { "magic", FLDT_UINT32X, OI(OFF(magic)), C1, 0, TYP_NONE },
476 { "level", FLDT_UINT16D, OI(OFF(level)), C1, 0, TYP_NONE },
477 { "numrecs", FLDT_UINT16D, OI(OFF(numrecs)), C1, 0, TYP_NONE },
478 { "leftsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_leftsib)), C1, 0, TYP_INOBT },
479 { "rightsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_rightsib)), C1, 0, TYP_INOBT },
480 { "bno", FLDT_DFSBNO, OI(OFF(u.s.bb_blkno)), C1, 0, TYP_INOBT },
481 { "lsn", FLDT_UINT64X, OI(OFF(u.s.bb_lsn)), C1, 0, TYP_NONE },
482 { "uuid", FLDT_UUID, OI(OFF(u.s.bb_uuid)), C1, 0, TYP_NONE },
483 { "owner", FLDT_AGNUMBER, OI(OFF(u.s.bb_owner)), C1, 0, TYP_NONE },
484 { "crc", FLDT_CRC, OI(OFF(u.s.bb_crc)), C1, 0, TYP_NONE },
485 { "recs", FLDT_INOBTSPREC, btblock_rec_offset, btblock_rec_count,
486 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE },
487 { "keys", FLDT_INOBTKEY, btblock_key_offset, btblock_key_count,
488 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE },
489 { "ptrs", FLDT_INOBTPTR, btblock_ptr_offset, btblock_key_count,
490 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_INOBT },
491 { NULL }
492 };
493
494 #undef OFF
495
496 #define KOFF(f) bitize(offsetof(xfs_inobt_key_t, ir_ ## f))
497 const field_t inobt_key_flds[] = {
498 { "startino", FLDT_AGINO, OI(KOFF(startino)), C1, 0, TYP_INODE },
499 { NULL }
500 };
501 #undef KOFF
502
503 #define ROFF(f) bitize(offsetof(xfs_inobt_rec_t, f))
504 const field_t inobt_rec_flds[] = {
505 { "startino", FLDT_AGINO, OI(ROFF(ir_startino)), C1, 0, TYP_INODE },
506 { "freecount", FLDT_INT32D, OI(ROFF(ir_u.f.ir_freecount)), C1, 0, TYP_NONE },
507 { "free", FLDT_INOFREE, OI(ROFF(ir_free)), C1, 0, TYP_NONE },
508 { NULL }
509 };
510 /* sparse inode on-disk format */
511 const field_t inobt_sprec_flds[] = {
512 { "startino", FLDT_AGINO, OI(ROFF(ir_startino)), C1, 0, TYP_INODE },
513 { "holemask", FLDT_UINT16X, OI(ROFF(ir_u.sp.ir_holemask)), C1, 0,
514 TYP_NONE },
515 { "count", FLDT_UINT8D, OI(ROFF(ir_u.sp.ir_count)), C1, 0, TYP_NONE },
516 { "freecount", FLDT_INT8D, OI(ROFF(ir_u.sp.ir_freecount)), C1, 0,
517 TYP_NONE },
518 { "free", FLDT_INOFREE, OI(ROFF(ir_free)), C1, 0, TYP_NONE },
519 { NULL }
520 };
521 #undef ROFF
522
523
524 /*
525 * Allocation btrees.
526 */
527 const field_t bnobt_hfld[] = {
528 { "", FLDT_BNOBT, OI(0), C1, 0, TYP_NONE },
529 { NULL }
530 };
531
532 const field_t bnobt_crc_hfld[] = {
533 { "", FLDT_BNOBT_CRC, OI(0), C1, 0, TYP_NONE },
534 { NULL }
535 };
536
537 #define OFF(f) bitize(offsetof(struct xfs_btree_block, bb_ ## f))
538 const field_t bnobt_flds[] = {
539 { "magic", FLDT_UINT32X, OI(OFF(magic)), C1, 0, TYP_NONE },
540 { "level", FLDT_UINT16D, OI(OFF(level)), C1, 0, TYP_NONE },
541 { "numrecs", FLDT_UINT16D, OI(OFF(numrecs)), C1, 0, TYP_NONE },
542 { "leftsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_leftsib)), C1, 0, TYP_BNOBT },
543 { "rightsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_rightsib)), C1, 0, TYP_BNOBT },
544 { "recs", FLDT_BNOBTREC, btblock_rec_offset, btblock_rec_count,
545 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE },
546 { "keys", FLDT_BNOBTKEY, btblock_key_offset, btblock_key_count,
547 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE },
548 { "ptrs", FLDT_BNOBTPTR, btblock_ptr_offset, btblock_key_count,
549 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_BNOBT },
550 { NULL }
551 };
552 const field_t bnobt_crc_flds[] = {
553 { "magic", FLDT_UINT32X, OI(OFF(magic)), C1, 0, TYP_NONE },
554 { "level", FLDT_UINT16D, OI(OFF(level)), C1, 0, TYP_NONE },
555 { "numrecs", FLDT_UINT16D, OI(OFF(numrecs)), C1, 0, TYP_NONE },
556 { "leftsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_leftsib)), C1, 0, TYP_BNOBT },
557 { "rightsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_rightsib)), C1, 0, TYP_BNOBT },
558 { "bno", FLDT_DFSBNO, OI(OFF(u.s.bb_blkno)), C1, 0, TYP_BNOBT },
559 { "lsn", FLDT_UINT64X, OI(OFF(u.s.bb_lsn)), C1, 0, TYP_NONE },
560 { "uuid", FLDT_UUID, OI(OFF(u.s.bb_uuid)), C1, 0, TYP_NONE },
561 { "owner", FLDT_AGNUMBER, OI(OFF(u.s.bb_owner)), C1, 0, TYP_NONE },
562 { "crc", FLDT_CRC, OI(OFF(u.s.bb_crc)), C1, 0, TYP_NONE },
563 { "recs", FLDT_BNOBTREC, btblock_rec_offset, btblock_rec_count,
564 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE },
565 { "keys", FLDT_BNOBTKEY, btblock_key_offset, btblock_key_count,
566 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE },
567 { "ptrs", FLDT_BNOBTPTR, btblock_ptr_offset, btblock_key_count,
568 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_BNOBT },
569 { NULL }
570 };
571 #undef OFF
572
573 #define KOFF(f) bitize(offsetof(xfs_alloc_key_t, ar_ ## f))
574 const field_t bnobt_key_flds[] = {
575 { "startblock", FLDT_AGBLOCK, OI(KOFF(startblock)), C1, 0, TYP_DATA },
576 { "blockcount", FLDT_EXTLEN, OI(KOFF(blockcount)), C1, 0, TYP_NONE },
577 { NULL }
578 };
579 #undef KOFF
580
581 #define ROFF(f) bitize(offsetof(xfs_alloc_rec_t, ar_ ## f))
582 const field_t bnobt_rec_flds[] = {
583 { "startblock", FLDT_AGBLOCK, OI(ROFF(startblock)), C1, 0, TYP_DATA },
584 { "blockcount", FLDT_EXTLEN, OI(ROFF(blockcount)), C1, 0, TYP_NONE },
585 { NULL }
586 };
587 #undef ROFF
588
589 const field_t cntbt_hfld[] = {
590 { "", FLDT_CNTBT, OI(0), C1, 0, TYP_NONE },
591 { NULL }
592 };
593
594 const field_t cntbt_crc_hfld[] = {
595 { "", FLDT_CNTBT_CRC, OI(0), C1, 0, TYP_NONE },
596 { NULL }
597 };
598
599 #define OFF(f) bitize(offsetof(struct xfs_btree_block, bb_ ## f))
600 const field_t cntbt_flds[] = {
601 { "magic", FLDT_UINT32X, OI(OFF(magic)), C1, 0, TYP_NONE },
602 { "level", FLDT_UINT16D, OI(OFF(level)), C1, 0, TYP_NONE },
603 { "numrecs", FLDT_UINT16D, OI(OFF(numrecs)), C1, 0, TYP_NONE },
604 { "leftsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_leftsib)), C1, 0, TYP_CNTBT },
605 { "rightsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_rightsib)), C1, 0, TYP_CNTBT },
606 { "recs", FLDT_CNTBTREC, btblock_rec_offset, btblock_rec_count,
607 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE },
608 { "keys", FLDT_CNTBTKEY, btblock_key_offset, btblock_key_count,
609 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE },
610 { "ptrs", FLDT_CNTBTPTR, btblock_ptr_offset, btblock_key_count,
611 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_CNTBT },
612 { NULL }
613 };
614 const field_t cntbt_crc_flds[] = {
615 { "magic", FLDT_UINT32X, OI(OFF(magic)), C1, 0, TYP_NONE },
616 { "level", FLDT_UINT16D, OI(OFF(level)), C1, 0, TYP_NONE },
617 { "numrecs", FLDT_UINT16D, OI(OFF(numrecs)), C1, 0, TYP_NONE },
618 { "leftsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_leftsib)), C1, 0, TYP_CNTBT },
619 { "rightsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_rightsib)), C1, 0, TYP_CNTBT },
620 { "bno", FLDT_DFSBNO, OI(OFF(u.s.bb_blkno)), C1, 0, TYP_CNTBT },
621 { "lsn", FLDT_UINT64X, OI(OFF(u.s.bb_lsn)), C1, 0, TYP_NONE },
622 { "uuid", FLDT_UUID, OI(OFF(u.s.bb_uuid)), C1, 0, TYP_NONE },
623 { "owner", FLDT_AGNUMBER, OI(OFF(u.s.bb_owner)), C1, 0, TYP_NONE },
624 { "crc", FLDT_CRC, OI(OFF(u.s.bb_crc)), C1, 0, TYP_NONE },
625 { "recs", FLDT_CNTBTREC, btblock_rec_offset, btblock_rec_count,
626 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE },
627 { "keys", FLDT_CNTBTKEY, btblock_key_offset, btblock_key_count,
628 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE },
629 { "ptrs", FLDT_CNTBTPTR, btblock_ptr_offset, btblock_key_count,
630 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_CNTBT },
631 { NULL }
632 };
633 #undef OFF
634
635 #define KOFF(f) bitize(offsetof(xfs_alloc_key_t, ar_ ## f))
636 const field_t cntbt_key_flds[] = {
637 { "blockcount", FLDT_EXTLEN, OI(KOFF(blockcount)), C1, 0, TYP_NONE },
638 { "startblock", FLDT_AGBLOCK, OI(KOFF(startblock)), C1, 0, TYP_DATA },
639 { NULL }
640 };
641 #undef KOFF
642
643 #define ROFF(f) bitize(offsetof(xfs_alloc_rec_t, ar_ ## f))
644 const field_t cntbt_rec_flds[] = {
645 { "startblock", FLDT_AGBLOCK, OI(ROFF(startblock)), C1, 0, TYP_DATA },
646 { "blockcount", FLDT_EXTLEN, OI(ROFF(blockcount)), C1, 0, TYP_NONE },
647 { NULL }
648 };
649 #undef ROFF
650
651 /* RMAP btree blocks */
652 const field_t rmapbt_crc_hfld[] = {
653 { "", FLDT_RMAPBT_CRC, OI(0), C1, 0, TYP_NONE },
654 { NULL }
655 };
656
657 #define OFF(f) bitize(offsetof(struct xfs_btree_block, bb_ ## f))
658 const field_t rmapbt_crc_flds[] = {
659 { "magic", FLDT_UINT32X, OI(OFF(magic)), C1, 0, TYP_NONE },
660 { "level", FLDT_UINT16D, OI(OFF(level)), C1, 0, TYP_NONE },
661 { "numrecs", FLDT_UINT16D, OI(OFF(numrecs)), C1, 0, TYP_NONE },
662 { "leftsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_leftsib)), C1, 0, TYP_RMAPBT },
663 { "rightsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_rightsib)), C1, 0, TYP_RMAPBT },
664 { "bno", FLDT_DFSBNO, OI(OFF(u.s.bb_blkno)), C1, 0, TYP_RMAPBT },
665 { "lsn", FLDT_UINT64X, OI(OFF(u.s.bb_lsn)), C1, 0, TYP_NONE },
666 { "uuid", FLDT_UUID, OI(OFF(u.s.bb_uuid)), C1, 0, TYP_NONE },
667 { "owner", FLDT_AGNUMBER, OI(OFF(u.s.bb_owner)), C1, 0, TYP_NONE },
668 { "crc", FLDT_CRC, OI(OFF(u.s.bb_crc)), C1, 0, TYP_NONE },
669 { "recs", FLDT_RMAPBTREC, btblock_rec_offset, btblock_rec_count,
670 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE },
671 { "keys", FLDT_RMAPBTKEY, btblock_key_offset, btblock_key_count,
672 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE },
673 { "ptrs", FLDT_RMAPBTPTR, btblock_ptr_offset, btblock_key_count,
674 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_RMAPBT },
675 { NULL }
676 };
677 #undef OFF
678
679 #define KOFF(f) bitize(offsetof(struct xfs_rmap_key, rm_ ## f))
680
681 #define RMAPBK_STARTBLOCK_BITOFF 0
682 #define RMAPBK_OWNER_BITOFF (RMAPBK_STARTBLOCK_BITOFF + RMAPBT_STARTBLOCK_BITLEN)
683 #define RMAPBK_ATTRFLAG_BITOFF (RMAPBK_OWNER_BITOFF + RMAPBT_OWNER_BITLEN)
684 #define RMAPBK_BMBTFLAG_BITOFF (RMAPBK_ATTRFLAG_BITOFF + RMAPBT_ATTRFLAG_BITLEN)
685 #define RMAPBK_EXNTFLAG_BITOFF (RMAPBK_BMBTFLAG_BITOFF + RMAPBT_BMBTFLAG_BITLEN)
686 #define RMAPBK_UNUSED_OFFSET_BITOFF (RMAPBK_EXNTFLAG_BITOFF + RMAPBT_EXNTFLAG_BITLEN)
687 #define RMAPBK_OFFSET_BITOFF (RMAPBK_UNUSED_OFFSET_BITOFF + RMAPBT_UNUSED_OFFSET_BITLEN)
688
689 #define HI_KOFF(f) bitize(sizeof(struct xfs_rmap_key) + offsetof(struct xfs_rmap_key, rm_ ## f))
690
691 #define RMAPBK_STARTBLOCKHI_BITOFF (bitize(sizeof(struct xfs_rmap_key)))
692 #define RMAPBK_OWNERHI_BITOFF (RMAPBK_STARTBLOCKHI_BITOFF + RMAPBT_STARTBLOCK_BITLEN)
693 #define RMAPBK_ATTRFLAGHI_BITOFF (RMAPBK_OWNERHI_BITOFF + RMAPBT_OWNER_BITLEN)
694 #define RMAPBK_BMBTFLAGHI_BITOFF (RMAPBK_ATTRFLAGHI_BITOFF + RMAPBT_ATTRFLAG_BITLEN)
695 #define RMAPBK_EXNTFLAGHI_BITOFF (RMAPBK_BMBTFLAGHI_BITOFF + RMAPBT_BMBTFLAG_BITLEN)
696 #define RMAPBK_UNUSED_OFFSETHI_BITOFF (RMAPBK_EXNTFLAGHI_BITOFF + RMAPBT_EXNTFLAG_BITLEN)
697 #define RMAPBK_OFFSETHI_BITOFF (RMAPBK_UNUSED_OFFSETHI_BITOFF + RMAPBT_UNUSED_OFFSET_BITLEN)
698
699 const field_t rmapbt_key_flds[] = {
700 { "startblock", FLDT_AGBLOCK, OI(KOFF(startblock)), C1, 0, TYP_DATA },
701 { "owner", FLDT_INT64D, OI(KOFF(owner)), C1, 0, TYP_NONE },
702 { "offset", FLDT_RFILEOFFD, OI(RMAPBK_OFFSET_BITOFF), C1, 0, TYP_NONE },
703 { "attrfork", FLDT_RATTRFORKFLG, OI(RMAPBK_ATTRFLAG_BITOFF), C1, 0,
704 TYP_NONE },
705 { "bmbtblock", FLDT_RBMBTFLG, OI(RMAPBK_BMBTFLAG_BITOFF), C1, 0,
706 TYP_NONE },
707 { "startblock_hi", FLDT_AGBLOCK, OI(HI_KOFF(startblock)), C1, 0, TYP_DATA },
708 { "owner_hi", FLDT_INT64D, OI(HI_KOFF(owner)), C1, 0, TYP_NONE },
709 { "offset_hi", FLDT_RFILEOFFD, OI(RMAPBK_OFFSETHI_BITOFF), C1, 0, TYP_NONE },
710 { "attrfork_hi", FLDT_RATTRFORKFLG, OI(RMAPBK_ATTRFLAGHI_BITOFF), C1, 0,
711 TYP_NONE },
712 { "bmbtblock_hi", FLDT_RBMBTFLG, OI(RMAPBK_BMBTFLAGHI_BITOFF), C1, 0,
713 TYP_NONE },
714 { NULL }
715 };
716 #undef HI_KOFF
717 #undef KOFF
718
719 #define RMAPBT_STARTBLOCK_BITOFF 0
720 #define RMAPBT_BLOCKCOUNT_BITOFF (RMAPBT_STARTBLOCK_BITOFF + RMAPBT_STARTBLOCK_BITLEN)
721 #define RMAPBT_OWNER_BITOFF (RMAPBT_BLOCKCOUNT_BITOFF + RMAPBT_BLOCKCOUNT_BITLEN)
722 #define RMAPBT_ATTRFLAG_BITOFF (RMAPBT_OWNER_BITOFF + RMAPBT_OWNER_BITLEN)
723 #define RMAPBT_BMBTFLAG_BITOFF (RMAPBT_ATTRFLAG_BITOFF + RMAPBT_ATTRFLAG_BITLEN)
724 #define RMAPBT_EXNTFLAG_BITOFF (RMAPBT_BMBTFLAG_BITOFF + RMAPBT_BMBTFLAG_BITLEN)
725 #define RMAPBT_UNUSED_OFFSET_BITOFF (RMAPBT_EXNTFLAG_BITOFF + RMAPBT_EXNTFLAG_BITLEN)
726 #define RMAPBT_OFFSET_BITOFF (RMAPBT_UNUSED_OFFSET_BITOFF + RMAPBT_UNUSED_OFFSET_BITLEN)
727
728 const field_t rmapbt_rec_flds[] = {
729 { "startblock", FLDT_AGBLOCK, OI(RMAPBT_STARTBLOCK_BITOFF), C1, 0, TYP_DATA },
730 { "blockcount", FLDT_REXTLEN, OI(RMAPBT_BLOCKCOUNT_BITOFF), C1, 0, TYP_NONE },
731 { "owner", FLDT_INT64D, OI(RMAPBT_OWNER_BITOFF), C1, 0, TYP_NONE },
732 { "offset", FLDT_RFILEOFFD, OI(RMAPBT_OFFSET_BITOFF), C1, 0, TYP_NONE },
733 { "extentflag", FLDT_REXTFLG, OI(RMAPBT_EXNTFLAG_BITOFF), C1, 0,
734 TYP_NONE },
735 { "attrfork", FLDT_RATTRFORKFLG, OI(RMAPBT_ATTRFLAG_BITOFF), C1, 0,
736 TYP_NONE },
737 { "bmbtblock", FLDT_RBMBTFLG, OI(RMAPBT_BMBTFLAG_BITOFF), C1, 0,
738 TYP_NONE },
739 { NULL }
740 };
741
742 /* refcount btree blocks */
743 const field_t refcbt_crc_hfld[] = {
744 { "", FLDT_REFCBT_CRC, OI(0), C1, 0, TYP_NONE },
745 { NULL }
746 };
747
748 #define OFF(f) bitize(offsetof(struct xfs_btree_block, bb_ ## f))
749 const field_t refcbt_crc_flds[] = {
750 { "magic", FLDT_UINT32X, OI(OFF(magic)), C1, 0, TYP_NONE },
751 { "level", FLDT_UINT16D, OI(OFF(level)), C1, 0, TYP_NONE },
752 { "numrecs", FLDT_UINT16D, OI(OFF(numrecs)), C1, 0, TYP_NONE },
753 { "leftsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_leftsib)), C1, 0, TYP_REFCBT },
754 { "rightsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_rightsib)), C1, 0, TYP_REFCBT },
755 { "bno", FLDT_DFSBNO, OI(OFF(u.s.bb_blkno)), C1, 0, TYP_REFCBT },
756 { "lsn", FLDT_UINT64X, OI(OFF(u.s.bb_lsn)), C1, 0, TYP_NONE },
757 { "uuid", FLDT_UUID, OI(OFF(u.s.bb_uuid)), C1, 0, TYP_NONE },
758 { "owner", FLDT_AGNUMBER, OI(OFF(u.s.bb_owner)), C1, 0, TYP_NONE },
759 { "crc", FLDT_CRC, OI(OFF(u.s.bb_crc)), C1, 0, TYP_NONE },
760 { "recs", FLDT_REFCBTREC, btblock_rec_offset, btblock_rec_count,
761 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE },
762 { "keys", FLDT_REFCBTKEY, btblock_key_offset, btblock_key_count,
763 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE },
764 { "ptrs", FLDT_REFCBTPTR, btblock_ptr_offset, btblock_key_count,
765 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_REFCBT },
766 { NULL }
767 };
768 #undef OFF
769
770 #define REFCNTBT_COWFLAG_BITOFF 0
771 #define REFCNTBT_STARTBLOCK_BITOFF (REFCNTBT_COWFLAG_BITOFF + REFCNTBT_COWFLAG_BITLEN)
772
773 const field_t refcbt_key_flds[] = {
774 { "startblock", FLDT_CAGBLOCK, OI(REFCNTBT_STARTBLOCK_BITOFF), C1, 0, TYP_DATA },
775 { "cowflag", FLDT_CCOWFLG, OI(REFCNTBT_COWFLAG_BITOFF), C1, 0, TYP_DATA },
776 { NULL }
777 };
778
779 #define ROFF(f) bitize(offsetof(struct xfs_refcount_rec, rc_ ## f))
780 const field_t refcbt_rec_flds[] = {
781 { "startblock", FLDT_CAGBLOCK, OI(REFCNTBT_STARTBLOCK_BITOFF), C1, 0, TYP_DATA },
782 { "blockcount", FLDT_EXTLEN, OI(ROFF(blockcount)), C1, 0, TYP_NONE },
783 { "refcount", FLDT_UINT32D, OI(ROFF(refcount)), C1, 0, TYP_DATA },
784 { "cowflag", FLDT_CCOWFLG, OI(REFCNTBT_COWFLAG_BITOFF), C1, 0, TYP_DATA },
785 { NULL }
786 };
787 #undef ROFF