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