2
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
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.
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.
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.
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.
23
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24
* Mountain View, CA 94043, or:
28
* For further information regarding this notice, see:
30
* http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
48
DBM_UNKNOWN, DBM_AGF, DBM_AGFL, DBM_AGI,
49
DBM_ATTR, DBM_BTBMAPA, DBM_BTBMAPD, DBM_BTBNO,
50
DBM_BTCNT, DBM_BTINO, DBM_DATA, DBM_DIR,
51
DBM_FREE1, DBM_FREE2, DBM_FREELIST, DBM_INODE,
52
DBM_LOG, DBM_MISSING, DBM_QUOTA, DBM_RTBITMAP,
53
DBM_RTDATA, DBM_RTFREE, DBM_RTSUM, DBM_SB,
58
typedef struct inodata {
66
struct inodata *parent;
69
#define MIN_INODATA_HASH_SIZE 256
70
#define MAX_INODATA_HASH_SIZE 65536
71
#define INODATA_AVG_HASH_LENGTH 8
73
typedef struct qinfo {
79
#define QDATA_HASH_SIZE 256
80
typedef struct qdata {
87
typedef struct blkent {
88
xfs_fileoff_t startoff;
90
xfs_fsblock_t blks[1];
92
#define BLKENT_SIZE(n) \
93
(offsetof(blkent_t, blks) + (sizeof(xfs_fsblock_t) * (n)))
95
typedef struct blkmap {
100
#define BLKMAP_SIZE(n) \
101
(offsetof(blkmap_t, ents) + (sizeof(blkent_t *) * (n)))
103
typedef struct freetab {
106
xfs_dir2_data_off_t ents[1];
108
#define FREETAB_SIZE(n) \
109
(offsetof(freetab_t, ents) + (sizeof(xfs_dir2_data_off_t) * (n)))
111
typedef struct dirhash {
112
struct dirhash *next;
113
xfs_dir2_leaf_entry_t entry;
116
#define DIR_HASH_SIZE 1024
117
#define DIR_HASH_FUNC(h,a) (((h) ^ (a)) % DIR_HASH_SIZE)
119
static xfs_extlen_t agffreeblks;
120
static xfs_extlen_t agflongest;
121
static xfs_agino_t agicount;
122
static xfs_agino_t agifreecount;
123
static xfs_fsblock_t *blist;
124
static int blist_size;
125
static char **dbmap; /* really dbm_t:8 */
126
static dirhash_t **dirhash;
128
static __uint64_t fdblocks;
129
static __uint64_t frextents;
130
static __uint64_t icount;
131
static __uint64_t ifree;
132
static inodata_t ***inodata;
133
static int inodata_hash_size;
134
static inodata_t ***inomap;
137
static qdata_t **qgdata;
139
static qdata_t **qudata;
141
static unsigned sbversion;
142
static int sbver_err;
143
static int serious_error;
145
static xfs_suminfo_t *sumcompute;
146
static xfs_suminfo_t *sumfile;
147
static const char *typename[] = {
177
#define CHECK_BLIST(b) (blist_size && check_blist(b))
178
#define CHECK_BLISTA(a,b) \
179
(blist_size && check_blist(XFS_AGB_TO_FSB(mp, a, b)))
181
typedef void (*scan_lbtree_f_t)(xfs_btree_lblock_t *block,
193
typedef void (*scan_sbtree_f_t)(xfs_btree_sblock_t *block,
199
static void add_blist(xfs_fsblock_t bno);
200
static void add_ilist(xfs_ino_t ino);
201
static void addlink_inode(inodata_t *id);
202
static void addname_inode(inodata_t *id, char *name, int namelen);
203
static void addparent_inode(inodata_t *id, xfs_ino_t parent);
204
static void blkent_append(blkent_t **entp, xfs_fsblock_t b,
206
static blkent_t *blkent_new(xfs_fileoff_t o, xfs_fsblock_t b,
208
static void blkent_prepend(blkent_t **entp, xfs_fsblock_t b,
210
static blkmap_t *blkmap_alloc(xfs_extnum_t);
211
static void blkmap_free(blkmap_t *blkmap);
212
static xfs_fsblock_t blkmap_get(blkmap_t *blkmap, xfs_fileoff_t o);
213
static int blkmap_getn(blkmap_t *blkmap, xfs_fileoff_t o, int nb,
215
static void blkmap_grow(blkmap_t **blkmapp, blkent_t **entp,
217
static xfs_fileoff_t blkmap_next_off(blkmap_t *blkmap, xfs_fileoff_t o,
219
static void blkmap_set_blk(blkmap_t **blkmapp, xfs_fileoff_t o,
221
static void blkmap_set_ext(blkmap_t **blkmapp, xfs_fileoff_t o,
222
xfs_fsblock_t b, xfs_extlen_t c);
223
static void blkmap_shrink(blkmap_t *blkmap, blkent_t **entp);
224
static int blockfree_f(int argc, char **argv);
225
static int blockget_f(int argc, char **argv);
227
static int blocktrash_f(int argc, char **argv);
229
static int blockuse_f(int argc, char **argv);
230
static int check_blist(xfs_fsblock_t bno);
231
static void check_dbmap(xfs_agnumber_t agno, xfs_agblock_t agbno,
232
xfs_extlen_t len, dbm_t type);
233
static int check_inomap(xfs_agnumber_t agno, xfs_agblock_t agbno,
234
xfs_extlen_t len, xfs_ino_t c_ino);
235
static void check_linkcounts(xfs_agnumber_t agno);
236
static int check_range(xfs_agnumber_t agno, xfs_agblock_t agbno,
238
static void check_rdbmap(xfs_drfsbno_t bno, xfs_extlen_t len,
240
static int check_rinomap(xfs_drfsbno_t bno, xfs_extlen_t len,
242
static void check_rootdir(void);
243
static int check_rrange(xfs_drfsbno_t bno, xfs_extlen_t len);
244
static void check_set_dbmap(xfs_agnumber_t agno,
245
xfs_agblock_t agbno, xfs_extlen_t len,
246
dbm_t type1, dbm_t type2,
247
xfs_agnumber_t c_agno,
248
xfs_agblock_t c_agbno);
249
static void check_set_rdbmap(xfs_drfsbno_t bno, xfs_extlen_t len,
250
dbm_t type1, dbm_t type2);
251
static void check_summary(void);
252
static void checknot_dbmap(xfs_agnumber_t agno, xfs_agblock_t agbno,
253
xfs_extlen_t len, int typemask);
254
static void checknot_rdbmap(xfs_drfsbno_t bno, xfs_extlen_t len,
256
static void dir_hash_add(xfs_dahash_t hash,
257
xfs_dir2_dataptr_t addr);
258
static void dir_hash_check(inodata_t *id, int v);
259
static void dir_hash_done(void);
260
static void dir_hash_init(void);
261
static int dir_hash_see(xfs_dahash_t hash,
262
xfs_dir2_dataptr_t addr);
263
static inodata_t *find_inode(xfs_ino_t ino, int add);
264
static void free_inodata(xfs_agnumber_t agno);
265
static int init(int argc, char **argv);
266
static char *inode_name(xfs_ino_t ino, inodata_t **ipp);
267
static int ncheck_f(int argc, char **argv);
268
static char *prepend_path(char *oldpath, char *parent);
269
static xfs_ino_t process_block_dir_v2(blkmap_t *blkmap, int *dot,
270
int *dotdot, inodata_t *id);
271
static void process_bmbt_reclist(xfs_bmbt_rec_32_t *rp, int numrecs,
272
dbm_t type, inodata_t *id,
275
static void process_btinode(inodata_t *id, xfs_dinode_t *dip,
276
dbm_t type, xfs_drfsbno_t *totd,
277
xfs_drfsbno_t *toti, xfs_extnum_t *nex,
278
blkmap_t **blkmapp, int whichfork);
279
static xfs_ino_t process_data_dir_v2(int *dot, int *dotdot,
280
inodata_t *id, int v,
282
freetab_t **freetabp);
283
static xfs_dir2_data_free_t
284
*process_data_dir_v2_freefind(xfs_dir2_data_t *data,
285
xfs_dir2_data_unused_t *dup);
286
static void process_dir(xfs_dinode_t *dip, blkmap_t *blkmap,
288
static int process_dir_v1(xfs_dinode_t *dip, blkmap_t *blkmap,
289
int *dot, int *dotdot, inodata_t *id,
291
static int process_dir_v2(xfs_dinode_t *dip, blkmap_t *blkmap,
292
int *dot, int *dotdot, inodata_t *id,
294
static void process_exinode(inodata_t *id, xfs_dinode_t *dip,
295
dbm_t type, xfs_drfsbno_t *totd,
296
xfs_drfsbno_t *toti, xfs_extnum_t *nex,
297
blkmap_t **blkmapp, int whichfork);
298
static void process_inode(xfs_agf_t *agf, xfs_agino_t agino,
299
xfs_dinode_t *dip, int isfree);
300
static void process_lclinode(inodata_t *id, xfs_dinode_t *dip,
301
dbm_t type, xfs_drfsbno_t *totd,
302
xfs_drfsbno_t *toti, xfs_extnum_t *nex,
303
blkmap_t **blkmapp, int whichfork);
304
static xfs_ino_t process_leaf_dir_v1(blkmap_t *blkmap, int *dot,
305
int *dotdot, inodata_t *id);
306
static xfs_ino_t process_leaf_dir_v1_int(int *dot, int *dotdot,
308
static xfs_ino_t process_leaf_node_dir_v2(blkmap_t *blkmap, int *dot,
309
int *dotdot, inodata_t *id,
310
xfs_fsize_t dirsize);
311
static void process_leaf_node_dir_v2_free(inodata_t *id, int v,
314
static void process_leaf_node_dir_v2_int(inodata_t *id, int v,
317
static xfs_ino_t process_node_dir_v1(blkmap_t *blkmap, int *dot,
318
int *dotdot, inodata_t *id);
319
static void process_quota(int isgrp, inodata_t *id,
321
static void process_rtbitmap(blkmap_t *blkmap);
322
static void process_rtsummary(blkmap_t *blkmap);
323
static xfs_ino_t process_sf_dir_v2(xfs_dinode_t *dip, int *dot,
324
int *dotdot, inodata_t *id);
325
static xfs_ino_t process_shortform_dir_v1(xfs_dinode_t *dip, int *dot,
326
int *dotdot, inodata_t *id);
327
static void quota_add(xfs_dqid_t grpid, xfs_dqid_t usrid,
328
int dq, xfs_qcnt_t bc, xfs_qcnt_t ic,
330
static void quota_add1(qdata_t **qt, xfs_dqid_t id, int dq,
331
xfs_qcnt_t bc, xfs_qcnt_t ic,
333
static void quota_check(char *s, qdata_t **qt);
334
static void quota_init(void);
335
static void scan_ag(xfs_agnumber_t agno);
336
static void scan_freelist(xfs_agf_t *agf);
337
static void scan_lbtree(xfs_fsblock_t root, int nlevels,
338
scan_lbtree_f_t func, dbm_t type,
339
inodata_t *id, xfs_drfsbno_t *totd,
340
xfs_drfsbno_t *toti, xfs_extnum_t *nex,
341
blkmap_t **blkmapp, int isroot,
343
static void scan_sbtree(xfs_agf_t *agf, xfs_agblock_t root,
344
int nlevels, int isroot,
345
scan_sbtree_f_t func, typnm_t btype);
346
static void scanfunc_bmap(xfs_btree_lblock_t *ablock, int level,
347
dbm_t type, xfs_fsblock_t bno,
348
inodata_t *id, xfs_drfsbno_t *totd,
349
xfs_drfsbno_t *toti, xfs_extnum_t *nex,
350
blkmap_t **blkmapp, int isroot,
352
static void scanfunc_bno(xfs_btree_sblock_t *ablock, int level,
353
xfs_agf_t *agf, xfs_agblock_t bno,
355
static void scanfunc_cnt(xfs_btree_sblock_t *ablock, int level,
356
xfs_agf_t *agf, xfs_agblock_t bno,
358
static void scanfunc_ino(xfs_btree_sblock_t *ablock, int level,
359
xfs_agf_t *agf, xfs_agblock_t bno,
361
static void set_dbmap(xfs_agnumber_t agno, xfs_agblock_t agbno,
362
xfs_extlen_t len, dbm_t type,
363
xfs_agnumber_t c_agno, xfs_agblock_t c_agbno);
364
static void set_inomap(xfs_agnumber_t agno, xfs_agblock_t agbno,
365
xfs_extlen_t len, inodata_t *id);
366
static void set_rdbmap(xfs_drfsbno_t bno, xfs_extlen_t len,
368
static void set_rinomap(xfs_drfsbno_t bno, xfs_extlen_t len,
370
static void setlink_inode(inodata_t *id, nlink_t nlink, int isdir,
373
static const cmdinfo_t blockfree_cmd =
374
{ "blockfree", NULL, blockfree_f, 0, 0, 0,
375
NULL, "free block usage information", NULL };
376
static const cmdinfo_t blockget_cmd =
377
{ "blockget", "check", blockget_f, 0, -1, 0,
378
"[-s|-v] [-n] [-b bno]... [-i ino] ...",
379
"get block usage and check consistency", NULL };
381
static const cmdinfo_t blocktrash_cmd =
382
{ "blocktrash", NULL, blocktrash_f, 0, -1, 0,
383
"[-n count] [-x minlen] [-y maxlen] [-s seed] [-0123] [-t type] ...",
384
"trash randomly selected block(s)", NULL };
386
static const cmdinfo_t blockuse_cmd =
387
{ "blockuse", NULL, blockuse_f, 0, 3, 0,
388
"[-n] [-c blockcount]",
389
"print usage for current block(s)", NULL };
390
static const cmdinfo_t ncheck_cmd =
391
{ "ncheck", NULL, ncheck_f, 0, -1, 0,
393
"print inode-name pairs", NULL };
401
blist = xrealloc(blist, blist_size * sizeof(bno));
402
blist[blist_size - 1] = bno;
411
id = find_inode(ino, 1);
413
dbprintf("-i %lld bad inode number\n", ino);
424
if (verbose || id->ilist)
425
dbprintf("inode %lld add link, now %u\n", id->ino,
435
if (!nflag || id->name)
437
id->name = xmalloc(namelen + 1);
438
memcpy(id->name, name, namelen);
439
id->name[namelen] = '\0';
449
pid = find_inode(parent, 1);
451
if (verbose || id->ilist || (pid && pid->ilist))
452
dbprintf("inode %lld parent %lld\n", id->ino, parent);
465
*entp = ent = xrealloc(ent, BLKENT_SIZE(c + ent->nblks));
466
for (i = 0; i < c; i++)
467
ent->blks[ent->nblks + i] = b + i;
480
ent = xmalloc(BLKENT_SIZE(c));
483
for (i = 0; i < c; i++)
484
ent->blks[i] = b + i;
499
newent = xmalloc(BLKENT_SIZE(oldent->nblks + c));
500
newent->nblks = oldent->nblks + c;
501
newent->startoff = oldent->startoff - c;
502
for (i = 0; i < c; i++)
503
newent->blks[i] = b + c;
504
for (; i < oldent->nblks + c; i++)
505
newent->blks[i] = oldent->blks[i - c];
518
blkmap = xmalloc(BLKMAP_SIZE(nex));
519
blkmap->naents = nex;
531
for (i = 0, entp = blkmap->ents; i < blkmap->nents; i++, entp++)
545
for (i = 0, entp = blkmap->ents; i < blkmap->nents; i++, entp++) {
547
if (o >= ent->startoff && o < ent->startoff + ent->nblks)
548
return ent->blks[o - ent->startoff];
567
for (i = nex = 0, bmp = NULL, entp = blkmap->ents;
571
if (ent->startoff >= o + nb)
573
if (ent->startoff + ent->nblks <= o)
575
for (ento = ent->startoff;
576
ento < ent->startoff + ent->nblks && ento < o + nb;
581
bmp[nex - 1].startoff + bmp[nex - 1].blockcount ==
583
bmp[nex - 1].startblock + bmp[nex - 1].blockcount ==
584
ent->blks[ento - ent->startoff])
585
bmp[nex - 1].blockcount++;
587
bmp = realloc(bmp, ++nex * sizeof(*bmp));
588
bmp[nex - 1].startoff = ento;
589
bmp[nex - 1].startblock =
590
ent->blks[ento - ent->startoff];
591
bmp[nex - 1].blockcount = 1;
592
bmp[nex - 1].flag = 0;
611
idx = (int)(entp - blkmap->ents);
612
if (blkmap->naents == blkmap->nents) {
613
blkmap = xrealloc(blkmap, BLKMAP_SIZE(blkmap->nents + 1));
617
for (i = blkmap->nents; i > idx; i--)
618
blkmap->ents[i] = blkmap->ents[i - 1];
619
blkmap->ents[idx] = newent;
631
ent = blkmap->ents[blkmap->nents - 1];
632
return ent->startoff + ent->nblks;
646
if (o == NULLFILEOFF) {
648
ent = blkmap->ents[0];
649
return ent->startoff;
651
entp = &blkmap->ents[*t];
653
if (o < ent->startoff + ent->nblks - 1)
656
if (entp >= &blkmap->ents[blkmap->nents])
660
return ent->startoff;
675
for (entp = blkmap->ents; entp < &blkmap->ents[blkmap->nents]; entp++) {
677
if (o < ent->startoff - 1) {
678
ent = blkent_new(o, b, 1);
679
blkmap_grow(blkmapp, entp, ent);
682
if (o == ent->startoff - 1) {
683
blkent_prepend(entp, b, 1);
686
if (o >= ent->startoff && o < ent->startoff + ent->nblks) {
687
ent->blks[o - ent->startoff] = b;
690
if (o > ent->startoff + ent->nblks)
692
blkent_append(entp, b, 1);
693
if (entp == &blkmap->ents[blkmap->nents - 1])
697
if (ent->startoff + ent->nblks < nextent->startoff)
699
blkent_append(entp, nextent->blks[0], nextent->nblks);
700
blkmap_shrink(blkmap, &entp[1]);
703
ent = blkent_new(o, b, 1);
704
blkmap_grow(blkmapp, entp, ent);
720
if (!blkmap->nents) {
721
blkmap->ents[0] = blkent_new(o, b, c);
725
entp = &blkmap->ents[blkmap->nents - 1];
727
if (ent->startoff + ent->nblks == o) {
728
blkent_append(entp, b, c);
731
if (ent->startoff + ent->nblks < o) {
732
ent = blkent_new(o, b, c);
733
blkmap_grow(blkmapp, &blkmap->ents[blkmap->nents], ent);
736
for (i = 0; i < c; i++)
737
blkmap_set_blk(blkmapp, o + i, b + i);
749
idx = (int)(entp - blkmap->ents);
750
for (i = idx + 1; i < blkmap->nents; i++)
751
blkmap->ents[i] = blkmap->ents[i - 1];
765
dbprintf("block usage information not allocated\n");
768
rt = mp->m_sb.sb_rextents != 0;
769
for (c = 0; c < mp->m_sb.sb_agcount; c++) {
779
sumcompute = sumfile = NULL;
791
* Check consistency of xfs filesystem contents.
803
dbprintf("already have block usage information\n");
806
if (!init(argc, argv))
808
oldprefix = dbprefix;
810
for (agno = 0, sbyell = 0; agno < mp->m_sb.sb_agcount; agno++) {
812
if (sbver_err > 4 && !sbyell && sbver_err >= agno) {
814
dbprintf("WARNING: this may be a newer XFS "
825
dbprefix = oldprefix;
829
for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
831
* Check that there are no blocks either
832
* a) unaccounted for or
833
* b) bno-free but not cnt-free
835
checknot_dbmap(agno, 0, mp->m_sb.sb_agblocks,
836
(1 << DBM_UNKNOWN) | (1 << DBM_FREE1));
837
check_linkcounts(agno);
839
if (mp->m_sb.sb_rblocks) {
841
(xfs_extlen_t)(mp->m_sb.sb_rextents *
842
mp->m_sb.sb_rextsize),
846
if (mp->m_sb.sb_icount != icount) {
848
dbprintf("sb_icount %lld, counted %lld\n",
849
mp->m_sb.sb_icount, icount);
852
if (mp->m_sb.sb_ifree != ifree) {
854
dbprintf("sb_ifree %lld, counted %lld\n",
855
mp->m_sb.sb_ifree, ifree);
858
if (mp->m_sb.sb_fdblocks != fdblocks) {
860
dbprintf("sb_fdblocks %lld, counted %lld\n",
861
mp->m_sb.sb_fdblocks, fdblocks);
864
if (mp->m_sb.sb_frextents != frextents) {
866
dbprintf("sb_frextents %lld, counted %lld\n",
867
mp->m_sb.sb_frextents, frextents);
870
if ((sbversion & XFS_SB_VERSION_ATTRBIT) &&
871
!XFS_SB_VERSION_HASATTR(&mp->m_sb)) {
873
dbprintf("sb versionnum missing attr bit %x\n",
874
XFS_SB_VERSION_ATTRBIT);
877
if ((sbversion & XFS_SB_VERSION_NLINKBIT) &&
878
!XFS_SB_VERSION_HASNLINK(&mp->m_sb)) {
880
dbprintf("sb versionnum missing nlink bit %x\n",
881
XFS_SB_VERSION_NLINKBIT);
884
if ((sbversion & XFS_SB_VERSION_QUOTABIT) &&
885
!XFS_SB_VERSION_HASQUOTA(&mp->m_sb)) {
887
dbprintf("sb versionnum missing quota bit %x\n",
888
XFS_SB_VERSION_QUOTABIT);
891
if (!(sbversion & XFS_SB_VERSION_ALIGNBIT) &&
892
XFS_SB_VERSION_HASALIGN(&mp->m_sb)) {
894
dbprintf("sb versionnum extra align bit %x\n",
895
XFS_SB_VERSION_ALIGNBIT);
899
quota_check("user", qudata);
901
quota_check("group", qgdata);
902
if (sbver_err > mp->m_sb.sb_agcount / 2)
903
dbprintf("WARNING: this may be a newer XFS filesystem.\n");
906
dbprefix = oldprefix;
911
typedef struct ltab {
932
static char *modestr[] = {
933
"zeroed", "set", "flipped", "randomized"
936
len = (int)((random() % (ltabp->max - ltabp->min + 1)) + ltabp->min);
937
offset = (int)(random() % (int)(mp->m_sb.sb_blocksize * NBBY));
940
set_cur(&typtab[DBM_UNKNOWN],
941
XFS_AGB_TO_DADDR(mp, agno, agbno), blkbb, DB_RING_IGN, NULL);
942
if ((buf = iocur_top->data) == NULL) {
943
dbprintf("can't read block %u/%u for trashing\n", agno, agbno);
947
for (bitno = 0; bitno < len; bitno++) {
948
bit = (offset + bitno) % (mp->m_sb.sb_blocksize * NBBY);
960
newbit = (buf[byte] & mask) == 0;
963
newbit = (int)random() & 1;
973
printf("blocktrash: %u/%u %s block %d bit%s starting %d:%d %s\n",
974
agno, agbno, typename[type], len, len == 1 ? "" : "s",
975
offset / NBBY, offset % NBBY, modestr[mode]);
986
xfs_drfsbno_t blocks;
1005
dbprintf("must run blockget first\n");
1013
gettimeofday(&now, NULL);
1014
seed = (unsigned int)(now.tv_sec ^ now.tv_usec);
1017
goodmask = (1 << DBM_AGF) |
1021
(1 << DBM_BTBMAPA) |
1022
(1 << DBM_BTBMAPD) |
1029
(1 << DBM_RTBITMAP) |
1032
while ((c = getopt(argc, argv, "0123n:s:t:x:y:")) != EOF) {
1047
count = (int)strtol(optarg, &p, 0);
1048
if (*p != '\0' || count <= 0) {
1049
dbprintf("bad blocktrash count %s\n", optarg);
1054
seed = (uint)strtoul(optarg, &p, 0);
1058
for (i = 0; typename[i]; i++) {
1059
if (strcmp(typename[i], optarg) == 0)
1062
if (!typename[i] || (((1 << i) & goodmask) == 0)) {
1063
dbprintf("bad blocktrash type %s\n", optarg);
1069
min = (int)strtol(optarg, &p, 0);
1070
if (*p != '\0' || min <= 0 ||
1071
min > mp->m_sb.sb_blocksize * NBBY) {
1072
dbprintf("bad blocktrash min %s\n", optarg);
1077
max = (int)strtol(optarg, &p, 0);
1078
if (*p != '\0' || max <= 0 ||
1079
max > mp->m_sb.sb_blocksize * NBBY) {
1080
dbprintf("bad blocktrash max %s\n", optarg);
1085
dbprintf("bad option for blocktrash command\n");
1090
dbprintf("bad min/max for blocktrash command\n");
1095
lentab = xmalloc(sizeof(ltab_t));
1096
lentab->min = lentab->max = min;
1098
for (i = min + 1; i <= max; i++) {
1099
if ((i & (i - 1)) == 0) {
1100
lentab = xrealloc(lentab,
1101
sizeof(ltab_t) * (lentablen + 1));
1102
lentab[lentablen].min = lentab[lentablen].max = i;
1105
lentab[lentablen - 1].max = i;
1107
for (blocks = 0, agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
1108
for (agbno = 0, p = dbmap[agno];
1109
agbno < mp->m_sb.sb_agblocks;
1111
if ((1 << *p) & tmask)
1116
dbprintf("blocktrash: no matching blocks\n");
1120
dbprintf("blocktrash: seed %u\n", seed);
1122
for (i = 0; i < count; i++) {
1123
randb = (xfs_drfsbno_t)((((__int64_t)random() << 32) |
1124
random()) % blocks);
1125
for (bi = 0, agno = 0, done = 0;
1126
!done && agno < mp->m_sb.sb_agcount;
1128
for (agbno = 0, p = dbmap[agno];
1129
agbno < mp->m_sb.sb_agblocks;
1131
if (!((1 << *p) & tmask))
1135
blocktrash_b(agno, agbno, (dbm_t)*p,
1136
&lentab[random() % lentablen], mode);
1152
xfs_agblock_t agbno;
1153
xfs_agnumber_t agno;
1163
dbprintf("must run blockget first\n");
1169
fsb = XFS_DADDR_TO_FSB(mp, iocur_top->off >> BBSHIFT);
1170
agno = XFS_FSB_TO_AGNO(mp, fsb);
1171
end = agbno = XFS_FSB_TO_AGBNO(mp, fsb);
1172
while ((c = getopt(argc, argv, "c:n")) != EOF) {
1175
count = (int)strtol(optarg, &p, 0);
1176
end = agbno + count - 1;
1177
if (*p != '\0' || count <= 0 ||
1178
end >= mp->m_sb.sb_agblocks) {
1179
dbprintf("bad blockuse count %s\n", optarg);
1185
dbprintf("must run blockget -n first\n");
1191
dbprintf("bad option for blockuse command\n");
1195
while (agbno <= end) {
1196
p = &dbmap[agno][agbno];
1197
i = inomap[agno][agbno];
1198
dbprintf("block %llu (%u/%u) type %s",
1199
(xfs_dfsbno_t)XFS_AGB_TO_FSB(mp, agno, agbno),
1200
agno, agbno, typename[(dbm_t)*p]);
1202
dbprintf(" inode %lld", i->ino);
1203
if (shownames && (p = inode_name(i->ino, NULL))) {
1220
for (i = 0; i < blist_size; i++) {
1221
if (blist[i] == bno)
1229
xfs_agnumber_t agno,
1230
xfs_agblock_t agbno,
1237
for (i = 0, p = &dbmap[agno][agbno]; i < len; i++, p++) {
1238
if ((dbm_t)*p != type) {
1239
if (!sflag || CHECK_BLISTA(agno, agbno + i))
1240
dbprintf("block %u/%u expected type %s got "
1242
agno, agbno + i, typename[type],
1243
typename[(dbm_t)*p]);
1252
add_command(&blockfree_cmd);
1253
add_command(&blockget_cmd);
1255
add_command(&blocktrash_cmd);
1257
add_command(&blockuse_cmd);
1258
add_command(&ncheck_cmd);
1263
xfs_agnumber_t agno,
1264
xfs_agblock_t agbno,
1272
if (!check_range(agno, agbno, len)) {
1273
dbprintf("blocks %u/%u..%u claimed by inode %lld\n",
1274
agno, agbno, agbno + len - 1, c_ino);
1277
for (i = 0, rval = 1, idp = &inomap[agno][agbno]; i < len; i++, idp++) {
1279
if (!sflag || (*idp)->ilist ||
1280
CHECK_BLISTA(agno, agbno + i))
1281
dbprintf("block %u/%u claimed by inode %lld, "
1282
"previous inum %lld\n",
1283
agno, agbno + i, c_ino, (*idp)->ino);
1293
xfs_agnumber_t agno)
1301
for (idx = 0; idx < inodata_hash_size; ht++, idx++) {
1304
if (ep->link_set != ep->link_add || ep->link_set == 0) {
1305
path = inode_name(ep->ino, NULL);
1306
if (!path && ep->link_add)
1307
path = xstrdup("?");
1308
if (!sflag || ep->ilist) {
1310
dbprintf("link count mismatch "
1311
"for inode %lld (name "
1317
else if (ep->link_set)
1318
dbprintf("disconnected inode "
1320
ep->ino, ep->link_set);
1322
dbprintf("allocated inode %lld "
1323
"has 0 link count\n",
1329
} else if (verbose || ep->ilist) {
1330
path = inode_name(ep->ino, NULL);
1332
dbprintf("inode %lld name %s\n",
1345
xfs_agnumber_t agno,
1346
xfs_agblock_t agbno,
1351
if (agno >= mp->m_sb.sb_agcount ||
1352
agbno + len - 1 >= mp->m_sb.sb_agblocks) {
1353
for (i = 0; i < len; i++) {
1354
if (!sflag || CHECK_BLISTA(agno, agbno + i))
1355
dbprintf("block %u/%u out of range\n",
1373
for (i = 0, p = &dbmap[mp->m_sb.sb_agcount][bno]; i < len; i++, p++) {
1374
if ((dbm_t)*p != type) {
1375
if (!sflag || CHECK_BLIST(bno + i))
1376
dbprintf("rtblock %llu expected type %s got "
1378
bno + i, typename[type],
1379
typename[(dbm_t)*p]);
1395
if (!check_rrange(bno, len)) {
1396
dbprintf("rtblocks %llu..%llu claimed by inode %lld\n",
1397
bno, bno + len - 1, c_ino);
1400
for (i = 0, rval = 1, idp = &inomap[mp->m_sb.sb_agcount][bno];
1404
if (!sflag || (*idp)->ilist || CHECK_BLIST(bno + i))
1405
dbprintf("rtblock %llu claimed by inode %lld, "
1406
"previous inum %lld\n",
1407
bno + i, c_ino, (*idp)->ino);
1420
id = find_inode(mp->m_sb.sb_rootino, 0);
1423
dbprintf("root inode %lld is missing\n",
1424
mp->m_sb.sb_rootino);
1426
} else if (!id->isdir) {
1427
if (!sflag || id->ilist)
1428
dbprintf("root inode %lld is not a directory\n",
1429
mp->m_sb.sb_rootino);
1441
if (bno + len - 1 >= mp->m_sb.sb_rblocks) {
1442
for (i = 0; i < len; i++) {
1443
if (!sflag || CHECK_BLIST(bno + i))
1444
dbprintf("rtblock %llu out of range\n",
1455
xfs_agnumber_t agno,
1456
xfs_agblock_t agbno,
1460
xfs_agnumber_t c_agno,
1461
xfs_agblock_t c_agbno)
1467
if (!check_range(agno, agbno, len)) {
1468
dbprintf("blocks %u/%u..%u claimed by block %u/%u\n", agno,
1469
agbno, agbno + len - 1, c_agno, c_agbno);
1472
check_dbmap(agno, agbno, len, type1);
1473
mayprint = verbose | blist_size;
1474
for (i = 0, p = &dbmap[agno][agbno]; i < len; i++, p++) {
1476
if (mayprint && (verbose || CHECK_BLISTA(agno, agbno + i)))
1477
dbprintf("setting block %u/%u to %s\n", agno, agbno + i,
1493
if (!check_rrange(bno, len))
1495
check_rdbmap(bno, len, type1);
1496
mayprint = verbose | blist_size;
1497
for (i = 0, p = &dbmap[mp->m_sb.sb_agcount][bno]; i < len; i++, p++) {
1499
if (mayprint && (verbose || CHECK_BLIST(bno + i)))
1500
dbprintf("setting rtblock %llu to %s\n",
1501
bno + i, typename[type2]);
1515
for (log = 0; log < mp->m_rsumlevels; log++) {
1517
bno < mp->m_sb.sb_rbmblocks;
1518
bno++, csp++, fsp++) {
1521
dbprintf("rt summary mismatch, size %d "
1522
"block %llu, file: %d, "
1524
log, bno, *fsp, *csp);
1533
xfs_agnumber_t agno,
1534
xfs_agblock_t agbno,
1541
if (!check_range(agno, agbno, len))
1543
for (i = 0, p = &dbmap[agno][agbno]; i < len; i++, p++) {
1544
if ((1 << *p) & typemask) {
1545
if (!sflag || CHECK_BLISTA(agno, agbno + i))
1546
dbprintf("block %u/%u type %s not expected\n",
1547
agno, agbno + i, typename[(dbm_t)*p]);
1562
if (!check_rrange(bno, len))
1564
for (i = 0, p = &dbmap[mp->m_sb.sb_agcount][bno]; i < len; i++, p++) {
1565
if ((1 << *p) & typemask) {
1566
if (!sflag || CHECK_BLIST(bno + i))
1567
dbprintf("rtblock %llu type %s not expected\n",
1568
bno + i, typename[(dbm_t)*p]);
1577
xfs_dir2_dataptr_t addr)
1582
i = DIR_HASH_FUNC(hash, addr);
1583
p = malloc(sizeof(*p));
1584
p->next = dirhash[i];
1586
p->entry.hashval = hash;
1587
p->entry.address = addr;
1599
for (i = 0; i < DIR_HASH_SIZE; i++) {
1600
for (p = dirhash[i]; p; p = p->next) {
1603
if (!sflag || id->ilist || v)
1604
dbprintf("dir ino %lld missing leaf entry for "
1606
id->ino, p->entry.hashval,
1620
for (i = 0; i < DIR_HASH_SIZE; i++) {
1621
for (p = dirhash[i]; p; p = n) {
1633
dirhash = calloc(DIR_HASH_SIZE, sizeof(*dirhash));
1639
xfs_dir2_dataptr_t addr)
1644
i = DIR_HASH_FUNC(hash, addr);
1645
for (p = dirhash[i]; p; p = p->next) {
1646
if (p->entry.hashval == hash && p->entry.address == addr) {
1662
xfs_agnumber_t agno;
1667
agno = XFS_INO_TO_AGNO(mp, ino);
1668
agino = XFS_INO_TO_AGINO(mp, ino);
1669
if (agno >= mp->m_sb.sb_agcount ||
1670
XFS_AGINO_TO_INO(mp, agno, agino) != ino)
1672
htab = inodata[agno];
1673
ih = agino % inodata_hash_size;
1676
if (ent->ino == ino)
1682
ent = xcalloc(1, sizeof(*ent));
1684
ent->next = htab[ih];
1691
xfs_agnumber_t agno)
1699
for (i = 0; i < inodata_hash_size; i++) {
1722
if (mp->m_sb.sb_magicnum != XFS_SB_MAGIC) {
1723
dbprintf("bad superblock magic number %x, giving up\n",
1724
mp->m_sb.sb_magicnum);
1727
rt = mp->m_sb.sb_rextents != 0;
1728
dbmap = xmalloc((mp->m_sb.sb_agcount + rt) * sizeof(*dbmap));
1729
inomap = xmalloc((mp->m_sb.sb_agcount + rt) * sizeof(*inomap));
1730
inodata = xmalloc(mp->m_sb.sb_agcount * sizeof(*inodata));
1732
(int)MAX(MIN(mp->m_sb.sb_icount /
1733
(INODATA_AVG_HASH_LENGTH * mp->m_sb.sb_agcount),
1734
MAX_INODATA_HASH_SIZE),
1735
MIN_INODATA_HASH_SIZE);
1736
for (c = 0; c < mp->m_sb.sb_agcount; c++) {
1737
dbmap[c] = xcalloc(mp->m_sb.sb_agblocks, sizeof(**dbmap));
1738
inomap[c] = xcalloc(mp->m_sb.sb_agblocks, sizeof(**inomap));
1739
inodata[c] = xcalloc(inodata_hash_size, sizeof(**inodata));
1742
dbmap[c] = xcalloc(mp->m_sb.sb_rblocks, sizeof(**dbmap));
1743
inomap[c] = xcalloc(mp->m_sb.sb_rblocks, sizeof(**inomap));
1744
sumfile = xcalloc(mp->m_rsumsize, 1);
1745
sumcompute = xcalloc(mp->m_rsumsize, 1);
1747
nflag = sflag = verbose = optind = 0;
1748
while ((c = getopt(argc, argv, "b:i:npsv")) != EOF) {
1751
bno = atoll(optarg);
1755
ino = atoll(optarg);
1771
dbprintf("bad option for blockget command\n");
1775
error = sbver_err = serious_error = 0;
1776
fdblocks = frextents = icount = ifree = 0;
1777
sbversion = XFS_SB_VERSION_4;
1778
if (mp->m_sb.sb_inoalignmt)
1779
sbversion |= XFS_SB_VERSION_ALIGNBIT;
1780
if ((mp->m_sb.sb_uquotino && mp->m_sb.sb_uquotino != NULLFSINO) ||
1781
(mp->m_sb.sb_gquotino && mp->m_sb.sb_gquotino != NULLFSINO))
1782
sbversion |= XFS_SB_VERSION_QUOTABIT;
1796
id = find_inode(ino, 0);
1801
if (id->name == NULL)
1803
path = xstrdup(id->name);
1804
while (id->parent) {
1806
if (id->name == NULL)
1808
npath = prepend_path(path, id->name);
1820
xfs_agnumber_t agno;
1833
if (!inodata || !nflag) {
1834
dbprintf("must run blockget -n first\n");
1837
security = optind = ilist_size = 0;
1839
while ((c = getopt(argc, argv, "i:s")) != EOF) {
1842
ino = atoll(optarg);
1843
ilist = xrealloc(ilist, (ilist_size + 1) *
1845
ilist[ilist_size++] = ino;
1851
dbprintf("bad option -%c for ncheck command\n", c);
1856
for (ilp = ilist; ilp < &ilist[ilist_size]; ilp++) {
1858
if ((p = inode_name(ino, &hp))) {
1859
dbprintf("%11llu %s", ino, p);
1869
for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
1871
for (i = 0; i < inodata_hash_size; i++) {
1873
for (hp = ht[i]; hp; hp = hp->next) {
1874
ino = XFS_AGINO_TO_INO(mp, agno, hp->ino);
1875
p = inode_name(ino, &id);
1878
if (!security || id->security) {
1879
dbprintf("%11llu %s", ino, p);
1899
len = (int)(strlen(oldpath) + strlen(parent) + 2);
1900
path = xmalloc(len);
1901
snprintf(path, len, "%s/%s", parent, oldpath);
1906
process_block_dir_v2(
1920
nex = blkmap_getn(blkmap, 0, mp->m_dirblkfsbs, &bmp);
1921
v = id->ilist || verbose;
1924
dbprintf("block 0 for directory inode %lld is "
1932
make_bbmap(&bbmap, nex, bmp);
1933
set_cur(&typtab[TYP_DIR], XFS_FSB_TO_DADDR(mp, bmp->startblock),
1934
mp->m_dirblkfsbs * blkbb, DB_RING_IGN, nex > 1 ? &bbmap : NULL);
1935
for (x = 0; !v && x < nex; x++) {
1936
for (b = bmp[x].startblock;
1937
!v && b < bmp[x].startblock + bmp[x].blockcount;
1942
if (iocur_top->data == NULL) {
1943
if (!sflag || id->ilist || v)
1944
dbprintf("can't read block 0 for directory inode "
1951
parent = process_data_dir_v2(dot, dotdot, id, v, mp->m_dirdatablk,
1953
dir_hash_check(id, v);
1960
process_bmbt_reclist(
1961
xfs_bmbt_rec_32_t *rp,
1968
xfs_agblock_t agbno;
1969
xfs_agnumber_t agno;
1975
xfs_agblock_t iagbno;
1976
xfs_agnumber_t iagno;
1983
v = verbose || id->ilist;
1984
iagno = XFS_INO_TO_AGNO(mp, id->ino);
1985
iagbno = XFS_INO_TO_AGBNO(mp, id->ino);
1986
for (i = 0; i < numrecs; i++, rp++) {
1987
convert_extent((xfs_bmbt_rec_64_t *)rp, &o, &s, &c, &f);
1989
dbprintf("inode %lld extent [%lld,%lld,%lld,%d]\n",
1990
id->ino, o, s, c, f);
1991
if (!sflag && i > 0 && op + cp > o)
1992
dbprintf("bmap rec out of order, inode %lld entry %d\n",
1996
if (type == DBM_RTDATA) {
1997
if (!sflag && s >= mp->m_sb.sb_rblocks) {
1998
dbprintf("inode %lld bad rt block number %lld, "
2003
} else if (!sflag) {
2004
agno = XFS_FSB_TO_AGNO(mp, s);
2005
agbno = XFS_FSB_TO_AGBNO(mp, s);
2006
if (agno >= mp->m_sb.sb_agcount ||
2007
agbno >= mp->m_sb.sb_agblocks) {
2008
dbprintf("inode %lld bad block number %lld "
2009
"[%d,%d], offset %lld\n",
2010
id->ino, s, agno, agbno, o);
2013
if (agbno + c - 1 >= mp->m_sb.sb_agblocks) {
2014
dbprintf("inode %lld bad block number %lld "
2015
"[%d,%d], offset %lld\n",
2016
id->ino, s + c - 1, agno,
2017
agbno + (xfs_agblock_t)c - 1, o);
2021
if (blkmapp && *blkmapp)
2022
blkmap_set_ext(blkmapp, (xfs_fileoff_t)o,
2023
(xfs_fsblock_t)s, (xfs_extlen_t)c);
2024
if (type == DBM_RTDATA) {
2025
set_rdbmap((xfs_fsblock_t)s, (xfs_extlen_t)c,
2027
set_rinomap((xfs_fsblock_t)s, (xfs_extlen_t)c, id);
2028
for (b = (xfs_fsblock_t)s;
2029
blist_size && b < s + c;
2032
dbprintf("inode %lld block %lld at "
2034
id->ino, (xfs_dfsbno_t)b, o);
2037
agno = XFS_FSB_TO_AGNO(mp, (xfs_fsblock_t)s);
2038
agbno = XFS_FSB_TO_AGBNO(mp, (xfs_fsblock_t)s);
2039
set_dbmap(agno, agbno, (xfs_extlen_t)c, type, iagno,
2041
set_inomap(agno, agbno, (xfs_extlen_t)c, id);
2042
for (b = (xfs_fsblock_t)s;
2043
blist_size && b < s + c;
2044
b++, o++, agbno++) {
2046
dbprintf("inode %lld block %lld at "
2048
id->ino, (xfs_dfsbno_t)b, o);
2060
xfs_drfsbno_t *totd,
2061
xfs_drfsbno_t *toti,
2066
xfs_bmdr_block_t *dib;
2069
xfs_bmbt_rec_32_t *rp;
2071
dib = (xfs_bmdr_block_t *)XFS_DFORK_PTR_ARCH(dip, whichfork, ARCH_NOCONVERT);
2072
if (INT_GET(dib->bb_level, ARCH_CONVERT) >= XFS_BM_MAXLEVELS(mp, whichfork)) {
2073
if (!sflag || id->ilist)
2074
dbprintf("level for ino %lld %s fork bmap root too "
2077
whichfork == XFS_DATA_FORK ? "data" : "attr",
2078
INT_GET(dib->bb_level, ARCH_CONVERT));
2082
if (INT_GET(dib->bb_numrecs, ARCH_CONVERT) >
2083
XFS_BTREE_BLOCK_MAXRECS(XFS_DFORK_SIZE_ARCH(dip, mp, whichfork, ARCH_NOCONVERT),
2084
xfs_bmdr, INT_GET(dib->bb_level, ARCH_CONVERT) == 0)) {
2085
if (!sflag || id->ilist)
2086
dbprintf("numrecs for ino %lld %s fork bmap root too "
2089
whichfork == XFS_DATA_FORK ? "data" : "attr",
2090
INT_GET(dib->bb_numrecs, ARCH_CONVERT));
2094
if (INT_GET(dib->bb_level, ARCH_CONVERT) == 0) {
2095
rp = (xfs_bmbt_rec_32_t *)XFS_BTREE_REC_ADDR(
2096
XFS_DFORK_SIZE_ARCH(dip, mp, whichfork, ARCH_NOCONVERT),
2098
XFS_BTREE_BLOCK_MAXRECS(XFS_DFORK_SIZE(dip, mp,
2101
process_bmbt_reclist(rp, INT_GET(dib->bb_numrecs, ARCH_CONVERT), type, id, totd,
2103
*nex += INT_GET(dib->bb_numrecs, ARCH_CONVERT);
2106
pp = XFS_BTREE_PTR_ADDR(XFS_DFORK_SIZE_ARCH(dip, mp, whichfork, ARCH_NOCONVERT),
2108
XFS_BTREE_BLOCK_MAXRECS(XFS_DFORK_SIZE(dip, mp,
2111
for (i = 0; i < INT_GET(dib->bb_numrecs, ARCH_CONVERT); i++)
2112
scan_lbtree((xfs_fsblock_t)INT_GET(pp[i], ARCH_CONVERT), INT_GET(dib->bb_level, ARCH_CONVERT),
2113
scanfunc_bmap, type, id, totd, toti, nex,
2115
whichfork == XFS_DATA_FORK ?
2116
TYP_BMAPBTD : TYP_BMAPBTA);
2119
XFS_DFORK_SIZE_ARCH(dip, mp, whichfork, ARCH_NOCONVERT) / sizeof(xfs_bmbt_rec_t)) {
2120
if (!sflag || id->ilist)
2121
dbprintf("extent count for ino %lld %s fork too low "
2122
"(%d) for file format\n",
2124
whichfork == XFS_DATA_FORK ? "data" : "attr",
2131
process_data_dir_v2(
2137
freetab_t **freetabp)
2139
xfs_dir2_dataptr_t addr;
2140
xfs_dir2_data_free_t *bf;
2142
xfs_dir2_block_t *block;
2143
xfs_dir2_block_tail_t *btp = NULL;
2146
xfs_dir2_data_t *data;
2148
xfs_dir2_data_entry_t *dep;
2149
xfs_dir2_data_free_t *dfp;
2150
xfs_dir2_data_unused_t *dup;
2158
xfs_dir2_leaf_entry_t *lep = NULL;
2160
xfs_ino_t parent = 0;
2164
xfs_dir2_data_off_t *tagp;
2166
data = iocur_top->data;
2167
block = iocur_top->data;
2168
if (INT_GET(block->hdr.magic, ARCH_CONVERT) != XFS_DIR2_BLOCK_MAGIC &&
2169
INT_GET(data->hdr.magic, ARCH_CONVERT) != XFS_DIR2_DATA_MAGIC) {
2171
dbprintf("bad directory data magic # %#x for dir ino "
2173
INT_GET(data->hdr.magic, ARCH_CONVERT), id->ino, dabno);
2177
db = XFS_DIR2_DA_TO_DB(mp, dabno);
2178
bf = data->hdr.bestfree;
2179
ptr = (char *)data->u;
2180
if (INT_GET(block->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC) {
2181
btp = XFS_DIR2_BLOCK_TAIL_P(mp, block);
2182
lep = XFS_DIR2_BLOCK_LEAF_P_ARCH(btp, ARCH_CONVERT);
2183
endptr = (char *)lep;
2184
if (endptr <= ptr || endptr > (char *)btp) {
2185
endptr = (char *)data + mp->m_dirblksize;
2188
dbprintf("bad block directory tail for dir ino "
2194
endptr = (char *)data + mp->m_dirblksize;
2195
bf_err = lastfree_err = tag_err = 0;
2196
count = lastfree = freeseen = 0;
2197
if (INT_GET(bf[0].length, ARCH_CONVERT) == 0) {
2198
bf_err += INT_GET(bf[0].offset, ARCH_CONVERT) != 0;
2201
if (INT_GET(bf[1].length, ARCH_CONVERT) == 0) {
2202
bf_err += INT_GET(bf[1].offset, ARCH_CONVERT) != 0;
2205
if (INT_GET(bf[2].length, ARCH_CONVERT) == 0) {
2206
bf_err += INT_GET(bf[2].offset, ARCH_CONVERT) != 0;
2209
bf_err += INT_GET(bf[0].length, ARCH_CONVERT) < INT_GET(bf[1].length, ARCH_CONVERT);
2210
bf_err += INT_GET(bf[1].length, ARCH_CONVERT) < INT_GET(bf[2].length, ARCH_CONVERT);
2212
freetab = *freetabp;
2213
if (freetab->naents <= db) {
2214
*freetabp = freetab =
2215
realloc(freetab, FREETAB_SIZE(db + 1));
2216
for (i = freetab->naents; i < db; i++)
2217
freetab->ents[i] = NULLDATAOFF;
2218
freetab->naents = db + 1;
2220
if (freetab->nents < db + 1)
2221
freetab->nents = db + 1;
2222
freetab->ents[db] = INT_GET(bf[0].length, ARCH_CONVERT);
2224
while (ptr < endptr) {
2225
dup = (xfs_dir2_data_unused_t *)ptr;
2226
if (INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG) {
2227
lastfree_err += lastfree != 0;
2228
if ((INT_GET(dup->length, ARCH_CONVERT) & (XFS_DIR2_DATA_ALIGN - 1)) ||
2229
INT_GET(dup->length, ARCH_CONVERT) == 0 ||
2230
(char *)(tagp = XFS_DIR2_DATA_UNUSED_TAG_P_ARCH(dup, ARCH_CONVERT)) >=
2233
dbprintf("dir %lld block %d bad free "
2241
tag_err += INT_GET(*tagp, ARCH_CONVERT) != (char *)dup - (char *)data;
2242
dfp = process_data_dir_v2_freefind(data, dup);
2244
i = (int)(dfp - bf);
2245
bf_err += (freeseen & (1 << i)) != 0;
2248
bf_err += INT_GET(dup->length, ARCH_CONVERT) > INT_GET(bf[2].length, ARCH_CONVERT);
2249
ptr += INT_GET(dup->length, ARCH_CONVERT);
2253
dep = (xfs_dir2_data_entry_t *)dup;
2254
if (dep->namelen == 0) {
2256
dbprintf("dir %lld block %d zero length entry "
2259
(int)((char *)dep - (char *)data));
2262
tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
2263
if ((char *)tagp >= endptr) {
2265
dbprintf("dir %lld block %d bad entry at %d\n",
2267
(int)((char *)dep - (char *)data));
2271
tag_err += INT_GET(*tagp, ARCH_CONVERT) != (char *)dep - (char *)data;
2272
addr = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, db,
2273
(char *)dep - (char *)data);
2274
hash = libxfs_da_hashname((char *)dep->name, dep->namelen);
2275
dir_hash_add(hash, addr);
2276
ptr += XFS_DIR2_DATA_ENTSIZE(dep->namelen);
2279
lino = INT_GET(dep->inumber, ARCH_CONVERT);
2280
cid = find_inode(lino, 1);
2282
dbprintf("dir %lld block %d entry %*.*s %lld\n",
2283
id->ino, dabno, dep->namelen, dep->namelen,
2289
dbprintf("dir %lld block %d entry %*.*s bad "
2290
"inode number %lld\n",
2291
id->ino, dabno, dep->namelen,
2292
dep->namelen, dep->name, lino);
2295
if (dep->namelen == 2 && dep->name[0] == '.' &&
2296
dep->name[1] == '.') {
2299
dbprintf("multiple .. entries in dir "
2300
"%lld (%lld, %lld)\n",
2301
id->ino, parent, lino);
2304
parent = cid ? lino : NULLFSINO;
2306
} else if (dep->namelen != 1 || dep->name[0] != '.') {
2310
addname_inode(cid, (char *)dep->name,
2314
if (lino != id->ino) {
2316
dbprintf("dir %lld entry . inode "
2317
"number mismatch (%lld)\n",
2324
if (INT_GET(data->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC) {
2325
endptr = (char *)data + mp->m_dirblksize;
2326
for (i = stale = 0; lep && i < INT_GET(btp->count, ARCH_CONVERT); i++) {
2327
if ((char *)&lep[i] >= endptr) {
2329
dbprintf("dir %lld block %d bad count "
2331
id->ino, dabno, INT_GET(btp->count, ARCH_CONVERT));
2335
if (INT_GET(lep[i].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR)
2337
else if (dir_hash_see(INT_GET(lep[i].hashval, ARCH_CONVERT), INT_GET(lep[i].address, ARCH_CONVERT))) {
2339
dbprintf("dir %lld block %d extra leaf "
2341
id->ino, dabno, INT_GET(lep[i].hashval, ARCH_CONVERT),
2342
INT_GET(lep[i].address, ARCH_CONVERT));
2347
bf_err += freeseen != 7;
2350
dbprintf("dir %lld block %d bad bestfree data\n",
2354
if (INT_GET(data->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC &&
2355
count != INT_GET(btp->count, ARCH_CONVERT) - INT_GET(btp->stale, ARCH_CONVERT)) {
2357
dbprintf("dir %lld block %d bad block tail count %d "
2359
id->ino, dabno, INT_GET(btp->count, ARCH_CONVERT), INT_GET(btp->stale, ARCH_CONVERT));
2362
if (INT_GET(data->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC && stale != INT_GET(btp->stale, ARCH_CONVERT)) {
2364
dbprintf("dir %lld block %d bad stale tail count %d\n",
2365
id->ino, dabno, INT_GET(btp->stale, ARCH_CONVERT));
2370
dbprintf("dir %lld block %d consecutive free entries\n",
2376
dbprintf("dir %lld block %d entry/unused tag "
2384
static xfs_dir2_data_free_t *
2385
process_data_dir_v2_freefind(
2386
xfs_dir2_data_t *data,
2387
xfs_dir2_data_unused_t *dup)
2389
xfs_dir2_data_free_t *dfp;
2390
xfs_dir2_data_aoff_t off;
2392
off = (xfs_dir2_data_aoff_t)((char *)dup - (char *)data);
2393
if (INT_GET(dup->length, ARCH_CONVERT) < INT_GET(data->hdr.bestfree[XFS_DIR2_DATA_FD_COUNT - 1].length, ARCH_CONVERT))
2395
for (dfp = &data->hdr.bestfree[0];
2396
dfp < &data->hdr.bestfree[XFS_DIR2_DATA_FD_COUNT];
2398
if (INT_GET(dfp->offset, ARCH_CONVERT) == 0)
2400
if (INT_GET(dfp->offset, ARCH_CONVERT) == off)
2418
if (XFS_DIR_IS_V2(mp)) {
2419
if (process_dir_v2(dip, blkmap, &dot, &dotdot, id, &parent))
2423
if (process_dir_v1(dip, blkmap, &dot, &dotdot, id, &parent))
2426
bno = XFS_INO_TO_FSB(mp, id->ino);
2428
if (!sflag || id->ilist || CHECK_BLIST(bno))
2429
dbprintf("no . entry for directory %lld\n", id->ino);
2433
if (!sflag || id->ilist || CHECK_BLIST(bno))
2434
dbprintf("no .. entry for directory %lld\n", id->ino);
2436
} else if (parent == id->ino && id->ino != mp->m_sb.sb_rootino) {
2437
if (!sflag || id->ilist || CHECK_BLIST(bno))
2438
dbprintf(". and .. same for non-root directory %lld\n",
2441
} else if (id->ino == mp->m_sb.sb_rootino && id->ino != parent) {
2442
if (!sflag || id->ilist || CHECK_BLIST(bno))
2443
dbprintf("root directory %lld has .. %lld\n", id->ino,
2446
} else if (parent != NULLFSINO && id->ino != parent)
2447
addparent_inode(id, parent);
2459
if (dip->di_core.di_size <= XFS_DFORK_DSIZE_ARCH(dip, mp, ARCH_NOCONVERT) &&
2460
dip->di_core.di_format == XFS_DINODE_FMT_LOCAL)
2462
process_shortform_dir_v1(dip, dot, dotdot, id);
2463
else if (dip->di_core.di_size == XFS_LBSIZE(mp) &&
2464
(dip->di_core.di_format == XFS_DINODE_FMT_EXTENTS ||
2465
dip->di_core.di_format == XFS_DINODE_FMT_BTREE))
2466
*parent = process_leaf_dir_v1(blkmap, dot, dotdot, id);
2467
else if (dip->di_core.di_size >= XFS_LBSIZE(mp) &&
2468
(dip->di_core.di_format == XFS_DINODE_FMT_EXTENTS ||
2469
dip->di_core.di_format == XFS_DINODE_FMT_BTREE))
2470
*parent = process_node_dir_v1(blkmap, dot, dotdot, id);
2472
dbprintf("bad size (%lld) or format (%d) for directory inode "
2474
dip->di_core.di_size, (int)dip->di_core.di_format,
2491
xfs_fileoff_t last = 0;
2494
last = blkmap_last_off(blkmap);
2495
if (dip->di_core.di_size <= XFS_DFORK_DSIZE_ARCH(dip, mp, ARCH_NOCONVERT) &&
2496
dip->di_core.di_format == XFS_DINODE_FMT_LOCAL)
2497
*parent = process_sf_dir_v2(dip, dot, dotdot, id);
2498
else if (last == mp->m_dirblkfsbs &&
2499
(dip->di_core.di_format == XFS_DINODE_FMT_EXTENTS ||
2500
dip->di_core.di_format == XFS_DINODE_FMT_BTREE))
2501
*parent = process_block_dir_v2(blkmap, dot, dotdot, id);
2502
else if (last >= mp->m_dirleafblk + mp->m_dirblkfsbs &&
2503
(dip->di_core.di_format == XFS_DINODE_FMT_EXTENTS ||
2504
dip->di_core.di_format == XFS_DINODE_FMT_BTREE))
2505
*parent = process_leaf_node_dir_v2(blkmap, dot, dotdot, id,
2506
dip->di_core.di_size);
2508
dbprintf("bad size (%lld) or format (%d) for directory inode "
2510
dip->di_core.di_size, (int)dip->di_core.di_format,
2524
xfs_drfsbno_t *totd,
2525
xfs_drfsbno_t *toti,
2530
xfs_bmbt_rec_32_t *rp;
2532
rp = (xfs_bmbt_rec_32_t *)XFS_DFORK_PTR_ARCH(dip, whichfork, ARCH_NOCONVERT);
2533
*nex = XFS_DFORK_NEXTENTS_ARCH(dip, whichfork, ARCH_NOCONVERT);
2536
XFS_DFORK_SIZE_ARCH(dip, mp, whichfork, ARCH_NOCONVERT) / sizeof(xfs_bmbt_rec_32_t)) {
2537
if (!sflag || id->ilist)
2538
dbprintf("bad number of extents %d for inode %lld\n",
2543
process_bmbt_reclist(rp, *nex, type, id, totd, blkmapp);
2554
xfs_fsblock_t bno = 0;
2555
xfs_dinode_core_t tdic;
2556
xfs_dinode_core_t *dic;
2557
inodata_t *id = NULL;
2559
xfs_extnum_t nextents = 0;
2562
xfs_drfsbno_t totblocks;
2563
xfs_drfsbno_t totdblocks = 0;
2564
xfs_drfsbno_t totiblocks = 0;
2566
xfs_extnum_t anextents = 0;
2567
xfs_drfsbno_t atotdblocks = 0;
2568
xfs_drfsbno_t atotiblocks = 0;
2572
static char okfmts[] = {
2573
0, /* type 0 unused */
2574
1 << XFS_DINODE_FMT_DEV, /* FIFO */
2575
1 << XFS_DINODE_FMT_DEV, /* CHR */
2576
0, /* type 3 unused */
2577
(1 << XFS_DINODE_FMT_LOCAL) |
2578
(1 << XFS_DINODE_FMT_EXTENTS) |
2579
(1 << XFS_DINODE_FMT_BTREE), /* DIR */
2580
0, /* type 5 unused */
2581
1 << XFS_DINODE_FMT_DEV, /* BLK */
2582
0, /* type 7 unused */
2583
(1 << XFS_DINODE_FMT_EXTENTS) |
2584
(1 << XFS_DINODE_FMT_BTREE), /* REG */
2585
0, /* type 9 unused */
2586
(1 << XFS_DINODE_FMT_LOCAL) |
2587
(1 << XFS_DINODE_FMT_EXTENTS), /* LNK */
2588
0, /* type 11 unused */
2589
1 << XFS_DINODE_FMT_DEV, /* SOCK */
2590
0, /* type 13 unused */
2591
1 << XFS_DINODE_FMT_UUID, /* MNT */
2592
0 /* type 15 unused */
2594
static char *fmtnames[] = {
2595
"dev", "local", "extents", "btree", "uuid"
2598
/* convert the core, then copy it back into the inode */
2599
libxfs_xlate_dinode_core((xfs_caddr_t)&dip->di_core, &tdic, 1,
2601
memcpy(&dip->di_core, &tdic, sizeof(xfs_dinode_core_t));
2604
ino = XFS_AGINO_TO_INO(mp, INT_GET(agf->agf_seqno, ARCH_CONVERT), agino);
2606
id = find_inode(ino, 1);
2607
bno = XFS_INO_TO_FSB(mp, ino);
2610
if (dic->di_magic != XFS_DINODE_MAGIC) {
2611
if (!sflag || isfree || id->ilist || CHECK_BLIST(bno))
2612
dbprintf("bad magic number %#x for inode %lld\n",
2613
dic->di_magic, ino);
2617
if (!XFS_DINODE_GOOD_VERSION(dic->di_version)) {
2618
if (!sflag || isfree || id->ilist || CHECK_BLIST(bno))
2619
dbprintf("bad version number %#x for inode %lld\n",
2620
dic->di_version, ino);
2625
if (dic->di_nblocks != 0) {
2626
if (!sflag || id->ilist || CHECK_BLIST(bno))
2627
dbprintf("bad nblocks %lld for free inode "
2629
dic->di_nblocks, ino);
2632
if (dic->di_version == XFS_DINODE_VERSION_1)
2633
nlink = dic->di_onlink;
2635
nlink = dic->di_nlink;
2637
if (!sflag || id->ilist || CHECK_BLIST(bno))
2638
dbprintf("bad nlink %d for free inode %lld\n",
2642
if (dic->di_mode != 0) {
2643
if (!sflag || id->ilist || CHECK_BLIST(bno))
2644
dbprintf("bad mode %#o for free inode %lld\n",
2651
* di_mode is a 16-bit uint so no need to check the < 0 case
2653
if ((((dic->di_mode & IFMT) >> 12) > 15) ||
2654
(!(okfmts[(dic->di_mode & IFMT) >> 12] & (1 << dic->di_format)))) {
2655
if (!sflag || id->ilist || CHECK_BLIST(bno))
2656
dbprintf("bad format %d for inode %lld type %#o\n",
2657
dic->di_format, id->ino, dic->di_mode & IFMT);
2661
if ((unsigned int)XFS_DFORK_ASIZE_ARCH(dip, mp, ARCH_NOCONVERT) >= XFS_LITINO(mp)) {
2662
if (!sflag || id->ilist)
2663
dbprintf("bad fork offset %d for inode %lld\n",
2664
dic->di_forkoff, id->ino);
2668
if ((unsigned int)dic->di_aformat > XFS_DINODE_FMT_BTREE) {
2669
if (!sflag || id->ilist)
2670
dbprintf("bad attribute format %d for inode %lld\n",
2671
dic->di_aformat, id->ino);
2675
if (verbose || id->ilist || CHECK_BLIST(bno))
2676
dbprintf("inode %lld mode %#o fmt %s "
2678
"nex %d anex %d nblk %lld sz %lld%s%s\n",
2679
id->ino, dic->di_mode, fmtnames[dic->di_format],
2680
fmtnames[dic->di_aformat],
2683
dic->di_nblocks, dic->di_size,
2684
dic->di_flags & XFS_DIFLAG_REALTIME ? " rt" : "",
2685
dic->di_flags & XFS_DIFLAG_PREALLOC ? " pre" : ""
2688
switch (dic->di_mode & IFMT) {
2691
if (dic->di_format == XFS_DINODE_FMT_LOCAL)
2693
blkmap = blkmap_alloc(dic->di_nextents);
2696
if (dic->di_flags & XFS_DIFLAG_REALTIME)
2698
else if (id->ino == mp->m_sb.sb_rbmino) {
2699
type = DBM_RTBITMAP;
2700
blkmap = blkmap_alloc(dic->di_nextents);
2702
} else if (id->ino == mp->m_sb.sb_rsumino) {
2704
blkmap = blkmap_alloc(dic->di_nextents);
2707
else if (id->ino == mp->m_sb.sb_uquotino ||
2708
id->ino == mp->m_sb.sb_gquotino) {
2710
blkmap = blkmap_alloc(dic->di_nextents);
2715
if (dic->di_mode & (ISUID | ISGID))
2726
if (dic->di_version == XFS_DINODE_VERSION_1)
2727
setlink_inode(id, dic->di_onlink, type == DBM_DIR, security);
2729
sbversion |= XFS_SB_VERSION_NLINKBIT;
2730
setlink_inode(id, dic->di_nlink, type == DBM_DIR, security);
2732
switch (dic->di_format) {
2733
case XFS_DINODE_FMT_LOCAL:
2734
process_lclinode(id, dip, type, &totdblocks, &totiblocks,
2735
&nextents, &blkmap, XFS_DATA_FORK);
2737
case XFS_DINODE_FMT_EXTENTS:
2738
process_exinode(id, dip, type, &totdblocks, &totiblocks,
2739
&nextents, &blkmap, XFS_DATA_FORK);
2741
case XFS_DINODE_FMT_BTREE:
2742
process_btinode(id, dip, type, &totdblocks, &totiblocks,
2743
&nextents, &blkmap, XFS_DATA_FORK);
2746
if (XFS_DFORK_Q_ARCH(dip, ARCH_NOCONVERT)) {
2747
sbversion |= XFS_SB_VERSION_ATTRBIT;
2748
switch (dic->di_aformat) {
2749
case XFS_DINODE_FMT_LOCAL:
2750
process_lclinode(id, dip, DBM_ATTR, &atotdblocks,
2751
&atotiblocks, &anextents, NULL, XFS_ATTR_FORK);
2753
case XFS_DINODE_FMT_EXTENTS:
2754
process_exinode(id, dip, DBM_ATTR, &atotdblocks,
2755
&atotiblocks, &anextents, NULL, XFS_ATTR_FORK);
2757
case XFS_DINODE_FMT_BTREE:
2758
process_btinode(id, dip, DBM_ATTR, &atotdblocks,
2759
&atotiblocks, &anextents, NULL, XFS_ATTR_FORK);
2771
bc = totdblocks + totiblocks +
2772
atotdblocks + atotiblocks;
2776
bc = totiblocks + atotdblocks + atotiblocks;
2783
quota_add(dic->di_gid, dic->di_uid, 0, bc, ic, rc);
2785
totblocks = totdblocks + totiblocks + atotdblocks + atotiblocks;
2786
if (totblocks != dic->di_nblocks) {
2787
if (!sflag || id->ilist || CHECK_BLIST(bno))
2788
dbprintf("bad nblocks %lld for inode %lld, counted "
2790
dic->di_nblocks, id->ino, totblocks);
2793
if (nextents != dic->di_nextents) {
2794
if (!sflag || id->ilist || CHECK_BLIST(bno))
2795
dbprintf("bad nextents %d for inode %lld, counted %d\n",
2796
dic->di_nextents, id->ino, nextents);
2799
if (anextents != dic->di_anextents) {
2800
if (!sflag || id->ilist || CHECK_BLIST(bno))
2801
dbprintf("bad anextents %d for inode %lld, counted "
2803
dic->di_anextents, id->ino, anextents);
2806
if (type == DBM_DIR)
2807
process_dir(dip, blkmap, id);
2808
else if (type == DBM_RTBITMAP)
2809
process_rtbitmap(blkmap);
2810
else if (type == DBM_RTSUM)
2811
process_rtsummary(blkmap);
2813
* If the CHKD flag is not set, this can legitimately contain garbage;
2814
* xfs_repair may have cleared that bit.
2816
else if (type == DBM_QUOTA) {
2817
if (id->ino == mp->m_sb.sb_uquotino &&
2818
(mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) &&
2819
(mp->m_sb.sb_qflags & XFS_UQUOTA_CHKD))
2820
process_quota(0, id, blkmap);
2821
else if (id->ino == mp->m_sb.sb_gquotino &&
2822
(mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) &&
2823
(mp->m_sb.sb_qflags & XFS_GQUOTA_CHKD))
2824
process_quota(1, id, blkmap);
2827
blkmap_free(blkmap);
2836
xfs_drfsbno_t *totd,
2837
xfs_drfsbno_t *toti,
2842
xfs_attr_shortform_t *asf;
2844
xfs_dinode_core_t *dic;
2846
dic = &dip->di_core;
2847
bno = XFS_INO_TO_FSB(mp, id->ino);
2848
if (whichfork == XFS_DATA_FORK &&
2849
dic->di_size > XFS_DFORK_DSIZE_ARCH(dip, mp, ARCH_NOCONVERT)) {
2850
if (!sflag || id->ilist || CHECK_BLIST(bno))
2851
dbprintf("local inode %lld data is too large (size "
2853
id->ino, dic->di_size);
2856
else if (whichfork == XFS_ATTR_FORK) {
2857
asf = (xfs_attr_shortform_t *)XFS_DFORK_PTR_ARCH(dip, whichfork, ARCH_NOCONVERT);
2858
if (INT_GET(asf->hdr.totsize, ARCH_CONVERT) > XFS_DFORK_ASIZE_ARCH(dip, mp, ARCH_NOCONVERT)) {
2859
if (!sflag || id->ilist || CHECK_BLIST(bno))
2860
dbprintf("local inode %lld attr is too large "
2862
id->ino, INT_GET(asf->hdr.totsize, ARCH_CONVERT));
2869
process_leaf_dir_v1(
2878
bno = blkmap_get(blkmap, 0);
2879
if (bno == NULLFSBLOCK) {
2880
if (!sflag || id->ilist)
2881
dbprintf("block 0 for directory inode %lld is "
2888
set_cur(&typtab[TYP_DIR], XFS_FSB_TO_DADDR(mp, bno), blkbb, DB_RING_IGN,
2890
if (iocur_top->data == NULL) {
2891
if (!sflag || id->ilist || CHECK_BLIST(bno))
2892
dbprintf("can't read block 0 for directory inode "
2898
parent = process_leaf_dir_v1_int(dot, dotdot, id);
2904
process_leaf_dir_v1_int(
2911
xfs_dir_leaf_entry_t *entry;
2913
xfs_dir_leafblock_t *leaf;
2915
xfs_dir_leaf_name_t *namest;
2916
xfs_ino_t parent = 0;
2919
bno = XFS_DADDR_TO_FSB(mp, iocur_top->bb);
2920
v = verbose || id->ilist || CHECK_BLIST(bno);
2921
leaf = iocur_top->data;
2922
if (INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) != XFS_DIR_LEAF_MAGIC) {
2923
if (!sflag || id->ilist || CHECK_BLIST(bno))
2924
dbprintf("bad directory leaf magic # %#x for dir ino "
2926
INT_GET(leaf->hdr.info.magic, ARCH_CONVERT), id->ino);
2930
entry = &leaf->entries[0];
2931
for (i = 0; i < INT_GET(leaf->hdr.count, ARCH_CONVERT); entry++, i++) {
2932
namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT));
2933
lino=DIRINO_GET_ARCH(&namest->inumber, ARCH_CONVERT);
2934
cid = find_inode(lino, 1);
2936
dbprintf("dir %lld entry %*.*s %lld\n", id->ino,
2937
entry->namelen, entry->namelen, namest->name,
2943
dbprintf("dir %lld entry %*.*s bad inode "
2945
id->ino, entry->namelen, entry->namelen,
2946
namest->name, lino);
2949
if (entry->namelen == 2 && namest->name[0] == '.' &&
2950
namest->name[1] == '.') {
2952
if (!sflag || id->ilist || CHECK_BLIST(bno))
2953
dbprintf("multiple .. entries in dir "
2954
"%lld (%lld, %lld)\n",
2955
id->ino, parent, lino);
2958
parent = cid ? lino : NULLFSINO;
2960
} else if (entry->namelen != 1 || namest->name[0] != '.') {
2964
addname_inode(cid, (char *)namest->name,
2968
if (lino != id->ino) {
2970
dbprintf("dir %lld entry . inode "
2971
"number mismatch (%lld)\n",
2982
process_leaf_node_dir_v2(
2987
xfs_fsize_t dirsize)
3003
v2 = verbose || id->ilist;
3006
freetab = malloc(FREETAB_SIZE(dirsize / mp->m_dirblksize));
3007
freetab->naents = (int)(dirsize / mp->m_dirblksize);
3009
for (i = 0; i < freetab->naents; i++)
3010
freetab->ents[i] = NULLDATAOFF;
3012
while ((dbno = blkmap_next_off(blkmap, dbno, &t)) != NULLFILEOFF) {
3013
nex = blkmap_getn(blkmap, dbno, mp->m_dirblkfsbs, &bmp);
3015
for (v = v2, x = 0; !v && x < nex; x++) {
3016
for (b = bmp[x].startblock;
3017
!v && b < bmp[x].startblock + bmp[x].blockcount;
3022
dbprintf("dir inode %lld block %u=%llu\n", id->ino,
3024
(xfs_dfsbno_t)bmp->startblock);
3027
make_bbmap(&bbmap, nex, bmp);
3028
set_cur(&typtab[TYP_DIR], XFS_FSB_TO_DADDR(mp, bmp->startblock),
3029
mp->m_dirblkfsbs * blkbb, DB_RING_IGN,
3030
nex > 1 ? &bbmap : NULL);
3032
if (iocur_top->data == NULL) {
3034
dbprintf("can't read block %u for directory "
3036
(__uint32_t)dbno, id->ino);
3039
dbno += mp->m_dirblkfsbs - 1;
3042
if (dbno < mp->m_dirleafblk) {
3043
lino = process_data_dir_v2(dot, dotdot, id, v,
3044
(xfs_dablk_t)dbno, &freetab);
3048
dbprintf("multiple .. entries "
3055
} else if (dbno < mp->m_dirfreeblk) {
3056
process_leaf_node_dir_v2_int(id, v, (xfs_dablk_t)dbno,
3059
process_leaf_node_dir_v2_free(id, v, (xfs_dablk_t)dbno,
3063
dbno += mp->m_dirblkfsbs - 1;
3065
dir_hash_check(id, v);
3067
for (i = 0; i < freetab->nents; i++) {
3068
if (freetab->ents[i] != NULLDATAOFF) {
3070
dbprintf("missing free index for data block %d "
3071
"in dir ino %lld\n",
3072
XFS_DIR2_DB_TO_DA(mp, i), id->ino);
3081
process_leaf_node_dir_v2_free(
3087
xfs_dir2_data_off_t ent;
3088
xfs_dir2_free_t *free;
3093
free = iocur_top->data;
3094
if (INT_GET(free->hdr.magic, ARCH_CONVERT) != XFS_DIR2_FREE_MAGIC) {
3096
dbprintf("bad free block magic # %#x for dir ino %lld "
3098
INT_GET(free->hdr.magic, ARCH_CONVERT), id->ino, dabno);
3102
maxent = XFS_DIR2_MAX_FREE_BESTS(mp);
3103
if (INT_GET(free->hdr.firstdb, ARCH_CONVERT) !=
3104
XFS_DIR2_DA_TO_DB(mp, dabno - mp->m_dirfreeblk) * maxent) {
3106
dbprintf("bad free block firstdb %d for dir ino %lld "
3108
INT_GET(free->hdr.firstdb, ARCH_CONVERT), id->ino, dabno);
3112
if (INT_GET(free->hdr.nvalid, ARCH_CONVERT) > maxent || INT_GET(free->hdr.nvalid, ARCH_CONVERT) < 0 ||
3113
INT_GET(free->hdr.nused, ARCH_CONVERT) > maxent || INT_GET(free->hdr.nused, ARCH_CONVERT) < 0 ||
3114
INT_GET(free->hdr.nused, ARCH_CONVERT) > INT_GET(free->hdr.nvalid, ARCH_CONVERT)) {
3116
dbprintf("bad free block nvalid/nused %d/%d for dir "
3117
"ino %lld block %d\n",
3118
INT_GET(free->hdr.nvalid, ARCH_CONVERT), INT_GET(free->hdr.nused, ARCH_CONVERT), id->ino,
3123
for (used = i = 0; i < INT_GET(free->hdr.nvalid, ARCH_CONVERT); i++) {
3124
if (freetab->nents <= INT_GET(free->hdr.firstdb, ARCH_CONVERT) + i)
3127
ent = freetab->ents[INT_GET(free->hdr.firstdb, ARCH_CONVERT) + i];
3128
if (ent != INT_GET(free->bests[i], ARCH_CONVERT)) {
3130
dbprintf("bad free block ent %d is %d should "
3131
"be %d for dir ino %lld block %d\n",
3132
i, INT_GET(free->bests[i], ARCH_CONVERT), ent, id->ino, dabno);
3135
if (INT_GET(free->bests[i], ARCH_CONVERT) != NULLDATAOFF)
3137
if (ent != NULLDATAOFF)
3138
freetab->ents[INT_GET(free->hdr.firstdb, ARCH_CONVERT) + i] = NULLDATAOFF;
3140
if (used != INT_GET(free->hdr.nused, ARCH_CONVERT)) {
3142
dbprintf("bad free block nused %d should be %d for dir "
3143
"ino %lld block %d\n",
3144
INT_GET(free->hdr.nused, ARCH_CONVERT), used, id->ino, dabno);
3150
process_leaf_node_dir_v2_int(
3157
xfs_dir2_data_off_t *lbp;
3158
xfs_dir2_leaf_t *leaf;
3159
xfs_dir2_leaf_entry_t *lep;
3160
xfs_dir2_leaf_tail_t *ltp;
3161
xfs_da_intnode_t *node;
3164
leaf = iocur_top->data;
3165
switch (INT_GET(leaf->hdr.info.magic, ARCH_CONVERT)) {
3166
case XFS_DIR2_LEAF1_MAGIC:
3167
if (INT_GET(leaf->hdr.info.forw, ARCH_CONVERT) || INT_GET(leaf->hdr.info.back, ARCH_CONVERT)) {
3169
dbprintf("bad leaf block forw/back pointers "
3170
"%d/%d for dir ino %lld block %d\n",
3171
INT_GET(leaf->hdr.info.forw, ARCH_CONVERT),
3172
INT_GET(leaf->hdr.info.back, ARCH_CONVERT), id->ino, dabno);
3175
if (dabno != mp->m_dirleafblk) {
3177
dbprintf("single leaf block for dir ino %lld "
3178
"block %d should be at block %d\n",
3180
(xfs_dablk_t)mp->m_dirleafblk);
3183
ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
3184
lbp = XFS_DIR2_LEAF_BESTS_P_ARCH(ltp, ARCH_CONVERT);
3185
for (i = 0; i < INT_GET(ltp->bestcount, ARCH_CONVERT); i++) {
3186
if (freetab->nents <= i || freetab->ents[i] != INT_GET(lbp[i], ARCH_CONVERT)) {
3188
dbprintf("bestfree %d for dir ino %lld "
3189
"block %d doesn't match table "
3191
freetab->nents <= i ?
3195
XFS_DIR2_DB_TO_DA(mp, i),
3196
INT_GET(lbp[i], ARCH_CONVERT));
3198
if (freetab->nents > i)
3199
freetab->ents[i] = NULLDATAOFF;
3202
case XFS_DIR2_LEAFN_MAGIC:
3203
/* if it's at the root location then we can check the
3204
* pointers are null XXX */
3206
case XFS_DA_NODE_MAGIC:
3207
node = iocur_top->data;
3208
if (INT_GET(node->hdr.level, ARCH_CONVERT) < 1 ||
3209
INT_GET(node->hdr.level, ARCH_CONVERT) > XFS_DA_NODE_MAXDEPTH) {
3211
dbprintf("bad node block level %d for dir ino "
3213
INT_GET(node->hdr.level, ARCH_CONVERT), id->ino, dabno);
3219
dbprintf("bad directory data magic # %#x for dir ino "
3221
INT_GET(leaf->hdr.info.magic, ARCH_CONVERT), id->ino, dabno);
3226
for (i = stale = 0; i < INT_GET(leaf->hdr.count, ARCH_CONVERT); i++) {
3227
if (INT_GET(lep[i].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR)
3229
else if (dir_hash_see(INT_GET(lep[i].hashval, ARCH_CONVERT), INT_GET(lep[i].address, ARCH_CONVERT))) {
3231
dbprintf("dir %lld block %d extra leaf entry "
3233
id->ino, dabno, INT_GET(lep[i].hashval, ARCH_CONVERT),
3234
INT_GET(lep[i].address, ARCH_CONVERT));
3238
if (stale != INT_GET(leaf->hdr.stale, ARCH_CONVERT)) {
3240
dbprintf("dir %lld block %d stale mismatch "
3242
id->ino, dabno, stale,
3243
INT_GET(leaf->hdr.stale, ARCH_CONVERT));
3249
process_node_dir_v1(
3258
xfs_da_intnode_t *node;
3264
v = verbose || id->ilist;
3267
while ((dbno = blkmap_next_off(blkmap, dbno, &t)) != NULLFILEOFF) {
3268
bno = blkmap_get(blkmap, dbno);
3269
v2 = bno != NULLFSBLOCK && CHECK_BLIST(bno);
3270
if (bno == NULLFSBLOCK && dbno == 0) {
3272
dbprintf("can't read root block for directory "
3278
dbprintf("dir inode %lld block %u=%llu\n", id->ino,
3279
(__uint32_t)dbno, (xfs_dfsbno_t)bno);
3280
if (bno == NULLFSBLOCK)
3283
set_cur(&typtab[TYP_DIR], XFS_FSB_TO_DADDR(mp, bno), blkbb,
3285
if ((node = iocur_top->data) == NULL) {
3286
if (!sflag || v || v2)
3287
dbprintf("can't read block %u for directory "
3289
(__uint32_t)dbno, id->ino);
3294
if (INT_GET(node->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC)
3296
if (INT_GET(node->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_NODE_MAGIC)
3302
lino = process_leaf_dir_v1_int(dot, dotdot, id);
3305
if (!sflag || v || v2)
3306
dbprintf("multiple .. entries in dir "
3336
perblock = (int)(mp->m_sb.sb_blocksize / sizeof(*dqb));
3337
s = isgrp ? "group" : "user";
3338
exp_flags = isgrp ? XFS_DQ_GROUP : XFS_DQ_USER;
3341
while ((qbno = blkmap_next_off(blkmap, qbno, &t)) !=
3343
bno = blkmap_get(blkmap, qbno);
3344
dqid = (xfs_dqid_t)qbno * perblock;
3345
cb = CHECK_BLIST(bno);
3346
scicb = !sflag || id->ilist || cb;
3348
set_cur(&typtab[TYP_DQBLK], XFS_FSB_TO_DADDR(mp, bno), blkbb,
3350
if ((dqb = iocur_top->data) == NULL) {
3353
dbprintf("can't read block %lld for %s quota "
3354
"inode (fsblock %lld)\n",
3355
(xfs_dfiloff_t)qbno, s,
3360
for (i = 0; i < perblock; i++, dqid++, dqb++) {
3361
if (verbose || id->ilist || cb)
3362
dbprintf("%s dqblk %lld entry %d id %d bc "
3363
"%lld ic %lld rc %lld\n",
3364
s, (xfs_dfiloff_t)qbno, i, dqid,
3365
INT_GET(dqb->dd_diskdq.d_bcount, ARCH_CONVERT),
3366
INT_GET(dqb->dd_diskdq.d_icount, ARCH_CONVERT),
3367
INT_GET(dqb->dd_diskdq.d_rtbcount, ARCH_CONVERT));
3368
if (INT_GET(dqb->dd_diskdq.d_magic, ARCH_CONVERT) != XFS_DQUOT_MAGIC) {
3370
dbprintf("bad magic number %#x for %s "
3371
"dqblk %lld entry %d id %d\n",
3372
INT_GET(dqb->dd_diskdq.d_magic, ARCH_CONVERT), s,
3373
(xfs_dfiloff_t)qbno, i, dqid);
3377
if (INT_GET(dqb->dd_diskdq.d_version, ARCH_CONVERT) != XFS_DQUOT_VERSION) {
3379
dbprintf("bad version number %#x for "
3380
"%s dqblk %lld entry %d id "
3382
INT_GET(dqb->dd_diskdq.d_version, ARCH_CONVERT), s,
3383
(xfs_dfiloff_t)qbno, i, dqid);
3387
if (INT_GET(dqb->dd_diskdq.d_flags, ARCH_CONVERT) != exp_flags) {
3389
dbprintf("bad flags %#x for %s dqblk "
3390
"%lld entry %d id %d\n",
3391
INT_GET(dqb->dd_diskdq.d_flags, ARCH_CONVERT), s,
3392
(xfs_dfiloff_t)qbno, i, dqid);
3396
if (INT_GET(dqb->dd_diskdq.d_id, ARCH_CONVERT) != dqid) {
3398
dbprintf("bad id %d for %s dqblk %lld "
3400
INT_GET(dqb->dd_diskdq.d_id, ARCH_CONVERT), s,
3401
(xfs_dfiloff_t)qbno, i, dqid);
3405
quota_add(isgrp ? dqid : -1, isgrp ? -1 : dqid, 1,
3406
INT_GET(dqb->dd_diskdq.d_bcount, ARCH_CONVERT),
3407
INT_GET(dqb->dd_diskdq.d_icount, ARCH_CONVERT),
3408
INT_GET(dqb->dd_diskdq.d_rtbcount, ARCH_CONVERT));
3418
#define xfs_highbit64 libxfs_highbit64 /* for XFS_RTBLOCKLOG macro */
3421
xfs_fileoff_t bmbno;
3428
xfs_drfsbno_t rtbno;
3432
xfs_rtword_t *words;
3434
bitsperblock = mp->m_sb.sb_blocksize * NBBY;
3435
bit = extno = prevbit = start_bmbno = start_bit = 0;
3436
bmbno = NULLFILEOFF;
3437
while ((bmbno = blkmap_next_off(blkmap, bmbno, &t)) !=
3439
bno = blkmap_get(blkmap, bmbno);
3440
if (bno == NULLFSBLOCK) {
3442
dbprintf("block %lld for rtbitmap inode is "
3444
(xfs_dfiloff_t)bmbno);
3449
set_cur(&typtab[TYP_RTBITMAP], XFS_FSB_TO_DADDR(mp, bno), blkbb,
3451
if ((words = iocur_top->data) == NULL) {
3454
dbprintf("can't read block %lld for rtbitmap "
3456
(xfs_dfiloff_t)bmbno);
3461
bit < bitsperblock && extno < mp->m_sb.sb_rextents;
3463
if (isset(words, bit)) {
3464
rtbno = extno * mp->m_sb.sb_rextsize;
3465
set_rdbmap(rtbno, mp->m_sb.sb_rextsize,
3469
start_bmbno = (int)bmbno;
3473
} else if (prevbit == 1) {
3474
len = ((int)bmbno - start_bmbno) *
3475
bitsperblock + (bit - start_bit);
3476
log = XFS_RTBLOCKLOG(len);
3477
offs = XFS_SUMOFFS(mp, log, start_bmbno);
3483
if (extno == mp->m_sb.sb_rextents)
3487
len = ((int)bmbno - start_bmbno) * bitsperblock +
3489
log = XFS_RTBLOCKLOG(len);
3490
offs = XFS_SUMOFFS(mp, log, start_bmbno);
3501
xfs_fileoff_t sumbno;
3504
sumbno = NULLFILEOFF;
3505
while ((sumbno = blkmap_next_off(blkmap, sumbno, &t)) !=
3507
bno = blkmap_get(blkmap, sumbno);
3508
if (bno == NULLFSBLOCK) {
3510
dbprintf("block %lld for rtsummary inode is "
3512
(xfs_dfiloff_t)sumbno);
3517
set_cur(&typtab[TYP_RTSUMMARY], XFS_FSB_TO_DADDR(mp, bno),
3518
blkbb, DB_RING_IGN, NULL);
3519
if ((bytes = iocur_top->data) == NULL) {
3521
dbprintf("can't read block %lld for rtsummary "
3523
(xfs_dfiloff_t)sumbno);
3527
memcpy((char *)sumfile + sumbno * mp->m_sb.sb_blocksize, bytes,
3528
mp->m_sb.sb_blocksize);
3546
xfs_dir2_sf_entry_t *sfe;
3549
sf = &dip->di_u.di_dir2sf;
3551
v = verbose || id->ilist;
3553
dbprintf("dir %lld entry . %lld\n", id->ino, id->ino);
3555
sfe = XFS_DIR2_SF_FIRSTENTRY(sf);
3556
offset = XFS_DIR2_DATA_FIRST_OFFSET;
3557
for (i = INT_GET(sf->hdr.count, ARCH_CONVERT) - 1, i8 = 0; i >= 0; i--) {
3558
if ((__psint_t)sfe + XFS_DIR2_SF_ENTSIZE_BYENTRY(sf, sfe) -
3559
(__psint_t)sf > dip->di_core.di_size) {
3561
dbprintf("dir %llu bad size in entry at %d\n",
3563
(int)((char *)sfe - (char *)sf));
3567
lino = XFS_DIR2_SF_GET_INUMBER_ARCH(sf, XFS_DIR2_SF_INUMBERP(sfe), ARCH_CONVERT);
3568
if (lino > XFS_DIR2_MAX_SHORT_INUM)
3570
cid = find_inode(lino, 1);
3573
dbprintf("dir %lld entry %*.*s bad inode "
3575
id->ino, sfe->namelen, sfe->namelen,
3582
addname_inode(cid, (char *)sfe->name, sfe->namelen);
3585
dbprintf("dir %lld entry %*.*s offset %d %lld\n",
3586
id->ino, sfe->namelen, sfe->namelen, sfe->name,
3587
XFS_DIR2_SF_GET_OFFSET_ARCH(sfe, ARCH_CONVERT), lino);
3588
if (XFS_DIR2_SF_GET_OFFSET_ARCH(sfe, ARCH_CONVERT) < offset) {
3590
dbprintf("dir %lld entry %*.*s bad offset %d\n",
3591
id->ino, sfe->namelen, sfe->namelen,
3592
sfe->name, XFS_DIR2_SF_GET_OFFSET_ARCH(sfe, ARCH_CONVERT));
3596
XFS_DIR2_SF_GET_OFFSET_ARCH(sfe, ARCH_CONVERT) +
3597
XFS_DIR2_DATA_ENTSIZE(sfe->namelen);
3598
sfe = XFS_DIR2_SF_NEXTENTRY(sf, sfe);
3600
if (i < 0 && (__psint_t)sfe - (__psint_t)sf != dip->di_core.di_size) {
3602
dbprintf("dir %llu size is %lld, should be %u\n",
3603
id->ino, dip->di_core.di_size,
3604
(uint)((char *)sfe - (char *)sf));
3607
if (offset + (INT_GET(sf->hdr.count, ARCH_CONVERT) + 2) * sizeof(xfs_dir2_leaf_entry_t) +
3608
sizeof(xfs_dir2_block_tail_t) > mp->m_dirblksize) {
3610
dbprintf("dir %llu offsets too high\n", id->ino);
3613
lino = XFS_DIR2_SF_GET_INUMBER_ARCH(sf, &sf->hdr.parent, ARCH_CONVERT);
3614
if (lino > XFS_DIR2_MAX_SHORT_INUM)
3616
cid = find_inode(lino, 1);
3621
dbprintf("dir %lld entry .. bad inode number %lld\n",
3626
dbprintf("dir %lld entry .. %lld\n", id->ino, lino);
3627
if (i8 != sf->hdr.i8count) {
3629
dbprintf("dir %lld i8count mismatch is %d should be "
3631
id->ino, sf->hdr.i8count, i8);
3635
return cid ? lino : NULLFSINO;
3639
process_shortform_dir_v1(
3648
xfs_dir_shortform_t *sf;
3649
xfs_dir_sf_entry_t *sfe;
3652
sf = &dip->di_u.di_dirsf;
3654
v = verbose || id->ilist;
3656
dbprintf("dir %lld entry . %lld\n", id->ino, id->ino);
3659
for (i = INT_GET(sf->hdr.count, ARCH_CONVERT) - 1; i >= 0; i--) {
3660
lino = DIRINO_GET_ARCH(&sfe->inumber, ARCH_CONVERT);
3661
cid = find_inode(lino, 1);
3664
dbprintf("dir %lld entry %*.*s bad inode "
3666
id->ino, sfe->namelen, sfe->namelen,
3673
addname_inode(cid, (char *)sfe->name, sfe->namelen);
3676
dbprintf("dir %lld entry %*.*s %lld\n", id->ino,
3677
sfe->namelen, sfe->namelen, sfe->name, lino);
3678
sfe = XFS_DIR_SF_NEXTENTRY(sfe);
3680
if ((__psint_t)sfe - (__psint_t)sf != dip->di_core.di_size)
3681
dbprintf("dir %llu size is %lld, should be %d\n",
3682
id->ino, dip->di_core.di_size,
3683
(int)((char *)sfe - (char *)sf));
3684
lino=DIRINO_GET_ARCH(&sf->hdr.parent, ARCH_CONVERT);
3685
cid = find_inode(lino, 1);
3690
dbprintf("dir %lld entry .. bad inode number %lld\n",
3695
dbprintf("dir %lld entry .. %lld\n", id->ino, lino);
3697
return cid ? lino : NULLFSINO;
3709
if (qudo && usrid != -1)
3710
quota_add1(qudata, usrid, dq, bc, ic, rc);
3711
if (qgdo && grpid != -1)
3712
quota_add1(qgdata, grpid, dq, bc, ic, rc);
3728
qh = (int)((__uint32_t)id % QDATA_HASH_SIZE);
3732
qi = dq ? &qe->dq : &qe->count;
3740
qe = xmalloc(sizeof(*qe));
3742
qi = dq ? &qe->dq : &qe->count;
3746
qi = dq ? &qe->count : &qe->dq;
3747
qi->bc = qi->ic = qi->rc = 0;
3761
for (i = 0; i < QDATA_HASH_SIZE; i++) {
3765
if (qp->count.bc != qp->dq.bc ||
3766
qp->count.ic != qp->dq.ic ||
3767
qp->count.rc != qp->dq.rc) {
3769
dbprintf("%s quota id %d, have/exp",
3771
if (qp->count.bc != qp->dq.bc)
3772
dbprintf(" bc %lld/%lld",
3775
if (qp->count.ic != qp->dq.ic)
3776
dbprintf(" ic %lld/%lld",
3779
if (qp->count.rc != qp->dq.rc)
3780
dbprintf(" rc %lld/%lld",
3797
qudo = mp->m_sb.sb_uquotino != 0 &&
3798
mp->m_sb.sb_uquotino != NULLFSINO &&
3799
(mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) &&
3800
(mp->m_sb.sb_qflags & XFS_UQUOTA_CHKD);
3801
qgdo = mp->m_sb.sb_gquotino != 0 &&
3802
mp->m_sb.sb_gquotino != NULLFSINO &&
3803
(mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) &&
3804
(mp->m_sb.sb_qflags & XFS_GQUOTA_CHKD);
3806
qudata = xcalloc(QDATA_HASH_SIZE, sizeof(qdata_t *));
3808
qgdata = xcalloc(QDATA_HASH_SIZE, sizeof(qdata_t *));
3813
xfs_agnumber_t agno)
3821
agffreeblks = agflongest = 0;
3822
agicount = agifreecount = 0;
3824
set_cur(&typtab[TYP_SB], XFS_AG_DADDR(mp, agno, XFS_SB_DADDR), 1,
3827
if (!iocur_top->data) {
3828
dbprintf("can't read superblock for ag %u\n", agno);
3834
libxfs_xlate_sb(iocur_top->data, sb, 1, ARCH_CONVERT, XFS_SB_ALL_BITS);
3836
if (sb->sb_magicnum != XFS_SB_MAGIC) {
3838
dbprintf("bad sb magic # %#x in ag %u\n",
3839
sb->sb_magicnum, agno);
3842
if (!XFS_SB_GOOD_VERSION(sb)) {
3844
dbprintf("bad sb version # %#x in ag %u\n",
3845
sb->sb_versionnum, agno);
3849
if (agno == 0 && sb->sb_inprogress != 0) {
3851
dbprintf("mkfs not completed successfully\n");
3854
set_dbmap(agno, XFS_SB_BLOCK(mp), 1, DBM_SB, agno, XFS_SB_BLOCK(mp));
3855
if (sb->sb_logstart && XFS_FSB_TO_AGNO(mp, sb->sb_logstart) == agno)
3856
set_dbmap(agno, XFS_FSB_TO_AGBNO(mp, sb->sb_logstart),
3857
sb->sb_logblocks, DBM_LOG, agno, XFS_SB_BLOCK(mp));
3859
set_cur(&typtab[TYP_AGF], XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR), 1,
3861
if ((agf = iocur_top->data) == NULL) {
3862
dbprintf("can't read agf block for ag %u\n", agno);
3868
if (INT_GET(agf->agf_magicnum, ARCH_CONVERT) != XFS_AGF_MAGIC) {
3870
dbprintf("bad agf magic # %#x in ag %u\n",
3871
INT_GET(agf->agf_magicnum, ARCH_CONVERT), agno);
3874
if (!XFS_AGF_GOOD_VERSION(INT_GET(agf->agf_versionnum, ARCH_CONVERT))) {
3876
dbprintf("bad agf version # %#x in ag %u\n",
3877
INT_GET(agf->agf_versionnum, ARCH_CONVERT), agno);
3880
if (XFS_SB_BLOCK(mp) != XFS_AGF_BLOCK(mp))
3881
set_dbmap(agno, XFS_AGF_BLOCK(mp), 1, DBM_AGF, agno,
3883
if (sb->sb_agblocks > INT_GET(agf->agf_length, ARCH_CONVERT))
3884
set_dbmap(agno, INT_GET(agf->agf_length, ARCH_CONVERT),
3885
sb->sb_agblocks - INT_GET(agf->agf_length, ARCH_CONVERT),
3886
DBM_MISSING, agno, XFS_SB_BLOCK(mp));
3888
set_cur(&typtab[TYP_AGI], XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR), 1,
3890
if ((agi = iocur_top->data) == NULL) {
3891
dbprintf("can't read agi block for ag %u\n", agno);
3898
if (INT_GET(agi->agi_magicnum, ARCH_CONVERT) != XFS_AGI_MAGIC) {
3900
dbprintf("bad agi magic # %#x in ag %u\n",
3901
INT_GET(agi->agi_magicnum, ARCH_CONVERT), agno);
3904
if (!XFS_AGI_GOOD_VERSION(INT_GET(agi->agi_versionnum, ARCH_CONVERT))) {
3906
dbprintf("bad agi version # %#x in ag %u\n",
3907
INT_GET(agi->agi_versionnum, ARCH_CONVERT), agno);
3910
if (XFS_SB_BLOCK(mp) != XFS_AGI_BLOCK(mp) &&
3911
XFS_AGF_BLOCK(mp) != XFS_AGI_BLOCK(mp))
3912
set_dbmap(agno, XFS_AGI_BLOCK(mp), 1, DBM_AGI, agno,
3917
INT_GET(agf->agf_roots[XFS_BTNUM_BNO], ARCH_CONVERT),
3918
INT_GET(agf->agf_levels[XFS_BTNUM_BNO], ARCH_CONVERT),
3919
1, scanfunc_bno, TYP_BNOBT);
3922
INT_GET(agf->agf_roots[XFS_BTNUM_CNT], ARCH_CONVERT),
3923
INT_GET(agf->agf_levels[XFS_BTNUM_CNT], ARCH_CONVERT),
3924
1, scanfunc_cnt, TYP_CNTBT);
3926
INT_GET(agi->agi_root, ARCH_CONVERT),
3927
INT_GET(agi->agi_level, ARCH_CONVERT),
3928
1, scanfunc_ino, TYP_INOBT);
3929
if (INT_GET(agf->agf_freeblks, ARCH_CONVERT) != agffreeblks) {
3931
dbprintf("agf_freeblks %u, counted %u in ag %u\n",
3932
INT_GET(agf->agf_freeblks, ARCH_CONVERT),
3936
if (INT_GET(agf->agf_longest, ARCH_CONVERT) != agflongest) {
3938
dbprintf("agf_longest %u, counted %u in ag %u\n",
3939
INT_GET(agf->agf_longest, ARCH_CONVERT),
3943
if (INT_GET(agi->agi_count, ARCH_CONVERT) != agicount) {
3945
dbprintf("agi_count %u, counted %u in ag %u\n",
3946
INT_GET(agi->agi_count, ARCH_CONVERT),
3950
if (INT_GET(agi->agi_freecount, ARCH_CONVERT) != agifreecount) {
3952
dbprintf("agi_freecount %u, counted %u in ag %u\n",
3953
INT_GET(agi->agi_freecount, ARCH_CONVERT),
3954
agifreecount, agno);
3957
for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++) {
3958
if (INT_GET(agi->agi_unlinked[i], ARCH_CONVERT) != NULLAGINO) {
3960
xfs_agino_t agino=INT_GET(agi->agi_unlinked[i], ARCH_CONVERT);
3961
dbprintf("agi unlinked bucket %d is %u in ag "
3962
"%u (inode=%lld)\n", i, agino, agno,
3963
XFS_AGINO_TO_INO(mp, agno, agino));
3977
xfs_agnumber_t seqno = INT_GET(agf->agf_seqno, ARCH_CONVERT);
3983
if (XFS_SB_BLOCK(mp) != XFS_AGFL_BLOCK(mp) &&
3984
XFS_AGF_BLOCK(mp) != XFS_AGFL_BLOCK(mp) &&
3985
XFS_AGI_BLOCK(mp) != XFS_AGFL_BLOCK(mp))
3986
set_dbmap(seqno, XFS_AGFL_BLOCK(mp), 1, DBM_AGFL, seqno,
3988
if (INT_GET(agf->agf_flcount, ARCH_CONVERT) == 0)
3991
set_cur(&typtab[TYP_AGFL],
3992
XFS_AG_DADDR(mp, seqno, XFS_AGFL_DADDR), 1, DB_RING_IGN, NULL);
3993
if ((agfl = iocur_top->data) == NULL) {
3994
dbprintf("can't read agfl block for ag %u\n", seqno);
3998
i = INT_GET(agf->agf_flfirst, ARCH_CONVERT);
4001
bno = INT_GET(agfl->agfl_bno[i], ARCH_CONVERT);
4002
set_dbmap(seqno, bno, 1, DBM_FREELIST, seqno,
4003
XFS_AGFL_BLOCK(mp));
4005
if (i == INT_GET(agf->agf_fllast, ARCH_CONVERT))
4007
if (++i == XFS_AGFL_SIZE)
4010
if (count != INT_GET(agf->agf_flcount, ARCH_CONVERT)) {
4012
dbprintf("freeblk count %u != flcount %u in ag %u\n",
4013
count, INT_GET(agf->agf_flcount, ARCH_CONVERT),
4025
scan_lbtree_f_t func,
4028
xfs_drfsbno_t *totd,
4029
xfs_drfsbno_t *toti,
4036
set_cur(&typtab[btype], XFS_FSB_TO_DADDR(mp, root), blkbb, DB_RING_IGN,
4038
if (iocur_top->data == NULL) {
4040
dbprintf("can't read btree block %u/%u\n",
4041
XFS_FSB_TO_AGNO(mp, root),
4042
XFS_FSB_TO_AGBNO(mp, root));
4046
(*func)(iocur_top->data, nlevels - 1, type, root, id, totd, toti, nex,
4047
blkmapp, isroot, btype);
4057
scan_sbtree_f_t func,
4060
xfs_agnumber_t seqno = INT_GET(agf->agf_seqno, ARCH_CONVERT);
4063
set_cur(&typtab[btype],
4064
XFS_AGB_TO_DADDR(mp, seqno, root), blkbb, DB_RING_IGN, NULL);
4065
if (iocur_top->data == NULL) {
4067
dbprintf("can't read btree block %u/%u\n", seqno, root);
4071
(*func)(iocur_top->data, nlevels - 1, agf, root, isroot);
4077
xfs_btree_lblock_t *ablock,
4082
xfs_drfsbno_t *totd,
4083
xfs_drfsbno_t *toti,
4089
xfs_agblock_t agbno;
4090
xfs_agnumber_t agno;
4091
xfs_bmbt_block_t *block = (xfs_bmbt_block_t *)ablock;
4094
xfs_bmbt_rec_32_t *rp;
4096
agno = XFS_FSB_TO_AGNO(mp, bno);
4097
agbno = XFS_FSB_TO_AGBNO(mp, bno);
4098
if (INT_GET(block->bb_magic, ARCH_CONVERT) != XFS_BMAP_MAGIC) {
4099
if (!sflag || id->ilist || CHECK_BLIST(bno))
4100
dbprintf("bad magic # %#x in inode %lld bmbt block "
4102
INT_GET(block->bb_magic, ARCH_CONVERT), id->ino, agno, agbno);
4105
if (INT_GET(block->bb_level, ARCH_CONVERT) != level) {
4106
if (!sflag || id->ilist || CHECK_BLIST(bno))
4107
dbprintf("expected level %d got %d in inode %lld bmbt "
4109
level, INT_GET(block->bb_level, ARCH_CONVERT), id->ino, agno, agbno);
4112
set_dbmap(agno, agbno, 1, type, agno, agbno);
4113
set_inomap(agno, agbno, 1, id);
4116
if (INT_GET(block->bb_numrecs, ARCH_CONVERT) > mp->m_bmap_dmxr[0] ||
4117
(isroot == 0 && INT_GET(block->bb_numrecs, ARCH_CONVERT) < mp->m_bmap_dmnr[0])) {
4118
if (!sflag || id->ilist || CHECK_BLIST(bno))
4119
dbprintf("bad btree nrecs (%u, min=%u, max=%u) "
4120
"in inode %lld bmap block %lld\n",
4121
INT_GET(block->bb_numrecs, ARCH_CONVERT), mp->m_bmap_dmnr[0],
4122
mp->m_bmap_dmxr[0], id->ino,
4127
rp = (xfs_bmbt_rec_32_t *)
4128
XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt,
4129
block, 1, mp->m_bmap_dmxr[0]);
4130
*nex += INT_GET(block->bb_numrecs, ARCH_CONVERT);
4131
process_bmbt_reclist(rp, INT_GET(block->bb_numrecs, ARCH_CONVERT), type, id, totd,
4135
if (INT_GET(block->bb_numrecs, ARCH_CONVERT) > mp->m_bmap_dmxr[1] ||
4136
(isroot == 0 && INT_GET(block->bb_numrecs, ARCH_CONVERT) < mp->m_bmap_dmnr[1])) {
4137
if (!sflag || id->ilist || CHECK_BLIST(bno))
4138
dbprintf("bad btree nrecs (%u, min=%u, max=%u) in "
4139
"inode %lld bmap block %lld\n",
4140
INT_GET(block->bb_numrecs, ARCH_CONVERT), mp->m_bmap_dmnr[1],
4141
mp->m_bmap_dmxr[1], id->ino, (xfs_dfsbno_t)bno);
4145
pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, block, 1,
4146
mp->m_bmap_dmxr[0]);
4147
for (i = 0; i < INT_GET(block->bb_numrecs, ARCH_CONVERT); i++)
4148
scan_lbtree(INT_GET(pp[i], ARCH_CONVERT), level, scanfunc_bmap, type, id, totd, toti,
4149
nex, blkmapp, 0, btype);
4154
xfs_btree_sblock_t *ablock,
4160
xfs_alloc_block_t *block = (xfs_alloc_block_t *)ablock;
4162
xfs_alloc_ptr_t *pp;
4163
xfs_alloc_rec_t *rp;
4164
xfs_agnumber_t seqno = INT_GET(agf->agf_seqno, ARCH_CONVERT);
4166
if (INT_GET(block->bb_magic, ARCH_CONVERT) != XFS_ABTB_MAGIC) {
4167
dbprintf("bad magic # %#x in btbno block %u/%u\n",
4168
INT_GET(block->bb_magic, ARCH_CONVERT), seqno, bno);
4173
if (INT_GET(block->bb_level, ARCH_CONVERT) != level) {
4175
dbprintf("expected level %d got %d in btbno block "
4177
level, INT_GET(block->bb_level, ARCH_CONVERT), seqno, bno);
4180
set_dbmap(seqno, bno, 1, DBM_BTBNO, seqno, bno);
4182
if (INT_GET(block->bb_numrecs, ARCH_CONVERT) > mp->m_alloc_mxr[0] ||
4183
(isroot == 0 && INT_GET(block->bb_numrecs, ARCH_CONVERT) < mp->m_alloc_mnr[0])) {
4184
dbprintf("bad btree nrecs (%u, min=%u, max=%u) in "
4185
"btbno block %u/%u\n",
4186
INT_GET(block->bb_numrecs, ARCH_CONVERT), mp->m_alloc_mnr[0],
4187
mp->m_alloc_mxr[0], seqno, bno);
4191
rp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_alloc, block,
4192
1, mp->m_alloc_mxr[0]);
4193
for (i = 0; i < INT_GET(block->bb_numrecs, ARCH_CONVERT); i++) {
4194
set_dbmap(seqno, INT_GET(rp[i].ar_startblock, ARCH_CONVERT),
4195
INT_GET(rp[i].ar_blockcount, ARCH_CONVERT), DBM_FREE1,
4200
if (INT_GET(block->bb_numrecs, ARCH_CONVERT) > mp->m_alloc_mxr[1] ||
4201
(isroot == 0 && INT_GET(block->bb_numrecs, ARCH_CONVERT) < mp->m_alloc_mnr[1])) {
4202
dbprintf("bad btree nrecs (%u, min=%u, max=%u) in btbno block "
4204
INT_GET(block->bb_numrecs, ARCH_CONVERT), mp->m_alloc_mnr[1],
4205
mp->m_alloc_mxr[1], seqno, bno);
4209
pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_alloc, block, 1,
4210
mp->m_alloc_mxr[1]);
4211
for (i = 0; i < INT_GET(block->bb_numrecs, ARCH_CONVERT); i++)
4212
scan_sbtree(agf, INT_GET(pp[i], ARCH_CONVERT), level, 0, scanfunc_bno, TYP_BNOBT);
4217
xfs_btree_sblock_t *ablock,
4223
xfs_alloc_block_t *block = (xfs_alloc_block_t *)ablock;
4224
xfs_agnumber_t seqno = INT_GET(agf->agf_seqno, ARCH_CONVERT);
4226
xfs_alloc_ptr_t *pp;
4227
xfs_alloc_rec_t *rp;
4229
if (INT_GET(block->bb_magic, ARCH_CONVERT) != XFS_ABTC_MAGIC) {
4230
dbprintf("bad magic # %#x in btcnt block %u/%u\n",
4231
INT_GET(block->bb_magic, ARCH_CONVERT), seqno, bno);
4236
if (INT_GET(block->bb_level, ARCH_CONVERT) != level) {
4238
dbprintf("expected level %d got %d in btcnt block "
4240
level, INT_GET(block->bb_level, ARCH_CONVERT), seqno, bno);
4243
set_dbmap(seqno, bno, 1, DBM_BTCNT, seqno, bno);
4245
if (INT_GET(block->bb_numrecs, ARCH_CONVERT) > mp->m_alloc_mxr[0] ||
4246
(isroot == 0 && INT_GET(block->bb_numrecs, ARCH_CONVERT) < mp->m_alloc_mnr[0])) {
4247
dbprintf("bad btree nrecs (%u, min=%u, max=%u) in "
4248
"btbno block %u/%u\n",
4249
INT_GET(block->bb_numrecs, ARCH_CONVERT), mp->m_alloc_mnr[0],
4250
mp->m_alloc_mxr[0], seqno, bno);
4254
rp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_alloc, block,
4255
1, mp->m_alloc_mxr[0]);
4256
for (i = 0; i < INT_GET(block->bb_numrecs, ARCH_CONVERT); i++) {
4257
check_set_dbmap(seqno, INT_GET(rp[i].ar_startblock, ARCH_CONVERT),
4258
INT_GET(rp[i].ar_blockcount, ARCH_CONVERT), DBM_FREE1, DBM_FREE2,
4260
fdblocks += INT_GET(rp[i].ar_blockcount, ARCH_CONVERT);
4261
agffreeblks += INT_GET(rp[i].ar_blockcount, ARCH_CONVERT);
4262
if (INT_GET(rp[i].ar_blockcount, ARCH_CONVERT) > agflongest)
4263
agflongest = INT_GET(rp[i].ar_blockcount, ARCH_CONVERT);
4267
if (INT_GET(block->bb_numrecs, ARCH_CONVERT) > mp->m_alloc_mxr[1] ||
4268
(isroot == 0 && INT_GET(block->bb_numrecs, ARCH_CONVERT) < mp->m_alloc_mnr[1])) {
4269
dbprintf("bad btree nrecs (%u, min=%u, max=%u) in btbno block "
4271
INT_GET(block->bb_numrecs, ARCH_CONVERT), mp->m_alloc_mnr[1],
4272
mp->m_alloc_mxr[1], seqno, bno);
4276
pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_alloc, block, 1,
4277
mp->m_alloc_mxr[1]);
4278
for (i = 0; i < INT_GET(block->bb_numrecs, ARCH_CONVERT); i++)
4279
scan_sbtree(agf, INT_GET(pp[i], ARCH_CONVERT), level, 0, scanfunc_cnt, TYP_CNTBT);
4284
xfs_btree_sblock_t *ablock,
4291
xfs_inobt_block_t *block = (xfs_inobt_block_t *)ablock;
4292
xfs_agnumber_t seqno = INT_GET(agf->agf_seqno, ARCH_CONVERT);
4298
xfs_inobt_ptr_t *pp;
4299
xfs_inobt_rec_t *rp;
4301
if (INT_GET(block->bb_magic, ARCH_CONVERT) != XFS_IBT_MAGIC) {
4302
dbprintf("bad magic # %#x in inobt block %u/%u\n",
4303
INT_GET(block->bb_magic, ARCH_CONVERT), seqno, bno);
4307
if (INT_GET(block->bb_level, ARCH_CONVERT) != level) {
4309
dbprintf("expected level %d got %d in inobt block "
4311
level, INT_GET(block->bb_level, ARCH_CONVERT), seqno, bno);
4314
set_dbmap(seqno, bno, 1, DBM_BTINO, seqno, bno);
4316
if (INT_GET(block->bb_numrecs, ARCH_CONVERT) > mp->m_inobt_mxr[0] ||
4317
(isroot == 0 && INT_GET(block->bb_numrecs, ARCH_CONVERT) < mp->m_inobt_mnr[0])) {
4318
dbprintf("bad btree nrecs (%u, min=%u, max=%u) in "
4319
"inobt block %u/%u\n",
4320
INT_GET(block->bb_numrecs, ARCH_CONVERT), mp->m_inobt_mnr[0],
4321
mp->m_inobt_mxr[0], seqno, bno);
4325
rp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_inobt, block,
4326
1, mp->m_inobt_mxr[0]);
4327
for (i = 0; i < INT_GET(block->bb_numrecs, ARCH_CONVERT); i++) {
4328
agino = INT_GET(rp[i].ir_startino, ARCH_CONVERT);
4329
off = XFS_INO_TO_OFFSET(mp, agino);
4331
if ((sbversion & XFS_SB_VERSION_ALIGNBIT) &&
4332
mp->m_sb.sb_inoalignmt &&
4333
(XFS_INO_TO_AGBNO(mp, agino) %
4334
mp->m_sb.sb_inoalignmt))
4335
sbversion &= ~XFS_SB_VERSION_ALIGNBIT;
4336
set_dbmap(seqno, XFS_AGINO_TO_AGBNO(mp, agino),
4337
(xfs_extlen_t)MAX(1,
4338
XFS_INODES_PER_CHUNK >>
4339
mp->m_sb.sb_inopblog),
4340
DBM_INODE, seqno, bno);
4342
icount += XFS_INODES_PER_CHUNK;
4343
agicount += XFS_INODES_PER_CHUNK;
4344
ifree += INT_GET(rp[i].ir_freecount, ARCH_CONVERT);
4345
agifreecount += INT_GET(rp[i].ir_freecount, ARCH_CONVERT);
4347
set_cur(&typtab[TYP_INODE],
4348
XFS_AGB_TO_DADDR(mp, seqno,
4349
XFS_AGINO_TO_AGBNO(mp, agino)),
4350
(int)XFS_FSB_TO_BB(mp, XFS_IALLOC_BLOCKS(mp)),
4352
if (iocur_top->data == NULL) {
4354
dbprintf("can't read inode block "
4357
XFS_AGINO_TO_AGBNO(mp, agino));
4361
for (j = 0, nfree = 0; j < XFS_INODES_PER_CHUNK; j++) {
4362
if ((isfree = XFS_INOBT_IS_FREE(&rp[i], j, ARCH_CONVERT)))
4364
process_inode(agf, agino + j,
4365
(xfs_dinode_t *)((char *)iocur_top->data + ((off + j) << mp->m_sb.sb_inodelog)),
4368
if (nfree != INT_GET(rp[i].ir_freecount, ARCH_CONVERT)) {
4370
dbprintf("ir_freecount/free mismatch, "
4371
"inode chunk %u/%u, freecount "
4374
INT_GET(rp[i].ir_freecount, ARCH_CONVERT), nfree);
4381
if (INT_GET(block->bb_numrecs, ARCH_CONVERT) > mp->m_inobt_mxr[1] ||
4382
(isroot == 0 && INT_GET(block->bb_numrecs, ARCH_CONVERT) < mp->m_inobt_mnr[1])) {
4383
dbprintf("bad btree nrecs (%u, min=%u, max=%u) in inobt block "
4385
INT_GET(block->bb_numrecs, ARCH_CONVERT), mp->m_inobt_mnr[1],
4386
mp->m_inobt_mxr[1], seqno, bno);
4390
pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_inobt, block, 1,
4391
mp->m_inobt_mxr[1]);
4392
for (i = 0; i < INT_GET(block->bb_numrecs, ARCH_CONVERT); i++)
4393
scan_sbtree(agf, INT_GET(pp[i], ARCH_CONVERT), level, 0, scanfunc_ino, TYP_INOBT);
4398
xfs_agnumber_t agno,
4399
xfs_agblock_t agbno,
4402
xfs_agnumber_t c_agno,
4403
xfs_agblock_t c_agbno)
4405
check_set_dbmap(agno, agbno, len, DBM_UNKNOWN, type, c_agno, c_agbno);
4410
xfs_agnumber_t agno,
4411
xfs_agblock_t agbno,
4419
if (!check_inomap(agno, agbno, len, id->ino))
4421
mayprint = verbose | id->ilist | blist_size;
4422
for (i = 0, idp = &inomap[agno][agbno]; i < len; i++, idp++) {
4425
(verbose || id->ilist || CHECK_BLISTA(agno, agbno + i)))
4426
dbprintf("setting inode to %lld for block %u/%u\n",
4427
id->ino, agno, agbno + i);
4437
check_set_rdbmap(bno, len, DBM_UNKNOWN, type);
4450
if (!check_rinomap(bno, len, id->ino))
4452
mayprint = verbose | id->ilist | blist_size;
4453
for (i = 0, idp = &inomap[mp->m_sb.sb_agcount][bno];
4457
if (mayprint && (verbose || id->ilist || CHECK_BLIST(bno + i)))
4458
dbprintf("setting inode to %lld for rtblock %llu\n",
4470
id->link_set = nlink;
4472
id->security = security;
4473
if (verbose || id->ilist)
4474
dbprintf("inode %lld nlink %u %s dir\n", id->ino, nlink,
4475
isdir ? "is" : "not");