2 * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
37 IS_USER_QUOTA
, IS_PROJECT_QUOTA
, IS_GROUP_QUOTA
,
41 DBM_UNKNOWN
, DBM_AGF
, DBM_AGFL
, DBM_AGI
,
42 DBM_ATTR
, DBM_BTBMAPA
, DBM_BTBMAPD
, DBM_BTBNO
,
43 DBM_BTCNT
, DBM_BTINO
, DBM_DATA
, DBM_DIR
,
44 DBM_FREE1
, DBM_FREE2
, DBM_FREELIST
, DBM_INODE
,
45 DBM_LOG
, DBM_MISSING
, DBM_QUOTA
, DBM_RTBITMAP
,
46 DBM_RTDATA
, DBM_RTFREE
, DBM_RTSUM
, DBM_SB
,
47 DBM_SYMLINK
, DBM_BTFINO
,
51 typedef struct inodata
{
59 struct inodata
*parent
;
62 #define MIN_INODATA_HASH_SIZE 256
63 #define MAX_INODATA_HASH_SIZE 65536
64 #define INODATA_AVG_HASH_LENGTH 8
66 typedef struct qinfo
{
72 #define QDATA_HASH_SIZE 256
73 typedef struct qdata
{
80 typedef struct blkent
{
81 xfs_fileoff_t startoff
;
83 xfs_fsblock_t blks
[1];
85 #define BLKENT_SIZE(n) \
86 (offsetof(blkent_t, blks) + (sizeof(xfs_fsblock_t) * (n)))
88 typedef struct blkmap
{
93 #define BLKMAP_SIZE(n) \
94 (offsetof(blkmap_t, ents) + (sizeof(blkent_t *) * (n)))
96 typedef struct freetab
{
99 xfs_dir2_data_off_t ents
[1];
101 #define FREETAB_SIZE(n) \
102 (offsetof(freetab_t, ents) + (sizeof(xfs_dir2_data_off_t) * (n)))
104 typedef struct dirhash
{
105 struct dirhash
*next
;
110 #define DIR_HASH_SIZE 1024
111 #define DIR_HASH_FUNC(h,a) (((h) ^ (a)) % DIR_HASH_SIZE)
113 static xfs_extlen_t agffreeblks
;
114 static xfs_extlen_t agflongest
;
115 static __uint64_t agf_aggr_freeblks
; /* aggregate count over all */
116 static __uint32_t agfbtreeblks
;
117 static int lazycount
;
118 static xfs_agino_t agicount
;
119 static xfs_agino_t agifreecount
;
120 static xfs_fsblock_t
*blist
;
121 static int blist_size
;
122 static char **dbmap
; /* really dbm_t:8 */
123 static dirhash_t
**dirhash
;
125 static __uint64_t fdblocks
;
126 static __uint64_t frextents
;
127 static __uint64_t icount
;
128 static __uint64_t ifree
;
129 static inodata_t
***inodata
;
130 static int inodata_hash_size
;
131 static inodata_t
***inomap
;
135 static qdata_t
**qpdata
;
137 static qdata_t
**qudata
;
139 static qdata_t
**qgdata
;
141 static unsigned sbversion
;
142 static int sbver_err
;
143 static int serious_error
;
145 static xfs_suminfo_t
*sumcompute
;
146 static xfs_suminfo_t
*sumfile
;
147 static const char *typename
[] = {
178 #define CHECK_BLIST(b) (blist_size && check_blist(b))
179 #define CHECK_BLISTA(a,b) \
180 (blist_size && check_blist(XFS_AGB_TO_FSB(mp, a, b)))
182 typedef void (*scan_lbtree_f_t
)(struct xfs_btree_block
*block
,
187 xfs_rfsblock_t
*totd
,
188 xfs_rfsblock_t
*toti
,
194 typedef void (*scan_sbtree_f_t
)(struct xfs_btree_block
*block
,
200 static void add_blist(xfs_fsblock_t bno
);
201 static void add_ilist(xfs_ino_t ino
);
202 static void addlink_inode(inodata_t
*id
);
203 static void addname_inode(inodata_t
*id
, char *name
, int namelen
);
204 static void addparent_inode(inodata_t
*id
, xfs_ino_t parent
);
205 static void blkent_append(blkent_t
**entp
, xfs_fsblock_t b
,
207 static blkent_t
*blkent_new(xfs_fileoff_t o
, xfs_fsblock_t b
,
209 static void blkent_prepend(blkent_t
**entp
, xfs_fsblock_t b
,
211 static blkmap_t
*blkmap_alloc(xfs_extnum_t
);
212 static void blkmap_free(blkmap_t
*blkmap
);
213 static xfs_fsblock_t
blkmap_get(blkmap_t
*blkmap
, xfs_fileoff_t o
);
214 static int blkmap_getn(blkmap_t
*blkmap
, xfs_fileoff_t o
, int nb
,
216 static void blkmap_grow(blkmap_t
**blkmapp
, blkent_t
**entp
,
218 static xfs_fileoff_t
blkmap_next_off(blkmap_t
*blkmap
, xfs_fileoff_t o
,
220 static void blkmap_set_blk(blkmap_t
**blkmapp
, xfs_fileoff_t o
,
222 static void blkmap_set_ext(blkmap_t
**blkmapp
, xfs_fileoff_t o
,
223 xfs_fsblock_t b
, xfs_extlen_t c
);
224 static void blkmap_shrink(blkmap_t
*blkmap
, blkent_t
**entp
);
225 static int blockfree_f(int argc
, char **argv
);
226 static int blockget_f(int argc
, char **argv
);
227 static int blocktrash_f(int argc
, char **argv
);
228 static int blockuse_f(int argc
, char **argv
);
229 static int check_blist(xfs_fsblock_t bno
);
230 static void check_dbmap(xfs_agnumber_t agno
, xfs_agblock_t agbno
,
231 xfs_extlen_t len
, dbm_t type
);
232 static int check_inomap(xfs_agnumber_t agno
, xfs_agblock_t agbno
,
233 xfs_extlen_t len
, xfs_ino_t c_ino
);
234 static void check_linkcounts(xfs_agnumber_t agno
);
235 static int check_range(xfs_agnumber_t agno
, xfs_agblock_t agbno
,
237 static void check_rdbmap(xfs_rfsblock_t bno
, xfs_extlen_t len
,
239 static int check_rinomap(xfs_rfsblock_t bno
, xfs_extlen_t len
,
241 static void check_rootdir(void);
242 static int check_rrange(xfs_rfsblock_t bno
, xfs_extlen_t len
);
243 static void check_set_dbmap(xfs_agnumber_t agno
,
244 xfs_agblock_t agbno
, xfs_extlen_t len
,
245 dbm_t type1
, dbm_t type2
,
246 xfs_agnumber_t c_agno
,
247 xfs_agblock_t c_agbno
);
248 static void check_set_rdbmap(xfs_rfsblock_t bno
, xfs_extlen_t len
,
249 dbm_t type1
, dbm_t type2
);
250 static void check_summary(void);
251 static void checknot_dbmap(xfs_agnumber_t agno
, xfs_agblock_t agbno
,
252 xfs_extlen_t len
, int typemask
);
253 static void checknot_rdbmap(xfs_rfsblock_t bno
, xfs_extlen_t len
,
255 static void dir_hash_add(xfs_dahash_t hash
,
256 xfs_dir2_dataptr_t addr
);
257 static void dir_hash_check(inodata_t
*id
, int v
);
258 static void dir_hash_done(void);
259 static void dir_hash_init(void);
260 static int dir_hash_see(xfs_dahash_t hash
,
261 xfs_dir2_dataptr_t addr
);
262 static inodata_t
*find_inode(xfs_ino_t ino
, int add
);
263 static void free_inodata(xfs_agnumber_t agno
);
264 static int init(int argc
, char **argv
);
265 static char *inode_name(xfs_ino_t ino
, inodata_t
**ipp
);
266 static int ncheck_f(int argc
, char **argv
);
267 static char *prepend_path(char *oldpath
, char *parent
);
268 static xfs_ino_t
process_block_dir_v2(blkmap_t
*blkmap
, int *dot
,
269 int *dotdot
, inodata_t
*id
);
270 static void process_bmbt_reclist(xfs_bmbt_rec_t
*rp
, int numrecs
,
271 dbm_t type
, inodata_t
*id
,
274 static void process_btinode(inodata_t
*id
, xfs_dinode_t
*dip
,
275 dbm_t type
, xfs_rfsblock_t
*totd
,
276 xfs_rfsblock_t
*toti
, xfs_extnum_t
*nex
,
277 blkmap_t
**blkmapp
, int whichfork
);
278 static xfs_ino_t
process_data_dir_v2(int *dot
, int *dotdot
,
279 inodata_t
*id
, int v
,
281 freetab_t
**freetabp
);
282 static xfs_dir2_data_free_t
*process_data_dir_v2_freefind(
283 struct xfs_dir2_data_hdr
*data
,
284 struct xfs_dir2_data_unused
*dup
);
285 static void process_dir(xfs_dinode_t
*dip
, blkmap_t
*blkmap
,
287 static int process_dir_v2(xfs_dinode_t
*dip
, blkmap_t
*blkmap
,
288 int *dot
, int *dotdot
, inodata_t
*id
,
290 static void process_exinode(inodata_t
*id
, xfs_dinode_t
*dip
,
291 dbm_t type
, xfs_rfsblock_t
*totd
,
292 xfs_rfsblock_t
*toti
, xfs_extnum_t
*nex
,
293 blkmap_t
**blkmapp
, int whichfork
);
294 static void process_inode(xfs_agf_t
*agf
, xfs_agino_t agino
,
295 xfs_dinode_t
*dip
, int isfree
);
296 static void process_lclinode(inodata_t
*id
, xfs_dinode_t
*dip
,
297 dbm_t type
, xfs_rfsblock_t
*totd
,
298 xfs_rfsblock_t
*toti
, xfs_extnum_t
*nex
,
299 blkmap_t
**blkmapp
, int whichfork
);
300 static xfs_ino_t
process_leaf_node_dir_v2(blkmap_t
*blkmap
, int *dot
,
301 int *dotdot
, inodata_t
*id
,
302 xfs_fsize_t dirsize
);
303 static void process_leaf_node_dir_v2_free(inodata_t
*id
, int v
,
306 static void process_leaf_node_dir_v2_int(inodata_t
*id
, int v
,
309 static void process_quota(qtype_t qtype
, inodata_t
*id
,
311 static void process_rtbitmap(blkmap_t
*blkmap
);
312 static void process_rtsummary(blkmap_t
*blkmap
);
313 static xfs_ino_t
process_sf_dir_v2(xfs_dinode_t
*dip
, int *dot
,
314 int *dotdot
, inodata_t
*id
);
315 static void quota_add(xfs_dqid_t
*p
, xfs_dqid_t
*g
, xfs_dqid_t
*u
,
316 int dq
, xfs_qcnt_t bc
, xfs_qcnt_t ic
,
318 static void quota_add1(qdata_t
**qt
, xfs_dqid_t id
, int dq
,
319 xfs_qcnt_t bc
, xfs_qcnt_t ic
,
321 static void quota_check(char *s
, qdata_t
**qt
);
322 static void quota_init(void);
323 static void scan_ag(xfs_agnumber_t agno
);
324 static void scan_freelist(xfs_agf_t
*agf
);
325 static void scan_lbtree(xfs_fsblock_t root
, int nlevels
,
326 scan_lbtree_f_t func
, dbm_t type
,
327 inodata_t
*id
, xfs_rfsblock_t
*totd
,
328 xfs_rfsblock_t
*toti
, xfs_extnum_t
*nex
,
329 blkmap_t
**blkmapp
, int isroot
,
331 static void scan_sbtree(xfs_agf_t
*agf
, xfs_agblock_t root
,
332 int nlevels
, int isroot
,
333 scan_sbtree_f_t func
, typnm_t btype
);
334 static void scanfunc_bmap(struct xfs_btree_block
*block
,
335 int level
, dbm_t type
, xfs_fsblock_t bno
,
336 inodata_t
*id
, xfs_rfsblock_t
*totd
,
337 xfs_rfsblock_t
*toti
, xfs_extnum_t
*nex
,
338 blkmap_t
**blkmapp
, int isroot
,
340 static void scanfunc_bno(struct xfs_btree_block
*block
, int level
,
341 xfs_agf_t
*agf
, xfs_agblock_t bno
,
343 static void scanfunc_cnt(struct xfs_btree_block
*block
, int level
,
344 xfs_agf_t
*agf
, xfs_agblock_t bno
,
346 static void scanfunc_ino(struct xfs_btree_block
*block
, int level
,
347 xfs_agf_t
*agf
, xfs_agblock_t bno
,
349 static void scanfunc_fino(struct xfs_btree_block
*block
, int level
,
350 struct xfs_agf
*agf
, xfs_agblock_t bno
,
352 static void set_dbmap(xfs_agnumber_t agno
, xfs_agblock_t agbno
,
353 xfs_extlen_t len
, dbm_t type
,
354 xfs_agnumber_t c_agno
, xfs_agblock_t c_agbno
);
355 static void set_inomap(xfs_agnumber_t agno
, xfs_agblock_t agbno
,
356 xfs_extlen_t len
, inodata_t
*id
);
357 static void set_rdbmap(xfs_rfsblock_t bno
, xfs_extlen_t len
,
359 static void set_rinomap(xfs_rfsblock_t bno
, xfs_extlen_t len
,
361 static void setlink_inode(inodata_t
*id
, nlink_t nlink
, int isdir
,
364 static const cmdinfo_t blockfree_cmd
=
365 { "blockfree", NULL
, blockfree_f
, 0, 0, 0,
366 NULL
, N_("free block usage information"), NULL
};
367 static const cmdinfo_t blockget_cmd
=
368 { "blockget", "check", blockget_f
, 0, -1, 0,
369 N_("[-s|-v] [-n] [-t] [-b bno]... [-i ino] ..."),
370 N_("get block usage and check consistency"), NULL
};
371 static const cmdinfo_t blocktrash_cmd
=
372 { "blocktrash", NULL
, blocktrash_f
, 0, -1, 0,
373 N_("[-n count] [-x minlen] [-y maxlen] [-s seed] [-0123] [-t type] ..."),
374 N_("trash randomly selected block(s)"), NULL
};
375 static const cmdinfo_t blockuse_cmd
=
376 { "blockuse", NULL
, blockuse_f
, 0, 3, 0,
377 N_("[-n] [-c blockcount]"),
378 N_("print usage for current block(s)"), NULL
};
379 static const cmdinfo_t ncheck_cmd
=
380 { "ncheck", NULL
, ncheck_f
, 0, -1, 0,
381 N_("[-s] [-i ino] ..."),
382 N_("print inode-name pairs"), NULL
};
390 blist
= xrealloc(blist
, blist_size
* sizeof(bno
));
391 blist
[blist_size
- 1] = bno
;
400 id
= find_inode(ino
, 1);
402 dbprintf(_("-i %lld bad inode number\n"), ino
);
413 if (verbose
|| id
->ilist
)
414 dbprintf(_("inode %lld add link, now %u\n"), id
->ino
,
424 if (!nflag
|| id
->name
)
426 id
->name
= xmalloc(namelen
+ 1);
427 memcpy(id
->name
, name
, namelen
);
428 id
->name
[namelen
] = '\0';
438 pid
= find_inode(parent
, 1);
440 if (verbose
|| id
->ilist
|| (pid
&& pid
->ilist
))
441 dbprintf(_("inode %lld parent %lld\n"), id
->ino
, parent
);
454 *entp
= ent
= xrealloc(ent
, BLKENT_SIZE(c
+ ent
->nblks
));
455 for (i
= 0; i
< c
; i
++)
456 ent
->blks
[ent
->nblks
+ i
] = b
+ i
;
469 ent
= xmalloc(BLKENT_SIZE(c
));
472 for (i
= 0; i
< c
; i
++)
473 ent
->blks
[i
] = b
+ i
;
488 newent
= xmalloc(BLKENT_SIZE(oldent
->nblks
+ c
));
489 newent
->nblks
= oldent
->nblks
+ c
;
490 newent
->startoff
= oldent
->startoff
- c
;
491 for (i
= 0; i
< c
; i
++)
492 newent
->blks
[i
] = b
+ c
;
493 for (; i
< oldent
->nblks
+ c
; i
++)
494 newent
->blks
[i
] = oldent
->blks
[i
- c
];
507 blkmap
= xmalloc(BLKMAP_SIZE(nex
));
508 blkmap
->naents
= nex
;
520 for (i
= 0, entp
= blkmap
->ents
; i
< blkmap
->nents
; i
++, entp
++)
534 for (i
= 0, entp
= blkmap
->ents
; i
< blkmap
->nents
; i
++, entp
++) {
536 if (o
>= ent
->startoff
&& o
< ent
->startoff
+ ent
->nblks
)
537 return ent
->blks
[o
- ent
->startoff
];
556 for (i
= nex
= 0, bmp
= NULL
, entp
= blkmap
->ents
;
560 if (ent
->startoff
>= o
+ nb
)
562 if (ent
->startoff
+ ent
->nblks
<= o
)
564 for (ento
= ent
->startoff
;
565 ento
< ent
->startoff
+ ent
->nblks
&& ento
< o
+ nb
;
570 bmp
[nex
- 1].startoff
+ bmp
[nex
- 1].blockcount
==
572 bmp
[nex
- 1].startblock
+ bmp
[nex
- 1].blockcount
==
573 ent
->blks
[ento
- ent
->startoff
])
574 bmp
[nex
- 1].blockcount
++;
576 bmp
= realloc(bmp
, ++nex
* sizeof(*bmp
));
577 bmp
[nex
- 1].startoff
= ento
;
578 bmp
[nex
- 1].startblock
=
579 ent
->blks
[ento
- ent
->startoff
];
580 bmp
[nex
- 1].blockcount
= 1;
581 bmp
[nex
- 1].flag
= 0;
600 idx
= (int)(entp
- blkmap
->ents
);
601 if (blkmap
->naents
== blkmap
->nents
) {
602 blkmap
= xrealloc(blkmap
, BLKMAP_SIZE(blkmap
->nents
+ 1));
606 for (i
= blkmap
->nents
; i
> idx
; i
--)
607 blkmap
->ents
[i
] = blkmap
->ents
[i
- 1];
608 blkmap
->ents
[idx
] = newent
;
620 ent
= blkmap
->ents
[blkmap
->nents
- 1];
621 return ent
->startoff
+ ent
->nblks
;
635 if (o
== NULLFILEOFF
) {
637 ent
= blkmap
->ents
[0];
638 return ent
->startoff
;
640 entp
= &blkmap
->ents
[*t
];
642 if (o
< ent
->startoff
+ ent
->nblks
- 1)
645 if (entp
>= &blkmap
->ents
[blkmap
->nents
])
649 return ent
->startoff
;
664 for (entp
= blkmap
->ents
; entp
< &blkmap
->ents
[blkmap
->nents
]; entp
++) {
666 if (o
< ent
->startoff
- 1) {
667 ent
= blkent_new(o
, b
, 1);
668 blkmap_grow(blkmapp
, entp
, ent
);
671 if (o
== ent
->startoff
- 1) {
672 blkent_prepend(entp
, b
, 1);
675 if (o
>= ent
->startoff
&& o
< ent
->startoff
+ ent
->nblks
) {
676 ent
->blks
[o
- ent
->startoff
] = b
;
679 if (o
> ent
->startoff
+ ent
->nblks
)
681 blkent_append(entp
, b
, 1);
682 if (entp
== &blkmap
->ents
[blkmap
->nents
- 1])
686 if (ent
->startoff
+ ent
->nblks
< nextent
->startoff
)
688 blkent_append(entp
, nextent
->blks
[0], nextent
->nblks
);
689 blkmap_shrink(blkmap
, &entp
[1]);
692 ent
= blkent_new(o
, b
, 1);
693 blkmap_grow(blkmapp
, entp
, ent
);
709 if (!blkmap
->nents
) {
710 blkmap
->ents
[0] = blkent_new(o
, b
, c
);
714 entp
= &blkmap
->ents
[blkmap
->nents
- 1];
716 if (ent
->startoff
+ ent
->nblks
== o
) {
717 blkent_append(entp
, b
, c
);
720 if (ent
->startoff
+ ent
->nblks
< o
) {
721 ent
= blkent_new(o
, b
, c
);
722 blkmap_grow(blkmapp
, &blkmap
->ents
[blkmap
->nents
], ent
);
725 for (i
= 0; i
< c
; i
++)
726 blkmap_set_blk(blkmapp
, o
+ i
, b
+ i
);
738 idx
= (int)(entp
- blkmap
->ents
);
739 for (i
= idx
+ 1; i
< blkmap
->nents
; i
++)
740 blkmap
->ents
[i
] = blkmap
->ents
[i
- 1];
754 dbprintf(_("block usage information not allocated\n"));
757 rt
= mp
->m_sb
.sb_rextents
!= 0;
758 for (c
= 0; c
< mp
->m_sb
.sb_agcount
; c
++) {
768 sumcompute
= sumfile
= NULL
;
780 * Check consistency of xfs filesystem contents.
792 dbprintf(_("already have block usage information\n"));
796 if (!init(argc
, argv
)) {
803 oldprefix
= dbprefix
;
805 for (agno
= 0, sbyell
= 0; agno
< mp
->m_sb
.sb_agcount
; agno
++) {
807 if (sbver_err
> 4 && !sbyell
&& sbver_err
>= agno
) {
809 dbprintf(_("WARNING: this may be a newer XFS "
820 dbprefix
= oldprefix
;
825 * Check that there are no blocks either
826 * a) unaccounted for or
827 * b) bno-free but not cnt-free
829 if (!tflag
) { /* are we in test mode, faking out freespace? */
830 for (agno
= 0; agno
< mp
->m_sb
.sb_agcount
; agno
++)
831 checknot_dbmap(agno
, 0, mp
->m_sb
.sb_agblocks
,
832 (1 << DBM_UNKNOWN
) | (1 << DBM_FREE1
));
834 for (agno
= 0; agno
< mp
->m_sb
.sb_agcount
; agno
++)
835 check_linkcounts(agno
);
836 if (mp
->m_sb
.sb_rblocks
) {
838 (xfs_extlen_t
)(mp
->m_sb
.sb_rextents
*
839 mp
->m_sb
.sb_rextsize
),
843 if (mp
->m_sb
.sb_icount
!= icount
) {
845 dbprintf(_("sb_icount %lld, counted %lld\n"),
846 mp
->m_sb
.sb_icount
, icount
);
849 if (mp
->m_sb
.sb_ifree
!= ifree
) {
851 dbprintf(_("sb_ifree %lld, counted %lld\n"),
852 mp
->m_sb
.sb_ifree
, ifree
);
855 if (mp
->m_sb
.sb_fdblocks
!= fdblocks
) {
857 dbprintf(_("sb_fdblocks %lld, counted %lld\n"),
858 mp
->m_sb
.sb_fdblocks
, fdblocks
);
861 if (lazycount
&& mp
->m_sb
.sb_fdblocks
!= agf_aggr_freeblks
) {
863 dbprintf(_("sb_fdblocks %lld, aggregate AGF count %lld\n"),
864 mp
->m_sb
.sb_fdblocks
, agf_aggr_freeblks
);
867 if (mp
->m_sb
.sb_frextents
!= frextents
) {
869 dbprintf(_("sb_frextents %lld, counted %lld\n"),
870 mp
->m_sb
.sb_frextents
, frextents
);
873 if (mp
->m_sb
.sb_bad_features2
!= 0 &&
874 mp
->m_sb
.sb_bad_features2
!= mp
->m_sb
.sb_features2
) {
876 dbprintf(_("sb_features2 (0x%x) not same as "
877 "sb_bad_features2 (0x%x)\n"),
878 mp
->m_sb
.sb_features2
,
879 mp
->m_sb
.sb_bad_features2
);
882 if ((sbversion
& XFS_SB_VERSION_ATTRBIT
) &&
883 !xfs_sb_version_hasattr(&mp
->m_sb
)) {
885 dbprintf(_("sb versionnum missing attr bit %x\n"),
886 XFS_SB_VERSION_ATTRBIT
);
889 if ((sbversion
& XFS_SB_VERSION_QUOTABIT
) &&
890 !xfs_sb_version_hasquota(&mp
->m_sb
)) {
892 dbprintf(_("sb versionnum missing quota bit %x\n"),
893 XFS_SB_VERSION_QUOTABIT
);
896 if (!(sbversion
& XFS_SB_VERSION_ALIGNBIT
) &&
897 xfs_sb_version_hasalign(&mp
->m_sb
)) {
899 dbprintf(_("sb versionnum extra align bit %x\n"),
900 XFS_SB_VERSION_ALIGNBIT
);
904 quota_check("user", qudata
);
906 quota_check("project", qpdata
);
908 quota_check("group", qgdata
);
909 if (sbver_err
> mp
->m_sb
.sb_agcount
/ 2)
910 dbprintf(_("WARNING: this may be a newer XFS filesystem.\n"));
913 dbprefix
= oldprefix
;
917 typedef struct ltab
{
936 const struct xfs_buf_ops
*stashed_ops
;
937 static char *modestr
[] = {
938 N_("zeroed"), N_("set"), N_("flipped"), N_("randomized")
943 agno
= XFS_FSB_TO_AGNO(mp
, XFS_DADDR_TO_FSB(mp
, iocur_top
->bb
));
944 agbno
= XFS_FSB_TO_AGBNO(mp
, XFS_DADDR_TO_FSB(mp
, iocur_top
->bb
));
945 if (iocur_top
->len
== 0) {
946 dbprintf(_("zero-length block %u/%u buffer to trash??\n"),
950 len
= (int)((random() % (ltabp
->max
- ltabp
->min
+ 1)) + ltabp
->min
);
952 * bit_offset >= 0: start fuzzing at this exact bit_offset.
953 * bit_offset < 0: pick an offset at least as high at -(bit_offset + 1).
955 if (bit_offset
< 0) {
956 bit_offset
= -(bit_offset
+ 1);
957 bit_offset
+= (int)(random() % (int)((iocur_top
->len
- bit_offset
) * NBBY
));
959 if (bit_offset
+ len
>= iocur_top
->len
* NBBY
)
960 len
= (iocur_top
->len
* NBBY
) - bit_offset
;
962 stashed_ops
= iocur_top
->bp
->b_ops
;
963 iocur_top
->bp
->b_ops
= NULL
;
964 if ((buf
= iocur_top
->data
) == NULL
) {
965 dbprintf(_("can't read block %u/%u for trashing\n"), agno
, agbno
);
968 for (bitno
= 0; bitno
< len
; bitno
++) {
969 bit
= (bit_offset
+ bitno
) % (mp
->m_sb
.sb_blocksize
* NBBY
);
981 newbit
= (buf
[byte
] & mask
) == 0;
984 newbit
= (int)random() & 1;
993 iocur_top
->bp
->b_ops
= stashed_ops
;
994 printf(_("blocktrash: %u/%u %s block %d bit%s starting %d:%d %s\n"),
995 agno
, agbno
, typename
[type
], len
, len
== 1 ? "" : "s",
996 bit_offset
/ NBBY
, bit_offset
% NBBY
, modestr
[mode
]);
1004 xfs_agblock_t agbno
;
1005 xfs_agnumber_t agno
;
1007 xfs_rfsblock_t blocks
;
1020 xfs_rfsblock_t randb
;
1024 bool this_block
= false;
1025 int bit_offset
= -1;
1032 gettimeofday(&now
, NULL
);
1033 seed
= (unsigned int)(now
.tv_sec
^ now
.tv_usec
);
1036 goodmask
= (1 << DBM_AGF
) |
1040 (1 << DBM_BTBMAPA
) |
1041 (1 << DBM_BTBMAPD
) |
1049 (1 << DBM_RTBITMAP
) |
1051 (1 << DBM_SYMLINK
) |
1054 while ((c
= getopt(argc
, argv
, "0123n:o:s:t:x:y:z")) != EOF
) {
1069 count
= (int)strtol(optarg
, &p
, 0);
1070 if (*p
!= '\0' || count
<= 0) {
1071 dbprintf(_("bad blocktrash count %s\n"), optarg
);
1077 if (optarg
[0] == '+') {
1081 bit_offset
= (int)strtol(optarg
, &p
, 0);
1082 if (*p
!= '\0' || bit_offset
< 0) {
1083 dbprintf(_("bad blocktrash offset %s\n"), optarg
);
1087 bit_offset
= -bit_offset
- 1;
1091 seed
= (uint
)strtoul(optarg
, &p
, 0);
1095 for (i
= 0; typename
[i
]; i
++) {
1096 if (strcmp(typename
[i
], optarg
) == 0)
1099 if (!typename
[i
] || (((1 << i
) & goodmask
) == 0)) {
1100 dbprintf(_("bad blocktrash type %s\n"), optarg
);
1106 min
= (int)strtol(optarg
, &p
, 0);
1107 if (*p
!= '\0' || min
<= 0 ||
1108 min
> mp
->m_sb
.sb_blocksize
* NBBY
) {
1109 dbprintf(_("bad blocktrash min %s\n"), optarg
);
1114 max
= (int)strtol(optarg
, &p
, 0);
1115 if (*p
!= '\0' || max
<= 0 ||
1116 max
> mp
->m_sb
.sb_blocksize
* NBBY
) {
1117 dbprintf(_("bad blocktrash max %s\n"), optarg
);
1125 dbprintf(_("bad option for blocktrash command\n"));
1129 if (!this_block
&& !dbmap
) {
1130 dbprintf(_("must run blockget first\n"));
1133 if (this_block
&& iocur_sp
== 0) {
1134 dbprintf(_("nothing on stack\n"));
1138 dbprintf(_("bad min/max for blocktrash command\n"));
1142 tmask
= goodmask
& ~((1 << DBM_LOG
) | (1 << DBM_SB
));
1143 lentab
= xmalloc(sizeof(ltab_t
));
1144 lentab
->min
= lentab
->max
= min
;
1146 for (i
= min
+ 1; i
<= max
; i
++) {
1147 if ((i
& (i
- 1)) == 0) {
1148 lentab
= xrealloc(lentab
,
1149 sizeof(ltab_t
) * (lentablen
+ 1));
1150 lentab
[lentablen
].min
= lentab
[lentablen
].max
= i
;
1153 lentab
[lentablen
- 1].max
= i
;
1156 dbprintf(_("blocktrash: seed %u\n"), seed
);
1159 blocktrash_b(bit_offset
, DBM_UNKNOWN
,
1160 &lentab
[random() % lentablen
], mode
);
1163 for (blocks
= 0, agno
= 0; agno
< mp
->m_sb
.sb_agcount
; agno
++) {
1164 for (agbno
= 0, p
= dbmap
[agno
];
1165 agbno
< mp
->m_sb
.sb_agblocks
;
1167 if ((1 << *p
) & tmask
)
1172 dbprintf(_("blocktrash: no matching blocks\n"));
1175 for (i
= 0; i
< count
; i
++) {
1176 randb
= (xfs_rfsblock_t
)((((__int64_t
)random() << 32) |
1177 random()) % blocks
);
1178 for (bi
= 0, agno
= 0, done
= 0;
1179 !done
&& agno
< mp
->m_sb
.sb_agcount
;
1181 for (agbno
= 0, p
= dbmap
[agno
];
1182 agbno
< mp
->m_sb
.sb_agblocks
;
1184 if (!((1 << *p
) & tmask
))
1190 XFS_AGB_TO_DADDR(mp
, agno
, agbno
),
1191 blkbb
, DB_RING_IGN
, NULL
);
1192 blocktrash_b(bit_offset
, (dbm_t
)*p
,
1193 &lentab
[random() % lentablen
], mode
);
1210 xfs_agblock_t agbno
;
1211 xfs_agnumber_t agno
;
1221 dbprintf(_("must run blockget first\n"));
1226 fsb
= XFS_DADDR_TO_FSB(mp
, iocur_top
->off
>> BBSHIFT
);
1227 agno
= XFS_FSB_TO_AGNO(mp
, fsb
);
1228 end
= agbno
= XFS_FSB_TO_AGBNO(mp
, fsb
);
1229 while ((c
= getopt(argc
, argv
, "c:n")) != EOF
) {
1232 count
= (int)strtol(optarg
, &p
, 0);
1233 end
= agbno
+ count
- 1;
1234 if (*p
!= '\0' || count
<= 0 ||
1235 end
>= mp
->m_sb
.sb_agblocks
) {
1236 dbprintf(_("bad blockuse count %s\n"), optarg
);
1242 dbprintf(_("must run blockget -n first\n"));
1248 dbprintf(_("bad option for blockuse command\n"));
1252 while (agbno
<= end
) {
1253 p
= &dbmap
[agno
][agbno
];
1254 i
= inomap
[agno
][agbno
];
1255 dbprintf(_("block %llu (%u/%u) type %s"),
1256 (xfs_fsblock_t
)XFS_AGB_TO_FSB(mp
, agno
, agbno
),
1257 agno
, agbno
, typename
[(dbm_t
)*p
]);
1259 dbprintf(_(" inode %lld"), i
->ino
);
1260 if (shownames
&& (p
= inode_name(i
->ino
, NULL
))) {
1277 for (i
= 0; i
< blist_size
; i
++) {
1278 if (blist
[i
] == bno
)
1286 xfs_agnumber_t agno
,
1287 xfs_agblock_t agbno
,
1294 for (i
= 0, p
= &dbmap
[agno
][agbno
]; i
< len
; i
++, p
++) {
1295 if ((dbm_t
)*p
!= type
) {
1296 if (!sflag
|| CHECK_BLISTA(agno
, agbno
+ i
))
1297 dbprintf(_("block %u/%u expected type %s got "
1299 agno
, agbno
+ i
, typename
[type
],
1300 typename
[(dbm_t
)*p
]);
1309 add_command(&blockfree_cmd
);
1310 add_command(&blockget_cmd
);
1312 add_command(&blocktrash_cmd
);
1313 add_command(&blockuse_cmd
);
1314 add_command(&ncheck_cmd
);
1319 xfs_agnumber_t agno
,
1320 xfs_agblock_t agbno
,
1328 if (!check_range(agno
, agbno
, len
)) {
1329 dbprintf(_("blocks %u/%u..%u claimed by inode %lld\n"),
1330 agno
, agbno
, agbno
+ len
- 1, c_ino
);
1333 for (i
= 0, rval
= 1, idp
= &inomap
[agno
][agbno
]; i
< len
; i
++, idp
++) {
1335 if (!sflag
|| (*idp
)->ilist
||
1336 CHECK_BLISTA(agno
, agbno
+ i
))
1337 dbprintf(_("block %u/%u claimed by inode %lld, "
1338 "previous inum %lld\n"),
1339 agno
, agbno
+ i
, c_ino
, (*idp
)->ino
);
1349 xfs_agnumber_t agno
)
1357 for (idx
= 0; idx
< inodata_hash_size
; ht
++, idx
++) {
1360 if (ep
->link_set
!= ep
->link_add
|| ep
->link_set
== 0) {
1361 path
= inode_name(ep
->ino
, NULL
);
1362 if (!path
&& ep
->link_add
)
1363 path
= xstrdup("?");
1364 if (!sflag
|| ep
->ilist
) {
1366 dbprintf(_("link count mismatch "
1367 "for inode %lld (name "
1373 else if (ep
->link_set
)
1374 dbprintf(_("disconnected inode "
1375 "%lld, nlink %d\n"),
1376 ep
->ino
, ep
->link_set
);
1378 dbprintf(_("allocated inode %lld "
1379 "has 0 link count\n"),
1385 } else if (verbose
|| ep
->ilist
) {
1386 path
= inode_name(ep
->ino
, NULL
);
1388 dbprintf(_("inode %lld name %s\n"),
1401 xfs_agnumber_t agno
,
1402 xfs_agblock_t agbno
,
1406 xfs_agblock_t low
= 0;
1407 xfs_agblock_t high
= 0;
1408 int valid_range
= 0;
1411 if (agno
>= mp
->m_sb
.sb_agcount
||
1412 agbno
+ len
- 1 >= mp
->m_sb
.sb_agblocks
) {
1413 for (i
= 0; i
< len
; i
++) {
1414 cur
= !sflag
|| CHECK_BLISTA(agno
, agbno
+ i
) ? 1 : 0;
1415 if (cur
== 1 && prev
== 0) {
1416 low
= high
= agbno
+ i
;
1418 } else if (cur
== 0 && prev
== 0) {
1420 } else if (cur
== 0 && prev
== 1) {
1422 dbprintf(_("block %u/%u out of range\n"),
1425 dbprintf(_("blocks %u/%u..%u "
1430 } else if (cur
== 1 && prev
== 1) {
1437 dbprintf(_("block %u/%u out of range\n"),
1440 dbprintf(_("blocks %u/%u..%u "
1460 for (i
= 0, p
= &dbmap
[mp
->m_sb
.sb_agcount
][bno
]; i
< len
; i
++, p
++) {
1461 if ((dbm_t
)*p
!= type
) {
1462 if (!sflag
|| CHECK_BLIST(bno
+ i
))
1463 dbprintf(_("rtblock %llu expected type %s got "
1465 bno
+ i
, typename
[type
],
1466 typename
[(dbm_t
)*p
]);
1482 if (!check_rrange(bno
, len
)) {
1483 dbprintf(_("rtblocks %llu..%llu claimed by inode %lld\n"),
1484 bno
, bno
+ len
- 1, c_ino
);
1487 for (i
= 0, rval
= 1, idp
= &inomap
[mp
->m_sb
.sb_agcount
][bno
];
1491 if (!sflag
|| (*idp
)->ilist
|| CHECK_BLIST(bno
+ i
))
1492 dbprintf(_("rtblock %llu claimed by inode %lld, "
1493 "previous inum %lld\n"),
1494 bno
+ i
, c_ino
, (*idp
)->ino
);
1507 id
= find_inode(mp
->m_sb
.sb_rootino
, 0);
1510 dbprintf(_("root inode %lld is missing\n"),
1511 mp
->m_sb
.sb_rootino
);
1513 } else if (!id
->isdir
) {
1514 if (!sflag
|| id
->ilist
)
1515 dbprintf(_("root inode %lld is not a directory\n"),
1516 mp
->m_sb
.sb_rootino
);
1528 if (bno
+ len
- 1 >= mp
->m_sb
.sb_rblocks
) {
1529 for (i
= 0; i
< len
; i
++) {
1530 if (!sflag
|| CHECK_BLIST(bno
+ i
))
1531 dbprintf(_("rtblock %llu out of range\n"),
1542 xfs_agnumber_t agno
,
1543 xfs_agblock_t agbno
,
1547 xfs_agnumber_t c_agno
,
1548 xfs_agblock_t c_agbno
)
1554 if (!check_range(agno
, agbno
, len
)) {
1555 dbprintf(_("blocks %u/%u..%u claimed by block %u/%u\n"), agno
,
1556 agbno
, agbno
+ len
- 1, c_agno
, c_agbno
);
1559 check_dbmap(agno
, agbno
, len
, type1
);
1560 mayprint
= verbose
| blist_size
;
1561 for (i
= 0, p
= &dbmap
[agno
][agbno
]; i
< len
; i
++, p
++) {
1563 if (mayprint
&& (verbose
|| CHECK_BLISTA(agno
, agbno
+ i
)))
1564 dbprintf(_("setting block %u/%u to %s\n"), agno
, agbno
+ i
,
1580 if (!check_rrange(bno
, len
))
1582 check_rdbmap(bno
, len
, type1
);
1583 mayprint
= verbose
| blist_size
;
1584 for (i
= 0, p
= &dbmap
[mp
->m_sb
.sb_agcount
][bno
]; i
< len
; i
++, p
++) {
1586 if (mayprint
&& (verbose
|| CHECK_BLIST(bno
+ i
)))
1587 dbprintf(_("setting rtblock %llu to %s\n"),
1588 bno
+ i
, typename
[type2
]);
1602 for (log
= 0; log
< mp
->m_rsumlevels
; log
++) {
1604 bno
< mp
->m_sb
.sb_rbmblocks
;
1605 bno
++, csp
++, fsp
++) {
1608 dbprintf(_("rt summary mismatch, size %d "
1609 "block %llu, file: %d, "
1611 log
, bno
, *fsp
, *csp
);
1620 xfs_agnumber_t agno
,
1621 xfs_agblock_t agbno
,
1628 if (!check_range(agno
, agbno
, len
))
1630 for (i
= 0, p
= &dbmap
[agno
][agbno
]; i
< len
; i
++, p
++) {
1631 if ((1 << *p
) & typemask
) {
1632 if (!sflag
|| CHECK_BLISTA(agno
, agbno
+ i
))
1633 dbprintf(_("block %u/%u type %s not expected\n"),
1634 agno
, agbno
+ i
, typename
[(dbm_t
)*p
]);
1649 if (!check_rrange(bno
, len
))
1651 for (i
= 0, p
= &dbmap
[mp
->m_sb
.sb_agcount
][bno
]; i
< len
; i
++, p
++) {
1652 if ((1 << *p
) & typemask
) {
1653 if (!sflag
|| CHECK_BLIST(bno
+ i
))
1654 dbprintf(_("rtblock %llu type %s not expected\n"),
1655 bno
+ i
, typename
[(dbm_t
)*p
]);
1664 xfs_dir2_dataptr_t addr
)
1669 i
= DIR_HASH_FUNC(hash
, addr
);
1670 p
= malloc(sizeof(*p
));
1671 p
->next
= dirhash
[i
];
1686 for (i
= 0; i
< DIR_HASH_SIZE
; i
++) {
1687 for (p
= dirhash
[i
]; p
; p
= p
->next
) {
1690 if (!sflag
|| id
->ilist
|| v
)
1691 dbprintf(_("dir ino %lld missing leaf entry for "
1693 id
->ino
, p
->hashval
, p
->address
);
1706 for (i
= 0; i
< DIR_HASH_SIZE
; i
++) {
1707 for (p
= dirhash
[i
]; p
; p
= n
) {
1719 dirhash
= calloc(DIR_HASH_SIZE
, sizeof(*dirhash
));
1725 xfs_dir2_dataptr_t addr
)
1730 i
= DIR_HASH_FUNC(hash
, addr
);
1731 for (p
= dirhash
[i
]; p
; p
= p
->next
) {
1732 if (p
->hashval
== hash
&& p
->address
== addr
) {
1748 xfs_agnumber_t agno
;
1753 agno
= XFS_INO_TO_AGNO(mp
, ino
);
1754 agino
= XFS_INO_TO_AGINO(mp
, ino
);
1755 if (agno
>= mp
->m_sb
.sb_agcount
||
1756 XFS_AGINO_TO_INO(mp
, agno
, agino
) != ino
)
1758 htab
= inodata
[agno
];
1759 ih
= agino
% inodata_hash_size
;
1762 if (ent
->ino
== ino
)
1768 ent
= xcalloc(1, sizeof(*ent
));
1770 ent
->next
= htab
[ih
];
1777 xfs_agnumber_t agno
)
1785 for (i
= 0; i
< inodata_hash_size
; i
++) {
1809 if (mp
->m_sb
.sb_magicnum
!= XFS_SB_MAGIC
) {
1810 dbprintf(_("bad superblock magic number %x, giving up\n"),
1811 mp
->m_sb
.sb_magicnum
);
1817 rt
= mp
->m_sb
.sb_rextents
!= 0;
1818 dbmap
= xmalloc((mp
->m_sb
.sb_agcount
+ rt
) * sizeof(*dbmap
));
1819 inomap
= xmalloc((mp
->m_sb
.sb_agcount
+ rt
) * sizeof(*inomap
));
1820 inodata
= xmalloc(mp
->m_sb
.sb_agcount
* sizeof(*inodata
));
1822 (int)MAX(MIN(mp
->m_sb
.sb_icount
/
1823 (INODATA_AVG_HASH_LENGTH
* mp
->m_sb
.sb_agcount
),
1824 MAX_INODATA_HASH_SIZE
),
1825 MIN_INODATA_HASH_SIZE
);
1826 for (c
= 0; c
< mp
->m_sb
.sb_agcount
; c
++) {
1827 dbmap
[c
] = xcalloc(mp
->m_sb
.sb_agblocks
, sizeof(**dbmap
));
1828 inomap
[c
] = xcalloc(mp
->m_sb
.sb_agblocks
, sizeof(**inomap
));
1829 inodata
[c
] = xcalloc(inodata_hash_size
, sizeof(**inodata
));
1832 dbmap
[c
] = xcalloc(mp
->m_sb
.sb_rblocks
, sizeof(**dbmap
));
1833 inomap
[c
] = xcalloc(mp
->m_sb
.sb_rblocks
, sizeof(**inomap
));
1834 sumfile
= xcalloc(mp
->m_rsumsize
, 1);
1835 sumcompute
= xcalloc(mp
->m_rsumsize
, 1);
1837 nflag
= sflag
= tflag
= verbose
= optind
= 0;
1838 while ((c
= getopt(argc
, argv
, "b:i:npstv")) != EOF
) {
1841 bno
= strtoll(optarg
, NULL
, 10);
1845 ino
= strtoll(optarg
, NULL
, 10);
1864 dbprintf(_("bad option for blockget command\n"));
1868 error
= sbver_err
= serious_error
= 0;
1869 fdblocks
= frextents
= icount
= ifree
= 0;
1870 sbversion
= XFS_SB_VERSION_4
;
1872 * Note that inoalignmt == 0 is valid when fsb size is large enough for
1873 * at least one full inode record per block. Check this case explicitly.
1875 if (mp
->m_sb
.sb_inoalignmt
||
1876 (xfs_sb_version_hasalign(&mp
->m_sb
) &&
1877 mp
->m_sb
.sb_inopblock
>= XFS_INODES_PER_CHUNK
))
1878 sbversion
|= XFS_SB_VERSION_ALIGNBIT
;
1879 if ((mp
->m_sb
.sb_uquotino
&& mp
->m_sb
.sb_uquotino
!= NULLFSINO
) ||
1880 (mp
->m_sb
.sb_gquotino
&& mp
->m_sb
.sb_gquotino
!= NULLFSINO
) ||
1881 (mp
->m_sb
.sb_pquotino
&& mp
->m_sb
.sb_pquotino
!= NULLFSINO
))
1882 sbversion
|= XFS_SB_VERSION_QUOTABIT
;
1896 id
= find_inode(ino
, 0);
1901 if (id
->name
== NULL
)
1903 path
= xstrdup(id
->name
);
1904 while (id
->parent
) {
1906 if (id
->name
== NULL
)
1908 npath
= prepend_path(path
, id
->name
);
1920 xfs_agnumber_t agno
;
1933 if (!inodata
|| !nflag
) {
1934 dbprintf(_("must run blockget -n first\n"));
1937 security
= optind
= ilist_size
= 0;
1939 while ((c
= getopt(argc
, argv
, "i:s")) != EOF
) {
1942 ino
= strtoll(optarg
, NULL
, 10);
1943 ilist
= xrealloc(ilist
, (ilist_size
+ 1) *
1945 ilist
[ilist_size
++] = ino
;
1951 dbprintf(_("bad option -%c for ncheck command\n"), c
);
1957 for (ilp
= ilist
; ilp
< &ilist
[ilist_size
]; ilp
++) {
1959 if ((p
= inode_name(ino
, &hp
))) {
1960 dbprintf("%11llu %s", ino
, p
);
1970 for (agno
= 0; agno
< mp
->m_sb
.sb_agcount
; agno
++) {
1972 for (i
= 0; i
< inodata_hash_size
; i
++) {
1974 for (hp
= ht
[i
]; hp
; hp
= hp
->next
) {
1975 ino
= XFS_AGINO_TO_INO(mp
, agno
, hp
->ino
);
1976 p
= inode_name(ino
, &id
);
1979 if (!security
|| id
->security
) {
1980 dbprintf("%11llu %s", ino
, p
);
2000 len
= (int)(strlen(oldpath
) + strlen(parent
) + 2);
2001 path
= xmalloc(len
);
2002 snprintf(path
, len
, "%s/%s", parent
, oldpath
);
2007 process_block_dir_v2(
2021 nex
= blkmap_getn(blkmap
, 0, mp
->m_dir_geo
->fsbcount
, &bmp
);
2022 v
= id
->ilist
|| verbose
;
2025 dbprintf(_("block 0 for directory inode %lld is "
2033 make_bbmap(&bbmap
, nex
, bmp
);
2034 set_cur(&typtab
[TYP_DIR2
], XFS_FSB_TO_DADDR(mp
, bmp
->startblock
),
2035 mp
->m_dir_geo
->fsbcount
* blkbb
, DB_RING_IGN
, nex
> 1 ? &bbmap
: NULL
);
2036 for (x
= 0; !v
&& x
< nex
; x
++) {
2037 for (b
= bmp
[x
].startblock
;
2038 !v
&& b
< bmp
[x
].startblock
+ bmp
[x
].blockcount
;
2043 if (iocur_top
->data
== NULL
) {
2044 if (!sflag
|| id
->ilist
|| v
)
2045 dbprintf(_("can't read block 0 for directory inode "
2053 parent
= process_data_dir_v2(dot
, dotdot
, id
, v
, mp
->m_dir_geo
->datablk
,
2055 dir_hash_check(id
, v
);
2062 process_bmbt_reclist(
2067 xfs_rfsblock_t
*tot
,
2070 xfs_agblock_t agbno
;
2071 xfs_agnumber_t agno
;
2077 xfs_agblock_t iagbno
;
2078 xfs_agnumber_t iagno
;
2085 v
= verbose
|| id
->ilist
;
2086 iagno
= XFS_INO_TO_AGNO(mp
, id
->ino
);
2087 iagbno
= XFS_INO_TO_AGBNO(mp
, id
->ino
);
2088 for (i
= 0; i
< numrecs
; i
++, rp
++) {
2089 convert_extent(rp
, &o
, &s
, &c
, &f
);
2091 dbprintf(_("inode %lld extent [%lld,%lld,%lld,%d]\n"),
2092 id
->ino
, o
, s
, c
, f
);
2093 if (!sflag
&& i
> 0 && op
+ cp
> o
)
2094 dbprintf(_("bmap rec out of order, inode %lld entry %d\n"),
2098 if (type
== DBM_RTDATA
) {
2099 if (!sflag
&& s
>= mp
->m_sb
.sb_rblocks
) {
2100 dbprintf(_("inode %lld bad rt block number %lld, "
2105 } else if (!sflag
) {
2106 agno
= XFS_FSB_TO_AGNO(mp
, s
);
2107 agbno
= XFS_FSB_TO_AGBNO(mp
, s
);
2108 if (agno
>= mp
->m_sb
.sb_agcount
||
2109 agbno
>= mp
->m_sb
.sb_agblocks
) {
2110 dbprintf(_("inode %lld bad block number %lld "
2111 "[%d,%d], offset %lld\n"),
2112 id
->ino
, s
, agno
, agbno
, o
);
2115 if (agbno
+ c
- 1 >= mp
->m_sb
.sb_agblocks
) {
2116 dbprintf(_("inode %lld bad block number %lld "
2117 "[%d,%d], offset %lld\n"),
2118 id
->ino
, s
+ c
- 1, agno
,
2119 agbno
+ (xfs_agblock_t
)c
- 1, o
);
2123 if (blkmapp
&& *blkmapp
)
2124 blkmap_set_ext(blkmapp
, (xfs_fileoff_t
)o
,
2125 (xfs_fsblock_t
)s
, (xfs_extlen_t
)c
);
2126 if (type
== DBM_RTDATA
) {
2127 set_rdbmap((xfs_fsblock_t
)s
, (xfs_extlen_t
)c
,
2129 set_rinomap((xfs_fsblock_t
)s
, (xfs_extlen_t
)c
, id
);
2130 for (b
= (xfs_fsblock_t
)s
;
2131 blist_size
&& b
< s
+ c
;
2134 dbprintf(_("inode %lld block %lld at "
2136 id
->ino
, (xfs_fsblock_t
)b
, o
);
2139 agno
= XFS_FSB_TO_AGNO(mp
, (xfs_fsblock_t
)s
);
2140 agbno
= XFS_FSB_TO_AGBNO(mp
, (xfs_fsblock_t
)s
);
2141 set_dbmap(agno
, agbno
, (xfs_extlen_t
)c
, type
, iagno
,
2143 set_inomap(agno
, agbno
, (xfs_extlen_t
)c
, id
);
2144 for (b
= (xfs_fsblock_t
)s
;
2145 blist_size
&& b
< s
+ c
;
2146 b
++, o
++, agbno
++) {
2148 dbprintf(_("inode %lld block %lld at "
2150 id
->ino
, (xfs_fsblock_t
)b
, o
);
2162 xfs_rfsblock_t
*totd
,
2163 xfs_rfsblock_t
*toti
,
2168 xfs_bmdr_block_t
*dib
;
2172 dib
= (xfs_bmdr_block_t
*)XFS_DFORK_PTR(dip
, whichfork
);
2173 if (be16_to_cpu(dib
->bb_level
) >= XFS_BM_MAXLEVELS(mp
, whichfork
)) {
2174 if (!sflag
|| id
->ilist
)
2175 dbprintf(_("level for ino %lld %s fork bmap root too "
2178 whichfork
== XFS_DATA_FORK
? _("data") : _("attr"),
2179 be16_to_cpu(dib
->bb_level
));
2183 if (be16_to_cpu(dib
->bb_numrecs
) >
2184 xfs_bmdr_maxrecs(XFS_DFORK_SIZE(dip
, mp
, whichfork
),
2185 be16_to_cpu(dib
->bb_level
) == 0)) {
2186 if (!sflag
|| id
->ilist
)
2187 dbprintf(_("numrecs for ino %lld %s fork bmap root too "
2190 whichfork
== XFS_DATA_FORK
? _("data") : _("attr"),
2191 be16_to_cpu(dib
->bb_numrecs
));
2195 if (be16_to_cpu(dib
->bb_level
) == 0) {
2196 xfs_bmbt_rec_t
*rp
= XFS_BMDR_REC_ADDR(dib
, 1);
2197 process_bmbt_reclist(rp
, be16_to_cpu(dib
->bb_numrecs
), type
,
2199 *nex
+= be16_to_cpu(dib
->bb_numrecs
);
2202 pp
= XFS_BMDR_PTR_ADDR(dib
, 1, xfs_bmdr_maxrecs(
2203 XFS_DFORK_SIZE(dip
, mp
, whichfork
), 0));
2204 for (i
= 0; i
< be16_to_cpu(dib
->bb_numrecs
); i
++)
2205 scan_lbtree(get_unaligned_be64(&pp
[i
]),
2206 be16_to_cpu(dib
->bb_level
),
2207 scanfunc_bmap
, type
, id
, totd
, toti
,
2209 whichfork
== XFS_DATA_FORK
?
2210 TYP_BMAPBTD
: TYP_BMAPBTA
);
2212 if (*nex
<= XFS_DFORK_SIZE(dip
, mp
, whichfork
) / sizeof(xfs_bmbt_rec_t
)) {
2213 if (!sflag
|| id
->ilist
)
2214 dbprintf(_("extent count for ino %lld %s fork too low "
2215 "(%d) for file format\n"),
2217 whichfork
== XFS_DATA_FORK
? _("data") : _("attr"),
2224 process_data_dir_v2(
2230 freetab_t
**freetabp
)
2232 xfs_dir2_dataptr_t addr
;
2233 xfs_dir2_data_free_t
*bf
;
2235 struct xfs_dir2_data_hdr
*block
;
2236 xfs_dir2_block_tail_t
*btp
= NULL
;
2239 struct xfs_dir2_data_hdr
*data
;
2241 xfs_dir2_data_entry_t
*dep
;
2242 xfs_dir2_data_free_t
*dfp
;
2243 xfs_dir2_data_unused_t
*dup
;
2250 xfs_dir2_leaf_entry_t
*lep
= NULL
;
2252 xfs_ino_t parent
= 0;
2257 struct xfs_name xname
;
2259 data
= iocur_top
->data
;
2260 block
= iocur_top
->data
;
2261 if (be32_to_cpu(block
->magic
) != XFS_DIR2_BLOCK_MAGIC
&&
2262 be32_to_cpu(data
->magic
) != XFS_DIR2_DATA_MAGIC
&&
2263 be32_to_cpu(block
->magic
) != XFS_DIR3_BLOCK_MAGIC
&&
2264 be32_to_cpu(data
->magic
) != XFS_DIR3_DATA_MAGIC
) {
2266 dbprintf(_("bad directory data magic # %#x for dir ino "
2268 be32_to_cpu(data
->magic
), id
->ino
, dabno
);
2272 db
= xfs_dir2_da_to_db(mp
->m_dir_geo
, dabno
);
2273 bf
= M_DIROPS(mp
)->data_bestfree_p(data
);
2274 ptr
= (char *)M_DIROPS(mp
)->data_unused_p(data
);
2275 if (be32_to_cpu(block
->magic
) == XFS_DIR2_BLOCK_MAGIC
||
2276 be32_to_cpu(block
->magic
) == XFS_DIR3_BLOCK_MAGIC
) {
2277 btp
= xfs_dir2_block_tail_p(mp
->m_dir_geo
, block
);
2278 lep
= xfs_dir2_block_leaf_p(btp
);
2279 endptr
= (char *)lep
;
2280 if (endptr
<= ptr
|| endptr
> (char *)btp
) {
2281 endptr
= (char *)data
+ mp
->m_dir_geo
->blksize
;
2284 dbprintf(_("bad block directory tail for dir ino "
2290 endptr
= (char *)data
+ mp
->m_dir_geo
->blksize
;
2291 bf_err
= lastfree_err
= tag_err
= 0;
2292 count
= lastfree
= freeseen
= 0;
2293 if (be16_to_cpu(bf
[0].length
) == 0) {
2294 bf_err
+= be16_to_cpu(bf
[0].offset
) != 0;
2297 if (be16_to_cpu(bf
[1].length
) == 0) {
2298 bf_err
+= be16_to_cpu(bf
[1].offset
) != 0;
2301 if (be16_to_cpu(bf
[2].length
) == 0) {
2302 bf_err
+= be16_to_cpu(bf
[2].offset
) != 0;
2305 bf_err
+= be16_to_cpu(bf
[0].length
) < be16_to_cpu(bf
[1].length
);
2306 bf_err
+= be16_to_cpu(bf
[1].length
) < be16_to_cpu(bf
[2].length
);
2308 freetab
= *freetabp
;
2309 if (freetab
->naents
<= db
) {
2310 *freetabp
= freetab
=
2311 realloc(freetab
, FREETAB_SIZE(db
+ 1));
2312 for (i
= freetab
->naents
; i
< db
; i
++)
2313 freetab
->ents
[i
] = NULLDATAOFF
;
2314 freetab
->naents
= db
+ 1;
2316 if (freetab
->nents
< db
+ 1)
2317 freetab
->nents
= db
+ 1;
2318 freetab
->ents
[db
] = be16_to_cpu(bf
[0].length
);
2320 while (ptr
< endptr
) {
2321 dup
= (xfs_dir2_data_unused_t
*)ptr
;
2322 if (be16_to_cpu(dup
->freetag
) == XFS_DIR2_DATA_FREE_TAG
) {
2323 lastfree_err
+= lastfree
!= 0;
2324 tagp
= xfs_dir2_data_unused_tag_p(dup
);
2325 if ((be16_to_cpu(dup
->length
) & (XFS_DIR2_DATA_ALIGN
- 1)) ||
2326 be16_to_cpu(dup
->length
) == 0 ||
2327 (char *)tagp
>= endptr
) {
2329 dbprintf(_("dir %lld block %d bad free "
2337 tag_err
+= be16_to_cpu(*tagp
) != (char *)dup
- (char *)data
;
2338 dfp
= process_data_dir_v2_freefind(data
, dup
);
2340 i
= (int)(dfp
- bf
);
2341 bf_err
+= (freeseen
& (1 << i
)) != 0;
2344 bf_err
+= be16_to_cpu(dup
->length
) >
2345 be16_to_cpu(bf
[2].length
);
2346 ptr
+= be16_to_cpu(dup
->length
);
2350 dep
= (xfs_dir2_data_entry_t
*)dup
;
2351 if (dep
->namelen
== 0) {
2353 dbprintf(_("dir %lld block %d zero length entry "
2356 (int)((char *)dep
- (char *)data
));
2359 tagp
= M_DIROPS(mp
)->data_entry_tag_p(dep
);
2360 if ((char *)tagp
>= endptr
) {
2362 dbprintf(_("dir %lld block %d bad entry at %d\n"),
2364 (int)((char *)dep
- (char *)data
));
2368 tag_err
+= be16_to_cpu(*tagp
) != (char *)dep
- (char *)data
;
2369 addr
= xfs_dir2_db_off_to_dataptr(mp
->m_dir_geo
, db
,
2370 (char *)dep
- (char *)data
);
2371 xname
.name
= dep
->name
;
2372 xname
.len
= dep
->namelen
;
2373 dir_hash_add(mp
->m_dirnameops
->hashname(&xname
), addr
);
2374 ptr
+= M_DIROPS(mp
)->data_entsize(dep
->namelen
);
2377 lino
= be64_to_cpu(dep
->inumber
);
2378 cid
= find_inode(lino
, 1);
2380 dbprintf(_("dir %lld block %d entry %*.*s %lld\n"),
2381 id
->ino
, dabno
, dep
->namelen
, dep
->namelen
,
2387 dbprintf(_("dir %lld block %d entry %*.*s bad "
2388 "inode number %lld\n"),
2389 id
->ino
, dabno
, dep
->namelen
,
2390 dep
->namelen
, dep
->name
, lino
);
2393 if (dep
->namelen
== 2 && dep
->name
[0] == '.' &&
2394 dep
->name
[1] == '.') {
2397 dbprintf(_("multiple .. entries in dir "
2398 "%lld (%lld, %lld)\n"),
2399 id
->ino
, parent
, lino
);
2402 parent
= cid
? lino
: NULLFSINO
;
2404 } else if (dep
->namelen
!= 1 || dep
->name
[0] != '.') {
2408 addname_inode(cid
, (char *)dep
->name
,
2412 if (lino
!= id
->ino
) {
2414 dbprintf(_("dir %lld entry . inode "
2415 "number mismatch (%lld)\n"),
2422 if (be32_to_cpu(data
->magic
) == XFS_DIR2_BLOCK_MAGIC
||
2423 be32_to_cpu(data
->magic
) == XFS_DIR3_BLOCK_MAGIC
) {
2424 endptr
= (char *)data
+ mp
->m_dir_geo
->blksize
;
2425 for (i
= stale
= 0; lep
&& i
< be32_to_cpu(btp
->count
); i
++) {
2426 if ((char *)&lep
[i
] >= endptr
) {
2428 dbprintf(_("dir %lld block %d bad count "
2429 "%u\n"), id
->ino
, dabno
,
2430 be32_to_cpu(btp
->count
));
2434 if (be32_to_cpu(lep
[i
].address
) == XFS_DIR2_NULL_DATAPTR
)
2436 else if (dir_hash_see(be32_to_cpu(lep
[i
].hashval
),
2437 be32_to_cpu(lep
[i
].address
))) {
2439 dbprintf(_("dir %lld block %d extra leaf "
2442 be32_to_cpu(lep
[i
].hashval
),
2443 be32_to_cpu(lep
[i
].address
));
2448 bf_err
+= freeseen
!= 7;
2451 dbprintf(_("dir %lld block %d bad bestfree data\n"),
2455 if ((be32_to_cpu(data
->magic
) == XFS_DIR2_BLOCK_MAGIC
||
2456 be32_to_cpu(data
->magic
) == XFS_DIR3_BLOCK_MAGIC
) &&
2457 count
!= be32_to_cpu(btp
->count
) - be32_to_cpu(btp
->stale
)) {
2459 dbprintf(_("dir %lld block %d bad block tail count %d "
2461 id
->ino
, dabno
, be32_to_cpu(btp
->count
),
2462 be32_to_cpu(btp
->stale
));
2465 if ((be32_to_cpu(data
->magic
) == XFS_DIR2_BLOCK_MAGIC
||
2466 be32_to_cpu(data
->magic
) == XFS_DIR2_BLOCK_MAGIC
) &&
2467 stale
!= be32_to_cpu(btp
->stale
)) {
2469 dbprintf(_("dir %lld block %d bad stale tail count %d\n"),
2470 id
->ino
, dabno
, be32_to_cpu(btp
->stale
));
2475 dbprintf(_("dir %lld block %d consecutive free entries\n"),
2481 dbprintf(_("dir %lld block %d entry/unused tag "
2489 static xfs_dir2_data_free_t
*
2490 process_data_dir_v2_freefind(
2491 struct xfs_dir2_data_hdr
*data
,
2492 xfs_dir2_data_unused_t
*dup
)
2494 struct xfs_dir2_data_free
*bf
;
2495 struct xfs_dir2_data_free
*dfp
;
2496 xfs_dir2_data_aoff_t off
;
2498 off
= (xfs_dir2_data_aoff_t
)((char *)dup
- (char *)data
);
2499 bf
= M_DIROPS(mp
)->data_bestfree_p(data
);
2500 if (be16_to_cpu(dup
->length
) <
2501 be16_to_cpu(bf
[XFS_DIR2_DATA_FD_COUNT
- 1].length
))
2503 for (dfp
= bf
; dfp
< &bf
[XFS_DIR2_DATA_FD_COUNT
]; dfp
++) {
2504 if (be16_to_cpu(dfp
->offset
) == 0)
2506 if (be16_to_cpu(dfp
->offset
) == off
)
2524 if (process_dir_v2(dip
, blkmap
, &dot
, &dotdot
, id
, &parent
))
2527 bno
= XFS_INO_TO_FSB(mp
, id
->ino
);
2529 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
2530 dbprintf(_("no . entry for directory %lld\n"), id
->ino
);
2534 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
2535 dbprintf(_("no .. entry for directory %lld\n"), id
->ino
);
2537 } else if (parent
== id
->ino
&& id
->ino
!= mp
->m_sb
.sb_rootino
) {
2538 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
2539 dbprintf(_(". and .. same for non-root directory %lld\n"),
2542 } else if (id
->ino
== mp
->m_sb
.sb_rootino
&& id
->ino
!= parent
) {
2543 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
2544 dbprintf(_("root directory %lld has .. %lld\n"), id
->ino
,
2547 } else if (parent
!= NULLFSINO
&& id
->ino
!= parent
)
2548 addparent_inode(id
, parent
);
2560 xfs_fileoff_t last
= 0;
2561 xfs_fsize_t size
= be64_to_cpu(dip
->di_size
);
2564 last
= blkmap_last_off(blkmap
);
2565 if (size
<= XFS_DFORK_DSIZE(dip
, mp
) &&
2566 dip
->di_format
== XFS_DINODE_FMT_LOCAL
)
2567 *parent
= process_sf_dir_v2(dip
, dot
, dotdot
, id
);
2568 else if (last
== mp
->m_dir_geo
->fsbcount
&&
2569 (dip
->di_format
== XFS_DINODE_FMT_EXTENTS
||
2570 dip
->di_format
== XFS_DINODE_FMT_BTREE
))
2571 *parent
= process_block_dir_v2(blkmap
, dot
, dotdot
, id
);
2572 else if (last
>= mp
->m_dir_geo
->leafblk
+ mp
->m_dir_geo
->fsbcount
&&
2573 (dip
->di_format
== XFS_DINODE_FMT_EXTENTS
||
2574 dip
->di_format
== XFS_DINODE_FMT_BTREE
))
2575 *parent
= process_leaf_node_dir_v2(blkmap
, dot
, dotdot
, id
, size
);
2577 dbprintf(_("bad size (%lld) or format (%d) for directory inode "
2579 size
, dip
->di_format
, id
->ino
);
2592 xfs_rfsblock_t
*totd
,
2593 xfs_rfsblock_t
*toti
,
2600 rp
= (xfs_bmbt_rec_t
*)XFS_DFORK_PTR(dip
, whichfork
);
2601 *nex
= XFS_DFORK_NEXTENTS(dip
, whichfork
);
2602 if (*nex
< 0 || *nex
> XFS_DFORK_SIZE(dip
, mp
, whichfork
) /
2603 sizeof(xfs_bmbt_rec_t
)) {
2604 if (!sflag
|| id
->ilist
)
2605 dbprintf(_("bad number of extents %d for inode %lld\n"),
2610 process_bmbt_reclist(rp
, *nex
, type
, id
, totd
, blkmapp
);
2621 xfs_fsblock_t bno
= 0;
2622 struct xfs_inode xino
;
2623 inodata_t
*id
= NULL
;
2625 xfs_extnum_t nextents
= 0;
2627 xfs_rfsblock_t totblocks
;
2628 xfs_rfsblock_t totdblocks
= 0;
2629 xfs_rfsblock_t totiblocks
= 0;
2631 xfs_extnum_t anextents
= 0;
2632 xfs_rfsblock_t atotdblocks
= 0;
2633 xfs_rfsblock_t atotiblocks
= 0;
2640 static char okfmts
[] = {
2641 0, /* type 0 unused */
2642 1 << XFS_DINODE_FMT_DEV
, /* FIFO */
2643 1 << XFS_DINODE_FMT_DEV
, /* CHR */
2644 0, /* type 3 unused */
2645 (1 << XFS_DINODE_FMT_LOCAL
) |
2646 (1 << XFS_DINODE_FMT_EXTENTS
) |
2647 (1 << XFS_DINODE_FMT_BTREE
), /* DIR */
2648 0, /* type 5 unused */
2649 1 << XFS_DINODE_FMT_DEV
, /* BLK */
2650 0, /* type 7 unused */
2651 (1 << XFS_DINODE_FMT_EXTENTS
) |
2652 (1 << XFS_DINODE_FMT_BTREE
), /* REG */
2653 0, /* type 9 unused */
2654 (1 << XFS_DINODE_FMT_LOCAL
) |
2655 (1 << XFS_DINODE_FMT_EXTENTS
), /* LNK */
2656 0, /* type 11 unused */
2657 1 << XFS_DINODE_FMT_DEV
, /* SOCK */
2658 0, /* type 13 unused */
2659 1 << XFS_DINODE_FMT_UUID
, /* MNT */
2660 0 /* type 15 unused */
2662 static char *fmtnames
[] = {
2663 "dev", "local", "extents", "btree", "uuid"
2666 libxfs_inode_from_disk(&xino
, dip
);
2668 ino
= XFS_AGINO_TO_INO(mp
, be32_to_cpu(agf
->agf_seqno
), agino
);
2670 id
= find_inode(ino
, 1);
2671 bno
= XFS_INO_TO_FSB(mp
, ino
);
2674 v
= (!sflag
|| (id
&& id
->ilist
) || CHECK_BLIST(bno
));
2675 if (dip
->di_magic
!= cpu_to_be16(XFS_DINODE_MAGIC
)) {
2677 dbprintf(_("bad magic number %#x for inode %lld\n"),
2678 be16_to_cpu(dip
->di_magic
), ino
);
2682 if (!xfs_dinode_good_version(mp
, xino
.i_d
.di_version
)) {
2684 dbprintf(_("bad version number %#x for inode %lld\n"),
2685 xino
.i_d
.di_version
, ino
);
2690 if (xino
.i_d
.di_nblocks
!= 0) {
2692 dbprintf(_("bad nblocks %lld for free inode "
2694 xino
.i_d
.di_nblocks
, ino
);
2697 if (dip
->di_nlink
!= 0) {
2699 dbprintf(_("bad nlink %d for free inode %lld\n"),
2700 be32_to_cpu(dip
->di_nlink
), ino
);
2703 if (dip
->di_mode
!= 0) {
2705 dbprintf(_("bad mode %#o for free inode %lld\n"),
2706 be16_to_cpu(dip
->di_mode
), ino
);
2712 if (be32_to_cpu(dip
->di_next_unlinked
) != NULLAGINO
) {
2714 dbprintf(_("bad next unlinked %#x for inode %lld\n"),
2715 be32_to_cpu(dip
->di_next_unlinked
), ino
);
2719 * di_mode is a 16-bit uint so no need to check the < 0 case
2721 mode
= be16_to_cpu(dip
->di_mode
);
2722 if ((((mode
& S_IFMT
) >> 12) > 15) ||
2723 (!(okfmts
[(mode
& S_IFMT
) >> 12] & (1 << xino
.i_d
.di_format
)))) {
2725 dbprintf(_("bad format %d for inode %lld type %#o\n"),
2726 xino
.i_d
.di_format
, id
->ino
, mode
& S_IFMT
);
2730 if ((unsigned int)XFS_DFORK_ASIZE(dip
, mp
) >=
2731 XFS_LITINO(mp
, xino
.i_d
.di_version
)) {
2733 dbprintf(_("bad fork offset %d for inode %lld\n"),
2734 xino
.i_d
.di_forkoff
, id
->ino
);
2738 if ((unsigned int)xino
.i_d
.di_aformat
> XFS_DINODE_FMT_BTREE
) {
2740 dbprintf(_("bad attribute format %d for inode %lld\n"),
2741 xino
.i_d
.di_aformat
, id
->ino
);
2745 if (verbose
|| (id
&& id
->ilist
) || CHECK_BLIST(bno
))
2746 dbprintf(_("inode %lld mode %#o fmt %s "
2748 "nex %d anex %d nblk %lld sz %lld%s%s%s%s%s%s%s\n"),
2749 id
->ino
, mode
, fmtnames
[(int)xino
.i_d
.di_format
],
2750 fmtnames
[(int)xino
.i_d
.di_aformat
],
2751 xino
.i_d
.di_nextents
,
2752 xino
.i_d
.di_anextents
,
2753 xino
.i_d
.di_nblocks
, xino
.i_d
.di_size
,
2754 xino
.i_d
.di_flags
& XFS_DIFLAG_REALTIME
? " rt" : "",
2755 xino
.i_d
.di_flags
& XFS_DIFLAG_PREALLOC
? " pre" : "",
2756 xino
.i_d
.di_flags
& XFS_DIFLAG_IMMUTABLE
? " imm" : "",
2757 xino
.i_d
.di_flags
& XFS_DIFLAG_APPEND
? " app" : "",
2758 xino
.i_d
.di_flags
& XFS_DIFLAG_SYNC
? " syn" : "",
2759 xino
.i_d
.di_flags
& XFS_DIFLAG_NOATIME
? " noa" : "",
2760 xino
.i_d
.di_flags
& XFS_DIFLAG_NODUMP
? " nod" : "");
2762 switch (mode
& S_IFMT
) {
2765 if (xino
.i_d
.di_format
== XFS_DINODE_FMT_LOCAL
)
2767 blkmap
= blkmap_alloc(xino
.i_d
.di_nextents
);
2770 if (xino
.i_d
.di_flags
& XFS_DIFLAG_REALTIME
)
2772 else if (id
->ino
== mp
->m_sb
.sb_rbmino
) {
2773 type
= DBM_RTBITMAP
;
2774 blkmap
= blkmap_alloc(xino
.i_d
.di_nextents
);
2776 } else if (id
->ino
== mp
->m_sb
.sb_rsumino
) {
2778 blkmap
= blkmap_alloc(xino
.i_d
.di_nextents
);
2781 else if (id
->ino
== mp
->m_sb
.sb_uquotino
||
2782 id
->ino
== mp
->m_sb
.sb_gquotino
||
2783 id
->ino
== mp
->m_sb
.sb_pquotino
) {
2785 blkmap
= blkmap_alloc(xino
.i_d
.di_nextents
);
2790 if (mode
& (S_ISUID
| S_ISGID
))
2802 setlink_inode(id
, VFS_I(&xino
)->i_nlink
, type
== DBM_DIR
, security
);
2804 switch (xino
.i_d
.di_format
) {
2805 case XFS_DINODE_FMT_LOCAL
:
2806 process_lclinode(id
, dip
, type
, &totdblocks
, &totiblocks
,
2807 &nextents
, &blkmap
, XFS_DATA_FORK
);
2809 case XFS_DINODE_FMT_EXTENTS
:
2810 process_exinode(id
, dip
, type
, &totdblocks
, &totiblocks
,
2811 &nextents
, &blkmap
, XFS_DATA_FORK
);
2813 case XFS_DINODE_FMT_BTREE
:
2814 process_btinode(id
, dip
, type
, &totdblocks
, &totiblocks
,
2815 &nextents
, &blkmap
, XFS_DATA_FORK
);
2818 if (XFS_DFORK_Q(dip
)) {
2819 sbversion
|= XFS_SB_VERSION_ATTRBIT
;
2820 switch (xino
.i_d
.di_aformat
) {
2821 case XFS_DINODE_FMT_LOCAL
:
2822 process_lclinode(id
, dip
, DBM_ATTR
, &atotdblocks
,
2823 &atotiblocks
, &anextents
, NULL
, XFS_ATTR_FORK
);
2825 case XFS_DINODE_FMT_EXTENTS
:
2826 process_exinode(id
, dip
, DBM_ATTR
, &atotdblocks
,
2827 &atotiblocks
, &anextents
, NULL
, XFS_ATTR_FORK
);
2829 case XFS_DINODE_FMT_BTREE
:
2830 process_btinode(id
, dip
, DBM_ATTR
, &atotdblocks
,
2831 &atotiblocks
, &anextents
, NULL
, XFS_ATTR_FORK
);
2835 if (qgdo
|| qpdo
|| qudo
) {
2843 bc
= totdblocks
+ totiblocks
+
2844 atotdblocks
+ atotiblocks
;
2848 bc
= totiblocks
+ atotdblocks
+ atotiblocks
;
2856 dqprid
= xfs_get_projid(&xino
.i_d
); /* dquot ID is u32 */
2857 quota_add(&dqprid
, &xino
.i_d
.di_gid
, &xino
.i_d
.di_uid
,
2861 totblocks
= totdblocks
+ totiblocks
+ atotdblocks
+ atotiblocks
;
2862 if (totblocks
!= xino
.i_d
.di_nblocks
) {
2864 dbprintf(_("bad nblocks %lld for inode %lld, counted "
2866 xino
.i_d
.di_nblocks
, id
->ino
, totblocks
);
2869 if (nextents
!= xino
.i_d
.di_nextents
) {
2871 dbprintf(_("bad nextents %d for inode %lld, counted %d\n"),
2872 xino
.i_d
.di_nextents
, id
->ino
, nextents
);
2875 if (anextents
!= xino
.i_d
.di_anextents
) {
2877 dbprintf(_("bad anextents %d for inode %lld, counted "
2879 xino
.i_d
.di_anextents
, id
->ino
, anextents
);
2882 if (type
== DBM_DIR
)
2883 process_dir(dip
, blkmap
, id
);
2884 else if (type
== DBM_RTBITMAP
)
2885 process_rtbitmap(blkmap
);
2886 else if (type
== DBM_RTSUM
)
2887 process_rtsummary(blkmap
);
2889 * If the CHKD flag is not set, this can legitimately contain garbage;
2890 * xfs_repair may have cleared that bit.
2892 else if (type
== DBM_QUOTA
) {
2893 if (id
->ino
== mp
->m_sb
.sb_uquotino
&&
2894 (mp
->m_sb
.sb_qflags
& XFS_UQUOTA_ACCT
) &&
2895 (mp
->m_sb
.sb_qflags
& XFS_UQUOTA_CHKD
))
2896 process_quota(IS_USER_QUOTA
, id
, blkmap
);
2897 else if (id
->ino
== mp
->m_sb
.sb_gquotino
&&
2898 (mp
->m_sb
.sb_qflags
& XFS_GQUOTA_ACCT
) &&
2899 (mp
->m_sb
.sb_qflags
& XFS_GQUOTA_CHKD
))
2900 process_quota(IS_GROUP_QUOTA
, id
, blkmap
);
2901 else if (id
->ino
== mp
->m_sb
.sb_pquotino
&&
2902 (mp
->m_sb
.sb_qflags
& XFS_PQUOTA_ACCT
) &&
2903 (mp
->m_sb
.sb_qflags
& XFS_PQUOTA_CHKD
))
2904 process_quota(IS_PROJECT_QUOTA
, id
, blkmap
);
2907 blkmap_free(blkmap
);
2916 xfs_rfsblock_t
*totd
,
2917 xfs_rfsblock_t
*toti
,
2922 xfs_attr_shortform_t
*asf
;
2925 bno
= XFS_INO_TO_FSB(mp
, id
->ino
);
2926 if (whichfork
== XFS_DATA_FORK
&& be64_to_cpu(dip
->di_size
) >
2927 XFS_DFORK_DSIZE(dip
, mp
)) {
2928 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
2929 dbprintf(_("local inode %lld data is too large (size "
2931 id
->ino
, be64_to_cpu(dip
->di_size
));
2934 else if (whichfork
== XFS_ATTR_FORK
) {
2935 asf
= (xfs_attr_shortform_t
*)XFS_DFORK_APTR(dip
);
2936 if (be16_to_cpu(asf
->hdr
.totsize
) > XFS_DFORK_ASIZE(dip
, mp
)) {
2937 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
2938 dbprintf(_("local inode %lld attr is too large "
2940 id
->ino
, be16_to_cpu(asf
->hdr
.totsize
));
2947 process_leaf_node_dir_v2(
2952 xfs_fsize_t dirsize
)
2968 v2
= verbose
|| id
->ilist
;
2971 freetab
= malloc(FREETAB_SIZE(dirsize
/ mp
->m_dir_geo
->blksize
));
2972 freetab
->naents
= (int)(dirsize
/ mp
->m_dir_geo
->blksize
);
2974 for (i
= 0; i
< freetab
->naents
; i
++)
2975 freetab
->ents
[i
] = NULLDATAOFF
;
2977 while ((dbno
= blkmap_next_off(blkmap
, dbno
, &t
)) != NULLFILEOFF
) {
2978 nex
= blkmap_getn(blkmap
, dbno
, mp
->m_dir_geo
->fsbcount
, &bmp
);
2980 for (v
= v2
, x
= 0; !v
&& x
< nex
; x
++) {
2981 for (b
= bmp
[x
].startblock
;
2982 !v
&& b
< bmp
[x
].startblock
+ bmp
[x
].blockcount
;
2987 dbprintf(_("dir inode %lld block %u=%llu\n"), id
->ino
,
2989 (xfs_fsblock_t
)bmp
->startblock
);
2992 make_bbmap(&bbmap
, nex
, bmp
);
2993 set_cur(&typtab
[TYP_DIR2
], XFS_FSB_TO_DADDR(mp
, bmp
->startblock
),
2994 mp
->m_dir_geo
->fsbcount
* blkbb
, DB_RING_IGN
,
2995 nex
> 1 ? &bbmap
: NULL
);
2997 if (iocur_top
->data
== NULL
) {
2999 dbprintf(_("can't read block %u for directory "
3001 (__uint32_t
)dbno
, id
->ino
);
3004 dbno
+= mp
->m_dir_geo
->fsbcount
- 1;
3007 if (dbno
< mp
->m_dir_geo
->leafblk
) {
3008 lino
= process_data_dir_v2(dot
, dotdot
, id
, v
,
3009 (xfs_dablk_t
)dbno
, &freetab
);
3013 dbprintf(_("multiple .. entries "
3020 } else if (dbno
< mp
->m_dir_geo
->freeblk
) {
3021 process_leaf_node_dir_v2_int(id
, v
, (xfs_dablk_t
)dbno
,
3024 process_leaf_node_dir_v2_free(id
, v
, (xfs_dablk_t
)dbno
,
3028 dbno
+= mp
->m_dir_geo
->fsbcount
- 1;
3030 dir_hash_check(id
, v
);
3032 for (i
= 0; i
< freetab
->nents
; i
++) {
3033 if (freetab
->ents
[i
] != NULLDATAOFF
) {
3035 dbprintf(_("missing free index for data block %d "
3036 "in dir ino %lld\n"),
3037 xfs_dir2_db_to_da(mp
->m_dir_geo
, i
), id
->ino
);
3046 process_leaf_node_dir_v3_free(
3052 xfs_dir2_data_off_t ent
;
3053 struct xfs_dir3_free
*free
;
3058 free
= iocur_top
->data
;
3059 maxent
= M_DIROPS(mp
)->free_max_bests(mp
->m_dir_geo
);
3060 if (be32_to_cpu(free
->hdr
.firstdb
) != xfs_dir2_da_to_db(mp
->m_dir_geo
,
3061 dabno
- mp
->m_dir_geo
->freeblk
) * maxent
) {
3063 dbprintf(_("bad free block firstdb %d for dir ino %lld "
3065 be32_to_cpu(free
->hdr
.firstdb
), id
->ino
, dabno
);
3069 if (be32_to_cpu(free
->hdr
.nvalid
) > maxent
||
3070 be32_to_cpu(free
->hdr
.nused
) > maxent
||
3071 be32_to_cpu(free
->hdr
.nused
) >
3072 be32_to_cpu(free
->hdr
.nvalid
)) {
3074 dbprintf(_("bad free block nvalid/nused %d/%d for dir "
3075 "ino %lld block %d\n"),
3076 be32_to_cpu(free
->hdr
.nvalid
),
3077 be32_to_cpu(free
->hdr
.nused
), id
->ino
, dabno
);
3081 for (used
= i
= 0; i
< be32_to_cpu(free
->hdr
.nvalid
); i
++) {
3082 if (freetab
->nents
<= be32_to_cpu(free
->hdr
.firstdb
) + i
)
3085 ent
= freetab
->ents
[be32_to_cpu(free
->hdr
.firstdb
) + i
];
3086 if (ent
!= be16_to_cpu(free
->bests
[i
])) {
3088 dbprintf(_("bad free block ent %d is %d should "
3089 "be %d for dir ino %lld block %d\n"),
3090 i
, be16_to_cpu(free
->bests
[i
]), ent
,
3094 if (be16_to_cpu(free
->bests
[i
]) != NULLDATAOFF
)
3096 if (ent
!= NULLDATAOFF
)
3097 freetab
->ents
[be32_to_cpu(free
->hdr
.firstdb
) + i
] =
3100 if (used
!= be32_to_cpu(free
->hdr
.nused
)) {
3102 dbprintf(_("bad free block nused %d should be %d for dir "
3103 "ino %lld block %d\n"),
3104 be32_to_cpu(free
->hdr
.nused
), used
, id
->ino
,
3111 process_leaf_node_dir_v2_free(
3117 xfs_dir2_data_off_t ent
;
3118 xfs_dir2_free_t
*free
;
3123 free
= iocur_top
->data
;
3124 if (be32_to_cpu(free
->hdr
.magic
) != XFS_DIR2_FREE_MAGIC
&&
3125 be32_to_cpu(free
->hdr
.magic
) != XFS_DIR3_FREE_MAGIC
) {
3127 dbprintf(_("bad free block magic # %#x for dir ino %lld "
3129 be32_to_cpu(free
->hdr
.magic
), id
->ino
, dabno
);
3133 if (be32_to_cpu(free
->hdr
.magic
) == XFS_DIR3_FREE_MAGIC
) {
3134 process_leaf_node_dir_v3_free(id
, v
, dabno
, freetab
);
3137 maxent
= M_DIROPS(mp
)->free_max_bests(mp
->m_dir_geo
);
3138 if (be32_to_cpu(free
->hdr
.firstdb
) != xfs_dir2_da_to_db(mp
->m_dir_geo
,
3139 dabno
- mp
->m_dir_geo
->freeblk
) * maxent
) {
3141 dbprintf(_("bad free block firstdb %d for dir ino %lld "
3143 be32_to_cpu(free
->hdr
.firstdb
), id
->ino
, dabno
);
3147 if (be32_to_cpu(free
->hdr
.nvalid
) > maxent
||
3148 be32_to_cpu(free
->hdr
.nvalid
) < 0 ||
3149 be32_to_cpu(free
->hdr
.nused
) > maxent
||
3150 be32_to_cpu(free
->hdr
.nused
) < 0 ||
3151 be32_to_cpu(free
->hdr
.nused
) >
3152 be32_to_cpu(free
->hdr
.nvalid
)) {
3154 dbprintf(_("bad free block nvalid/nused %d/%d for dir "
3155 "ino %lld block %d\n"),
3156 be32_to_cpu(free
->hdr
.nvalid
),
3157 be32_to_cpu(free
->hdr
.nused
), id
->ino
, dabno
);
3161 for (used
= i
= 0; i
< be32_to_cpu(free
->hdr
.nvalid
); i
++) {
3162 if (freetab
->nents
<= be32_to_cpu(free
->hdr
.firstdb
) + i
)
3165 ent
= freetab
->ents
[be32_to_cpu(free
->hdr
.firstdb
) + i
];
3166 if (ent
!= be16_to_cpu(free
->bests
[i
])) {
3168 dbprintf(_("bad free block ent %d is %d should "
3169 "be %d for dir ino %lld block %d\n"),
3170 i
, be16_to_cpu(free
->bests
[i
]), ent
,
3174 if (be16_to_cpu(free
->bests
[i
]) != NULLDATAOFF
)
3176 if (ent
!= NULLDATAOFF
)
3177 freetab
->ents
[be32_to_cpu(free
->hdr
.firstdb
) + i
] =
3180 if (used
!= be32_to_cpu(free
->hdr
.nused
)) {
3182 dbprintf(_("bad free block nused %d should be %d for dir "
3183 "ino %lld block %d\n"),
3184 be32_to_cpu(free
->hdr
.nused
), used
, id
->ino
,
3191 * Get address of the bestcount field in the single-leaf block.
3194 xfs_dir3_leaf_ents_count(struct xfs_dir2_leaf
*lp
)
3196 if (lp
->hdr
.info
.magic
== cpu_to_be16(XFS_DIR3_LEAF1_MAGIC
) ||
3197 lp
->hdr
.info
.magic
== cpu_to_be16(XFS_DIR3_LEAFN_MAGIC
)) {
3198 struct xfs_dir3_leaf
*lp3
= (struct xfs_dir3_leaf
*)lp
;
3200 return be16_to_cpu(lp3
->hdr
.count
);
3202 return be16_to_cpu(lp
->hdr
.count
);
3206 process_leaf_node_dir_v2_int(
3214 xfs_dir2_leaf_t
*leaf
;
3215 struct xfs_dir3_leaf
*leaf3
= NULL
;
3216 xfs_dir2_leaf_entry_t
*lep
;
3217 xfs_dir2_leaf_tail_t
*ltp
;
3218 xfs_da_intnode_t
*node
;
3220 struct xfs_da3_icnode_hdr nodehdr
;
3222 leaf
= iocur_top
->data
;
3223 switch (be16_to_cpu(leaf
->hdr
.info
.magic
)) {
3224 case XFS_DIR3_LEAF1_MAGIC
:
3225 case XFS_DIR3_LEAFN_MAGIC
:
3226 case XFS_DA3_NODE_MAGIC
:
3227 leaf3
= iocur_top
->data
;
3230 switch (be16_to_cpu(leaf
->hdr
.info
.magic
)) {
3231 case XFS_DIR2_LEAF1_MAGIC
:
3232 case XFS_DIR3_LEAF1_MAGIC
:
3233 if (be32_to_cpu(leaf
->hdr
.info
.forw
) ||
3234 be32_to_cpu(leaf
->hdr
.info
.back
)) {
3236 dbprintf(_("bad leaf block forw/back pointers "
3237 "%d/%d for dir ino %lld block %d\n"),
3238 be32_to_cpu(leaf
->hdr
.info
.forw
),
3239 be32_to_cpu(leaf
->hdr
.info
.back
),
3243 if (dabno
!= mp
->m_dir_geo
->leafblk
) {
3245 dbprintf(_("single leaf block for dir ino %lld "
3246 "block %d should be at block %d\n"),
3248 (xfs_dablk_t
)mp
->m_dir_geo
->leafblk
);
3251 ltp
= xfs_dir2_leaf_tail_p(mp
->m_dir_geo
, leaf
);
3252 lbp
= xfs_dir2_leaf_bests_p(ltp
);
3253 for (i
= 0; i
< be32_to_cpu(ltp
->bestcount
); i
++) {
3254 if (freetab
->nents
<= i
|| freetab
->ents
[i
] !=
3255 be16_to_cpu(lbp
[i
])) {
3257 dbprintf(_("bestfree %d for dir ino %lld "
3258 "block %d doesn't match table "
3260 freetab
->nents
<= i
?
3264 xfs_dir2_db_to_da(mp
->m_dir_geo
, i
),
3265 be16_to_cpu(lbp
[i
]));
3267 if (freetab
->nents
> i
)
3268 freetab
->ents
[i
] = NULLDATAOFF
;
3271 case XFS_DIR2_LEAFN_MAGIC
:
3272 case XFS_DIR3_LEAFN_MAGIC
:
3273 /* if it's at the root location then we can check the
3274 * pointers are null XXX */
3276 case XFS_DA_NODE_MAGIC
:
3277 case XFS_DA3_NODE_MAGIC
:
3278 node
= iocur_top
->data
;
3279 M_DIROPS(mp
)->node_hdr_from_disk(&nodehdr
, node
);
3280 if (nodehdr
.level
< 1 || nodehdr
.level
> XFS_DA_NODE_MAXDEPTH
) {
3282 dbprintf(_("bad node block level %d for dir ino "
3284 nodehdr
.level
, id
->ino
,
3291 dbprintf(_("bad directory data magic # %#x for dir ino "
3293 be16_to_cpu(leaf
->hdr
.info
.magic
), id
->ino
,
3298 lep
= M_DIROPS(mp
)->leaf_ents_p(leaf
);
3299 for (i
= stale
= 0; i
< xfs_dir3_leaf_ents_count(leaf
); i
++) {
3300 if (be32_to_cpu(lep
[i
].address
) == XFS_DIR2_NULL_DATAPTR
)
3302 else if (dir_hash_see(be32_to_cpu(lep
[i
].hashval
),
3303 be32_to_cpu(lep
[i
].address
))) {
3305 dbprintf(_("dir %lld block %d extra leaf entry "
3306 "%x %x\n"), id
->ino
, dabno
,
3307 be32_to_cpu(lep
[i
].hashval
),
3308 be32_to_cpu(lep
[i
].address
));
3312 if (leaf3
&& stale
!= be16_to_cpu(leaf3
->hdr
.stale
)) {
3314 dbprintf(_("dir3 %lld block %d stale mismatch "
3316 id
->ino
, dabno
, stale
,
3317 be16_to_cpu(leaf3
->hdr
.stale
));
3319 } else if (!leaf
&& stale
!= be16_to_cpu(leaf
->hdr
.stale
)) {
3321 dbprintf(_("dir %lld block %d stale mismatch "
3323 id
->ino
, dabno
, stale
,
3324 be16_to_cpu(leaf
->hdr
.stale
));
3339 u_int8_t exp_flags
= 0;
3350 exp_flags
= XFS_DQ_USER
;
3352 case IS_PROJECT_QUOTA
:
3354 exp_flags
= XFS_DQ_PROJ
;
3356 case IS_GROUP_QUOTA
:
3358 exp_flags
= XFS_DQ_GROUP
;
3364 perblock
= (uint
)(mp
->m_sb
.sb_blocksize
/ sizeof(*dqb
));
3367 while ((qbno
= blkmap_next_off(blkmap
, qbno
, &t
)) != NULLFILEOFF
) {
3368 bno
= blkmap_get(blkmap
, qbno
);
3369 dqid
= (xfs_dqid_t
)qbno
* perblock
;
3370 cb
= CHECK_BLIST(bno
);
3371 scicb
= !sflag
|| id
->ilist
|| cb
;
3373 set_cur(&typtab
[TYP_DQBLK
], XFS_FSB_TO_DADDR(mp
, bno
), blkbb
,
3375 if ((dqb
= iocur_top
->data
) == NULL
) {
3377 dbprintf(_("can't read block %lld for %s quota "
3378 "inode (fsblock %lld)\n"),
3379 (xfs_fileoff_t
)qbno
, s
,
3380 (xfs_fsblock_t
)bno
);
3385 for (i
= 0; i
< perblock
; i
++, dqid
++, dqb
++) {
3386 if (verbose
|| id
->ilist
|| cb
)
3387 dbprintf(_("%s dqblk %lld entry %d id %u bc "
3388 "%lld ic %lld rc %lld\n"),
3389 s
, (xfs_fileoff_t
)qbno
, i
, dqid
,
3390 be64_to_cpu(dqb
->dd_diskdq
.d_bcount
),
3391 be64_to_cpu(dqb
->dd_diskdq
.d_icount
),
3392 be64_to_cpu(dqb
->dd_diskdq
.d_rtbcount
));
3393 if (be16_to_cpu(dqb
->dd_diskdq
.d_magic
) != XFS_DQUOT_MAGIC
) {
3395 dbprintf(_("bad magic number %#x for %s "
3396 "dqblk %lld entry %d id %u\n"),
3397 be16_to_cpu(dqb
->dd_diskdq
.d_magic
), s
,
3398 (xfs_fileoff_t
)qbno
, i
, dqid
);
3402 if (dqb
->dd_diskdq
.d_version
!= XFS_DQUOT_VERSION
) {
3404 dbprintf(_("bad version number %#x for "
3405 "%s dqblk %lld entry %d id "
3407 dqb
->dd_diskdq
.d_version
, s
,
3408 (xfs_fileoff_t
)qbno
, i
, dqid
);
3412 if (dqb
->dd_diskdq
.d_flags
!= exp_flags
) {
3414 dbprintf(_("bad flags %#x for %s dqblk "
3415 "%lld entry %d id %u\n"),
3416 dqb
->dd_diskdq
.d_flags
, s
,
3417 (xfs_fileoff_t
)qbno
, i
, dqid
);
3421 if (be32_to_cpu(dqb
->dd_diskdq
.d_id
) != dqid
) {
3423 dbprintf(_("bad id %u for %s dqblk %lld "
3424 "entry %d id %u\n"),
3425 be32_to_cpu(dqb
->dd_diskdq
.d_id
), s
,
3426 (xfs_fileoff_t
)qbno
, i
, dqid
);
3430 quota_add((qtype
== IS_PROJECT_QUOTA
) ? &dqid
: NULL
,
3431 (qtype
== IS_GROUP_QUOTA
) ? &dqid
: NULL
,
3432 (qtype
== IS_USER_QUOTA
) ? &dqid
: NULL
,
3434 be64_to_cpu(dqb
->dd_diskdq
.d_bcount
),
3435 be64_to_cpu(dqb
->dd_diskdq
.d_icount
),
3436 be64_to_cpu(dqb
->dd_diskdq
.d_rtbcount
));
3448 xfs_fileoff_t bmbno
;
3450 xfs_rtblock_t extno
;
3455 xfs_rfsblock_t rtbno
;
3459 xfs_rtword_t
*words
;
3461 bitsperblock
= mp
->m_sb
.sb_blocksize
* NBBY
;
3462 bit
= extno
= prevbit
= start_bmbno
= start_bit
= 0;
3463 bmbno
= NULLFILEOFF
;
3464 while ((bmbno
= blkmap_next_off(blkmap
, bmbno
, &t
)) !=
3466 bno
= blkmap_get(blkmap
, bmbno
);
3467 if (bno
== NULLFSBLOCK
) {
3469 dbprintf(_("block %lld for rtbitmap inode is "
3471 (xfs_fileoff_t
)bmbno
);
3476 set_cur(&typtab
[TYP_RTBITMAP
], XFS_FSB_TO_DADDR(mp
, bno
), blkbb
,
3478 if ((words
= iocur_top
->data
) == NULL
) {
3480 dbprintf(_("can't read block %lld for rtbitmap "
3482 (xfs_fileoff_t
)bmbno
);
3488 bit
< bitsperblock
&& extno
< mp
->m_sb
.sb_rextents
;
3490 if (xfs_isset(words
, bit
)) {
3491 rtbno
= extno
* mp
->m_sb
.sb_rextsize
;
3492 set_rdbmap(rtbno
, mp
->m_sb
.sb_rextsize
,
3496 start_bmbno
= (int)bmbno
;
3500 } else if (prevbit
== 1) {
3501 len
= ((int)bmbno
- start_bmbno
) *
3502 bitsperblock
+ (bit
- start_bit
);
3503 log
= XFS_RTBLOCKLOG(len
);
3504 offs
= XFS_SUMOFFS(mp
, log
, start_bmbno
);
3510 if (extno
== mp
->m_sb
.sb_rextents
)
3514 len
= ((int)bmbno
- start_bmbno
) * bitsperblock
+
3516 log
= XFS_RTBLOCKLOG(len
);
3517 offs
= XFS_SUMOFFS(mp
, log
, start_bmbno
);
3528 xfs_fileoff_t sumbno
;
3531 sumbno
= NULLFILEOFF
;
3532 while ((sumbno
= blkmap_next_off(blkmap
, sumbno
, &t
)) != NULLFILEOFF
) {
3533 bno
= blkmap_get(blkmap
, sumbno
);
3534 if (bno
== NULLFSBLOCK
) {
3536 dbprintf(_("block %lld for rtsummary inode is "
3538 (xfs_fileoff_t
)sumbno
);
3543 set_cur(&typtab
[TYP_RTSUMMARY
], XFS_FSB_TO_DADDR(mp
, bno
),
3544 blkbb
, DB_RING_IGN
, NULL
);
3545 if ((bytes
= iocur_top
->data
) == NULL
) {
3547 dbprintf(_("can't read block %lld for rtsummary "
3549 (xfs_fileoff_t
)sumbno
);
3554 memcpy((char *)sumfile
+ sumbno
* mp
->m_sb
.sb_blocksize
, bytes
,
3555 mp
->m_sb
.sb_blocksize
);
3572 struct xfs_dir2_sf_hdr
*sf
;
3573 xfs_dir2_sf_entry_t
*sfe
;
3576 sf
= (struct xfs_dir2_sf_hdr
*)XFS_DFORK_DPTR(dip
);
3578 v
= verbose
|| id
->ilist
;
3580 dbprintf(_("dir %lld entry . %lld\n"), id
->ino
, id
->ino
);
3582 sfe
= xfs_dir2_sf_firstentry(sf
);
3583 offset
= M_DIROPS(mp
)->data_first_offset
;
3584 for (i
= sf
->count
- 1, i8
= 0; i
>= 0; i
--) {
3585 if ((intptr_t)sfe
+ M_DIROPS(mp
)->sf_entsize(sf
, sfe
->namelen
) -
3586 (intptr_t)sf
> be64_to_cpu(dip
->di_size
)) {
3588 dbprintf(_("dir %llu bad size in entry at %d\n"),
3590 (int)((char *)sfe
- (char *)sf
));
3594 lino
= M_DIROPS(mp
)->sf_get_ino(sf
, sfe
);
3595 if (lino
> XFS_DIR2_MAX_SHORT_INUM
)
3597 cid
= find_inode(lino
, 1);
3600 dbprintf(_("dir %lld entry %*.*s bad inode "
3602 id
->ino
, sfe
->namelen
, sfe
->namelen
,
3609 addname_inode(cid
, (char *)sfe
->name
, sfe
->namelen
);
3612 dbprintf(_("dir %lld entry %*.*s offset %d %lld\n"),
3613 id
->ino
, sfe
->namelen
, sfe
->namelen
, sfe
->name
,
3614 xfs_dir2_sf_get_offset(sfe
), lino
);
3615 if (xfs_dir2_sf_get_offset(sfe
) < offset
) {
3617 dbprintf(_("dir %lld entry %*.*s bad offset %d\n"),
3618 id
->ino
, sfe
->namelen
, sfe
->namelen
,
3619 sfe
->name
, xfs_dir2_sf_get_offset(sfe
));
3623 xfs_dir2_sf_get_offset(sfe
) +
3624 M_DIROPS(mp
)->sf_entsize(sf
, sfe
->namelen
);
3625 sfe
= M_DIROPS(mp
)->sf_nextentry(sf
, sfe
);
3627 if (i
< 0 && (intptr_t)sfe
- (intptr_t)sf
!=
3628 be64_to_cpu(dip
->di_size
)) {
3630 dbprintf(_("dir %llu size is %lld, should be %u\n"),
3631 id
->ino
, be64_to_cpu(dip
->di_size
),
3632 (uint
)((char *)sfe
- (char *)sf
));
3635 if (offset
+ (sf
->count
+ 2) * sizeof(xfs_dir2_leaf_entry_t
) +
3636 sizeof(xfs_dir2_block_tail_t
) > mp
->m_dir_geo
->blksize
) {
3638 dbprintf(_("dir %llu offsets too high\n"), id
->ino
);
3641 lino
= M_DIROPS(mp
)->sf_get_parent_ino(sf
);
3642 if (lino
> XFS_DIR2_MAX_SHORT_INUM
)
3644 cid
= find_inode(lino
, 1);
3649 dbprintf(_("dir %lld entry .. bad inode number %lld\n"),
3654 dbprintf(_("dir %lld entry .. %lld\n"), id
->ino
, lino
);
3655 if (i8
!= sf
->i8count
) {
3657 dbprintf(_("dir %lld i8count mismatch is %d should be "
3659 id
->ino
, sf
->i8count
, i8
);
3663 return cid
? lino
: NULLFSINO
;
3677 if (qudo
&& usrid
!= NULL
)
3678 quota_add1(qudata
, *usrid
, dq
, bc
, ic
, rc
);
3679 if (qgdo
&& grpid
!= NULL
)
3680 quota_add1(qgdata
, *grpid
, dq
, bc
, ic
, rc
);
3681 if (qpdo
&& prjid
!= NULL
)
3682 quota_add1(qpdata
, *prjid
, dq
, bc
, ic
, rc
);
3698 qh
= (int)(id
% QDATA_HASH_SIZE
);
3702 qi
= dq
? &qe
->dq
: &qe
->count
;
3710 qe
= xmalloc(sizeof(*qe
));
3712 qi
= dq
? &qe
->dq
: &qe
->count
;
3716 qi
= dq
? &qe
->count
: &qe
->dq
;
3717 qi
->bc
= qi
->ic
= qi
->rc
= 0;
3731 for (i
= 0; i
< QDATA_HASH_SIZE
; i
++) {
3735 if (qp
->count
.bc
!= qp
->dq
.bc
||
3736 qp
->count
.ic
!= qp
->dq
.ic
||
3737 qp
->count
.rc
!= qp
->dq
.rc
) {
3739 dbprintf(_("%s quota id %u, have/exp"),
3741 if (qp
->count
.bc
!= qp
->dq
.bc
)
3742 dbprintf(_(" bc %lld/%lld"),
3745 if (qp
->count
.ic
!= qp
->dq
.ic
)
3746 dbprintf(_(" ic %lld/%lld"),
3749 if (qp
->count
.rc
!= qp
->dq
.rc
)
3750 dbprintf(_(" rc %lld/%lld"),
3767 qudo
= mp
->m_sb
.sb_uquotino
!= 0 &&
3768 mp
->m_sb
.sb_uquotino
!= NULLFSINO
&&
3769 (mp
->m_sb
.sb_qflags
& XFS_UQUOTA_ACCT
) &&
3770 (mp
->m_sb
.sb_qflags
& XFS_UQUOTA_CHKD
);
3771 qgdo
= mp
->m_sb
.sb_gquotino
!= 0 &&
3772 mp
->m_sb
.sb_gquotino
!= NULLFSINO
&&
3773 (mp
->m_sb
.sb_qflags
& XFS_GQUOTA_ACCT
) &&
3774 (mp
->m_sb
.sb_qflags
& XFS_GQUOTA_CHKD
);
3775 qpdo
= mp
->m_sb
.sb_pquotino
!= 0 &&
3776 mp
->m_sb
.sb_pquotino
!= NULLFSINO
&&
3777 (mp
->m_sb
.sb_qflags
& XFS_PQUOTA_ACCT
) &&
3778 (mp
->m_sb
.sb_qflags
& XFS_PQUOTA_CHKD
);
3780 qudata
= xcalloc(QDATA_HASH_SIZE
, sizeof(qdata_t
*));
3782 qgdata
= xcalloc(QDATA_HASH_SIZE
, sizeof(qdata_t
*));
3784 qpdata
= xcalloc(QDATA_HASH_SIZE
, sizeof(qdata_t
*));
3789 xfs_agnumber_t agno
)
3795 xfs_sb_t
*sb
= &tsb
;
3797 agffreeblks
= agflongest
= 0;
3799 agicount
= agifreecount
= 0;
3800 push_cur(); /* 1 pushed */
3801 set_cur(&typtab
[TYP_SB
],
3802 XFS_AG_DADDR(mp
, agno
, XFS_SB_DADDR
),
3803 XFS_FSS_TO_BB(mp
, 1), DB_RING_IGN
, NULL
);
3805 if (!iocur_top
->data
) {
3806 dbprintf(_("can't read superblock for ag %u\n"), agno
);
3811 libxfs_sb_from_disk(sb
, iocur_top
->data
);
3813 if (sb
->sb_magicnum
!= XFS_SB_MAGIC
) {
3815 dbprintf(_("bad sb magic # %#x in ag %u\n"),
3816 sb
->sb_magicnum
, agno
);
3819 if (!xfs_sb_good_version(sb
)) {
3821 dbprintf(_("bad sb version # %#x in ag %u\n"),
3822 sb
->sb_versionnum
, agno
);
3826 if (!lazycount
&& xfs_sb_version_haslazysbcount(sb
)) {
3829 if (agno
== 0 && sb
->sb_inprogress
!= 0) {
3831 dbprintf(_("mkfs not completed successfully\n"));
3834 set_dbmap(agno
, XFS_SB_BLOCK(mp
), 1, DBM_SB
, agno
, XFS_SB_BLOCK(mp
));
3835 if (sb
->sb_logstart
&& XFS_FSB_TO_AGNO(mp
, sb
->sb_logstart
) == agno
)
3836 set_dbmap(agno
, XFS_FSB_TO_AGBNO(mp
, sb
->sb_logstart
),
3837 sb
->sb_logblocks
, DBM_LOG
, agno
, XFS_SB_BLOCK(mp
));
3838 push_cur(); /* 2 pushed */
3839 set_cur(&typtab
[TYP_AGF
],
3840 XFS_AG_DADDR(mp
, agno
, XFS_AGF_DADDR(mp
)),
3841 XFS_FSS_TO_BB(mp
, 1), DB_RING_IGN
, NULL
);
3842 if ((agf
= iocur_top
->data
) == NULL
) {
3843 dbprintf(_("can't read agf block for ag %u\n"), agno
);
3847 if (be32_to_cpu(agf
->agf_magicnum
) != XFS_AGF_MAGIC
) {
3849 dbprintf(_("bad agf magic # %#x in ag %u\n"),
3850 be32_to_cpu(agf
->agf_magicnum
), agno
);
3853 if (!XFS_AGF_GOOD_VERSION(be32_to_cpu(agf
->agf_versionnum
))) {
3855 dbprintf(_("bad agf version # %#x in ag %u\n"),
3856 be32_to_cpu(agf
->agf_versionnum
), agno
);
3859 if (XFS_SB_BLOCK(mp
) != XFS_AGF_BLOCK(mp
))
3860 set_dbmap(agno
, XFS_AGF_BLOCK(mp
), 1, DBM_AGF
, agno
,
3862 if (sb
->sb_agblocks
> be32_to_cpu(agf
->agf_length
))
3863 set_dbmap(agno
, be32_to_cpu(agf
->agf_length
),
3864 sb
->sb_agblocks
- be32_to_cpu(agf
->agf_length
),
3865 DBM_MISSING
, agno
, XFS_SB_BLOCK(mp
));
3866 push_cur(); /* 3 pushed */
3867 set_cur(&typtab
[TYP_AGI
],
3868 XFS_AG_DADDR(mp
, agno
, XFS_AGI_DADDR(mp
)),
3869 XFS_FSS_TO_BB(mp
, 1), DB_RING_IGN
, NULL
);
3870 if ((agi
= iocur_top
->data
) == NULL
) {
3871 dbprintf(_("can't read agi block for ag %u\n"), agno
);
3875 if (be32_to_cpu(agi
->agi_magicnum
) != XFS_AGI_MAGIC
) {
3877 dbprintf(_("bad agi magic # %#x in ag %u\n"),
3878 be32_to_cpu(agi
->agi_magicnum
), agno
);
3881 if (!XFS_AGI_GOOD_VERSION(be32_to_cpu(agi
->agi_versionnum
))) {
3883 dbprintf(_("bad agi version # %#x in ag %u\n"),
3884 be32_to_cpu(agi
->agi_versionnum
), agno
);
3887 if (XFS_SB_BLOCK(mp
) != XFS_AGI_BLOCK(mp
) &&
3888 XFS_AGF_BLOCK(mp
) != XFS_AGI_BLOCK(mp
))
3889 set_dbmap(agno
, XFS_AGI_BLOCK(mp
), 1, DBM_AGI
, agno
,
3894 be32_to_cpu(agf
->agf_roots
[XFS_BTNUM_BNO
]),
3895 be32_to_cpu(agf
->agf_levels
[XFS_BTNUM_BNO
]),
3896 1, scanfunc_bno
, TYP_BNOBT
);
3899 be32_to_cpu(agf
->agf_roots
[XFS_BTNUM_CNT
]),
3900 be32_to_cpu(agf
->agf_levels
[XFS_BTNUM_CNT
]),
3901 1, scanfunc_cnt
, TYP_CNTBT
);
3903 be32_to_cpu(agi
->agi_root
),
3904 be32_to_cpu(agi
->agi_level
),
3905 1, scanfunc_ino
, TYP_INOBT
);
3906 if (agi
->agi_free_root
) {
3908 be32_to_cpu(agi
->agi_free_root
),
3909 be32_to_cpu(agi
->agi_free_level
),
3910 1, scanfunc_fino
, TYP_FINOBT
);
3912 if (be32_to_cpu(agf
->agf_freeblks
) != agffreeblks
) {
3914 dbprintf(_("agf_freeblks %u, counted %u in ag %u\n"),
3915 be32_to_cpu(agf
->agf_freeblks
),
3919 if (be32_to_cpu(agf
->agf_longest
) != agflongest
) {
3921 dbprintf(_("agf_longest %u, counted %u in ag %u\n"),
3922 be32_to_cpu(agf
->agf_longest
),
3927 be32_to_cpu(agf
->agf_btreeblks
) != agfbtreeblks
) {
3929 dbprintf(_("agf_btreeblks %u, counted %u in ag %u\n"),
3930 be32_to_cpu(agf
->agf_btreeblks
),
3931 agfbtreeblks
, agno
);
3934 agf_aggr_freeblks
+= agffreeblks
+ agfbtreeblks
;
3935 if (be32_to_cpu(agi
->agi_count
) != agicount
) {
3937 dbprintf(_("agi_count %u, counted %u in ag %u\n"),
3938 be32_to_cpu(agi
->agi_count
),
3942 if (be32_to_cpu(agi
->agi_freecount
) != agifreecount
) {
3944 dbprintf(_("agi_freecount %u, counted %u in ag %u\n"),
3945 be32_to_cpu(agi
->agi_freecount
),
3946 agifreecount
, agno
);
3949 for (i
= 0; i
< XFS_AGI_UNLINKED_BUCKETS
; i
++) {
3950 if (be32_to_cpu(agi
->agi_unlinked
[i
]) != NULLAGINO
) {
3952 xfs_agino_t agino
=be32_to_cpu(agi
->agi_unlinked
[i
]);
3953 dbprintf(_("agi unlinked bucket %d is %u in ag "
3954 "%u (inode=%lld)\n"), i
, agino
, agno
,
3955 XFS_AGINO_TO_INO(mp
, agno
, agino
));
3972 xfs_agnumber_t seqno
= be32_to_cpu(agf
->agf_seqno
);
3979 if (XFS_SB_BLOCK(mp
) != XFS_AGFL_BLOCK(mp
) &&
3980 XFS_AGF_BLOCK(mp
) != XFS_AGFL_BLOCK(mp
) &&
3981 XFS_AGI_BLOCK(mp
) != XFS_AGFL_BLOCK(mp
))
3982 set_dbmap(seqno
, XFS_AGFL_BLOCK(mp
), 1, DBM_AGFL
, seqno
,
3984 if (be32_to_cpu(agf
->agf_flcount
) == 0)
3987 set_cur(&typtab
[TYP_AGFL
],
3988 XFS_AG_DADDR(mp
, seqno
, XFS_AGFL_DADDR(mp
)),
3989 XFS_FSS_TO_BB(mp
, 1), DB_RING_IGN
, NULL
);
3990 if ((agfl
= iocur_top
->data
) == NULL
) {
3991 dbprintf(_("can't read agfl block for ag %u\n"), seqno
);
3996 i
= be32_to_cpu(agf
->agf_flfirst
);
3998 /* verify agf values before proceeding */
3999 if (be32_to_cpu(agf
->agf_flfirst
) >= XFS_AGFL_SIZE(mp
) ||
4000 be32_to_cpu(agf
->agf_fllast
) >= XFS_AGFL_SIZE(mp
)) {
4001 dbprintf(_("agf %d freelist blocks bad, skipping "
4002 "freelist scan\n"), i
);
4007 /* open coded XFS_BUF_TO_AGFL_BNO */
4008 freelist
= xfs_sb_version_hascrc(&((mp
)->m_sb
)) ? &agfl
->agfl_bno
[0]
4012 bno
= be32_to_cpu(freelist
[i
]);
4013 set_dbmap(seqno
, bno
, 1, DBM_FREELIST
, seqno
,
4014 XFS_AGFL_BLOCK(mp
));
4016 if (i
== be32_to_cpu(agf
->agf_fllast
))
4018 if (++i
== XFS_AGFL_SIZE(mp
))
4021 if (count
!= be32_to_cpu(agf
->agf_flcount
)) {
4023 dbprintf(_("freeblk count %u != flcount %u in ag %u\n"),
4024 count
, be32_to_cpu(agf
->agf_flcount
),
4029 agf_aggr_freeblks
+= count
;
4037 scan_lbtree_f_t func
,
4040 xfs_rfsblock_t
*totd
,
4041 xfs_rfsblock_t
*toti
,
4048 set_cur(&typtab
[btype
], XFS_FSB_TO_DADDR(mp
, root
), blkbb
, DB_RING_IGN
,
4050 if (iocur_top
->data
== NULL
) {
4052 dbprintf(_("can't read btree block %u/%u\n"),
4053 XFS_FSB_TO_AGNO(mp
, root
),
4054 XFS_FSB_TO_AGBNO(mp
, root
));
4059 (*func
)(iocur_top
->data
, nlevels
- 1, type
, root
, id
, totd
, toti
, nex
,
4060 blkmapp
, isroot
, btype
);
4070 scan_sbtree_f_t func
,
4073 xfs_agnumber_t seqno
= be32_to_cpu(agf
->agf_seqno
);
4076 set_cur(&typtab
[btype
],
4077 XFS_AGB_TO_DADDR(mp
, seqno
, root
), blkbb
, DB_RING_IGN
, NULL
);
4078 if (iocur_top
->data
== NULL
) {
4080 dbprintf(_("can't read btree block %u/%u\n"), seqno
, root
);
4085 (*func
)(iocur_top
->data
, nlevels
- 1, agf
, root
, isroot
);
4091 struct xfs_btree_block
*block
,
4096 xfs_rfsblock_t
*totd
,
4097 xfs_rfsblock_t
*toti
,
4103 xfs_agblock_t agbno
;
4104 xfs_agnumber_t agno
;
4109 agno
= XFS_FSB_TO_AGNO(mp
, bno
);
4110 agbno
= XFS_FSB_TO_AGBNO(mp
, bno
);
4111 if (be32_to_cpu(block
->bb_magic
) != XFS_BMAP_MAGIC
&&
4112 be32_to_cpu(block
->bb_magic
) != XFS_BMAP_CRC_MAGIC
) {
4113 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
4114 dbprintf(_("bad magic # %#x in inode %lld bmbt block "
4116 be32_to_cpu(block
->bb_magic
), id
->ino
, agno
, agbno
);
4119 if (be16_to_cpu(block
->bb_level
) != level
) {
4120 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
4121 dbprintf(_("expected level %d got %d in inode %lld bmbt "
4123 level
, be16_to_cpu(block
->bb_level
), id
->ino
, agno
, agbno
);
4126 set_dbmap(agno
, agbno
, 1, type
, agno
, agbno
);
4127 set_inomap(agno
, agbno
, 1, id
);
4130 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_bmap_dmxr
[0] ||
4131 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_bmap_dmnr
[0])) {
4132 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
4133 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) "
4134 "in inode %lld bmap block %lld\n"),
4135 be16_to_cpu(block
->bb_numrecs
), mp
->m_bmap_dmnr
[0],
4136 mp
->m_bmap_dmxr
[0], id
->ino
,
4137 (xfs_fsblock_t
)bno
);
4141 rp
= XFS_BMBT_REC_ADDR(mp
, block
, 1);
4142 *nex
+= be16_to_cpu(block
->bb_numrecs
);
4143 process_bmbt_reclist(rp
, be16_to_cpu(block
->bb_numrecs
), type
, id
, totd
,
4147 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_bmap_dmxr
[1] ||
4148 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_bmap_dmnr
[1])) {
4149 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
4150 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in "
4151 "inode %lld bmap block %lld\n"),
4152 be16_to_cpu(block
->bb_numrecs
), mp
->m_bmap_dmnr
[1],
4153 mp
->m_bmap_dmxr
[1], id
->ino
, (xfs_fsblock_t
)bno
);
4157 pp
= XFS_BMBT_PTR_ADDR(mp
, block
, 1, mp
->m_bmap_dmxr
[0]);
4158 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++)
4159 scan_lbtree(be64_to_cpu(pp
[i
]), level
, scanfunc_bmap
, type
, id
,
4160 totd
, toti
, nex
, blkmapp
, 0, btype
);
4165 struct xfs_btree_block
*block
,
4172 xfs_alloc_ptr_t
*pp
;
4173 xfs_alloc_rec_t
*rp
;
4174 xfs_agnumber_t seqno
= be32_to_cpu(agf
->agf_seqno
);
4175 xfs_agblock_t lastblock
;
4177 if (be32_to_cpu(block
->bb_magic
) != XFS_ABTB_MAGIC
&&
4178 be32_to_cpu(block
->bb_magic
) != XFS_ABTB_CRC_MAGIC
) {
4179 dbprintf(_("bad magic # %#x in btbno block %u/%u\n"),
4180 be32_to_cpu(block
->bb_magic
), seqno
, bno
);
4186 if (be16_to_cpu(block
->bb_level
) != level
) {
4188 dbprintf(_("expected level %d got %d in btbno block "
4190 level
, be16_to_cpu(block
->bb_level
), seqno
, bno
);
4193 set_dbmap(seqno
, bno
, 1, DBM_BTBNO
, seqno
, bno
);
4195 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_alloc_mxr
[0] ||
4196 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_alloc_mnr
[0])) {
4197 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in "
4198 "btbno block %u/%u\n"),
4199 be16_to_cpu(block
->bb_numrecs
), mp
->m_alloc_mnr
[0],
4200 mp
->m_alloc_mxr
[0], seqno
, bno
);
4204 rp
= XFS_ALLOC_REC_ADDR(mp
, block
, 1);
4206 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++) {
4207 set_dbmap(seqno
, be32_to_cpu(rp
[i
].ar_startblock
),
4208 be32_to_cpu(rp
[i
].ar_blockcount
), DBM_FREE1
,
4210 if (be32_to_cpu(rp
[i
].ar_startblock
) <= lastblock
) {
4212 "out-of-order bno btree record %d (%u %u) block %u/%u\n"),
4213 i
, be32_to_cpu(rp
[i
].ar_startblock
),
4214 be32_to_cpu(rp
[i
].ar_blockcount
),
4215 be32_to_cpu(agf
->agf_seqno
), bno
);
4218 lastblock
= be32_to_cpu(rp
[i
].ar_startblock
);
4223 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_alloc_mxr
[1] ||
4224 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_alloc_mnr
[1])) {
4225 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in btbno block "
4227 be16_to_cpu(block
->bb_numrecs
), mp
->m_alloc_mnr
[1],
4228 mp
->m_alloc_mxr
[1], seqno
, bno
);
4232 pp
= XFS_ALLOC_PTR_ADDR(mp
, block
, 1, mp
->m_alloc_mxr
[1]);
4233 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++)
4234 scan_sbtree(agf
, be32_to_cpu(pp
[i
]), level
, 0, scanfunc_bno
, TYP_BNOBT
);
4239 struct xfs_btree_block
*block
,
4245 xfs_agnumber_t seqno
= be32_to_cpu(agf
->agf_seqno
);
4247 xfs_alloc_ptr_t
*pp
;
4248 xfs_alloc_rec_t
*rp
;
4249 xfs_extlen_t lastcount
;
4251 if (be32_to_cpu(block
->bb_magic
) != XFS_ABTC_MAGIC
&&
4252 be32_to_cpu(block
->bb_magic
) != XFS_ABTC_CRC_MAGIC
) {
4253 dbprintf(_("bad magic # %#x in btcnt block %u/%u\n"),
4254 be32_to_cpu(block
->bb_magic
), seqno
, bno
);
4260 if (be16_to_cpu(block
->bb_level
) != level
) {
4262 dbprintf(_("expected level %d got %d in btcnt block "
4264 level
, be16_to_cpu(block
->bb_level
), seqno
, bno
);
4267 set_dbmap(seqno
, bno
, 1, DBM_BTCNT
, seqno
, bno
);
4269 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_alloc_mxr
[0] ||
4270 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_alloc_mnr
[0])) {
4271 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in "
4272 "btbno block %u/%u\n"),
4273 be16_to_cpu(block
->bb_numrecs
), mp
->m_alloc_mnr
[0],
4274 mp
->m_alloc_mxr
[0], seqno
, bno
);
4278 rp
= XFS_ALLOC_REC_ADDR(mp
, block
, 1);
4280 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++) {
4281 check_set_dbmap(seqno
, be32_to_cpu(rp
[i
].ar_startblock
),
4282 be32_to_cpu(rp
[i
].ar_blockcount
), DBM_FREE1
, DBM_FREE2
,
4284 fdblocks
+= be32_to_cpu(rp
[i
].ar_blockcount
);
4285 agffreeblks
+= be32_to_cpu(rp
[i
].ar_blockcount
);
4286 if (be32_to_cpu(rp
[i
].ar_blockcount
) > agflongest
)
4287 agflongest
= be32_to_cpu(rp
[i
].ar_blockcount
);
4288 if (be32_to_cpu(rp
[i
].ar_blockcount
) < lastcount
) {
4290 "out-of-order cnt btree record %d (%u %u) block %u/%u\n"),
4291 i
, be32_to_cpu(rp
[i
].ar_startblock
),
4292 be32_to_cpu(rp
[i
].ar_blockcount
),
4293 be32_to_cpu(agf
->agf_seqno
), bno
);
4295 lastcount
= be32_to_cpu(rp
[i
].ar_blockcount
);
4300 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_alloc_mxr
[1] ||
4301 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_alloc_mnr
[1])) {
4302 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in btbno block "
4304 be16_to_cpu(block
->bb_numrecs
), mp
->m_alloc_mnr
[1],
4305 mp
->m_alloc_mxr
[1], seqno
, bno
);
4309 pp
= XFS_ALLOC_PTR_ADDR(mp
, block
, 1, mp
->m_alloc_mxr
[1]);
4310 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++)
4311 scan_sbtree(agf
, be32_to_cpu(pp
[i
]), level
, 0, scanfunc_cnt
, TYP_CNTBT
);
4316 struct xfs_inobt_rec
*rp
,
4319 if (!xfs_sb_version_hassparseinodes(&mp
->m_sb
))
4322 return xfs_inobt_is_sparse_disk(rp
, offset
);
4333 startino
/= XFS_INODES_PER_HOLEMASK_BIT
;
4336 for (n
= startino
; n
< sizeof(mask
) * NBBY
&& !(mask
& 1); n
++, mask
>>= 1)
4339 return b
* XFS_INODES_PER_HOLEMASK_BIT
;
4350 startino
/= XFS_INODES_PER_HOLEMASK_BIT
;
4353 for (n
= startino
; n
< sizeof(mask
) * NBBY
&& (mask
& 1); n
++, mask
>>= 1)
4356 return b
* XFS_INODES_PER_HOLEMASK_BIT
;
4361 struct xfs_btree_block
*block
,
4368 xfs_agnumber_t seqno
= be32_to_cpu(agf
->agf_seqno
);
4374 xfs_inobt_ptr_t
*pp
;
4375 xfs_inobt_rec_t
*rp
;
4377 int inodes_per_chunk
;
4379 int startidx
, endidx
;
4382 xfs_extlen_t cblocks
;
4384 if (be32_to_cpu(block
->bb_magic
) != XFS_IBT_MAGIC
&&
4385 be32_to_cpu(block
->bb_magic
) != XFS_IBT_CRC_MAGIC
) {
4386 dbprintf(_("bad magic # %#x in inobt block %u/%u\n"),
4387 be32_to_cpu(block
->bb_magic
), seqno
, bno
);
4391 if (be16_to_cpu(block
->bb_level
) != level
) {
4393 dbprintf(_("expected level %d got %d in inobt block "
4395 level
, be16_to_cpu(block
->bb_level
), seqno
, bno
);
4398 set_dbmap(seqno
, bno
, 1, DBM_BTINO
, seqno
, bno
);
4400 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_inobt_mxr
[0] ||
4401 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_inobt_mnr
[0])) {
4402 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in "
4403 "inobt block %u/%u\n"),
4404 be16_to_cpu(block
->bb_numrecs
), mp
->m_inobt_mnr
[0],
4405 mp
->m_inobt_mxr
[0], seqno
, bno
);
4409 rp
= XFS_INOBT_REC_ADDR(mp
, block
, 1);
4410 sparse
= xfs_sb_version_hassparseinodes(&mp
->m_sb
);
4411 crc
= xfs_sb_version_hascrc(&mp
->m_sb
);
4412 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++) {
4415 /* First let's look at the inode chunk alignment */
4416 agino
= be32_to_cpu(rp
[i
].ir_startino
);
4417 off
= XFS_INO_TO_OFFSET(mp
, agino
);
4419 (sbversion
& XFS_SB_VERSION_ALIGNBIT
) &&
4420 mp
->m_sb
.sb_inoalignmt
&&
4421 (XFS_INO_TO_AGBNO(mp
, agino
) %
4422 mp
->m_sb
.sb_inoalignmt
)) {
4423 if (sparse
|| crc
) {
4424 dbprintf(_("incorrect record %u/%u "
4425 "alignment in inobt block "
4427 seqno
, agino
, seqno
, bno
);
4430 sbversion
&= ~XFS_SB_VERSION_ALIGNBIT
;
4433 /* Move on to examining the inode chunks */
4435 inodes_per_chunk
= rp
[i
].ir_u
.sp
.ir_count
;
4436 freecount
= rp
[i
].ir_u
.sp
.ir_freecount
;
4437 holemask
= be16_to_cpu(rp
[i
].ir_u
.sp
.ir_holemask
);
4438 startidx
= find_zero_ino_bit(holemask
, 0);
4440 inodes_per_chunk
= XFS_INODES_PER_CHUNK
;
4441 freecount
= be32_to_cpu(rp
[i
].ir_u
.f
.ir_freecount
);
4446 /* For each allocated chunk, look at each inode. */
4447 endidx
= find_one_ino_bit(holemask
, startidx
);
4449 rino
= agino
+ startidx
;
4450 cblocks
= (endidx
- startidx
) >>
4451 mp
->m_sb
.sb_inopblog
;
4453 /* Check the sparse chunk alignment */
4455 (XFS_INO_TO_AGBNO(mp
, rino
) %
4456 mp
->m_sb
.sb_spino_align
)) {
4457 dbprintf(_("incorrect chunk %u/%u "
4458 "alignment in inobt block "
4460 seqno
, rino
, seqno
, bno
);
4464 /* Check the block map */
4465 set_dbmap(seqno
, XFS_AGINO_TO_AGBNO(mp
, rino
),
4466 cblocks
, DBM_INODE
, seqno
, bno
);
4469 set_cur(&typtab
[TYP_INODE
],
4470 XFS_AGB_TO_DADDR(mp
, seqno
,
4471 XFS_AGINO_TO_AGBNO(mp
, rino
)),
4472 (int)XFS_FSB_TO_BB(mp
, cblocks
),
4474 if (iocur_top
->data
== NULL
) {
4476 dbprintf(_("can't read inode block "
4479 XFS_AGINO_TO_AGBNO(mp
, agino
));
4485 /* Examine each inode in this chunk */
4486 for (j
= startidx
; j
< endidx
; j
++) {
4487 if (ino_issparse(&rp
[i
], j
))
4489 isfree
= XFS_INOBT_IS_FREE_DISK(&rp
[i
], j
);
4492 process_inode(agf
, agino
+ j
,
4493 (xfs_dinode_t
*)((char *)iocur_top
->data
+ ((j
- startidx
) << mp
->m_sb
.sb_inodelog
)),
4498 startidx
= find_zero_ino_bit(holemask
, endidx
);
4499 endidx
= find_one_ino_bit(holemask
, startidx
);
4500 } while (endidx
< XFS_INODES_PER_CHUNK
);
4501 icount
+= inodes_per_chunk
;
4502 agicount
+= inodes_per_chunk
;
4504 agifreecount
+= freecount
;
4506 if (nfree
!= freecount
) {
4508 dbprintf(_("ir_freecount/free mismatch, "
4509 "inode chunk %u/%u, freecount "
4518 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_inobt_mxr
[1] ||
4519 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_inobt_mnr
[1])) {
4520 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in inobt block "
4522 be16_to_cpu(block
->bb_numrecs
), mp
->m_inobt_mnr
[1],
4523 mp
->m_inobt_mxr
[1], seqno
, bno
);
4527 pp
= XFS_INOBT_PTR_ADDR(mp
, block
, 1, mp
->m_inobt_mxr
[1]);
4528 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++)
4529 scan_sbtree(agf
, be32_to_cpu(pp
[i
]), level
, 0, scanfunc_ino
, TYP_INOBT
);
4534 struct xfs_btree_block
*block
,
4536 struct xfs_agf
*agf
,
4541 xfs_agnumber_t seqno
= be32_to_cpu(agf
->agf_seqno
);
4544 xfs_inobt_ptr_t
*pp
;
4545 struct xfs_inobt_rec
*rp
;
4547 int startidx
, endidx
;
4550 xfs_extlen_t cblocks
;
4552 if (be32_to_cpu(block
->bb_magic
) != XFS_FIBT_MAGIC
&&
4553 be32_to_cpu(block
->bb_magic
) != XFS_FIBT_CRC_MAGIC
) {
4554 dbprintf(_("bad magic # %#x in finobt block %u/%u\n"),
4555 be32_to_cpu(block
->bb_magic
), seqno
, bno
);
4559 if (be16_to_cpu(block
->bb_level
) != level
) {
4561 dbprintf(_("expected level %d got %d in finobt block "
4563 level
, be16_to_cpu(block
->bb_level
), seqno
, bno
);
4566 set_dbmap(seqno
, bno
, 1, DBM_BTFINO
, seqno
, bno
);
4568 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_inobt_mxr
[0] ||
4569 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_inobt_mnr
[0])) {
4570 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in "
4571 "finobt block %u/%u\n"),
4572 be16_to_cpu(block
->bb_numrecs
), mp
->m_inobt_mnr
[0],
4573 mp
->m_inobt_mxr
[0], seqno
, bno
);
4577 rp
= XFS_INOBT_REC_ADDR(mp
, block
, 1);
4578 sparse
= xfs_sb_version_hassparseinodes(&mp
->m_sb
);
4579 crc
= xfs_sb_version_hascrc(&mp
->m_sb
);
4580 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++) {
4581 /* First let's look at the inode chunk alignment */
4582 agino
= be32_to_cpu(rp
[i
].ir_startino
);
4583 off
= XFS_INO_TO_OFFSET(mp
, agino
);
4585 (sbversion
& XFS_SB_VERSION_ALIGNBIT
) &&
4586 mp
->m_sb
.sb_inoalignmt
&&
4587 (XFS_INO_TO_AGBNO(mp
, agino
) %
4588 mp
->m_sb
.sb_inoalignmt
)) {
4589 if (sparse
|| crc
) {
4590 dbprintf(_("incorrect record %u/%u "
4591 "alignment in finobt block "
4593 seqno
, agino
, seqno
, bno
);
4596 sbversion
&= ~XFS_SB_VERSION_ALIGNBIT
;
4599 /* Move on to examining the inode chunks */
4601 holemask
= be16_to_cpu(rp
[i
].ir_u
.sp
.ir_holemask
);
4602 startidx
= find_zero_ino_bit(holemask
, 0);
4608 /* For each allocated chunk... */
4609 endidx
= find_one_ino_bit(holemask
, startidx
);
4611 rino
= agino
+ startidx
;
4612 cblocks
= (endidx
- startidx
) >>
4613 mp
->m_sb
.sb_inopblog
;
4615 /* Check the sparse chunk alignment */
4617 (XFS_INO_TO_AGBNO(mp
, rino
) %
4618 mp
->m_sb
.sb_spino_align
)) {
4619 dbprintf(_("incorrect chunk %u/%u "
4620 "alignment in finobt block "
4622 seqno
, rino
, seqno
, bno
);
4626 /* Check the block map */
4627 check_set_dbmap(seqno
,
4628 XFS_AGINO_TO_AGBNO(mp
, rino
),
4629 cblocks
, DBM_INODE
, DBM_INODE
,
4632 startidx
= find_zero_ino_bit(holemask
, endidx
);
4633 endidx
= find_one_ino_bit(holemask
, startidx
);
4634 } while (endidx
< XFS_INODES_PER_CHUNK
);
4638 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_inobt_mxr
[1] ||
4639 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_inobt_mnr
[1])) {
4640 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in finobt block "
4642 be16_to_cpu(block
->bb_numrecs
), mp
->m_inobt_mnr
[1],
4643 mp
->m_inobt_mxr
[1], seqno
, bno
);
4647 pp
= XFS_INOBT_PTR_ADDR(mp
, block
, 1, mp
->m_inobt_mxr
[1]);
4648 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++)
4649 scan_sbtree(agf
, be32_to_cpu(pp
[i
]), level
, 0, scanfunc_fino
, TYP_FINOBT
);
4654 xfs_agnumber_t agno
,
4655 xfs_agblock_t agbno
,
4658 xfs_agnumber_t c_agno
,
4659 xfs_agblock_t c_agbno
)
4661 check_set_dbmap(agno
, agbno
, len
, DBM_UNKNOWN
, type
, c_agno
, c_agbno
);
4666 xfs_agnumber_t agno
,
4667 xfs_agblock_t agbno
,
4675 if (!check_inomap(agno
, agbno
, len
, id
->ino
))
4677 mayprint
= verbose
| id
->ilist
| blist_size
;
4678 for (i
= 0, idp
= &inomap
[agno
][agbno
]; i
< len
; i
++, idp
++) {
4681 (verbose
|| id
->ilist
|| CHECK_BLISTA(agno
, agbno
+ i
)))
4682 dbprintf(_("setting inode to %lld for block %u/%u\n"),
4683 id
->ino
, agno
, agbno
+ i
);
4693 check_set_rdbmap(bno
, len
, DBM_UNKNOWN
, type
);
4706 if (!check_rinomap(bno
, len
, id
->ino
))
4708 mayprint
= verbose
| id
->ilist
| blist_size
;
4709 for (i
= 0, idp
= &inomap
[mp
->m_sb
.sb_agcount
][bno
];
4713 if (mayprint
&& (verbose
|| id
->ilist
|| CHECK_BLIST(bno
+ i
)))
4714 dbprintf(_("setting inode to %lld for rtblock %llu\n"),
4726 id
->link_set
= nlink
;
4728 id
->security
= security
;
4729 if (verbose
|| id
->ilist
)
4730 dbprintf(_("inode %lld nlink %u %s dir\n"), id
->ino
, nlink
,
4731 isdir
? "is" : "not");