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 void check_linkcounts(xfs_agnumber_t agno
);
240 static int check_range(xfs_agnumber_t agno
, xfs_agblock_t agbno
,
242 static void check_rdbmap(xfs_rfsblock_t bno
, xfs_extlen_t len
,
244 static int check_rinomap(xfs_rfsblock_t bno
, xfs_extlen_t len
,
246 static void check_rootdir(void);
247 static int check_rrange(xfs_rfsblock_t bno
, xfs_extlen_t len
);
248 static void check_set_dbmap(xfs_agnumber_t agno
,
249 xfs_agblock_t agbno
, xfs_extlen_t len
,
250 dbm_t type1
, dbm_t type2
,
251 xfs_agnumber_t c_agno
,
252 xfs_agblock_t c_agbno
);
253 static void check_set_rdbmap(xfs_rfsblock_t bno
, xfs_extlen_t len
,
254 dbm_t type1
, dbm_t type2
);
255 static void check_summary(void);
256 static void checknot_dbmap(xfs_agnumber_t agno
, xfs_agblock_t agbno
,
257 xfs_extlen_t len
, int typemask
);
258 static void checknot_rdbmap(xfs_rfsblock_t bno
, xfs_extlen_t len
,
260 static void dir_hash_add(xfs_dahash_t hash
,
261 xfs_dir2_dataptr_t addr
);
262 static void dir_hash_check(inodata_t
*id
, int v
);
263 static void dir_hash_done(void);
264 static void dir_hash_init(void);
265 static int dir_hash_see(xfs_dahash_t hash
,
266 xfs_dir2_dataptr_t addr
);
267 static inodata_t
*find_inode(xfs_ino_t ino
, int add
);
268 static void free_inodata(xfs_agnumber_t agno
);
269 static int init(int argc
, char **argv
);
270 static char *inode_name(xfs_ino_t ino
, inodata_t
**ipp
);
271 static int ncheck_f(int argc
, char **argv
);
272 static char *prepend_path(char *oldpath
, char *parent
);
273 static xfs_ino_t
process_block_dir_v2(blkmap_t
*blkmap
, int *dot
,
274 int *dotdot
, inodata_t
*id
);
275 static void process_bmbt_reclist(xfs_bmbt_rec_t
*rp
,
276 xfs_extnum_t numrecs
, dbm_t type
,
277 inodata_t
*id
, xfs_rfsblock_t
*tot
,
279 static void process_btinode(inodata_t
*id
, struct xfs_dinode
*dip
,
280 dbm_t type
, xfs_rfsblock_t
*totd
,
281 xfs_rfsblock_t
*toti
, xfs_extnum_t
*nex
,
282 blkmap_t
**blkmapp
, int whichfork
);
283 static xfs_ino_t
process_data_dir_v2(int *dot
, int *dotdot
,
284 inodata_t
*id
, int v
,
286 freetab_t
**freetabp
);
287 static xfs_dir2_data_free_t
*process_data_dir_v2_freefind(
288 struct xfs_dir2_data_hdr
*data
,
289 struct xfs_dir2_data_unused
*dup
);
290 static void process_dir(struct xfs_dinode
*dip
, blkmap_t
*blkmap
,
292 static int process_dir_v2(struct xfs_dinode
*dip
, blkmap_t
*blkmap
,
293 int *dot
, int *dotdot
, inodata_t
*id
,
295 static void process_exinode(inodata_t
*id
, struct xfs_dinode
*dip
,
296 dbm_t type
, xfs_rfsblock_t
*totd
,
297 xfs_rfsblock_t
*toti
, xfs_extnum_t
*nex
,
298 blkmap_t
**blkmapp
, int whichfork
);
299 static void process_inode(xfs_agf_t
*agf
, xfs_agino_t agino
,
300 struct xfs_dinode
*dip
, int isfree
);
301 static void process_lclinode(inodata_t
*id
, struct xfs_dinode
*dip
,
302 dbm_t type
, xfs_rfsblock_t
*totd
,
303 xfs_rfsblock_t
*toti
, xfs_extnum_t
*nex
,
304 blkmap_t
**blkmapp
, int whichfork
);
305 static xfs_ino_t
process_leaf_node_dir_v2(blkmap_t
*blkmap
, int *dot
,
306 int *dotdot
, inodata_t
*id
,
307 xfs_fsize_t dirsize
);
308 static void process_leaf_node_dir_v2_free(inodata_t
*id
, int v
,
311 static void process_leaf_node_dir_v2_int(inodata_t
*id
, int v
,
314 static void process_quota(qtype_t qtype
, inodata_t
*id
,
316 static void process_rtbitmap(blkmap_t
*blkmap
);
317 static void process_rtsummary(blkmap_t
*blkmap
);
318 static xfs_ino_t
process_sf_dir_v2(struct xfs_dinode
*dip
, int *dot
,
319 int *dotdot
, inodata_t
*id
);
320 static void quota_add(xfs_dqid_t
*p
, xfs_dqid_t
*g
, xfs_dqid_t
*u
,
321 int dq
, xfs_qcnt_t bc
, xfs_qcnt_t ic
,
323 static void quota_add1(qdata_t
**qt
, xfs_dqid_t id
, int dq
,
324 xfs_qcnt_t bc
, xfs_qcnt_t ic
,
326 static void quota_check(char *s
, qdata_t
**qt
);
327 static void quota_init(void);
328 static void scan_ag(xfs_agnumber_t agno
);
329 static void scan_freelist(xfs_agf_t
*agf
);
330 static void scan_lbtree(xfs_fsblock_t root
, int nlevels
,
331 scan_lbtree_f_t func
, dbm_t type
,
332 inodata_t
*id
, xfs_rfsblock_t
*totd
,
333 xfs_rfsblock_t
*toti
, xfs_extnum_t
*nex
,
334 blkmap_t
**blkmapp
, int isroot
,
336 static void scan_sbtree(xfs_agf_t
*agf
, xfs_agblock_t root
,
337 int nlevels
, int isroot
,
338 scan_sbtree_f_t func
, typnm_t btype
);
339 static void scanfunc_bmap(struct xfs_btree_block
*block
,
340 int level
, dbm_t type
, xfs_fsblock_t bno
,
341 inodata_t
*id
, xfs_rfsblock_t
*totd
,
342 xfs_rfsblock_t
*toti
, xfs_extnum_t
*nex
,
343 blkmap_t
**blkmapp
, int isroot
,
345 static void scanfunc_bno(struct xfs_btree_block
*block
, int level
,
346 xfs_agf_t
*agf
, xfs_agblock_t bno
,
348 static void scanfunc_cnt(struct xfs_btree_block
*block
, int level
,
349 xfs_agf_t
*agf
, xfs_agblock_t bno
,
351 static void scanfunc_ino(struct xfs_btree_block
*block
, int level
,
352 xfs_agf_t
*agf
, xfs_agblock_t bno
,
354 static void scanfunc_fino(struct xfs_btree_block
*block
, int level
,
355 struct xfs_agf
*agf
, xfs_agblock_t bno
,
357 static void scanfunc_rmap(struct xfs_btree_block
*block
, int level
,
358 struct xfs_agf
*agf
, xfs_agblock_t bno
,
360 static void scanfunc_refcnt(struct xfs_btree_block
*block
, int level
,
361 struct xfs_agf
*agf
, xfs_agblock_t bno
,
363 static void set_dbmap(xfs_agnumber_t agno
, xfs_agblock_t agbno
,
364 xfs_extlen_t len
, dbm_t type
,
365 xfs_agnumber_t c_agno
, xfs_agblock_t c_agbno
);
366 static void set_inomap(xfs_agnumber_t agno
, xfs_agblock_t agbno
,
367 xfs_extlen_t len
, inodata_t
*id
);
368 static void set_rdbmap(xfs_rfsblock_t bno
, xfs_extlen_t len
,
370 static void set_rinomap(xfs_rfsblock_t bno
, xfs_extlen_t len
,
372 static void setlink_inode(inodata_t
*id
, nlink_t nlink
, int isdir
,
375 static const cmdinfo_t blockfree_cmd
=
376 { "blockfree", NULL
, blockfree_f
, 0, 0, 0,
377 NULL
, N_("free block usage information"), NULL
};
378 static const cmdinfo_t blockget_cmd
=
379 { "blockget", "check", blockget_f
, 0, -1, 0,
380 N_("[-s|-v] [-n] [-t] [-b bno]... [-i ino] ..."),
381 N_("get block usage and check consistency"), NULL
};
382 static const cmdinfo_t blocktrash_cmd
=
383 { "blocktrash", NULL
, blocktrash_f
, 0, -1, 0,
384 N_("[-n count] [-x minlen] [-y maxlen] [-s seed] [-0123] [-t type] ..."),
385 N_("trash randomly selected block(s)"), NULL
};
386 static const cmdinfo_t blockuse_cmd
=
387 { "blockuse", NULL
, blockuse_f
, 0, 3, 0,
388 N_("[-n] [-c blockcount]"),
389 N_("print usage for current block(s)"), NULL
};
390 static const cmdinfo_t ncheck_cmd
=
391 { "ncheck", NULL
, ncheck_f
, 0, -1, 0,
392 N_("[-s] [-i ino] ..."),
393 N_("print inode-name pairs"), NULL
};
401 blist
= xrealloc(blist
, blist_size
* sizeof(bno
));
402 blist
[blist_size
- 1] = bno
;
411 id
= find_inode(ino
, 1);
413 dbprintf(_("-i %lld bad inode number\n"), ino
);
424 if (verbose
|| id
->ilist
)
425 dbprintf(_("inode %lld add link, now %u\n"), id
->ino
,
435 if (!nflag
|| id
->name
)
437 id
->name
= xmalloc(namelen
+ 1);
438 memcpy(id
->name
, name
, namelen
);
439 id
->name
[namelen
] = '\0';
449 pid
= find_inode(parent
, 1);
451 if (verbose
|| id
->ilist
|| (pid
&& pid
->ilist
))
452 dbprintf(_("inode %lld parent %lld\n"), id
->ino
, parent
);
465 *entp
= ent
= xrealloc(ent
, BLKENT_SIZE(c
+ ent
->nblks
));
466 for (i
= 0; i
< c
; i
++)
467 ent
->blks
[ent
->nblks
+ i
] = b
+ i
;
480 ent
= xmalloc(BLKENT_SIZE(c
));
483 for (i
= 0; i
< c
; i
++)
484 ent
->blks
[i
] = b
+ i
;
499 newent
= xmalloc(BLKENT_SIZE(oldent
->nblks
+ c
));
500 newent
->nblks
= oldent
->nblks
+ c
;
501 newent
->startoff
= oldent
->startoff
- c
;
502 for (i
= 0; i
< c
; i
++)
503 newent
->blks
[i
] = b
+ c
;
504 for (; i
< oldent
->nblks
+ c
; i
++)
505 newent
->blks
[i
] = oldent
->blks
[i
- c
];
518 blkmap
= xmalloc(BLKMAP_SIZE(nex
));
519 blkmap
->naents
= nex
;
531 for (i
= 0, entp
= blkmap
->ents
; i
< blkmap
->nents
; i
++, entp
++)
545 for (i
= 0, entp
= blkmap
->ents
; i
< blkmap
->nents
; i
++, entp
++) {
547 if (o
>= ent
->startoff
&& o
< ent
->startoff
+ ent
->nblks
)
548 return ent
->blks
[o
- ent
->startoff
];
567 for (i
= nex
= 0, bmp
= NULL
, entp
= blkmap
->ents
;
571 if (ent
->startoff
>= o
+ nb
)
573 if (ent
->startoff
+ ent
->nblks
<= o
)
575 for (ento
= ent
->startoff
;
576 ento
< ent
->startoff
+ ent
->nblks
&& ento
< o
+ nb
;
581 bmp
[nex
- 1].startoff
+ bmp
[nex
- 1].blockcount
==
583 bmp
[nex
- 1].startblock
+ bmp
[nex
- 1].blockcount
==
584 ent
->blks
[ento
- ent
->startoff
])
585 bmp
[nex
- 1].blockcount
++;
587 bmp
= realloc(bmp
, ++nex
* sizeof(*bmp
));
588 bmp
[nex
- 1].startoff
= ento
;
589 bmp
[nex
- 1].startblock
=
590 ent
->blks
[ento
- ent
->startoff
];
591 bmp
[nex
- 1].blockcount
= 1;
592 bmp
[nex
- 1].flag
= 0;
611 idx
= (int)(entp
- blkmap
->ents
);
612 if (blkmap
->naents
== blkmap
->nents
) {
613 blkmap
= xrealloc(blkmap
, BLKMAP_SIZE(blkmap
->nents
+ 1));
617 for (i
= blkmap
->nents
; i
> idx
; i
--)
618 blkmap
->ents
[i
] = blkmap
->ents
[i
- 1];
619 blkmap
->ents
[idx
] = newent
;
631 ent
= blkmap
->ents
[blkmap
->nents
- 1];
632 return ent
->startoff
+ ent
->nblks
;
646 if (o
== NULLFILEOFF
) {
648 ent
= blkmap
->ents
[0];
649 return ent
->startoff
;
651 entp
= &blkmap
->ents
[*t
];
653 if (o
< ent
->startoff
+ ent
->nblks
- 1)
656 if (entp
>= &blkmap
->ents
[blkmap
->nents
])
660 return ent
->startoff
;
675 for (entp
= blkmap
->ents
; entp
< &blkmap
->ents
[blkmap
->nents
]; entp
++) {
677 if (o
< ent
->startoff
- 1) {
678 ent
= blkent_new(o
, b
, 1);
679 blkmap_grow(blkmapp
, entp
, ent
);
682 if (o
== ent
->startoff
- 1) {
683 blkent_prepend(entp
, b
, 1);
686 if (o
>= ent
->startoff
&& o
< ent
->startoff
+ ent
->nblks
) {
687 ent
->blks
[o
- ent
->startoff
] = b
;
690 if (o
> ent
->startoff
+ ent
->nblks
)
692 blkent_append(entp
, b
, 1);
693 if (entp
== &blkmap
->ents
[blkmap
->nents
- 1])
697 if (ent
->startoff
+ ent
->nblks
< nextent
->startoff
)
699 blkent_append(entp
, nextent
->blks
[0], nextent
->nblks
);
700 blkmap_shrink(blkmap
, &entp
[1]);
703 ent
= blkent_new(o
, b
, 1);
704 blkmap_grow(blkmapp
, entp
, ent
);
720 if (!blkmap
->nents
) {
721 blkmap
->ents
[0] = blkent_new(o
, b
, c
);
725 entp
= &blkmap
->ents
[blkmap
->nents
- 1];
727 if (ent
->startoff
+ ent
->nblks
== o
) {
728 blkent_append(entp
, b
, c
);
731 if (ent
->startoff
+ ent
->nblks
< o
) {
732 ent
= blkent_new(o
, b
, c
);
733 blkmap_grow(blkmapp
, &blkmap
->ents
[blkmap
->nents
], ent
);
736 for (i
= 0; i
< c
; i
++)
737 blkmap_set_blk(blkmapp
, o
+ i
, b
+ i
);
749 idx
= (int)(entp
- blkmap
->ents
);
750 for (i
= idx
+ 1; i
< blkmap
->nents
; i
++)
751 blkmap
->ents
[i
] = blkmap
->ents
[i
- 1];
765 dbprintf(_("block usage information not allocated\n"));
768 rt
= mp
->m_sb
.sb_rextents
!= 0;
769 for (c
= 0; c
< mp
->m_sb
.sb_agcount
; c
++) {
779 sumcompute
= sumfile
= NULL
;
791 * Check consistency of xfs filesystem contents.
803 dbprintf(_("already have block usage information\n"));
807 if (!init(argc
, argv
)) {
814 oldprefix
= dbprefix
;
816 for (agno
= 0, sbyell
= 0; agno
< mp
->m_sb
.sb_agcount
; agno
++) {
818 if (sbver_err
> 4 && !sbyell
&& sbver_err
>= agno
) {
820 dbprintf(_("WARNING: this may be a newer XFS "
831 dbprefix
= oldprefix
;
836 * Check that there are no blocks either
837 * a) unaccounted for or
838 * b) bno-free but not cnt-free
840 if (!tflag
) { /* are we in test mode, faking out freespace? */
841 for (agno
= 0; agno
< mp
->m_sb
.sb_agcount
; agno
++)
842 checknot_dbmap(agno
, 0, mp
->m_sb
.sb_agblocks
,
843 (1 << DBM_UNKNOWN
) | (1 << DBM_FREE1
));
845 for (agno
= 0; agno
< mp
->m_sb
.sb_agcount
; agno
++)
846 check_linkcounts(agno
);
847 if (mp
->m_sb
.sb_rblocks
) {
849 (xfs_extlen_t
)(mp
->m_sb
.sb_rextents
*
850 mp
->m_sb
.sb_rextsize
),
854 if (mp
->m_sb
.sb_icount
!= icount
) {
856 dbprintf(_("sb_icount %lld, counted %lld\n"),
857 mp
->m_sb
.sb_icount
, icount
);
860 if (mp
->m_sb
.sb_ifree
!= ifree
) {
862 dbprintf(_("sb_ifree %lld, counted %lld\n"),
863 mp
->m_sb
.sb_ifree
, ifree
);
866 if (mp
->m_sb
.sb_fdblocks
!= fdblocks
) {
868 dbprintf(_("sb_fdblocks %lld, counted %lld\n"),
869 mp
->m_sb
.sb_fdblocks
, fdblocks
);
872 if (lazycount
&& mp
->m_sb
.sb_fdblocks
!= agf_aggr_freeblks
) {
874 dbprintf(_("sb_fdblocks %lld, aggregate AGF count %lld\n"),
875 mp
->m_sb
.sb_fdblocks
, agf_aggr_freeblks
);
878 if (mp
->m_sb
.sb_frextents
!= frextents
) {
880 dbprintf(_("sb_frextents %lld, counted %lld\n"),
881 mp
->m_sb
.sb_frextents
, frextents
);
884 if (mp
->m_sb
.sb_bad_features2
!= 0 &&
885 mp
->m_sb
.sb_bad_features2
!= mp
->m_sb
.sb_features2
) {
887 dbprintf(_("sb_features2 (0x%x) not same as "
888 "sb_bad_features2 (0x%x)\n"),
889 mp
->m_sb
.sb_features2
,
890 mp
->m_sb
.sb_bad_features2
);
893 if ((sbversion
& XFS_SB_VERSION_ATTRBIT
) &&
896 dbprintf(_("sb versionnum missing attr bit %x\n"),
897 XFS_SB_VERSION_ATTRBIT
);
900 if ((sbversion
& XFS_SB_VERSION_QUOTABIT
) &&
901 !xfs_has_quota(mp
)) {
903 dbprintf(_("sb versionnum missing quota bit %x\n"),
904 XFS_SB_VERSION_QUOTABIT
);
907 if (!(sbversion
& XFS_SB_VERSION_ALIGNBIT
) &&
910 dbprintf(_("sb versionnum extra align bit %x\n"),
911 XFS_SB_VERSION_ALIGNBIT
);
915 quota_check("user", qudata
);
917 quota_check("project", qpdata
);
919 quota_check("group", qgdata
);
920 if (sbver_err
> mp
->m_sb
.sb_agcount
/ 2)
921 dbprintf(_("WARNING: this may be a newer XFS filesystem.\n"));
924 dbprefix
= oldprefix
;
928 typedef struct ltab
{
947 const struct xfs_buf_ops
*stashed_ops
;
948 static char *modestr
[] = {
949 N_("zeroed"), N_("set"), N_("flipped"), N_("randomized")
954 agno
= XFS_FSB_TO_AGNO(mp
, XFS_DADDR_TO_FSB(mp
, iocur_top
->bb
));
955 agbno
= XFS_FSB_TO_AGBNO(mp
, XFS_DADDR_TO_FSB(mp
, iocur_top
->bb
));
956 if (iocur_top
->len
== 0) {
957 dbprintf(_("zero-length block %u/%u buffer to trash??\n"),
961 len
= (int)((random() % (ltabp
->max
- ltabp
->min
+ 1)) + ltabp
->min
);
963 * bit_offset >= 0: start fuzzing at this exact bit_offset.
964 * bit_offset < 0: pick an offset at least as high at -(bit_offset + 1).
966 if (bit_offset
< 0) {
967 bit_offset
= -(bit_offset
+ 1);
968 bit_offset
+= (int)(random() % (int)((iocur_top
->len
- bit_offset
) * NBBY
));
970 if (bit_offset
+ len
>= iocur_top
->len
* NBBY
)
971 len
= (iocur_top
->len
* NBBY
) - bit_offset
;
973 stashed_ops
= iocur_top
->bp
->b_ops
;
974 iocur_top
->bp
->b_ops
= NULL
;
975 if ((buf
= iocur_top
->data
) == NULL
) {
976 dbprintf(_("can't read block %u/%u for trashing\n"), agno
, agbno
);
979 for (bitno
= 0; bitno
< len
; bitno
++) {
980 bit
= (bit_offset
+ bitno
) % (mp
->m_sb
.sb_blocksize
* NBBY
);
992 newbit
= (buf
[byte
] & mask
) == 0;
995 newbit
= (int)random() & 1;
1004 iocur_top
->bp
->b_ops
= stashed_ops
;
1005 printf(_("blocktrash: %u/%u %s block %d bit%s starting %d:%d %s\n"),
1006 agno
, agbno
, typename
[type
], len
, len
== 1 ? "" : "s",
1007 bit_offset
/ NBBY
, bit_offset
% NBBY
, modestr
[mode
]);
1015 xfs_agblock_t agbno
;
1016 xfs_agnumber_t agno
;
1018 xfs_rfsblock_t blocks
;
1031 xfs_rfsblock_t randb
;
1035 bool this_block
= false;
1036 int bit_offset
= -1;
1043 gettimeofday(&now
, NULL
);
1044 seed
= (unsigned int)(now
.tv_sec
^ now
.tv_usec
);
1047 goodmask
= (1 << DBM_AGF
) |
1051 (1 << DBM_BTBMAPA
) |
1052 (1 << DBM_BTBMAPD
) |
1060 (1 << DBM_RTBITMAP
) |
1062 (1 << DBM_SYMLINK
) |
1067 while ((c
= getopt(argc
, argv
, "0123n:o:s:t:x:y:z")) != EOF
) {
1082 count
= (int)strtol(optarg
, &p
, 0);
1083 if (*p
!= '\0' || count
<= 0) {
1084 dbprintf(_("bad blocktrash count %s\n"), optarg
);
1090 if (optarg
[0] == '+') {
1094 bit_offset
= (int)strtol(optarg
, &p
, 0);
1095 if (*p
!= '\0' || bit_offset
< 0) {
1096 dbprintf(_("bad blocktrash offset %s\n"), optarg
);
1100 bit_offset
= -bit_offset
- 1;
1104 seed
= (uint
)strtoul(optarg
, &p
, 0);
1108 for (i
= 0; typename
[i
]; i
++) {
1109 if (strcmp(typename
[i
], optarg
) == 0)
1112 if (!typename
[i
] || (((1 << i
) & goodmask
) == 0)) {
1113 dbprintf(_("bad blocktrash type %s\n"), optarg
);
1119 min
= (int)strtol(optarg
, &p
, 0);
1120 if (*p
!= '\0' || min
<= 0 ||
1121 min
> mp
->m_sb
.sb_blocksize
* NBBY
) {
1122 dbprintf(_("bad blocktrash min %s\n"), optarg
);
1127 max
= (int)strtol(optarg
, &p
, 0);
1128 if (*p
!= '\0' || max
<= 0 ||
1129 max
> mp
->m_sb
.sb_blocksize
* NBBY
) {
1130 dbprintf(_("bad blocktrash max %s\n"), optarg
);
1138 dbprintf(_("bad option for blocktrash command\n"));
1142 if (!this_block
&& !dbmap
) {
1143 dbprintf(_("must run blockget first\n"));
1146 if (this_block
&& iocur_sp
== 0) {
1147 dbprintf(_("nothing on stack\n"));
1151 dbprintf(_("bad min/max for blocktrash command\n"));
1155 tmask
= goodmask
& ~((1 << DBM_LOG
) | (1 << DBM_SB
));
1156 lentab
= xmalloc(sizeof(ltab_t
));
1157 lentab
->min
= lentab
->max
= min
;
1159 for (i
= min
+ 1; i
<= max
; i
++) {
1160 if ((i
& (i
- 1)) == 0) {
1161 lentab
= xrealloc(lentab
,
1162 sizeof(ltab_t
) * (lentablen
+ 1));
1163 lentab
[lentablen
].min
= lentab
[lentablen
].max
= i
;
1166 lentab
[lentablen
- 1].max
= i
;
1169 dbprintf(_("blocktrash: seed %u\n"), seed
);
1172 blocktrash_b(bit_offset
, DBM_UNKNOWN
,
1173 &lentab
[random() % lentablen
], mode
);
1176 for (blocks
= 0, agno
= 0; agno
< mp
->m_sb
.sb_agcount
; agno
++) {
1177 for (agbno
= 0, p
= dbmap
[agno
];
1178 agbno
< mp
->m_sb
.sb_agblocks
;
1180 if ((1 << *p
) & tmask
)
1185 dbprintf(_("blocktrash: no matching blocks\n"));
1188 for (i
= 0; i
< count
; i
++) {
1189 randb
= (xfs_rfsblock_t
)((((int64_t)random() << 32) |
1190 random()) % blocks
);
1191 for (bi
= 0, agno
= 0, done
= 0;
1192 !done
&& agno
< mp
->m_sb
.sb_agcount
;
1194 for (agbno
= 0, p
= dbmap
[agno
];
1195 agbno
< mp
->m_sb
.sb_agblocks
;
1197 if (!((1 << *p
) & tmask
))
1203 XFS_AGB_TO_DADDR(mp
, agno
, agbno
),
1204 blkbb
, DB_RING_IGN
, NULL
);
1205 blocktrash_b(bit_offset
, (dbm_t
)*p
,
1206 &lentab
[random() % lentablen
], mode
);
1223 xfs_agblock_t agbno
;
1224 xfs_agnumber_t agno
;
1234 dbprintf(_("must run blockget first\n"));
1239 fsb
= XFS_DADDR_TO_FSB(mp
, iocur_top
->off
>> BBSHIFT
);
1240 agno
= XFS_FSB_TO_AGNO(mp
, fsb
);
1241 end
= agbno
= XFS_FSB_TO_AGBNO(mp
, fsb
);
1242 while ((c
= getopt(argc
, argv
, "c:n")) != EOF
) {
1245 count
= (int)strtol(optarg
, &p
, 0);
1246 end
= agbno
+ count
- 1;
1247 if (*p
!= '\0' || count
<= 0 ||
1248 end
>= mp
->m_sb
.sb_agblocks
) {
1249 dbprintf(_("bad blockuse count %s\n"), optarg
);
1255 dbprintf(_("must run blockget -n first\n"));
1261 dbprintf(_("bad option for blockuse command\n"));
1265 while (agbno
<= end
) {
1266 p
= &dbmap
[agno
][agbno
];
1267 i
= inomap
[agno
][agbno
];
1268 dbprintf(_("block %llu (%u/%u) type %s"),
1269 (xfs_fsblock_t
)XFS_AGB_TO_FSB(mp
, agno
, agbno
),
1270 agno
, agbno
, typename
[(dbm_t
)*p
]);
1272 dbprintf(_(" inode %lld"), i
->ino
);
1273 if (shownames
&& (p
= inode_name(i
->ino
, NULL
))) {
1290 for (i
= 0; i
< blist_size
; i
++) {
1291 if (blist
[i
] == bno
)
1299 xfs_agnumber_t agno
,
1300 xfs_agblock_t agbno
)
1302 if (agno
>= mp
->m_sb
.sb_agcount
)
1304 if (agbno
>= mp
->m_sb
.sb_agblocks
)
1311 xfs_agnumber_t agno
,
1312 xfs_agblock_t agbno
,
1321 for (i
= 0, p
= &dbmap
[agno
][agbno
]; i
< len
; i
++, p
++) {
1322 if (!dbmap_boundscheck(agno
, agbno
+ i
)) {
1323 dbprintf(_("block %u/%u beyond end of expected area\n"),
1329 if (ignore_reflink
&& (d
== DBM_UNKNOWN
|| d
== DBM_DATA
||
1332 if ((dbm_t
)*p
!= type
) {
1333 if (!sflag
|| CHECK_BLISTA(agno
, agbno
+ i
)) {
1334 dbprintf(_("block %u/%u expected type %s got "
1336 agno
, agbno
+ i
, typename
[type
],
1337 typename
[(dbm_t
)*p
]);
1347 add_command(&blockfree_cmd
);
1348 add_command(&blockget_cmd
);
1350 add_command(&blocktrash_cmd
);
1351 add_command(&blockuse_cmd
);
1352 add_command(&ncheck_cmd
);
1357 xfs_agnumber_t agno
,
1358 xfs_agblock_t agbno
,
1366 if (!check_range(agno
, agbno
, len
)) {
1367 dbprintf(_("blocks %u/%u..%u claimed by inode %lld\n"),
1368 agno
, agbno
, agbno
+ len
- 1, c_ino
);
1371 for (i
= 0, rval
= 1, idp
= &inomap
[agno
][agbno
]; i
< len
; i
++, idp
++) {
1372 if (*idp
&& !(*idp
)->isreflink
) {
1373 if (!sflag
|| (*idp
)->ilist
||
1374 CHECK_BLISTA(agno
, agbno
+ i
))
1375 dbprintf(_("block %u/%u claimed by inode %lld, "
1376 "previous inum %lld\n"),
1377 agno
, agbno
+ i
, c_ino
, (*idp
)->ino
);
1387 xfs_agnumber_t agno
)
1395 for (idx
= 0; idx
< inodata_hash_size
; ht
++, idx
++) {
1398 if (ep
->link_set
!= ep
->link_add
|| ep
->link_set
== 0) {
1399 path
= inode_name(ep
->ino
, NULL
);
1400 if (!path
&& ep
->link_add
)
1401 path
= xstrdup("?");
1402 if (!sflag
|| ep
->ilist
) {
1404 dbprintf(_("link count mismatch "
1405 "for inode %lld (name "
1411 else if (ep
->link_set
)
1412 dbprintf(_("disconnected inode "
1413 "%lld, nlink %d\n"),
1414 ep
->ino
, ep
->link_set
);
1416 dbprintf(_("allocated inode %lld "
1417 "has 0 link count\n"),
1423 } else if (verbose
|| ep
->ilist
) {
1424 path
= inode_name(ep
->ino
, NULL
);
1426 dbprintf(_("inode %lld name %s\n"),
1439 xfs_agnumber_t agno
,
1440 xfs_agblock_t agbno
,
1444 xfs_agblock_t low
= 0;
1445 xfs_agblock_t high
= 0;
1446 int valid_range
= 0;
1449 if (agno
>= mp
->m_sb
.sb_agcount
||
1450 agbno
+ len
- 1 >= mp
->m_sb
.sb_agblocks
) {
1451 for (i
= 0; i
< len
; i
++) {
1452 cur
= !sflag
|| CHECK_BLISTA(agno
, agbno
+ i
) ? 1 : 0;
1453 if (cur
== 1 && prev
== 0) {
1454 low
= high
= agbno
+ i
;
1456 } else if (cur
== 0 && prev
== 0) {
1458 } else if (cur
== 0 && prev
== 1) {
1460 dbprintf(_("block %u/%u out of range\n"),
1463 dbprintf(_("blocks %u/%u..%u "
1468 } else if (cur
== 1 && prev
== 1) {
1475 dbprintf(_("block %u/%u out of range\n"),
1478 dbprintf(_("blocks %u/%u..%u "
1493 return bno
< mp
->m_sb
.sb_rblocks
;
1505 for (i
= 0, p
= &dbmap
[mp
->m_sb
.sb_agcount
][bno
]; i
< len
; i
++, p
++) {
1506 if (!rdbmap_boundscheck(bno
+ i
)) {
1507 dbprintf(_("rtblock %llu beyond end of expected area\n"),
1512 if ((dbm_t
)*p
!= type
) {
1513 if (!sflag
|| CHECK_BLIST(bno
+ i
))
1514 dbprintf(_("rtblock %llu expected type %s got "
1516 bno
+ i
, typename
[type
],
1517 typename
[(dbm_t
)*p
]);
1533 if (!check_rrange(bno
, len
)) {
1534 dbprintf(_("rtblocks %llu..%llu claimed by inode %lld\n"),
1535 bno
, bno
+ len
- 1, c_ino
);
1538 for (i
= 0, rval
= 1, idp
= &inomap
[mp
->m_sb
.sb_agcount
][bno
];
1542 if (!sflag
|| (*idp
)->ilist
|| CHECK_BLIST(bno
+ i
))
1543 dbprintf(_("rtblock %llu claimed by inode %lld, "
1544 "previous inum %lld\n"),
1545 bno
+ i
, c_ino
, (*idp
)->ino
);
1558 id
= find_inode(mp
->m_sb
.sb_rootino
, 0);
1561 dbprintf(_("root inode %lld is missing\n"),
1562 mp
->m_sb
.sb_rootino
);
1564 } else if (!id
->isdir
) {
1565 if (!sflag
|| id
->ilist
)
1566 dbprintf(_("root inode %lld is not a directory\n"),
1567 mp
->m_sb
.sb_rootino
);
1575 xfs_rfsblock_t high
)
1578 dbprintf(_("rtblock %llu out of range\n"), low
);
1580 dbprintf(_("rtblocks %llu..%llu out of range\n"), low
, high
);
1589 xfs_rfsblock_t low
= 0;
1590 xfs_rfsblock_t high
= 0;
1591 bool valid_range
= false;
1594 if (bno
+ len
- 1 >= mp
->m_sb
.sb_rblocks
) {
1595 for (i
= 0; i
< len
; i
++) {
1596 cur
= !sflag
|| CHECK_BLIST(bno
+ i
) ? 1 : 0;
1597 if (cur
== 1 && prev
== 0) {
1598 low
= high
= bno
+ i
;
1600 } else if (cur
== 0 && prev
== 0) {
1602 } else if (cur
== 0 && prev
== 1) {
1603 report_rrange(low
, high
);
1604 valid_range
= false;
1605 } else if (cur
== 1 && prev
== 1) {
1611 report_rrange(low
, high
);
1619 * We don't check the accuracy of reference counts -- all we do is ensure
1620 * that a data block never crosses with non-data blocks. repair can check
1621 * those kinds of things.
1623 * So with that in mind, if we're setting a block to be data or rldata,
1624 * don't complain so long as the block is currently unknown, data, or rldata.
1625 * Don't let blocks downgrade from rldata -> data.
1631 if (!xfs_has_reflink(mp
))
1633 if (type2
== DBM_DATA
|| type2
== DBM_RLDATA
)
1640 xfs_agnumber_t agno
,
1641 xfs_agblock_t agbno
,
1645 xfs_agnumber_t c_agno
,
1646 xfs_agblock_t c_agbno
)
1652 if (!check_range(agno
, agbno
, len
)) {
1653 dbprintf(_("blocks %u/%u..%u claimed by block %u/%u\n"), agno
,
1654 agbno
, agbno
+ len
- 1, c_agno
, c_agbno
);
1657 check_dbmap(agno
, agbno
, len
, type1
, is_reflink(type2
));
1658 mayprint
= verbose
| blist_size
;
1659 for (i
= 0, p
= &dbmap
[agno
][agbno
]; i
< len
; i
++, p
++) {
1660 if (!dbmap_boundscheck(agno
, agbno
+ i
)) {
1661 dbprintf(_("block %u/%u beyond end of expected area\n"),
1666 if (*p
== DBM_RLDATA
&& type2
== DBM_DATA
)
1668 else if (*p
== DBM_DATA
&& type2
== DBM_DATA
)
1669 *p
= (char)DBM_RLDATA
;
1672 if (mayprint
&& (verbose
|| CHECK_BLISTA(agno
, agbno
+ i
)))
1673 dbprintf(_("setting block %u/%u to %s\n"), agno
, agbno
+ i
,
1689 if (!check_rrange(bno
, len
))
1691 check_rdbmap(bno
, len
, type1
);
1692 mayprint
= verbose
| blist_size
;
1693 for (i
= 0, p
= &dbmap
[mp
->m_sb
.sb_agcount
][bno
]; i
< len
; i
++, p
++) {
1694 if (!rdbmap_boundscheck(bno
+ i
)) {
1695 dbprintf(_("rtblock %llu beyond end of expected area\n"),
1701 if (mayprint
&& (verbose
|| CHECK_BLIST(bno
+ i
)))
1702 dbprintf(_("setting rtblock %llu to %s\n"),
1703 bno
+ i
, typename
[type2
]);
1707 static inline xfs_suminfo_t
1709 struct xfs_mount
*mp
,
1710 union xfs_suminfo_raw
*raw
)
1719 union xfs_suminfo_raw
*csp
;
1720 union xfs_suminfo_raw
*fsp
;
1725 for (log
= 0; log
< mp
->m_rsumlevels
; log
++) {
1727 bno
< mp
->m_sb
.sb_rbmblocks
;
1728 bno
++, csp
++, fsp
++) {
1729 if (csp
->old
!= fsp
->old
) {
1731 dbprintf(_("rt summary mismatch, size %d "
1732 "block %llu, file: %d, "
1735 get_suminfo(mp
, fsp
),
1736 get_suminfo(mp
, csp
));
1745 xfs_agnumber_t agno
,
1746 xfs_agblock_t agbno
,
1753 if (!check_range(agno
, agbno
, len
))
1755 for (i
= 0, p
= &dbmap
[agno
][agbno
]; i
< len
; i
++, p
++) {
1756 if ((1 << *p
) & typemask
) {
1757 if (!sflag
|| CHECK_BLISTA(agno
, agbno
+ i
))
1758 dbprintf(_("block %u/%u type %s not expected\n"),
1759 agno
, agbno
+ i
, typename
[(dbm_t
)*p
]);
1774 if (!check_rrange(bno
, len
))
1776 for (i
= 0, p
= &dbmap
[mp
->m_sb
.sb_agcount
][bno
]; i
< len
; i
++, p
++) {
1777 if ((1 << *p
) & typemask
) {
1778 if (!sflag
|| CHECK_BLIST(bno
+ i
))
1779 dbprintf(_("rtblock %llu type %s not expected\n"),
1780 bno
+ i
, typename
[(dbm_t
)*p
]);
1789 xfs_dir2_dataptr_t addr
)
1794 i
= DIR_HASH_FUNC(hash
, addr
);
1795 p
= malloc(sizeof(*p
));
1796 p
->next
= dirhash
[i
];
1811 for (i
= 0; i
< DIR_HASH_SIZE
; i
++) {
1812 for (p
= dirhash
[i
]; p
; p
= p
->next
) {
1815 if (!sflag
|| id
->ilist
|| v
)
1816 dbprintf(_("dir ino %lld missing leaf entry for "
1818 id
->ino
, p
->hashval
, p
->address
);
1831 for (i
= 0; i
< DIR_HASH_SIZE
; i
++) {
1832 for (p
= dirhash
[i
]; p
; p
= n
) {
1844 dirhash
= calloc(DIR_HASH_SIZE
, sizeof(*dirhash
));
1850 xfs_dir2_dataptr_t addr
)
1855 i
= DIR_HASH_FUNC(hash
, addr
);
1856 for (p
= dirhash
[i
]; p
; p
= p
->next
) {
1857 if (p
->hashval
== hash
&& p
->address
== addr
) {
1873 xfs_agnumber_t agno
;
1878 agno
= XFS_INO_TO_AGNO(mp
, ino
);
1879 agino
= XFS_INO_TO_AGINO(mp
, ino
);
1880 if (agno
>= mp
->m_sb
.sb_agcount
||
1881 XFS_AGINO_TO_INO(mp
, agno
, agino
) != ino
)
1883 htab
= inodata
[agno
];
1884 ih
= agino
% inodata_hash_size
;
1887 if (ent
->ino
== ino
)
1893 ent
= xcalloc(1, sizeof(*ent
));
1895 ent
->next
= htab
[ih
];
1902 xfs_agnumber_t agno
)
1910 for (i
= 0; i
< inodata_hash_size
; i
++) {
1934 if (mp
->m_sb
.sb_magicnum
!= XFS_SB_MAGIC
) {
1935 dbprintf(_("bad superblock magic number %x, giving up\n"),
1936 mp
->m_sb
.sb_magicnum
);
1942 rt
= mp
->m_sb
.sb_rextents
!= 0;
1943 dbmap
= xmalloc((mp
->m_sb
.sb_agcount
+ rt
) * sizeof(*dbmap
));
1944 inomap
= xmalloc((mp
->m_sb
.sb_agcount
+ rt
) * sizeof(*inomap
));
1945 inodata
= xmalloc(mp
->m_sb
.sb_agcount
* sizeof(*inodata
));
1947 (int)max(min(mp
->m_sb
.sb_icount
/
1948 (INODATA_AVG_HASH_LENGTH
* mp
->m_sb
.sb_agcount
),
1949 MAX_INODATA_HASH_SIZE
),
1950 MIN_INODATA_HASH_SIZE
);
1951 for (c
= 0; c
< mp
->m_sb
.sb_agcount
; c
++) {
1952 dbmap
[c
] = xcalloc(mp
->m_sb
.sb_agblocks
, sizeof(**dbmap
));
1953 inomap
[c
] = xcalloc(mp
->m_sb
.sb_agblocks
, sizeof(**inomap
));
1954 inodata
[c
] = xcalloc(inodata_hash_size
, sizeof(**inodata
));
1957 unsigned long long words
;
1959 dbmap
[c
] = xcalloc(mp
->m_sb
.sb_rblocks
, sizeof(**dbmap
));
1960 inomap
[c
] = xcalloc(mp
->m_sb
.sb_rblocks
, sizeof(**inomap
));
1961 words
= libxfs_rtsummary_wordcount(mp
, mp
->m_rsumlevels
,
1962 mp
->m_sb
.sb_rbmblocks
);
1963 sumfile
= xcalloc(words
, sizeof(union xfs_suminfo_raw
));
1964 sumcompute
= xcalloc(words
, sizeof(union xfs_suminfo_raw
));
1966 nflag
= sflag
= tflag
= verbose
= optind
= 0;
1967 while ((c
= getopt(argc
, argv
, "b:i:npstv")) != EOF
) {
1970 bno
= strtoll(optarg
, NULL
, 10);
1974 ino
= strtoll(optarg
, NULL
, 10);
1993 dbprintf(_("bad option for blockget command\n"));
1997 error
= sbver_err
= serious_error
= 0;
1998 fdblocks
= frextents
= icount
= ifree
= 0;
1999 sbversion
= XFS_SB_VERSION_4
;
2001 * Note that inoalignmt == 0 is valid when fsb size is large enough for
2002 * at least one full inode record per block. Check this case explicitly.
2004 if (mp
->m_sb
.sb_inoalignmt
||
2005 (xfs_has_align(mp
) &&
2006 mp
->m_sb
.sb_inopblock
>= XFS_INODES_PER_CHUNK
))
2007 sbversion
|= XFS_SB_VERSION_ALIGNBIT
;
2008 if ((mp
->m_sb
.sb_uquotino
&& mp
->m_sb
.sb_uquotino
!= NULLFSINO
) ||
2009 (mp
->m_sb
.sb_gquotino
&& mp
->m_sb
.sb_gquotino
!= NULLFSINO
) ||
2010 (mp
->m_sb
.sb_pquotino
&& mp
->m_sb
.sb_pquotino
!= NULLFSINO
))
2011 sbversion
|= XFS_SB_VERSION_QUOTABIT
;
2025 id
= find_inode(ino
, 0);
2030 if (id
->name
== NULL
)
2032 path
= xstrdup(id
->name
);
2033 while (id
->parent
) {
2035 if (id
->name
== NULL
)
2037 npath
= prepend_path(path
, id
->name
);
2049 xfs_agnumber_t agno
;
2062 if (!inodata
|| !nflag
) {
2063 dbprintf(_("must run blockget -n first\n"));
2066 security
= optind
= ilist_size
= 0;
2068 while ((c
= getopt(argc
, argv
, "i:s")) != EOF
) {
2071 ino
= strtoll(optarg
, NULL
, 10);
2072 ilist
= xrealloc(ilist
, (ilist_size
+ 1) *
2074 ilist
[ilist_size
++] = ino
;
2080 dbprintf(_("bad option -%c for ncheck command\n"), c
);
2086 for (ilp
= ilist
; ilp
< &ilist
[ilist_size
]; ilp
++) {
2088 if ((p
= inode_name(ino
, &hp
))) {
2089 dbprintf("%11llu %s", ino
, p
);
2099 for (agno
= 0; agno
< mp
->m_sb
.sb_agcount
; agno
++) {
2101 for (i
= 0; i
< inodata_hash_size
; i
++) {
2103 for (hp
= ht
[i
]; hp
; hp
= hp
->next
) {
2104 ino
= XFS_AGINO_TO_INO(mp
, agno
, hp
->ino
);
2105 p
= inode_name(ino
, &id
);
2108 if (!security
|| id
->security
) {
2109 dbprintf("%11llu %s", ino
, p
);
2129 len
= (int)(strlen(oldpath
) + strlen(parent
) + 2);
2130 path
= xmalloc(len
);
2131 snprintf(path
, len
, "%s/%s", parent
, oldpath
);
2136 process_block_dir_v2(
2150 nex
= blkmap_getn(blkmap
, 0, mp
->m_dir_geo
->fsbcount
, &bmp
);
2151 v
= id
->ilist
|| verbose
;
2154 dbprintf(_("block 0 for directory inode %lld is "
2162 make_bbmap(&bbmap
, nex
, bmp
);
2163 set_cur(&typtab
[TYP_DIR2
], XFS_FSB_TO_DADDR(mp
, bmp
->startblock
),
2164 mp
->m_dir_geo
->fsbcount
* blkbb
, DB_RING_IGN
, nex
> 1 ? &bbmap
: NULL
);
2165 for (i
= 0; !v
&& i
< nex
; i
++) {
2166 for (b
= bmp
[i
].startblock
;
2167 !v
&& b
< bmp
[i
].startblock
+ bmp
[i
].blockcount
;
2172 if (iocur_top
->data
== NULL
) {
2173 if (!sflag
|| id
->ilist
|| v
)
2174 dbprintf(_("can't read block 0 for directory inode "
2182 parent
= process_data_dir_v2(dot
, dotdot
, id
, v
, mp
->m_dir_geo
->datablk
,
2184 dir_hash_check(id
, v
);
2191 process_bmbt_reclist(
2193 xfs_extnum_t numrecs
,
2196 xfs_rfsblock_t
*tot
,
2199 xfs_agblock_t agbno
;
2200 xfs_agnumber_t agno
;
2206 xfs_agblock_t iagbno
;
2207 xfs_agnumber_t iagno
;
2214 v
= verbose
|| id
->ilist
;
2215 iagno
= XFS_INO_TO_AGNO(mp
, id
->ino
);
2216 iagbno
= XFS_INO_TO_AGBNO(mp
, id
->ino
);
2217 for (i
= 0; i
< numrecs
; i
++, rp
++) {
2218 convert_extent(rp
, &o
, &s
, &c
, &f
);
2220 dbprintf(_("inode %lld extent [%lld,%lld,%lld,%d]\n"),
2221 id
->ino
, o
, s
, c
, f
);
2222 if (!sflag
&& i
> 0 && op
+ cp
> o
)
2223 dbprintf(_("bmap rec out of order, inode %lld entry %d\n"),
2227 if (type
== DBM_RTDATA
) {
2228 if (!sflag
&& s
>= mp
->m_sb
.sb_rblocks
) {
2229 dbprintf(_("inode %lld bad rt block number %lld, "
2234 } else if (!sflag
) {
2235 agno
= XFS_FSB_TO_AGNO(mp
, s
);
2236 agbno
= XFS_FSB_TO_AGBNO(mp
, s
);
2237 if (agno
>= mp
->m_sb
.sb_agcount
||
2238 agbno
>= mp
->m_sb
.sb_agblocks
) {
2239 dbprintf(_("inode %lld bad block number %lld "
2240 "[%d,%d], offset %lld\n"),
2241 id
->ino
, s
, agno
, agbno
, o
);
2244 if (agbno
+ c
- 1 >= mp
->m_sb
.sb_agblocks
) {
2245 dbprintf(_("inode %lld bad block number %lld "
2246 "[%d,%d], offset %lld\n"),
2247 id
->ino
, s
+ c
- 1, agno
,
2248 agbno
+ (xfs_agblock_t
)c
- 1, o
);
2252 if (blkmapp
&& *blkmapp
)
2253 blkmap_set_ext(blkmapp
, (xfs_fileoff_t
)o
,
2254 (xfs_fsblock_t
)s
, (xfs_extlen_t
)c
);
2255 if (type
== DBM_RTDATA
) {
2256 set_rdbmap((xfs_fsblock_t
)s
, (xfs_extlen_t
)c
,
2258 set_rinomap((xfs_fsblock_t
)s
, (xfs_extlen_t
)c
, id
);
2259 for (b
= (xfs_fsblock_t
)s
;
2260 blist_size
&& b
< s
+ c
;
2263 dbprintf(_("inode %lld block %lld at "
2265 id
->ino
, (xfs_fsblock_t
)b
, o
);
2268 agno
= XFS_FSB_TO_AGNO(mp
, (xfs_fsblock_t
)s
);
2269 agbno
= XFS_FSB_TO_AGBNO(mp
, (xfs_fsblock_t
)s
);
2270 set_dbmap(agno
, agbno
, (xfs_extlen_t
)c
, type
, iagno
,
2272 set_inomap(agno
, agbno
, (xfs_extlen_t
)c
, id
);
2273 for (b
= (xfs_fsblock_t
)s
;
2274 blist_size
&& b
< s
+ c
;
2275 b
++, o
++, agbno
++) {
2277 dbprintf(_("inode %lld block %lld at "
2279 id
->ino
, (xfs_fsblock_t
)b
, o
);
2289 struct xfs_dinode
*dip
,
2291 xfs_rfsblock_t
*totd
,
2292 xfs_rfsblock_t
*toti
,
2297 xfs_bmdr_block_t
*dib
;
2301 dib
= (xfs_bmdr_block_t
*)XFS_DFORK_PTR(dip
, whichfork
);
2302 if (be16_to_cpu(dib
->bb_level
) >= XFS_BM_MAXLEVELS(mp
, whichfork
)) {
2303 if (!sflag
|| id
->ilist
)
2304 dbprintf(_("level for ino %lld %s fork bmap root too "
2307 whichfork
== XFS_DATA_FORK
? _("data") : _("attr"),
2308 be16_to_cpu(dib
->bb_level
));
2312 if (be16_to_cpu(dib
->bb_numrecs
) >
2313 libxfs_bmdr_maxrecs(XFS_DFORK_SIZE(dip
, mp
, whichfork
),
2314 be16_to_cpu(dib
->bb_level
) == 0)) {
2315 if (!sflag
|| id
->ilist
)
2316 dbprintf(_("numrecs for ino %lld %s fork bmap root too "
2319 whichfork
== XFS_DATA_FORK
? _("data") : _("attr"),
2320 be16_to_cpu(dib
->bb_numrecs
));
2324 if (be16_to_cpu(dib
->bb_level
) == 0) {
2325 xfs_bmbt_rec_t
*rp
= XFS_BMDR_REC_ADDR(dib
, 1);
2326 process_bmbt_reclist(rp
, be16_to_cpu(dib
->bb_numrecs
), type
,
2328 *nex
+= be16_to_cpu(dib
->bb_numrecs
);
2331 pp
= XFS_BMDR_PTR_ADDR(dib
, 1, libxfs_bmdr_maxrecs(
2332 XFS_DFORK_SIZE(dip
, mp
, whichfork
), 0));
2333 for (i
= 0; i
< be16_to_cpu(dib
->bb_numrecs
); i
++)
2334 scan_lbtree(get_unaligned_be64(&pp
[i
]),
2335 be16_to_cpu(dib
->bb_level
),
2336 scanfunc_bmap
, type
, id
, totd
, toti
,
2338 whichfork
== XFS_DATA_FORK
?
2339 TYP_BMAPBTD
: TYP_BMAPBTA
);
2341 if (*nex
<= XFS_DFORK_SIZE(dip
, mp
, whichfork
) / sizeof(xfs_bmbt_rec_t
)) {
2342 if (!sflag
|| id
->ilist
)
2343 dbprintf(_("extent count for ino %lld %s fork too low "
2344 "(%d) for file format\n"),
2346 whichfork
== XFS_DATA_FORK
? _("data") : _("attr"),
2353 process_data_dir_v2(
2359 freetab_t
**freetabp
)
2361 xfs_dir2_dataptr_t addr
;
2362 xfs_dir2_data_free_t
*bf
;
2364 struct xfs_dir2_data_hdr
*block
;
2365 xfs_dir2_block_tail_t
*btp
= NULL
;
2368 struct xfs_dir2_data_hdr
*data
;
2370 xfs_dir2_data_entry_t
*dep
;
2371 xfs_dir2_data_free_t
*dfp
;
2372 xfs_dir2_data_unused_t
*dup
;
2379 xfs_dir2_leaf_entry_t
*lep
= NULL
;
2381 xfs_ino_t parent
= 0;
2386 struct xfs_name xname
;
2388 data
= iocur_top
->data
;
2389 block
= iocur_top
->data
;
2390 if (be32_to_cpu(block
->magic
) != XFS_DIR2_BLOCK_MAGIC
&&
2391 be32_to_cpu(data
->magic
) != XFS_DIR2_DATA_MAGIC
&&
2392 be32_to_cpu(block
->magic
) != XFS_DIR3_BLOCK_MAGIC
&&
2393 be32_to_cpu(data
->magic
) != XFS_DIR3_DATA_MAGIC
) {
2395 dbprintf(_("bad directory data magic # %#x for dir ino "
2397 be32_to_cpu(data
->magic
), id
->ino
, dabno
);
2401 db
= xfs_dir2_da_to_db(mp
->m_dir_geo
, dabno
);
2402 bf
= libxfs_dir2_data_bestfree_p(mp
, data
);
2403 ptr
= (char *)data
+ mp
->m_dir_geo
->data_entry_offset
;
2404 if (be32_to_cpu(block
->magic
) == XFS_DIR2_BLOCK_MAGIC
||
2405 be32_to_cpu(block
->magic
) == XFS_DIR3_BLOCK_MAGIC
) {
2406 btp
= xfs_dir2_block_tail_p(mp
->m_dir_geo
, block
);
2407 lep
= xfs_dir2_block_leaf_p(btp
);
2408 endptr
= (char *)lep
;
2409 if (endptr
<= ptr
|| endptr
> (char *)btp
) {
2410 endptr
= (char *)data
+ mp
->m_dir_geo
->blksize
;
2413 dbprintf(_("bad block directory tail for dir ino "
2419 endptr
= (char *)data
+ mp
->m_dir_geo
->blksize
;
2420 bf_err
= lastfree_err
= tag_err
= 0;
2421 count
= lastfree
= freeseen
= 0;
2422 if (be16_to_cpu(bf
[0].length
) == 0) {
2423 bf_err
+= be16_to_cpu(bf
[0].offset
) != 0;
2426 if (be16_to_cpu(bf
[1].length
) == 0) {
2427 bf_err
+= be16_to_cpu(bf
[1].offset
) != 0;
2430 if (be16_to_cpu(bf
[2].length
) == 0) {
2431 bf_err
+= be16_to_cpu(bf
[2].offset
) != 0;
2434 bf_err
+= be16_to_cpu(bf
[0].length
) < be16_to_cpu(bf
[1].length
);
2435 bf_err
+= be16_to_cpu(bf
[1].length
) < be16_to_cpu(bf
[2].length
);
2437 freetab
= *freetabp
;
2438 if (freetab
->naents
<= db
) {
2439 *freetabp
= freetab
=
2440 realloc(freetab
, FREETAB_SIZE(db
+ 1));
2441 for (i
= freetab
->naents
; i
< db
; i
++)
2442 freetab
->ents
[i
] = NULLDATAOFF
;
2443 freetab
->naents
= db
+ 1;
2445 if (freetab
->nents
< db
+ 1)
2446 freetab
->nents
= db
+ 1;
2447 freetab
->ents
[db
] = be16_to_cpu(bf
[0].length
);
2449 while (ptr
< endptr
) {
2450 dup
= (xfs_dir2_data_unused_t
*)ptr
;
2451 if (be16_to_cpu(dup
->freetag
) == XFS_DIR2_DATA_FREE_TAG
) {
2452 lastfree_err
+= lastfree
!= 0;
2453 tagp
= xfs_dir2_data_unused_tag_p(dup
);
2454 if ((be16_to_cpu(dup
->length
) & (XFS_DIR2_DATA_ALIGN
- 1)) ||
2455 be16_to_cpu(dup
->length
) == 0 ||
2456 (char *)tagp
>= endptr
) {
2458 dbprintf(_("dir %lld block %d bad free "
2466 tag_err
+= be16_to_cpu(*tagp
) != (char *)dup
- (char *)data
;
2467 dfp
= process_data_dir_v2_freefind(data
, dup
);
2469 i
= (int)(dfp
- bf
);
2470 bf_err
+= (freeseen
& (1 << i
)) != 0;
2473 bf_err
+= be16_to_cpu(dup
->length
) >
2474 be16_to_cpu(bf
[2].length
);
2475 ptr
+= be16_to_cpu(dup
->length
);
2479 dep
= (xfs_dir2_data_entry_t
*)dup
;
2480 if (dep
->namelen
== 0) {
2482 dbprintf(_("dir %lld block %d zero length entry "
2485 (int)((char *)dep
- (char *)data
));
2488 tagp
= libxfs_dir2_data_entry_tag_p(mp
, dep
);
2489 if ((char *)tagp
>= endptr
) {
2491 dbprintf(_("dir %lld block %d bad entry at %d\n"),
2493 (int)((char *)dep
- (char *)data
));
2497 tag_err
+= be16_to_cpu(*tagp
) != (char *)dep
- (char *)data
;
2498 addr
= xfs_dir2_db_off_to_dataptr(mp
->m_dir_geo
, db
,
2499 (char *)dep
- (char *)data
);
2500 xname
.name
= dep
->name
;
2501 xname
.len
= dep
->namelen
;
2502 dir_hash_add(libxfs_dir2_hashname(mp
, &xname
), addr
);
2503 ptr
+= libxfs_dir2_data_entsize(mp
, dep
->namelen
);
2506 lino
= be64_to_cpu(dep
->inumber
);
2507 cid
= find_inode(lino
, 1);
2509 dbprintf(_("dir %lld block %d entry %*.*s %lld\n"),
2510 id
->ino
, dabno
, dep
->namelen
, dep
->namelen
,
2516 dbprintf(_("dir %lld block %d entry %*.*s bad "
2517 "inode number %lld\n"),
2518 id
->ino
, dabno
, dep
->namelen
,
2519 dep
->namelen
, dep
->name
, lino
);
2522 if (dep
->namelen
== 2 && dep
->name
[0] == '.' &&
2523 dep
->name
[1] == '.') {
2526 dbprintf(_("multiple .. entries in dir "
2527 "%lld (%lld, %lld)\n"),
2528 id
->ino
, parent
, lino
);
2531 parent
= cid
? lino
: NULLFSINO
;
2533 } else if (dep
->namelen
!= 1 || dep
->name
[0] != '.') {
2537 addname_inode(cid
, (char *)dep
->name
,
2541 if (lino
!= id
->ino
) {
2543 dbprintf(_("dir %lld entry . inode "
2544 "number mismatch (%lld)\n"),
2551 if (be32_to_cpu(data
->magic
) == XFS_DIR2_BLOCK_MAGIC
||
2552 be32_to_cpu(data
->magic
) == XFS_DIR3_BLOCK_MAGIC
) {
2553 endptr
= (char *)data
+ mp
->m_dir_geo
->blksize
;
2554 for (i
= stale
= 0; lep
&& i
< be32_to_cpu(btp
->count
); i
++) {
2555 if ((char *)&lep
[i
] >= endptr
) {
2557 dbprintf(_("dir %lld block %d bad count "
2558 "%u\n"), id
->ino
, dabno
,
2559 be32_to_cpu(btp
->count
));
2563 if (be32_to_cpu(lep
[i
].address
) == XFS_DIR2_NULL_DATAPTR
)
2565 else if (dir_hash_see(be32_to_cpu(lep
[i
].hashval
),
2566 be32_to_cpu(lep
[i
].address
))) {
2568 dbprintf(_("dir %lld block %d extra leaf "
2571 be32_to_cpu(lep
[i
].hashval
),
2572 be32_to_cpu(lep
[i
].address
));
2577 bf_err
+= freeseen
!= 7;
2580 dbprintf(_("dir %lld block %d bad bestfree data\n"),
2584 if ((be32_to_cpu(data
->magic
) == XFS_DIR2_BLOCK_MAGIC
||
2585 be32_to_cpu(data
->magic
) == XFS_DIR3_BLOCK_MAGIC
) &&
2586 count
!= be32_to_cpu(btp
->count
) - be32_to_cpu(btp
->stale
)) {
2588 dbprintf(_("dir %lld block %d bad block tail count %d "
2590 id
->ino
, dabno
, be32_to_cpu(btp
->count
),
2591 be32_to_cpu(btp
->stale
));
2594 if ((be32_to_cpu(data
->magic
) == XFS_DIR2_BLOCK_MAGIC
||
2595 be32_to_cpu(data
->magic
) == XFS_DIR3_BLOCK_MAGIC
) &&
2596 stale
!= be32_to_cpu(btp
->stale
)) {
2598 dbprintf(_("dir %lld block %d bad stale tail count %d\n"),
2599 id
->ino
, dabno
, be32_to_cpu(btp
->stale
));
2604 dbprintf(_("dir %lld block %d consecutive free entries\n"),
2610 dbprintf(_("dir %lld block %d entry/unused tag "
2618 static xfs_dir2_data_free_t
*
2619 process_data_dir_v2_freefind(
2620 struct xfs_dir2_data_hdr
*data
,
2621 xfs_dir2_data_unused_t
*dup
)
2623 struct xfs_dir2_data_free
*bf
;
2624 struct xfs_dir2_data_free
*dfp
;
2625 xfs_dir2_data_aoff_t off
;
2627 off
= (xfs_dir2_data_aoff_t
)((char *)dup
- (char *)data
);
2628 bf
= libxfs_dir2_data_bestfree_p(mp
, data
);
2629 if (be16_to_cpu(dup
->length
) <
2630 be16_to_cpu(bf
[XFS_DIR2_DATA_FD_COUNT
- 1].length
))
2632 for (dfp
= bf
; dfp
< &bf
[XFS_DIR2_DATA_FD_COUNT
]; dfp
++) {
2633 if (be16_to_cpu(dfp
->offset
) == 0)
2635 if (be16_to_cpu(dfp
->offset
) == off
)
2643 struct xfs_dinode
*dip
,
2653 if (process_dir_v2(dip
, blkmap
, &dot
, &dotdot
, id
, &parent
))
2656 bno
= XFS_INO_TO_FSB(mp
, id
->ino
);
2658 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
2659 dbprintf(_("no . entry for directory %lld\n"), id
->ino
);
2663 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
2664 dbprintf(_("no .. entry for directory %lld\n"), id
->ino
);
2666 } else if (parent
== id
->ino
&& id
->ino
!= mp
->m_sb
.sb_rootino
) {
2667 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
2668 dbprintf(_(". and .. same for non-root directory %lld\n"),
2671 } else if (id
->ino
== mp
->m_sb
.sb_rootino
&& id
->ino
!= parent
) {
2672 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
2673 dbprintf(_("root directory %lld has .. %lld\n"), id
->ino
,
2676 } else if (parent
!= NULLFSINO
&& id
->ino
!= parent
)
2677 addparent_inode(id
, parent
);
2682 struct xfs_dinode
*dip
,
2689 xfs_fileoff_t last
= 0;
2690 xfs_fsize_t size
= be64_to_cpu(dip
->di_size
);
2693 last
= blkmap_last_off(blkmap
);
2694 if (size
<= XFS_DFORK_DSIZE(dip
, mp
) &&
2695 dip
->di_format
== XFS_DINODE_FMT_LOCAL
)
2696 *parent
= process_sf_dir_v2(dip
, dot
, dotdot
, id
);
2697 else if (last
== mp
->m_dir_geo
->fsbcount
&&
2698 (dip
->di_format
== XFS_DINODE_FMT_EXTENTS
||
2699 dip
->di_format
== XFS_DINODE_FMT_BTREE
))
2700 *parent
= process_block_dir_v2(blkmap
, dot
, dotdot
, id
);
2701 else if (last
>= mp
->m_dir_geo
->leafblk
+ mp
->m_dir_geo
->fsbcount
&&
2702 (dip
->di_format
== XFS_DINODE_FMT_EXTENTS
||
2703 dip
->di_format
== XFS_DINODE_FMT_BTREE
))
2704 *parent
= process_leaf_node_dir_v2(blkmap
, dot
, dotdot
, id
, size
);
2706 dbprintf(_("bad size (%lld) or format (%d) for directory inode "
2708 size
, dip
->di_format
, id
->ino
);
2719 struct xfs_dinode
*dip
,
2721 xfs_rfsblock_t
*totd
,
2722 xfs_rfsblock_t
*toti
,
2728 xfs_extnum_t max_nex
;
2730 rp
= (xfs_bmbt_rec_t
*)XFS_DFORK_PTR(dip
, whichfork
);
2731 *nex
= xfs_dfork_nextents(dip
, whichfork
);
2732 max_nex
= xfs_iext_max_nextents(
2733 xfs_dinode_has_large_extent_counts(dip
),
2735 if (*nex
> max_nex
|| *nex
> XFS_DFORK_SIZE(dip
, mp
, whichfork
) /
2736 sizeof(xfs_bmbt_rec_t
)) {
2737 if (!sflag
|| id
->ilist
)
2738 dbprintf(_("bad number of extents %llu for inode %lld\n"),
2739 (unsigned long long)*nex
, id
->ino
);
2743 process_bmbt_reclist(rp
, *nex
, type
, id
, totd
, blkmapp
);
2750 struct xfs_dinode
*dip
,
2754 xfs_fsblock_t bno
= 0;
2755 inodata_t
*id
= NULL
;
2757 xfs_extnum_t nextents
= 0;
2758 xfs_extnum_t dnextents
;
2760 xfs_rfsblock_t totblocks
;
2761 xfs_rfsblock_t totdblocks
= 0;
2762 xfs_rfsblock_t totiblocks
= 0;
2764 xfs_extnum_t anextents
= 0;
2765 xfs_extnum_t danextents
;
2766 xfs_rfsblock_t atotdblocks
= 0;
2767 xfs_rfsblock_t atotiblocks
= 0;
2774 uint64_t diflags2
= 0;
2779 static char okfmts
[] = {
2780 0, /* type 0 unused */
2781 1 << XFS_DINODE_FMT_DEV
, /* FIFO */
2782 1 << XFS_DINODE_FMT_DEV
, /* CHR */
2783 0, /* type 3 unused */
2784 (1 << XFS_DINODE_FMT_LOCAL
) |
2785 (1 << XFS_DINODE_FMT_EXTENTS
) |
2786 (1 << XFS_DINODE_FMT_BTREE
), /* DIR */
2787 0, /* type 5 unused */
2788 1 << XFS_DINODE_FMT_DEV
, /* BLK */
2789 0, /* type 7 unused */
2790 (1 << XFS_DINODE_FMT_EXTENTS
) |
2791 (1 << XFS_DINODE_FMT_BTREE
), /* REG */
2792 0, /* type 9 unused */
2793 (1 << XFS_DINODE_FMT_LOCAL
) |
2794 (1 << XFS_DINODE_FMT_EXTENTS
), /* LNK */
2795 0, /* type 11 unused */
2796 1 << XFS_DINODE_FMT_DEV
, /* SOCK */
2797 0, /* type 13 unused */
2798 1 << XFS_DINODE_FMT_UUID
, /* MNT */
2799 0 /* type 15 unused */
2801 static char *fmtnames
[] = {
2802 "dev", "local", "extents", "btree", "uuid"
2805 ino
= XFS_AGINO_TO_INO(mp
, be32_to_cpu(agf
->agf_seqno
), agino
);
2807 id
= find_inode(ino
, 1);
2808 bno
= XFS_INO_TO_FSB(mp
, ino
);
2811 v
= (!sflag
|| (id
&& id
->ilist
) || CHECK_BLIST(bno
));
2812 if (dip
->di_magic
!= cpu_to_be16(XFS_DINODE_MAGIC
)) {
2814 dbprintf(_("bad magic number %#x for inode %lld\n"),
2815 be16_to_cpu(dip
->di_magic
), ino
);
2819 if (!libxfs_dinode_good_version(mp
, dip
->di_version
)) {
2821 dbprintf(_("bad version number %#x for inode %lld\n"),
2822 dip
->di_version
, ino
);
2826 if (dip
->di_version
== 1) {
2827 nlink
= be16_to_cpu(dip
->di_onlink
);
2830 nlink
= be32_to_cpu(dip
->di_nlink
);
2831 prid
= (xfs_dqid_t
)be16_to_cpu(dip
->di_projid_hi
) << 16 |
2832 be16_to_cpu(dip
->di_projid_lo
);
2834 uid
= be32_to_cpu(dip
->di_uid
);
2835 gid
= be32_to_cpu(dip
->di_gid
);
2836 diflags
= be16_to_cpu(dip
->di_flags
);
2837 if (xfs_has_v3inodes(mp
))
2838 diflags2
= be64_to_cpu(dip
->di_flags2
);
2840 if (be64_to_cpu(dip
->di_nblocks
) != 0) {
2842 dbprintf(_("bad nblocks %lld for free inode "
2844 be64_to_cpu(dip
->di_nblocks
), ino
);
2849 dbprintf(_("bad nlink %d for free inode %lld\n"),
2853 if (dip
->di_mode
!= 0) {
2855 dbprintf(_("bad mode %#o for free inode %lld\n"),
2856 be16_to_cpu(dip
->di_mode
), ino
);
2862 if (be32_to_cpu(dip
->di_next_unlinked
) != NULLAGINO
) {
2864 dbprintf(_("bad next unlinked %#x for inode %lld\n"),
2865 be32_to_cpu(dip
->di_next_unlinked
), ino
);
2869 * di_mode is a 16-bit uint so no need to check the < 0 case
2871 mode
= be16_to_cpu(dip
->di_mode
);
2872 if ((((mode
& S_IFMT
) >> 12) > 15) ||
2873 (!(okfmts
[(mode
& S_IFMT
) >> 12] & (1 << dip
->di_format
)))) {
2875 dbprintf(_("bad format %d for inode %lld type %#o\n"),
2876 dip
->di_format
, id
->ino
, mode
& S_IFMT
);
2880 if ((unsigned int)XFS_DFORK_ASIZE(dip
, mp
) >= XFS_LITINO(mp
)) {
2882 dbprintf(_("bad fork offset %d for inode %lld\n"),
2883 dip
->di_forkoff
, id
->ino
);
2887 if ((unsigned int)dip
->di_aformat
> XFS_DINODE_FMT_BTREE
) {
2889 dbprintf(_("bad attribute format %d for inode %lld\n"),
2890 dip
->di_aformat
, id
->ino
);
2895 dnextents
= xfs_dfork_data_extents(dip
);
2896 danextents
= xfs_dfork_attr_extents(dip
);
2898 if (verbose
|| (id
&& id
->ilist
) || CHECK_BLIST(bno
))
2899 dbprintf(_("inode %lld mode %#o fmt %s "
2901 "nex %d anex %d nblk %lld sz %lld%s%s%s%s%s%s%s\n"),
2902 id
->ino
, mode
, fmtnames
[(int)dip
->di_format
],
2903 fmtnames
[(int)dip
->di_aformat
],
2904 dnextents
, danextents
,
2905 be64_to_cpu(dip
->di_nblocks
), be64_to_cpu(dip
->di_size
),
2906 diflags
& XFS_DIFLAG_REALTIME
? " rt" : "",
2907 diflags
& XFS_DIFLAG_PREALLOC
? " pre" : "",
2908 diflags
& XFS_DIFLAG_IMMUTABLE
? " imm" : "",
2909 diflags
& XFS_DIFLAG_APPEND
? " app" : "",
2910 diflags
& XFS_DIFLAG_SYNC
? " syn" : "",
2911 diflags
& XFS_DIFLAG_NOATIME
? " noa" : "",
2912 diflags
& XFS_DIFLAG_NODUMP
? " nod" : "");
2914 switch (mode
& S_IFMT
) {
2917 if (dip
->di_format
== XFS_DINODE_FMT_LOCAL
)
2919 blkmap
= blkmap_alloc(dnextents
);
2922 if (diflags
& XFS_DIFLAG_REALTIME
)
2924 else if (id
->ino
== mp
->m_sb
.sb_rbmino
) {
2925 type
= DBM_RTBITMAP
;
2926 blkmap
= blkmap_alloc(dnextents
);
2928 } else if (id
->ino
== mp
->m_sb
.sb_rsumino
) {
2930 blkmap
= blkmap_alloc(dnextents
);
2933 else if (id
->ino
== mp
->m_sb
.sb_uquotino
||
2934 id
->ino
== mp
->m_sb
.sb_gquotino
||
2935 id
->ino
== mp
->m_sb
.sb_pquotino
) {
2937 blkmap
= blkmap_alloc(dnextents
);
2942 if (mode
& (S_ISUID
| S_ISGID
))
2954 id
->isreflink
= !!(diflags2
& XFS_DIFLAG2_REFLINK
);
2955 setlink_inode(id
, nlink
, type
== DBM_DIR
, security
);
2957 switch (dip
->di_format
) {
2958 case XFS_DINODE_FMT_LOCAL
:
2959 process_lclinode(id
, dip
, type
, &totdblocks
, &totiblocks
,
2960 &nextents
, &blkmap
, XFS_DATA_FORK
);
2962 case XFS_DINODE_FMT_EXTENTS
:
2963 process_exinode(id
, dip
, type
, &totdblocks
, &totiblocks
,
2964 &nextents
, &blkmap
, XFS_DATA_FORK
);
2966 case XFS_DINODE_FMT_BTREE
:
2967 process_btinode(id
, dip
, type
, &totdblocks
, &totiblocks
,
2968 &nextents
, &blkmap
, XFS_DATA_FORK
);
2971 if (dip
->di_forkoff
) {
2972 sbversion
|= XFS_SB_VERSION_ATTRBIT
;
2973 switch (dip
->di_aformat
) {
2974 case XFS_DINODE_FMT_LOCAL
:
2975 process_lclinode(id
, dip
, DBM_ATTR
, &atotdblocks
,
2976 &atotiblocks
, &anextents
, NULL
, XFS_ATTR_FORK
);
2978 case XFS_DINODE_FMT_EXTENTS
:
2979 process_exinode(id
, dip
, DBM_ATTR
, &atotdblocks
,
2980 &atotiblocks
, &anextents
, NULL
, XFS_ATTR_FORK
);
2982 case XFS_DINODE_FMT_BTREE
:
2983 process_btinode(id
, dip
, DBM_ATTR
, &atotdblocks
,
2984 &atotiblocks
, &anextents
, NULL
, XFS_ATTR_FORK
);
2988 if (qgdo
|| qpdo
|| qudo
) {
2996 bc
= totdblocks
+ totiblocks
+
2997 atotdblocks
+ atotiblocks
;
3001 bc
= totiblocks
+ atotdblocks
+ atotiblocks
;
3009 quota_add(&prid
, &gid
, &uid
, 0, bc
, ic
, rc
);
3011 totblocks
= totdblocks
+ totiblocks
+ atotdblocks
+ atotiblocks
;
3012 if (totblocks
!= be64_to_cpu(dip
->di_nblocks
)) {
3014 dbprintf(_("bad nblocks %lld for inode %lld, counted "
3016 be64_to_cpu(dip
->di_nblocks
), id
->ino
, totblocks
);
3019 if (nextents
!= dnextents
) {
3021 dbprintf(_("bad nextents %d for inode %lld, counted %d\n"),
3022 dnextents
, id
->ino
, nextents
);
3025 if (anextents
!= danextents
) {
3027 dbprintf(_("bad anextents %d for inode %lld, counted "
3029 danextents
, id
->ino
, anextents
);
3032 if (type
== DBM_DIR
)
3033 process_dir(dip
, blkmap
, id
);
3034 else if (type
== DBM_RTBITMAP
)
3035 process_rtbitmap(blkmap
);
3036 else if (type
== DBM_RTSUM
)
3037 process_rtsummary(blkmap
);
3039 * If the CHKD flag is not set, this can legitimately contain garbage;
3040 * xfs_repair may have cleared that bit.
3042 else if (type
== DBM_QUOTA
) {
3043 if (id
->ino
== mp
->m_sb
.sb_uquotino
&&
3044 (mp
->m_sb
.sb_qflags
& XFS_UQUOTA_ACCT
) &&
3045 (mp
->m_sb
.sb_qflags
& XFS_UQUOTA_CHKD
))
3046 process_quota(IS_USER_QUOTA
, id
, blkmap
);
3047 else if (id
->ino
== mp
->m_sb
.sb_gquotino
&&
3048 (mp
->m_sb
.sb_qflags
& XFS_GQUOTA_ACCT
) &&
3049 (mp
->m_sb
.sb_qflags
& XFS_GQUOTA_CHKD
))
3050 process_quota(IS_GROUP_QUOTA
, id
, blkmap
);
3051 else if (id
->ino
== mp
->m_sb
.sb_pquotino
&&
3052 (mp
->m_sb
.sb_qflags
& XFS_PQUOTA_ACCT
) &&
3053 (mp
->m_sb
.sb_qflags
& XFS_PQUOTA_CHKD
))
3054 process_quota(IS_PROJECT_QUOTA
, id
, blkmap
);
3057 blkmap_free(blkmap
);
3064 struct xfs_dinode
*dip
,
3066 xfs_rfsblock_t
*totd
,
3067 xfs_rfsblock_t
*toti
,
3072 struct xfs_attr_sf_hdr
*hdr
;
3075 bno
= XFS_INO_TO_FSB(mp
, id
->ino
);
3076 if (whichfork
== XFS_DATA_FORK
&& be64_to_cpu(dip
->di_size
) >
3077 XFS_DFORK_DSIZE(dip
, mp
)) {
3078 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
3079 dbprintf(_("local inode %lld data is too large (size "
3081 id
->ino
, be64_to_cpu(dip
->di_size
));
3084 else if (whichfork
== XFS_ATTR_FORK
) {
3085 hdr
= XFS_DFORK_APTR(dip
);
3086 if (be16_to_cpu(hdr
->totsize
) > XFS_DFORK_ASIZE(dip
, mp
)) {
3087 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
3088 dbprintf(_("local inode %lld attr is too large "
3090 id
->ino
, be16_to_cpu(hdr
->totsize
));
3097 process_leaf_node_dir_v2(
3102 xfs_fsize_t dirsize
)
3117 v2
= verbose
|| id
->ilist
;
3120 freetab
= malloc(FREETAB_SIZE(dirsize
/ mp
->m_dir_geo
->blksize
));
3121 freetab
->naents
= (int)(dirsize
/ mp
->m_dir_geo
->blksize
);
3123 for (i
= 0; i
< freetab
->naents
; i
++)
3124 freetab
->ents
[i
] = NULLDATAOFF
;
3126 while ((dbno
= blkmap_next_off(blkmap
, dbno
, &t
)) != NULLFILEOFF
) {
3127 nex
= blkmap_getn(blkmap
, dbno
, mp
->m_dir_geo
->fsbcount
, &bmp
);
3129 for (v
= v2
, i
= 0; !v
&& i
< nex
; i
++) {
3130 for (b
= bmp
[i
].startblock
;
3131 !v
&& b
< bmp
[i
].startblock
+ bmp
[i
].blockcount
;
3136 dbprintf(_("dir inode %lld block %u=%llu\n"), id
->ino
,
3138 (xfs_fsblock_t
)bmp
->startblock
);
3141 make_bbmap(&bbmap
, nex
, bmp
);
3142 set_cur(&typtab
[TYP_DIR2
], XFS_FSB_TO_DADDR(mp
, bmp
->startblock
),
3143 mp
->m_dir_geo
->fsbcount
* blkbb
, DB_RING_IGN
,
3144 nex
> 1 ? &bbmap
: NULL
);
3146 if (iocur_top
->data
== NULL
) {
3148 dbprintf(_("can't read block %u for directory "
3150 (uint32_t)dbno
, id
->ino
);
3153 dbno
+= mp
->m_dir_geo
->fsbcount
- 1;
3156 if (dbno
< mp
->m_dir_geo
->leafblk
) {
3157 lino
= process_data_dir_v2(dot
, dotdot
, id
, v
,
3158 (xfs_dablk_t
)dbno
, &freetab
);
3162 dbprintf(_("multiple .. entries "
3169 } else if (dbno
< mp
->m_dir_geo
->freeblk
) {
3170 process_leaf_node_dir_v2_int(id
, v
, (xfs_dablk_t
)dbno
,
3173 process_leaf_node_dir_v2_free(id
, v
, (xfs_dablk_t
)dbno
,
3177 dbno
+= mp
->m_dir_geo
->fsbcount
- 1;
3179 dir_hash_check(id
, v
);
3181 for (i
= 0; i
< freetab
->nents
; i
++) {
3182 if (freetab
->ents
[i
] != NULLDATAOFF
) {
3184 dbprintf(_("missing free index for data block %d "
3185 "in dir ino %lld\n"),
3186 xfs_dir2_db_to_da(mp
->m_dir_geo
, i
), id
->ino
);
3195 process_leaf_node_dir_v3_free(
3201 xfs_dir2_data_off_t ent
;
3202 struct xfs_dir3_free
*free
;
3207 free
= iocur_top
->data
;
3208 maxent
= mp
->m_dir_geo
->free_max_bests
;
3209 if (be32_to_cpu(free
->hdr
.firstdb
) != xfs_dir2_da_to_db(mp
->m_dir_geo
,
3210 dabno
- mp
->m_dir_geo
->freeblk
) * maxent
) {
3212 dbprintf(_("bad free block firstdb %d for dir ino %lld "
3214 be32_to_cpu(free
->hdr
.firstdb
), id
->ino
, dabno
);
3218 if (be32_to_cpu(free
->hdr
.nvalid
) > maxent
||
3219 be32_to_cpu(free
->hdr
.nused
) > maxent
||
3220 be32_to_cpu(free
->hdr
.nused
) >
3221 be32_to_cpu(free
->hdr
.nvalid
)) {
3223 dbprintf(_("bad free block nvalid/nused %d/%d for dir "
3224 "ino %lld block %d\n"),
3225 be32_to_cpu(free
->hdr
.nvalid
),
3226 be32_to_cpu(free
->hdr
.nused
), id
->ino
, dabno
);
3230 for (used
= i
= 0; i
< be32_to_cpu(free
->hdr
.nvalid
); i
++) {
3231 if (freetab
->nents
<= be32_to_cpu(free
->hdr
.firstdb
) + i
)
3234 ent
= freetab
->ents
[be32_to_cpu(free
->hdr
.firstdb
) + i
];
3235 if (ent
!= be16_to_cpu(free
->bests
[i
])) {
3237 dbprintf(_("bad free block ent %d is %d should "
3238 "be %d for dir ino %lld block %d\n"),
3239 i
, be16_to_cpu(free
->bests
[i
]), ent
,
3243 if (be16_to_cpu(free
->bests
[i
]) != NULLDATAOFF
)
3245 if (ent
!= NULLDATAOFF
)
3246 freetab
->ents
[be32_to_cpu(free
->hdr
.firstdb
) + i
] =
3249 if (used
!= be32_to_cpu(free
->hdr
.nused
)) {
3251 dbprintf(_("bad free block nused %d should be %d for dir "
3252 "ino %lld block %d\n"),
3253 be32_to_cpu(free
->hdr
.nused
), used
, id
->ino
,
3260 process_leaf_node_dir_v2_free(
3266 xfs_dir2_data_off_t ent
;
3267 xfs_dir2_free_t
*free
;
3272 free
= iocur_top
->data
;
3273 if (be32_to_cpu(free
->hdr
.magic
) != XFS_DIR2_FREE_MAGIC
&&
3274 be32_to_cpu(free
->hdr
.magic
) != XFS_DIR3_FREE_MAGIC
) {
3276 dbprintf(_("bad free block magic # %#x for dir ino %lld "
3278 be32_to_cpu(free
->hdr
.magic
), id
->ino
, dabno
);
3282 if (be32_to_cpu(free
->hdr
.magic
) == XFS_DIR3_FREE_MAGIC
) {
3283 process_leaf_node_dir_v3_free(id
, v
, dabno
, freetab
);
3286 maxent
= mp
->m_dir_geo
->free_max_bests
;
3287 if (be32_to_cpu(free
->hdr
.firstdb
) != xfs_dir2_da_to_db(mp
->m_dir_geo
,
3288 dabno
- mp
->m_dir_geo
->freeblk
) * maxent
) {
3290 dbprintf(_("bad free block firstdb %d for dir ino %lld "
3292 be32_to_cpu(free
->hdr
.firstdb
), id
->ino
, dabno
);
3296 if (be32_to_cpu(free
->hdr
.nvalid
) > maxent
||
3297 be32_to_cpu(free
->hdr
.nused
) > maxent
||
3298 be32_to_cpu(free
->hdr
.nused
) >
3299 be32_to_cpu(free
->hdr
.nvalid
)) {
3301 dbprintf(_("bad free block nvalid/nused %d/%d for dir "
3302 "ino %lld block %d\n"),
3303 be32_to_cpu(free
->hdr
.nvalid
),
3304 be32_to_cpu(free
->hdr
.nused
), id
->ino
, dabno
);
3308 for (used
= i
= 0; i
< be32_to_cpu(free
->hdr
.nvalid
); i
++) {
3309 if (freetab
->nents
<= be32_to_cpu(free
->hdr
.firstdb
) + i
)
3312 ent
= freetab
->ents
[be32_to_cpu(free
->hdr
.firstdb
) + i
];
3313 if (ent
!= be16_to_cpu(free
->bests
[i
])) {
3315 dbprintf(_("bad free block ent %d is %d should "
3316 "be %d for dir ino %lld block %d\n"),
3317 i
, be16_to_cpu(free
->bests
[i
]), ent
,
3321 if (be16_to_cpu(free
->bests
[i
]) != NULLDATAOFF
)
3323 if (ent
!= NULLDATAOFF
)
3324 freetab
->ents
[be32_to_cpu(free
->hdr
.firstdb
) + i
] =
3327 if (used
!= be32_to_cpu(free
->hdr
.nused
)) {
3329 dbprintf(_("bad free block nused %d should be %d for dir "
3330 "ino %lld block %d\n"),
3331 be32_to_cpu(free
->hdr
.nused
), used
, id
->ino
,
3338 * Get address of the bestcount field in the single-leaf block.
3341 xfs_dir3_leaf_ents_count(struct xfs_dir2_leaf
*lp
)
3343 if (lp
->hdr
.info
.magic
== cpu_to_be16(XFS_DIR3_LEAF1_MAGIC
) ||
3344 lp
->hdr
.info
.magic
== cpu_to_be16(XFS_DIR3_LEAFN_MAGIC
)) {
3345 struct xfs_dir3_leaf
*lp3
= (struct xfs_dir3_leaf
*)lp
;
3347 return be16_to_cpu(lp3
->hdr
.count
);
3349 return be16_to_cpu(lp
->hdr
.count
);
3353 process_leaf_node_dir_v2_int(
3361 xfs_dir2_leaf_t
*leaf
;
3362 struct xfs_dir3_leaf
*leaf3
= NULL
;
3363 xfs_dir2_leaf_entry_t
*lep
;
3364 xfs_dir2_leaf_tail_t
*ltp
;
3365 xfs_da_intnode_t
*node
;
3367 struct xfs_da3_icnode_hdr nodehdr
;
3368 struct xfs_dir3_icleaf_hdr leafhdr
;
3370 leaf
= iocur_top
->data
;
3371 libxfs_dir2_leaf_hdr_from_disk(mp
, &leafhdr
, leaf
);
3373 switch (be16_to_cpu(leaf
->hdr
.info
.magic
)) {
3374 case XFS_DIR3_LEAF1_MAGIC
:
3375 case XFS_DIR3_LEAFN_MAGIC
:
3376 case XFS_DA3_NODE_MAGIC
:
3377 leaf3
= iocur_top
->data
;
3380 switch (be16_to_cpu(leaf
->hdr
.info
.magic
)) {
3381 case XFS_DIR2_LEAF1_MAGIC
:
3382 case XFS_DIR3_LEAF1_MAGIC
:
3383 if (be32_to_cpu(leaf
->hdr
.info
.forw
) ||
3384 be32_to_cpu(leaf
->hdr
.info
.back
)) {
3386 dbprintf(_("bad leaf block forw/back pointers "
3387 "%d/%d for dir ino %lld block %d\n"),
3388 be32_to_cpu(leaf
->hdr
.info
.forw
),
3389 be32_to_cpu(leaf
->hdr
.info
.back
),
3393 if (dabno
!= mp
->m_dir_geo
->leafblk
) {
3395 dbprintf(_("single leaf block for dir ino %lld "
3396 "block %d should be at block %d\n"),
3398 (xfs_dablk_t
)mp
->m_dir_geo
->leafblk
);
3401 ltp
= xfs_dir2_leaf_tail_p(mp
->m_dir_geo
, leaf
);
3402 lbp
= xfs_dir2_leaf_bests_p(ltp
);
3403 for (i
= 0; i
< be32_to_cpu(ltp
->bestcount
); i
++) {
3404 if (freetab
->nents
<= i
|| freetab
->ents
[i
] !=
3405 be16_to_cpu(lbp
[i
])) {
3407 dbprintf(_("bestfree %d for dir ino %lld "
3408 "block %d doesn't match table "
3410 freetab
->nents
<= i
?
3414 xfs_dir2_db_to_da(mp
->m_dir_geo
, i
),
3415 be16_to_cpu(lbp
[i
]));
3417 if (freetab
->nents
> i
)
3418 freetab
->ents
[i
] = NULLDATAOFF
;
3421 case XFS_DIR2_LEAFN_MAGIC
:
3422 case XFS_DIR3_LEAFN_MAGIC
:
3423 /* if it's at the root location then we can check the
3424 * pointers are null XXX */
3426 case XFS_DA_NODE_MAGIC
:
3427 case XFS_DA3_NODE_MAGIC
:
3428 node
= iocur_top
->data
;
3429 libxfs_da3_node_hdr_from_disk(mp
, &nodehdr
, node
);
3430 if (nodehdr
.level
< 1 || nodehdr
.level
> XFS_DA_NODE_MAXDEPTH
) {
3432 dbprintf(_("bad node block level %d for dir ino "
3434 nodehdr
.level
, id
->ino
,
3441 dbprintf(_("bad directory data magic # %#x for dir ino "
3443 be16_to_cpu(leaf
->hdr
.info
.magic
), id
->ino
,
3449 for (i
= stale
= 0; i
< xfs_dir3_leaf_ents_count(leaf
); i
++) {
3450 if (be32_to_cpu(lep
[i
].address
) == XFS_DIR2_NULL_DATAPTR
)
3452 else if (dir_hash_see(be32_to_cpu(lep
[i
].hashval
),
3453 be32_to_cpu(lep
[i
].address
))) {
3455 dbprintf(_("dir %lld block %d extra leaf entry "
3456 "%x %x\n"), id
->ino
, dabno
,
3457 be32_to_cpu(lep
[i
].hashval
),
3458 be32_to_cpu(lep
[i
].address
));
3462 if (leaf3
&& stale
!= be16_to_cpu(leaf3
->hdr
.stale
)) {
3464 dbprintf(_("dir3 %lld block %d stale mismatch "
3466 id
->ino
, dabno
, stale
,
3467 be16_to_cpu(leaf3
->hdr
.stale
));
3469 } else if (!leaf3
&& stale
!= be16_to_cpu(leaf
->hdr
.stale
)) {
3471 dbprintf(_("dir %lld block %d stale mismatch "
3473 id
->ino
, dabno
, stale
,
3474 be16_to_cpu(leaf
->hdr
.stale
));
3487 struct xfs_dqblk
*dqb
;
3489 uint8_t exp_flags
= 0;
3500 exp_flags
= XFS_DQTYPE_USER
;
3502 case IS_PROJECT_QUOTA
:
3504 exp_flags
= XFS_DQTYPE_PROJ
;
3506 case IS_GROUP_QUOTA
:
3508 exp_flags
= XFS_DQTYPE_GROUP
;
3514 perblock
= (uint
)(mp
->m_sb
.sb_blocksize
/ sizeof(*dqb
));
3517 while ((qbno
= blkmap_next_off(blkmap
, qbno
, &t
)) != NULLFILEOFF
) {
3518 bno
= blkmap_get(blkmap
, qbno
);
3519 dqid
= (xfs_dqid_t
)qbno
* perblock
;
3520 cb
= CHECK_BLIST(bno
);
3521 scicb
= !sflag
|| id
->ilist
|| cb
;
3523 set_cur(&typtab
[TYP_DQBLK
], XFS_FSB_TO_DADDR(mp
, bno
), blkbb
,
3525 if ((dqb
= iocur_top
->data
) == NULL
) {
3527 dbprintf(_("can't read block %lld for %s quota "
3528 "inode (fsblock %lld)\n"),
3529 (xfs_fileoff_t
)qbno
, s
,
3530 (xfs_fsblock_t
)bno
);
3535 for (i
= 0; i
< perblock
; i
++, dqid
++, dqb
++) {
3536 if (verbose
|| id
->ilist
|| cb
)
3537 dbprintf(_("%s dqblk %lld entry %d id %u bc "
3538 "%lld ic %lld rc %lld\n"),
3539 s
, (xfs_fileoff_t
)qbno
, i
, dqid
,
3540 be64_to_cpu(dqb
->dd_diskdq
.d_bcount
),
3541 be64_to_cpu(dqb
->dd_diskdq
.d_icount
),
3542 be64_to_cpu(dqb
->dd_diskdq
.d_rtbcount
));
3543 if (be16_to_cpu(dqb
->dd_diskdq
.d_magic
) != XFS_DQUOT_MAGIC
) {
3545 dbprintf(_("bad magic number %#x for %s "
3546 "dqblk %lld entry %d id %u\n"),
3547 be16_to_cpu(dqb
->dd_diskdq
.d_magic
), s
,
3548 (xfs_fileoff_t
)qbno
, i
, dqid
);
3552 if (dqb
->dd_diskdq
.d_version
!= XFS_DQUOT_VERSION
) {
3554 dbprintf(_("bad version number %#x for "
3555 "%s dqblk %lld entry %d id "
3557 dqb
->dd_diskdq
.d_version
, s
,
3558 (xfs_fileoff_t
)qbno
, i
, dqid
);
3562 if (dqb
->dd_diskdq
.d_type
& ~XFS_DQTYPE_ANY
) {
3564 dbprintf(_("bad flags %#x for %s dqblk "
3565 "%lld entry %d id %u\n"),
3566 dqb
->dd_diskdq
.d_type
, s
,
3567 (xfs_fileoff_t
)qbno
, i
, dqid
);
3571 if ((dqb
->dd_diskdq
.d_type
& XFS_DQTYPE_REC_MASK
)
3574 dbprintf(_("wrong type %#x for %s dqblk "
3575 "%lld entry %d id %u\n"),
3576 dqb
->dd_diskdq
.d_type
&
3577 XFS_DQTYPE_REC_MASK
, s
,
3578 (xfs_fileoff_t
)qbno
, i
, dqid
);
3582 if (be32_to_cpu(dqb
->dd_diskdq
.d_id
) != dqid
) {
3584 dbprintf(_("bad id %u for %s dqblk %lld "
3585 "entry %d id %u\n"),
3586 be32_to_cpu(dqb
->dd_diskdq
.d_id
), s
,
3587 (xfs_fileoff_t
)qbno
, i
, dqid
);
3591 quota_add((qtype
== IS_PROJECT_QUOTA
) ? &dqid
: NULL
,
3592 (qtype
== IS_GROUP_QUOTA
) ? &dqid
: NULL
,
3593 (qtype
== IS_USER_QUOTA
) ? &dqid
: NULL
,
3595 be64_to_cpu(dqb
->dd_diskdq
.d_bcount
),
3596 be64_to_cpu(dqb
->dd_diskdq
.d_icount
),
3597 be64_to_cpu(dqb
->dd_diskdq
.d_rtbcount
));
3605 struct xfs_mount
*mp
,
3606 union xfs_suminfo_raw
*info
,
3607 xfs_rtsumoff_t index
)
3609 union xfs_suminfo_raw
*p
= info
+ index
;
3620 xfs_fileoff_t bmbno
;
3627 xfs_rfsblock_t rtbno
;
3631 xfs_rtword_t
*words
;
3633 bitsperblock
= mp
->m_blockwsize
<< XFS_NBWORDLOG
;
3634 words
= malloc(mp
->m_blockwsize
<< XFS_WORDLOG
);
3636 dbprintf(_("could not allocate rtwords buffer\n"));
3640 bit
= extno
= prevbit
= start_bmbno
= start_bit
= 0;
3641 bmbno
= NULLFILEOFF
;
3642 while ((bmbno
= blkmap_next_off(blkmap
, bmbno
, &t
)) != NULLFILEOFF
) {
3643 struct xfs_rtalloc_args args
= {
3646 xfs_rtword_t
*incore
= words
;
3649 bno
= blkmap_get(blkmap
, bmbno
);
3650 if (bno
== NULLFSBLOCK
) {
3652 dbprintf(_("block %lld for rtbitmap inode is "
3654 (xfs_fileoff_t
)bmbno
);
3659 set_cur(&typtab
[TYP_RTBITMAP
], XFS_FSB_TO_DADDR(mp
, bno
), blkbb
,
3661 if (!iocur_top
->bp
) {
3663 dbprintf(_("can't read block %lld for rtbitmap "
3665 (xfs_fileoff_t
)bmbno
);
3671 args
.rbmbp
= iocur_top
->bp
;
3672 for (i
= 0; i
< mp
->m_blockwsize
; i
++, incore
++)
3673 *incore
= libxfs_rtbitmap_getword(&args
, i
);
3676 bit
< bitsperblock
&& extno
< mp
->m_sb
.sb_rextents
;
3678 if (xfs_isset(words
, bit
)) {
3679 rtbno
= extno
* mp
->m_sb
.sb_rextsize
;
3680 set_rdbmap(rtbno
, mp
->m_sb
.sb_rextsize
,
3684 start_bmbno
= (int)bmbno
;
3688 } else if (prevbit
== 1) {
3689 len
= ((int)bmbno
- start_bmbno
) *
3690 bitsperblock
+ (bit
- start_bit
);
3691 log
= libxfs_highbit64(len
);
3692 offs
= xfs_rtsumoffs(mp
, log
, start_bmbno
);
3693 inc_sumcount(mp
, sumcompute
, offs
);
3698 if (extno
== mp
->m_sb
.sb_rextents
)
3702 len
= ((int)bmbno
- start_bmbno
) * bitsperblock
+
3704 log
= libxfs_highbit64(len
);
3705 offs
= xfs_rtsumoffs(mp
, log
, start_bmbno
);
3706 inc_sumcount(mp
, sumcompute
, offs
);
3716 union xfs_suminfo_raw
*sfile
= sumfile
;
3717 xfs_fileoff_t sumbno
;
3720 sumbno
= NULLFILEOFF
;
3721 while ((sumbno
= blkmap_next_off(blkmap
, sumbno
, &t
)) != NULLFILEOFF
) {
3722 struct xfs_rtalloc_args args
= {
3725 union xfs_suminfo_raw
*ondisk
;
3727 bno
= blkmap_get(blkmap
, sumbno
);
3728 if (bno
== NULLFSBLOCK
) {
3730 dbprintf(_("block %lld for rtsummary inode is "
3732 (xfs_fileoff_t
)sumbno
);
3737 set_cur(&typtab
[TYP_RTSUMMARY
], XFS_FSB_TO_DADDR(mp
, bno
),
3738 blkbb
, DB_RING_IGN
, NULL
);
3739 if (!iocur_top
->bp
) {
3741 dbprintf(_("can't read block %lld for rtsummary "
3743 (xfs_fileoff_t
)sumbno
);
3746 sfile
+= mp
->m_blockwsize
;
3750 args
.sumbp
= iocur_top
->bp
;
3751 ondisk
= xfs_rsumblock_infoptr(&args
, 0);
3752 memcpy(sfile
, ondisk
, mp
->m_blockwsize
<< XFS_WORDLOG
);
3754 sfile
+= mp
->m_blockwsize
;
3760 struct xfs_dinode
*dip
,
3770 struct xfs_dir2_sf_hdr
*sf
;
3771 xfs_dir2_sf_entry_t
*sfe
;
3774 sf
= (struct xfs_dir2_sf_hdr
*)XFS_DFORK_DPTR(dip
);
3776 v
= verbose
|| id
->ilist
;
3778 dbprintf(_("dir %lld entry . %lld\n"), id
->ino
, id
->ino
);
3780 sfe
= xfs_dir2_sf_firstentry(sf
);
3781 offset
= mp
->m_dir_geo
->data_first_offset
;
3782 for (i
= sf
->count
- 1, i8
= 0; i
>= 0; i
--) {
3784 libxfs_dir2_sf_entsize(mp
, sf
, sfe
->namelen
) -
3785 (intptr_t)sf
> be64_to_cpu(dip
->di_size
)) {
3787 dbprintf(_("dir %llu bad size in entry at %d\n"),
3789 (int)((char *)sfe
- (char *)sf
));
3793 lino
= libxfs_dir2_sf_get_ino(mp
, sf
, sfe
);
3794 if (lino
> XFS_DIR2_MAX_SHORT_INUM
)
3796 cid
= find_inode(lino
, 1);
3799 dbprintf(_("dir %lld entry %*.*s bad inode "
3801 id
->ino
, sfe
->namelen
, sfe
->namelen
,
3808 addname_inode(cid
, (char *)sfe
->name
, sfe
->namelen
);
3811 dbprintf(_("dir %lld entry %*.*s offset %d %lld\n"),
3812 id
->ino
, sfe
->namelen
, sfe
->namelen
, sfe
->name
,
3813 xfs_dir2_sf_get_offset(sfe
), lino
);
3814 if (xfs_dir2_sf_get_offset(sfe
) < offset
) {
3816 dbprintf(_("dir %lld entry %*.*s bad offset %d\n"),
3817 id
->ino
, sfe
->namelen
, sfe
->namelen
,
3818 sfe
->name
, xfs_dir2_sf_get_offset(sfe
));
3822 xfs_dir2_sf_get_offset(sfe
) +
3823 libxfs_dir2_sf_entsize(mp
, sf
, sfe
->namelen
);
3824 sfe
= libxfs_dir2_sf_nextentry(mp
, sf
, sfe
);
3826 if (i
< 0 && (intptr_t)sfe
- (intptr_t)sf
!=
3827 be64_to_cpu(dip
->di_size
)) {
3829 dbprintf(_("dir %llu size is %lld, should be %u\n"),
3830 id
->ino
, be64_to_cpu(dip
->di_size
),
3831 (uint
)((char *)sfe
- (char *)sf
));
3834 if (offset
+ (sf
->count
+ 2) * sizeof(xfs_dir2_leaf_entry_t
) +
3835 sizeof(xfs_dir2_block_tail_t
) > mp
->m_dir_geo
->blksize
) {
3837 dbprintf(_("dir %llu offsets too high\n"), id
->ino
);
3840 lino
= libxfs_dir2_sf_get_parent_ino(sf
);
3841 if (lino
> XFS_DIR2_MAX_SHORT_INUM
)
3843 cid
= find_inode(lino
, 1);
3848 dbprintf(_("dir %lld entry .. bad inode number %lld\n"),
3853 dbprintf(_("dir %lld entry .. %lld\n"), id
->ino
, lino
);
3854 if (i8
!= sf
->i8count
) {
3856 dbprintf(_("dir %lld i8count mismatch is %d should be "
3858 id
->ino
, sf
->i8count
, i8
);
3862 return cid
? lino
: NULLFSINO
;
3876 if (qudo
&& usrid
!= NULL
)
3877 quota_add1(qudata
, *usrid
, dq
, bc
, ic
, rc
);
3878 if (qgdo
&& grpid
!= NULL
)
3879 quota_add1(qgdata
, *grpid
, dq
, bc
, ic
, rc
);
3880 if (qpdo
&& prjid
!= NULL
)
3881 quota_add1(qpdata
, *prjid
, dq
, bc
, ic
, rc
);
3897 qh
= (int)(id
% QDATA_HASH_SIZE
);
3901 qi
= dq
? &qe
->dq
: &qe
->count
;
3909 qe
= xmalloc(sizeof(*qe
));
3911 qi
= dq
? &qe
->dq
: &qe
->count
;
3915 qi
= dq
? &qe
->count
: &qe
->dq
;
3916 qi
->bc
= qi
->ic
= qi
->rc
= 0;
3930 for (i
= 0; i
< QDATA_HASH_SIZE
; i
++) {
3934 if (qp
->count
.bc
!= qp
->dq
.bc
||
3935 qp
->count
.ic
!= qp
->dq
.ic
||
3936 qp
->count
.rc
!= qp
->dq
.rc
) {
3938 dbprintf(_("%s quota id %u, have/exp"),
3940 if (qp
->count
.bc
!= qp
->dq
.bc
)
3941 dbprintf(_(" bc %lld/%lld"),
3944 if (qp
->count
.ic
!= qp
->dq
.ic
)
3945 dbprintf(_(" ic %lld/%lld"),
3948 if (qp
->count
.rc
!= qp
->dq
.rc
)
3949 dbprintf(_(" rc %lld/%lld"),
3966 qudo
= mp
->m_sb
.sb_uquotino
!= 0 &&
3967 mp
->m_sb
.sb_uquotino
!= NULLFSINO
&&
3968 (mp
->m_sb
.sb_qflags
& XFS_UQUOTA_ACCT
) &&
3969 (mp
->m_sb
.sb_qflags
& XFS_UQUOTA_CHKD
);
3970 qgdo
= mp
->m_sb
.sb_gquotino
!= 0 &&
3971 mp
->m_sb
.sb_gquotino
!= NULLFSINO
&&
3972 (mp
->m_sb
.sb_qflags
& XFS_GQUOTA_ACCT
) &&
3973 (mp
->m_sb
.sb_qflags
& XFS_GQUOTA_CHKD
);
3974 qpdo
= mp
->m_sb
.sb_pquotino
!= 0 &&
3975 mp
->m_sb
.sb_pquotino
!= NULLFSINO
&&
3976 (mp
->m_sb
.sb_qflags
& XFS_PQUOTA_ACCT
) &&
3977 (mp
->m_sb
.sb_qflags
& XFS_PQUOTA_CHKD
);
3979 qudata
= xcalloc(QDATA_HASH_SIZE
, sizeof(qdata_t
*));
3981 qgdata
= xcalloc(QDATA_HASH_SIZE
, sizeof(qdata_t
*));
3983 qpdata
= xcalloc(QDATA_HASH_SIZE
, sizeof(qdata_t
*));
3988 xfs_agnumber_t agno
)
3994 xfs_sb_t
*sb
= &tsb
;
3996 agffreeblks
= agflongest
= 0;
3998 agicount
= agifreecount
= 0;
3999 push_cur(); /* 1 pushed */
4000 set_cur(&typtab
[TYP_SB
],
4001 XFS_AG_DADDR(mp
, agno
, XFS_SB_DADDR
),
4002 XFS_FSS_TO_BB(mp
, 1), DB_RING_IGN
, NULL
);
4004 if (!iocur_top
->data
) {
4005 dbprintf(_("can't read superblock for ag %u\n"), agno
);
4010 libxfs_sb_from_disk(sb
, iocur_top
->data
);
4012 if (sb
->sb_magicnum
!= XFS_SB_MAGIC
) {
4014 dbprintf(_("bad sb magic # %#x in ag %u\n"),
4015 sb
->sb_magicnum
, agno
);
4018 if (!xfs_sb_good_version(sb
)) {
4020 dbprintf(_("bad sb version # %#x in ag %u\n"),
4021 sb
->sb_versionnum
, agno
);
4025 if (!lazycount
&& xfs_sb_version_haslazysbcount(sb
)) {
4028 if (agno
== 0 && sb
->sb_inprogress
!= 0) {
4030 dbprintf(_("mkfs not completed successfully\n"));
4033 if (xfs_sb_version_needsrepair(sb
)) {
4035 dbprintf(_("filesystem needs xfs_repair\n"));
4038 set_dbmap(agno
, XFS_SB_BLOCK(mp
), 1, DBM_SB
, agno
, XFS_SB_BLOCK(mp
));
4039 if (sb
->sb_logstart
&& XFS_FSB_TO_AGNO(mp
, sb
->sb_logstart
) == agno
)
4040 set_dbmap(agno
, XFS_FSB_TO_AGBNO(mp
, sb
->sb_logstart
),
4041 sb
->sb_logblocks
, DBM_LOG
, agno
, XFS_SB_BLOCK(mp
));
4042 push_cur(); /* 2 pushed */
4043 set_cur(&typtab
[TYP_AGF
],
4044 XFS_AG_DADDR(mp
, agno
, XFS_AGF_DADDR(mp
)),
4045 XFS_FSS_TO_BB(mp
, 1), DB_RING_IGN
, NULL
);
4046 if ((agf
= iocur_top
->data
) == NULL
) {
4047 dbprintf(_("can't read agf block for ag %u\n"), agno
);
4051 if (be32_to_cpu(agf
->agf_magicnum
) != XFS_AGF_MAGIC
) {
4053 dbprintf(_("bad agf magic # %#x in ag %u\n"),
4054 be32_to_cpu(agf
->agf_magicnum
), agno
);
4057 if (!XFS_AGF_GOOD_VERSION(be32_to_cpu(agf
->agf_versionnum
))) {
4059 dbprintf(_("bad agf version # %#x in ag %u\n"),
4060 be32_to_cpu(agf
->agf_versionnum
), agno
);
4063 if (XFS_SB_BLOCK(mp
) != XFS_AGF_BLOCK(mp
))
4064 set_dbmap(agno
, XFS_AGF_BLOCK(mp
), 1, DBM_AGF
, agno
,
4066 if (sb
->sb_agblocks
> be32_to_cpu(agf
->agf_length
))
4067 set_dbmap(agno
, be32_to_cpu(agf
->agf_length
),
4068 sb
->sb_agblocks
- be32_to_cpu(agf
->agf_length
),
4069 DBM_MISSING
, agno
, XFS_SB_BLOCK(mp
));
4070 push_cur(); /* 3 pushed */
4071 set_cur(&typtab
[TYP_AGI
],
4072 XFS_AG_DADDR(mp
, agno
, XFS_AGI_DADDR(mp
)),
4073 XFS_FSS_TO_BB(mp
, 1), DB_RING_IGN
, NULL
);
4074 if ((agi
= iocur_top
->data
) == NULL
) {
4075 dbprintf(_("can't read agi block for ag %u\n"), agno
);
4079 if (be32_to_cpu(agi
->agi_magicnum
) != XFS_AGI_MAGIC
) {
4081 dbprintf(_("bad agi magic # %#x in ag %u\n"),
4082 be32_to_cpu(agi
->agi_magicnum
), agno
);
4085 if (!XFS_AGI_GOOD_VERSION(be32_to_cpu(agi
->agi_versionnum
))) {
4087 dbprintf(_("bad agi version # %#x in ag %u\n"),
4088 be32_to_cpu(agi
->agi_versionnum
), agno
);
4091 if (XFS_SB_BLOCK(mp
) != XFS_AGI_BLOCK(mp
) &&
4092 XFS_AGF_BLOCK(mp
) != XFS_AGI_BLOCK(mp
))
4093 set_dbmap(agno
, XFS_AGI_BLOCK(mp
), 1, DBM_AGI
, agno
,
4098 be32_to_cpu(agf
->agf_roots
[XFS_BTNUM_BNO
]),
4099 be32_to_cpu(agf
->agf_levels
[XFS_BTNUM_BNO
]),
4100 1, scanfunc_bno
, TYP_BNOBT
);
4103 be32_to_cpu(agf
->agf_roots
[XFS_BTNUM_CNT
]),
4104 be32_to_cpu(agf
->agf_levels
[XFS_BTNUM_CNT
]),
4105 1, scanfunc_cnt
, TYP_CNTBT
);
4106 if (agf
->agf_roots
[XFS_BTNUM_RMAP
]) {
4108 be32_to_cpu(agf
->agf_roots
[XFS_BTNUM_RMAP
]),
4109 be32_to_cpu(agf
->agf_levels
[XFS_BTNUM_RMAP
]),
4110 1, scanfunc_rmap
, TYP_RMAPBT
);
4112 if (agf
->agf_refcount_root
) {
4114 be32_to_cpu(agf
->agf_refcount_root
),
4115 be32_to_cpu(agf
->agf_refcount_level
),
4116 1, scanfunc_refcnt
, TYP_REFCBT
);
4119 be32_to_cpu(agi
->agi_root
),
4120 be32_to_cpu(agi
->agi_level
),
4121 1, scanfunc_ino
, TYP_INOBT
);
4122 if (agi
->agi_free_root
) {
4124 be32_to_cpu(agi
->agi_free_root
),
4125 be32_to_cpu(agi
->agi_free_level
),
4126 1, scanfunc_fino
, TYP_FINOBT
);
4128 if (be32_to_cpu(agf
->agf_freeblks
) != agffreeblks
) {
4130 dbprintf(_("agf_freeblks %u, counted %u in ag %u\n"),
4131 be32_to_cpu(agf
->agf_freeblks
),
4135 if (be32_to_cpu(agf
->agf_longest
) != agflongest
) {
4137 dbprintf(_("agf_longest %u, counted %u in ag %u\n"),
4138 be32_to_cpu(agf
->agf_longest
),
4143 be32_to_cpu(agf
->agf_btreeblks
) != agfbtreeblks
) {
4145 dbprintf(_("agf_btreeblks %u, counted %u in ag %u\n"),
4146 be32_to_cpu(agf
->agf_btreeblks
),
4147 agfbtreeblks
, agno
);
4150 agf_aggr_freeblks
+= agffreeblks
+ agfbtreeblks
;
4151 if (be32_to_cpu(agi
->agi_count
) != agicount
) {
4153 dbprintf(_("agi_count %u, counted %u in ag %u\n"),
4154 be32_to_cpu(agi
->agi_count
),
4158 if (be32_to_cpu(agi
->agi_freecount
) != agifreecount
) {
4160 dbprintf(_("agi_freecount %u, counted %u in ag %u\n"),
4161 be32_to_cpu(agi
->agi_freecount
),
4162 agifreecount
, agno
);
4165 for (i
= 0; i
< XFS_AGI_UNLINKED_BUCKETS
; i
++) {
4166 if (be32_to_cpu(agi
->agi_unlinked
[i
]) != NULLAGINO
) {
4168 xfs_agino_t agino
=be32_to_cpu(agi
->agi_unlinked
[i
]);
4169 dbprintf(_("agi unlinked bucket %d is %u in ag "
4170 "%u (inode=%lld)\n"), i
, agino
, agno
,
4171 XFS_AGINO_TO_INO(mp
, agno
, agino
));
4185 xfs_agnumber_t agno
;
4191 struct xfs_mount
*mp
,
4195 struct agfl_state
*as
= priv
;
4197 set_dbmap(as
->agno
, bno
, 1, DBM_FREELIST
, as
->agno
, XFS_AGFL_BLOCK(mp
));
4206 xfs_agnumber_t seqno
= be32_to_cpu(agf
->agf_seqno
);
4207 struct agfl_state state
;
4209 if (XFS_SB_BLOCK(mp
) != XFS_AGFL_BLOCK(mp
) &&
4210 XFS_AGF_BLOCK(mp
) != XFS_AGFL_BLOCK(mp
) &&
4211 XFS_AGI_BLOCK(mp
) != XFS_AGFL_BLOCK(mp
))
4212 set_dbmap(seqno
, XFS_AGFL_BLOCK(mp
), 1, DBM_AGFL
, seqno
,
4214 if (be32_to_cpu(agf
->agf_flcount
) == 0)
4217 set_cur(&typtab
[TYP_AGFL
],
4218 XFS_AG_DADDR(mp
, seqno
, XFS_AGFL_DADDR(mp
)),
4219 XFS_FSS_TO_BB(mp
, 1), DB_RING_IGN
, NULL
);
4220 if (iocur_top
->data
== NULL
) {
4221 dbprintf(_("can't read agfl block for ag %u\n"), seqno
);
4227 /* verify agf values before proceeding */
4228 if (be32_to_cpu(agf
->agf_flfirst
) >= libxfs_agfl_size(mp
) ||
4229 be32_to_cpu(agf
->agf_fllast
) >= libxfs_agfl_size(mp
)) {
4230 dbprintf(_("agf %d freelist blocks bad, skipping "
4231 "freelist scan\n"), seqno
);
4236 /* open coded xfs_buf_to_agfl_bno */
4239 libxfs_agfl_walk(mp
, agf
, iocur_top
->bp
, scan_agfl
, &state
);
4240 if (state
.count
!= be32_to_cpu(agf
->agf_flcount
)) {
4242 dbprintf(_("freeblk count %u != flcount %u in ag %u\n"),
4244 be32_to_cpu(agf
->agf_flcount
),
4248 fdblocks
+= state
.count
;
4249 agf_aggr_freeblks
+= state
.count
;
4257 scan_lbtree_f_t func
,
4260 xfs_rfsblock_t
*totd
,
4261 xfs_rfsblock_t
*toti
,
4268 set_cur(&typtab
[btype
], XFS_FSB_TO_DADDR(mp
, root
), blkbb
, DB_RING_IGN
,
4270 if (iocur_top
->data
== NULL
) {
4272 dbprintf(_("can't read btree block %u/%u\n"),
4273 XFS_FSB_TO_AGNO(mp
, root
),
4274 XFS_FSB_TO_AGBNO(mp
, root
));
4279 (*func
)(iocur_top
->data
, nlevels
- 1, type
, root
, id
, totd
, toti
, nex
,
4280 blkmapp
, isroot
, btype
);
4290 scan_sbtree_f_t func
,
4293 xfs_agnumber_t seqno
= be32_to_cpu(agf
->agf_seqno
);
4296 set_cur(&typtab
[btype
],
4297 XFS_AGB_TO_DADDR(mp
, seqno
, root
), blkbb
, DB_RING_IGN
, NULL
);
4298 if (iocur_top
->data
== NULL
) {
4300 dbprintf(_("can't read btree block %u/%u\n"), seqno
, root
);
4305 (*func
)(iocur_top
->data
, nlevels
- 1, agf
, root
, isroot
);
4311 struct xfs_btree_block
*block
,
4316 xfs_rfsblock_t
*totd
,
4317 xfs_rfsblock_t
*toti
,
4323 xfs_agblock_t agbno
;
4324 xfs_agnumber_t agno
;
4329 agno
= XFS_FSB_TO_AGNO(mp
, bno
);
4330 agbno
= XFS_FSB_TO_AGBNO(mp
, bno
);
4331 if (be32_to_cpu(block
->bb_magic
) != XFS_BMAP_MAGIC
&&
4332 be32_to_cpu(block
->bb_magic
) != XFS_BMAP_CRC_MAGIC
) {
4333 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
4334 dbprintf(_("bad magic # %#x in inode %lld bmbt block "
4336 be32_to_cpu(block
->bb_magic
), id
->ino
, agno
, agbno
);
4339 if (be16_to_cpu(block
->bb_level
) != level
) {
4340 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
4341 dbprintf(_("expected level %d got %d in inode %lld bmbt "
4343 level
, be16_to_cpu(block
->bb_level
), id
->ino
, agno
, agbno
);
4346 set_dbmap(agno
, agbno
, 1, type
, agno
, agbno
);
4347 set_inomap(agno
, agbno
, 1, id
);
4350 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_bmap_dmxr
[0] ||
4351 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_bmap_dmnr
[0])) {
4352 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
4353 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) "
4354 "in inode %lld bmap block %lld\n"),
4355 be16_to_cpu(block
->bb_numrecs
), mp
->m_bmap_dmnr
[0],
4356 mp
->m_bmap_dmxr
[0], id
->ino
,
4357 (xfs_fsblock_t
)bno
);
4361 rp
= XFS_BMBT_REC_ADDR(mp
, block
, 1);
4362 *nex
+= be16_to_cpu(block
->bb_numrecs
);
4363 process_bmbt_reclist(rp
, be16_to_cpu(block
->bb_numrecs
), type
, id
, totd
,
4367 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_bmap_dmxr
[1] ||
4368 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_bmap_dmnr
[1])) {
4369 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
4370 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in "
4371 "inode %lld bmap block %lld\n"),
4372 be16_to_cpu(block
->bb_numrecs
), mp
->m_bmap_dmnr
[1],
4373 mp
->m_bmap_dmxr
[1], id
->ino
, (xfs_fsblock_t
)bno
);
4377 pp
= XFS_BMBT_PTR_ADDR(mp
, block
, 1, mp
->m_bmap_dmxr
[0]);
4378 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++)
4379 scan_lbtree(be64_to_cpu(pp
[i
]), level
, scanfunc_bmap
, type
, id
,
4380 totd
, toti
, nex
, blkmapp
, 0, btype
);
4385 struct xfs_btree_block
*block
,
4392 xfs_alloc_ptr_t
*pp
;
4393 xfs_alloc_rec_t
*rp
;
4394 xfs_agnumber_t seqno
= be32_to_cpu(agf
->agf_seqno
);
4395 xfs_agblock_t lastblock
;
4397 if (be32_to_cpu(block
->bb_magic
) != XFS_ABTB_MAGIC
&&
4398 be32_to_cpu(block
->bb_magic
) != XFS_ABTB_CRC_MAGIC
) {
4399 dbprintf(_("bad magic # %#x in btbno block %u/%u\n"),
4400 be32_to_cpu(block
->bb_magic
), seqno
, bno
);
4406 if (be16_to_cpu(block
->bb_level
) != level
) {
4408 dbprintf(_("expected level %d got %d in btbno block "
4410 level
, be16_to_cpu(block
->bb_level
), seqno
, bno
);
4413 set_dbmap(seqno
, bno
, 1, DBM_BTBNO
, seqno
, bno
);
4415 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_alloc_mxr
[0] ||
4416 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_alloc_mnr
[0])) {
4417 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in "
4418 "btbno block %u/%u\n"),
4419 be16_to_cpu(block
->bb_numrecs
), mp
->m_alloc_mnr
[0],
4420 mp
->m_alloc_mxr
[0], seqno
, bno
);
4424 rp
= XFS_ALLOC_REC_ADDR(mp
, block
, 1);
4426 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++) {
4427 set_dbmap(seqno
, be32_to_cpu(rp
[i
].ar_startblock
),
4428 be32_to_cpu(rp
[i
].ar_blockcount
), DBM_FREE1
,
4430 if (be32_to_cpu(rp
[i
].ar_startblock
) <= lastblock
) {
4432 "out-of-order bno btree record %d (%u %u) block %u/%u\n"),
4433 i
, be32_to_cpu(rp
[i
].ar_startblock
),
4434 be32_to_cpu(rp
[i
].ar_blockcount
),
4435 be32_to_cpu(agf
->agf_seqno
), bno
);
4438 lastblock
= be32_to_cpu(rp
[i
].ar_startblock
);
4443 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_alloc_mxr
[1] ||
4444 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_alloc_mnr
[1])) {
4445 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in btbno block "
4447 be16_to_cpu(block
->bb_numrecs
), mp
->m_alloc_mnr
[1],
4448 mp
->m_alloc_mxr
[1], seqno
, bno
);
4452 pp
= XFS_ALLOC_PTR_ADDR(mp
, block
, 1, mp
->m_alloc_mxr
[1]);
4453 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++)
4454 scan_sbtree(agf
, be32_to_cpu(pp
[i
]), level
, 0, scanfunc_bno
, TYP_BNOBT
);
4459 struct xfs_btree_block
*block
,
4465 xfs_agnumber_t seqno
= be32_to_cpu(agf
->agf_seqno
);
4467 xfs_alloc_ptr_t
*pp
;
4468 xfs_alloc_rec_t
*rp
;
4469 xfs_extlen_t lastcount
;
4471 if (be32_to_cpu(block
->bb_magic
) != XFS_ABTC_MAGIC
&&
4472 be32_to_cpu(block
->bb_magic
) != XFS_ABTC_CRC_MAGIC
) {
4473 dbprintf(_("bad magic # %#x in btcnt block %u/%u\n"),
4474 be32_to_cpu(block
->bb_magic
), seqno
, bno
);
4480 if (be16_to_cpu(block
->bb_level
) != level
) {
4482 dbprintf(_("expected level %d got %d in btcnt block "
4484 level
, be16_to_cpu(block
->bb_level
), seqno
, bno
);
4487 set_dbmap(seqno
, bno
, 1, DBM_BTCNT
, seqno
, bno
);
4489 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_alloc_mxr
[0] ||
4490 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_alloc_mnr
[0])) {
4491 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in "
4492 "btbno block %u/%u\n"),
4493 be16_to_cpu(block
->bb_numrecs
), mp
->m_alloc_mnr
[0],
4494 mp
->m_alloc_mxr
[0], seqno
, bno
);
4498 rp
= XFS_ALLOC_REC_ADDR(mp
, block
, 1);
4500 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++) {
4501 check_set_dbmap(seqno
, be32_to_cpu(rp
[i
].ar_startblock
),
4502 be32_to_cpu(rp
[i
].ar_blockcount
), DBM_FREE1
, DBM_FREE2
,
4504 fdblocks
+= be32_to_cpu(rp
[i
].ar_blockcount
);
4505 agffreeblks
+= be32_to_cpu(rp
[i
].ar_blockcount
);
4506 if (be32_to_cpu(rp
[i
].ar_blockcount
) > agflongest
)
4507 agflongest
= be32_to_cpu(rp
[i
].ar_blockcount
);
4508 if (be32_to_cpu(rp
[i
].ar_blockcount
) < lastcount
) {
4510 "out-of-order cnt btree record %d (%u %u) block %u/%u\n"),
4511 i
, be32_to_cpu(rp
[i
].ar_startblock
),
4512 be32_to_cpu(rp
[i
].ar_blockcount
),
4513 be32_to_cpu(agf
->agf_seqno
), bno
);
4515 lastcount
= be32_to_cpu(rp
[i
].ar_blockcount
);
4520 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_alloc_mxr
[1] ||
4521 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_alloc_mnr
[1])) {
4522 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in btbno block "
4524 be16_to_cpu(block
->bb_numrecs
), mp
->m_alloc_mnr
[1],
4525 mp
->m_alloc_mxr
[1], seqno
, bno
);
4529 pp
= XFS_ALLOC_PTR_ADDR(mp
, block
, 1, mp
->m_alloc_mxr
[1]);
4530 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++)
4531 scan_sbtree(agf
, be32_to_cpu(pp
[i
]), level
, 0, scanfunc_cnt
, TYP_CNTBT
);
4536 struct xfs_btree_block
*block
,
4543 xfs_agnumber_t seqno
= be32_to_cpu(agf
->agf_seqno
);
4550 xfs_inobt_ptr_t
*pp
;
4551 xfs_inobt_rec_t
*rp
;
4552 xfs_agblock_t agbno
;
4553 xfs_agblock_t end_agbno
;
4554 struct xfs_dinode
*dip
;
4558 struct xfs_ino_geometry
*igeo
= M_IGEO(mp
);
4560 if (xfs_has_sparseinodes(mp
))
4561 blks_per_buf
= igeo
->blocks_per_cluster
;
4563 blks_per_buf
= igeo
->ialloc_blks
;
4564 inodes_per_buf
= min(XFS_FSB_TO_INO(mp
, blks_per_buf
),
4565 XFS_INODES_PER_CHUNK
);
4567 if (be32_to_cpu(block
->bb_magic
) != XFS_IBT_MAGIC
&&
4568 be32_to_cpu(block
->bb_magic
) != XFS_IBT_CRC_MAGIC
) {
4569 dbprintf(_("bad magic # %#x in inobt block %u/%u\n"),
4570 be32_to_cpu(block
->bb_magic
), seqno
, bno
);
4574 if (be16_to_cpu(block
->bb_level
) != level
) {
4576 dbprintf(_("expected level %d got %d in inobt block "
4578 level
, be16_to_cpu(block
->bb_level
), seqno
, bno
);
4581 set_dbmap(seqno
, bno
, 1, DBM_BTINO
, seqno
, bno
);
4583 if (be16_to_cpu(block
->bb_numrecs
) > igeo
->inobt_mxr
[0] ||
4584 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < igeo
->inobt_mnr
[0])) {
4585 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in "
4586 "inobt block %u/%u\n"),
4587 be16_to_cpu(block
->bb_numrecs
), igeo
->inobt_mnr
[0],
4588 igeo
->inobt_mxr
[0], seqno
, bno
);
4592 rp
= XFS_INOBT_REC_ADDR(mp
, block
, 1);
4593 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++) {
4594 agino
= be32_to_cpu(rp
[i
].ir_startino
);
4595 agbno
= XFS_AGINO_TO_AGBNO(mp
, agino
);
4596 off
= XFS_AGINO_TO_OFFSET(mp
, agino
);
4597 end_agbno
= agbno
+ igeo
->ialloc_blks
;
4599 if ((sbversion
& XFS_SB_VERSION_ALIGNBIT
) &&
4600 mp
->m_sb
.sb_inoalignmt
&&
4601 (XFS_INO_TO_AGBNO(mp
, agino
) %
4602 mp
->m_sb
.sb_inoalignmt
))
4603 sbversion
&= ~XFS_SB_VERSION_ALIGNBIT
;
4610 while (agbno
< end_agbno
&&
4611 ioff
< XFS_INODES_PER_CHUNK
) {
4612 if (xfs_inobt_is_sparse_disk(&rp
[i
], ioff
))
4615 if (off
< XFS_INODES_PER_CHUNK
)
4616 set_dbmap(seqno
, agbno
, blks_per_buf
,
4617 DBM_INODE
, seqno
, bno
);
4619 icount
+= inodes_per_buf
;
4620 agicount
+= inodes_per_buf
;
4622 set_cur(&typtab
[TYP_INODE
],
4623 XFS_AGB_TO_DADDR(mp
, seqno
, agbno
),
4624 XFS_FSB_TO_BB(mp
, blks_per_buf
),
4626 if (iocur_top
->data
== NULL
) {
4628 dbprintf(_("can't read inode block "
4635 for (j
= 0; j
< inodes_per_buf
; j
++) {
4636 isfree
= XFS_INOBT_IS_FREE_DISK(&rp
[i
], ioff
+ j
);
4639 dip
= (struct xfs_dinode
*)((char *)iocur_top
->data
+
4640 ((off
+ j
) << mp
->m_sb
.sb_inodelog
));
4641 process_inode(agf
, agino
+ ioff
+ j
, dip
, isfree
);
4645 agbno
+= blks_per_buf
;
4646 ioff
+= inodes_per_buf
;
4649 if (xfs_has_sparseinodes(mp
))
4650 freecount
= rp
[i
].ir_u
.sp
.ir_freecount
;
4652 freecount
= be32_to_cpu(rp
[i
].ir_u
.f
.ir_freecount
);
4655 agifreecount
+= freecount
;
4657 if (nfree
!= freecount
) {
4659 dbprintf(_("ir_freecount/free mismatch, "
4660 "inode chunk %u/%u, freecount "
4662 seqno
, agino
, freecount
, nfree
);
4669 if (be16_to_cpu(block
->bb_numrecs
) > igeo
->inobt_mxr
[1] ||
4670 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < igeo
->inobt_mnr
[1])) {
4671 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in inobt block "
4673 be16_to_cpu(block
->bb_numrecs
), igeo
->inobt_mnr
[1],
4674 igeo
->inobt_mxr
[1], seqno
, bno
);
4678 pp
= XFS_INOBT_PTR_ADDR(mp
, block
, 1, igeo
->inobt_mxr
[1]);
4679 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++)
4680 scan_sbtree(agf
, be32_to_cpu(pp
[i
]), level
, 0, scanfunc_ino
, TYP_INOBT
);
4685 struct xfs_btree_block
*block
,
4687 struct xfs_agf
*agf
,
4692 xfs_agnumber_t seqno
= be32_to_cpu(agf
->agf_seqno
);
4695 xfs_inobt_ptr_t
*pp
;
4696 struct xfs_inobt_rec
*rp
;
4697 xfs_agblock_t agbno
;
4698 xfs_agblock_t end_agbno
;
4702 struct xfs_ino_geometry
*igeo
= M_IGEO(mp
);
4704 if (xfs_has_sparseinodes(mp
))
4705 blks_per_buf
= igeo
->blocks_per_cluster
;
4707 blks_per_buf
= igeo
->ialloc_blks
;
4708 inodes_per_buf
= min(XFS_FSB_TO_INO(mp
, blks_per_buf
),
4709 XFS_INODES_PER_CHUNK
);
4711 if (be32_to_cpu(block
->bb_magic
) != XFS_FIBT_MAGIC
&&
4712 be32_to_cpu(block
->bb_magic
) != XFS_FIBT_CRC_MAGIC
) {
4713 dbprintf(_("bad magic # %#x in finobt block %u/%u\n"),
4714 be32_to_cpu(block
->bb_magic
), seqno
, bno
);
4718 if (be16_to_cpu(block
->bb_level
) != level
) {
4720 dbprintf(_("expected level %d got %d in finobt block "
4722 level
, be16_to_cpu(block
->bb_level
), seqno
, bno
);
4725 set_dbmap(seqno
, bno
, 1, DBM_BTFINO
, seqno
, bno
);
4727 if (be16_to_cpu(block
->bb_numrecs
) > igeo
->inobt_mxr
[0] ||
4728 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < igeo
->inobt_mnr
[0])) {
4729 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in "
4730 "finobt block %u/%u\n"),
4731 be16_to_cpu(block
->bb_numrecs
), igeo
->inobt_mnr
[0],
4732 igeo
->inobt_mxr
[0], seqno
, bno
);
4736 rp
= XFS_INOBT_REC_ADDR(mp
, block
, 1);
4737 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++) {
4738 agino
= be32_to_cpu(rp
[i
].ir_startino
);
4739 agbno
= XFS_AGINO_TO_AGBNO(mp
, agino
);
4740 off
= XFS_AGINO_TO_OFFSET(mp
, agino
);
4741 end_agbno
= agbno
+ igeo
->ialloc_blks
;
4743 if ((sbversion
& XFS_SB_VERSION_ALIGNBIT
) &&
4744 mp
->m_sb
.sb_inoalignmt
&&
4745 (XFS_INO_TO_AGBNO(mp
, agino
) %
4746 mp
->m_sb
.sb_inoalignmt
))
4747 sbversion
&= ~XFS_SB_VERSION_ALIGNBIT
;
4751 while (agbno
< end_agbno
&&
4752 ioff
< XFS_INODES_PER_CHUNK
) {
4753 if (xfs_inobt_is_sparse_disk(&rp
[i
], ioff
))
4756 check_set_dbmap(seqno
, agbno
,
4757 (xfs_extlen_t
)max(1,
4759 mp
->m_sb
.sb_inopblog
),
4760 DBM_INODE
, DBM_INODE
, seqno
, bno
);
4763 agbno
+= blks_per_buf
;
4764 ioff
+= inodes_per_buf
;
4770 if (be16_to_cpu(block
->bb_numrecs
) > igeo
->inobt_mxr
[1] ||
4771 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < igeo
->inobt_mnr
[1])) {
4772 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in finobt block "
4774 be16_to_cpu(block
->bb_numrecs
), igeo
->inobt_mnr
[1],
4775 igeo
->inobt_mxr
[1], seqno
, bno
);
4779 pp
= XFS_INOBT_PTR_ADDR(mp
, block
, 1, igeo
->inobt_mxr
[1]);
4780 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++)
4781 scan_sbtree(agf
, be32_to_cpu(pp
[i
]), level
, 0, scanfunc_fino
, TYP_FINOBT
);
4786 struct xfs_btree_block
*block
,
4788 struct xfs_agf
*agf
,
4792 xfs_agnumber_t seqno
= be32_to_cpu(agf
->agf_seqno
);
4795 struct xfs_rmap_rec
*rp
;
4796 xfs_agblock_t lastblock
;
4798 if (be32_to_cpu(block
->bb_magic
) != XFS_RMAP_CRC_MAGIC
) {
4799 dbprintf(_("bad magic # %#x in rmapbt block %u/%u\n"),
4800 be32_to_cpu(block
->bb_magic
), seqno
, bno
);
4804 if (be16_to_cpu(block
->bb_level
) != level
) {
4806 dbprintf(_("expected level %d got %d in rmapbt block "
4808 level
, be16_to_cpu(block
->bb_level
), seqno
, bno
);
4815 set_dbmap(seqno
, bno
, 1, DBM_BTRMAP
, seqno
, bno
);
4817 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_rmap_mxr
[0] ||
4818 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_rmap_mnr
[0])) {
4819 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in "
4820 "rmapbt block %u/%u\n"),
4821 be16_to_cpu(block
->bb_numrecs
), mp
->m_rmap_mnr
[0],
4822 mp
->m_rmap_mxr
[0], seqno
, bno
);
4826 rp
= XFS_RMAP_REC_ADDR(block
, 1);
4828 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++) {
4829 if (be32_to_cpu(rp
[i
].rm_startblock
) < lastblock
) {
4831 "out-of-order rmap btree record %d (%u %u) block %u/%u\n"),
4832 i
, be32_to_cpu(rp
[i
].rm_startblock
),
4833 be32_to_cpu(rp
[i
].rm_startblock
),
4834 be32_to_cpu(agf
->agf_seqno
), bno
);
4836 lastblock
= be32_to_cpu(rp
[i
].rm_startblock
);
4841 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_rmap_mxr
[1] ||
4842 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_rmap_mnr
[1])) {
4843 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in rmapbt "
4845 be16_to_cpu(block
->bb_numrecs
), mp
->m_rmap_mnr
[1],
4846 mp
->m_rmap_mxr
[1], seqno
, bno
);
4850 pp
= XFS_RMAP_PTR_ADDR(block
, 1, mp
->m_rmap_mxr
[1]);
4851 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++)
4852 scan_sbtree(agf
, be32_to_cpu(pp
[i
]), level
, 0, scanfunc_rmap
,
4858 struct xfs_btree_block
*block
,
4860 struct xfs_agf
*agf
,
4864 xfs_agnumber_t seqno
= be32_to_cpu(agf
->agf_seqno
);
4866 xfs_refcount_ptr_t
*pp
;
4867 struct xfs_refcount_rec
*rp
;
4868 xfs_agblock_t lastblock
;
4870 if (be32_to_cpu(block
->bb_magic
) != XFS_REFC_CRC_MAGIC
) {
4871 dbprintf(_("bad magic # %#x in refcntbt block %u/%u\n"),
4872 be32_to_cpu(block
->bb_magic
), seqno
, bno
);
4876 if (be16_to_cpu(block
->bb_level
) != level
) {
4878 dbprintf(_("expected level %d got %d in refcntbt block "
4880 level
, be16_to_cpu(block
->bb_level
), seqno
, bno
);
4883 set_dbmap(seqno
, bno
, 1, DBM_BTREFC
, seqno
, bno
);
4885 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_refc_mxr
[0] ||
4886 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_refc_mnr
[0])) {
4887 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in "
4888 "refcntbt block %u/%u\n"),
4889 be16_to_cpu(block
->bb_numrecs
), mp
->m_refc_mnr
[0],
4890 mp
->m_refc_mxr
[0], seqno
, bno
);
4894 rp
= XFS_REFCOUNT_REC_ADDR(block
, 1);
4896 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++) {
4897 if (be32_to_cpu(rp
[i
].rc_refcount
) == 1) {
4898 xfs_agblock_t agbno
;
4901 agbno
= be32_to_cpu(rp
[i
].rc_startblock
);
4902 if (agbno
& XFS_REFC_COWFLAG
) {
4903 agbno
&= ~XFS_REFC_COWFLAG
;
4905 "leftover CoW extent (%u/%u) len %u\n");
4908 "leftover CoW extent at unexpected address (%u/%u) len %u\n");
4913 be32_to_cpu(rp
[i
].rc_blockcount
));
4916 be32_to_cpu(rp
[i
].rc_blockcount
),
4917 DBM_COWDATA
, seqno
, bno
);
4920 be32_to_cpu(rp
[i
].rc_startblock
),
4921 be32_to_cpu(rp
[i
].rc_blockcount
),
4922 DBM_RLDATA
, seqno
, bno
);
4924 if (be32_to_cpu(rp
[i
].rc_startblock
) < lastblock
) {
4926 "out-of-order refcnt btree record %d (%u %u) block %u/%u\n"),
4927 i
, be32_to_cpu(rp
[i
].rc_startblock
),
4928 be32_to_cpu(rp
[i
].rc_startblock
),
4929 be32_to_cpu(agf
->agf_seqno
), bno
);
4931 lastblock
= be32_to_cpu(rp
[i
].rc_startblock
) +
4932 be32_to_cpu(rp
[i
].rc_blockcount
);
4937 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_refc_mxr
[1] ||
4938 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_refc_mnr
[1])) {
4939 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in refcntbt "
4941 be16_to_cpu(block
->bb_numrecs
), mp
->m_refc_mnr
[1],
4942 mp
->m_refc_mxr
[1], seqno
, bno
);
4946 pp
= XFS_REFCOUNT_PTR_ADDR(block
, 1, mp
->m_refc_mxr
[1]);
4947 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++)
4948 scan_sbtree(agf
, be32_to_cpu(pp
[i
]), level
, 0, scanfunc_refcnt
,
4954 xfs_agnumber_t agno
,
4955 xfs_agblock_t agbno
,
4958 xfs_agnumber_t c_agno
,
4959 xfs_agblock_t c_agbno
)
4961 check_set_dbmap(agno
, agbno
, len
, DBM_UNKNOWN
, type
, c_agno
, c_agbno
);
4966 xfs_agnumber_t agno
,
4967 xfs_agblock_t agbno
,
4975 if (!check_inomap(agno
, agbno
, len
, id
->ino
))
4977 mayprint
= verbose
| id
->ilist
| blist_size
;
4978 for (i
= 0, idp
= &inomap
[agno
][agbno
]; i
< len
; i
++, idp
++) {
4981 (verbose
|| id
->ilist
|| CHECK_BLISTA(agno
, agbno
+ i
)))
4982 dbprintf(_("setting inode to %lld for block %u/%u\n"),
4983 id
->ino
, agno
, agbno
+ i
);
4993 check_set_rdbmap(bno
, len
, DBM_UNKNOWN
, type
);
5006 if (!check_rinomap(bno
, len
, id
->ino
))
5008 mayprint
= verbose
| id
->ilist
| blist_size
;
5009 for (i
= 0, idp
= &inomap
[mp
->m_sb
.sb_agcount
][bno
];
5013 if (mayprint
&& (verbose
|| id
->ilist
|| CHECK_BLIST(bno
+ i
)))
5014 dbprintf(_("setting inode to %lld for rtblock %llu\n"),
5026 id
->link_set
= nlink
;
5028 id
->security
= security
;
5029 if (verbose
|| id
->ilist
)
5030 dbprintf(_("inode %lld nlink %u %s dir\n"), id
->ino
, nlink
,
5031 isdir
? "is" : "not");