1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
25 IS_USER_QUOTA
, IS_PROJECT_QUOTA
, IS_GROUP_QUOTA
,
29 DBM_UNKNOWN
, DBM_AGF
, DBM_AGFL
, DBM_AGI
,
30 DBM_ATTR
, DBM_BTBMAPA
, DBM_BTBMAPD
, DBM_BTBNO
,
31 DBM_BTCNT
, DBM_BTINO
, DBM_DATA
, DBM_DIR
,
32 DBM_FREE1
, DBM_FREE2
, DBM_FREELIST
, DBM_INODE
,
33 DBM_LOG
, DBM_MISSING
, DBM_QUOTA
, DBM_RTBITMAP
,
34 DBM_RTDATA
, DBM_RTFREE
, DBM_RTSUM
, DBM_SB
,
35 DBM_SYMLINK
, DBM_BTFINO
, DBM_BTRMAP
, DBM_BTREFC
,
36 DBM_RLDATA
, DBM_COWDATA
,
40 typedef struct inodata
{
49 struct inodata
*parent
;
52 #define MIN_INODATA_HASH_SIZE 256
53 #define MAX_INODATA_HASH_SIZE 65536
54 #define INODATA_AVG_HASH_LENGTH 8
56 typedef struct qinfo
{
62 #define QDATA_HASH_SIZE 256
63 typedef struct qdata
{
70 typedef struct blkent
{
71 xfs_fileoff_t startoff
;
73 xfs_fsblock_t blks
[1];
75 #define BLKENT_SIZE(n) \
76 (offsetof(blkent_t, blks) + (sizeof(xfs_fsblock_t) * (n)))
78 typedef struct blkmap
{
83 #define BLKMAP_SIZE(n) \
84 (offsetof(blkmap_t, ents) + (sizeof(blkent_t *) * (n)))
86 typedef struct freetab
{
89 xfs_dir2_data_off_t ents
[1];
91 #define FREETAB_SIZE(n) \
92 (offsetof(freetab_t, ents) + (sizeof(xfs_dir2_data_off_t) * (n)))
94 typedef struct dirhash
{
100 #define DIR_HASH_SIZE 1024
101 #define DIR_HASH_FUNC(h,a) (((h) ^ (a)) % DIR_HASH_SIZE)
103 static xfs_extlen_t agffreeblks
;
104 static xfs_extlen_t agflongest
;
105 static uint64_t agf_aggr_freeblks
; /* aggregate count over all */
106 static uint32_t agfbtreeblks
;
107 static int lazycount
;
108 static xfs_agino_t agicount
;
109 static xfs_agino_t agifreecount
;
110 static xfs_fsblock_t
*blist
;
111 static int blist_size
;
112 static char **dbmap
; /* really dbm_t:8 */
113 static dirhash_t
**dirhash
;
115 static uint64_t fdblocks
;
116 static uint64_t frextents
;
117 static uint64_t icount
;
118 static uint64_t ifree
;
119 static inodata_t
***inodata
;
120 static int inodata_hash_size
;
121 static inodata_t
***inomap
;
125 static qdata_t
**qpdata
;
127 static qdata_t
**qudata
;
129 static qdata_t
**qgdata
;
131 static unsigned sbversion
;
132 static int sbver_err
;
133 static int serious_error
;
135 static union xfs_suminfo_raw
*sumcompute
;
136 static union xfs_suminfo_raw
*sumfile
;
137 static const char *typename
[] = {
172 * Make sure typename has the same number of elements as there are DBM types.
173 * This function isn't called anywhere; we just use it to trip up the compiler.
175 static inline void check_typename(void)
177 BUILD_BUG_ON(ARRAY_SIZE(typename
) != DBM_NDBM
+ 1);
182 #define CHECK_BLIST(b) (blist_size && check_blist(b))
183 #define CHECK_BLISTA(a,b) \
184 (blist_size && check_blist(XFS_AGB_TO_FSB(mp, a, b)))
186 typedef void (*scan_lbtree_f_t
)(struct xfs_btree_block
*block
,
191 xfs_rfsblock_t
*totd
,
192 xfs_rfsblock_t
*toti
,
198 typedef void (*scan_sbtree_f_t
)(struct xfs_btree_block
*block
,
204 static void add_blist(xfs_fsblock_t bno
);
205 static void add_ilist(xfs_ino_t ino
);
206 static void addlink_inode(inodata_t
*id
);
207 static void addname_inode(inodata_t
*id
, char *name
, int namelen
);
208 static void addparent_inode(inodata_t
*id
, xfs_ino_t parent
);
209 static void blkent_append(blkent_t
**entp
, xfs_fsblock_t b
,
211 static blkent_t
*blkent_new(xfs_fileoff_t o
, xfs_fsblock_t b
,
213 static void blkent_prepend(blkent_t
**entp
, xfs_fsblock_t b
,
215 static blkmap_t
*blkmap_alloc(xfs_extnum_t
);
216 static void blkmap_free(blkmap_t
*blkmap
);
217 static xfs_fsblock_t
blkmap_get(blkmap_t
*blkmap
, xfs_fileoff_t o
);
218 static int blkmap_getn(blkmap_t
*blkmap
, xfs_fileoff_t o
, int nb
,
220 static void blkmap_grow(blkmap_t
**blkmapp
, blkent_t
**entp
,
222 static xfs_fileoff_t
blkmap_next_off(blkmap_t
*blkmap
, xfs_fileoff_t o
,
224 static void blkmap_set_blk(blkmap_t
**blkmapp
, xfs_fileoff_t o
,
226 static void blkmap_set_ext(blkmap_t
**blkmapp
, xfs_fileoff_t o
,
227 xfs_fsblock_t b
, xfs_extlen_t c
);
228 static void blkmap_shrink(blkmap_t
*blkmap
, blkent_t
**entp
);
229 static int blockfree_f(int argc
, char **argv
);
230 static int blockget_f(int argc
, char **argv
);
231 static int blocktrash_f(int argc
, char **argv
);
232 static int blockuse_f(int argc
, char **argv
);
233 static int check_blist(xfs_fsblock_t bno
);
234 static void check_dbmap(xfs_agnumber_t agno
, xfs_agblock_t agbno
,
235 xfs_extlen_t len
, dbm_t type
,
237 static int check_inomap(xfs_agnumber_t agno
, xfs_agblock_t agbno
,
238 xfs_extlen_t len
, xfs_ino_t c_ino
);
239 static int check_range(xfs_agnumber_t agno
, xfs_agblock_t agbno
,
241 static void check_rdbmap(xfs_rfsblock_t bno
, xfs_extlen_t len
,
243 static int check_rinomap(xfs_rfsblock_t bno
, xfs_extlen_t len
,
245 static int check_rrange(xfs_rfsblock_t bno
, xfs_extlen_t len
);
246 static void check_set_dbmap(xfs_agnumber_t agno
,
247 xfs_agblock_t agbno
, xfs_extlen_t len
,
248 dbm_t type1
, dbm_t type2
,
249 xfs_agnumber_t c_agno
,
250 xfs_agblock_t c_agbno
);
251 static void check_set_rdbmap(xfs_rfsblock_t bno
, xfs_extlen_t len
,
252 dbm_t type1
, dbm_t type2
);
253 static void dir_hash_add(xfs_dahash_t hash
,
254 xfs_dir2_dataptr_t addr
);
255 static void dir_hash_check(inodata_t
*id
, int v
);
256 static void dir_hash_done(void);
257 static void dir_hash_init(void);
258 static int dir_hash_see(xfs_dahash_t hash
,
259 xfs_dir2_dataptr_t addr
);
260 static inodata_t
*find_inode(xfs_ino_t ino
, int add
);
261 static void free_inodata(xfs_agnumber_t agno
);
262 static int init(int argc
, char **argv
);
263 static char *inode_name(xfs_ino_t ino
, inodata_t
**ipp
);
264 static int ncheck_f(int argc
, char **argv
);
265 static char *prepend_path(char *oldpath
, char *parent
);
266 static xfs_ino_t
process_block_dir_v2(blkmap_t
*blkmap
, int *dot
,
267 int *dotdot
, inodata_t
*id
);
268 static void process_bmbt_reclist(xfs_bmbt_rec_t
*rp
,
269 xfs_extnum_t numrecs
, dbm_t type
,
270 inodata_t
*id
, xfs_rfsblock_t
*tot
,
272 static void process_btinode(inodata_t
*id
, struct xfs_dinode
*dip
,
273 dbm_t type
, xfs_rfsblock_t
*totd
,
274 xfs_rfsblock_t
*toti
, xfs_extnum_t
*nex
,
275 blkmap_t
**blkmapp
, int whichfork
);
276 static xfs_ino_t
process_data_dir_v2(int *dot
, int *dotdot
,
277 inodata_t
*id
, int v
,
279 freetab_t
**freetabp
);
280 static xfs_dir2_data_free_t
*process_data_dir_v2_freefind(
281 struct xfs_dir2_data_hdr
*data
,
282 struct xfs_dir2_data_unused
*dup
);
283 static void process_dir(struct xfs_dinode
*dip
, blkmap_t
*blkmap
,
285 static int process_dir_v2(struct xfs_dinode
*dip
, blkmap_t
*blkmap
,
286 int *dot
, int *dotdot
, inodata_t
*id
,
288 static void process_exinode(inodata_t
*id
, struct xfs_dinode
*dip
,
289 dbm_t type
, xfs_rfsblock_t
*totd
,
290 xfs_rfsblock_t
*toti
, xfs_extnum_t
*nex
,
291 blkmap_t
**blkmapp
, int whichfork
);
292 static void process_inode(xfs_agf_t
*agf
, xfs_agino_t agino
,
293 struct xfs_dinode
*dip
, int isfree
);
294 static void process_lclinode(inodata_t
*id
, struct xfs_dinode
*dip
,
295 dbm_t type
, xfs_rfsblock_t
*totd
,
296 xfs_rfsblock_t
*toti
, xfs_extnum_t
*nex
,
297 blkmap_t
**blkmapp
, int whichfork
);
298 static xfs_ino_t
process_leaf_node_dir_v2(blkmap_t
*blkmap
, int *dot
,
299 int *dotdot
, inodata_t
*id
,
300 xfs_fsize_t dirsize
);
301 static void process_leaf_node_dir_v2_free(inodata_t
*id
, int v
,
304 static void process_leaf_node_dir_v2_int(inodata_t
*id
, int v
,
307 static void process_quota(qtype_t qtype
, inodata_t
*id
,
309 static void process_rtbitmap(blkmap_t
*blkmap
);
310 static void process_rtsummary(blkmap_t
*blkmap
);
311 static xfs_ino_t
process_sf_dir_v2(struct xfs_dinode
*dip
, int *dot
,
312 int *dotdot
, inodata_t
*id
);
313 static void quota_add(xfs_dqid_t
*p
, xfs_dqid_t
*g
, xfs_dqid_t
*u
,
314 int dq
, xfs_qcnt_t bc
, xfs_qcnt_t ic
,
316 static void quota_add1(qdata_t
**qt
, xfs_dqid_t id
, int dq
,
317 xfs_qcnt_t bc
, xfs_qcnt_t ic
,
319 static void quota_init(void);
320 static void scan_ag(xfs_agnumber_t agno
);
321 static void scan_freelist(xfs_agf_t
*agf
);
322 static void scan_lbtree(xfs_fsblock_t root
, int nlevels
,
323 scan_lbtree_f_t func
, dbm_t type
,
324 inodata_t
*id
, xfs_rfsblock_t
*totd
,
325 xfs_rfsblock_t
*toti
, xfs_extnum_t
*nex
,
326 blkmap_t
**blkmapp
, int isroot
,
328 static void scan_sbtree(xfs_agf_t
*agf
, xfs_agblock_t root
,
329 int nlevels
, int isroot
,
330 scan_sbtree_f_t func
, typnm_t btype
);
331 static void scanfunc_bmap(struct xfs_btree_block
*block
,
332 int level
, dbm_t type
, xfs_fsblock_t bno
,
333 inodata_t
*id
, xfs_rfsblock_t
*totd
,
334 xfs_rfsblock_t
*toti
, xfs_extnum_t
*nex
,
335 blkmap_t
**blkmapp
, int isroot
,
337 static void scanfunc_bno(struct xfs_btree_block
*block
, int level
,
338 xfs_agf_t
*agf
, xfs_agblock_t bno
,
340 static void scanfunc_cnt(struct xfs_btree_block
*block
, int level
,
341 xfs_agf_t
*agf
, xfs_agblock_t bno
,
343 static void scanfunc_ino(struct xfs_btree_block
*block
, int level
,
344 xfs_agf_t
*agf
, xfs_agblock_t bno
,
346 static void scanfunc_fino(struct xfs_btree_block
*block
, int level
,
347 struct xfs_agf
*agf
, xfs_agblock_t bno
,
349 static void scanfunc_rmap(struct xfs_btree_block
*block
, int level
,
350 struct xfs_agf
*agf
, xfs_agblock_t bno
,
352 static void scanfunc_refcnt(struct xfs_btree_block
*block
, int level
,
353 struct xfs_agf
*agf
, xfs_agblock_t bno
,
355 static void set_dbmap(xfs_agnumber_t agno
, xfs_agblock_t agbno
,
356 xfs_extlen_t len
, dbm_t type
,
357 xfs_agnumber_t c_agno
, xfs_agblock_t c_agbno
);
358 static void set_inomap(xfs_agnumber_t agno
, xfs_agblock_t agbno
,
359 xfs_extlen_t len
, inodata_t
*id
);
360 static void set_rdbmap(xfs_rfsblock_t bno
, xfs_extlen_t len
,
362 static void set_rinomap(xfs_rfsblock_t bno
, xfs_extlen_t len
,
364 static void setlink_inode(inodata_t
*id
, nlink_t nlink
, int isdir
,
367 static const cmdinfo_t blockfree_cmd
=
368 { "blockfree", NULL
, blockfree_f
, 0, 0, 0,
369 NULL
, N_("free block usage information"), NULL
};
370 static const cmdinfo_t blockget_cmd
=
371 { "blockget", NULL
, blockget_f
, 0, -1, 0,
372 N_("[-s|-v] [-n] [-t] [-b bno]... [-i ino] ..."),
373 N_("get block usage and check consistency"), NULL
};
374 static const cmdinfo_t blocktrash_cmd
=
375 { "blocktrash", NULL
, blocktrash_f
, 0, -1, 0,
376 N_("[-n count] [-x minlen] [-y maxlen] [-s seed] [-0123] [-t type] ..."),
377 N_("trash randomly selected block(s)"), NULL
};
378 static const cmdinfo_t blockuse_cmd
=
379 { "blockuse", NULL
, blockuse_f
, 0, 3, 0,
380 N_("[-n] [-c blockcount]"),
381 N_("print usage for current block(s)"), NULL
};
382 static const cmdinfo_t ncheck_cmd
=
383 { "ncheck", NULL
, ncheck_f
, 0, -1, 0,
384 N_("[-s] [-i ino] ..."),
385 N_("print inode-name pairs"), NULL
};
393 blist
= xrealloc(blist
, blist_size
* sizeof(bno
));
394 blist
[blist_size
- 1] = bno
;
403 id
= find_inode(ino
, 1);
405 dbprintf(_("-i %lld bad inode number\n"), ino
);
416 if (verbose
|| id
->ilist
)
417 dbprintf(_("inode %lld add link, now %u\n"), id
->ino
,
427 if (!nflag
|| id
->name
)
429 id
->name
= xmalloc(namelen
+ 1);
430 memcpy(id
->name
, name
, namelen
);
431 id
->name
[namelen
] = '\0';
441 pid
= find_inode(parent
, 1);
443 if (verbose
|| id
->ilist
|| (pid
&& pid
->ilist
))
444 dbprintf(_("inode %lld parent %lld\n"), id
->ino
, parent
);
457 *entp
= ent
= xrealloc(ent
, BLKENT_SIZE(c
+ ent
->nblks
));
458 for (i
= 0; i
< c
; i
++)
459 ent
->blks
[ent
->nblks
+ i
] = b
+ i
;
472 ent
= xmalloc(BLKENT_SIZE(c
));
475 for (i
= 0; i
< c
; i
++)
476 ent
->blks
[i
] = b
+ i
;
491 newent
= xmalloc(BLKENT_SIZE(oldent
->nblks
+ c
));
492 newent
->nblks
= oldent
->nblks
+ c
;
493 newent
->startoff
= oldent
->startoff
- c
;
494 for (i
= 0; i
< c
; i
++)
495 newent
->blks
[i
] = b
+ c
;
496 for (; i
< oldent
->nblks
+ c
; i
++)
497 newent
->blks
[i
] = oldent
->blks
[i
- c
];
510 blkmap
= xmalloc(BLKMAP_SIZE(nex
));
511 blkmap
->naents
= nex
;
523 for (i
= 0, entp
= blkmap
->ents
; i
< blkmap
->nents
; i
++, entp
++)
537 for (i
= 0, entp
= blkmap
->ents
; i
< blkmap
->nents
; i
++, entp
++) {
539 if (o
>= ent
->startoff
&& o
< ent
->startoff
+ ent
->nblks
)
540 return ent
->blks
[o
- ent
->startoff
];
559 for (i
= nex
= 0, bmp
= NULL
, entp
= blkmap
->ents
;
563 if (ent
->startoff
>= o
+ nb
)
565 if (ent
->startoff
+ ent
->nblks
<= o
)
567 for (ento
= ent
->startoff
;
568 ento
< ent
->startoff
+ ent
->nblks
&& ento
< o
+ nb
;
573 bmp
[nex
- 1].startoff
+ bmp
[nex
- 1].blockcount
==
575 bmp
[nex
- 1].startblock
+ bmp
[nex
- 1].blockcount
==
576 ent
->blks
[ento
- ent
->startoff
])
577 bmp
[nex
- 1].blockcount
++;
579 bmp
= realloc(bmp
, ++nex
* sizeof(*bmp
));
580 bmp
[nex
- 1].startoff
= ento
;
581 bmp
[nex
- 1].startblock
=
582 ent
->blks
[ento
- ent
->startoff
];
583 bmp
[nex
- 1].blockcount
= 1;
584 bmp
[nex
- 1].flag
= 0;
603 idx
= (int)(entp
- blkmap
->ents
);
604 if (blkmap
->naents
== blkmap
->nents
) {
605 blkmap
= xrealloc(blkmap
, BLKMAP_SIZE(blkmap
->nents
+ 1));
609 for (i
= blkmap
->nents
; i
> idx
; i
--)
610 blkmap
->ents
[i
] = blkmap
->ents
[i
- 1];
611 blkmap
->ents
[idx
] = newent
;
623 ent
= blkmap
->ents
[blkmap
->nents
- 1];
624 return ent
->startoff
+ ent
->nblks
;
638 if (o
== NULLFILEOFF
) {
640 ent
= blkmap
->ents
[0];
641 return ent
->startoff
;
643 entp
= &blkmap
->ents
[*t
];
645 if (o
< ent
->startoff
+ ent
->nblks
- 1)
648 if (entp
>= &blkmap
->ents
[blkmap
->nents
])
652 return ent
->startoff
;
667 for (entp
= blkmap
->ents
; entp
< &blkmap
->ents
[blkmap
->nents
]; entp
++) {
669 if (o
< ent
->startoff
- 1) {
670 ent
= blkent_new(o
, b
, 1);
671 blkmap_grow(blkmapp
, entp
, ent
);
674 if (o
== ent
->startoff
- 1) {
675 blkent_prepend(entp
, b
, 1);
678 if (o
>= ent
->startoff
&& o
< ent
->startoff
+ ent
->nblks
) {
679 ent
->blks
[o
- ent
->startoff
] = b
;
682 if (o
> ent
->startoff
+ ent
->nblks
)
684 blkent_append(entp
, b
, 1);
685 if (entp
== &blkmap
->ents
[blkmap
->nents
- 1])
689 if (ent
->startoff
+ ent
->nblks
< nextent
->startoff
)
691 blkent_append(entp
, nextent
->blks
[0], nextent
->nblks
);
692 blkmap_shrink(blkmap
, &entp
[1]);
695 ent
= blkent_new(o
, b
, 1);
696 blkmap_grow(blkmapp
, entp
, ent
);
712 if (!blkmap
->nents
) {
713 blkmap
->ents
[0] = blkent_new(o
, b
, c
);
717 entp
= &blkmap
->ents
[blkmap
->nents
- 1];
719 if (ent
->startoff
+ ent
->nblks
== o
) {
720 blkent_append(entp
, b
, c
);
723 if (ent
->startoff
+ ent
->nblks
< o
) {
724 ent
= blkent_new(o
, b
, c
);
725 blkmap_grow(blkmapp
, &blkmap
->ents
[blkmap
->nents
], ent
);
728 for (i
= 0; i
< c
; i
++)
729 blkmap_set_blk(blkmapp
, o
+ i
, b
+ i
);
741 idx
= (int)(entp
- blkmap
->ents
);
742 for (i
= idx
+ 1; i
< blkmap
->nents
; i
++)
743 blkmap
->ents
[i
] = blkmap
->ents
[i
- 1];
757 dbprintf(_("block usage information not allocated\n"));
760 rt
= mp
->m_sb
.sb_rextents
!= 0;
761 for (c
= 0; c
< mp
->m_sb
.sb_agcount
; c
++) {
771 sumcompute
= sumfile
= NULL
;
783 * Check consistency of xfs filesystem contents.
795 dbprintf(_("already have block usage information\n"));
799 if (!init(argc
, argv
)) {
806 oldprefix
= dbprefix
;
808 for (agno
= 0, sbyell
= 0; agno
< mp
->m_sb
.sb_agcount
; agno
++) {
810 if (sbver_err
> 4 && !sbyell
&& sbver_err
>= agno
) {
812 dbprintf(_("WARNING: this may be a newer XFS "
824 dbprefix
= oldprefix
;
828 typedef struct ltab
{
847 const struct xfs_buf_ops
*stashed_ops
;
848 static char *modestr
[] = {
849 N_("zeroed"), N_("set"), N_("flipped"), N_("randomized")
854 agno
= XFS_FSB_TO_AGNO(mp
, XFS_DADDR_TO_FSB(mp
, iocur_top
->bb
));
855 agbno
= XFS_FSB_TO_AGBNO(mp
, XFS_DADDR_TO_FSB(mp
, iocur_top
->bb
));
856 if (iocur_top
->len
== 0) {
857 dbprintf(_("zero-length block %u/%u buffer to trash??\n"),
861 len
= (int)((random() % (ltabp
->max
- ltabp
->min
+ 1)) + ltabp
->min
);
863 * bit_offset >= 0: start fuzzing at this exact bit_offset.
864 * bit_offset < 0: pick an offset at least as high at -(bit_offset + 1).
866 if (bit_offset
< 0) {
867 bit_offset
= -(bit_offset
+ 1);
868 bit_offset
+= (int)(random() % (int)((iocur_top
->len
- bit_offset
) * NBBY
));
870 if (bit_offset
+ len
>= iocur_top
->len
* NBBY
)
871 len
= (iocur_top
->len
* NBBY
) - bit_offset
;
873 stashed_ops
= iocur_top
->bp
->b_ops
;
874 iocur_top
->bp
->b_ops
= NULL
;
875 if ((buf
= iocur_top
->data
) == NULL
) {
876 dbprintf(_("can't read block %u/%u for trashing\n"), agno
, agbno
);
879 for (bitno
= 0; bitno
< len
; bitno
++) {
880 bit
= (bit_offset
+ bitno
) % (mp
->m_sb
.sb_blocksize
* NBBY
);
892 newbit
= (buf
[byte
] & mask
) == 0;
895 newbit
= (int)random() & 1;
904 iocur_top
->bp
->b_ops
= stashed_ops
;
905 printf(_("blocktrash: %u/%u %s block %d bit%s starting %d:%d %s\n"),
906 agno
, agbno
, typename
[type
], len
, len
== 1 ? "" : "s",
907 bit_offset
/ NBBY
, bit_offset
% NBBY
, modestr
[mode
]);
918 xfs_rfsblock_t blocks
;
931 xfs_rfsblock_t randb
;
935 bool this_block
= false;
943 gettimeofday(&now
, NULL
);
944 seed
= (unsigned int)(now
.tv_sec
^ now
.tv_usec
);
947 goodmask
= (1 << DBM_AGF
) |
960 (1 << DBM_RTBITMAP
) |
967 while ((c
= getopt(argc
, argv
, "0123n:o:s:t:x:y:z")) != EOF
) {
982 count
= (int)strtol(optarg
, &p
, 0);
983 if (*p
!= '\0' || count
<= 0) {
984 dbprintf(_("bad blocktrash count %s\n"), optarg
);
990 if (optarg
[0] == '+') {
994 bit_offset
= (int)strtol(optarg
, &p
, 0);
995 if (*p
!= '\0' || bit_offset
< 0) {
996 dbprintf(_("bad blocktrash offset %s\n"), optarg
);
1000 bit_offset
= -bit_offset
- 1;
1004 seed
= (uint
)strtoul(optarg
, &p
, 0);
1008 for (i
= 0; typename
[i
]; i
++) {
1009 if (strcmp(typename
[i
], optarg
) == 0)
1012 if (!typename
[i
] || (((1 << i
) & goodmask
) == 0)) {
1013 dbprintf(_("bad blocktrash type %s\n"), optarg
);
1019 min
= (int)strtol(optarg
, &p
, 0);
1020 if (*p
!= '\0' || min
<= 0 ||
1021 min
> mp
->m_sb
.sb_blocksize
* NBBY
) {
1022 dbprintf(_("bad blocktrash min %s\n"), optarg
);
1027 max
= (int)strtol(optarg
, &p
, 0);
1028 if (*p
!= '\0' || max
<= 0 ||
1029 max
> mp
->m_sb
.sb_blocksize
* NBBY
) {
1030 dbprintf(_("bad blocktrash max %s\n"), optarg
);
1038 dbprintf(_("bad option for blocktrash command\n"));
1042 if (!this_block
&& !dbmap
) {
1043 dbprintf(_("must run blockget first\n"));
1046 if (this_block
&& iocur_sp
== 0) {
1047 dbprintf(_("nothing on stack\n"));
1051 dbprintf(_("bad min/max for blocktrash command\n"));
1055 tmask
= goodmask
& ~((1 << DBM_LOG
) | (1 << DBM_SB
));
1056 lentab
= xmalloc(sizeof(ltab_t
));
1057 lentab
->min
= lentab
->max
= min
;
1059 for (i
= min
+ 1; i
<= max
; i
++) {
1060 if ((i
& (i
- 1)) == 0) {
1061 lentab
= xrealloc(lentab
,
1062 sizeof(ltab_t
) * (lentablen
+ 1));
1063 lentab
[lentablen
].min
= lentab
[lentablen
].max
= i
;
1066 lentab
[lentablen
- 1].max
= i
;
1069 dbprintf(_("blocktrash: seed %u\n"), seed
);
1072 blocktrash_b(bit_offset
, DBM_UNKNOWN
,
1073 &lentab
[random() % lentablen
], mode
);
1076 for (blocks
= 0, agno
= 0; agno
< mp
->m_sb
.sb_agcount
; agno
++) {
1077 for (agbno
= 0, p
= dbmap
[agno
];
1078 agbno
< mp
->m_sb
.sb_agblocks
;
1080 if ((1 << *p
) & tmask
)
1085 dbprintf(_("blocktrash: no matching blocks\n"));
1088 for (i
= 0; i
< count
; i
++) {
1089 randb
= (xfs_rfsblock_t
)((((int64_t)random() << 32) |
1090 random()) % blocks
);
1091 for (bi
= 0, agno
= 0, done
= 0;
1092 !done
&& agno
< mp
->m_sb
.sb_agcount
;
1094 for (agbno
= 0, p
= dbmap
[agno
];
1095 agbno
< mp
->m_sb
.sb_agblocks
;
1097 if (!((1 << *p
) & tmask
))
1103 XFS_AGB_TO_DADDR(mp
, agno
, agbno
),
1104 blkbb
, DB_RING_IGN
, NULL
);
1105 blocktrash_b(bit_offset
, (dbm_t
)*p
,
1106 &lentab
[random() % lentablen
], mode
);
1123 xfs_agblock_t agbno
;
1124 xfs_agnumber_t agno
;
1134 dbprintf(_("must run blockget first\n"));
1139 fsb
= XFS_DADDR_TO_FSB(mp
, iocur_top
->off
>> BBSHIFT
);
1140 agno
= XFS_FSB_TO_AGNO(mp
, fsb
);
1141 end
= agbno
= XFS_FSB_TO_AGBNO(mp
, fsb
);
1142 while ((c
= getopt(argc
, argv
, "c:n")) != EOF
) {
1145 count
= (int)strtol(optarg
, &p
, 0);
1146 end
= agbno
+ count
- 1;
1147 if (*p
!= '\0' || count
<= 0 ||
1148 end
>= mp
->m_sb
.sb_agblocks
) {
1149 dbprintf(_("bad blockuse count %s\n"), optarg
);
1155 dbprintf(_("must run blockget -n first\n"));
1161 dbprintf(_("bad option for blockuse command\n"));
1165 while (agbno
<= end
) {
1166 p
= &dbmap
[agno
][agbno
];
1167 i
= inomap
[agno
][agbno
];
1168 dbprintf(_("block %llu (%u/%u) type %s"),
1169 (xfs_fsblock_t
)XFS_AGB_TO_FSB(mp
, agno
, agbno
),
1170 agno
, agbno
, typename
[(dbm_t
)*p
]);
1172 dbprintf(_(" inode %lld"), i
->ino
);
1173 if (shownames
&& (p
= inode_name(i
->ino
, NULL
))) {
1190 for (i
= 0; i
< blist_size
; i
++) {
1191 if (blist
[i
] == bno
)
1199 xfs_agnumber_t agno
,
1200 xfs_agblock_t agbno
)
1202 if (agno
>= mp
->m_sb
.sb_agcount
)
1204 if (agbno
>= mp
->m_sb
.sb_agblocks
)
1211 xfs_agnumber_t agno
,
1212 xfs_agblock_t agbno
,
1221 for (i
= 0, p
= &dbmap
[agno
][agbno
]; i
< len
; i
++, p
++) {
1222 if (!dbmap_boundscheck(agno
, agbno
+ i
)) {
1223 dbprintf(_("block %u/%u beyond end of expected area\n"),
1229 if (ignore_reflink
&& (d
== DBM_UNKNOWN
|| d
== DBM_DATA
||
1232 if ((dbm_t
)*p
!= type
) {
1233 if (!sflag
|| CHECK_BLISTA(agno
, agbno
+ i
)) {
1234 dbprintf(_("block %u/%u expected type %s got "
1236 agno
, agbno
+ i
, typename
[type
],
1237 typename
[(dbm_t
)*p
]);
1247 add_command(&blockfree_cmd
);
1248 add_command(&blockget_cmd
);
1250 add_command(&blocktrash_cmd
);
1251 add_command(&blockuse_cmd
);
1252 add_command(&ncheck_cmd
);
1257 xfs_agnumber_t agno
,
1258 xfs_agblock_t agbno
,
1266 if (!check_range(agno
, agbno
, len
)) {
1267 dbprintf(_("blocks %u/%u..%u claimed by inode %lld\n"),
1268 agno
, agbno
, agbno
+ len
- 1, c_ino
);
1271 for (i
= 0, rval
= 1, idp
= &inomap
[agno
][agbno
]; i
< len
; i
++, idp
++) {
1272 if (*idp
&& !(*idp
)->isreflink
) {
1273 if (!sflag
|| (*idp
)->ilist
||
1274 CHECK_BLISTA(agno
, agbno
+ i
))
1275 dbprintf(_("block %u/%u claimed by inode %lld, "
1276 "previous inum %lld\n"),
1277 agno
, agbno
+ i
, c_ino
, (*idp
)->ino
);
1287 xfs_agnumber_t agno
,
1288 xfs_agblock_t agbno
,
1292 xfs_agblock_t low
= 0;
1293 xfs_agblock_t high
= 0;
1294 int valid_range
= 0;
1297 if (agno
>= mp
->m_sb
.sb_agcount
||
1298 agbno
+ len
- 1 >= mp
->m_sb
.sb_agblocks
) {
1299 for (i
= 0; i
< len
; i
++) {
1300 cur
= !sflag
|| CHECK_BLISTA(agno
, agbno
+ i
) ? 1 : 0;
1301 if (cur
== 1 && prev
== 0) {
1302 low
= high
= agbno
+ i
;
1304 } else if (cur
== 0 && prev
== 0) {
1306 } else if (cur
== 0 && prev
== 1) {
1308 dbprintf(_("block %u/%u out of range\n"),
1311 dbprintf(_("blocks %u/%u..%u "
1316 } else if (cur
== 1 && prev
== 1) {
1323 dbprintf(_("block %u/%u out of range\n"),
1326 dbprintf(_("blocks %u/%u..%u "
1341 return bno
< mp
->m_sb
.sb_rblocks
;
1353 for (i
= 0, p
= &dbmap
[mp
->m_sb
.sb_agcount
][bno
]; i
< len
; i
++, p
++) {
1354 if (!rdbmap_boundscheck(bno
+ i
)) {
1355 dbprintf(_("rtblock %llu beyond end of expected area\n"),
1360 if ((dbm_t
)*p
!= type
) {
1361 if (!sflag
|| CHECK_BLIST(bno
+ i
))
1362 dbprintf(_("rtblock %llu expected type %s got "
1364 bno
+ i
, typename
[type
],
1365 typename
[(dbm_t
)*p
]);
1381 if (!check_rrange(bno
, len
)) {
1382 dbprintf(_("rtblocks %llu..%llu claimed by inode %lld\n"),
1383 bno
, bno
+ len
- 1, c_ino
);
1386 for (i
= 0, rval
= 1, idp
= &inomap
[mp
->m_sb
.sb_agcount
][bno
];
1390 if (!sflag
|| (*idp
)->ilist
|| CHECK_BLIST(bno
+ i
))
1391 dbprintf(_("rtblock %llu claimed by inode %lld, "
1392 "previous inum %lld\n"),
1393 bno
+ i
, c_ino
, (*idp
)->ino
);
1404 xfs_rfsblock_t high
)
1407 dbprintf(_("rtblock %llu out of range\n"), low
);
1409 dbprintf(_("rtblocks %llu..%llu out of range\n"), low
, high
);
1418 xfs_rfsblock_t low
= 0;
1419 xfs_rfsblock_t high
= 0;
1420 bool valid_range
= false;
1423 if (bno
+ len
- 1 >= mp
->m_sb
.sb_rblocks
) {
1424 for (i
= 0; i
< len
; i
++) {
1425 cur
= !sflag
|| CHECK_BLIST(bno
+ i
) ? 1 : 0;
1426 if (cur
== 1 && prev
== 0) {
1427 low
= high
= bno
+ i
;
1429 } else if (cur
== 0 && prev
== 0) {
1431 } else if (cur
== 0 && prev
== 1) {
1432 report_rrange(low
, high
);
1433 valid_range
= false;
1434 } else if (cur
== 1 && prev
== 1) {
1440 report_rrange(low
, high
);
1448 * We don't check the accuracy of reference counts -- all we do is ensure
1449 * that a data block never crosses with non-data blocks. repair can check
1450 * those kinds of things.
1452 * So with that in mind, if we're setting a block to be data or rldata,
1453 * don't complain so long as the block is currently unknown, data, or rldata.
1454 * Don't let blocks downgrade from rldata -> data.
1460 if (!xfs_has_reflink(mp
))
1462 if (type2
== DBM_DATA
|| type2
== DBM_RLDATA
)
1469 xfs_agnumber_t agno
,
1470 xfs_agblock_t agbno
,
1474 xfs_agnumber_t c_agno
,
1475 xfs_agblock_t c_agbno
)
1481 if (!check_range(agno
, agbno
, len
)) {
1482 dbprintf(_("blocks %u/%u..%u claimed by block %u/%u\n"), agno
,
1483 agbno
, agbno
+ len
- 1, c_agno
, c_agbno
);
1486 check_dbmap(agno
, agbno
, len
, type1
, is_reflink(type2
));
1487 mayprint
= verbose
| blist_size
;
1488 for (i
= 0, p
= &dbmap
[agno
][agbno
]; i
< len
; i
++, p
++) {
1489 if (!dbmap_boundscheck(agno
, agbno
+ i
)) {
1490 dbprintf(_("block %u/%u beyond end of expected area\n"),
1495 if (*p
== DBM_RLDATA
&& type2
== DBM_DATA
)
1497 else if (*p
== DBM_DATA
&& type2
== DBM_DATA
)
1498 *p
= (char)DBM_RLDATA
;
1501 if (mayprint
&& (verbose
|| CHECK_BLISTA(agno
, agbno
+ i
)))
1502 dbprintf(_("setting block %u/%u to %s\n"), agno
, agbno
+ i
,
1518 if (!check_rrange(bno
, len
))
1520 check_rdbmap(bno
, len
, type1
);
1521 mayprint
= verbose
| blist_size
;
1522 for (i
= 0, p
= &dbmap
[mp
->m_sb
.sb_agcount
][bno
]; i
< len
; i
++, p
++) {
1523 if (!rdbmap_boundscheck(bno
+ i
)) {
1524 dbprintf(_("rtblock %llu beyond end of expected area\n"),
1530 if (mayprint
&& (verbose
|| CHECK_BLIST(bno
+ i
)))
1531 dbprintf(_("setting rtblock %llu to %s\n"),
1532 bno
+ i
, typename
[type2
]);
1536 static inline xfs_suminfo_t
1538 struct xfs_mount
*mp
,
1539 union xfs_suminfo_raw
*raw
)
1547 xfs_dir2_dataptr_t addr
)
1552 i
= DIR_HASH_FUNC(hash
, addr
);
1553 p
= malloc(sizeof(*p
));
1554 p
->next
= dirhash
[i
];
1569 for (i
= 0; i
< DIR_HASH_SIZE
; i
++) {
1570 for (p
= dirhash
[i
]; p
; p
= p
->next
) {
1573 if (!sflag
|| id
->ilist
|| v
)
1574 dbprintf(_("dir ino %lld missing leaf entry for "
1576 id
->ino
, p
->hashval
, p
->address
);
1589 for (i
= 0; i
< DIR_HASH_SIZE
; i
++) {
1590 for (p
= dirhash
[i
]; p
; p
= n
) {
1602 dirhash
= calloc(DIR_HASH_SIZE
, sizeof(*dirhash
));
1608 xfs_dir2_dataptr_t addr
)
1613 i
= DIR_HASH_FUNC(hash
, addr
);
1614 for (p
= dirhash
[i
]; p
; p
= p
->next
) {
1615 if (p
->hashval
== hash
&& p
->address
== addr
) {
1631 xfs_agnumber_t agno
;
1636 agno
= XFS_INO_TO_AGNO(mp
, ino
);
1637 agino
= XFS_INO_TO_AGINO(mp
, ino
);
1638 if (agno
>= mp
->m_sb
.sb_agcount
||
1639 XFS_AGINO_TO_INO(mp
, agno
, agino
) != ino
)
1641 htab
= inodata
[agno
];
1642 ih
= agino
% inodata_hash_size
;
1645 if (ent
->ino
== ino
)
1651 ent
= xcalloc(1, sizeof(*ent
));
1653 ent
->next
= htab
[ih
];
1660 xfs_agnumber_t agno
)
1668 for (i
= 0; i
< inodata_hash_size
; i
++) {
1692 if (mp
->m_sb
.sb_magicnum
!= XFS_SB_MAGIC
) {
1693 dbprintf(_("bad superblock magic number %x, giving up\n"),
1694 mp
->m_sb
.sb_magicnum
);
1700 rt
= mp
->m_sb
.sb_rextents
!= 0;
1701 dbmap
= xmalloc((mp
->m_sb
.sb_agcount
+ rt
) * sizeof(*dbmap
));
1702 inomap
= xmalloc((mp
->m_sb
.sb_agcount
+ rt
) * sizeof(*inomap
));
1703 inodata
= xmalloc(mp
->m_sb
.sb_agcount
* sizeof(*inodata
));
1705 (int)max(min(mp
->m_sb
.sb_icount
/
1706 (INODATA_AVG_HASH_LENGTH
* mp
->m_sb
.sb_agcount
),
1707 MAX_INODATA_HASH_SIZE
),
1708 MIN_INODATA_HASH_SIZE
);
1709 for (c
= 0; c
< mp
->m_sb
.sb_agcount
; c
++) {
1710 dbmap
[c
] = xcalloc(mp
->m_sb
.sb_agblocks
, sizeof(**dbmap
));
1711 inomap
[c
] = xcalloc(mp
->m_sb
.sb_agblocks
, sizeof(**inomap
));
1712 inodata
[c
] = xcalloc(inodata_hash_size
, sizeof(**inodata
));
1715 unsigned long long words
;
1717 dbmap
[c
] = xcalloc(mp
->m_sb
.sb_rblocks
, sizeof(**dbmap
));
1718 inomap
[c
] = xcalloc(mp
->m_sb
.sb_rblocks
, sizeof(**inomap
));
1719 words
= XFS_FSB_TO_B(mp
, mp
->m_rsumblocks
) >> XFS_WORDLOG
;
1720 sumfile
= xcalloc(words
, sizeof(union xfs_suminfo_raw
));
1721 sumcompute
= xcalloc(words
, sizeof(union xfs_suminfo_raw
));
1723 nflag
= sflag
= tflag
= verbose
= optind
= 0;
1724 while ((c
= getopt(argc
, argv
, "b:i:npstv")) != EOF
) {
1727 bno
= strtoll(optarg
, NULL
, 10);
1731 ino
= strtoll(optarg
, NULL
, 10);
1750 dbprintf(_("bad option for blockget command\n"));
1754 error
= sbver_err
= serious_error
= 0;
1755 fdblocks
= frextents
= icount
= ifree
= 0;
1756 sbversion
= XFS_SB_VERSION_4
;
1758 * Note that inoalignmt == 0 is valid when fsb size is large enough for
1759 * at least one full inode record per block. Check this case explicitly.
1761 if (mp
->m_sb
.sb_inoalignmt
||
1762 (xfs_has_align(mp
) &&
1763 mp
->m_sb
.sb_inopblock
>= XFS_INODES_PER_CHUNK
))
1764 sbversion
|= XFS_SB_VERSION_ALIGNBIT
;
1765 if ((mp
->m_sb
.sb_uquotino
&& mp
->m_sb
.sb_uquotino
!= NULLFSINO
) ||
1766 (mp
->m_sb
.sb_gquotino
&& mp
->m_sb
.sb_gquotino
!= NULLFSINO
) ||
1767 (mp
->m_sb
.sb_pquotino
&& mp
->m_sb
.sb_pquotino
!= NULLFSINO
))
1768 sbversion
|= XFS_SB_VERSION_QUOTABIT
;
1782 id
= find_inode(ino
, 0);
1787 if (id
->name
== NULL
)
1789 path
= xstrdup(id
->name
);
1790 while (id
->parent
) {
1792 if (id
->name
== NULL
)
1794 npath
= prepend_path(path
, id
->name
);
1806 xfs_agnumber_t agno
;
1819 if (!inodata
|| !nflag
) {
1820 dbprintf(_("must run blockget -n first\n"));
1823 security
= optind
= ilist_size
= 0;
1825 while ((c
= getopt(argc
, argv
, "i:s")) != EOF
) {
1828 ino
= strtoll(optarg
, NULL
, 10);
1829 ilist
= xrealloc(ilist
, (ilist_size
+ 1) *
1831 ilist
[ilist_size
++] = ino
;
1837 dbprintf(_("bad option -%c for ncheck command\n"), c
);
1843 for (ilp
= ilist
; ilp
< &ilist
[ilist_size
]; ilp
++) {
1845 if ((p
= inode_name(ino
, &hp
))) {
1846 dbprintf("%11llu %s", ino
, p
);
1856 for (agno
= 0; agno
< mp
->m_sb
.sb_agcount
; agno
++) {
1858 for (i
= 0; i
< inodata_hash_size
; i
++) {
1860 for (hp
= ht
[i
]; hp
; hp
= hp
->next
) {
1861 ino
= XFS_AGINO_TO_INO(mp
, agno
, hp
->ino
);
1862 p
= inode_name(ino
, &id
);
1865 if (!security
|| id
->security
) {
1866 dbprintf("%11llu %s", ino
, p
);
1886 len
= (int)(strlen(oldpath
) + strlen(parent
) + 2);
1887 path
= xmalloc(len
);
1888 snprintf(path
, len
, "%s/%s", parent
, oldpath
);
1893 process_block_dir_v2(
1907 nex
= blkmap_getn(blkmap
, 0, mp
->m_dir_geo
->fsbcount
, &bmp
);
1908 v
= id
->ilist
|| verbose
;
1911 dbprintf(_("block 0 for directory inode %lld is "
1919 make_bbmap(&bbmap
, nex
, bmp
);
1920 set_cur(&typtab
[TYP_DIR2
], XFS_FSB_TO_DADDR(mp
, bmp
->startblock
),
1921 mp
->m_dir_geo
->fsbcount
* blkbb
, DB_RING_IGN
, nex
> 1 ? &bbmap
: NULL
);
1922 for (i
= 0; !v
&& i
< nex
; i
++) {
1923 for (b
= bmp
[i
].startblock
;
1924 !v
&& b
< bmp
[i
].startblock
+ bmp
[i
].blockcount
;
1929 if (iocur_top
->data
== NULL
) {
1930 if (!sflag
|| id
->ilist
|| v
)
1931 dbprintf(_("can't read block 0 for directory inode "
1939 parent
= process_data_dir_v2(dot
, dotdot
, id
, v
, mp
->m_dir_geo
->datablk
,
1941 dir_hash_check(id
, v
);
1948 process_bmbt_reclist(
1950 xfs_extnum_t numrecs
,
1953 xfs_rfsblock_t
*tot
,
1956 xfs_agblock_t agbno
;
1957 xfs_agnumber_t agno
;
1963 xfs_agblock_t iagbno
;
1964 xfs_agnumber_t iagno
;
1971 v
= verbose
|| id
->ilist
;
1972 iagno
= XFS_INO_TO_AGNO(mp
, id
->ino
);
1973 iagbno
= XFS_INO_TO_AGBNO(mp
, id
->ino
);
1974 for (i
= 0; i
< numrecs
; i
++, rp
++) {
1975 convert_extent(rp
, &o
, &s
, &c
, &f
);
1977 dbprintf(_("inode %lld extent [%lld,%lld,%lld,%d]\n"),
1978 id
->ino
, o
, s
, c
, f
);
1979 if (!sflag
&& i
> 0 && op
+ cp
> o
)
1980 dbprintf(_("bmap rec out of order, inode %lld entry %d\n"),
1984 if (type
== DBM_RTDATA
) {
1985 if (!sflag
&& s
>= mp
->m_sb
.sb_rblocks
) {
1986 dbprintf(_("inode %lld bad rt block number %lld, "
1991 } else if (!sflag
) {
1992 agno
= XFS_FSB_TO_AGNO(mp
, s
);
1993 agbno
= XFS_FSB_TO_AGBNO(mp
, s
);
1994 if (agno
>= mp
->m_sb
.sb_agcount
||
1995 agbno
>= mp
->m_sb
.sb_agblocks
) {
1996 dbprintf(_("inode %lld bad block number %lld "
1997 "[%d,%d], offset %lld\n"),
1998 id
->ino
, s
, agno
, agbno
, o
);
2001 if (agbno
+ c
- 1 >= mp
->m_sb
.sb_agblocks
) {
2002 dbprintf(_("inode %lld bad block number %lld "
2003 "[%d,%d], offset %lld\n"),
2004 id
->ino
, s
+ c
- 1, agno
,
2005 agbno
+ (xfs_agblock_t
)c
- 1, o
);
2009 if (blkmapp
&& *blkmapp
)
2010 blkmap_set_ext(blkmapp
, (xfs_fileoff_t
)o
,
2011 (xfs_fsblock_t
)s
, (xfs_extlen_t
)c
);
2012 if (type
== DBM_RTDATA
) {
2013 set_rdbmap((xfs_fsblock_t
)s
, (xfs_extlen_t
)c
,
2015 set_rinomap((xfs_fsblock_t
)s
, (xfs_extlen_t
)c
, id
);
2016 for (b
= (xfs_fsblock_t
)s
;
2017 blist_size
&& b
< s
+ c
;
2020 dbprintf(_("inode %lld block %lld at "
2022 id
->ino
, (xfs_fsblock_t
)b
, o
);
2025 agno
= XFS_FSB_TO_AGNO(mp
, (xfs_fsblock_t
)s
);
2026 agbno
= XFS_FSB_TO_AGBNO(mp
, (xfs_fsblock_t
)s
);
2027 set_dbmap(agno
, agbno
, (xfs_extlen_t
)c
, type
, iagno
,
2029 set_inomap(agno
, agbno
, (xfs_extlen_t
)c
, id
);
2030 for (b
= (xfs_fsblock_t
)s
;
2031 blist_size
&& b
< s
+ c
;
2032 b
++, o
++, agbno
++) {
2034 dbprintf(_("inode %lld block %lld at "
2036 id
->ino
, (xfs_fsblock_t
)b
, o
);
2046 struct xfs_dinode
*dip
,
2048 xfs_rfsblock_t
*totd
,
2049 xfs_rfsblock_t
*toti
,
2054 xfs_bmdr_block_t
*dib
;
2058 dib
= (xfs_bmdr_block_t
*)XFS_DFORK_PTR(dip
, whichfork
);
2059 if (be16_to_cpu(dib
->bb_level
) >= XFS_BM_MAXLEVELS(mp
, whichfork
)) {
2060 if (!sflag
|| id
->ilist
)
2061 dbprintf(_("level for ino %lld %s fork bmap root too "
2064 whichfork
== XFS_DATA_FORK
? _("data") : _("attr"),
2065 be16_to_cpu(dib
->bb_level
));
2069 if (be16_to_cpu(dib
->bb_numrecs
) >
2070 libxfs_bmdr_maxrecs(XFS_DFORK_SIZE(dip
, mp
, whichfork
),
2071 be16_to_cpu(dib
->bb_level
) == 0)) {
2072 if (!sflag
|| id
->ilist
)
2073 dbprintf(_("numrecs for ino %lld %s fork bmap root too "
2076 whichfork
== XFS_DATA_FORK
? _("data") : _("attr"),
2077 be16_to_cpu(dib
->bb_numrecs
));
2081 if (be16_to_cpu(dib
->bb_level
) == 0) {
2082 xfs_bmbt_rec_t
*rp
= xfs_bmdr_rec_addr(dib
, 1);
2083 process_bmbt_reclist(rp
, be16_to_cpu(dib
->bb_numrecs
), type
,
2085 *nex
+= be16_to_cpu(dib
->bb_numrecs
);
2088 pp
= xfs_bmdr_ptr_addr(dib
, 1, libxfs_bmdr_maxrecs(
2089 XFS_DFORK_SIZE(dip
, mp
, whichfork
), 0));
2090 for (i
= 0; i
< be16_to_cpu(dib
->bb_numrecs
); i
++)
2091 scan_lbtree(get_unaligned_be64(&pp
[i
]),
2092 be16_to_cpu(dib
->bb_level
),
2093 scanfunc_bmap
, type
, id
, totd
, toti
,
2095 whichfork
== XFS_DATA_FORK
?
2096 TYP_BMAPBTD
: TYP_BMAPBTA
);
2098 if (*nex
<= XFS_DFORK_SIZE(dip
, mp
, whichfork
) / sizeof(xfs_bmbt_rec_t
)) {
2099 if (!sflag
|| id
->ilist
)
2100 dbprintf(_("extent count for ino %lld %s fork too low "
2101 "(%d) for file format\n"),
2103 whichfork
== XFS_DATA_FORK
? _("data") : _("attr"),
2110 process_data_dir_v2(
2116 freetab_t
**freetabp
)
2118 xfs_dir2_dataptr_t addr
;
2119 xfs_dir2_data_free_t
*bf
;
2121 struct xfs_dir2_data_hdr
*block
;
2122 xfs_dir2_block_tail_t
*btp
= NULL
;
2125 struct xfs_dir2_data_hdr
*data
;
2127 xfs_dir2_data_entry_t
*dep
;
2128 xfs_dir2_data_free_t
*dfp
;
2129 xfs_dir2_data_unused_t
*dup
;
2136 xfs_dir2_leaf_entry_t
*lep
= NULL
;
2138 xfs_ino_t parent
= 0;
2143 struct xfs_name xname
;
2145 data
= iocur_top
->data
;
2146 block
= iocur_top
->data
;
2147 if (be32_to_cpu(block
->magic
) != XFS_DIR2_BLOCK_MAGIC
&&
2148 be32_to_cpu(data
->magic
) != XFS_DIR2_DATA_MAGIC
&&
2149 be32_to_cpu(block
->magic
) != XFS_DIR3_BLOCK_MAGIC
&&
2150 be32_to_cpu(data
->magic
) != XFS_DIR3_DATA_MAGIC
) {
2152 dbprintf(_("bad directory data magic # %#x for dir ino "
2154 be32_to_cpu(data
->magic
), id
->ino
, dabno
);
2158 db
= xfs_dir2_da_to_db(mp
->m_dir_geo
, dabno
);
2159 bf
= libxfs_dir2_data_bestfree_p(mp
, data
);
2160 ptr
= (char *)data
+ mp
->m_dir_geo
->data_entry_offset
;
2161 if (be32_to_cpu(block
->magic
) == XFS_DIR2_BLOCK_MAGIC
||
2162 be32_to_cpu(block
->magic
) == XFS_DIR3_BLOCK_MAGIC
) {
2163 btp
= xfs_dir2_block_tail_p(mp
->m_dir_geo
, block
);
2164 lep
= xfs_dir2_block_leaf_p(btp
);
2165 endptr
= (char *)lep
;
2166 if (endptr
<= ptr
|| endptr
> (char *)btp
) {
2167 endptr
= (char *)data
+ mp
->m_dir_geo
->blksize
;
2170 dbprintf(_("bad block directory tail for dir ino "
2176 endptr
= (char *)data
+ mp
->m_dir_geo
->blksize
;
2177 bf_err
= lastfree_err
= tag_err
= 0;
2178 count
= lastfree
= freeseen
= 0;
2179 if (be16_to_cpu(bf
[0].length
) == 0) {
2180 bf_err
+= be16_to_cpu(bf
[0].offset
) != 0;
2183 if (be16_to_cpu(bf
[1].length
) == 0) {
2184 bf_err
+= be16_to_cpu(bf
[1].offset
) != 0;
2187 if (be16_to_cpu(bf
[2].length
) == 0) {
2188 bf_err
+= be16_to_cpu(bf
[2].offset
) != 0;
2191 bf_err
+= be16_to_cpu(bf
[0].length
) < be16_to_cpu(bf
[1].length
);
2192 bf_err
+= be16_to_cpu(bf
[1].length
) < be16_to_cpu(bf
[2].length
);
2194 freetab
= *freetabp
;
2195 if (freetab
->naents
<= db
) {
2196 *freetabp
= freetab
=
2197 realloc(freetab
, FREETAB_SIZE(db
+ 1));
2198 for (i
= freetab
->naents
; i
< db
; i
++)
2199 freetab
->ents
[i
] = NULLDATAOFF
;
2200 freetab
->naents
= db
+ 1;
2202 if (freetab
->nents
< db
+ 1)
2203 freetab
->nents
= db
+ 1;
2204 freetab
->ents
[db
] = be16_to_cpu(bf
[0].length
);
2206 while (ptr
< endptr
) {
2207 dup
= (xfs_dir2_data_unused_t
*)ptr
;
2208 if (be16_to_cpu(dup
->freetag
) == XFS_DIR2_DATA_FREE_TAG
) {
2209 lastfree_err
+= lastfree
!= 0;
2210 tagp
= xfs_dir2_data_unused_tag_p(dup
);
2211 if ((be16_to_cpu(dup
->length
) & (XFS_DIR2_DATA_ALIGN
- 1)) ||
2212 be16_to_cpu(dup
->length
) == 0 ||
2213 (char *)tagp
>= endptr
) {
2215 dbprintf(_("dir %lld block %d bad free "
2223 tag_err
+= be16_to_cpu(*tagp
) != (char *)dup
- (char *)data
;
2224 dfp
= process_data_dir_v2_freefind(data
, dup
);
2226 i
= (int)(dfp
- bf
);
2227 bf_err
+= (freeseen
& (1 << i
)) != 0;
2230 bf_err
+= be16_to_cpu(dup
->length
) >
2231 be16_to_cpu(bf
[2].length
);
2232 ptr
+= be16_to_cpu(dup
->length
);
2236 dep
= (xfs_dir2_data_entry_t
*)dup
;
2237 if (dep
->namelen
== 0) {
2239 dbprintf(_("dir %lld block %d zero length entry "
2242 (int)((char *)dep
- (char *)data
));
2245 tagp
= libxfs_dir2_data_entry_tag_p(mp
, dep
);
2246 if ((char *)tagp
>= endptr
) {
2248 dbprintf(_("dir %lld block %d bad entry at %d\n"),
2250 (int)((char *)dep
- (char *)data
));
2254 tag_err
+= be16_to_cpu(*tagp
) != (char *)dep
- (char *)data
;
2255 addr
= xfs_dir2_db_off_to_dataptr(mp
->m_dir_geo
, db
,
2256 (char *)dep
- (char *)data
);
2257 xname
.name
= dep
->name
;
2258 xname
.len
= dep
->namelen
;
2259 dir_hash_add(libxfs_dir2_hashname(mp
, &xname
), addr
);
2260 ptr
+= libxfs_dir2_data_entsize(mp
, dep
->namelen
);
2263 lino
= be64_to_cpu(dep
->inumber
);
2264 cid
= find_inode(lino
, 1);
2266 dbprintf(_("dir %lld block %d entry %*.*s %lld\n"),
2267 id
->ino
, dabno
, dep
->namelen
, dep
->namelen
,
2273 dbprintf(_("dir %lld block %d entry %*.*s bad "
2274 "inode number %lld\n"),
2275 id
->ino
, dabno
, dep
->namelen
,
2276 dep
->namelen
, dep
->name
, lino
);
2279 if (dep
->namelen
== 2 && dep
->name
[0] == '.' &&
2280 dep
->name
[1] == '.') {
2283 dbprintf(_("multiple .. entries in dir "
2284 "%lld (%lld, %lld)\n"),
2285 id
->ino
, parent
, lino
);
2288 parent
= cid
? lino
: NULLFSINO
;
2290 } else if (dep
->namelen
!= 1 || dep
->name
[0] != '.') {
2294 addname_inode(cid
, (char *)dep
->name
,
2298 if (lino
!= id
->ino
) {
2300 dbprintf(_("dir %lld entry . inode "
2301 "number mismatch (%lld)\n"),
2308 if (be32_to_cpu(data
->magic
) == XFS_DIR2_BLOCK_MAGIC
||
2309 be32_to_cpu(data
->magic
) == XFS_DIR3_BLOCK_MAGIC
) {
2310 endptr
= (char *)data
+ mp
->m_dir_geo
->blksize
;
2311 for (i
= stale
= 0; lep
&& i
< be32_to_cpu(btp
->count
); i
++) {
2312 if ((char *)&lep
[i
] >= endptr
) {
2314 dbprintf(_("dir %lld block %d bad count "
2315 "%u\n"), id
->ino
, dabno
,
2316 be32_to_cpu(btp
->count
));
2320 if (be32_to_cpu(lep
[i
].address
) == XFS_DIR2_NULL_DATAPTR
)
2322 else if (dir_hash_see(be32_to_cpu(lep
[i
].hashval
),
2323 be32_to_cpu(lep
[i
].address
))) {
2325 dbprintf(_("dir %lld block %d extra leaf "
2328 be32_to_cpu(lep
[i
].hashval
),
2329 be32_to_cpu(lep
[i
].address
));
2334 bf_err
+= freeseen
!= 7;
2337 dbprintf(_("dir %lld block %d bad bestfree data\n"),
2341 if ((be32_to_cpu(data
->magic
) == XFS_DIR2_BLOCK_MAGIC
||
2342 be32_to_cpu(data
->magic
) == XFS_DIR3_BLOCK_MAGIC
) &&
2343 count
!= be32_to_cpu(btp
->count
) - be32_to_cpu(btp
->stale
)) {
2345 dbprintf(_("dir %lld block %d bad block tail count %d "
2347 id
->ino
, dabno
, be32_to_cpu(btp
->count
),
2348 be32_to_cpu(btp
->stale
));
2351 if ((be32_to_cpu(data
->magic
) == XFS_DIR2_BLOCK_MAGIC
||
2352 be32_to_cpu(data
->magic
) == XFS_DIR3_BLOCK_MAGIC
) &&
2353 stale
!= be32_to_cpu(btp
->stale
)) {
2355 dbprintf(_("dir %lld block %d bad stale tail count %d\n"),
2356 id
->ino
, dabno
, be32_to_cpu(btp
->stale
));
2361 dbprintf(_("dir %lld block %d consecutive free entries\n"),
2367 dbprintf(_("dir %lld block %d entry/unused tag "
2375 static xfs_dir2_data_free_t
*
2376 process_data_dir_v2_freefind(
2377 struct xfs_dir2_data_hdr
*data
,
2378 xfs_dir2_data_unused_t
*dup
)
2380 struct xfs_dir2_data_free
*bf
;
2381 struct xfs_dir2_data_free
*dfp
;
2382 xfs_dir2_data_aoff_t off
;
2384 off
= (xfs_dir2_data_aoff_t
)((char *)dup
- (char *)data
);
2385 bf
= libxfs_dir2_data_bestfree_p(mp
, data
);
2386 if (be16_to_cpu(dup
->length
) <
2387 be16_to_cpu(bf
[XFS_DIR2_DATA_FD_COUNT
- 1].length
))
2389 for (dfp
= bf
; dfp
< &bf
[XFS_DIR2_DATA_FD_COUNT
]; dfp
++) {
2390 if (be16_to_cpu(dfp
->offset
) == 0)
2392 if (be16_to_cpu(dfp
->offset
) == off
)
2400 struct xfs_dinode
*dip
,
2410 if (process_dir_v2(dip
, blkmap
, &dot
, &dotdot
, id
, &parent
))
2413 bno
= XFS_INO_TO_FSB(mp
, id
->ino
);
2415 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
2416 dbprintf(_("no . entry for directory %lld\n"), id
->ino
);
2420 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
2421 dbprintf(_("no .. entry for directory %lld\n"), id
->ino
);
2423 } else if (parent
== id
->ino
&& id
->ino
!= mp
->m_sb
.sb_rootino
) {
2424 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
2425 dbprintf(_(". and .. same for non-root directory %lld\n"),
2428 } else if (id
->ino
== mp
->m_sb
.sb_rootino
&& id
->ino
!= parent
) {
2429 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
2430 dbprintf(_("root directory %lld has .. %lld\n"), id
->ino
,
2433 } else if (parent
!= NULLFSINO
&& id
->ino
!= parent
)
2434 addparent_inode(id
, parent
);
2439 struct xfs_dinode
*dip
,
2446 xfs_fileoff_t last
= 0;
2447 xfs_fsize_t size
= be64_to_cpu(dip
->di_size
);
2450 last
= blkmap_last_off(blkmap
);
2451 if (size
<= XFS_DFORK_DSIZE(dip
, mp
) &&
2452 dip
->di_format
== XFS_DINODE_FMT_LOCAL
)
2453 *parent
= process_sf_dir_v2(dip
, dot
, dotdot
, id
);
2454 else if (last
== mp
->m_dir_geo
->fsbcount
&&
2455 (dip
->di_format
== XFS_DINODE_FMT_EXTENTS
||
2456 dip
->di_format
== XFS_DINODE_FMT_BTREE
))
2457 *parent
= process_block_dir_v2(blkmap
, dot
, dotdot
, id
);
2458 else if (last
>= mp
->m_dir_geo
->leafblk
+ mp
->m_dir_geo
->fsbcount
&&
2459 (dip
->di_format
== XFS_DINODE_FMT_EXTENTS
||
2460 dip
->di_format
== XFS_DINODE_FMT_BTREE
))
2461 *parent
= process_leaf_node_dir_v2(blkmap
, dot
, dotdot
, id
, size
);
2463 dbprintf(_("bad size (%lld) or format (%d) for directory inode "
2465 size
, dip
->di_format
, id
->ino
);
2476 struct xfs_dinode
*dip
,
2478 xfs_rfsblock_t
*totd
,
2479 xfs_rfsblock_t
*toti
,
2485 xfs_extnum_t max_nex
;
2487 rp
= (xfs_bmbt_rec_t
*)XFS_DFORK_PTR(dip
, whichfork
);
2488 *nex
= xfs_dfork_nextents(dip
, whichfork
);
2489 max_nex
= xfs_iext_max_nextents(
2490 xfs_dinode_has_large_extent_counts(dip
),
2492 if (*nex
> max_nex
|| *nex
> XFS_DFORK_SIZE(dip
, mp
, whichfork
) /
2493 sizeof(xfs_bmbt_rec_t
)) {
2494 if (!sflag
|| id
->ilist
)
2495 dbprintf(_("bad number of extents %llu for inode %lld\n"),
2496 (unsigned long long)*nex
, id
->ino
);
2500 process_bmbt_reclist(rp
, *nex
, type
, id
, totd
, blkmapp
);
2507 struct xfs_dinode
*dip
,
2511 xfs_fsblock_t bno
= 0;
2512 inodata_t
*id
= NULL
;
2514 xfs_extnum_t nextents
= 0;
2515 xfs_extnum_t dnextents
;
2517 xfs_rfsblock_t totblocks
;
2518 xfs_rfsblock_t totdblocks
= 0;
2519 xfs_rfsblock_t totiblocks
= 0;
2521 xfs_extnum_t anextents
= 0;
2522 xfs_extnum_t danextents
;
2523 xfs_rfsblock_t atotdblocks
= 0;
2524 xfs_rfsblock_t atotiblocks
= 0;
2531 uint64_t diflags2
= 0;
2536 static char okfmts
[] = {
2537 0, /* type 0 unused */
2538 1 << XFS_DINODE_FMT_DEV
, /* FIFO */
2539 1 << XFS_DINODE_FMT_DEV
, /* CHR */
2540 0, /* type 3 unused */
2541 (1 << XFS_DINODE_FMT_LOCAL
) |
2542 (1 << XFS_DINODE_FMT_EXTENTS
) |
2543 (1 << XFS_DINODE_FMT_BTREE
), /* DIR */
2544 0, /* type 5 unused */
2545 1 << XFS_DINODE_FMT_DEV
, /* BLK */
2546 0, /* type 7 unused */
2547 (1 << XFS_DINODE_FMT_EXTENTS
) |
2548 (1 << XFS_DINODE_FMT_BTREE
), /* REG */
2549 0, /* type 9 unused */
2550 (1 << XFS_DINODE_FMT_LOCAL
) |
2551 (1 << XFS_DINODE_FMT_EXTENTS
), /* LNK */
2552 0, /* type 11 unused */
2553 1 << XFS_DINODE_FMT_DEV
, /* SOCK */
2554 0, /* type 13 unused */
2555 1 << XFS_DINODE_FMT_UUID
, /* MNT */
2556 0 /* type 15 unused */
2558 static char *fmtnames
[] = {
2559 "dev", "local", "extents", "btree", "uuid"
2562 ino
= XFS_AGINO_TO_INO(mp
, be32_to_cpu(agf
->agf_seqno
), agino
);
2564 id
= find_inode(ino
, 1);
2565 bno
= XFS_INO_TO_FSB(mp
, ino
);
2568 v
= (!sflag
|| (id
&& id
->ilist
) || CHECK_BLIST(bno
));
2569 if (dip
->di_magic
!= cpu_to_be16(XFS_DINODE_MAGIC
)) {
2571 dbprintf(_("bad magic number %#x for inode %lld\n"),
2572 be16_to_cpu(dip
->di_magic
), ino
);
2576 if (!libxfs_dinode_good_version(mp
, dip
->di_version
)) {
2578 dbprintf(_("bad version number %#x for inode %lld\n"),
2579 dip
->di_version
, ino
);
2583 if (dip
->di_version
== 1) {
2584 nlink
= be16_to_cpu(dip
->di_metatype
);
2587 nlink
= be32_to_cpu(dip
->di_nlink
);
2588 prid
= (xfs_dqid_t
)be16_to_cpu(dip
->di_projid_hi
) << 16 |
2589 be16_to_cpu(dip
->di_projid_lo
);
2591 uid
= be32_to_cpu(dip
->di_uid
);
2592 gid
= be32_to_cpu(dip
->di_gid
);
2593 diflags
= be16_to_cpu(dip
->di_flags
);
2594 if (xfs_has_v3inodes(mp
))
2595 diflags2
= be64_to_cpu(dip
->di_flags2
);
2597 if (be64_to_cpu(dip
->di_nblocks
) != 0) {
2599 dbprintf(_("bad nblocks %lld for free inode "
2601 be64_to_cpu(dip
->di_nblocks
), ino
);
2606 dbprintf(_("bad nlink %d for free inode %lld\n"),
2610 if (dip
->di_mode
!= 0) {
2612 dbprintf(_("bad mode %#o for free inode %lld\n"),
2613 be16_to_cpu(dip
->di_mode
), ino
);
2619 if (be32_to_cpu(dip
->di_next_unlinked
) != NULLAGINO
) {
2621 dbprintf(_("bad next unlinked %#x for inode %lld\n"),
2622 be32_to_cpu(dip
->di_next_unlinked
), ino
);
2626 * di_mode is a 16-bit uint so no need to check the < 0 case
2628 mode
= be16_to_cpu(dip
->di_mode
);
2629 if ((((mode
& S_IFMT
) >> 12) > 15) ||
2630 (!(okfmts
[(mode
& S_IFMT
) >> 12] & (1 << dip
->di_format
)))) {
2632 dbprintf(_("bad format %d for inode %lld type %#o\n"),
2633 dip
->di_format
, id
->ino
, mode
& S_IFMT
);
2637 if ((unsigned int)XFS_DFORK_ASIZE(dip
, mp
) >= XFS_LITINO(mp
)) {
2639 dbprintf(_("bad fork offset %d for inode %lld\n"),
2640 dip
->di_forkoff
, id
->ino
);
2644 if ((unsigned int)dip
->di_aformat
> XFS_DINODE_FMT_BTREE
) {
2646 dbprintf(_("bad attribute format %d for inode %lld\n"),
2647 dip
->di_aformat
, id
->ino
);
2652 dnextents
= xfs_dfork_data_extents(dip
);
2653 danextents
= xfs_dfork_attr_extents(dip
);
2655 if (verbose
|| (id
&& id
->ilist
) || CHECK_BLIST(bno
))
2656 dbprintf(_("inode %lld mode %#o fmt %s "
2658 "nex %d anex %d nblk %lld sz %lld%s%s%s%s%s%s%s\n"),
2659 id
->ino
, mode
, fmtnames
[(int)dip
->di_format
],
2660 fmtnames
[(int)dip
->di_aformat
],
2661 dnextents
, danextents
,
2662 be64_to_cpu(dip
->di_nblocks
), be64_to_cpu(dip
->di_size
),
2663 diflags
& XFS_DIFLAG_REALTIME
? " rt" : "",
2664 diflags
& XFS_DIFLAG_PREALLOC
? " pre" : "",
2665 diflags
& XFS_DIFLAG_IMMUTABLE
? " imm" : "",
2666 diflags
& XFS_DIFLAG_APPEND
? " app" : "",
2667 diflags
& XFS_DIFLAG_SYNC
? " syn" : "",
2668 diflags
& XFS_DIFLAG_NOATIME
? " noa" : "",
2669 diflags
& XFS_DIFLAG_NODUMP
? " nod" : "");
2671 switch (mode
& S_IFMT
) {
2674 if (dip
->di_format
== XFS_DINODE_FMT_LOCAL
)
2676 blkmap
= blkmap_alloc(dnextents
);
2679 if (diflags
& XFS_DIFLAG_REALTIME
)
2681 else if (id
->ino
== mp
->m_sb
.sb_rbmino
) {
2682 type
= DBM_RTBITMAP
;
2683 blkmap
= blkmap_alloc(dnextents
);
2685 } else if (id
->ino
== mp
->m_sb
.sb_rsumino
) {
2687 blkmap
= blkmap_alloc(dnextents
);
2690 else if (id
->ino
== mp
->m_sb
.sb_uquotino
||
2691 id
->ino
== mp
->m_sb
.sb_gquotino
||
2692 id
->ino
== mp
->m_sb
.sb_pquotino
) {
2694 blkmap
= blkmap_alloc(dnextents
);
2699 if (mode
& (S_ISUID
| S_ISGID
))
2711 id
->isreflink
= !!(diflags2
& XFS_DIFLAG2_REFLINK
);
2712 setlink_inode(id
, nlink
, type
== DBM_DIR
, security
);
2714 switch (dip
->di_format
) {
2715 case XFS_DINODE_FMT_LOCAL
:
2716 process_lclinode(id
, dip
, type
, &totdblocks
, &totiblocks
,
2717 &nextents
, &blkmap
, XFS_DATA_FORK
);
2719 case XFS_DINODE_FMT_EXTENTS
:
2720 process_exinode(id
, dip
, type
, &totdblocks
, &totiblocks
,
2721 &nextents
, &blkmap
, XFS_DATA_FORK
);
2723 case XFS_DINODE_FMT_BTREE
:
2724 process_btinode(id
, dip
, type
, &totdblocks
, &totiblocks
,
2725 &nextents
, &blkmap
, XFS_DATA_FORK
);
2728 if (dip
->di_forkoff
) {
2729 sbversion
|= XFS_SB_VERSION_ATTRBIT
;
2730 switch (dip
->di_aformat
) {
2731 case XFS_DINODE_FMT_LOCAL
:
2732 process_lclinode(id
, dip
, DBM_ATTR
, &atotdblocks
,
2733 &atotiblocks
, &anextents
, NULL
, XFS_ATTR_FORK
);
2735 case XFS_DINODE_FMT_EXTENTS
:
2736 process_exinode(id
, dip
, DBM_ATTR
, &atotdblocks
,
2737 &atotiblocks
, &anextents
, NULL
, XFS_ATTR_FORK
);
2739 case XFS_DINODE_FMT_BTREE
:
2740 process_btinode(id
, dip
, DBM_ATTR
, &atotdblocks
,
2741 &atotiblocks
, &anextents
, NULL
, XFS_ATTR_FORK
);
2745 if (qgdo
|| qpdo
|| qudo
) {
2753 bc
= totdblocks
+ totiblocks
+
2754 atotdblocks
+ atotiblocks
;
2758 bc
= totiblocks
+ atotdblocks
+ atotiblocks
;
2766 quota_add(&prid
, &gid
, &uid
, 0, bc
, ic
, rc
);
2768 totblocks
= totdblocks
+ totiblocks
+ atotdblocks
+ atotiblocks
;
2769 if (totblocks
!= be64_to_cpu(dip
->di_nblocks
)) {
2771 dbprintf(_("bad nblocks %lld for inode %lld, counted "
2773 be64_to_cpu(dip
->di_nblocks
), id
->ino
, totblocks
);
2776 if (nextents
!= dnextents
) {
2778 dbprintf(_("bad nextents %d for inode %lld, counted %d\n"),
2779 dnextents
, id
->ino
, nextents
);
2782 if (anextents
!= danextents
) {
2784 dbprintf(_("bad anextents %d for inode %lld, counted "
2786 danextents
, id
->ino
, anextents
);
2789 if (type
== DBM_DIR
)
2790 process_dir(dip
, blkmap
, id
);
2791 else if (type
== DBM_RTBITMAP
)
2792 process_rtbitmap(blkmap
);
2793 else if (type
== DBM_RTSUM
)
2794 process_rtsummary(blkmap
);
2796 * If the CHKD flag is not set, this can legitimately contain garbage;
2797 * xfs_repair may have cleared that bit.
2799 else if (type
== DBM_QUOTA
) {
2800 if (id
->ino
== mp
->m_sb
.sb_uquotino
&&
2801 (mp
->m_sb
.sb_qflags
& XFS_UQUOTA_ACCT
) &&
2802 (mp
->m_sb
.sb_qflags
& XFS_UQUOTA_CHKD
))
2803 process_quota(IS_USER_QUOTA
, id
, blkmap
);
2804 else if (id
->ino
== mp
->m_sb
.sb_gquotino
&&
2805 (mp
->m_sb
.sb_qflags
& XFS_GQUOTA_ACCT
) &&
2806 (mp
->m_sb
.sb_qflags
& XFS_GQUOTA_CHKD
))
2807 process_quota(IS_GROUP_QUOTA
, id
, blkmap
);
2808 else if (id
->ino
== mp
->m_sb
.sb_pquotino
&&
2809 (mp
->m_sb
.sb_qflags
& XFS_PQUOTA_ACCT
) &&
2810 (mp
->m_sb
.sb_qflags
& XFS_PQUOTA_CHKD
))
2811 process_quota(IS_PROJECT_QUOTA
, id
, blkmap
);
2814 blkmap_free(blkmap
);
2821 struct xfs_dinode
*dip
,
2823 xfs_rfsblock_t
*totd
,
2824 xfs_rfsblock_t
*toti
,
2829 struct xfs_attr_sf_hdr
*hdr
;
2832 bno
= XFS_INO_TO_FSB(mp
, id
->ino
);
2833 if (whichfork
== XFS_DATA_FORK
&& be64_to_cpu(dip
->di_size
) >
2834 XFS_DFORK_DSIZE(dip
, mp
)) {
2835 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
2836 dbprintf(_("local inode %lld data is too large (size "
2838 id
->ino
, be64_to_cpu(dip
->di_size
));
2841 else if (whichfork
== XFS_ATTR_FORK
) {
2842 hdr
= XFS_DFORK_APTR(dip
);
2843 if (be16_to_cpu(hdr
->totsize
) > XFS_DFORK_ASIZE(dip
, mp
)) {
2844 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
2845 dbprintf(_("local inode %lld attr is too large "
2847 id
->ino
, be16_to_cpu(hdr
->totsize
));
2854 process_leaf_node_dir_v2(
2859 xfs_fsize_t dirsize
)
2874 v2
= verbose
|| id
->ilist
;
2877 freetab
= malloc(FREETAB_SIZE(dirsize
/ mp
->m_dir_geo
->blksize
));
2878 freetab
->naents
= (int)(dirsize
/ mp
->m_dir_geo
->blksize
);
2880 for (i
= 0; i
< freetab
->naents
; i
++)
2881 freetab
->ents
[i
] = NULLDATAOFF
;
2883 while ((dbno
= blkmap_next_off(blkmap
, dbno
, &t
)) != NULLFILEOFF
) {
2884 nex
= blkmap_getn(blkmap
, dbno
, mp
->m_dir_geo
->fsbcount
, &bmp
);
2886 for (v
= v2
, i
= 0; !v
&& i
< nex
; i
++) {
2887 for (b
= bmp
[i
].startblock
;
2888 !v
&& b
< bmp
[i
].startblock
+ bmp
[i
].blockcount
;
2893 dbprintf(_("dir inode %lld block %u=%llu\n"), id
->ino
,
2895 (xfs_fsblock_t
)bmp
->startblock
);
2898 make_bbmap(&bbmap
, nex
, bmp
);
2899 set_cur(&typtab
[TYP_DIR2
], XFS_FSB_TO_DADDR(mp
, bmp
->startblock
),
2900 mp
->m_dir_geo
->fsbcount
* blkbb
, DB_RING_IGN
,
2901 nex
> 1 ? &bbmap
: NULL
);
2903 if (iocur_top
->data
== NULL
) {
2905 dbprintf(_("can't read block %u for directory "
2907 (uint32_t)dbno
, id
->ino
);
2910 dbno
+= mp
->m_dir_geo
->fsbcount
- 1;
2913 if (dbno
< mp
->m_dir_geo
->leafblk
) {
2914 lino
= process_data_dir_v2(dot
, dotdot
, id
, v
,
2915 (xfs_dablk_t
)dbno
, &freetab
);
2919 dbprintf(_("multiple .. entries "
2926 } else if (dbno
< mp
->m_dir_geo
->freeblk
) {
2927 process_leaf_node_dir_v2_int(id
, v
, (xfs_dablk_t
)dbno
,
2930 process_leaf_node_dir_v2_free(id
, v
, (xfs_dablk_t
)dbno
,
2934 dbno
+= mp
->m_dir_geo
->fsbcount
- 1;
2936 dir_hash_check(id
, v
);
2938 for (i
= 0; i
< freetab
->nents
; i
++) {
2939 if (freetab
->ents
[i
] != NULLDATAOFF
) {
2941 dbprintf(_("missing free index for data block %d "
2942 "in dir ino %lld\n"),
2943 xfs_dir2_db_to_da(mp
->m_dir_geo
, i
), id
->ino
);
2952 process_leaf_node_dir_v3_free(
2958 xfs_dir2_data_off_t ent
;
2959 struct xfs_dir3_free
*free
;
2964 free
= iocur_top
->data
;
2965 maxent
= mp
->m_dir_geo
->free_max_bests
;
2966 if (be32_to_cpu(free
->hdr
.firstdb
) != xfs_dir2_da_to_db(mp
->m_dir_geo
,
2967 dabno
- mp
->m_dir_geo
->freeblk
) * maxent
) {
2969 dbprintf(_("bad free block firstdb %d for dir ino %lld "
2971 be32_to_cpu(free
->hdr
.firstdb
), id
->ino
, dabno
);
2975 if (be32_to_cpu(free
->hdr
.nvalid
) > maxent
||
2976 be32_to_cpu(free
->hdr
.nused
) > maxent
||
2977 be32_to_cpu(free
->hdr
.nused
) >
2978 be32_to_cpu(free
->hdr
.nvalid
)) {
2980 dbprintf(_("bad free block nvalid/nused %d/%d for dir "
2981 "ino %lld block %d\n"),
2982 be32_to_cpu(free
->hdr
.nvalid
),
2983 be32_to_cpu(free
->hdr
.nused
), id
->ino
, dabno
);
2987 for (used
= i
= 0; i
< be32_to_cpu(free
->hdr
.nvalid
); i
++) {
2988 if (freetab
->nents
<= be32_to_cpu(free
->hdr
.firstdb
) + i
)
2991 ent
= freetab
->ents
[be32_to_cpu(free
->hdr
.firstdb
) + i
];
2992 if (ent
!= be16_to_cpu(free
->bests
[i
])) {
2994 dbprintf(_("bad free block ent %d is %d should "
2995 "be %d for dir ino %lld block %d\n"),
2996 i
, be16_to_cpu(free
->bests
[i
]), ent
,
3000 if (be16_to_cpu(free
->bests
[i
]) != NULLDATAOFF
)
3002 if (ent
!= NULLDATAOFF
)
3003 freetab
->ents
[be32_to_cpu(free
->hdr
.firstdb
) + i
] =
3006 if (used
!= be32_to_cpu(free
->hdr
.nused
)) {
3008 dbprintf(_("bad free block nused %d should be %d for dir "
3009 "ino %lld block %d\n"),
3010 be32_to_cpu(free
->hdr
.nused
), used
, id
->ino
,
3017 process_leaf_node_dir_v2_free(
3023 xfs_dir2_data_off_t ent
;
3024 xfs_dir2_free_t
*free
;
3029 free
= iocur_top
->data
;
3030 if (be32_to_cpu(free
->hdr
.magic
) != XFS_DIR2_FREE_MAGIC
&&
3031 be32_to_cpu(free
->hdr
.magic
) != XFS_DIR3_FREE_MAGIC
) {
3033 dbprintf(_("bad free block magic # %#x for dir ino %lld "
3035 be32_to_cpu(free
->hdr
.magic
), id
->ino
, dabno
);
3039 if (be32_to_cpu(free
->hdr
.magic
) == XFS_DIR3_FREE_MAGIC
) {
3040 process_leaf_node_dir_v3_free(id
, v
, dabno
, freetab
);
3043 maxent
= mp
->m_dir_geo
->free_max_bests
;
3044 if (be32_to_cpu(free
->hdr
.firstdb
) != xfs_dir2_da_to_db(mp
->m_dir_geo
,
3045 dabno
- mp
->m_dir_geo
->freeblk
) * maxent
) {
3047 dbprintf(_("bad free block firstdb %d for dir ino %lld "
3049 be32_to_cpu(free
->hdr
.firstdb
), id
->ino
, dabno
);
3053 if (be32_to_cpu(free
->hdr
.nvalid
) > maxent
||
3054 be32_to_cpu(free
->hdr
.nused
) > maxent
||
3055 be32_to_cpu(free
->hdr
.nused
) >
3056 be32_to_cpu(free
->hdr
.nvalid
)) {
3058 dbprintf(_("bad free block nvalid/nused %d/%d for dir "
3059 "ino %lld block %d\n"),
3060 be32_to_cpu(free
->hdr
.nvalid
),
3061 be32_to_cpu(free
->hdr
.nused
), id
->ino
, dabno
);
3065 for (used
= i
= 0; i
< be32_to_cpu(free
->hdr
.nvalid
); i
++) {
3066 if (freetab
->nents
<= be32_to_cpu(free
->hdr
.firstdb
) + i
)
3069 ent
= freetab
->ents
[be32_to_cpu(free
->hdr
.firstdb
) + i
];
3070 if (ent
!= be16_to_cpu(free
->bests
[i
])) {
3072 dbprintf(_("bad free block ent %d is %d should "
3073 "be %d for dir ino %lld block %d\n"),
3074 i
, be16_to_cpu(free
->bests
[i
]), ent
,
3078 if (be16_to_cpu(free
->bests
[i
]) != NULLDATAOFF
)
3080 if (ent
!= NULLDATAOFF
)
3081 freetab
->ents
[be32_to_cpu(free
->hdr
.firstdb
) + i
] =
3084 if (used
!= be32_to_cpu(free
->hdr
.nused
)) {
3086 dbprintf(_("bad free block nused %d should be %d for dir "
3087 "ino %lld block %d\n"),
3088 be32_to_cpu(free
->hdr
.nused
), used
, id
->ino
,
3095 * Get address of the bestcount field in the single-leaf block.
3098 xfs_dir3_leaf_ents_count(struct xfs_dir2_leaf
*lp
)
3100 if (lp
->hdr
.info
.magic
== cpu_to_be16(XFS_DIR3_LEAF1_MAGIC
) ||
3101 lp
->hdr
.info
.magic
== cpu_to_be16(XFS_DIR3_LEAFN_MAGIC
)) {
3102 struct xfs_dir3_leaf
*lp3
= (struct xfs_dir3_leaf
*)lp
;
3104 return be16_to_cpu(lp3
->hdr
.count
);
3106 return be16_to_cpu(lp
->hdr
.count
);
3110 process_leaf_node_dir_v2_int(
3118 xfs_dir2_leaf_t
*leaf
;
3119 struct xfs_dir3_leaf
*leaf3
= NULL
;
3120 xfs_dir2_leaf_entry_t
*lep
;
3121 xfs_dir2_leaf_tail_t
*ltp
;
3122 xfs_da_intnode_t
*node
;
3124 struct xfs_da3_icnode_hdr nodehdr
;
3125 struct xfs_dir3_icleaf_hdr leafhdr
;
3127 leaf
= iocur_top
->data
;
3128 libxfs_dir2_leaf_hdr_from_disk(mp
, &leafhdr
, leaf
);
3130 switch (be16_to_cpu(leaf
->hdr
.info
.magic
)) {
3131 case XFS_DIR3_LEAF1_MAGIC
:
3132 case XFS_DIR3_LEAFN_MAGIC
:
3133 case XFS_DA3_NODE_MAGIC
:
3134 leaf3
= iocur_top
->data
;
3137 switch (be16_to_cpu(leaf
->hdr
.info
.magic
)) {
3138 case XFS_DIR2_LEAF1_MAGIC
:
3139 case XFS_DIR3_LEAF1_MAGIC
:
3140 if (be32_to_cpu(leaf
->hdr
.info
.forw
) ||
3141 be32_to_cpu(leaf
->hdr
.info
.back
)) {
3143 dbprintf(_("bad leaf block forw/back pointers "
3144 "%d/%d for dir ino %lld block %d\n"),
3145 be32_to_cpu(leaf
->hdr
.info
.forw
),
3146 be32_to_cpu(leaf
->hdr
.info
.back
),
3150 if (dabno
!= mp
->m_dir_geo
->leafblk
) {
3152 dbprintf(_("single leaf block for dir ino %lld "
3153 "block %d should be at block %d\n"),
3155 (xfs_dablk_t
)mp
->m_dir_geo
->leafblk
);
3158 ltp
= xfs_dir2_leaf_tail_p(mp
->m_dir_geo
, leaf
);
3159 lbp
= xfs_dir2_leaf_bests_p(ltp
);
3160 for (i
= 0; i
< be32_to_cpu(ltp
->bestcount
); i
++) {
3161 if (freetab
->nents
<= i
|| freetab
->ents
[i
] !=
3162 be16_to_cpu(lbp
[i
])) {
3164 dbprintf(_("bestfree %d for dir ino %lld "
3165 "block %d doesn't match table "
3167 freetab
->nents
<= i
?
3171 xfs_dir2_db_to_da(mp
->m_dir_geo
, i
),
3172 be16_to_cpu(lbp
[i
]));
3174 if (freetab
->nents
> i
)
3175 freetab
->ents
[i
] = NULLDATAOFF
;
3178 case XFS_DIR2_LEAFN_MAGIC
:
3179 case XFS_DIR3_LEAFN_MAGIC
:
3180 /* if it's at the root location then we can check the
3181 * pointers are null XXX */
3183 case XFS_DA_NODE_MAGIC
:
3184 case XFS_DA3_NODE_MAGIC
:
3185 node
= iocur_top
->data
;
3186 libxfs_da3_node_hdr_from_disk(mp
, &nodehdr
, node
);
3187 if (nodehdr
.level
< 1 || nodehdr
.level
> XFS_DA_NODE_MAXDEPTH
) {
3189 dbprintf(_("bad node block level %d for dir ino "
3191 nodehdr
.level
, id
->ino
,
3198 dbprintf(_("bad directory data magic # %#x for dir ino "
3200 be16_to_cpu(leaf
->hdr
.info
.magic
), id
->ino
,
3206 for (i
= stale
= 0; i
< xfs_dir3_leaf_ents_count(leaf
); i
++) {
3207 if (be32_to_cpu(lep
[i
].address
) == XFS_DIR2_NULL_DATAPTR
)
3209 else if (dir_hash_see(be32_to_cpu(lep
[i
].hashval
),
3210 be32_to_cpu(lep
[i
].address
))) {
3212 dbprintf(_("dir %lld block %d extra leaf entry "
3213 "%x %x\n"), id
->ino
, dabno
,
3214 be32_to_cpu(lep
[i
].hashval
),
3215 be32_to_cpu(lep
[i
].address
));
3219 if (leaf3
&& stale
!= be16_to_cpu(leaf3
->hdr
.stale
)) {
3221 dbprintf(_("dir3 %lld block %d stale mismatch "
3223 id
->ino
, dabno
, stale
,
3224 be16_to_cpu(leaf3
->hdr
.stale
));
3226 } else if (!leaf3
&& stale
!= be16_to_cpu(leaf
->hdr
.stale
)) {
3228 dbprintf(_("dir %lld block %d stale mismatch "
3230 id
->ino
, dabno
, stale
,
3231 be16_to_cpu(leaf
->hdr
.stale
));
3244 struct xfs_dqblk
*dqb
;
3246 uint8_t exp_flags
= 0;
3257 exp_flags
= XFS_DQTYPE_USER
;
3259 case IS_PROJECT_QUOTA
:
3261 exp_flags
= XFS_DQTYPE_PROJ
;
3263 case IS_GROUP_QUOTA
:
3265 exp_flags
= XFS_DQTYPE_GROUP
;
3271 perblock
= (uint
)(mp
->m_sb
.sb_blocksize
/ sizeof(*dqb
));
3274 while ((qbno
= blkmap_next_off(blkmap
, qbno
, &t
)) != NULLFILEOFF
) {
3275 bno
= blkmap_get(blkmap
, qbno
);
3276 dqid
= (xfs_dqid_t
)qbno
* perblock
;
3277 cb
= CHECK_BLIST(bno
);
3278 scicb
= !sflag
|| id
->ilist
|| cb
;
3280 set_cur(&typtab
[TYP_DQBLK
], XFS_FSB_TO_DADDR(mp
, bno
), blkbb
,
3282 if ((dqb
= iocur_top
->data
) == NULL
) {
3284 dbprintf(_("can't read block %lld for %s quota "
3285 "inode (fsblock %lld)\n"),
3286 (xfs_fileoff_t
)qbno
, s
,
3287 (xfs_fsblock_t
)bno
);
3292 for (i
= 0; i
< perblock
; i
++, dqid
++, dqb
++) {
3293 if (verbose
|| id
->ilist
|| cb
)
3294 dbprintf(_("%s dqblk %lld entry %d id %u bc "
3295 "%lld ic %lld rc %lld\n"),
3296 s
, (xfs_fileoff_t
)qbno
, i
, dqid
,
3297 be64_to_cpu(dqb
->dd_diskdq
.d_bcount
),
3298 be64_to_cpu(dqb
->dd_diskdq
.d_icount
),
3299 be64_to_cpu(dqb
->dd_diskdq
.d_rtbcount
));
3300 if (be16_to_cpu(dqb
->dd_diskdq
.d_magic
) != XFS_DQUOT_MAGIC
) {
3302 dbprintf(_("bad magic number %#x for %s "
3303 "dqblk %lld entry %d id %u\n"),
3304 be16_to_cpu(dqb
->dd_diskdq
.d_magic
), s
,
3305 (xfs_fileoff_t
)qbno
, i
, dqid
);
3309 if (dqb
->dd_diskdq
.d_version
!= XFS_DQUOT_VERSION
) {
3311 dbprintf(_("bad version number %#x for "
3312 "%s dqblk %lld entry %d id "
3314 dqb
->dd_diskdq
.d_version
, s
,
3315 (xfs_fileoff_t
)qbno
, i
, dqid
);
3319 if (dqb
->dd_diskdq
.d_type
& ~XFS_DQTYPE_ANY
) {
3321 dbprintf(_("bad flags %#x for %s dqblk "
3322 "%lld entry %d id %u\n"),
3323 dqb
->dd_diskdq
.d_type
, s
,
3324 (xfs_fileoff_t
)qbno
, i
, dqid
);
3328 if ((dqb
->dd_diskdq
.d_type
& XFS_DQTYPE_REC_MASK
)
3331 dbprintf(_("wrong type %#x for %s dqblk "
3332 "%lld entry %d id %u\n"),
3333 dqb
->dd_diskdq
.d_type
&
3334 XFS_DQTYPE_REC_MASK
, s
,
3335 (xfs_fileoff_t
)qbno
, i
, dqid
);
3339 if (be32_to_cpu(dqb
->dd_diskdq
.d_id
) != dqid
) {
3341 dbprintf(_("bad id %u for %s dqblk %lld "
3342 "entry %d id %u\n"),
3343 be32_to_cpu(dqb
->dd_diskdq
.d_id
), s
,
3344 (xfs_fileoff_t
)qbno
, i
, dqid
);
3348 quota_add((qtype
== IS_PROJECT_QUOTA
) ? &dqid
: NULL
,
3349 (qtype
== IS_GROUP_QUOTA
) ? &dqid
: NULL
,
3350 (qtype
== IS_USER_QUOTA
) ? &dqid
: NULL
,
3352 be64_to_cpu(dqb
->dd_diskdq
.d_bcount
),
3353 be64_to_cpu(dqb
->dd_diskdq
.d_icount
),
3354 be64_to_cpu(dqb
->dd_diskdq
.d_rtbcount
));
3362 struct xfs_mount
*mp
,
3363 union xfs_suminfo_raw
*info
,
3364 xfs_rtsumoff_t index
)
3366 union xfs_suminfo_raw
*p
= info
+ index
;
3377 xfs_fileoff_t bmbno
;
3384 xfs_rfsblock_t rtbno
;
3388 xfs_rtword_t
*words
;
3390 bitsperblock
= mp
->m_blockwsize
<< XFS_NBWORDLOG
;
3391 words
= malloc(mp
->m_blockwsize
<< XFS_WORDLOG
);
3393 dbprintf(_("could not allocate rtwords buffer\n"));
3397 bit
= extno
= prevbit
= start_bmbno
= start_bit
= 0;
3398 bmbno
= NULLFILEOFF
;
3399 while ((bmbno
= blkmap_next_off(blkmap
, bmbno
, &t
)) != NULLFILEOFF
) {
3400 struct xfs_rtalloc_args args
= {
3403 xfs_rtword_t
*incore
= words
;
3406 bno
= blkmap_get(blkmap
, bmbno
);
3407 if (bno
== NULLFSBLOCK
) {
3409 dbprintf(_("block %lld for rtbitmap inode is "
3411 (xfs_fileoff_t
)bmbno
);
3416 set_cur(&typtab
[TYP_RTBITMAP
], XFS_FSB_TO_DADDR(mp
, bno
), blkbb
,
3418 if (!iocur_top
->bp
) {
3420 dbprintf(_("can't read block %lld for rtbitmap "
3422 (xfs_fileoff_t
)bmbno
);
3428 args
.rbmbp
= iocur_top
->bp
;
3429 for (i
= 0; i
< mp
->m_blockwsize
; i
++, incore
++)
3430 *incore
= libxfs_rtbitmap_getword(&args
, i
);
3433 bit
< bitsperblock
&& extno
< mp
->m_sb
.sb_rextents
;
3435 if (xfs_isset(words
, bit
)) {
3436 rtbno
= extno
* mp
->m_sb
.sb_rextsize
;
3437 set_rdbmap(rtbno
, mp
->m_sb
.sb_rextsize
,
3441 start_bmbno
= (int)bmbno
;
3445 } else if (prevbit
== 1) {
3446 len
= ((int)bmbno
- start_bmbno
) *
3447 bitsperblock
+ (bit
- start_bit
);
3448 log
= libxfs_highbit64(len
);
3449 offs
= xfs_rtsumoffs(mp
, log
, start_bmbno
);
3450 inc_sumcount(mp
, sumcompute
, offs
);
3455 if (extno
== mp
->m_sb
.sb_rextents
)
3459 len
= ((int)bmbno
- start_bmbno
) * bitsperblock
+
3461 log
= libxfs_highbit64(len
);
3462 offs
= xfs_rtsumoffs(mp
, log
, start_bmbno
);
3463 inc_sumcount(mp
, sumcompute
, offs
);
3473 union xfs_suminfo_raw
*sfile
= sumfile
;
3474 xfs_fileoff_t sumbno
;
3477 sumbno
= NULLFILEOFF
;
3478 while ((sumbno
= blkmap_next_off(blkmap
, sumbno
, &t
)) != NULLFILEOFF
) {
3479 struct xfs_rtalloc_args args
= {
3482 union xfs_suminfo_raw
*ondisk
;
3484 bno
= blkmap_get(blkmap
, sumbno
);
3485 if (bno
== NULLFSBLOCK
) {
3487 dbprintf(_("block %lld for rtsummary inode is "
3489 (xfs_fileoff_t
)sumbno
);
3494 set_cur(&typtab
[TYP_RTSUMMARY
], XFS_FSB_TO_DADDR(mp
, bno
),
3495 blkbb
, DB_RING_IGN
, NULL
);
3496 if (!iocur_top
->bp
) {
3498 dbprintf(_("can't read block %lld for rtsummary "
3500 (xfs_fileoff_t
)sumbno
);
3503 sfile
+= mp
->m_blockwsize
;
3507 args
.sumbp
= iocur_top
->bp
;
3508 ondisk
= xfs_rsumblock_infoptr(&args
, 0);
3509 memcpy(sfile
, ondisk
, mp
->m_blockwsize
<< XFS_WORDLOG
);
3511 sfile
+= mp
->m_blockwsize
;
3517 struct xfs_dinode
*dip
,
3527 struct xfs_dir2_sf_hdr
*sf
;
3528 xfs_dir2_sf_entry_t
*sfe
;
3531 sf
= (struct xfs_dir2_sf_hdr
*)XFS_DFORK_DPTR(dip
);
3533 v
= verbose
|| id
->ilist
;
3535 dbprintf(_("dir %lld entry . %lld\n"), id
->ino
, id
->ino
);
3537 sfe
= xfs_dir2_sf_firstentry(sf
);
3538 offset
= mp
->m_dir_geo
->data_first_offset
;
3539 for (i
= sf
->count
- 1, i8
= 0; i
>= 0; i
--) {
3541 libxfs_dir2_sf_entsize(mp
, sf
, sfe
->namelen
) -
3542 (intptr_t)sf
> be64_to_cpu(dip
->di_size
)) {
3544 dbprintf(_("dir %llu bad size in entry at %d\n"),
3546 (int)((char *)sfe
- (char *)sf
));
3550 lino
= libxfs_dir2_sf_get_ino(mp
, sf
, sfe
);
3551 if (lino
> XFS_DIR2_MAX_SHORT_INUM
)
3553 cid
= find_inode(lino
, 1);
3556 dbprintf(_("dir %lld entry %*.*s bad inode "
3558 id
->ino
, sfe
->namelen
, sfe
->namelen
,
3565 addname_inode(cid
, (char *)sfe
->name
, sfe
->namelen
);
3568 dbprintf(_("dir %lld entry %*.*s offset %d %lld\n"),
3569 id
->ino
, sfe
->namelen
, sfe
->namelen
, sfe
->name
,
3570 xfs_dir2_sf_get_offset(sfe
), lino
);
3571 if (xfs_dir2_sf_get_offset(sfe
) < offset
) {
3573 dbprintf(_("dir %lld entry %*.*s bad offset %d\n"),
3574 id
->ino
, sfe
->namelen
, sfe
->namelen
,
3575 sfe
->name
, xfs_dir2_sf_get_offset(sfe
));
3579 xfs_dir2_sf_get_offset(sfe
) +
3580 libxfs_dir2_sf_entsize(mp
, sf
, sfe
->namelen
);
3581 sfe
= libxfs_dir2_sf_nextentry(mp
, sf
, sfe
);
3583 if (i
< 0 && (intptr_t)sfe
- (intptr_t)sf
!=
3584 be64_to_cpu(dip
->di_size
)) {
3586 dbprintf(_("dir %llu size is %lld, should be %u\n"),
3587 id
->ino
, be64_to_cpu(dip
->di_size
),
3588 (uint
)((char *)sfe
- (char *)sf
));
3591 if (offset
+ (sf
->count
+ 2) * sizeof(xfs_dir2_leaf_entry_t
) +
3592 sizeof(xfs_dir2_block_tail_t
) > mp
->m_dir_geo
->blksize
) {
3594 dbprintf(_("dir %llu offsets too high\n"), id
->ino
);
3597 lino
= libxfs_dir2_sf_get_parent_ino(sf
);
3598 if (lino
> XFS_DIR2_MAX_SHORT_INUM
)
3600 cid
= find_inode(lino
, 1);
3605 dbprintf(_("dir %lld entry .. bad inode number %lld\n"),
3610 dbprintf(_("dir %lld entry .. %lld\n"), id
->ino
, lino
);
3611 if (i8
!= sf
->i8count
) {
3613 dbprintf(_("dir %lld i8count mismatch is %d should be "
3615 id
->ino
, sf
->i8count
, i8
);
3619 return cid
? lino
: NULLFSINO
;
3633 if (qudo
&& usrid
!= NULL
)
3634 quota_add1(qudata
, *usrid
, dq
, bc
, ic
, rc
);
3635 if (qgdo
&& grpid
!= NULL
)
3636 quota_add1(qgdata
, *grpid
, dq
, bc
, ic
, rc
);
3637 if (qpdo
&& prjid
!= NULL
)
3638 quota_add1(qpdata
, *prjid
, dq
, bc
, ic
, rc
);
3654 qh
= (int)(id
% QDATA_HASH_SIZE
);
3658 qi
= dq
? &qe
->dq
: &qe
->count
;
3666 qe
= xmalloc(sizeof(*qe
));
3668 qi
= dq
? &qe
->dq
: &qe
->count
;
3672 qi
= dq
? &qe
->count
: &qe
->dq
;
3673 qi
->bc
= qi
->ic
= qi
->rc
= 0;
3681 qudo
= mp
->m_sb
.sb_uquotino
!= 0 &&
3682 mp
->m_sb
.sb_uquotino
!= NULLFSINO
&&
3683 (mp
->m_sb
.sb_qflags
& XFS_UQUOTA_ACCT
) &&
3684 (mp
->m_sb
.sb_qflags
& XFS_UQUOTA_CHKD
);
3685 qgdo
= mp
->m_sb
.sb_gquotino
!= 0 &&
3686 mp
->m_sb
.sb_gquotino
!= NULLFSINO
&&
3687 (mp
->m_sb
.sb_qflags
& XFS_GQUOTA_ACCT
) &&
3688 (mp
->m_sb
.sb_qflags
& XFS_GQUOTA_CHKD
);
3689 qpdo
= mp
->m_sb
.sb_pquotino
!= 0 &&
3690 mp
->m_sb
.sb_pquotino
!= NULLFSINO
&&
3691 (mp
->m_sb
.sb_qflags
& XFS_PQUOTA_ACCT
) &&
3692 (mp
->m_sb
.sb_qflags
& XFS_PQUOTA_CHKD
);
3694 qudata
= xcalloc(QDATA_HASH_SIZE
, sizeof(qdata_t
*));
3696 qgdata
= xcalloc(QDATA_HASH_SIZE
, sizeof(qdata_t
*));
3698 qpdata
= xcalloc(QDATA_HASH_SIZE
, sizeof(qdata_t
*));
3703 xfs_agnumber_t agno
)
3709 xfs_sb_t
*sb
= &tsb
;
3711 agffreeblks
= agflongest
= 0;
3713 agicount
= agifreecount
= 0;
3714 push_cur(); /* 1 pushed */
3715 set_cur(&typtab
[TYP_SB
],
3716 XFS_AG_DADDR(mp
, agno
, XFS_SB_DADDR
),
3717 XFS_FSS_TO_BB(mp
, 1), DB_RING_IGN
, NULL
);
3719 if (!iocur_top
->data
) {
3720 dbprintf(_("can't read superblock for ag %u\n"), agno
);
3725 libxfs_sb_from_disk(sb
, iocur_top
->data
);
3727 if (sb
->sb_magicnum
!= XFS_SB_MAGIC
) {
3729 dbprintf(_("bad sb magic # %#x in ag %u\n"),
3730 sb
->sb_magicnum
, agno
);
3733 if (!xfs_sb_good_version(sb
)) {
3735 dbprintf(_("bad sb version # %#x in ag %u\n"),
3736 sb
->sb_versionnum
, agno
);
3740 if (!lazycount
&& xfs_sb_version_haslazysbcount(sb
)) {
3743 if (agno
== 0 && sb
->sb_inprogress
!= 0) {
3745 dbprintf(_("mkfs not completed successfully\n"));
3748 if (xfs_sb_version_needsrepair(sb
)) {
3750 dbprintf(_("filesystem needs xfs_repair\n"));
3753 set_dbmap(agno
, XFS_SB_BLOCK(mp
), 1, DBM_SB
, agno
, XFS_SB_BLOCK(mp
));
3754 if (sb
->sb_logstart
&& XFS_FSB_TO_AGNO(mp
, sb
->sb_logstart
) == agno
)
3755 set_dbmap(agno
, XFS_FSB_TO_AGBNO(mp
, sb
->sb_logstart
),
3756 sb
->sb_logblocks
, DBM_LOG
, agno
, XFS_SB_BLOCK(mp
));
3757 push_cur(); /* 2 pushed */
3758 set_cur(&typtab
[TYP_AGF
],
3759 XFS_AG_DADDR(mp
, agno
, XFS_AGF_DADDR(mp
)),
3760 XFS_FSS_TO_BB(mp
, 1), DB_RING_IGN
, NULL
);
3761 if ((agf
= iocur_top
->data
) == NULL
) {
3762 dbprintf(_("can't read agf block for ag %u\n"), agno
);
3766 if (be32_to_cpu(agf
->agf_magicnum
) != XFS_AGF_MAGIC
) {
3768 dbprintf(_("bad agf magic # %#x in ag %u\n"),
3769 be32_to_cpu(agf
->agf_magicnum
), agno
);
3772 if (!XFS_AGF_GOOD_VERSION(be32_to_cpu(agf
->agf_versionnum
))) {
3774 dbprintf(_("bad agf version # %#x in ag %u\n"),
3775 be32_to_cpu(agf
->agf_versionnum
), agno
);
3778 if (XFS_SB_BLOCK(mp
) != XFS_AGF_BLOCK(mp
))
3779 set_dbmap(agno
, XFS_AGF_BLOCK(mp
), 1, DBM_AGF
, agno
,
3781 if (sb
->sb_agblocks
> be32_to_cpu(agf
->agf_length
))
3782 set_dbmap(agno
, be32_to_cpu(agf
->agf_length
),
3783 sb
->sb_agblocks
- be32_to_cpu(agf
->agf_length
),
3784 DBM_MISSING
, agno
, XFS_SB_BLOCK(mp
));
3785 push_cur(); /* 3 pushed */
3786 set_cur(&typtab
[TYP_AGI
],
3787 XFS_AG_DADDR(mp
, agno
, XFS_AGI_DADDR(mp
)),
3788 XFS_FSS_TO_BB(mp
, 1), DB_RING_IGN
, NULL
);
3789 if ((agi
= iocur_top
->data
) == NULL
) {
3790 dbprintf(_("can't read agi block for ag %u\n"), agno
);
3794 if (be32_to_cpu(agi
->agi_magicnum
) != XFS_AGI_MAGIC
) {
3796 dbprintf(_("bad agi magic # %#x in ag %u\n"),
3797 be32_to_cpu(agi
->agi_magicnum
), agno
);
3800 if (!XFS_AGI_GOOD_VERSION(be32_to_cpu(agi
->agi_versionnum
))) {
3802 dbprintf(_("bad agi version # %#x in ag %u\n"),
3803 be32_to_cpu(agi
->agi_versionnum
), agno
);
3806 if (XFS_SB_BLOCK(mp
) != XFS_AGI_BLOCK(mp
) &&
3807 XFS_AGF_BLOCK(mp
) != XFS_AGI_BLOCK(mp
))
3808 set_dbmap(agno
, XFS_AGI_BLOCK(mp
), 1, DBM_AGI
, agno
,
3813 be32_to_cpu(agf
->agf_bno_root
),
3814 be32_to_cpu(agf
->agf_bno_level
),
3815 1, scanfunc_bno
, TYP_BNOBT
);
3818 be32_to_cpu(agf
->agf_cnt_root
),
3819 be32_to_cpu(agf
->agf_cnt_level
),
3820 1, scanfunc_cnt
, TYP_CNTBT
);
3821 if (agf
->agf_rmap_root
) {
3823 be32_to_cpu(agf
->agf_rmap_root
),
3824 be32_to_cpu(agf
->agf_rmap_level
),
3825 1, scanfunc_rmap
, TYP_RMAPBT
);
3827 if (agf
->agf_refcount_root
) {
3829 be32_to_cpu(agf
->agf_refcount_root
),
3830 be32_to_cpu(agf
->agf_refcount_level
),
3831 1, scanfunc_refcnt
, TYP_REFCBT
);
3834 be32_to_cpu(agi
->agi_root
),
3835 be32_to_cpu(agi
->agi_level
),
3836 1, scanfunc_ino
, TYP_INOBT
);
3837 if (agi
->agi_free_root
) {
3839 be32_to_cpu(agi
->agi_free_root
),
3840 be32_to_cpu(agi
->agi_free_level
),
3841 1, scanfunc_fino
, TYP_FINOBT
);
3843 if (be32_to_cpu(agf
->agf_freeblks
) != agffreeblks
) {
3845 dbprintf(_("agf_freeblks %u, counted %u in ag %u\n"),
3846 be32_to_cpu(agf
->agf_freeblks
),
3850 if (be32_to_cpu(agf
->agf_longest
) != agflongest
) {
3852 dbprintf(_("agf_longest %u, counted %u in ag %u\n"),
3853 be32_to_cpu(agf
->agf_longest
),
3858 be32_to_cpu(agf
->agf_btreeblks
) != agfbtreeblks
) {
3860 dbprintf(_("agf_btreeblks %u, counted %u in ag %u\n"),
3861 be32_to_cpu(agf
->agf_btreeblks
),
3862 agfbtreeblks
, agno
);
3865 agf_aggr_freeblks
+= agffreeblks
+ agfbtreeblks
;
3866 if (be32_to_cpu(agi
->agi_count
) != agicount
) {
3868 dbprintf(_("agi_count %u, counted %u in ag %u\n"),
3869 be32_to_cpu(agi
->agi_count
),
3873 if (be32_to_cpu(agi
->agi_freecount
) != agifreecount
) {
3875 dbprintf(_("agi_freecount %u, counted %u in ag %u\n"),
3876 be32_to_cpu(agi
->agi_freecount
),
3877 agifreecount
, agno
);
3880 for (i
= 0; i
< XFS_AGI_UNLINKED_BUCKETS
; i
++) {
3881 if (be32_to_cpu(agi
->agi_unlinked
[i
]) != NULLAGINO
) {
3883 xfs_agino_t agino
=be32_to_cpu(agi
->agi_unlinked
[i
]);
3884 dbprintf(_("agi unlinked bucket %d is %u in ag "
3885 "%u (inode=%lld)\n"), i
, agino
, agno
,
3886 XFS_AGINO_TO_INO(mp
, agno
, agino
));
3900 xfs_agnumber_t agno
;
3906 struct xfs_mount
*mp
,
3910 struct agfl_state
*as
= priv
;
3912 set_dbmap(as
->agno
, bno
, 1, DBM_FREELIST
, as
->agno
, XFS_AGFL_BLOCK(mp
));
3921 xfs_agnumber_t seqno
= be32_to_cpu(agf
->agf_seqno
);
3922 struct agfl_state state
;
3924 if (XFS_SB_BLOCK(mp
) != XFS_AGFL_BLOCK(mp
) &&
3925 XFS_AGF_BLOCK(mp
) != XFS_AGFL_BLOCK(mp
) &&
3926 XFS_AGI_BLOCK(mp
) != XFS_AGFL_BLOCK(mp
))
3927 set_dbmap(seqno
, XFS_AGFL_BLOCK(mp
), 1, DBM_AGFL
, seqno
,
3929 if (be32_to_cpu(agf
->agf_flcount
) == 0)
3932 set_cur(&typtab
[TYP_AGFL
],
3933 XFS_AG_DADDR(mp
, seqno
, XFS_AGFL_DADDR(mp
)),
3934 XFS_FSS_TO_BB(mp
, 1), DB_RING_IGN
, NULL
);
3935 if (iocur_top
->data
== NULL
) {
3936 dbprintf(_("can't read agfl block for ag %u\n"), seqno
);
3942 /* verify agf values before proceeding */
3943 if (be32_to_cpu(agf
->agf_flfirst
) >= libxfs_agfl_size(mp
) ||
3944 be32_to_cpu(agf
->agf_fllast
) >= libxfs_agfl_size(mp
)) {
3945 dbprintf(_("agf %d freelist blocks bad, skipping "
3946 "freelist scan\n"), seqno
);
3951 /* open coded xfs_buf_to_agfl_bno */
3954 libxfs_agfl_walk(mp
, agf
, iocur_top
->bp
, scan_agfl
, &state
);
3955 if (state
.count
!= be32_to_cpu(agf
->agf_flcount
)) {
3957 dbprintf(_("freeblk count %u != flcount %u in ag %u\n"),
3959 be32_to_cpu(agf
->agf_flcount
),
3963 fdblocks
+= state
.count
;
3964 agf_aggr_freeblks
+= state
.count
;
3972 scan_lbtree_f_t func
,
3975 xfs_rfsblock_t
*totd
,
3976 xfs_rfsblock_t
*toti
,
3983 set_cur(&typtab
[btype
], XFS_FSB_TO_DADDR(mp
, root
), blkbb
, DB_RING_IGN
,
3985 if (iocur_top
->data
== NULL
) {
3987 dbprintf(_("can't read btree block %u/%u\n"),
3988 XFS_FSB_TO_AGNO(mp
, root
),
3989 XFS_FSB_TO_AGBNO(mp
, root
));
3994 (*func
)(iocur_top
->data
, nlevels
- 1, type
, root
, id
, totd
, toti
, nex
,
3995 blkmapp
, isroot
, btype
);
4005 scan_sbtree_f_t func
,
4008 xfs_agnumber_t seqno
= be32_to_cpu(agf
->agf_seqno
);
4011 set_cur(&typtab
[btype
],
4012 XFS_AGB_TO_DADDR(mp
, seqno
, root
), blkbb
, DB_RING_IGN
, NULL
);
4013 if (iocur_top
->data
== NULL
) {
4015 dbprintf(_("can't read btree block %u/%u\n"), seqno
, root
);
4020 (*func
)(iocur_top
->data
, nlevels
- 1, agf
, root
, isroot
);
4026 struct xfs_btree_block
*block
,
4031 xfs_rfsblock_t
*totd
,
4032 xfs_rfsblock_t
*toti
,
4038 xfs_agblock_t agbno
;
4039 xfs_agnumber_t agno
;
4044 agno
= XFS_FSB_TO_AGNO(mp
, bno
);
4045 agbno
= XFS_FSB_TO_AGBNO(mp
, bno
);
4046 if (be32_to_cpu(block
->bb_magic
) != XFS_BMAP_MAGIC
&&
4047 be32_to_cpu(block
->bb_magic
) != XFS_BMAP_CRC_MAGIC
) {
4048 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
4049 dbprintf(_("bad magic # %#x in inode %lld bmbt block "
4051 be32_to_cpu(block
->bb_magic
), id
->ino
, agno
, agbno
);
4054 if (be16_to_cpu(block
->bb_level
) != level
) {
4055 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
4056 dbprintf(_("expected level %d got %d in inode %lld bmbt "
4058 level
, be16_to_cpu(block
->bb_level
), id
->ino
, agno
, agbno
);
4061 set_dbmap(agno
, agbno
, 1, type
, agno
, agbno
);
4062 set_inomap(agno
, agbno
, 1, id
);
4065 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_bmap_dmxr
[0] ||
4066 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_bmap_dmnr
[0])) {
4067 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
4068 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) "
4069 "in inode %lld bmap block %lld\n"),
4070 be16_to_cpu(block
->bb_numrecs
), mp
->m_bmap_dmnr
[0],
4071 mp
->m_bmap_dmxr
[0], id
->ino
,
4072 (xfs_fsblock_t
)bno
);
4076 rp
= xfs_bmbt_rec_addr(mp
, block
, 1);
4077 *nex
+= be16_to_cpu(block
->bb_numrecs
);
4078 process_bmbt_reclist(rp
, be16_to_cpu(block
->bb_numrecs
), type
, id
, totd
,
4082 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_bmap_dmxr
[1] ||
4083 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_bmap_dmnr
[1])) {
4084 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
4085 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in "
4086 "inode %lld bmap block %lld\n"),
4087 be16_to_cpu(block
->bb_numrecs
), mp
->m_bmap_dmnr
[1],
4088 mp
->m_bmap_dmxr
[1], id
->ino
, (xfs_fsblock_t
)bno
);
4092 pp
= xfs_bmbt_ptr_addr(mp
, block
, 1, mp
->m_bmap_dmxr
[0]);
4093 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++)
4094 scan_lbtree(be64_to_cpu(pp
[i
]), level
, scanfunc_bmap
, type
, id
,
4095 totd
, toti
, nex
, blkmapp
, 0, btype
);
4100 struct xfs_btree_block
*block
,
4107 xfs_alloc_ptr_t
*pp
;
4108 xfs_alloc_rec_t
*rp
;
4109 xfs_agnumber_t seqno
= be32_to_cpu(agf
->agf_seqno
);
4110 xfs_agblock_t lastblock
;
4112 if (be32_to_cpu(block
->bb_magic
) != XFS_ABTB_MAGIC
&&
4113 be32_to_cpu(block
->bb_magic
) != XFS_ABTB_CRC_MAGIC
) {
4114 dbprintf(_("bad magic # %#x in btbno block %u/%u\n"),
4115 be32_to_cpu(block
->bb_magic
), seqno
, bno
);
4121 if (be16_to_cpu(block
->bb_level
) != level
) {
4123 dbprintf(_("expected level %d got %d in btbno block "
4125 level
, be16_to_cpu(block
->bb_level
), seqno
, bno
);
4128 set_dbmap(seqno
, bno
, 1, DBM_BTBNO
, seqno
, bno
);
4130 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_alloc_mxr
[0] ||
4131 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_alloc_mnr
[0])) {
4132 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in "
4133 "btbno block %u/%u\n"),
4134 be16_to_cpu(block
->bb_numrecs
), mp
->m_alloc_mnr
[0],
4135 mp
->m_alloc_mxr
[0], seqno
, bno
);
4139 rp
= XFS_ALLOC_REC_ADDR(mp
, block
, 1);
4141 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++) {
4142 set_dbmap(seqno
, be32_to_cpu(rp
[i
].ar_startblock
),
4143 be32_to_cpu(rp
[i
].ar_blockcount
), DBM_FREE1
,
4145 if (be32_to_cpu(rp
[i
].ar_startblock
) <= lastblock
) {
4147 "out-of-order bno btree record %d (%u %u) block %u/%u\n"),
4148 i
, be32_to_cpu(rp
[i
].ar_startblock
),
4149 be32_to_cpu(rp
[i
].ar_blockcount
),
4150 be32_to_cpu(agf
->agf_seqno
), bno
);
4153 lastblock
= be32_to_cpu(rp
[i
].ar_startblock
);
4158 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_alloc_mxr
[1] ||
4159 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_alloc_mnr
[1])) {
4160 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in btbno block "
4162 be16_to_cpu(block
->bb_numrecs
), mp
->m_alloc_mnr
[1],
4163 mp
->m_alloc_mxr
[1], seqno
, bno
);
4167 pp
= XFS_ALLOC_PTR_ADDR(mp
, block
, 1, mp
->m_alloc_mxr
[1]);
4168 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++)
4169 scan_sbtree(agf
, be32_to_cpu(pp
[i
]), level
, 0, scanfunc_bno
, TYP_BNOBT
);
4174 struct xfs_btree_block
*block
,
4180 xfs_agnumber_t seqno
= be32_to_cpu(agf
->agf_seqno
);
4182 xfs_alloc_ptr_t
*pp
;
4183 xfs_alloc_rec_t
*rp
;
4184 xfs_extlen_t lastcount
;
4186 if (be32_to_cpu(block
->bb_magic
) != XFS_ABTC_MAGIC
&&
4187 be32_to_cpu(block
->bb_magic
) != XFS_ABTC_CRC_MAGIC
) {
4188 dbprintf(_("bad magic # %#x in btcnt block %u/%u\n"),
4189 be32_to_cpu(block
->bb_magic
), seqno
, bno
);
4195 if (be16_to_cpu(block
->bb_level
) != level
) {
4197 dbprintf(_("expected level %d got %d in btcnt block "
4199 level
, be16_to_cpu(block
->bb_level
), seqno
, bno
);
4202 set_dbmap(seqno
, bno
, 1, DBM_BTCNT
, seqno
, bno
);
4204 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_alloc_mxr
[0] ||
4205 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_alloc_mnr
[0])) {
4206 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in "
4207 "btbno block %u/%u\n"),
4208 be16_to_cpu(block
->bb_numrecs
), mp
->m_alloc_mnr
[0],
4209 mp
->m_alloc_mxr
[0], seqno
, bno
);
4213 rp
= XFS_ALLOC_REC_ADDR(mp
, block
, 1);
4215 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++) {
4216 check_set_dbmap(seqno
, be32_to_cpu(rp
[i
].ar_startblock
),
4217 be32_to_cpu(rp
[i
].ar_blockcount
), DBM_FREE1
, DBM_FREE2
,
4219 fdblocks
+= be32_to_cpu(rp
[i
].ar_blockcount
);
4220 agffreeblks
+= be32_to_cpu(rp
[i
].ar_blockcount
);
4221 if (be32_to_cpu(rp
[i
].ar_blockcount
) > agflongest
)
4222 agflongest
= be32_to_cpu(rp
[i
].ar_blockcount
);
4223 if (be32_to_cpu(rp
[i
].ar_blockcount
) < lastcount
) {
4225 "out-of-order cnt btree record %d (%u %u) block %u/%u\n"),
4226 i
, be32_to_cpu(rp
[i
].ar_startblock
),
4227 be32_to_cpu(rp
[i
].ar_blockcount
),
4228 be32_to_cpu(agf
->agf_seqno
), bno
);
4230 lastcount
= be32_to_cpu(rp
[i
].ar_blockcount
);
4235 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_alloc_mxr
[1] ||
4236 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_alloc_mnr
[1])) {
4237 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in btbno block "
4239 be16_to_cpu(block
->bb_numrecs
), mp
->m_alloc_mnr
[1],
4240 mp
->m_alloc_mxr
[1], seqno
, bno
);
4244 pp
= XFS_ALLOC_PTR_ADDR(mp
, block
, 1, mp
->m_alloc_mxr
[1]);
4245 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++)
4246 scan_sbtree(agf
, be32_to_cpu(pp
[i
]), level
, 0, scanfunc_cnt
, TYP_CNTBT
);
4251 struct xfs_btree_block
*block
,
4258 xfs_agnumber_t seqno
= be32_to_cpu(agf
->agf_seqno
);
4265 xfs_inobt_ptr_t
*pp
;
4266 xfs_inobt_rec_t
*rp
;
4267 xfs_agblock_t agbno
;
4268 xfs_agblock_t end_agbno
;
4269 struct xfs_dinode
*dip
;
4273 struct xfs_ino_geometry
*igeo
= M_IGEO(mp
);
4275 if (xfs_has_sparseinodes(mp
))
4276 blks_per_buf
= igeo
->blocks_per_cluster
;
4278 blks_per_buf
= igeo
->ialloc_blks
;
4279 inodes_per_buf
= min(XFS_FSB_TO_INO(mp
, blks_per_buf
),
4280 XFS_INODES_PER_CHUNK
);
4282 if (be32_to_cpu(block
->bb_magic
) != XFS_IBT_MAGIC
&&
4283 be32_to_cpu(block
->bb_magic
) != XFS_IBT_CRC_MAGIC
) {
4284 dbprintf(_("bad magic # %#x in inobt block %u/%u\n"),
4285 be32_to_cpu(block
->bb_magic
), seqno
, bno
);
4289 if (be16_to_cpu(block
->bb_level
) != level
) {
4291 dbprintf(_("expected level %d got %d in inobt block "
4293 level
, be16_to_cpu(block
->bb_level
), seqno
, bno
);
4296 set_dbmap(seqno
, bno
, 1, DBM_BTINO
, seqno
, bno
);
4298 if (be16_to_cpu(block
->bb_numrecs
) > igeo
->inobt_mxr
[0] ||
4299 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < igeo
->inobt_mnr
[0])) {
4300 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in "
4301 "inobt block %u/%u\n"),
4302 be16_to_cpu(block
->bb_numrecs
), igeo
->inobt_mnr
[0],
4303 igeo
->inobt_mxr
[0], seqno
, bno
);
4307 rp
= XFS_INOBT_REC_ADDR(mp
, block
, 1);
4308 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++) {
4309 agino
= be32_to_cpu(rp
[i
].ir_startino
);
4310 agbno
= XFS_AGINO_TO_AGBNO(mp
, agino
);
4311 off
= XFS_AGINO_TO_OFFSET(mp
, agino
);
4312 end_agbno
= agbno
+ igeo
->ialloc_blks
;
4314 if ((sbversion
& XFS_SB_VERSION_ALIGNBIT
) &&
4315 mp
->m_sb
.sb_inoalignmt
&&
4316 (XFS_INO_TO_AGBNO(mp
, agino
) %
4317 mp
->m_sb
.sb_inoalignmt
))
4318 sbversion
&= ~XFS_SB_VERSION_ALIGNBIT
;
4325 while (agbno
< end_agbno
&&
4326 ioff
< XFS_INODES_PER_CHUNK
) {
4327 if (xfs_inobt_is_sparse_disk(&rp
[i
], ioff
))
4330 if (off
< XFS_INODES_PER_CHUNK
)
4331 set_dbmap(seqno
, agbno
, blks_per_buf
,
4332 DBM_INODE
, seqno
, bno
);
4334 icount
+= inodes_per_buf
;
4335 agicount
+= inodes_per_buf
;
4337 set_cur(&typtab
[TYP_INODE
],
4338 XFS_AGB_TO_DADDR(mp
, seqno
, agbno
),
4339 XFS_FSB_TO_BB(mp
, blks_per_buf
),
4341 if (iocur_top
->data
== NULL
) {
4343 dbprintf(_("can't read inode block "
4350 for (j
= 0; j
< inodes_per_buf
; j
++) {
4351 isfree
= XFS_INOBT_IS_FREE_DISK(&rp
[i
], ioff
+ j
);
4354 dip
= (struct xfs_dinode
*)((char *)iocur_top
->data
+
4355 ((off
+ j
) << mp
->m_sb
.sb_inodelog
));
4356 process_inode(agf
, agino
+ ioff
+ j
, dip
, isfree
);
4360 agbno
+= blks_per_buf
;
4361 ioff
+= inodes_per_buf
;
4364 if (xfs_has_sparseinodes(mp
))
4365 freecount
= rp
[i
].ir_u
.sp
.ir_freecount
;
4367 freecount
= be32_to_cpu(rp
[i
].ir_u
.f
.ir_freecount
);
4370 agifreecount
+= freecount
;
4372 if (nfree
!= freecount
) {
4374 dbprintf(_("ir_freecount/free mismatch, "
4375 "inode chunk %u/%u, freecount "
4377 seqno
, agino
, freecount
, nfree
);
4384 if (be16_to_cpu(block
->bb_numrecs
) > igeo
->inobt_mxr
[1] ||
4385 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < igeo
->inobt_mnr
[1])) {
4386 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in inobt block "
4388 be16_to_cpu(block
->bb_numrecs
), igeo
->inobt_mnr
[1],
4389 igeo
->inobt_mxr
[1], seqno
, bno
);
4393 pp
= XFS_INOBT_PTR_ADDR(mp
, block
, 1, igeo
->inobt_mxr
[1]);
4394 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++)
4395 scan_sbtree(agf
, be32_to_cpu(pp
[i
]), level
, 0, scanfunc_ino
, TYP_INOBT
);
4400 struct xfs_btree_block
*block
,
4402 struct xfs_agf
*agf
,
4407 xfs_agnumber_t seqno
= be32_to_cpu(agf
->agf_seqno
);
4410 xfs_inobt_ptr_t
*pp
;
4411 struct xfs_inobt_rec
*rp
;
4412 xfs_agblock_t agbno
;
4413 xfs_agblock_t end_agbno
;
4417 struct xfs_ino_geometry
*igeo
= M_IGEO(mp
);
4419 if (xfs_has_sparseinodes(mp
))
4420 blks_per_buf
= igeo
->blocks_per_cluster
;
4422 blks_per_buf
= igeo
->ialloc_blks
;
4423 inodes_per_buf
= min(XFS_FSB_TO_INO(mp
, blks_per_buf
),
4424 XFS_INODES_PER_CHUNK
);
4426 if (be32_to_cpu(block
->bb_magic
) != XFS_FIBT_MAGIC
&&
4427 be32_to_cpu(block
->bb_magic
) != XFS_FIBT_CRC_MAGIC
) {
4428 dbprintf(_("bad magic # %#x in finobt block %u/%u\n"),
4429 be32_to_cpu(block
->bb_magic
), seqno
, bno
);
4433 if (be16_to_cpu(block
->bb_level
) != level
) {
4435 dbprintf(_("expected level %d got %d in finobt block "
4437 level
, be16_to_cpu(block
->bb_level
), seqno
, bno
);
4440 set_dbmap(seqno
, bno
, 1, DBM_BTFINO
, seqno
, bno
);
4442 if (be16_to_cpu(block
->bb_numrecs
) > igeo
->inobt_mxr
[0] ||
4443 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < igeo
->inobt_mnr
[0])) {
4444 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in "
4445 "finobt block %u/%u\n"),
4446 be16_to_cpu(block
->bb_numrecs
), igeo
->inobt_mnr
[0],
4447 igeo
->inobt_mxr
[0], seqno
, bno
);
4451 rp
= XFS_INOBT_REC_ADDR(mp
, block
, 1);
4452 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++) {
4453 agino
= be32_to_cpu(rp
[i
].ir_startino
);
4454 agbno
= XFS_AGINO_TO_AGBNO(mp
, agino
);
4455 off
= XFS_AGINO_TO_OFFSET(mp
, agino
);
4456 end_agbno
= agbno
+ igeo
->ialloc_blks
;
4458 if ((sbversion
& XFS_SB_VERSION_ALIGNBIT
) &&
4459 mp
->m_sb
.sb_inoalignmt
&&
4460 (XFS_INO_TO_AGBNO(mp
, agino
) %
4461 mp
->m_sb
.sb_inoalignmt
))
4462 sbversion
&= ~XFS_SB_VERSION_ALIGNBIT
;
4466 while (agbno
< end_agbno
&&
4467 ioff
< XFS_INODES_PER_CHUNK
) {
4468 if (xfs_inobt_is_sparse_disk(&rp
[i
], ioff
))
4471 check_set_dbmap(seqno
, agbno
,
4472 (xfs_extlen_t
)max(1,
4474 mp
->m_sb
.sb_inopblog
),
4475 DBM_INODE
, DBM_INODE
, seqno
, bno
);
4478 agbno
+= blks_per_buf
;
4479 ioff
+= inodes_per_buf
;
4485 if (be16_to_cpu(block
->bb_numrecs
) > igeo
->inobt_mxr
[1] ||
4486 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < igeo
->inobt_mnr
[1])) {
4487 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in finobt block "
4489 be16_to_cpu(block
->bb_numrecs
), igeo
->inobt_mnr
[1],
4490 igeo
->inobt_mxr
[1], seqno
, bno
);
4494 pp
= XFS_INOBT_PTR_ADDR(mp
, block
, 1, igeo
->inobt_mxr
[1]);
4495 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++)
4496 scan_sbtree(agf
, be32_to_cpu(pp
[i
]), level
, 0, scanfunc_fino
, TYP_FINOBT
);
4501 struct xfs_btree_block
*block
,
4503 struct xfs_agf
*agf
,
4507 xfs_agnumber_t seqno
= be32_to_cpu(agf
->agf_seqno
);
4510 struct xfs_rmap_rec
*rp
;
4511 xfs_agblock_t lastblock
;
4513 if (be32_to_cpu(block
->bb_magic
) != XFS_RMAP_CRC_MAGIC
) {
4514 dbprintf(_("bad magic # %#x in rmapbt block %u/%u\n"),
4515 be32_to_cpu(block
->bb_magic
), seqno
, bno
);
4519 if (be16_to_cpu(block
->bb_level
) != level
) {
4521 dbprintf(_("expected level %d got %d in rmapbt block "
4523 level
, be16_to_cpu(block
->bb_level
), seqno
, bno
);
4530 set_dbmap(seqno
, bno
, 1, DBM_BTRMAP
, seqno
, bno
);
4532 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_rmap_mxr
[0] ||
4533 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_rmap_mnr
[0])) {
4534 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in "
4535 "rmapbt block %u/%u\n"),
4536 be16_to_cpu(block
->bb_numrecs
), mp
->m_rmap_mnr
[0],
4537 mp
->m_rmap_mxr
[0], seqno
, bno
);
4541 rp
= XFS_RMAP_REC_ADDR(block
, 1);
4543 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++) {
4544 if (be32_to_cpu(rp
[i
].rm_startblock
) < lastblock
) {
4546 "out-of-order rmap btree record %d (%u %u) block %u/%u\n"),
4547 i
, be32_to_cpu(rp
[i
].rm_startblock
),
4548 be32_to_cpu(rp
[i
].rm_startblock
),
4549 be32_to_cpu(agf
->agf_seqno
), bno
);
4551 lastblock
= be32_to_cpu(rp
[i
].rm_startblock
);
4556 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_rmap_mxr
[1] ||
4557 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_rmap_mnr
[1])) {
4558 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in rmapbt "
4560 be16_to_cpu(block
->bb_numrecs
), mp
->m_rmap_mnr
[1],
4561 mp
->m_rmap_mxr
[1], seqno
, bno
);
4565 pp
= XFS_RMAP_PTR_ADDR(block
, 1, mp
->m_rmap_mxr
[1]);
4566 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++)
4567 scan_sbtree(agf
, be32_to_cpu(pp
[i
]), level
, 0, scanfunc_rmap
,
4573 struct xfs_btree_block
*block
,
4575 struct xfs_agf
*agf
,
4579 xfs_agnumber_t seqno
= be32_to_cpu(agf
->agf_seqno
);
4581 xfs_refcount_ptr_t
*pp
;
4582 struct xfs_refcount_rec
*rp
;
4583 xfs_agblock_t lastblock
;
4585 if (be32_to_cpu(block
->bb_magic
) != XFS_REFC_CRC_MAGIC
) {
4586 dbprintf(_("bad magic # %#x in refcntbt block %u/%u\n"),
4587 be32_to_cpu(block
->bb_magic
), seqno
, bno
);
4591 if (be16_to_cpu(block
->bb_level
) != level
) {
4593 dbprintf(_("expected level %d got %d in refcntbt block "
4595 level
, be16_to_cpu(block
->bb_level
), seqno
, bno
);
4598 set_dbmap(seqno
, bno
, 1, DBM_BTREFC
, seqno
, bno
);
4600 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_refc_mxr
[0] ||
4601 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_refc_mnr
[0])) {
4602 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in "
4603 "refcntbt block %u/%u\n"),
4604 be16_to_cpu(block
->bb_numrecs
), mp
->m_refc_mnr
[0],
4605 mp
->m_refc_mxr
[0], seqno
, bno
);
4609 rp
= XFS_REFCOUNT_REC_ADDR(block
, 1);
4611 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++) {
4612 if (be32_to_cpu(rp
[i
].rc_refcount
) == 1) {
4613 xfs_agblock_t agbno
;
4616 agbno
= be32_to_cpu(rp
[i
].rc_startblock
);
4617 if (agbno
& XFS_REFC_COWFLAG
) {
4618 agbno
&= ~XFS_REFC_COWFLAG
;
4620 "leftover CoW extent (%u/%u) len %u\n");
4623 "leftover CoW extent at unexpected address (%u/%u) len %u\n");
4628 be32_to_cpu(rp
[i
].rc_blockcount
));
4631 be32_to_cpu(rp
[i
].rc_blockcount
),
4632 DBM_COWDATA
, seqno
, bno
);
4635 be32_to_cpu(rp
[i
].rc_startblock
),
4636 be32_to_cpu(rp
[i
].rc_blockcount
),
4637 DBM_RLDATA
, seqno
, bno
);
4639 if (be32_to_cpu(rp
[i
].rc_startblock
) < lastblock
) {
4641 "out-of-order refcnt btree record %d (%u %u) block %u/%u\n"),
4642 i
, be32_to_cpu(rp
[i
].rc_startblock
),
4643 be32_to_cpu(rp
[i
].rc_startblock
),
4644 be32_to_cpu(agf
->agf_seqno
), bno
);
4646 lastblock
= be32_to_cpu(rp
[i
].rc_startblock
) +
4647 be32_to_cpu(rp
[i
].rc_blockcount
);
4652 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_refc_mxr
[1] ||
4653 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_refc_mnr
[1])) {
4654 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in refcntbt "
4656 be16_to_cpu(block
->bb_numrecs
), mp
->m_refc_mnr
[1],
4657 mp
->m_refc_mxr
[1], seqno
, bno
);
4661 pp
= XFS_REFCOUNT_PTR_ADDR(block
, 1, mp
->m_refc_mxr
[1]);
4662 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++)
4663 scan_sbtree(agf
, be32_to_cpu(pp
[i
]), level
, 0, scanfunc_refcnt
,
4669 xfs_agnumber_t agno
,
4670 xfs_agblock_t agbno
,
4673 xfs_agnumber_t c_agno
,
4674 xfs_agblock_t c_agbno
)
4676 check_set_dbmap(agno
, agbno
, len
, DBM_UNKNOWN
, type
, c_agno
, c_agbno
);
4681 xfs_agnumber_t agno
,
4682 xfs_agblock_t agbno
,
4690 if (!check_inomap(agno
, agbno
, len
, id
->ino
))
4692 mayprint
= verbose
| id
->ilist
| blist_size
;
4693 for (i
= 0, idp
= &inomap
[agno
][agbno
]; i
< len
; i
++, idp
++) {
4696 (verbose
|| id
->ilist
|| CHECK_BLISTA(agno
, agbno
+ i
)))
4697 dbprintf(_("setting inode to %lld for block %u/%u\n"),
4698 id
->ino
, agno
, agbno
+ i
);
4708 check_set_rdbmap(bno
, len
, DBM_UNKNOWN
, type
);
4721 if (!check_rinomap(bno
, len
, id
->ino
))
4723 mayprint
= verbose
| id
->ilist
| blist_size
;
4724 for (i
= 0, idp
= &inomap
[mp
->m_sb
.sb_agcount
][bno
];
4728 if (mayprint
&& (verbose
|| id
->ilist
|| CHECK_BLIST(bno
+ i
)))
4729 dbprintf(_("setting inode to %lld for rtblock %llu\n"),
4741 id
->link_set
= nlink
;
4743 id
->security
= security
;
4744 if (verbose
|| id
->ilist
)
4745 dbprintf(_("inode %lld nlink %u %s dir\n"), id
->ino
, nlink
,
4746 isdir
? "is" : "not");