]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - db/dir2.c
Add a missing build dependency for building Debian packages (thanks to
[thirdparty/xfsprogs-dev.git] / db / dir2.c
CommitLineData
2bd0ea18 1/*
0d3e0b37 2 * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
2bd0ea18
NS
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
33#include <libxfs.h>
34#include "bit.h"
35#include "type.h"
36#include "faddr.h"
37#include "fprint.h"
38#include "field.h"
39#include "dir.h"
40#include "dir2.h"
41#include "mount.h"
42#include "data.h"
43
44static int dir2_block_hdr_count(void *obj, int startoff);
45static int dir2_block_leaf_count(void *obj, int startoff);
46static int dir2_block_leaf_offset(void *obj, int startoff, int idx);
47static int dir2_block_tail_count(void *obj, int startoff);
48static int dir2_block_tail_offset(void *obj, int startoff, int idx);
49static int dir2_block_u_count(void *obj, int startoff);
50static int dir2_block_u_offset(void *obj, int startoff, int idx);
51static int dir2_data_union_freetag_count(void *obj, int startoff);
52static int dir2_data_union_inumber_count(void *obj, int startoff);
53static int dir2_data_union_length_count(void *obj, int startoff);
54static int dir2_data_union_name_count(void *obj, int startoff);
55static int dir2_data_union_namelen_count(void *obj, int startoff);
56static int dir2_data_union_tag_count(void *obj, int startoff);
57static int dir2_data_union_tag_offset(void *obj, int startoff, int idx);
58static int dir2_data_hdr_count(void *obj, int startoff);
59static int dir2_data_u_count(void *obj, int startoff);
60static int dir2_data_u_offset(void *obj, int startoff, int idx);
61static int dir2_free_bests_count(void *obj, int startoff);
62static int dir2_free_hdr_count(void *obj, int startoff);
63static int dir2_leaf_bests_count(void *obj, int startoff);
64static int dir2_leaf_bests_offset(void *obj, int startoff, int idx);
65static int dir2_leaf_ents_count(void *obj, int startoff);
66static int dir2_leaf_hdr_count(void *obj, int startoff);
67static int dir2_leaf_tail_count(void *obj, int startoff);
68static int dir2_leaf_tail_offset(void *obj, int startoff, int idx);
69static int dir2_node_btree_count(void *obj, int startoff);
70static int dir2_node_hdr_count(void *obj, int startoff);
71
72const field_t dir2_hfld[] = {
73 { "", FLDT_DIR2, OI(0), C1, 0, TYP_NONE },
74 { NULL }
75};
76
77#define BOFF(f) bitize(offsetof(xfs_dir2_block_t, f))
78#define DOFF(f) bitize(offsetof(xfs_dir2_data_t, f))
79#define FOFF(f) bitize(offsetof(xfs_dir2_free_t, f))
80#define LOFF(f) bitize(offsetof(xfs_dir2_leaf_t, f))
81#define NOFF(f) bitize(offsetof(xfs_da_intnode_t, f))
82const field_t dir2_flds[] = {
83 { "bhdr", FLDT_DIR2_DATA_HDR, OI(BOFF(hdr)), dir2_block_hdr_count,
84 FLD_COUNT, TYP_NONE },
85 { "bu", FLDT_DIR2_DATA_UNION, dir2_block_u_offset, dir2_block_u_count,
86 FLD_ARRAY|FLD_OFFSET|FLD_COUNT, TYP_NONE },
87 { "bleaf", FLDT_DIR2_LEAF_ENTRY, dir2_block_leaf_offset,
88 dir2_block_leaf_count, FLD_ARRAY|FLD_OFFSET|FLD_COUNT, TYP_NONE },
89 { "btail", FLDT_DIR2_BLOCK_TAIL, dir2_block_tail_offset,
90 dir2_block_tail_count, FLD_OFFSET|FLD_COUNT, TYP_NONE },
91 { "dhdr", FLDT_DIR2_DATA_HDR, OI(DOFF(hdr)), dir2_data_hdr_count,
92 FLD_COUNT, TYP_NONE },
93 { "du", FLDT_DIR2_DATA_UNION, dir2_data_u_offset, dir2_data_u_count,
94 FLD_ARRAY|FLD_OFFSET|FLD_COUNT, TYP_NONE },
95 { "lhdr", FLDT_DIR2_LEAF_HDR, OI(LOFF(hdr)), dir2_leaf_hdr_count,
96 FLD_COUNT, TYP_NONE },
97 { "lbests", FLDT_DIR2_DATA_OFF, dir2_leaf_bests_offset,
98 dir2_leaf_bests_count, FLD_ARRAY|FLD_OFFSET|FLD_COUNT, TYP_NONE },
99 { "lents", FLDT_DIR2_LEAF_ENTRY, OI(LOFF(ents)), dir2_leaf_ents_count,
100 FLD_ARRAY|FLD_COUNT, TYP_NONE },
101 { "ltail", FLDT_DIR2_LEAF_TAIL, dir2_leaf_tail_offset,
102 dir2_leaf_tail_count, FLD_OFFSET|FLD_COUNT, TYP_NONE },
103 { "nhdr", FLDT_DIR_NODE_HDR, OI(NOFF(hdr)), dir2_node_hdr_count,
104 FLD_COUNT, TYP_NONE },
105 { "nbtree", FLDT_DIR_NODE_ENTRY, OI(NOFF(btree)), dir2_node_btree_count,
106 FLD_ARRAY|FLD_COUNT, TYP_NONE },
107 { "fhdr", FLDT_DIR2_FREE_HDR, OI(FOFF(hdr)), dir2_free_hdr_count,
108 FLD_COUNT, TYP_NONE },
109 { "fbests", FLDT_DIR2_DATA_OFFNZ, OI(FOFF(bests)),
110 dir2_free_bests_count, FLD_ARRAY|FLD_COUNT, TYP_NONE },
111 { NULL }
112};
113
114#define BTOFF(f) bitize(offsetof(xfs_dir2_block_tail_t, f))
115const field_t dir2_block_tail_flds[] = {
116 { "count", FLDT_UINT32D, OI(BTOFF(count)), C1, 0, TYP_NONE },
117 { "stale", FLDT_UINT32D, OI(BTOFF(stale)), C1, 0, TYP_NONE },
118 { NULL }
119};
120
121#define DFOFF(f) bitize(offsetof(xfs_dir2_data_free_t, f))
122const field_t dir2_data_free_flds[] = {
123 { "offset", FLDT_DIR2_DATA_OFF, OI(DFOFF(offset)), C1, 0, TYP_NONE },
124 { "length", FLDT_DIR2_DATA_OFF, OI(DFOFF(length)), C1, 0, TYP_NONE },
125 { NULL }
126};
127
128#define DHOFF(f) bitize(offsetof(xfs_dir2_data_hdr_t, f))
129const field_t dir2_data_hdr_flds[] = {
130 { "magic", FLDT_UINT32X, OI(DHOFF(magic)), C1, 0, TYP_NONE },
131 { "bestfree", FLDT_DIR2_DATA_FREE, OI(DHOFF(bestfree)),
132 CI(XFS_DIR2_DATA_FD_COUNT), FLD_ARRAY, TYP_NONE },
133 { NULL }
134};
135
136#define DEOFF(f) bitize(offsetof(xfs_dir2_data_entry_t, f))
137#define DUOFF(f) bitize(offsetof(xfs_dir2_data_unused_t, f))
138const field_t dir2_data_union_flds[] = {
139 { "freetag", FLDT_UINT16X, OI(DUOFF(freetag)),
140 dir2_data_union_freetag_count, FLD_COUNT, TYP_NONE },
141 { "inumber", FLDT_INO, OI(DEOFF(inumber)),
142 dir2_data_union_inumber_count, FLD_COUNT, TYP_INODE },
143 { "length", FLDT_DIR2_DATA_OFF, OI(DUOFF(length)),
144 dir2_data_union_length_count, FLD_COUNT, TYP_NONE },
145 { "namelen", FLDT_UINT8D, OI(DEOFF(namelen)),
146 dir2_data_union_namelen_count, FLD_COUNT, TYP_NONE },
147 { "name", FLDT_CHARNS, OI(DEOFF(name)), dir2_data_union_name_count,
148 FLD_COUNT, TYP_NONE },
149 { "tag", FLDT_DIR2_DATA_OFF, dir2_data_union_tag_offset,
150 dir2_data_union_tag_count, FLD_OFFSET|FLD_COUNT, TYP_NONE },
151 { NULL }
152};
153
154#define LEOFF(f) bitize(offsetof(xfs_dir2_leaf_entry_t, f))
155const field_t dir2_leaf_entry_flds[] = {
156 { "hashval", FLDT_UINT32X, OI(LEOFF(hashval)), C1, 0, TYP_NONE },
157 { "address", FLDT_UINT32X, OI(LEOFF(address)), C1, 0, TYP_NONE },
158 { NULL }
159};
160
161#define LHOFF(f) bitize(offsetof(xfs_dir2_leaf_hdr_t, f))
162const field_t dir2_leaf_hdr_flds[] = {
163 { "info", FLDT_DIR_BLKINFO, OI(LHOFF(info)), C1, 0, TYP_NONE },
164 { "count", FLDT_UINT16D, OI(LHOFF(count)), C1, 0, TYP_NONE },
165 { "stale", FLDT_UINT16D, OI(LHOFF(stale)), C1, 0, TYP_NONE },
166 { NULL }
167};
168
169#define LTOFF(f) bitize(offsetof(xfs_dir2_leaf_tail_t, f))
170const field_t dir2_leaf_tail_flds[] = {
171 { "bestcount", FLDT_UINT32D, OI(LTOFF(bestcount)), C1, 0, TYP_NONE },
172 { NULL }
173};
174
175#define FHOFF(f) bitize(offsetof(xfs_dir2_free_hdr_t, f))
176const field_t dir2_free_hdr_flds[] = {
177 { "magic", FLDT_UINT32X, OI(FHOFF(magic)), C1, 0, TYP_NONE },
178 { "firstdb", FLDT_INT32D, OI(FHOFF(firstdb)), C1, 0, TYP_NONE },
179 { "nvalid", FLDT_INT32D, OI(FHOFF(nvalid)), C1, 0, TYP_NONE },
180 { "nused", FLDT_INT32D, OI(FHOFF(nused)), C1, 0, TYP_NONE },
181 { NULL }
182};
183
184/*ARGSUSED*/
185static int
186dir2_block_hdr_count(
187 void *obj,
188 int startoff)
189{
190 xfs_dir2_block_t *block;
191
192 ASSERT(startoff == 0);
193 block = obj;
194 return INT_GET(block->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC;
195}
196
197/*ARGSUSED*/
198static int
199dir2_block_leaf_count(
200 void *obj,
201 int startoff)
202{
203 xfs_dir2_block_t *block;
204 xfs_dir2_block_tail_t *btp;
205
206 ASSERT(startoff == 0);
207 block = obj;
208 if (INT_GET(block->hdr.magic, ARCH_CONVERT) != XFS_DIR2_BLOCK_MAGIC)
209 return 0;
210 btp = XFS_DIR2_BLOCK_TAIL_P(mp, block);
211 return INT_GET(btp->count, ARCH_CONVERT);
212}
213
214/*ARGSUSED*/
215static int
216dir2_block_leaf_offset(
217 void *obj,
218 int startoff,
219 int idx)
220{
221 xfs_dir2_block_t *block;
222 xfs_dir2_block_tail_t *btp;
223 xfs_dir2_leaf_entry_t *lep;
224
225 ASSERT(startoff == 0);
226 block = obj;
227 ASSERT(INT_GET(block->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC);
228 btp = XFS_DIR2_BLOCK_TAIL_P(mp, block);
229 lep = XFS_DIR2_BLOCK_LEAF_P_ARCH(btp, ARCH_CONVERT) + idx;
230 return bitize((int)((char *)lep - (char *)block));
231}
232
233/*ARGSUSED*/
234static int
235dir2_block_tail_count(
236 void *obj,
237 int startoff)
238{
239 xfs_dir2_block_t *block;
240
241 ASSERT(startoff == 0);
242 block = obj;
243 return INT_GET(block->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC;
244}
245
246/*ARGSUSED*/
247static int
248dir2_block_tail_offset(
249 void *obj,
250 int startoff,
251 int idx)
252{
253 xfs_dir2_block_t *block;
254 xfs_dir2_block_tail_t *btp;
255
256 ASSERT(startoff == 0);
257 ASSERT(idx == 0);
258 block = obj;
259 ASSERT(INT_GET(block->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC);
260 btp = XFS_DIR2_BLOCK_TAIL_P(mp, block);
261 return bitize((int)((char *)btp - (char *)block));
262}
263
264/*ARGSUSED*/
265static int
266dir2_block_u_count(
267 void *obj,
268 int startoff)
269{
270 xfs_dir2_block_t *block;
271 xfs_dir2_block_tail_t *btp;
272 xfs_dir2_data_entry_t *dep;
273 xfs_dir2_data_unused_t *dup;
274 char *endptr;
275 int i;
276 char *ptr;
277
278 ASSERT(startoff == 0);
279 block = obj;
280 if (INT_GET(block->hdr.magic, ARCH_CONVERT) != XFS_DIR2_BLOCK_MAGIC)
281 return 0;
282 btp = XFS_DIR2_BLOCK_TAIL_P(mp, block);
283 ptr = (char *)block->u;
284 endptr = (char *)XFS_DIR2_BLOCK_LEAF_P_ARCH(btp, ARCH_CONVERT);
285 for (i = 0; ptr < endptr; i++) {
286 dup = (xfs_dir2_data_unused_t *)ptr;
287 if (INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG)
288 ptr += INT_GET(dup->length, ARCH_CONVERT);
289 else {
290 dep = (xfs_dir2_data_entry_t *)ptr;
291 ptr += XFS_DIR2_DATA_ENTSIZE(dep->namelen);
292 }
293 }
294 return i;
295}
296
297/*ARGSUSED*/
298static int
299dir2_block_u_offset(
300 void *obj,
301 int startoff,
302 int idx)
303{
304 xfs_dir2_block_t *block;
305 xfs_dir2_block_tail_t *btp;
306 xfs_dir2_data_entry_t *dep;
307 xfs_dir2_data_unused_t *dup;
308 /*REFERENCED*/
309 char *endptr;
310 int i;
311 char *ptr;
312
313 ASSERT(startoff == 0);
314 block = obj;
315 ASSERT(INT_GET(block->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC);
316 btp = XFS_DIR2_BLOCK_TAIL_P(mp, block);
317 ptr = (char *)block->u;
318 endptr = (char *)XFS_DIR2_BLOCK_LEAF_P_ARCH(btp, ARCH_CONVERT);
319 for (i = 0; i < idx; i++) {
320 ASSERT(ptr < endptr);
321 dup = (xfs_dir2_data_unused_t *)ptr;
322 if (INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG)
323 ptr += INT_GET(dup->length, ARCH_CONVERT);
324 else {
325 dep = (xfs_dir2_data_entry_t *)ptr;
326 ptr += XFS_DIR2_DATA_ENTSIZE(dep->namelen);
327 }
328 }
329 return bitize((int)(ptr - (char *)block));
330}
331
332static int
333dir2_data_union_freetag_count(
334 void *obj,
335 int startoff)
336{
337 xfs_dir2_data_unused_t *dup;
338 char *end;
339
340 ASSERT(bitoffs(startoff) == 0);
341 dup = (xfs_dir2_data_unused_t *)((char *)obj + byteize(startoff));
342 end = (char *)&dup->freetag + sizeof(dup->freetag);
343 return end <= (char *)obj + mp->m_dirblksize &&
344 INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG;
345}
346
347static int
348dir2_data_union_inumber_count(
349 void *obj,
350 int startoff)
351{
352 xfs_dir2_data_entry_t *dep;
353 xfs_dir2_data_unused_t *dup;
354 char *end;
355
356 ASSERT(bitoffs(startoff) == 0);
357 dup = (xfs_dir2_data_unused_t *)((char *)obj + byteize(startoff));
358 dep = (xfs_dir2_data_entry_t *)dup;
359 end = (char *)&dep->inumber + sizeof(dep->inumber);
360 return end <= (char *)obj + mp->m_dirblksize &&
361 INT_GET(dup->freetag, ARCH_CONVERT) != XFS_DIR2_DATA_FREE_TAG;
362}
363
364static int
365dir2_data_union_length_count(
366 void *obj,
367 int startoff)
368{
369 xfs_dir2_data_unused_t *dup;
370 char *end;
371
372 ASSERT(bitoffs(startoff) == 0);
373 dup = (xfs_dir2_data_unused_t *)((char *)obj + byteize(startoff));
374 end = (char *)&dup->length + sizeof(dup->length);
375 return end <= (char *)obj + mp->m_dirblksize &&
376 INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG;
377}
378
379static int
380dir2_data_union_name_count(
381 void *obj,
382 int startoff)
383{
384 xfs_dir2_data_entry_t *dep;
385 xfs_dir2_data_unused_t *dup;
386 char *end;
387
388 ASSERT(bitoffs(startoff) == 0);
389 dup = (xfs_dir2_data_unused_t *)((char *)obj + byteize(startoff));
390 dep = (xfs_dir2_data_entry_t *)dup;
391 end = (char *)&dep->namelen + sizeof(dep->namelen);
392 if (end >= (char *)obj + mp->m_dirblksize ||
393 INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG)
394 return 0;
395 end = (char *)&dep->name[0] + dep->namelen;
396 return end <= (char *)obj + mp->m_dirblksize ? dep->namelen : 0;
397}
398
399static int
400dir2_data_union_namelen_count(
401 void *obj,
402 int startoff)
403{
404 xfs_dir2_data_entry_t *dep;
405 xfs_dir2_data_unused_t *dup;
406 char *end;
407
408 ASSERT(bitoffs(startoff) == 0);
409 dup = (xfs_dir2_data_unused_t *)((char *)obj + byteize(startoff));
410 dep = (xfs_dir2_data_entry_t *)dup;
411 end = (char *)&dep->namelen + sizeof(dep->namelen);
412 return end <= (char *)obj + mp->m_dirblksize &&
413 INT_GET(dup->freetag, ARCH_CONVERT) != XFS_DIR2_DATA_FREE_TAG;
414}
415
416static int
417dir2_data_union_tag_count(
418 void *obj,
419 int startoff)
420{
421 xfs_dir2_data_entry_t *dep;
422 xfs_dir2_data_unused_t *dup;
423 char *end;
424 xfs_dir2_data_off_t *tagp;
425
426 ASSERT(bitoffs(startoff) == 0);
427 dup = (xfs_dir2_data_unused_t *)((char *)obj + byteize(startoff));
428 dep = (xfs_dir2_data_entry_t *)dup;
429 end = (char *)&dup->freetag + sizeof(dup->freetag);
430 if (end > (char *)obj + mp->m_dirblksize)
431 return 0;
432 if (INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG) {
433 end = (char *)&dup->length + sizeof(dup->length);
434 if (end > (char *)obj + mp->m_dirblksize)
435 return 0;
436 tagp = XFS_DIR2_DATA_UNUSED_TAG_P_ARCH(dup, ARCH_CONVERT);
437 } else {
438 end = (char *)&dep->namelen + sizeof(dep->namelen);
439 if (end > (char *)obj + mp->m_dirblksize)
440 return 0;
441 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
442 }
443 end = (char *)tagp + sizeof(*tagp);
444 return end <= (char *)obj + mp->m_dirblksize;
445}
446
447/*ARGSUSED*/
448static int
449dir2_data_union_tag_offset(
450 void *obj,
451 int startoff,
452 int idx)
453{
454 xfs_dir2_data_entry_t *dep;
455 xfs_dir2_data_unused_t *dup;
456
457 ASSERT(bitoffs(startoff) == 0);
458 ASSERT(idx == 0);
459 dup = (xfs_dir2_data_unused_t *)((char *)obj + byteize(startoff));
460 if (INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG)
461 return bitize((int)((char *)XFS_DIR2_DATA_UNUSED_TAG_P_ARCH(dup, ARCH_CONVERT) -
462 (char *)dup));
463 dep = (xfs_dir2_data_entry_t *)dup;
464 return bitize((int)((char *)XFS_DIR2_DATA_ENTRY_TAG_P(dep) -
465 (char *)dep));
466}
467
468/*ARGSUSED*/
469static int
470dir2_data_hdr_count(
471 void *obj,
472 int startoff)
473{
474 xfs_dir2_data_t *data;
475
476 ASSERT(startoff == 0);
477 data = obj;
478 return INT_GET(data->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC;
479}
480
481/*ARGSUSED*/
482static int
483dir2_data_u_count(
484 void *obj,
485 int startoff)
486{
487 xfs_dir2_data_t *data;
488 xfs_dir2_data_entry_t *dep;
489 xfs_dir2_data_unused_t *dup;
490 char *endptr;
491 int i;
492 char *ptr;
493
494 ASSERT(startoff == 0);
495 data = obj;
496 if (INT_GET(data->hdr.magic, ARCH_CONVERT) != XFS_DIR2_DATA_MAGIC)
497 return 0;
498 ptr = (char *)data->u;
499 endptr = (char *)data + mp->m_dirblksize;
500 for (i = 0; ptr < endptr; i++) {
501 dup = (xfs_dir2_data_unused_t *)ptr;
502 if (INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG)
503 ptr += INT_GET(dup->length, ARCH_CONVERT);
504 else {
505 dep = (xfs_dir2_data_entry_t *)ptr;
506 ptr += XFS_DIR2_DATA_ENTSIZE(dep->namelen);
507 }
508 }
509 return i;
510}
511
512/*ARGSUSED*/
513static int
514dir2_data_u_offset(
515 void *obj,
516 int startoff,
517 int idx)
518{
519 xfs_dir2_data_t *data;
520 xfs_dir2_data_entry_t *dep;
521 xfs_dir2_data_unused_t *dup;
522 /*REFERENCED*/
523 char *endptr;
524 int i;
525 char *ptr;
526
527 ASSERT(startoff == 0);
528 data = obj;
529 ASSERT(INT_GET(data->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC);
530 ptr = (char *)data->u;
531 endptr = (char *)data + mp->m_dirblksize;
532 for (i = 0; i < idx; i++) {
533 ASSERT(ptr < endptr);
534 dup = (xfs_dir2_data_unused_t *)ptr;
535 if (INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG)
536 ptr += INT_GET(dup->length, ARCH_CONVERT);
537 else {
538 dep = (xfs_dir2_data_entry_t *)ptr;
539 ptr += XFS_DIR2_DATA_ENTSIZE(dep->namelen);
540 }
541 }
542 return bitize((int)(ptr - (char *)data));
543}
544
545/*ARGSUSED*/
546int
547dir2_data_union_size(
548 void *obj,
549 int startoff,
550 int idx)
551{
552 xfs_dir2_data_entry_t *dep;
553 xfs_dir2_data_unused_t *dup;
554
555 ASSERT(bitoffs(startoff) == 0);
556 ASSERT(idx == 0);
557 dup = (xfs_dir2_data_unused_t *)((char *)obj + byteize(startoff));
558 if (INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG)
559 return bitize(INT_GET(dup->length, ARCH_CONVERT));
560 else {
561 dep = (xfs_dir2_data_entry_t *)dup;
562 return bitize(XFS_DIR2_DATA_ENTSIZE(dep->namelen));
563 }
564}
565
566/*ARGSUSED*/
567static int
568dir2_free_bests_count(
569 void *obj,
570 int startoff)
571{
572 xfs_dir2_free_t *free;
573
574 ASSERT(startoff == 0);
575 free = obj;
576 if (INT_GET(free->hdr.magic, ARCH_CONVERT) != XFS_DIR2_FREE_MAGIC)
577 return 0;
578 return INT_GET(free->hdr.nvalid, ARCH_CONVERT);
579}
580
581/*ARGSUSED*/
582static int
583dir2_free_hdr_count(
584 void *obj,
585 int startoff)
586{
587 xfs_dir2_free_t *free;
588
589 ASSERT(startoff == 0);
590 free = obj;
591 return INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC;
592}
593
594/*ARGSUSED*/
595static int
596dir2_leaf_bests_count(
597 void *obj,
598 int startoff)
599{
600 xfs_dir2_leaf_t *leaf;
601 xfs_dir2_leaf_tail_t *ltp;
602
603 ASSERT(startoff == 0);
604 leaf = obj;
605 if (INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) != XFS_DIR2_LEAF1_MAGIC)
606 return 0;
607 ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
608 return INT_GET(ltp->bestcount, ARCH_CONVERT);
609}
610
611/*ARGSUSED*/
612static int
613dir2_leaf_bests_offset(
614 void *obj,
615 int startoff,
616 int idx)
617{
618 xfs_dir2_data_off_t *lbp;
619 xfs_dir2_leaf_t *leaf;
620 xfs_dir2_leaf_tail_t *ltp;
621
622 ASSERT(startoff == 0);
623 leaf = obj;
624 ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC);
625 ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
626 lbp = XFS_DIR2_LEAF_BESTS_P_ARCH(ltp, ARCH_CONVERT) + idx;
627 return bitize((int)((char *)lbp - (char *)leaf));
628}
629
630/*ARGSUSED*/
631static int
632dir2_leaf_ents_count(
633 void *obj,
634 int startoff)
635{
636 xfs_dir2_leaf_t *leaf;
637
638 ASSERT(startoff == 0);
639 leaf = obj;
640 if (INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) != XFS_DIR2_LEAF1_MAGIC &&
641 INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) != XFS_DIR2_LEAFN_MAGIC)
642 return 0;
643 return INT_GET(leaf->hdr.count, ARCH_CONVERT);
644}
645
646/*ARGSUSED*/
647static int
648dir2_leaf_hdr_count(
649 void *obj,
650 int startoff)
651{
652 xfs_dir2_leaf_t *leaf;
653
654 ASSERT(startoff == 0);
655 leaf = obj;
656 return INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC ||
657 INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC;
658}
659
660/*ARGSUSED*/
661static int
662dir2_leaf_tail_count(
663 void *obj,
664 int startoff)
665{
666 xfs_dir2_leaf_t *leaf;
667
668 ASSERT(startoff == 0);
669 leaf = obj;
670 return INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC;
671}
672
673/*ARGSUSED*/
674static int
675dir2_leaf_tail_offset(
676 void *obj,
677 int startoff,
678 int idx)
679{
680 xfs_dir2_leaf_t *leaf;
681 xfs_dir2_leaf_tail_t *ltp;
682
683 ASSERT(startoff == 0);
684 ASSERT(idx == 0);
685 leaf = obj;
686 ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC);
687 ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
688 return bitize((int)((char *)ltp - (char *)leaf));
689}
690
691/*ARGSUSED*/
692static int
693dir2_node_btree_count(
694 void *obj,
695 int startoff)
696{
697 xfs_da_intnode_t *node;
698
699 ASSERT(startoff == 0);
700 node = obj;
701 if (INT_GET(node->hdr.info.magic, ARCH_CONVERT) != XFS_DA_NODE_MAGIC)
702 return 0;
703 return INT_GET(node->hdr.count, ARCH_CONVERT);
704}
705
706/*ARGSUSED*/
707static int
708dir2_node_hdr_count(
709 void *obj,
710 int startoff)
711{
712 xfs_da_intnode_t *node;
713
714 ASSERT(startoff == 0);
715 node = obj;
716 return INT_GET(node->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC;
717}
718
719/*ARGSUSED*/
720int
721dir2_size(
722 void *obj,
723 int startoff,
724 int idx)
725{
726 return bitize(mp->m_dirblksize);
727}