]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - db/inode.c
xfsprogs: remove double-underscore integer types
[thirdparty/xfsprogs-dev.git] / db / inode.c
CommitLineData
2bd0ea18 1/*
da23017d
NS
2 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
dfc130f3 4 *
da23017d
NS
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
2bd0ea18 7 * published by the Free Software Foundation.
dfc130f3 8 *
da23017d
NS
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.
dfc130f3 13 *
da23017d
NS
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
2bd0ea18
NS
17 */
18
6b803e5a 19#include "libxfs.h"
2bd0ea18 20#include "command.h"
2bd0ea18
NS
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"
4ca431fc 31#include "init.h"
2bd0ea18
NS
32
33static int inode_a_bmbt_count(void *obj, int startoff);
34static int inode_a_bmx_count(void *obj, int startoff);
35static int inode_a_count(void *obj, int startoff);
36static int inode_a_offset(void *obj, int startoff, int idx);
37static int inode_a_sfattr_count(void *obj, int startoff);
38static int inode_core_nlinkv2_count(void *obj, int startoff);
39static int inode_core_onlink_count(void *obj, int startoff);
40static int inode_core_projid_count(void *obj, int startoff);
41static int inode_core_nlinkv1_count(void *obj, int startoff);
42static int inode_f(int argc, char **argv);
56b2de80 43static int inode_u_offset(void *obj, int startoff, int idx);
2bd0ea18
NS
44static int inode_u_bmbt_count(void *obj, int startoff);
45static int inode_u_bmx_count(void *obj, int startoff);
46static int inode_u_c_count(void *obj, int startoff);
47static int inode_u_dev_count(void *obj, int startoff);
48static int inode_u_muuid_count(void *obj, int startoff);
2bd0ea18 49static int inode_u_sfdir2_count(void *obj, int startoff);
3beed08e 50static int inode_u_sfdir3_count(void *obj, int startoff);
2bd0ea18
NS
51static int inode_u_symlink_count(void *obj, int startoff);
52
53static const cmdinfo_t inode_cmd =
54 { "inode", NULL, inode_f, 0, 1, 1, "[inode#]",
55 "set current inode", NULL };
56
57const field_t inode_hfld[] = {
58 { "", FLDT_INODE, OI(0), C1, 0, TYP_NONE },
59 { NULL }
60};
c2907bd7
DC
61const field_t inode_crc_hfld[] = {
62 { "", FLDT_INODE_CRC, OI(0), C1, 0, TYP_NONE },
63 { NULL }
64};
2bd0ea18 65
56b2de80 66/* XXX: fix this up! */
2bd0ea18
NS
67#define OFF(f) bitize(offsetof(xfs_dinode_t, di_ ## f))
68const field_t inode_flds[] = {
56b2de80 69 { "core", FLDT_DINODE_CORE, OI(OFF(magic)), C1, 0, TYP_NONE },
2bd0ea18
NS
70 { "next_unlinked", FLDT_AGINO, OI(OFF(next_unlinked)), C1, 0,
71 TYP_INODE },
56b2de80 72 { "u", FLDT_DINODE_U, inode_u_offset, C1, FLD_OFFSET, TYP_NONE },
2bd0ea18
NS
73 { "a", FLDT_DINODE_A, inode_a_offset, inode_a_count,
74 FLD_COUNT|FLD_OFFSET, TYP_NONE },
75 { NULL }
76};
c2907bd7
DC
77const field_t inode_crc_flds[] = {
78 { "core", FLDT_DINODE_CORE, OI(OFF(magic)), C1, 0, TYP_NONE },
79 { "next_unlinked", FLDT_AGINO, OI(OFF(next_unlinked)), C1, 0,
80 TYP_INODE },
81 { "v3", FLDT_DINODE_V3, OI(OFF(magic)), C1, 0, TYP_NONE },
3beed08e 82 { "u3", FLDT_DINODE_U, inode_u_offset, C1, FLD_OFFSET, TYP_NONE },
c2907bd7
DC
83 { "a", FLDT_DINODE_A, inode_a_offset, inode_a_count,
84 FLD_COUNT|FLD_OFFSET, TYP_NONE },
85 { NULL }
86};
87
2bd0ea18 88
56b2de80 89#define COFF(f) bitize(offsetof(xfs_dinode_t, di_ ## f))
2bd0ea18
NS
90const field_t inode_core_flds[] = {
91 { "magic", FLDT_UINT16X, OI(COFF(magic)), C1, 0, TYP_NONE },
92 { "mode", FLDT_UINT16O, OI(COFF(mode)), C1, 0, TYP_NONE },
93 { "version", FLDT_INT8D, OI(COFF(version)), C1, 0, TYP_NONE },
94 { "format", FLDT_DINODE_FMT, OI(COFF(format)), C1, 0, TYP_NONE },
95 { "nlinkv1", FLDT_UINT16D, OI(COFF(onlink)), inode_core_nlinkv1_count,
96 FLD_COUNT, TYP_NONE },
97 { "nlinkv2", FLDT_UINT32D, OI(COFF(nlink)), inode_core_nlinkv2_count,
98 FLD_COUNT, TYP_NONE },
99 { "onlink", FLDT_UINT16D, OI(COFF(onlink)), inode_core_onlink_count,
100 FLD_COUNT, TYP_NONE },
22bc10ed
AM
101 { "projid_lo", FLDT_UINT16D, OI(COFF(projid_lo)),
102 inode_core_projid_count, FLD_COUNT, TYP_NONE },
103 { "projid_hi", FLDT_UINT16D, OI(COFF(projid_hi)),
104 inode_core_projid_count, FLD_COUNT, TYP_NONE },
2bd0ea18
NS
105 { "uid", FLDT_UINT32D, OI(COFF(uid)), C1, 0, TYP_NONE },
106 { "gid", FLDT_UINT32D, OI(COFF(gid)), C1, 0, TYP_NONE },
ec783255 107 { "flushiter", FLDT_UINT16D, OI(COFF(flushiter)), C1, 0, TYP_NONE },
2bd0ea18
NS
108 { "atime", FLDT_TIMESTAMP, OI(COFF(atime)), C1, 0, TYP_NONE },
109 { "mtime", FLDT_TIMESTAMP, OI(COFF(mtime)), C1, 0, TYP_NONE },
110 { "ctime", FLDT_TIMESTAMP, OI(COFF(ctime)), C1, 0, TYP_NONE },
111 { "size", FLDT_FSIZE, OI(COFF(size)), C1, 0, TYP_NONE },
112 { "nblocks", FLDT_DRFSBNO, OI(COFF(nblocks)), C1, 0, TYP_NONE },
113 { "extsize", FLDT_EXTLEN, OI(COFF(extsize)), C1, 0, TYP_NONE },
114 { "nextents", FLDT_EXTNUM, OI(COFF(nextents)), C1, 0, TYP_NONE },
115 { "naextents", FLDT_AEXTNUM, OI(COFF(anextents)), C1, 0, TYP_NONE },
116 { "forkoff", FLDT_UINT8D, OI(COFF(forkoff)), C1, 0, TYP_NONE },
117 { "aformat", FLDT_DINODE_FMT, OI(COFF(aformat)), C1, 0, TYP_NONE },
118 { "dmevmask", FLDT_UINT32X, OI(COFF(dmevmask)), C1, 0, TYP_NONE },
119 { "dmstate", FLDT_UINT16D, OI(COFF(dmstate)), C1, 0, TYP_NONE },
120 { "flags", FLDT_UINT16X, OI(COFF(flags)), C1, FLD_SKIPALL, TYP_NONE },
121 { "newrtbm", FLDT_UINT1,
14f8b681 122 OI(COFF(flags) + bitsz(uint16_t) - XFS_DIFLAG_NEWRTBM_BIT - 1), C1,
2bd0ea18
NS
123 0, TYP_NONE },
124 { "prealloc", FLDT_UINT1,
14f8b681 125 OI(COFF(flags) + bitsz(uint16_t) - XFS_DIFLAG_PREALLOC_BIT - 1), C1,
2bd0ea18
NS
126 0, TYP_NONE },
127 { "realtime", FLDT_UINT1,
14f8b681 128 OI(COFF(flags) + bitsz(uint16_t) - XFS_DIFLAG_REALTIME_BIT - 1), C1,
2bd0ea18 129 0, TYP_NONE },
2b288ccf 130 { "immutable", FLDT_UINT1,
14f8b681 131 OI(COFF(flags) + bitsz(uint16_t) - XFS_DIFLAG_IMMUTABLE_BIT-1), C1,
2b288ccf
NS
132 0, TYP_NONE },
133 { "append", FLDT_UINT1,
14f8b681 134 OI(COFF(flags) + bitsz(uint16_t) - XFS_DIFLAG_APPEND_BIT - 1), C1,
2b288ccf
NS
135 0, TYP_NONE },
136 { "sync", FLDT_UINT1,
14f8b681 137 OI(COFF(flags) + bitsz(uint16_t) - XFS_DIFLAG_SYNC_BIT - 1), C1,
2b288ccf
NS
138 0, TYP_NONE },
139 { "noatime", FLDT_UINT1,
14f8b681 140 OI(COFF(flags) + bitsz(uint16_t) - XFS_DIFLAG_NOATIME_BIT - 1), C1,
2b288ccf
NS
141 0, TYP_NONE },
142 { "nodump", FLDT_UINT1,
14f8b681 143 OI(COFF(flags) + bitsz(uint16_t) - XFS_DIFLAG_NODUMP_BIT - 1), C1,
2b288ccf 144 0, TYP_NONE },
4ebdd912 145 { "rtinherit", FLDT_UINT1,
14f8b681 146 OI(COFF(flags) + bitsz(uint16_t) - XFS_DIFLAG_RTINHERIT_BIT-1), C1,
4ebdd912 147 0, TYP_NONE },
5ecb3de2 148 { "projinherit", FLDT_UINT1,
14f8b681 149 OI(COFF(flags) + bitsz(uint16_t) - XFS_DIFLAG_PROJINHERIT_BIT-1), C1,
5ecb3de2
NS
150 0, TYP_NONE },
151 { "nosymlinks", FLDT_UINT1,
14f8b681 152 OI(COFF(flags) + bitsz(uint16_t) - XFS_DIFLAG_NOSYMLINKS_BIT-1), C1,
5ecb3de2 153 0, TYP_NONE },
ae541a2b 154 { "extsz", FLDT_UINT1,
14f8b681 155 OI(COFF(flags) + bitsz(uint16_t) - XFS_DIFLAG_EXTSIZE_BIT-1), C1,
ae541a2b
NS
156 0, TYP_NONE },
157 { "extszinherit", FLDT_UINT1,
14f8b681 158 OI(COFF(flags) + bitsz(uint16_t) - XFS_DIFLAG_EXTSZINHERIT_BIT-1), C1,
ae541a2b 159 0, TYP_NONE },
ed832ad2 160 { "nodefrag", FLDT_UINT1,
14f8b681 161 OI(COFF(flags) + bitsz(uint16_t) - XFS_DIFLAG_NODEFRAG_BIT-1), C1,
ed832ad2 162 0, TYP_NONE },
2d5121ac 163 { "filestream", FLDT_UINT1,
14f8b681 164 OI(COFF(flags) + bitsz(uint16_t) - XFS_DIFLAG_FILESTREAM_BIT-1), C1,
2d5121ac 165 0, TYP_NONE },
2bd0ea18
NS
166 { "gen", FLDT_UINT32D, OI(COFF(gen)), C1, 0, TYP_NONE },
167 { NULL }
168};
169
c2907bd7 170const field_t inode_v3_flds[] = {
0522f1cc 171 { "crc", FLDT_CRC, OI(COFF(crc)), C1, 0, TYP_NONE },
c2907bd7
DC
172 { "change_count", FLDT_UINT64D, OI(COFF(changecount)), C1, 0, TYP_NONE },
173 { "lsn", FLDT_UINT64X, OI(COFF(lsn)), C1, 0, TYP_NONE },
174 { "flags2", FLDT_UINT64X, OI(COFF(flags2)), C1, 0, TYP_NONE },
1f5407ac 175 { "cowextsize", FLDT_EXTLEN, OI(COFF(cowextsize)), C1, 0, TYP_NONE },
c2907bd7
DC
176 { "crtime", FLDT_TIMESTAMP, OI(COFF(crtime)), C1, 0, TYP_NONE },
177 { "inumber", FLDT_INO, OI(COFF(ino)), C1, 0, TYP_NONE },
178 { "uuid", FLDT_UUID, OI(COFF(uuid)), C1, 0, TYP_NONE },
9fb2cb27 179 { "reflink", FLDT_UINT1,
14f8b681 180 OI(COFF(flags2) + bitsz(uint64_t) - XFS_DIFLAG2_REFLINK_BIT-1), C1,
9fb2cb27 181 0, TYP_NONE },
1f5407ac 182 { "cowextsz", FLDT_UINT1,
14f8b681 183 OI(COFF(flags2) + bitsz(uint64_t) - XFS_DIFLAG2_COWEXTSIZE_BIT-1), C1,
1f5407ac 184 0, TYP_NONE },
c2907bd7
DC
185 { NULL }
186};
187
188
2bd0ea18
NS
189#define TOFF(f) bitize(offsetof(xfs_timestamp_t, t_ ## f))
190const field_t timestamp_flds[] = {
191 { "sec", FLDT_TIME, OI(TOFF(sec)), C1, 0, TYP_NONE },
192 { "nsec", FLDT_NSEC, OI(TOFF(nsec)), C1, 0, TYP_NONE },
193 { NULL }
194};
195
196const field_t inode_u_flds[] = {
5e656dbb
BN
197 { "bmbt", FLDT_BMROOTD, NULL, inode_u_bmbt_count, FLD_COUNT, TYP_NONE },
198 { "bmx", FLDT_BMAPBTDREC, NULL, inode_u_bmx_count, FLD_ARRAY|FLD_COUNT,
2bd0ea18 199 TYP_NONE },
5e656dbb
BN
200 { "c", FLDT_CHARNS, NULL, inode_u_c_count, FLD_COUNT, TYP_NONE },
201 { "dev", FLDT_DEV, NULL, inode_u_dev_count, FLD_COUNT, TYP_NONE },
202 { "muuid", FLDT_UUID, NULL, inode_u_muuid_count, FLD_COUNT, TYP_NONE },
5e656dbb 203 { "sfdir2", FLDT_DIR2SF, NULL, inode_u_sfdir2_count, FLD_COUNT, TYP_NONE },
3beed08e 204 { "sfdir3", FLDT_DIR3SF, NULL, inode_u_sfdir3_count, FLD_COUNT, TYP_NONE },
5e656dbb 205 { "symlink", FLDT_CHARNS, NULL, inode_u_symlink_count, FLD_COUNT,
2bd0ea18
NS
206 TYP_NONE },
207 { NULL }
208};
209
210const field_t inode_a_flds[] = {
5e656dbb
BN
211 { "bmbt", FLDT_BMROOTA, NULL, inode_a_bmbt_count, FLD_COUNT, TYP_NONE },
212 { "bmx", FLDT_BMAPBTAREC, NULL, inode_a_bmx_count, FLD_ARRAY|FLD_COUNT,
2bd0ea18 213 TYP_NONE },
5e656dbb 214 { "sfattr", FLDT_ATTRSHORT, NULL, inode_a_sfattr_count, FLD_COUNT,
2bd0ea18
NS
215 TYP_NONE },
216 { NULL }
217};
218
219static const char *dinode_fmt_name[] =
220 { "dev", "local", "extents", "btree", "uuid" };
221static const int dinode_fmt_name_size =
222 sizeof(dinode_fmt_name) / sizeof(dinode_fmt_name[0]);
223
224/*ARGSUSED*/
225int
226fp_dinode_fmt(
227 void *obj,
228 int bit,
229 int count,
230 char *fmtstr,
231 int size,
232 int arg,
233 int base,
234 int array)
235{
236 int bitpos;
237 xfs_dinode_fmt_t f;
238 int i;
239
240 for (i = 0, bitpos = bit; i < count; i++, bitpos += size) {
47dd6743 241 f = (xfs_dinode_fmt_t)getbitval(obj, bitpos, size, BVUNSIGNED);
2bd0ea18
NS
242 if (array)
243 dbprintf("%d:", i + base);
244 if (f < 0 || f >= dinode_fmt_name_size)
245 dbprintf("%d", (int)f);
246 else
247 dbprintf("%d (%s)", (int)f, dinode_fmt_name[(int)f]);
248 if (i < count - 1)
249 dbprintf(" ");
250 }
251 return 1;
252}
253
254static int
255inode_a_bmbt_count(
256 void *obj,
257 int startoff)
258{
259 xfs_dinode_t *dip;
260
261 ASSERT(bitoffs(startoff) == 0);
262 ASSERT(obj == iocur_top->data);
263 dip = obj;
46eca962 264 if (!XFS_DFORK_Q(dip))
2bd0ea18 265 return 0;
46eca962 266 ASSERT((char *)XFS_DFORK_APTR(dip) - (char *)dip == byteize(startoff));
56b2de80 267 return dip->di_aformat == XFS_DINODE_FMT_BTREE;
2bd0ea18
NS
268}
269
270static int
271inode_a_bmx_count(
272 void *obj,
273 int startoff)
274{
275 xfs_dinode_t *dip;
276
277 ASSERT(bitoffs(startoff) == 0);
278 ASSERT(obj == iocur_top->data);
279 dip = obj;
46eca962 280 if (!XFS_DFORK_Q(dip))
2bd0ea18 281 return 0;
46eca962 282 ASSERT((char *)XFS_DFORK_APTR(dip) - (char *)dip == byteize(startoff));
56b2de80
DC
283 return dip->di_aformat == XFS_DINODE_FMT_EXTENTS ?
284 be16_to_cpu(dip->di_anextents) : 0;
2bd0ea18
NS
285}
286
287static int
288inode_a_count(
289 void *obj,
290 int startoff)
291{
292 xfs_dinode_t *dip;
293
294 ASSERT(startoff == 0);
295 dip = obj;
46eca962 296 return XFS_DFORK_Q(dip);
2bd0ea18
NS
297}
298
299static int
300inode_a_offset(
301 void *obj,
302 int startoff,
303 int idx)
304{
305 xfs_dinode_t *dip;
306
307 ASSERT(startoff == 0);
308 ASSERT(idx == 0);
309 dip = obj;
46eca962
NS
310 ASSERT(XFS_DFORK_Q(dip));
311 return bitize((int)((char *)XFS_DFORK_APTR(dip) - (char *)dip));
2bd0ea18
NS
312}
313
314static int
315inode_a_sfattr_count(
316 void *obj,
317 int startoff)
318{
319 xfs_dinode_t *dip;
320
321 ASSERT(bitoffs(startoff) == 0);
322 ASSERT(obj == iocur_top->data);
323 dip = obj;
46eca962 324 if (!XFS_DFORK_Q(dip))
2bd0ea18 325 return 0;
46eca962 326 ASSERT((char *)XFS_DFORK_APTR(dip) - (char *)dip == byteize(startoff));
56b2de80 327 return dip->di_aformat == XFS_DINODE_FMT_LOCAL;
2bd0ea18
NS
328}
329
330int
331inode_a_size(
332 void *obj,
333 int startoff,
334 int idx)
335{
336 xfs_attr_shortform_t *asf;
337 xfs_dinode_t *dip;
338
339 ASSERT(startoff == 0);
340 ASSERT(idx == 0);
341 dip = obj;
56b2de80 342 switch (dip->di_aformat) {
2bd0ea18 343 case XFS_DINODE_FMT_LOCAL:
46eca962 344 asf = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip);
5e656dbb 345 return bitize(be16_to_cpu(asf->hdr.totsize));
2bd0ea18 346 case XFS_DINODE_FMT_EXTENTS:
f8149110 347 return (int)be16_to_cpu(dip->di_anextents) *
5e656dbb 348 bitsz(xfs_bmbt_rec_t);
2bd0ea18 349 case XFS_DINODE_FMT_BTREE:
46eca962 350 return bitize((int)XFS_DFORK_ASIZE(dip, mp));
2bd0ea18
NS
351 default:
352 return 0;
353 }
354}
355
356static int
357inode_core_nlinkv1_count(
56b2de80
DC
358 void *obj,
359 int startoff)
2bd0ea18 360{
56b2de80 361 xfs_dinode_t *dic;
2bd0ea18
NS
362
363 ASSERT(startoff == 0);
364 ASSERT(obj == iocur_top->data);
365 dic = obj;
56b2de80 366 return dic->di_version == 1;
2bd0ea18
NS
367}
368
369static int
370inode_core_nlinkv2_count(
56b2de80
DC
371 void *obj,
372 int startoff)
2bd0ea18 373{
56b2de80 374 xfs_dinode_t *dic;
2bd0ea18
NS
375
376 ASSERT(startoff == 0);
377 ASSERT(obj == iocur_top->data);
378 dic = obj;
6367f2a3 379 return dic->di_version >= 2;
2bd0ea18
NS
380}
381
382static int
383inode_core_onlink_count(
56b2de80
DC
384 void *obj,
385 int startoff)
2bd0ea18 386{
56b2de80 387 xfs_dinode_t *dic;
2bd0ea18
NS
388
389 ASSERT(startoff == 0);
390 ASSERT(obj == iocur_top->data);
391 dic = obj;
6367f2a3 392 return dic->di_version >= 2;
2bd0ea18
NS
393}
394
395static int
396inode_core_projid_count(
56b2de80
DC
397 void *obj,
398 int startoff)
2bd0ea18 399{
56b2de80 400 xfs_dinode_t *dic;
2bd0ea18
NS
401
402 ASSERT(startoff == 0);
403 ASSERT(obj == iocur_top->data);
404 dic = obj;
6367f2a3 405 return dic->di_version >= 2;
2bd0ea18
NS
406}
407
408static int
409inode_f(
410 int argc,
411 char **argv)
412{
413 xfs_ino_t ino;
414 char *p;
415
416 if (argc > 1) {
417 ino = strtoull(argv[1], &p, 0);
418 if (*p != '\0') {
9ee7055c 419 dbprintf(_("bad value for inode number %s\n"), argv[1]);
2bd0ea18
NS
420 return 0;
421 }
422 set_cur_inode(ino);
423 } else if (iocur_top->ino == NULLFSINO)
9ee7055c 424 dbprintf(_("no current inode\n"));
2bd0ea18 425 else
9ee7055c 426 dbprintf(_("current inode number is %lld\n"), iocur_top->ino);
2bd0ea18
NS
427 return 0;
428}
429
430void
431inode_init(void)
432{
433 add_command(&inode_cmd);
434}
435
436typnm_t
437inode_next_type(void)
438{
322f2a29
SL
439 switch (iocur_top->mode & S_IFMT) {
440 case S_IFDIR:
9a048535 441 return TYP_DIR2;
322f2a29 442 case S_IFLNK:
2bd0ea18 443 return TYP_SYMLINK;
322f2a29 444 case S_IFREG:
2bd0ea18
NS
445 if (iocur_top->ino == mp->m_sb.sb_rbmino)
446 return TYP_RTBITMAP;
447 else if (iocur_top->ino == mp->m_sb.sb_rsumino)
448 return TYP_RTSUMMARY;
449 else if (iocur_top->ino == mp->m_sb.sb_uquotino ||
0340d706
CS
450 iocur_top->ino == mp->m_sb.sb_gquotino ||
451 iocur_top->ino == mp->m_sb.sb_pquotino)
2bd0ea18
NS
452 return TYP_DQBLK;
453 else
454 return TYP_DATA;
455 default:
456 return TYP_NONE;
457 }
458}
459
460int
461inode_size(
462 void *obj,
463 int startoff,
464 int idx)
465{
466 return bitize(mp->m_sb.sb_inodesize);
467}
468
56b2de80
DC
469static int
470inode_u_offset(
471 void *obj,
472 int startoff,
473 int idx)
474{
475 xfs_dinode_t *dip;
476
477 ASSERT(startoff == 0);
478 ASSERT(idx == 0);
479 dip = obj;
480 return bitize((int)((char *)XFS_DFORK_DPTR(dip) - (char *)dip));
481}
482
2bd0ea18
NS
483static int
484inode_u_bmbt_count(
485 void *obj,
486 int startoff)
487{
488 xfs_dinode_t *dip;
489
490 ASSERT(bitoffs(startoff) == 0);
491 ASSERT(obj == iocur_top->data);
492 dip = obj;
56b2de80
DC
493 ASSERT((char *)XFS_DFORK_DPTR(dip) - (char *)dip == byteize(startoff));
494 return dip->di_format == XFS_DINODE_FMT_BTREE;
2bd0ea18
NS
495}
496
497static int
498inode_u_bmx_count(
499 void *obj,
500 int startoff)
501{
502 xfs_dinode_t *dip;
503
504 ASSERT(bitoffs(startoff) == 0);
505 ASSERT(obj == iocur_top->data);
506 dip = obj;
56b2de80
DC
507 ASSERT((char *)XFS_DFORK_DPTR(dip) - (char *)dip == byteize(startoff));
508 return dip->di_format == XFS_DINODE_FMT_EXTENTS ?
509 be32_to_cpu(dip->di_nextents) : 0;
2bd0ea18
NS
510}
511
512static int
513inode_u_c_count(
514 void *obj,
515 int startoff)
516{
517 xfs_dinode_t *dip;
518
519 ASSERT(bitoffs(startoff) == 0);
520 ASSERT(obj == iocur_top->data);
521 dip = obj;
56b2de80
DC
522 ASSERT((char *)XFS_DFORK_DPTR(dip) - (char *)dip == byteize(startoff));
523 return dip->di_format == XFS_DINODE_FMT_LOCAL &&
524 (be16_to_cpu(dip->di_mode) & S_IFMT) == S_IFREG ?
525 (int)be64_to_cpu(dip->di_size) : 0;
2bd0ea18
NS
526}
527
528static int
529inode_u_dev_count(
530 void *obj,
531 int startoff)
532{
533 xfs_dinode_t *dip;
534
535 ASSERT(bitoffs(startoff) == 0);
536 ASSERT(obj == iocur_top->data);
537 dip = obj;
56b2de80
DC
538 ASSERT((char *)XFS_DFORK_DPTR(dip) - (char *)dip == byteize(startoff));
539 return dip->di_format == XFS_DINODE_FMT_DEV;
2bd0ea18
NS
540}
541
542static int
543inode_u_muuid_count(
544 void *obj,
545 int startoff)
546{
547 xfs_dinode_t *dip;
548
549 ASSERT(bitoffs(startoff) == 0);
550 ASSERT(obj == iocur_top->data);
551 dip = obj;
56b2de80
DC
552 ASSERT((char *)XFS_DFORK_DPTR(dip) - (char *)dip == byteize(startoff));
553 return dip->di_format == XFS_DINODE_FMT_UUID;
2bd0ea18
NS
554}
555
2bd0ea18
NS
556static int
557inode_u_sfdir2_count(
558 void *obj,
559 int startoff)
560{
561 xfs_dinode_t *dip;
562
563 ASSERT(bitoffs(startoff) == 0);
564 ASSERT(obj == iocur_top->data);
565 dip = obj;
56b2de80
DC
566 ASSERT((char *)XFS_DFORK_DPTR(dip) - (char *)dip == byteize(startoff));
567 return dip->di_format == XFS_DINODE_FMT_LOCAL &&
568 (be16_to_cpu(dip->di_mode) & S_IFMT) == S_IFDIR &&
3beed08e
DC
569 !xfs_sb_version_hasftype(&mp->m_sb);
570}
571
572static int
573inode_u_sfdir3_count(
574 void *obj,
575 int startoff)
576{
577 xfs_dinode_t *dip;
578
579 ASSERT(bitoffs(startoff) == 0);
580 ASSERT(obj == iocur_top->data);
581 dip = obj;
582 ASSERT((char *)XFS_DFORK_DPTR(dip) - (char *)dip == byteize(startoff));
583 return dip->di_format == XFS_DINODE_FMT_LOCAL &&
584 (be16_to_cpu(dip->di_mode) & S_IFMT) == S_IFDIR &&
585 xfs_sb_version_hasftype(&mp->m_sb);
2bd0ea18
NS
586}
587
588int
589inode_u_size(
590 void *obj,
591 int startoff,
592 int idx)
593{
594 xfs_dinode_t *dip;
595
596 ASSERT(startoff == 0);
597 ASSERT(idx == 0);
598 dip = obj;
56b2de80 599 switch (dip->di_format) {
2bd0ea18
NS
600 case XFS_DINODE_FMT_DEV:
601 return bitsz(xfs_dev_t);
602 case XFS_DINODE_FMT_LOCAL:
56b2de80 603 return bitize((int)be64_to_cpu(dip->di_size));
2bd0ea18 604 case XFS_DINODE_FMT_EXTENTS:
f8149110 605 return (int)be32_to_cpu(dip->di_nextents) *
5e656dbb 606 bitsz(xfs_bmbt_rec_t);
2bd0ea18 607 case XFS_DINODE_FMT_BTREE:
46eca962 608 return bitize((int)XFS_DFORK_DSIZE(dip, mp));
2bd0ea18
NS
609 case XFS_DINODE_FMT_UUID:
610 return bitsz(uuid_t);
611 default:
612 return 0;
613 }
614}
615
616static int
617inode_u_symlink_count(
618 void *obj,
619 int startoff)
620{
621 xfs_dinode_t *dip;
622
623 ASSERT(bitoffs(startoff) == 0);
624 ASSERT(obj == iocur_top->data);
625 dip = obj;
56b2de80
DC
626 ASSERT((char *)XFS_DFORK_DPTR(dip) - (char *)dip == byteize(startoff));
627 return dip->di_format == XFS_DINODE_FMT_LOCAL &&
628 (be16_to_cpu(dip->di_mode) & S_IFMT) == S_IFLNK ?
629 (int)be64_to_cpu(dip->di_size) : 0;
2bd0ea18
NS
630}
631
06d80a7c
DC
632/*
633 * We are now using libxfs for our IO backend, so we should always try to use
634 * inode cluster buffers rather than filesystem block sized buffers for reading
635 * inodes. This means that we always use the same buffers as libxfs operations
636 * does, and that avoids buffer cache issues caused by overlapping buffers. This
637 * can be seen clearly when trying to read the root inode. Much of this logic is
638 * similar to libxfs_imap().
639 */
2bd0ea18
NS
640void
641set_cur_inode(
642 xfs_ino_t ino)
643{
644 xfs_agblock_t agbno;
645 xfs_agino_t agino;
646 xfs_agnumber_t agno;
647 xfs_dinode_t *dip;
648 int offset;
06d80a7c
DC
649 int numblks = blkbb;
650 xfs_agblock_t cluster_agbno;
651
2bd0ea18
NS
652
653 agno = XFS_INO_TO_AGNO(mp, ino);
654 agino = XFS_INO_TO_AGINO(mp, ino);
655 agbno = XFS_AGINO_TO_AGBNO(mp, agino);
656 offset = XFS_AGINO_TO_OFFSET(mp, agino);
657 if (agno >= mp->m_sb.sb_agcount || agbno >= mp->m_sb.sb_agblocks ||
658 offset >= mp->m_sb.sb_inopblock ||
659 XFS_AGINO_TO_INO(mp, agno, agino) != ino) {
9ee7055c 660 dbprintf(_("bad inode number %lld\n"), ino);
2bd0ea18
NS
661 return;
662 }
663 cur_agno = agno;
06d80a7c
DC
664
665 if (mp->m_inode_cluster_size > mp->m_sb.sb_blocksize &&
666 mp->m_inoalign_mask) {
667 xfs_agblock_t chunk_agbno;
668 xfs_agblock_t offset_agbno;
669 int blks_per_cluster;
670
671 blks_per_cluster = mp->m_inode_cluster_size >>
672 mp->m_sb.sb_blocklog;
673 offset_agbno = agbno & mp->m_inoalign_mask;
674 chunk_agbno = agbno - offset_agbno;
675 cluster_agbno = chunk_agbno +
676 ((offset_agbno / blks_per_cluster) * blks_per_cluster);
677 offset += ((agbno - cluster_agbno) * mp->m_sb.sb_inopblock);
678 numblks = XFS_FSB_TO_BB(mp, blks_per_cluster);
679 } else
680 cluster_agbno = agbno;
681
2bd0ea18
NS
682 /*
683 * First set_cur to the block with the inode
684 * then use off_cur to get the right part of the buffer.
685 */
686 ASSERT(typtab[TYP_INODE].typnm == TYP_INODE);
687
688 /* ingore ring update here, do it explicitly below */
06d80a7c
DC
689 set_cur(&typtab[TYP_INODE], XFS_AGB_TO_DADDR(mp, agno, cluster_agbno),
690 numblks, DB_RING_IGN, NULL);
2bd0ea18 691 off_cur(offset << mp->m_sb.sb_inodelog, mp->m_sb.sb_inodesize);
603ab21e
DW
692 if (!iocur_top->data)
693 return;
2bd0ea18 694 dip = iocur_top->data;
a73b88f2 695 iocur_top->ino_buf = 1;
2bd0ea18 696 iocur_top->ino = ino;
56b2de80 697 iocur_top->mode = be16_to_cpu(dip->di_mode);
322f2a29 698 if ((iocur_top->mode & S_IFMT) == S_IFDIR)
2bd0ea18
NS
699 iocur_top->dirino = ino;
700
b335ecb5
ES
701 if (xfs_sb_version_hascrc(&mp->m_sb)) {
702 iocur_top->ino_crc_ok = libxfs_verify_cksum((char *)dip,
703 mp->m_sb.sb_inodesize,
704 XFS_DINODE_CRC_OFF);
705 if (!iocur_top->ino_crc_ok)
706 dbprintf(
707_("Metadata CRC error detected for ino %lld\n"),
708 ino);
709 }
710
2bd0ea18
NS
711 /* track updated info in ring */
712 ring_add();
713}