]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - db/bmroot.c
83507350b760cf7798829e7674aace390c54fdfe
[thirdparty/xfsprogs-dev.git] / db / bmroot.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 "bmroot.h"
13 #include "io.h"
14 #include "print.h"
15 #include "bit.h"
16 #include "init.h"
17
18 static int bmroota_key_count(void *obj, int startoff);
19 static int bmroota_key_offset(void *obj, int startoff, int idx);
20 static int bmroota_ptr_count(void *obj, int startoff);
21 static int bmroota_ptr_offset(void *obj, int startoff, int idx);
22 static int bmrootd_key_count(void *obj, int startoff);
23 static int bmrootd_key_offset(void *obj, int startoff, int idx);
24 static int bmrootd_ptr_count(void *obj, int startoff);
25 static int bmrootd_ptr_offset(void *obj, int startoff, int idx);
26
27 static int rtrmaproot_rec_count(void *obj, int startoff);
28 static int rtrmaproot_rec_offset(void *obj, int startoff, int idx);
29 static int rtrmaproot_key_count(void *obj, int startoff);
30 static int rtrmaproot_key_offset(void *obj, int startoff, int idx);
31 static int rtrmaproot_ptr_count(void *obj, int startoff);
32 static int rtrmaproot_ptr_offset(void *obj, int startoff, int idx);
33
34 static int rtrefcroot_rec_count(void *obj, int startoff);
35 static int rtrefcroot_rec_offset(void *obj, int startoff, int idx);
36 static int rtrefcroot_key_count(void *obj, int startoff);
37 static int rtrefcroot_key_offset(void *obj, int startoff, int idx);
38 static int rtrefcroot_ptr_count(void *obj, int startoff);
39 static int rtrefcroot_ptr_offset(void *obj, int startoff, int idx);
40
41 #define OFF(f) bitize(offsetof(xfs_bmdr_block_t, bb_ ## f))
42 const field_t bmroota_flds[] = {
43 { "level", FLDT_UINT16D, OI(OFF(level)), C1, 0, TYP_NONE },
44 { "numrecs", FLDT_UINT16D, OI(OFF(numrecs)), C1, 0, TYP_NONE },
45 { "keys", FLDT_BMROOTAKEY, bmroota_key_offset, bmroota_key_count,
46 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE },
47 { "ptrs", FLDT_BMROOTAPTR, bmroota_ptr_offset, bmroota_ptr_count,
48 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_BMAPBTA },
49 { NULL }
50 };
51 const field_t bmrootd_flds[] = {
52 { "level", FLDT_UINT16D, OI(OFF(level)), C1, 0, TYP_NONE },
53 { "numrecs", FLDT_UINT16D, OI(OFF(numrecs)), C1, 0, TYP_NONE },
54 { "keys", FLDT_BMROOTDKEY, bmrootd_key_offset, bmrootd_key_count,
55 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE },
56 { "ptrs", FLDT_BMROOTDPTR, bmrootd_ptr_offset, bmrootd_ptr_count,
57 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_BMAPBTD },
58 { NULL }
59 };
60
61 #define KOFF(f) bitize(offsetof(xfs_bmdr_key_t, br_ ## f))
62 const field_t bmroota_key_flds[] = {
63 { "startoff", FLDT_DFILOFFA, OI(KOFF(startoff)), C1, 0, TYP_NONE },
64 { NULL }
65 };
66 const field_t bmrootd_key_flds[] = {
67 { "startoff", FLDT_DFILOFFD, OI(KOFF(startoff)), C1, 0, TYP_NONE },
68 { NULL }
69 };
70
71 /* realtime rmap btree root */
72 const field_t rtrmaproot_flds[] = {
73 { "level", FLDT_UINT16D, OI(OFF(level)), C1, 0, TYP_NONE },
74 { "numrecs", FLDT_UINT16D, OI(OFF(numrecs)), C1, 0, TYP_NONE },
75 { "recs", FLDT_RTRMAPBTREC, rtrmaproot_rec_offset, rtrmaproot_rec_count,
76 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE },
77 { "keys", FLDT_RTRMAPBTKEY, rtrmaproot_key_offset, rtrmaproot_key_count,
78 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE },
79 { "ptrs", FLDT_RTRMAPBTPTR, rtrmaproot_ptr_offset, rtrmaproot_ptr_count,
80 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_RTRMAPBT },
81 { NULL }
82 };
83
84 /* realtime refcount btree root */
85 const field_t rtrefcroot_flds[] = {
86 { "level", FLDT_UINT16D, OI(OFF(level)), C1, 0, TYP_NONE },
87 { "numrecs", FLDT_UINT16D, OI(OFF(numrecs)), C1, 0, TYP_NONE },
88 { "recs", FLDT_RTREFCBTREC, rtrefcroot_rec_offset, rtrefcroot_rec_count,
89 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE },
90 { "keys", FLDT_RTREFCBTKEY, rtrefcroot_key_offset, rtrefcroot_key_count,
91 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE },
92 { "ptrs", FLDT_RTREFCBTPTR, rtrefcroot_ptr_offset, rtrefcroot_ptr_count,
93 FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_RTREFCBT },
94 { NULL }
95 };
96 #undef OFF
97
98 static int
99 bmroota_key_count(
100 void *obj,
101 int startoff)
102 {
103 xfs_bmdr_block_t *block;
104 #ifdef DEBUG
105 struct xfs_dinode *dip = obj;
106 #endif
107
108 ASSERT(bitoffs(startoff) == 0);
109 ASSERT(obj == iocur_top->data);
110 block = (xfs_bmdr_block_t *)((char *)obj + byteize(startoff));
111 ASSERT(dip->di_forkoff != 0 && (char *)block == XFS_DFORK_APTR(dip));
112 ASSERT(be16_to_cpu(block->bb_level) > 0);
113 return be16_to_cpu(block->bb_numrecs);
114 }
115
116 static int
117 bmroota_key_offset(
118 void *obj,
119 int startoff,
120 int idx)
121 {
122 xfs_bmdr_block_t *block;
123 #ifdef DEBUG
124 struct xfs_dinode *dip = obj;
125 #endif
126 xfs_bmdr_key_t *kp;
127
128 ASSERT(bitoffs(startoff) == 0);
129 ASSERT(obj == iocur_top->data);
130 block = (xfs_bmdr_block_t *)((char *)obj + byteize(startoff));
131 ASSERT(dip->di_forkoff != 0 && (char *)block == XFS_DFORK_APTR(dip));
132 ASSERT(be16_to_cpu(block->bb_level) > 0);
133 kp = xfs_bmdr_key_addr(block, idx);
134 return bitize((int)((char *)kp - (char *)block));
135 }
136
137 static int
138 bmroota_ptr_count(
139 void *obj,
140 int startoff)
141 {
142 xfs_bmdr_block_t *block;
143 #ifdef DEBUG
144 struct xfs_dinode *dip = obj;
145 #endif
146
147 ASSERT(bitoffs(startoff) == 0);
148 ASSERT(obj == iocur_top->data);
149 block = (xfs_bmdr_block_t *)((char *)obj + byteize(startoff));
150 ASSERT(dip->di_forkoff != 0 && (char *)block == XFS_DFORK_APTR(dip));
151 ASSERT(be16_to_cpu(block->bb_level) > 0);
152 return be16_to_cpu(block->bb_numrecs);
153 }
154
155 static int
156 bmroota_ptr_offset(
157 void *obj,
158 int startoff,
159 int idx)
160 {
161 xfs_bmdr_block_t *block;
162 struct xfs_dinode *dip;
163 xfs_bmdr_ptr_t *pp;
164
165 ASSERT(bitoffs(startoff) == 0);
166 ASSERT(obj == iocur_top->data);
167 dip = obj;
168 block = (xfs_bmdr_block_t *)((char *)obj + byteize(startoff));
169 ASSERT(dip->di_forkoff != 0 && (char *)block == XFS_DFORK_APTR(dip));
170 ASSERT(be16_to_cpu(block->bb_level) > 0);
171 pp = xfs_bmdr_ptr_addr(block, idx,
172 libxfs_bmdr_maxrecs(XFS_DFORK_ASIZE(dip, mp), 0));
173 return bitize((int)((char *)pp - (char *)block));
174 }
175
176 int
177 bmroota_size(
178 void *obj,
179 int startoff,
180 int idx)
181 {
182 struct xfs_dinode *dip;
183 #ifdef DEBUG
184 xfs_bmdr_block_t *block;
185 #endif
186
187 ASSERT(bitoffs(startoff) == 0);
188 ASSERT(obj == iocur_top->data);
189 ASSERT(idx == 0);
190 dip = obj;
191 #ifdef DEBUG
192 block = (xfs_bmdr_block_t *)((char *)obj + byteize(startoff));
193 ASSERT(dip->di_forkoff != 0 && (char *)block == XFS_DFORK_APTR(dip));
194 #endif
195 return bitize((int)XFS_DFORK_ASIZE(dip, mp));
196 }
197
198 static int
199 bmrootd_key_count(
200 void *obj,
201 int startoff)
202 {
203 xfs_bmdr_block_t *block;
204 #ifdef DEBUG
205 struct xfs_dinode *dip = obj;
206 #endif
207
208 ASSERT(bitoffs(startoff) == 0);
209 ASSERT(obj == iocur_top->data);
210 block = (xfs_bmdr_block_t *)((char *)obj + byteize(startoff));
211 ASSERT((char *)block == XFS_DFORK_DPTR(dip));
212 ASSERT(be16_to_cpu(block->bb_level) > 0);
213 return be16_to_cpu(block->bb_numrecs);
214 }
215
216 static int
217 bmrootd_key_offset(
218 void *obj,
219 int startoff,
220 int idx)
221 {
222 xfs_bmdr_block_t *block;
223 xfs_bmdr_key_t *kp;
224
225 ASSERT(bitoffs(startoff) == 0);
226 ASSERT(obj == iocur_top->data);
227 block = (xfs_bmdr_block_t *)((char *)obj + byteize(startoff));
228 ASSERT(be16_to_cpu(block->bb_level) > 0);
229 kp = xfs_bmdr_key_addr(block, idx);
230 return bitize((int)((char *)kp - (char *)block));
231 }
232
233 static int
234 bmrootd_ptr_count(
235 void *obj,
236 int startoff)
237 {
238 xfs_bmdr_block_t *block;
239 #ifdef DEBUG
240 struct xfs_dinode *dip = obj;
241 #endif
242
243 ASSERT(bitoffs(startoff) == 0);
244 ASSERT(obj == iocur_top->data);
245 block = (xfs_bmdr_block_t *)((char *)obj + byteize(startoff));
246 ASSERT((char *)block == XFS_DFORK_DPTR(dip));
247 ASSERT(be16_to_cpu(block->bb_level) > 0);
248 return be16_to_cpu(block->bb_numrecs);
249 }
250
251 static int
252 bmrootd_ptr_offset(
253 void *obj,
254 int startoff,
255 int idx)
256 {
257 xfs_bmdr_block_t *block;
258 xfs_bmdr_ptr_t *pp;
259 struct xfs_dinode *dip;
260
261 ASSERT(bitoffs(startoff) == 0);
262 ASSERT(obj == iocur_top->data);
263 dip = obj;
264 block = (xfs_bmdr_block_t *)((char *)obj + byteize(startoff));
265 ASSERT(be16_to_cpu(block->bb_level) > 0);
266 pp = xfs_bmdr_ptr_addr(block, idx,
267 libxfs_bmdr_maxrecs(XFS_DFORK_DSIZE(dip, mp), 0));
268 return bitize((int)((char *)pp - (char *)block));
269 }
270
271 int
272 bmrootd_size(
273 void *obj,
274 int startoff,
275 int idx)
276 {
277 struct xfs_dinode *dip;
278
279 ASSERT(bitoffs(startoff) == 0);
280 ASSERT(obj == iocur_top->data);
281 ASSERT(idx == 0);
282 dip = obj;
283 return bitize((int)XFS_DFORK_DSIZE(dip, mp));
284 }
285
286 /* realtime rmap root */
287 static int
288 rtrmaproot_rec_count(
289 void *obj,
290 int startoff)
291 {
292 struct xfs_dinode *dip = obj;
293 struct xfs_rtrmap_root *block = XFS_DFORK_DPTR(dip);
294
295 ASSERT(block == obj + byteize(startoff));
296
297 if (be16_to_cpu(block->bb_level) > 0)
298 return 0;
299 return be16_to_cpu(block->bb_numrecs);
300 }
301
302 static int
303 rtrmaproot_rec_offset(
304 void *obj,
305 int startoff,
306 int idx)
307 {
308 struct xfs_dinode *dip = obj;
309 struct xfs_rtrmap_root *block = XFS_DFORK_DPTR(dip);
310 struct xfs_rmap_rec *kp;
311
312 ASSERT(block == obj + byteize(startoff));
313 ASSERT(be16_to_cpu(block->bb_level) == 0);
314
315 kp = xfs_rtrmap_droot_rec_addr(block, idx);
316 return bitize((int)((char *)kp - (char *)block));
317 }
318
319 static int
320 rtrmaproot_key_count(
321 void *obj,
322 int startoff)
323 {
324 struct xfs_dinode *dip = obj;
325 struct xfs_rtrmap_root *block = XFS_DFORK_DPTR(dip);
326
327 ASSERT(block == obj + byteize(startoff));
328
329 if (be16_to_cpu(block->bb_level) == 0)
330 return 0;
331 return be16_to_cpu(block->bb_numrecs);
332 }
333
334 static int
335 rtrmaproot_key_offset(
336 void *obj,
337 int startoff,
338 int idx)
339 {
340 struct xfs_dinode *dip = obj;
341 struct xfs_rtrmap_root *block = XFS_DFORK_DPTR(dip);
342 struct xfs_rmap_key *kp;
343
344 ASSERT(block == obj + byteize(startoff));
345 ASSERT(be16_to_cpu(block->bb_level) > 0);
346
347 kp = xfs_rtrmap_droot_key_addr(block, idx);
348 return bitize((int)((char *)kp - (char *)block));
349 }
350
351 static int
352 rtrmaproot_ptr_count(
353 void *obj,
354 int startoff)
355 {
356 struct xfs_dinode *dip = obj;
357 struct xfs_rtrmap_root *block = XFS_DFORK_DPTR(dip);
358
359 ASSERT(block == obj + byteize(startoff));
360
361 if (be16_to_cpu(block->bb_level) == 0)
362 return 0;
363 return be16_to_cpu(block->bb_numrecs);
364 }
365
366 static int
367 rtrmaproot_ptr_offset(
368 void *obj,
369 int startoff,
370 int idx)
371 {
372 struct xfs_dinode *dip = obj;
373 struct xfs_rtrmap_root *block = XFS_DFORK_DPTR(dip);
374 xfs_rtrmap_ptr_t *pp;
375 int dmxr;
376
377 ASSERT(block == obj + byteize(startoff));
378 ASSERT(be16_to_cpu(block->bb_level) > 0);
379
380 dmxr = libxfs_rtrmapbt_droot_maxrecs(XFS_DFORK_DSIZE(dip, mp), false);
381 pp = xfs_rtrmap_droot_ptr_addr(block, idx, dmxr);
382 return bitize((int)((char *)pp - (char *)block));
383 }
384
385 int
386 rtrmaproot_size(
387 void *obj,
388 int startoff,
389 int idx)
390 {
391 struct xfs_dinode *dip;
392
393 ASSERT(bitoffs(startoff) == 0);
394 ASSERT(obj == iocur_top->data);
395 ASSERT(idx == 0);
396 dip = obj;
397 return bitize((int)XFS_DFORK_DSIZE(dip, mp));
398 }
399
400 /* realtime refcount root */
401 static int
402 rtrefcroot_rec_count(
403 void *obj,
404 int startoff)
405 {
406 struct xfs_dinode *dip = obj;
407 struct xfs_rtrefcount_root *block = XFS_DFORK_DPTR(dip);
408
409 ASSERT(block == obj + byteize(startoff));
410
411 if (be16_to_cpu(block->bb_level) > 0)
412 return 0;
413 return be16_to_cpu(block->bb_numrecs);
414 }
415
416 static int
417 rtrefcroot_rec_offset(
418 void *obj,
419 int startoff,
420 int idx)
421 {
422 struct xfs_dinode *dip = obj;
423 struct xfs_rtrefcount_root *block = XFS_DFORK_DPTR(dip);
424 struct xfs_refcount_rec *kp;
425
426 ASSERT(block == obj + byteize(startoff));
427 ASSERT(be16_to_cpu(block->bb_level) == 0);
428
429 kp = xfs_rtrefcount_droot_rec_addr(block, idx);
430 return bitize((int)((char *)kp - (char *)block));
431 }
432
433 static int
434 rtrefcroot_key_count(
435 void *obj,
436 int startoff)
437 {
438 struct xfs_dinode *dip = obj;
439 struct xfs_rtrefcount_root *block = XFS_DFORK_DPTR(dip);
440
441 ASSERT(block == obj + byteize(startoff));
442
443 if (be16_to_cpu(block->bb_level) == 0)
444 return 0;
445 return be16_to_cpu(block->bb_numrecs);
446 }
447
448 static int
449 rtrefcroot_key_offset(
450 void *obj,
451 int startoff,
452 int idx)
453 {
454 struct xfs_dinode *dip = obj;
455 struct xfs_rtrefcount_root *block = XFS_DFORK_DPTR(dip);
456 struct xfs_refcount_key *kp;
457
458 ASSERT(block == obj + byteize(startoff));
459 ASSERT(be16_to_cpu(block->bb_level) > 0);
460
461 kp = xfs_rtrefcount_droot_key_addr(block, idx);
462 return bitize((int)((char *)kp - (char *)block));
463 }
464
465 static int
466 rtrefcroot_ptr_count(
467 void *obj,
468 int startoff)
469 {
470 struct xfs_dinode *dip = obj;
471 struct xfs_rtrefcount_root *block = XFS_DFORK_DPTR(dip);
472
473 ASSERT(block == obj + byteize(startoff));
474
475 if (be16_to_cpu(block->bb_level) == 0)
476 return 0;
477 return be16_to_cpu(block->bb_numrecs);
478 }
479
480 static int
481 rtrefcroot_ptr_offset(
482 void *obj,
483 int startoff,
484 int idx)
485 {
486 struct xfs_dinode *dip = obj;
487 struct xfs_rtrefcount_root *block = XFS_DFORK_DPTR(dip);
488 xfs_rtrefcount_ptr_t *pp;
489 int dmxr;
490
491 ASSERT(block == obj + byteize(startoff));
492 ASSERT(be16_to_cpu(block->bb_level) > 0);
493
494 dmxr = libxfs_rtrefcountbt_droot_maxrecs(XFS_DFORK_DSIZE(dip, mp),
495 false);
496 pp = xfs_rtrefcount_droot_ptr_addr(block, idx, dmxr);
497 return bitize((int)((char *)pp - (char *)block));
498 }
499
500 int
501 rtrefcroot_size(
502 void *obj,
503 int startoff,
504 int idx)
505 {
506 struct xfs_dinode *dip;
507
508 ASSERT(bitoffs(startoff) == 0);
509 ASSERT(obj == iocur_top->data);
510 ASSERT(idx == 0);
511 dip = obj;
512 return bitize((int)XFS_DFORK_DSIZE(dip, mp));
513 }