]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - db/inode.c
Merge whitespace changes over
[thirdparty/xfsprogs-dev.git] / db / inode.c
1 /*
2 * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
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 "command.h"
35 #include "type.h"
36 #include "faddr.h"
37 #include "fprint.h"
38 #include "field.h"
39 #include "inode.h"
40 #include "io.h"
41 #include "print.h"
42 #include "block.h"
43 #include "bit.h"
44 #include "output.h"
45 #include "init.h"
46
47 static int inode_a_bmbt_count(void *obj, int startoff);
48 static int inode_a_bmx_count(void *obj, int startoff);
49 static int inode_a_count(void *obj, int startoff);
50 static int inode_a_offset(void *obj, int startoff, int idx);
51 static int inode_a_sfattr_count(void *obj, int startoff);
52 static int inode_core_nlinkv2_count(void *obj, int startoff);
53 static int inode_core_onlink_count(void *obj, int startoff);
54 static int inode_core_projid_count(void *obj, int startoff);
55 static int inode_core_nlinkv1_count(void *obj, int startoff);
56 static int inode_f(int argc, char **argv);
57 static int inode_u_bmbt_count(void *obj, int startoff);
58 static int inode_u_bmx_count(void *obj, int startoff);
59 static int inode_u_c_count(void *obj, int startoff);
60 static int inode_u_dev_count(void *obj, int startoff);
61 static int inode_u_muuid_count(void *obj, int startoff);
62 static int inode_u_sfdir_count(void *obj, int startoff);
63 static int inode_u_sfdir2_count(void *obj, int startoff);
64 static int inode_u_symlink_count(void *obj, int startoff);
65
66 static const cmdinfo_t inode_cmd =
67 { "inode", NULL, inode_f, 0, 1, 1, "[inode#]",
68 "set current inode", NULL };
69
70 const field_t inode_hfld[] = {
71 { "", FLDT_INODE, OI(0), C1, 0, TYP_NONE },
72 { NULL }
73 };
74
75 #define OFF(f) bitize(offsetof(xfs_dinode_t, di_ ## f))
76 const field_t inode_flds[] = {
77 { "core", FLDT_DINODE_CORE, OI(OFF(core)), C1, 0, TYP_NONE },
78 { "next_unlinked", FLDT_AGINO, OI(OFF(next_unlinked)), C1, 0,
79 TYP_INODE },
80 { "u", FLDT_DINODE_U, OI(OFF(u)), C1, 0, TYP_NONE },
81 { "a", FLDT_DINODE_A, inode_a_offset, inode_a_count,
82 FLD_COUNT|FLD_OFFSET, TYP_NONE },
83 { NULL }
84 };
85
86 #define COFF(f) bitize(offsetof(xfs_dinode_core_t, di_ ## f))
87 const field_t inode_core_flds[] = {
88 { "magic", FLDT_UINT16X, OI(COFF(magic)), C1, 0, TYP_NONE },
89 { "mode", FLDT_UINT16O, OI(COFF(mode)), C1, 0, TYP_NONE },
90 { "version", FLDT_INT8D, OI(COFF(version)), C1, 0, TYP_NONE },
91 { "format", FLDT_DINODE_FMT, OI(COFF(format)), C1, 0, TYP_NONE },
92 { "nlinkv1", FLDT_UINT16D, OI(COFF(onlink)), inode_core_nlinkv1_count,
93 FLD_COUNT, TYP_NONE },
94 { "nlinkv2", FLDT_UINT32D, OI(COFF(nlink)), inode_core_nlinkv2_count,
95 FLD_COUNT, TYP_NONE },
96 { "onlink", FLDT_UINT16D, OI(COFF(onlink)), inode_core_onlink_count,
97 FLD_COUNT, TYP_NONE },
98 { "projid", FLDT_UINT16D, OI(COFF(projid)), inode_core_projid_count,
99 FLD_COUNT, TYP_NONE },
100 { "uid", FLDT_UINT32D, OI(COFF(uid)), C1, 0, TYP_NONE },
101 { "gid", FLDT_UINT32D, OI(COFF(gid)), C1, 0, TYP_NONE },
102 { "atime", FLDT_TIMESTAMP, OI(COFF(atime)), C1, 0, TYP_NONE },
103 { "mtime", FLDT_TIMESTAMP, OI(COFF(mtime)), C1, 0, TYP_NONE },
104 { "ctime", FLDT_TIMESTAMP, OI(COFF(ctime)), C1, 0, TYP_NONE },
105 { "size", FLDT_FSIZE, OI(COFF(size)), C1, 0, TYP_NONE },
106 { "nblocks", FLDT_DRFSBNO, OI(COFF(nblocks)), C1, 0, TYP_NONE },
107 { "extsize", FLDT_EXTLEN, OI(COFF(extsize)), C1, 0, TYP_NONE },
108 { "nextents", FLDT_EXTNUM, OI(COFF(nextents)), C1, 0, TYP_NONE },
109 { "naextents", FLDT_AEXTNUM, OI(COFF(anextents)), C1, 0, TYP_NONE },
110 { "forkoff", FLDT_UINT8D, OI(COFF(forkoff)), C1, 0, TYP_NONE },
111 { "aformat", FLDT_DINODE_FMT, OI(COFF(aformat)), C1, 0, TYP_NONE },
112 { "dmevmask", FLDT_UINT32X, OI(COFF(dmevmask)), C1, 0, TYP_NONE },
113 { "dmstate", FLDT_UINT16D, OI(COFF(dmstate)), C1, 0, TYP_NONE },
114 { "flags", FLDT_UINT16X, OI(COFF(flags)), C1, FLD_SKIPALL, TYP_NONE },
115 { "newrtbm", FLDT_UINT1,
116 OI(COFF(flags) + bitsz(__uint16_t) - XFS_DIFLAG_NEWRTBM_BIT - 1), C1,
117 0, TYP_NONE },
118 { "prealloc", FLDT_UINT1,
119 OI(COFF(flags) + bitsz(__uint16_t) - XFS_DIFLAG_PREALLOC_BIT - 1), C1,
120 0, TYP_NONE },
121 { "realtime", FLDT_UINT1,
122 OI(COFF(flags) + bitsz(__uint16_t) - XFS_DIFLAG_REALTIME_BIT - 1), C1,
123 0, TYP_NONE },
124 { "gen", FLDT_UINT32D, OI(COFF(gen)), C1, 0, TYP_NONE },
125 { NULL }
126 };
127
128 #define TOFF(f) bitize(offsetof(xfs_timestamp_t, t_ ## f))
129 const field_t timestamp_flds[] = {
130 { "sec", FLDT_TIME, OI(TOFF(sec)), C1, 0, TYP_NONE },
131 { "nsec", FLDT_NSEC, OI(TOFF(nsec)), C1, 0, TYP_NONE },
132 { NULL }
133 };
134
135 const field_t inode_u_flds[] = {
136 { "bmbt", FLDT_BMROOTD, 0, inode_u_bmbt_count, FLD_COUNT, TYP_NONE },
137 { "bmx", FLDT_BMAPBTDREC, 0, inode_u_bmx_count, FLD_ARRAY|FLD_COUNT,
138 TYP_NONE },
139 { "c", FLDT_CHARNS, 0, inode_u_c_count, FLD_COUNT, TYP_NONE },
140 { "dev", FLDT_DEV, 0, inode_u_dev_count, FLD_COUNT, TYP_NONE },
141 { "muuid", FLDT_UUID, 0, inode_u_muuid_count, FLD_COUNT, TYP_NONE },
142 { "sfdir", FLDT_DIRSHORT, 0, inode_u_sfdir_count, FLD_COUNT, TYP_NONE },
143 { "sfdir2", FLDT_DIR2SF, 0, inode_u_sfdir2_count, FLD_COUNT, TYP_NONE },
144 { "symlink", FLDT_CHARNS, 0, inode_u_symlink_count, FLD_COUNT,
145 TYP_NONE },
146 { NULL }
147 };
148
149 const field_t inode_a_flds[] = {
150 { "bmbt", FLDT_BMROOTA, 0, inode_a_bmbt_count, FLD_COUNT, TYP_NONE },
151 { "bmx", FLDT_BMAPBTAREC, 0, inode_a_bmx_count, FLD_ARRAY|FLD_COUNT,
152 TYP_NONE },
153 { "sfattr", FLDT_ATTRSHORT, 0, inode_a_sfattr_count, FLD_COUNT,
154 TYP_NONE },
155 { NULL }
156 };
157
158 static const char *dinode_fmt_name[] =
159 { "dev", "local", "extents", "btree", "uuid" };
160 static const int dinode_fmt_name_size =
161 sizeof(dinode_fmt_name) / sizeof(dinode_fmt_name[0]);
162
163 /*ARGSUSED*/
164 int
165 fp_dinode_fmt(
166 void *obj,
167 int bit,
168 int count,
169 char *fmtstr,
170 int size,
171 int arg,
172 int base,
173 int array)
174 {
175 int bitpos;
176 xfs_dinode_fmt_t f;
177 int i;
178
179 for (i = 0, bitpos = bit; i < count; i++, bitpos += size) {
180 f = (xfs_dinode_fmt_t)getbitval(obj, bitpos, size, BVSIGNED);
181 if (array)
182 dbprintf("%d:", i + base);
183 if (f < 0 || f >= dinode_fmt_name_size)
184 dbprintf("%d", (int)f);
185 else
186 dbprintf("%d (%s)", (int)f, dinode_fmt_name[(int)f]);
187 if (i < count - 1)
188 dbprintf(" ");
189 }
190 return 1;
191 }
192
193 static int
194 inode_a_bmbt_count(
195 void *obj,
196 int startoff)
197 {
198 xfs_dinode_t *dip;
199
200 ASSERT(bitoffs(startoff) == 0);
201 ASSERT(obj == iocur_top->data);
202 dip = obj;
203 if (!XFS_DFORK_Q_ARCH(dip, ARCH_CONVERT))
204 return 0;
205 ASSERT((char *)XFS_DFORK_APTR_ARCH(dip, ARCH_CONVERT) - (char *)dip == byteize(startoff));
206 return INT_GET(dip->di_core.di_aformat, ARCH_CONVERT) == XFS_DINODE_FMT_BTREE;
207 }
208
209 static int
210 inode_a_bmx_count(
211 void *obj,
212 int startoff)
213 {
214 xfs_dinode_t *dip;
215
216 ASSERT(bitoffs(startoff) == 0);
217 ASSERT(obj == iocur_top->data);
218 dip = obj;
219 if (!XFS_DFORK_Q_ARCH(dip, ARCH_CONVERT))
220 return 0;
221 ASSERT((char *)XFS_DFORK_APTR_ARCH(dip, ARCH_CONVERT) - (char *)dip == byteize(startoff));
222 return INT_GET(dip->di_core.di_aformat, ARCH_CONVERT) == XFS_DINODE_FMT_EXTENTS ?
223 INT_GET(dip->di_core.di_anextents, ARCH_CONVERT) : 0;
224 }
225
226 static int
227 inode_a_count(
228 void *obj,
229 int startoff)
230 {
231 xfs_dinode_t *dip;
232
233 ASSERT(startoff == 0);
234 dip = obj;
235 return XFS_DFORK_Q_ARCH(dip, ARCH_CONVERT);
236 }
237
238 static int
239 inode_a_offset(
240 void *obj,
241 int startoff,
242 int idx)
243 {
244 xfs_dinode_t *dip;
245
246 ASSERT(startoff == 0);
247 ASSERT(idx == 0);
248 dip = obj;
249 ASSERT(XFS_DFORK_Q_ARCH(dip, ARCH_CONVERT));
250 return bitize((int)((char *)XFS_DFORK_APTR_ARCH(dip, ARCH_CONVERT) - (char *)dip));
251 }
252
253 static int
254 inode_a_sfattr_count(
255 void *obj,
256 int startoff)
257 {
258 xfs_dinode_t *dip;
259
260 ASSERT(bitoffs(startoff) == 0);
261 ASSERT(obj == iocur_top->data);
262 dip = obj;
263 if (!XFS_DFORK_Q_ARCH(dip, ARCH_CONVERT))
264 return 0;
265 ASSERT((char *)XFS_DFORK_APTR_ARCH(dip, ARCH_CONVERT) - (char *)dip == byteize(startoff));
266 return INT_GET(dip->di_core.di_aformat, ARCH_CONVERT) == XFS_DINODE_FMT_LOCAL;
267 }
268
269 int
270 inode_a_size(
271 void *obj,
272 int startoff,
273 int idx)
274 {
275 xfs_attr_shortform_t *asf;
276 xfs_dinode_t *dip;
277
278 ASSERT(startoff == 0);
279 ASSERT(idx == 0);
280 dip = obj;
281 switch (INT_GET(dip->di_core.di_aformat, ARCH_CONVERT)) {
282 case XFS_DINODE_FMT_LOCAL:
283 asf = (xfs_attr_shortform_t *)XFS_DFORK_APTR_ARCH(dip, ARCH_CONVERT);
284 return bitize((int)asf->hdr.totsize);
285 case XFS_DINODE_FMT_EXTENTS:
286 return (int)(INT_GET(dip->di_core.di_anextents, ARCH_CONVERT) * bitsz(xfs_bmbt_rec_t));
287 case XFS_DINODE_FMT_BTREE:
288 return bitize((int)XFS_DFORK_ASIZE_ARCH(dip, mp, ARCH_CONVERT));
289 default:
290 return 0;
291 }
292 }
293
294 static int
295 inode_core_nlinkv1_count(
296 void *obj,
297 int startoff)
298 {
299 xfs_dinode_core_t *dic;
300
301 ASSERT(startoff == 0);
302 ASSERT(obj == iocur_top->data);
303 dic = obj;
304 return dic->di_version == XFS_DINODE_VERSION_1;
305 }
306
307 static int
308 inode_core_nlinkv2_count(
309 void *obj,
310 int startoff)
311 {
312 xfs_dinode_core_t *dic;
313
314 ASSERT(startoff == 0);
315 ASSERT(obj == iocur_top->data);
316 dic = obj;
317 return dic->di_version == XFS_DINODE_VERSION_2;
318 }
319
320 static int
321 inode_core_onlink_count(
322 void *obj,
323 int startoff)
324 {
325 xfs_dinode_core_t *dic;
326
327 ASSERT(startoff == 0);
328 ASSERT(obj == iocur_top->data);
329 dic = obj;
330 return dic->di_version == XFS_DINODE_VERSION_2;
331 }
332
333 static int
334 inode_core_projid_count(
335 void *obj,
336 int startoff)
337 {
338 xfs_dinode_core_t *dic;
339
340 ASSERT(startoff == 0);
341 ASSERT(obj == iocur_top->data);
342 dic = obj;
343 return dic->di_version == XFS_DINODE_VERSION_2;
344 }
345
346 static int
347 inode_f(
348 int argc,
349 char **argv)
350 {
351 xfs_ino_t ino;
352 char *p;
353
354 if (argc > 1) {
355 ino = strtoull(argv[1], &p, 0);
356 if (*p != '\0') {
357 dbprintf("bad value for inode number %s\n", argv[1]);
358 return 0;
359 }
360 set_cur_inode(ino);
361 } else if (iocur_top->ino == NULLFSINO)
362 dbprintf("no current inode\n");
363 else
364 dbprintf("current inode number is %lld\n", iocur_top->ino);
365 return 0;
366 }
367
368 void
369 inode_init(void)
370 {
371 add_command(&inode_cmd);
372 }
373
374 typnm_t
375 inode_next_type(void)
376 {
377 switch (iocur_top->mode & IFMT) {
378 case IFDIR:
379 return XFS_DIR_IS_V2(mp) ? TYP_DIR2 : TYP_DIR;
380 case IFLNK:
381 return TYP_SYMLINK;
382 case IFREG:
383 if (iocur_top->ino == mp->m_sb.sb_rbmino)
384 return TYP_RTBITMAP;
385 else if (iocur_top->ino == mp->m_sb.sb_rsumino)
386 return TYP_RTSUMMARY;
387 else if (iocur_top->ino == mp->m_sb.sb_uquotino ||
388 iocur_top->ino == mp->m_sb.sb_gquotino)
389 return TYP_DQBLK;
390 else
391 return TYP_DATA;
392 default:
393 return TYP_NONE;
394 }
395 }
396
397 int
398 inode_size(
399 void *obj,
400 int startoff,
401 int idx)
402 {
403 return bitize(mp->m_sb.sb_inodesize);
404 }
405
406 static int
407 inode_u_bmbt_count(
408 void *obj,
409 int startoff)
410 {
411 xfs_dinode_t *dip;
412
413 ASSERT(bitoffs(startoff) == 0);
414 ASSERT(obj == iocur_top->data);
415 dip = obj;
416 ASSERT((char *)&dip->di_u - (char *)dip == byteize(startoff));
417 return INT_GET(dip->di_core.di_format, ARCH_CONVERT) == XFS_DINODE_FMT_BTREE;
418 }
419
420 static int
421 inode_u_bmx_count(
422 void *obj,
423 int startoff)
424 {
425 xfs_dinode_t *dip;
426
427 ASSERT(bitoffs(startoff) == 0);
428 ASSERT(obj == iocur_top->data);
429 dip = obj;
430 ASSERT((char *)&dip->di_u - (char *)dip == byteize(startoff));
431 return INT_GET(dip->di_core.di_format, ARCH_CONVERT) == XFS_DINODE_FMT_EXTENTS ?
432 INT_GET(dip->di_core.di_nextents, ARCH_CONVERT) : 0;
433 }
434
435 static int
436 inode_u_c_count(
437 void *obj,
438 int startoff)
439 {
440 xfs_dinode_t *dip;
441
442 ASSERT(bitoffs(startoff) == 0);
443 ASSERT(obj == iocur_top->data);
444 dip = obj;
445 ASSERT((char *)&dip->di_u - (char *)dip == byteize(startoff));
446 return INT_GET(dip->di_core.di_format, ARCH_CONVERT) == XFS_DINODE_FMT_LOCAL &&
447 (INT_GET(dip->di_core.di_mode, ARCH_CONVERT) & IFMT) == IFREG ?
448 (int)INT_GET(dip->di_core.di_size, ARCH_CONVERT) : 0;
449 }
450
451 static int
452 inode_u_dev_count(
453 void *obj,
454 int startoff)
455 {
456 xfs_dinode_t *dip;
457
458 ASSERT(bitoffs(startoff) == 0);
459 ASSERT(obj == iocur_top->data);
460 dip = obj;
461 ASSERT((char *)&dip->di_u - (char *)dip == byteize(startoff));
462 return INT_GET(dip->di_core.di_format, ARCH_CONVERT) == XFS_DINODE_FMT_DEV;
463 }
464
465 static int
466 inode_u_muuid_count(
467 void *obj,
468 int startoff)
469 {
470 xfs_dinode_t *dip;
471
472 ASSERT(bitoffs(startoff) == 0);
473 ASSERT(obj == iocur_top->data);
474 dip = obj;
475 ASSERT((char *)&dip->di_u - (char *)dip == byteize(startoff));
476 return INT_GET(dip->di_core.di_format, ARCH_CONVERT) == XFS_DINODE_FMT_UUID;
477 }
478
479 static int
480 inode_u_sfdir_count(
481 void *obj,
482 int startoff)
483 {
484 xfs_dinode_t *dip;
485
486 ASSERT(bitoffs(startoff) == 0);
487 ASSERT(obj == iocur_top->data);
488 dip = obj;
489 ASSERT((char *)&dip->di_u - (char *)dip == byteize(startoff));
490 return INT_GET(dip->di_core.di_format, ARCH_CONVERT) == XFS_DINODE_FMT_LOCAL &&
491 (INT_GET(dip->di_core.di_mode, ARCH_CONVERT) & IFMT) == IFDIR
492 && XFS_DIR_IS_V1(mp);
493 }
494
495 static int
496 inode_u_sfdir2_count(
497 void *obj,
498 int startoff)
499 {
500 xfs_dinode_t *dip;
501
502 ASSERT(bitoffs(startoff) == 0);
503 ASSERT(obj == iocur_top->data);
504 dip = obj;
505 ASSERT((char *)&dip->di_u - (char *)dip == byteize(startoff));
506 return INT_GET(dip->di_core.di_format, ARCH_CONVERT) == XFS_DINODE_FMT_LOCAL &&
507 (INT_GET(dip->di_core.di_mode, ARCH_CONVERT) & IFMT) == IFDIR &&
508 XFS_DIR_IS_V2(mp);
509 }
510
511 int
512 inode_u_size(
513 void *obj,
514 int startoff,
515 int idx)
516 {
517 xfs_dinode_t *dip;
518
519 ASSERT(startoff == 0);
520 ASSERT(idx == 0);
521 dip = obj;
522 switch (INT_GET(dip->di_core.di_format, ARCH_CONVERT)) {
523 case XFS_DINODE_FMT_DEV:
524 return bitsz(xfs_dev_t);
525 case XFS_DINODE_FMT_LOCAL:
526 return bitize((int)INT_GET(dip->di_core.di_size, ARCH_CONVERT));
527 case XFS_DINODE_FMT_EXTENTS:
528 return (int)(INT_GET(dip->di_core.di_nextents, ARCH_CONVERT) * bitsz(xfs_bmbt_rec_t));
529 case XFS_DINODE_FMT_BTREE:
530 return bitize((int)XFS_DFORK_DSIZE_ARCH(dip, mp, ARCH_CONVERT));
531 case XFS_DINODE_FMT_UUID:
532 return bitsz(uuid_t);
533 default:
534 return 0;
535 }
536 }
537
538 static int
539 inode_u_symlink_count(
540 void *obj,
541 int startoff)
542 {
543 xfs_dinode_t *dip;
544
545 ASSERT(bitoffs(startoff) == 0);
546 ASSERT(obj == iocur_top->data);
547 dip = obj;
548 ASSERT((char *)&dip->di_u - (char *)dip == byteize(startoff));
549 return INT_GET(dip->di_core.di_format, ARCH_CONVERT) == XFS_DINODE_FMT_LOCAL &&
550 (INT_GET(dip->di_core.di_mode, ARCH_CONVERT) & IFMT) == IFLNK ?
551 (int)INT_GET(dip->di_core.di_size, ARCH_CONVERT) : 0;
552 }
553
554 void
555 set_cur_inode(
556 xfs_ino_t ino)
557 {
558 xfs_agblock_t agbno;
559 xfs_agino_t agino;
560 xfs_agnumber_t agno;
561 xfs_dinode_t *dip;
562 int offset;
563
564 agno = XFS_INO_TO_AGNO(mp, ino);
565 agino = XFS_INO_TO_AGINO(mp, ino);
566 agbno = XFS_AGINO_TO_AGBNO(mp, agino);
567 offset = XFS_AGINO_TO_OFFSET(mp, agino);
568 if (agno >= mp->m_sb.sb_agcount || agbno >= mp->m_sb.sb_agblocks ||
569 offset >= mp->m_sb.sb_inopblock ||
570 XFS_AGINO_TO_INO(mp, agno, agino) != ino) {
571 dbprintf("bad inode number %lld\n", ino);
572 return;
573 }
574 cur_agno = agno;
575 /*
576 * First set_cur to the block with the inode
577 * then use off_cur to get the right part of the buffer.
578 */
579 ASSERT(typtab[TYP_INODE].typnm == TYP_INODE);
580
581 /* ingore ring update here, do it explicitly below */
582 set_cur(&typtab[TYP_INODE], XFS_AGB_TO_DADDR(mp, agno, agbno),
583 blkbb, DB_RING_IGN, NULL);
584 off_cur(offset << mp->m_sb.sb_inodelog, mp->m_sb.sb_inodesize);
585 dip = iocur_top->data;
586 iocur_top->ino = ino;
587 iocur_top->mode = INT_GET(dip->di_core.di_mode, ARCH_CONVERT);
588 if ((iocur_top->mode & IFMT) == IFDIR)
589 iocur_top->dirino = ino;
590
591 /* track updated info in ring */
592 ring_add();
593 }