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