]>
Commit | Line | Data |
---|---|---|
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 | } |