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
19 #include <xfs/libxfs.h>
36 IS_USER_QUOTA
, IS_PROJECT_QUOTA
, IS_GROUP_QUOTA
,
40 DBM_UNKNOWN
, DBM_AGF
, DBM_AGFL
, DBM_AGI
,
41 DBM_ATTR
, DBM_BTBMAPA
, DBM_BTBMAPD
, DBM_BTBNO
,
42 DBM_BTCNT
, DBM_BTINO
, DBM_DATA
, DBM_DIR
,
43 DBM_FREE1
, DBM_FREE2
, DBM_FREELIST
, DBM_INODE
,
44 DBM_LOG
, DBM_MISSING
, DBM_QUOTA
, DBM_RTBITMAP
,
45 DBM_RTDATA
, DBM_RTFREE
, DBM_RTSUM
, DBM_SB
,
50 typedef struct inodata
{
58 struct inodata
*parent
;
61 #define MIN_INODATA_HASH_SIZE 256
62 #define MAX_INODATA_HASH_SIZE 65536
63 #define INODATA_AVG_HASH_LENGTH 8
65 typedef struct qinfo
{
71 #define QDATA_HASH_SIZE 256
72 typedef struct qdata
{
79 typedef struct blkent
{
80 xfs_fileoff_t startoff
;
82 xfs_fsblock_t blks
[1];
84 #define BLKENT_SIZE(n) \
85 (offsetof(blkent_t, blks) + (sizeof(xfs_fsblock_t) * (n)))
87 typedef struct blkmap
{
92 #define BLKMAP_SIZE(n) \
93 (offsetof(blkmap_t, ents) + (sizeof(blkent_t *) * (n)))
95 typedef struct freetab
{
98 xfs_dir2_data_off_t ents
[1];
100 #define FREETAB_SIZE(n) \
101 (offsetof(freetab_t, ents) + (sizeof(xfs_dir2_data_off_t) * (n)))
103 typedef struct dirhash
{
104 struct dirhash
*next
;
109 #define DIR_HASH_SIZE 1024
110 #define DIR_HASH_FUNC(h,a) (((h) ^ (a)) % DIR_HASH_SIZE)
112 static xfs_extlen_t agffreeblks
;
113 static xfs_extlen_t agflongest
;
114 static __uint64_t agf_aggr_freeblks
; /* aggregate count over all */
115 static __uint32_t agfbtreeblks
;
116 static int lazycount
;
117 static xfs_agino_t agicount
;
118 static xfs_agino_t agifreecount
;
119 static xfs_fsblock_t
*blist
;
120 static int blist_size
;
121 static char **dbmap
; /* really dbm_t:8 */
122 static dirhash_t
**dirhash
;
124 static __uint64_t fdblocks
;
125 static __uint64_t frextents
;
126 static __uint64_t icount
;
127 static __uint64_t ifree
;
128 static inodata_t
***inodata
;
129 static int inodata_hash_size
;
130 static inodata_t
***inomap
;
134 static qdata_t
**qpdata
;
136 static qdata_t
**qudata
;
138 static qdata_t
**qgdata
;
140 static unsigned sbversion
;
141 static int sbver_err
;
142 static int serious_error
;
144 static xfs_suminfo_t
*sumcompute
;
145 static xfs_suminfo_t
*sumfile
;
146 static const char *typename
[] = {
176 #define CHECK_BLIST(b) (blist_size && check_blist(b))
177 #define CHECK_BLISTA(a,b) \
178 (blist_size && check_blist(XFS_AGB_TO_FSB(mp, a, b)))
180 typedef void (*scan_lbtree_f_t
)(struct xfs_btree_block
*block
,
192 typedef void (*scan_sbtree_f_t
)(struct xfs_btree_block
*block
,
198 static void add_blist(xfs_fsblock_t bno
);
199 static void add_ilist(xfs_ino_t ino
);
200 static void addlink_inode(inodata_t
*id
);
201 static void addname_inode(inodata_t
*id
, char *name
, int namelen
);
202 static void addparent_inode(inodata_t
*id
, xfs_ino_t parent
);
203 static void blkent_append(blkent_t
**entp
, xfs_fsblock_t b
,
205 static blkent_t
*blkent_new(xfs_fileoff_t o
, xfs_fsblock_t b
,
207 static void blkent_prepend(blkent_t
**entp
, xfs_fsblock_t b
,
209 static blkmap_t
*blkmap_alloc(xfs_extnum_t
);
210 static void blkmap_free(blkmap_t
*blkmap
);
211 static xfs_fsblock_t
blkmap_get(blkmap_t
*blkmap
, xfs_fileoff_t o
);
212 static int blkmap_getn(blkmap_t
*blkmap
, xfs_fileoff_t o
, int nb
,
214 static void blkmap_grow(blkmap_t
**blkmapp
, blkent_t
**entp
,
216 static xfs_fileoff_t
blkmap_next_off(blkmap_t
*blkmap
, xfs_fileoff_t o
,
218 static void blkmap_set_blk(blkmap_t
**blkmapp
, xfs_fileoff_t o
,
220 static void blkmap_set_ext(blkmap_t
**blkmapp
, xfs_fileoff_t o
,
221 xfs_fsblock_t b
, xfs_extlen_t c
);
222 static void blkmap_shrink(blkmap_t
*blkmap
, blkent_t
**entp
);
223 static int blockfree_f(int argc
, char **argv
);
224 static int blockget_f(int argc
, char **argv
);
225 static int blocktrash_f(int argc
, char **argv
);
226 static int blockuse_f(int argc
, char **argv
);
227 static int check_blist(xfs_fsblock_t bno
);
228 static void check_dbmap(xfs_agnumber_t agno
, xfs_agblock_t agbno
,
229 xfs_extlen_t len
, dbm_t type
);
230 static int check_inomap(xfs_agnumber_t agno
, xfs_agblock_t agbno
,
231 xfs_extlen_t len
, xfs_ino_t c_ino
);
232 static void check_linkcounts(xfs_agnumber_t agno
);
233 static int check_range(xfs_agnumber_t agno
, xfs_agblock_t agbno
,
235 static void check_rdbmap(xfs_drfsbno_t bno
, xfs_extlen_t len
,
237 static int check_rinomap(xfs_drfsbno_t bno
, xfs_extlen_t len
,
239 static void check_rootdir(void);
240 static int check_rrange(xfs_drfsbno_t bno
, xfs_extlen_t len
);
241 static void check_set_dbmap(xfs_agnumber_t agno
,
242 xfs_agblock_t agbno
, xfs_extlen_t len
,
243 dbm_t type1
, dbm_t type2
,
244 xfs_agnumber_t c_agno
,
245 xfs_agblock_t c_agbno
);
246 static void check_set_rdbmap(xfs_drfsbno_t bno
, xfs_extlen_t len
,
247 dbm_t type1
, dbm_t type2
);
248 static void check_summary(void);
249 static void checknot_dbmap(xfs_agnumber_t agno
, xfs_agblock_t agbno
,
250 xfs_extlen_t len
, int typemask
);
251 static void checknot_rdbmap(xfs_drfsbno_t bno
, xfs_extlen_t len
,
253 static void dir_hash_add(xfs_dahash_t hash
,
254 xfs_dir2_dataptr_t addr
);
255 static void dir_hash_check(inodata_t
*id
, int v
);
256 static void dir_hash_done(void);
257 static void dir_hash_init(void);
258 static int dir_hash_see(xfs_dahash_t hash
,
259 xfs_dir2_dataptr_t addr
);
260 static inodata_t
*find_inode(xfs_ino_t ino
, int add
);
261 static void free_inodata(xfs_agnumber_t agno
);
262 static int init(int argc
, char **argv
);
263 static char *inode_name(xfs_ino_t ino
, inodata_t
**ipp
);
264 static int ncheck_f(int argc
, char **argv
);
265 static char *prepend_path(char *oldpath
, char *parent
);
266 static xfs_ino_t
process_block_dir_v2(blkmap_t
*blkmap
, int *dot
,
267 int *dotdot
, inodata_t
*id
);
268 static void process_bmbt_reclist(xfs_bmbt_rec_t
*rp
, int numrecs
,
269 dbm_t type
, inodata_t
*id
,
272 static void process_btinode(inodata_t
*id
, xfs_dinode_t
*dip
,
273 dbm_t type
, xfs_drfsbno_t
*totd
,
274 xfs_drfsbno_t
*toti
, xfs_extnum_t
*nex
,
275 blkmap_t
**blkmapp
, int whichfork
);
276 static xfs_ino_t
process_data_dir_v2(int *dot
, int *dotdot
,
277 inodata_t
*id
, int v
,
279 freetab_t
**freetabp
);
280 static xfs_dir2_data_free_t
281 *process_data_dir_v2_freefind(xfs_dir2_data_t
*data
,
282 xfs_dir2_data_unused_t
*dup
);
283 static void process_dir(xfs_dinode_t
*dip
, blkmap_t
*blkmap
,
285 static int process_dir_v1(xfs_dinode_t
*dip
, blkmap_t
*blkmap
,
286 int *dot
, int *dotdot
, inodata_t
*id
,
288 static int process_dir_v2(xfs_dinode_t
*dip
, blkmap_t
*blkmap
,
289 int *dot
, int *dotdot
, inodata_t
*id
,
291 static void process_exinode(inodata_t
*id
, xfs_dinode_t
*dip
,
292 dbm_t type
, xfs_drfsbno_t
*totd
,
293 xfs_drfsbno_t
*toti
, xfs_extnum_t
*nex
,
294 blkmap_t
**blkmapp
, int whichfork
);
295 static void process_inode(xfs_agf_t
*agf
, xfs_agino_t agino
,
296 xfs_dinode_t
*dip
, int isfree
);
297 static void process_lclinode(inodata_t
*id
, xfs_dinode_t
*dip
,
298 dbm_t type
, xfs_drfsbno_t
*totd
,
299 xfs_drfsbno_t
*toti
, xfs_extnum_t
*nex
,
300 blkmap_t
**blkmapp
, int whichfork
);
301 static xfs_ino_t
process_leaf_dir_v1(blkmap_t
*blkmap
, int *dot
,
302 int *dotdot
, inodata_t
*id
);
303 static xfs_ino_t
process_leaf_dir_v1_int(int *dot
, int *dotdot
,
305 static xfs_ino_t
process_leaf_node_dir_v2(blkmap_t
*blkmap
, int *dot
,
306 int *dotdot
, inodata_t
*id
,
307 xfs_fsize_t dirsize
);
308 static void process_leaf_node_dir_v2_free(inodata_t
*id
, int v
,
311 static void process_leaf_node_dir_v2_int(inodata_t
*id
, int v
,
314 static xfs_ino_t
process_node_dir_v1(blkmap_t
*blkmap
, int *dot
,
315 int *dotdot
, inodata_t
*id
);
316 static void process_quota(qtype_t qtype
, inodata_t
*id
,
318 static void process_rtbitmap(blkmap_t
*blkmap
);
319 static void process_rtsummary(blkmap_t
*blkmap
);
320 static xfs_ino_t
process_sf_dir_v2(xfs_dinode_t
*dip
, int *dot
,
321 int *dotdot
, inodata_t
*id
);
322 static xfs_ino_t
process_shortform_dir_v1(xfs_dinode_t
*dip
, int *dot
,
323 int *dotdot
, inodata_t
*id
);
324 static void quota_add(xfs_dqid_t
*p
, xfs_dqid_t
*g
, xfs_dqid_t
*u
,
325 int dq
, xfs_qcnt_t bc
, xfs_qcnt_t ic
,
327 static void quota_add1(qdata_t
**qt
, xfs_dqid_t id
, int dq
,
328 xfs_qcnt_t bc
, xfs_qcnt_t ic
,
330 static void quota_check(char *s
, qdata_t
**qt
);
331 static void quota_init(void);
332 static void scan_ag(xfs_agnumber_t agno
);
333 static void scan_freelist(xfs_agf_t
*agf
);
334 static void scan_lbtree(xfs_fsblock_t root
, int nlevels
,
335 scan_lbtree_f_t func
, dbm_t type
,
336 inodata_t
*id
, xfs_drfsbno_t
*totd
,
337 xfs_drfsbno_t
*toti
, xfs_extnum_t
*nex
,
338 blkmap_t
**blkmapp
, int isroot
,
340 static void scan_sbtree(xfs_agf_t
*agf
, xfs_agblock_t root
,
341 int nlevels
, int isroot
,
342 scan_sbtree_f_t func
, typnm_t btype
);
343 static void scanfunc_bmap(struct xfs_btree_block
*block
,
344 int level
, dbm_t type
, xfs_fsblock_t bno
,
345 inodata_t
*id
, xfs_drfsbno_t
*totd
,
346 xfs_drfsbno_t
*toti
, xfs_extnum_t
*nex
,
347 blkmap_t
**blkmapp
, int isroot
,
349 static void scanfunc_bno(struct xfs_btree_block
*block
, int level
,
350 xfs_agf_t
*agf
, xfs_agblock_t bno
,
352 static void scanfunc_cnt(struct xfs_btree_block
*block
, int level
,
353 xfs_agf_t
*agf
, xfs_agblock_t bno
,
355 static void scanfunc_ino(struct xfs_btree_block
*block
, int level
,
356 xfs_agf_t
*agf
, xfs_agblock_t bno
,
358 static void set_dbmap(xfs_agnumber_t agno
, xfs_agblock_t agbno
,
359 xfs_extlen_t len
, dbm_t type
,
360 xfs_agnumber_t c_agno
, xfs_agblock_t c_agbno
);
361 static void set_inomap(xfs_agnumber_t agno
, xfs_agblock_t agbno
,
362 xfs_extlen_t len
, inodata_t
*id
);
363 static void set_rdbmap(xfs_drfsbno_t bno
, xfs_extlen_t len
,
365 static void set_rinomap(xfs_drfsbno_t bno
, xfs_extlen_t len
,
367 static void setlink_inode(inodata_t
*id
, nlink_t nlink
, int isdir
,
370 static const cmdinfo_t blockfree_cmd
=
371 { "blockfree", NULL
, blockfree_f
, 0, 0, 0,
372 NULL
, N_("free block usage information"), NULL
};
373 static const cmdinfo_t blockget_cmd
=
374 { "blockget", "check", blockget_f
, 0, -1, 0,
375 N_("[-s|-v] [-n] [-t] [-b bno]... [-i ino] ..."),
376 N_("get block usage and check consistency"), NULL
};
377 static const cmdinfo_t blocktrash_cmd
=
378 { "blocktrash", NULL
, blocktrash_f
, 0, -1, 0,
379 N_("[-n count] [-x minlen] [-y maxlen] [-s seed] [-0123] [-t type] ..."),
380 N_("trash randomly selected block(s)"), NULL
};
381 static const cmdinfo_t blockuse_cmd
=
382 { "blockuse", NULL
, blockuse_f
, 0, 3, 0,
383 N_("[-n] [-c blockcount]"),
384 N_("print usage for current block(s)"), NULL
};
385 static const cmdinfo_t ncheck_cmd
=
386 { "ncheck", NULL
, ncheck_f
, 0, -1, 0,
387 N_("[-s] [-i ino] ..."),
388 N_("print inode-name pairs"), NULL
};
396 blist
= xrealloc(blist
, blist_size
* sizeof(bno
));
397 blist
[blist_size
- 1] = bno
;
406 id
= find_inode(ino
, 1);
408 dbprintf(_("-i %lld bad inode number\n"), ino
);
419 if (verbose
|| id
->ilist
)
420 dbprintf(_("inode %lld add link, now %u\n"), id
->ino
,
430 if (!nflag
|| id
->name
)
432 id
->name
= xmalloc(namelen
+ 1);
433 memcpy(id
->name
, name
, namelen
);
434 id
->name
[namelen
] = '\0';
444 pid
= find_inode(parent
, 1);
446 if (verbose
|| id
->ilist
|| (pid
&& pid
->ilist
))
447 dbprintf(_("inode %lld parent %lld\n"), id
->ino
, parent
);
460 *entp
= ent
= xrealloc(ent
, BLKENT_SIZE(c
+ ent
->nblks
));
461 for (i
= 0; i
< c
; i
++)
462 ent
->blks
[ent
->nblks
+ i
] = b
+ i
;
475 ent
= xmalloc(BLKENT_SIZE(c
));
478 for (i
= 0; i
< c
; i
++)
479 ent
->blks
[i
] = b
+ i
;
494 newent
= xmalloc(BLKENT_SIZE(oldent
->nblks
+ c
));
495 newent
->nblks
= oldent
->nblks
+ c
;
496 newent
->startoff
= oldent
->startoff
- c
;
497 for (i
= 0; i
< c
; i
++)
498 newent
->blks
[i
] = b
+ c
;
499 for (; i
< oldent
->nblks
+ c
; i
++)
500 newent
->blks
[i
] = oldent
->blks
[i
- c
];
513 blkmap
= xmalloc(BLKMAP_SIZE(nex
));
514 blkmap
->naents
= nex
;
526 for (i
= 0, entp
= blkmap
->ents
; i
< blkmap
->nents
; i
++, entp
++)
540 for (i
= 0, entp
= blkmap
->ents
; i
< blkmap
->nents
; i
++, entp
++) {
542 if (o
>= ent
->startoff
&& o
< ent
->startoff
+ ent
->nblks
)
543 return ent
->blks
[o
- ent
->startoff
];
562 for (i
= nex
= 0, bmp
= NULL
, entp
= blkmap
->ents
;
566 if (ent
->startoff
>= o
+ nb
)
568 if (ent
->startoff
+ ent
->nblks
<= o
)
570 for (ento
= ent
->startoff
;
571 ento
< ent
->startoff
+ ent
->nblks
&& ento
< o
+ nb
;
576 bmp
[nex
- 1].startoff
+ bmp
[nex
- 1].blockcount
==
578 bmp
[nex
- 1].startblock
+ bmp
[nex
- 1].blockcount
==
579 ent
->blks
[ento
- ent
->startoff
])
580 bmp
[nex
- 1].blockcount
++;
582 bmp
= realloc(bmp
, ++nex
* sizeof(*bmp
));
583 bmp
[nex
- 1].startoff
= ento
;
584 bmp
[nex
- 1].startblock
=
585 ent
->blks
[ento
- ent
->startoff
];
586 bmp
[nex
- 1].blockcount
= 1;
587 bmp
[nex
- 1].flag
= 0;
606 idx
= (int)(entp
- blkmap
->ents
);
607 if (blkmap
->naents
== blkmap
->nents
) {
608 blkmap
= xrealloc(blkmap
, BLKMAP_SIZE(blkmap
->nents
+ 1));
612 for (i
= blkmap
->nents
; i
> idx
; i
--)
613 blkmap
->ents
[i
] = blkmap
->ents
[i
- 1];
614 blkmap
->ents
[idx
] = newent
;
626 ent
= blkmap
->ents
[blkmap
->nents
- 1];
627 return ent
->startoff
+ ent
->nblks
;
641 if (o
== NULLFILEOFF
) {
643 ent
= blkmap
->ents
[0];
644 return ent
->startoff
;
646 entp
= &blkmap
->ents
[*t
];
648 if (o
< ent
->startoff
+ ent
->nblks
- 1)
651 if (entp
>= &blkmap
->ents
[blkmap
->nents
])
655 return ent
->startoff
;
670 for (entp
= blkmap
->ents
; entp
< &blkmap
->ents
[blkmap
->nents
]; entp
++) {
672 if (o
< ent
->startoff
- 1) {
673 ent
= blkent_new(o
, b
, 1);
674 blkmap_grow(blkmapp
, entp
, ent
);
677 if (o
== ent
->startoff
- 1) {
678 blkent_prepend(entp
, b
, 1);
681 if (o
>= ent
->startoff
&& o
< ent
->startoff
+ ent
->nblks
) {
682 ent
->blks
[o
- ent
->startoff
] = b
;
685 if (o
> ent
->startoff
+ ent
->nblks
)
687 blkent_append(entp
, b
, 1);
688 if (entp
== &blkmap
->ents
[blkmap
->nents
- 1])
692 if (ent
->startoff
+ ent
->nblks
< nextent
->startoff
)
694 blkent_append(entp
, nextent
->blks
[0], nextent
->nblks
);
695 blkmap_shrink(blkmap
, &entp
[1]);
698 ent
= blkent_new(o
, b
, 1);
699 blkmap_grow(blkmapp
, entp
, ent
);
715 if (!blkmap
->nents
) {
716 blkmap
->ents
[0] = blkent_new(o
, b
, c
);
720 entp
= &blkmap
->ents
[blkmap
->nents
- 1];
722 if (ent
->startoff
+ ent
->nblks
== o
) {
723 blkent_append(entp
, b
, c
);
726 if (ent
->startoff
+ ent
->nblks
< o
) {
727 ent
= blkent_new(o
, b
, c
);
728 blkmap_grow(blkmapp
, &blkmap
->ents
[blkmap
->nents
], ent
);
731 for (i
= 0; i
< c
; i
++)
732 blkmap_set_blk(blkmapp
, o
+ i
, b
+ i
);
744 idx
= (int)(entp
- blkmap
->ents
);
745 for (i
= idx
+ 1; i
< blkmap
->nents
; i
++)
746 blkmap
->ents
[i
] = blkmap
->ents
[i
- 1];
760 dbprintf(_("block usage information not allocated\n"));
763 rt
= mp
->m_sb
.sb_rextents
!= 0;
764 for (c
= 0; c
< mp
->m_sb
.sb_agcount
; c
++) {
774 sumcompute
= sumfile
= NULL
;
786 * Check consistency of xfs filesystem contents.
798 dbprintf(_("already have block usage information\n"));
801 if (!init(argc
, argv
)) {
808 oldprefix
= dbprefix
;
810 for (agno
= 0, sbyell
= 0; agno
< mp
->m_sb
.sb_agcount
; agno
++) {
812 if (sbver_err
> 4 && !sbyell
&& sbver_err
>= agno
) {
814 dbprintf(_("WARNING: this may be a newer XFS "
825 dbprefix
= oldprefix
;
830 * Check that there are no blocks either
831 * a) unaccounted for or
832 * b) bno-free but not cnt-free
834 if (!tflag
) { /* are we in test mode, faking out freespace? */
835 for (agno
= 0; agno
< mp
->m_sb
.sb_agcount
; agno
++)
836 checknot_dbmap(agno
, 0, mp
->m_sb
.sb_agblocks
,
837 (1 << DBM_UNKNOWN
) | (1 << DBM_FREE1
));
839 for (agno
= 0; agno
< mp
->m_sb
.sb_agcount
; agno
++)
840 check_linkcounts(agno
);
841 if (mp
->m_sb
.sb_rblocks
) {
843 (xfs_extlen_t
)(mp
->m_sb
.sb_rextents
*
844 mp
->m_sb
.sb_rextsize
),
848 if (mp
->m_sb
.sb_icount
!= icount
) {
850 dbprintf(_("sb_icount %lld, counted %lld\n"),
851 mp
->m_sb
.sb_icount
, icount
);
854 if (mp
->m_sb
.sb_ifree
!= ifree
) {
856 dbprintf(_("sb_ifree %lld, counted %lld\n"),
857 mp
->m_sb
.sb_ifree
, ifree
);
860 if (mp
->m_sb
.sb_fdblocks
!= fdblocks
) {
862 dbprintf(_("sb_fdblocks %lld, counted %lld\n"),
863 mp
->m_sb
.sb_fdblocks
, fdblocks
);
866 if (lazycount
&& mp
->m_sb
.sb_fdblocks
!= agf_aggr_freeblks
) {
868 dbprintf(_("sb_fdblocks %lld, aggregate AGF count %lld\n"),
869 mp
->m_sb
.sb_fdblocks
, agf_aggr_freeblks
);
872 if (mp
->m_sb
.sb_frextents
!= frextents
) {
874 dbprintf(_("sb_frextents %lld, counted %lld\n"),
875 mp
->m_sb
.sb_frextents
, frextents
);
878 if (mp
->m_sb
.sb_bad_features2
!= 0 &&
879 mp
->m_sb
.sb_bad_features2
!= mp
->m_sb
.sb_features2
) {
881 dbprintf(_("sb_features2 (0x%x) not same as "
882 "sb_bad_features2 (0x%x)\n"),
883 mp
->m_sb
.sb_features2
,
884 mp
->m_sb
.sb_bad_features2
);
887 if ((sbversion
& XFS_SB_VERSION_ATTRBIT
) &&
888 !xfs_sb_version_hasattr(&mp
->m_sb
)) {
890 dbprintf(_("sb versionnum missing attr bit %x\n"),
891 XFS_SB_VERSION_ATTRBIT
);
894 if ((sbversion
& XFS_SB_VERSION_NLINKBIT
) &&
895 !xfs_sb_version_hasnlink(&mp
->m_sb
)) {
897 dbprintf(_("sb versionnum missing nlink bit %x\n"),
898 XFS_SB_VERSION_NLINKBIT
);
901 if ((sbversion
& XFS_SB_VERSION_QUOTABIT
) &&
902 !xfs_sb_version_hasquota(&mp
->m_sb
)) {
904 dbprintf(_("sb versionnum missing quota bit %x\n"),
905 XFS_SB_VERSION_QUOTABIT
);
908 if (!(sbversion
& XFS_SB_VERSION_ALIGNBIT
) &&
909 xfs_sb_version_hasalign(&mp
->m_sb
)) {
911 dbprintf(_("sb versionnum extra align bit %x\n"),
912 XFS_SB_VERSION_ALIGNBIT
);
916 quota_check("user", qudata
);
918 quota_check("project", qpdata
);
920 quota_check("group", qgdata
);
921 if (sbver_err
> mp
->m_sb
.sb_agcount
/ 2)
922 dbprintf(_("WARNING: this may be a newer XFS filesystem.\n"));
925 dbprefix
= oldprefix
;
929 typedef struct ltab
{
950 static char *modestr
[] = {
951 N_("zeroed"), N_("set"), N_("flipped"), N_("randomized")
954 len
= (int)((random() % (ltabp
->max
- ltabp
->min
+ 1)) + ltabp
->min
);
955 offset
= (int)(random() % (int)(mp
->m_sb
.sb_blocksize
* NBBY
));
958 set_cur(&typtab
[DBM_UNKNOWN
],
959 XFS_AGB_TO_DADDR(mp
, agno
, agbno
), blkbb
, DB_RING_IGN
, NULL
);
960 if ((buf
= iocur_top
->data
) == NULL
) {
961 dbprintf(_("can't read block %u/%u for trashing\n"), agno
, agbno
);
965 for (bitno
= 0; bitno
< len
; bitno
++) {
966 bit
= (offset
+ bitno
) % (mp
->m_sb
.sb_blocksize
* NBBY
);
978 newbit
= (buf
[byte
] & mask
) == 0;
981 newbit
= (int)random() & 1;
991 printf(_("blocktrash: %u/%u %s block %d bit%s starting %d:%d %s\n"),
992 agno
, agbno
, typename
[type
], len
, len
== 1 ? "" : "s",
993 offset
/ NBBY
, offset
% NBBY
, modestr
[mode
]);
1001 xfs_agblock_t agbno
;
1002 xfs_agnumber_t agno
;
1004 xfs_drfsbno_t blocks
;
1017 xfs_drfsbno_t randb
;
1023 dbprintf(_("must run blockget first\n"));
1031 gettimeofday(&now
, NULL
);
1032 seed
= (unsigned int)(now
.tv_sec
^ now
.tv_usec
);
1035 goodmask
= (1 << DBM_AGF
) |
1039 (1 << DBM_BTBMAPA
) |
1040 (1 << DBM_BTBMAPD
) |
1047 (1 << DBM_RTBITMAP
) |
1050 while ((c
= getopt(argc
, argv
, "0123n:s:t:x:y:")) != EOF
) {
1065 count
= (int)strtol(optarg
, &p
, 0);
1066 if (*p
!= '\0' || count
<= 0) {
1067 dbprintf(_("bad blocktrash count %s\n"), optarg
);
1072 seed
= (uint
)strtoul(optarg
, &p
, 0);
1076 for (i
= 0; typename
[i
]; i
++) {
1077 if (strcmp(typename
[i
], optarg
) == 0)
1080 if (!typename
[i
] || (((1 << i
) & goodmask
) == 0)) {
1081 dbprintf(_("bad blocktrash type %s\n"), optarg
);
1087 min
= (int)strtol(optarg
, &p
, 0);
1088 if (*p
!= '\0' || min
<= 0 ||
1089 min
> mp
->m_sb
.sb_blocksize
* NBBY
) {
1090 dbprintf(_("bad blocktrash min %s\n"), optarg
);
1095 max
= (int)strtol(optarg
, &p
, 0);
1096 if (*p
!= '\0' || max
<= 0 ||
1097 max
> mp
->m_sb
.sb_blocksize
* NBBY
) {
1098 dbprintf(_("bad blocktrash max %s\n"), optarg
);
1103 dbprintf(_("bad option for blocktrash command\n"));
1108 dbprintf(_("bad min/max for blocktrash command\n"));
1113 lentab
= xmalloc(sizeof(ltab_t
));
1114 lentab
->min
= lentab
->max
= min
;
1116 for (i
= min
+ 1; i
<= max
; i
++) {
1117 if ((i
& (i
- 1)) == 0) {
1118 lentab
= xrealloc(lentab
,
1119 sizeof(ltab_t
) * (lentablen
+ 1));
1120 lentab
[lentablen
].min
= lentab
[lentablen
].max
= i
;
1123 lentab
[lentablen
- 1].max
= i
;
1125 for (blocks
= 0, agno
= 0; agno
< mp
->m_sb
.sb_agcount
; agno
++) {
1126 for (agbno
= 0, p
= dbmap
[agno
];
1127 agbno
< mp
->m_sb
.sb_agblocks
;
1129 if ((1 << *p
) & tmask
)
1134 dbprintf(_("blocktrash: no matching blocks\n"));
1138 dbprintf(_("blocktrash: seed %u\n"), seed
);
1140 for (i
= 0; i
< count
; i
++) {
1141 randb
= (xfs_drfsbno_t
)((((__int64_t
)random() << 32) |
1142 random()) % blocks
);
1143 for (bi
= 0, agno
= 0, done
= 0;
1144 !done
&& agno
< mp
->m_sb
.sb_agcount
;
1146 for (agbno
= 0, p
= dbmap
[agno
];
1147 agbno
< mp
->m_sb
.sb_agblocks
;
1149 if (!((1 << *p
) & tmask
))
1153 blocktrash_b(agno
, agbno
, (dbm_t
)*p
,
1154 &lentab
[random() % lentablen
], mode
);
1169 xfs_agblock_t agbno
;
1170 xfs_agnumber_t agno
;
1180 dbprintf(_("must run blockget first\n"));
1186 fsb
= XFS_DADDR_TO_FSB(mp
, iocur_top
->off
>> BBSHIFT
);
1187 agno
= XFS_FSB_TO_AGNO(mp
, fsb
);
1188 end
= agbno
= XFS_FSB_TO_AGBNO(mp
, fsb
);
1189 while ((c
= getopt(argc
, argv
, "c:n")) != EOF
) {
1192 count
= (int)strtol(optarg
, &p
, 0);
1193 end
= agbno
+ count
- 1;
1194 if (*p
!= '\0' || count
<= 0 ||
1195 end
>= mp
->m_sb
.sb_agblocks
) {
1196 dbprintf(_("bad blockuse count %s\n"), optarg
);
1202 dbprintf(_("must run blockget -n first\n"));
1208 dbprintf(_("bad option for blockuse command\n"));
1212 while (agbno
<= end
) {
1213 p
= &dbmap
[agno
][agbno
];
1214 i
= inomap
[agno
][agbno
];
1215 dbprintf(_("block %llu (%u/%u) type %s"),
1216 (xfs_dfsbno_t
)XFS_AGB_TO_FSB(mp
, agno
, agbno
),
1217 agno
, agbno
, typename
[(dbm_t
)*p
]);
1219 dbprintf(_(" inode %lld"), i
->ino
);
1220 if (shownames
&& (p
= inode_name(i
->ino
, NULL
))) {
1237 for (i
= 0; i
< blist_size
; i
++) {
1238 if (blist
[i
] == bno
)
1246 xfs_agnumber_t agno
,
1247 xfs_agblock_t agbno
,
1254 for (i
= 0, p
= &dbmap
[agno
][agbno
]; i
< len
; i
++, p
++) {
1255 if ((dbm_t
)*p
!= type
) {
1256 if (!sflag
|| CHECK_BLISTA(agno
, agbno
+ i
))
1257 dbprintf(_("block %u/%u expected type %s got "
1259 agno
, agbno
+ i
, typename
[type
],
1260 typename
[(dbm_t
)*p
]);
1269 add_command(&blockfree_cmd
);
1270 add_command(&blockget_cmd
);
1272 add_command(&blocktrash_cmd
);
1273 add_command(&blockuse_cmd
);
1274 add_command(&ncheck_cmd
);
1279 xfs_agnumber_t agno
,
1280 xfs_agblock_t agbno
,
1288 if (!check_range(agno
, agbno
, len
)) {
1289 dbprintf(_("blocks %u/%u..%u claimed by inode %lld\n"),
1290 agno
, agbno
, agbno
+ len
- 1, c_ino
);
1293 for (i
= 0, rval
= 1, idp
= &inomap
[agno
][agbno
]; i
< len
; i
++, idp
++) {
1295 if (!sflag
|| (*idp
)->ilist
||
1296 CHECK_BLISTA(agno
, agbno
+ i
))
1297 dbprintf(_("block %u/%u claimed by inode %lld, "
1298 "previous inum %lld\n"),
1299 agno
, agbno
+ i
, c_ino
, (*idp
)->ino
);
1309 xfs_agnumber_t agno
)
1317 for (idx
= 0; idx
< inodata_hash_size
; ht
++, idx
++) {
1320 if (ep
->link_set
!= ep
->link_add
|| ep
->link_set
== 0) {
1321 path
= inode_name(ep
->ino
, NULL
);
1322 if (!path
&& ep
->link_add
)
1323 path
= xstrdup("?");
1324 if (!sflag
|| ep
->ilist
) {
1326 dbprintf(_("link count mismatch "
1327 "for inode %lld (name "
1333 else if (ep
->link_set
)
1334 dbprintf(_("disconnected inode "
1335 "%lld, nlink %d\n"),
1336 ep
->ino
, ep
->link_set
);
1338 dbprintf(_("allocated inode %lld "
1339 "has 0 link count\n"),
1345 } else if (verbose
|| ep
->ilist
) {
1346 path
= inode_name(ep
->ino
, NULL
);
1348 dbprintf(_("inode %lld name %s\n"),
1361 xfs_agnumber_t agno
,
1362 xfs_agblock_t agbno
,
1366 xfs_agblock_t low
= 0;
1367 xfs_agblock_t high
= 0;
1368 int valid_range
= 0;
1371 if (agno
>= mp
->m_sb
.sb_agcount
||
1372 agbno
+ len
- 1 >= mp
->m_sb
.sb_agblocks
) {
1373 for (i
= 0; i
< len
; i
++) {
1374 cur
= !sflag
|| CHECK_BLISTA(agno
, agbno
+ i
) ? 1 : 0;
1375 if (cur
== 1 && prev
== 0) {
1376 low
= high
= agbno
+ i
;
1378 } else if (cur
== 0 && prev
== 0) {
1380 } else if (cur
== 0 && prev
== 1) {
1382 dbprintf(_("block %u/%u out of range\n"),
1385 dbprintf(_("blocks %u/%u..%u "
1390 } else if (cur
== 1 && prev
== 1) {
1397 dbprintf(_("block %u/%u out of range\n"),
1400 dbprintf(_("blocks %u/%u..%u "
1420 for (i
= 0, p
= &dbmap
[mp
->m_sb
.sb_agcount
][bno
]; i
< len
; i
++, p
++) {
1421 if ((dbm_t
)*p
!= type
) {
1422 if (!sflag
|| CHECK_BLIST(bno
+ i
))
1423 dbprintf(_("rtblock %llu expected type %s got "
1425 bno
+ i
, typename
[type
],
1426 typename
[(dbm_t
)*p
]);
1442 if (!check_rrange(bno
, len
)) {
1443 dbprintf(_("rtblocks %llu..%llu claimed by inode %lld\n"),
1444 bno
, bno
+ len
- 1, c_ino
);
1447 for (i
= 0, rval
= 1, idp
= &inomap
[mp
->m_sb
.sb_agcount
][bno
];
1451 if (!sflag
|| (*idp
)->ilist
|| CHECK_BLIST(bno
+ i
))
1452 dbprintf(_("rtblock %llu claimed by inode %lld, "
1453 "previous inum %lld\n"),
1454 bno
+ i
, c_ino
, (*idp
)->ino
);
1467 id
= find_inode(mp
->m_sb
.sb_rootino
, 0);
1470 dbprintf(_("root inode %lld is missing\n"),
1471 mp
->m_sb
.sb_rootino
);
1473 } else if (!id
->isdir
) {
1474 if (!sflag
|| id
->ilist
)
1475 dbprintf(_("root inode %lld is not a directory\n"),
1476 mp
->m_sb
.sb_rootino
);
1488 if (bno
+ len
- 1 >= mp
->m_sb
.sb_rblocks
) {
1489 for (i
= 0; i
< len
; i
++) {
1490 if (!sflag
|| CHECK_BLIST(bno
+ i
))
1491 dbprintf(_("rtblock %llu out of range\n"),
1502 xfs_agnumber_t agno
,
1503 xfs_agblock_t agbno
,
1507 xfs_agnumber_t c_agno
,
1508 xfs_agblock_t c_agbno
)
1514 if (!check_range(agno
, agbno
, len
)) {
1515 dbprintf(_("blocks %u/%u..%u claimed by block %u/%u\n"), agno
,
1516 agbno
, agbno
+ len
- 1, c_agno
, c_agbno
);
1519 check_dbmap(agno
, agbno
, len
, type1
);
1520 mayprint
= verbose
| blist_size
;
1521 for (i
= 0, p
= &dbmap
[agno
][agbno
]; i
< len
; i
++, p
++) {
1523 if (mayprint
&& (verbose
|| CHECK_BLISTA(agno
, agbno
+ i
)))
1524 dbprintf(_("setting block %u/%u to %s\n"), agno
, agbno
+ i
,
1540 if (!check_rrange(bno
, len
))
1542 check_rdbmap(bno
, len
, type1
);
1543 mayprint
= verbose
| blist_size
;
1544 for (i
= 0, p
= &dbmap
[mp
->m_sb
.sb_agcount
][bno
]; i
< len
; i
++, p
++) {
1546 if (mayprint
&& (verbose
|| CHECK_BLIST(bno
+ i
)))
1547 dbprintf(_("setting rtblock %llu to %s\n"),
1548 bno
+ i
, typename
[type2
]);
1562 for (log
= 0; log
< mp
->m_rsumlevels
; log
++) {
1564 bno
< mp
->m_sb
.sb_rbmblocks
;
1565 bno
++, csp
++, fsp
++) {
1568 dbprintf(_("rt summary mismatch, size %d "
1569 "block %llu, file: %d, "
1571 log
, bno
, *fsp
, *csp
);
1580 xfs_agnumber_t agno
,
1581 xfs_agblock_t agbno
,
1588 if (!check_range(agno
, agbno
, len
))
1590 for (i
= 0, p
= &dbmap
[agno
][agbno
]; i
< len
; i
++, p
++) {
1591 if ((1 << *p
) & typemask
) {
1592 if (!sflag
|| CHECK_BLISTA(agno
, agbno
+ i
))
1593 dbprintf(_("block %u/%u type %s not expected\n"),
1594 agno
, agbno
+ i
, typename
[(dbm_t
)*p
]);
1609 if (!check_rrange(bno
, len
))
1611 for (i
= 0, p
= &dbmap
[mp
->m_sb
.sb_agcount
][bno
]; i
< len
; i
++, p
++) {
1612 if ((1 << *p
) & typemask
) {
1613 if (!sflag
|| CHECK_BLIST(bno
+ i
))
1614 dbprintf(_("rtblock %llu type %s not expected\n"),
1615 bno
+ i
, typename
[(dbm_t
)*p
]);
1624 xfs_dir2_dataptr_t addr
)
1629 i
= DIR_HASH_FUNC(hash
, addr
);
1630 p
= malloc(sizeof(*p
));
1631 p
->next
= dirhash
[i
];
1646 for (i
= 0; i
< DIR_HASH_SIZE
; i
++) {
1647 for (p
= dirhash
[i
]; p
; p
= p
->next
) {
1650 if (!sflag
|| id
->ilist
|| v
)
1651 dbprintf(_("dir ino %lld missing leaf entry for "
1653 id
->ino
, p
->hashval
, p
->address
);
1666 for (i
= 0; i
< DIR_HASH_SIZE
; i
++) {
1667 for (p
= dirhash
[i
]; p
; p
= n
) {
1679 dirhash
= calloc(DIR_HASH_SIZE
, sizeof(*dirhash
));
1685 xfs_dir2_dataptr_t addr
)
1690 i
= DIR_HASH_FUNC(hash
, addr
);
1691 for (p
= dirhash
[i
]; p
; p
= p
->next
) {
1692 if (p
->hashval
== hash
&& p
->address
== addr
) {
1708 xfs_agnumber_t agno
;
1713 agno
= XFS_INO_TO_AGNO(mp
, ino
);
1714 agino
= XFS_INO_TO_AGINO(mp
, ino
);
1715 if (agno
>= mp
->m_sb
.sb_agcount
||
1716 XFS_AGINO_TO_INO(mp
, agno
, agino
) != ino
)
1718 htab
= inodata
[agno
];
1719 ih
= agino
% inodata_hash_size
;
1722 if (ent
->ino
== ino
)
1728 ent
= xcalloc(1, sizeof(*ent
));
1730 ent
->next
= htab
[ih
];
1737 xfs_agnumber_t agno
)
1745 for (i
= 0; i
< inodata_hash_size
; i
++) {
1769 if (mp
->m_sb
.sb_magicnum
!= XFS_SB_MAGIC
) {
1770 dbprintf(_("bad superblock magic number %x, giving up\n"),
1771 mp
->m_sb
.sb_magicnum
);
1777 rt
= mp
->m_sb
.sb_rextents
!= 0;
1778 dbmap
= xmalloc((mp
->m_sb
.sb_agcount
+ rt
) * sizeof(*dbmap
));
1779 inomap
= xmalloc((mp
->m_sb
.sb_agcount
+ rt
) * sizeof(*inomap
));
1780 inodata
= xmalloc(mp
->m_sb
.sb_agcount
* sizeof(*inodata
));
1782 (int)MAX(MIN(mp
->m_sb
.sb_icount
/
1783 (INODATA_AVG_HASH_LENGTH
* mp
->m_sb
.sb_agcount
),
1784 MAX_INODATA_HASH_SIZE
),
1785 MIN_INODATA_HASH_SIZE
);
1786 for (c
= 0; c
< mp
->m_sb
.sb_agcount
; c
++) {
1787 dbmap
[c
] = xcalloc(mp
->m_sb
.sb_agblocks
, sizeof(**dbmap
));
1788 inomap
[c
] = xcalloc(mp
->m_sb
.sb_agblocks
, sizeof(**inomap
));
1789 inodata
[c
] = xcalloc(inodata_hash_size
, sizeof(**inodata
));
1792 dbmap
[c
] = xcalloc(mp
->m_sb
.sb_rblocks
, sizeof(**dbmap
));
1793 inomap
[c
] = xcalloc(mp
->m_sb
.sb_rblocks
, sizeof(**inomap
));
1794 sumfile
= xcalloc(mp
->m_rsumsize
, 1);
1795 sumcompute
= xcalloc(mp
->m_rsumsize
, 1);
1797 nflag
= sflag
= tflag
= verbose
= optind
= 0;
1798 while ((c
= getopt(argc
, argv
, "b:i:npstv")) != EOF
) {
1801 bno
= strtoll(optarg
, NULL
, 10);
1805 ino
= strtoll(optarg
, NULL
, 10);
1824 dbprintf(_("bad option for blockget command\n"));
1828 error
= sbver_err
= serious_error
= 0;
1829 fdblocks
= frextents
= icount
= ifree
= 0;
1830 sbversion
= XFS_SB_VERSION_4
;
1831 if (mp
->m_sb
.sb_inoalignmt
)
1832 sbversion
|= XFS_SB_VERSION_ALIGNBIT
;
1833 if ((mp
->m_sb
.sb_uquotino
&& mp
->m_sb
.sb_uquotino
!= NULLFSINO
) ||
1834 (mp
->m_sb
.sb_gquotino
&& mp
->m_sb
.sb_gquotino
!= NULLFSINO
))
1835 sbversion
|= XFS_SB_VERSION_QUOTABIT
;
1849 id
= find_inode(ino
, 0);
1854 if (id
->name
== NULL
)
1856 path
= xstrdup(id
->name
);
1857 while (id
->parent
) {
1859 if (id
->name
== NULL
)
1861 npath
= prepend_path(path
, id
->name
);
1873 xfs_agnumber_t agno
;
1886 if (!inodata
|| !nflag
) {
1887 dbprintf(_("must run blockget -n first\n"));
1890 security
= optind
= ilist_size
= 0;
1892 while ((c
= getopt(argc
, argv
, "i:s")) != EOF
) {
1895 ino
= strtoll(optarg
, NULL
, 10);
1896 ilist
= xrealloc(ilist
, (ilist_size
+ 1) *
1898 ilist
[ilist_size
++] = ino
;
1904 dbprintf(_("bad option -%c for ncheck command\n"), c
);
1909 for (ilp
= ilist
; ilp
< &ilist
[ilist_size
]; ilp
++) {
1911 if ((p
= inode_name(ino
, &hp
))) {
1912 dbprintf("%11llu %s", ino
, p
);
1922 for (agno
= 0; agno
< mp
->m_sb
.sb_agcount
; agno
++) {
1924 for (i
= 0; i
< inodata_hash_size
; i
++) {
1926 for (hp
= ht
[i
]; hp
; hp
= hp
->next
) {
1927 ino
= XFS_AGINO_TO_INO(mp
, agno
, hp
->ino
);
1928 p
= inode_name(ino
, &id
);
1931 if (!security
|| id
->security
) {
1932 dbprintf("%11llu %s", ino
, p
);
1952 len
= (int)(strlen(oldpath
) + strlen(parent
) + 2);
1953 path
= xmalloc(len
);
1954 snprintf(path
, len
, "%s/%s", parent
, oldpath
);
1959 process_block_dir_v2(
1973 nex
= blkmap_getn(blkmap
, 0, mp
->m_dirblkfsbs
, &bmp
);
1974 v
= id
->ilist
|| verbose
;
1977 dbprintf(_("block 0 for directory inode %lld is "
1985 make_bbmap(&bbmap
, nex
, bmp
);
1986 set_cur(&typtab
[TYP_DIR
], XFS_FSB_TO_DADDR(mp
, bmp
->startblock
),
1987 mp
->m_dirblkfsbs
* blkbb
, DB_RING_IGN
, nex
> 1 ? &bbmap
: NULL
);
1988 for (x
= 0; !v
&& x
< nex
; x
++) {
1989 for (b
= bmp
[x
].startblock
;
1990 !v
&& b
< bmp
[x
].startblock
+ bmp
[x
].blockcount
;
1995 if (iocur_top
->data
== NULL
) {
1996 if (!sflag
|| id
->ilist
|| v
)
1997 dbprintf(_("can't read block 0 for directory inode "
2005 parent
= process_data_dir_v2(dot
, dotdot
, id
, v
, mp
->m_dirdatablk
,
2007 dir_hash_check(id
, v
);
2014 process_bmbt_reclist(
2022 xfs_agblock_t agbno
;
2023 xfs_agnumber_t agno
;
2029 xfs_agblock_t iagbno
;
2030 xfs_agnumber_t iagno
;
2037 v
= verbose
|| id
->ilist
;
2038 iagno
= XFS_INO_TO_AGNO(mp
, id
->ino
);
2039 iagbno
= XFS_INO_TO_AGBNO(mp
, id
->ino
);
2040 for (i
= 0; i
< numrecs
; i
++, rp
++) {
2041 convert_extent(rp
, &o
, &s
, &c
, &f
);
2043 dbprintf(_("inode %lld extent [%lld,%lld,%lld,%d]\n"),
2044 id
->ino
, o
, s
, c
, f
);
2045 if (!sflag
&& i
> 0 && op
+ cp
> o
)
2046 dbprintf(_("bmap rec out of order, inode %lld entry %d\n"),
2050 if (type
== DBM_RTDATA
) {
2051 if (!sflag
&& s
>= mp
->m_sb
.sb_rblocks
) {
2052 dbprintf(_("inode %lld bad rt block number %lld, "
2057 } else if (!sflag
) {
2058 agno
= XFS_FSB_TO_AGNO(mp
, s
);
2059 agbno
= XFS_FSB_TO_AGBNO(mp
, s
);
2060 if (agno
>= mp
->m_sb
.sb_agcount
||
2061 agbno
>= mp
->m_sb
.sb_agblocks
) {
2062 dbprintf(_("inode %lld bad block number %lld "
2063 "[%d,%d], offset %lld\n"),
2064 id
->ino
, s
, agno
, agbno
, o
);
2067 if (agbno
+ c
- 1 >= mp
->m_sb
.sb_agblocks
) {
2068 dbprintf(_("inode %lld bad block number %lld "
2069 "[%d,%d], offset %lld\n"),
2070 id
->ino
, s
+ c
- 1, agno
,
2071 agbno
+ (xfs_agblock_t
)c
- 1, o
);
2075 if (blkmapp
&& *blkmapp
)
2076 blkmap_set_ext(blkmapp
, (xfs_fileoff_t
)o
,
2077 (xfs_fsblock_t
)s
, (xfs_extlen_t
)c
);
2078 if (type
== DBM_RTDATA
) {
2079 set_rdbmap((xfs_fsblock_t
)s
, (xfs_extlen_t
)c
,
2081 set_rinomap((xfs_fsblock_t
)s
, (xfs_extlen_t
)c
, id
);
2082 for (b
= (xfs_fsblock_t
)s
;
2083 blist_size
&& b
< s
+ c
;
2086 dbprintf(_("inode %lld block %lld at "
2088 id
->ino
, (xfs_dfsbno_t
)b
, o
);
2091 agno
= XFS_FSB_TO_AGNO(mp
, (xfs_fsblock_t
)s
);
2092 agbno
= XFS_FSB_TO_AGBNO(mp
, (xfs_fsblock_t
)s
);
2093 set_dbmap(agno
, agbno
, (xfs_extlen_t
)c
, type
, iagno
,
2095 set_inomap(agno
, agbno
, (xfs_extlen_t
)c
, id
);
2096 for (b
= (xfs_fsblock_t
)s
;
2097 blist_size
&& b
< s
+ c
;
2098 b
++, o
++, agbno
++) {
2100 dbprintf(_("inode %lld block %lld at "
2102 id
->ino
, (xfs_dfsbno_t
)b
, o
);
2114 xfs_drfsbno_t
*totd
,
2115 xfs_drfsbno_t
*toti
,
2120 xfs_bmdr_block_t
*dib
;
2124 dib
= (xfs_bmdr_block_t
*)XFS_DFORK_PTR(dip
, whichfork
);
2125 if (be16_to_cpu(dib
->bb_level
) >= XFS_BM_MAXLEVELS(mp
, whichfork
)) {
2126 if (!sflag
|| id
->ilist
)
2127 dbprintf(_("level for ino %lld %s fork bmap root too "
2130 whichfork
== XFS_DATA_FORK
? _("data") : _("attr"),
2131 be16_to_cpu(dib
->bb_level
));
2135 if (be16_to_cpu(dib
->bb_numrecs
) >
2136 xfs_bmdr_maxrecs(mp
, XFS_DFORK_SIZE(dip
, mp
, whichfork
),
2137 be16_to_cpu(dib
->bb_level
) == 0)) {
2138 if (!sflag
|| id
->ilist
)
2139 dbprintf(_("numrecs for ino %lld %s fork bmap root too "
2142 whichfork
== XFS_DATA_FORK
? _("data") : _("attr"),
2143 be16_to_cpu(dib
->bb_numrecs
));
2147 if (be16_to_cpu(dib
->bb_level
) == 0) {
2148 xfs_bmbt_rec_t
*rp
= XFS_BMDR_REC_ADDR(dib
, 1);
2149 process_bmbt_reclist(rp
, be16_to_cpu(dib
->bb_numrecs
), type
,
2151 *nex
+= be16_to_cpu(dib
->bb_numrecs
);
2154 pp
= XFS_BMDR_PTR_ADDR(dib
, 1, xfs_bmdr_maxrecs(mp
,
2155 XFS_DFORK_SIZE(dip
, mp
, whichfork
), 0));
2156 for (i
= 0; i
< be16_to_cpu(dib
->bb_numrecs
); i
++)
2157 scan_lbtree(be64_to_cpu(pp
[i
]),
2158 be16_to_cpu(dib
->bb_level
),
2159 scanfunc_bmap
, type
, id
, totd
, toti
,
2161 whichfork
== XFS_DATA_FORK
?
2162 TYP_BMAPBTD
: TYP_BMAPBTA
);
2164 if (*nex
<= XFS_DFORK_SIZE(dip
, mp
, whichfork
) / sizeof(xfs_bmbt_rec_t
)) {
2165 if (!sflag
|| id
->ilist
)
2166 dbprintf(_("extent count for ino %lld %s fork too low "
2167 "(%d) for file format\n"),
2169 whichfork
== XFS_DATA_FORK
? _("data") : _("attr"),
2176 process_data_dir_v2(
2182 freetab_t
**freetabp
)
2184 xfs_dir2_dataptr_t addr
;
2185 xfs_dir2_data_free_t
*bf
;
2187 xfs_dir2_block_t
*block
;
2188 xfs_dir2_block_tail_t
*btp
= NULL
;
2191 xfs_dir2_data_t
*data
;
2193 xfs_dir2_data_entry_t
*dep
;
2194 xfs_dir2_data_free_t
*dfp
;
2195 xfs_dir2_data_unused_t
*dup
;
2202 xfs_dir2_leaf_entry_t
*lep
= NULL
;
2204 xfs_ino_t parent
= 0;
2209 struct xfs_name xname
;
2211 data
= iocur_top
->data
;
2212 block
= iocur_top
->data
;
2213 if (be32_to_cpu(block
->hdr
.magic
) != XFS_DIR2_BLOCK_MAGIC
&&
2214 be32_to_cpu(data
->hdr
.magic
) != XFS_DIR2_DATA_MAGIC
) {
2216 dbprintf(_("bad directory data magic # %#x for dir ino "
2218 be32_to_cpu(data
->hdr
.magic
), id
->ino
, dabno
);
2222 db
= xfs_dir2_da_to_db(mp
, dabno
);
2223 bf
= data
->hdr
.bestfree
;
2224 ptr
= (char *)data
->u
;
2225 if (be32_to_cpu(block
->hdr
.magic
) == XFS_DIR2_BLOCK_MAGIC
) {
2226 btp
= xfs_dir2_block_tail_p(mp
, block
);
2227 lep
= xfs_dir2_block_leaf_p(btp
);
2228 endptr
= (char *)lep
;
2229 if (endptr
<= ptr
|| endptr
> (char *)btp
) {
2230 endptr
= (char *)data
+ mp
->m_dirblksize
;
2233 dbprintf(_("bad block directory tail for dir ino "
2239 endptr
= (char *)data
+ mp
->m_dirblksize
;
2240 bf_err
= lastfree_err
= tag_err
= 0;
2241 count
= lastfree
= freeseen
= 0;
2242 if (be16_to_cpu(bf
[0].length
) == 0) {
2243 bf_err
+= be16_to_cpu(bf
[0].offset
) != 0;
2246 if (be16_to_cpu(bf
[1].length
) == 0) {
2247 bf_err
+= be16_to_cpu(bf
[1].offset
) != 0;
2250 if (be16_to_cpu(bf
[2].length
) == 0) {
2251 bf_err
+= be16_to_cpu(bf
[2].offset
) != 0;
2254 bf_err
+= be16_to_cpu(bf
[0].length
) < be16_to_cpu(bf
[1].length
);
2255 bf_err
+= be16_to_cpu(bf
[1].length
) < be16_to_cpu(bf
[2].length
);
2257 freetab
= *freetabp
;
2258 if (freetab
->naents
<= db
) {
2259 *freetabp
= freetab
=
2260 realloc(freetab
, FREETAB_SIZE(db
+ 1));
2261 for (i
= freetab
->naents
; i
< db
; i
++)
2262 freetab
->ents
[i
] = NULLDATAOFF
;
2263 freetab
->naents
= db
+ 1;
2265 if (freetab
->nents
< db
+ 1)
2266 freetab
->nents
= db
+ 1;
2267 freetab
->ents
[db
] = be16_to_cpu(bf
[0].length
);
2269 while (ptr
< endptr
) {
2270 dup
= (xfs_dir2_data_unused_t
*)ptr
;
2271 if (be16_to_cpu(dup
->freetag
) == XFS_DIR2_DATA_FREE_TAG
) {
2272 lastfree_err
+= lastfree
!= 0;
2273 tagp
= xfs_dir2_data_unused_tag_p(dup
);
2274 if ((be16_to_cpu(dup
->length
) & (XFS_DIR2_DATA_ALIGN
- 1)) ||
2275 be16_to_cpu(dup
->length
) == 0 ||
2276 (char *)tagp
>= endptr
) {
2278 dbprintf(_("dir %lld block %d bad free "
2286 tag_err
+= be16_to_cpu(*tagp
) != (char *)dup
- (char *)data
;
2287 dfp
= process_data_dir_v2_freefind(data
, dup
);
2289 i
= (int)(dfp
- bf
);
2290 bf_err
+= (freeseen
& (1 << i
)) != 0;
2293 bf_err
+= be16_to_cpu(dup
->length
) >
2294 be16_to_cpu(bf
[2].length
);
2295 ptr
+= be16_to_cpu(dup
->length
);
2299 dep
= (xfs_dir2_data_entry_t
*)dup
;
2300 if (dep
->namelen
== 0) {
2302 dbprintf(_("dir %lld block %d zero length entry "
2305 (int)((char *)dep
- (char *)data
));
2308 tagp
= xfs_dir2_data_entry_tag_p(dep
);
2309 if ((char *)tagp
>= endptr
) {
2311 dbprintf(_("dir %lld block %d bad entry at %d\n"),
2313 (int)((char *)dep
- (char *)data
));
2317 tag_err
+= be16_to_cpu(*tagp
) != (char *)dep
- (char *)data
;
2318 addr
= xfs_dir2_db_off_to_dataptr(mp
, db
,
2319 (char *)dep
- (char *)data
);
2320 xname
.name
= dep
->name
;
2321 xname
.len
= dep
->namelen
;
2322 dir_hash_add(mp
->m_dirnameops
->hashname(&xname
), addr
);
2323 ptr
+= xfs_dir2_data_entsize(dep
->namelen
);
2326 lino
= be64_to_cpu(dep
->inumber
);
2327 cid
= find_inode(lino
, 1);
2329 dbprintf(_("dir %lld block %d entry %*.*s %lld\n"),
2330 id
->ino
, dabno
, dep
->namelen
, dep
->namelen
,
2336 dbprintf(_("dir %lld block %d entry %*.*s bad "
2337 "inode number %lld\n"),
2338 id
->ino
, dabno
, dep
->namelen
,
2339 dep
->namelen
, dep
->name
, lino
);
2342 if (dep
->namelen
== 2 && dep
->name
[0] == '.' &&
2343 dep
->name
[1] == '.') {
2346 dbprintf(_("multiple .. entries in dir "
2347 "%lld (%lld, %lld)\n"),
2348 id
->ino
, parent
, lino
);
2351 parent
= cid
? lino
: NULLFSINO
;
2353 } else if (dep
->namelen
!= 1 || dep
->name
[0] != '.') {
2357 addname_inode(cid
, (char *)dep
->name
,
2361 if (lino
!= id
->ino
) {
2363 dbprintf(_("dir %lld entry . inode "
2364 "number mismatch (%lld)\n"),
2371 if (be32_to_cpu(data
->hdr
.magic
) == XFS_DIR2_BLOCK_MAGIC
) {
2372 endptr
= (char *)data
+ mp
->m_dirblksize
;
2373 for (i
= stale
= 0; lep
&& i
< be32_to_cpu(btp
->count
); i
++) {
2374 if ((char *)&lep
[i
] >= endptr
) {
2376 dbprintf(_("dir %lld block %d bad count "
2377 "%u\n"), id
->ino
, dabno
,
2378 be32_to_cpu(btp
->count
));
2382 if (be32_to_cpu(lep
[i
].address
) == XFS_DIR2_NULL_DATAPTR
)
2384 else if (dir_hash_see(be32_to_cpu(lep
[i
].hashval
),
2385 be32_to_cpu(lep
[i
].address
))) {
2387 dbprintf(_("dir %lld block %d extra leaf "
2390 be32_to_cpu(lep
[i
].hashval
),
2391 be32_to_cpu(lep
[i
].address
));
2396 bf_err
+= freeseen
!= 7;
2399 dbprintf(_("dir %lld block %d bad bestfree data\n"),
2403 if (be32_to_cpu(data
->hdr
.magic
) == XFS_DIR2_BLOCK_MAGIC
&&
2404 count
!= be32_to_cpu(btp
->count
) -
2405 be32_to_cpu(btp
->stale
)) {
2407 dbprintf(_("dir %lld block %d bad block tail count %d "
2409 id
->ino
, dabno
, be32_to_cpu(btp
->count
),
2410 be32_to_cpu(btp
->stale
));
2413 if (be32_to_cpu(data
->hdr
.magic
) == XFS_DIR2_BLOCK_MAGIC
&&
2414 stale
!= be32_to_cpu(btp
->stale
)) {
2416 dbprintf(_("dir %lld block %d bad stale tail count %d\n"),
2417 id
->ino
, dabno
, be32_to_cpu(btp
->stale
));
2422 dbprintf(_("dir %lld block %d consecutive free entries\n"),
2428 dbprintf(_("dir %lld block %d entry/unused tag "
2436 static xfs_dir2_data_free_t
*
2437 process_data_dir_v2_freefind(
2438 xfs_dir2_data_t
*data
,
2439 xfs_dir2_data_unused_t
*dup
)
2441 xfs_dir2_data_free_t
*dfp
;
2442 xfs_dir2_data_aoff_t off
;
2444 off
= (xfs_dir2_data_aoff_t
)((char *)dup
- (char *)data
);
2445 if (be16_to_cpu(dup
->length
) < be16_to_cpu(data
->hdr
.
2446 bestfree
[XFS_DIR2_DATA_FD_COUNT
- 1].length
))
2448 for (dfp
= &data
->hdr
.bestfree
[0]; dfp
< &data
->hdr
.
2449 bestfree
[XFS_DIR2_DATA_FD_COUNT
]; dfp
++) {
2450 if (be16_to_cpu(dfp
->offset
) == 0)
2452 if (be16_to_cpu(dfp
->offset
) == off
)
2470 if (xfs_sb_version_hasdirv2(&mp
->m_sb
)) {
2471 if (process_dir_v2(dip
, blkmap
, &dot
, &dotdot
, id
, &parent
))
2475 if (process_dir_v1(dip
, blkmap
, &dot
, &dotdot
, id
, &parent
))
2478 bno
= XFS_INO_TO_FSB(mp
, id
->ino
);
2480 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
2481 dbprintf(_("no . entry for directory %lld\n"), id
->ino
);
2485 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
2486 dbprintf(_("no .. entry for directory %lld\n"), id
->ino
);
2488 } else if (parent
== id
->ino
&& id
->ino
!= mp
->m_sb
.sb_rootino
) {
2489 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
2490 dbprintf(_(". and .. same for non-root directory %lld\n"),
2493 } else if (id
->ino
== mp
->m_sb
.sb_rootino
&& id
->ino
!= parent
) {
2494 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
2495 dbprintf(_("root directory %lld has .. %lld\n"), id
->ino
,
2498 } else if (parent
!= NULLFSINO
&& id
->ino
!= parent
)
2499 addparent_inode(id
, parent
);
2511 xfs_fsize_t size
= be64_to_cpu(dip
->di_size
);
2513 if (size
<= XFS_DFORK_DSIZE(dip
, mp
) &&
2514 dip
->di_format
== XFS_DINODE_FMT_LOCAL
)
2515 *parent
= process_shortform_dir_v1(dip
, dot
, dotdot
, id
);
2516 else if (size
== XFS_LBSIZE(mp
) &&
2517 (dip
->di_format
== XFS_DINODE_FMT_EXTENTS
||
2518 dip
->di_format
== XFS_DINODE_FMT_BTREE
))
2519 *parent
= process_leaf_dir_v1(blkmap
, dot
, dotdot
, id
);
2520 else if (size
>= XFS_LBSIZE(mp
) &&
2521 (dip
->di_format
== XFS_DINODE_FMT_EXTENTS
||
2522 dip
->di_format
== XFS_DINODE_FMT_BTREE
))
2523 *parent
= process_node_dir_v1(blkmap
, dot
, dotdot
, id
);
2525 dbprintf(_("bad size (%lld) or format (%d) for directory inode "
2527 size
, dip
->di_format
, id
->ino
);
2543 xfs_fileoff_t last
= 0;
2544 xfs_fsize_t size
= be64_to_cpu(dip
->di_size
);
2547 last
= blkmap_last_off(blkmap
);
2548 if (size
<= XFS_DFORK_DSIZE(dip
, mp
) &&
2549 dip
->di_format
== XFS_DINODE_FMT_LOCAL
)
2550 *parent
= process_sf_dir_v2(dip
, dot
, dotdot
, id
);
2551 else if (last
== mp
->m_dirblkfsbs
&&
2552 (dip
->di_format
== XFS_DINODE_FMT_EXTENTS
||
2553 dip
->di_format
== XFS_DINODE_FMT_BTREE
))
2554 *parent
= process_block_dir_v2(blkmap
, dot
, dotdot
, id
);
2555 else if (last
>= mp
->m_dirleafblk
+ mp
->m_dirblkfsbs
&&
2556 (dip
->di_format
== XFS_DINODE_FMT_EXTENTS
||
2557 dip
->di_format
== XFS_DINODE_FMT_BTREE
))
2558 *parent
= process_leaf_node_dir_v2(blkmap
, dot
, dotdot
, id
, size
);
2560 dbprintf(_("bad size (%lld) or format (%d) for directory inode "
2562 size
, dip
->di_format
, id
->ino
);
2575 xfs_drfsbno_t
*totd
,
2576 xfs_drfsbno_t
*toti
,
2583 rp
= (xfs_bmbt_rec_t
*)XFS_DFORK_PTR(dip
, whichfork
);
2584 *nex
= XFS_DFORK_NEXTENTS(dip
, whichfork
);
2585 if (*nex
< 0 || *nex
> XFS_DFORK_SIZE(dip
, mp
, whichfork
) /
2586 sizeof(xfs_bmbt_rec_t
)) {
2587 if (!sflag
|| id
->ilist
)
2588 dbprintf(_("bad number of extents %d for inode %lld\n"),
2593 process_bmbt_reclist(rp
, *nex
, type
, id
, totd
, blkmapp
);
2604 xfs_fsblock_t bno
= 0;
2605 xfs_icdinode_t idic
;
2606 inodata_t
*id
= NULL
;
2608 xfs_extnum_t nextents
= 0;
2611 xfs_drfsbno_t totblocks
;
2612 xfs_drfsbno_t totdblocks
= 0;
2613 xfs_drfsbno_t totiblocks
= 0;
2615 xfs_extnum_t anextents
= 0;
2616 xfs_drfsbno_t atotdblocks
= 0;
2617 xfs_drfsbno_t atotiblocks
= 0;
2623 static char okfmts
[] = {
2624 0, /* type 0 unused */
2625 1 << XFS_DINODE_FMT_DEV
, /* FIFO */
2626 1 << XFS_DINODE_FMT_DEV
, /* CHR */
2627 0, /* type 3 unused */
2628 (1 << XFS_DINODE_FMT_LOCAL
) |
2629 (1 << XFS_DINODE_FMT_EXTENTS
) |
2630 (1 << XFS_DINODE_FMT_BTREE
), /* DIR */
2631 0, /* type 5 unused */
2632 1 << XFS_DINODE_FMT_DEV
, /* BLK */
2633 0, /* type 7 unused */
2634 (1 << XFS_DINODE_FMT_EXTENTS
) |
2635 (1 << XFS_DINODE_FMT_BTREE
), /* REG */
2636 0, /* type 9 unused */
2637 (1 << XFS_DINODE_FMT_LOCAL
) |
2638 (1 << XFS_DINODE_FMT_EXTENTS
), /* LNK */
2639 0, /* type 11 unused */
2640 1 << XFS_DINODE_FMT_DEV
, /* SOCK */
2641 0, /* type 13 unused */
2642 1 << XFS_DINODE_FMT_UUID
, /* MNT */
2643 0 /* type 15 unused */
2645 static char *fmtnames
[] = {
2646 "dev", "local", "extents", "btree", "uuid"
2649 libxfs_dinode_from_disk(&idic
, dip
);
2651 ino
= XFS_AGINO_TO_INO(mp
, be32_to_cpu(agf
->agf_seqno
), agino
);
2653 id
= find_inode(ino
, 1);
2654 bno
= XFS_INO_TO_FSB(mp
, ino
);
2657 v
= (!sflag
|| (id
&& id
->ilist
) || CHECK_BLIST(bno
));
2658 if (idic
.di_magic
!= XFS_DINODE_MAGIC
) {
2660 dbprintf(_("bad magic number %#x for inode %lld\n"),
2661 idic
.di_magic
, ino
);
2665 if (!XFS_DINODE_GOOD_VERSION(idic
.di_version
)) {
2667 dbprintf(_("bad version number %#x for inode %lld\n"),
2668 idic
.di_version
, ino
);
2673 if (idic
.di_nblocks
!= 0) {
2675 dbprintf(_("bad nblocks %lld for free inode "
2677 idic
.di_nblocks
, ino
);
2680 if (idic
.di_version
== 1)
2681 nlink
= idic
.di_onlink
;
2683 nlink
= idic
.di_nlink
;
2686 dbprintf(_("bad nlink %d for free inode %lld\n"),
2690 if (idic
.di_mode
!= 0) {
2692 dbprintf(_("bad mode %#o for free inode %lld\n"),
2699 if (be32_to_cpu(dip
->di_next_unlinked
) != NULLAGINO
) {
2701 dbprintf(_("bad next unlinked %#x for inode %lld\n"),
2702 be32_to_cpu(dip
->di_next_unlinked
), ino
);
2706 * di_mode is a 16-bit uint so no need to check the < 0 case
2708 if ((((idic
.di_mode
& S_IFMT
) >> 12) > 15) ||
2709 (!(okfmts
[(idic
.di_mode
& S_IFMT
) >> 12] & (1 << idic
.di_format
)))) {
2711 dbprintf(_("bad format %d for inode %lld type %#o\n"),
2712 idic
.di_format
, id
->ino
, idic
.di_mode
& S_IFMT
);
2716 if ((unsigned int)XFS_DFORK_ASIZE(dip
, mp
) >= XFS_LITINO(mp
)) {
2718 dbprintf(_("bad fork offset %d for inode %lld\n"),
2719 idic
.di_forkoff
, id
->ino
);
2723 if ((unsigned int)idic
.di_aformat
> XFS_DINODE_FMT_BTREE
) {
2725 dbprintf(_("bad attribute format %d for inode %lld\n"),
2726 idic
.di_aformat
, id
->ino
);
2730 if (verbose
|| (id
&& id
->ilist
) || CHECK_BLIST(bno
))
2731 dbprintf(_("inode %lld mode %#o fmt %s "
2733 "nex %d anex %d nblk %lld sz %lld%s%s%s%s%s%s%s\n"),
2734 id
->ino
, idic
.di_mode
, fmtnames
[(int)idic
.di_format
],
2735 fmtnames
[(int)idic
.di_aformat
],
2738 idic
.di_nblocks
, idic
.di_size
,
2739 idic
.di_flags
& XFS_DIFLAG_REALTIME
? " rt" : "",
2740 idic
.di_flags
& XFS_DIFLAG_PREALLOC
? " pre" : "",
2741 idic
.di_flags
& XFS_DIFLAG_IMMUTABLE
? " imm" : "",
2742 idic
.di_flags
& XFS_DIFLAG_APPEND
? " app" : "",
2743 idic
.di_flags
& XFS_DIFLAG_SYNC
? " syn" : "",
2744 idic
.di_flags
& XFS_DIFLAG_NOATIME
? " noa" : "",
2745 idic
.di_flags
& XFS_DIFLAG_NODUMP
? " nod" : "");
2747 switch (idic
.di_mode
& S_IFMT
) {
2750 if (idic
.di_format
== XFS_DINODE_FMT_LOCAL
)
2752 blkmap
= blkmap_alloc(idic
.di_nextents
);
2755 if (idic
.di_flags
& XFS_DIFLAG_REALTIME
)
2757 else if (id
->ino
== mp
->m_sb
.sb_rbmino
) {
2758 type
= DBM_RTBITMAP
;
2759 blkmap
= blkmap_alloc(idic
.di_nextents
);
2761 } else if (id
->ino
== mp
->m_sb
.sb_rsumino
) {
2763 blkmap
= blkmap_alloc(idic
.di_nextents
);
2766 else if (id
->ino
== mp
->m_sb
.sb_uquotino
||
2767 id
->ino
== mp
->m_sb
.sb_gquotino
) {
2769 blkmap
= blkmap_alloc(idic
.di_nextents
);
2774 if (idic
.di_mode
& (S_ISUID
| S_ISGID
))
2785 if (idic
.di_version
== 1)
2786 setlink_inode(id
, idic
.di_onlink
, type
== DBM_DIR
, security
);
2788 sbversion
|= XFS_SB_VERSION_NLINKBIT
;
2789 setlink_inode(id
, idic
.di_nlink
, type
== DBM_DIR
, security
);
2791 switch (idic
.di_format
) {
2792 case XFS_DINODE_FMT_LOCAL
:
2793 process_lclinode(id
, dip
, type
, &totdblocks
, &totiblocks
,
2794 &nextents
, &blkmap
, XFS_DATA_FORK
);
2796 case XFS_DINODE_FMT_EXTENTS
:
2797 process_exinode(id
, dip
, type
, &totdblocks
, &totiblocks
,
2798 &nextents
, &blkmap
, XFS_DATA_FORK
);
2800 case XFS_DINODE_FMT_BTREE
:
2801 process_btinode(id
, dip
, type
, &totdblocks
, &totiblocks
,
2802 &nextents
, &blkmap
, XFS_DATA_FORK
);
2805 if (XFS_DFORK_Q(dip
)) {
2806 sbversion
|= XFS_SB_VERSION_ATTRBIT
;
2807 switch (idic
.di_aformat
) {
2808 case XFS_DINODE_FMT_LOCAL
:
2809 process_lclinode(id
, dip
, DBM_ATTR
, &atotdblocks
,
2810 &atotiblocks
, &anextents
, NULL
, XFS_ATTR_FORK
);
2812 case XFS_DINODE_FMT_EXTENTS
:
2813 process_exinode(id
, dip
, DBM_ATTR
, &atotdblocks
,
2814 &atotiblocks
, &anextents
, NULL
, XFS_ATTR_FORK
);
2816 case XFS_DINODE_FMT_BTREE
:
2817 process_btinode(id
, dip
, DBM_ATTR
, &atotdblocks
,
2818 &atotiblocks
, &anextents
, NULL
, XFS_ATTR_FORK
);
2822 if (qgdo
|| qpdo
|| qudo
) {
2830 bc
= totdblocks
+ totiblocks
+
2831 atotdblocks
+ atotiblocks
;
2835 bc
= totiblocks
+ atotdblocks
+ atotiblocks
;
2843 dqprid
= xfs_get_projid(idic
); /* dquot ID is u32 */
2844 quota_add(&dqprid
, &idic
.di_gid
, &idic
.di_uid
,
2848 totblocks
= totdblocks
+ totiblocks
+ atotdblocks
+ atotiblocks
;
2849 if (totblocks
!= idic
.di_nblocks
) {
2851 dbprintf(_("bad nblocks %lld for inode %lld, counted "
2853 idic
.di_nblocks
, id
->ino
, totblocks
);
2856 if (nextents
!= idic
.di_nextents
) {
2858 dbprintf(_("bad nextents %d for inode %lld, counted %d\n"),
2859 idic
.di_nextents
, id
->ino
, nextents
);
2862 if (anextents
!= idic
.di_anextents
) {
2864 dbprintf(_("bad anextents %d for inode %lld, counted "
2866 idic
.di_anextents
, id
->ino
, anextents
);
2869 if (type
== DBM_DIR
)
2870 process_dir(dip
, blkmap
, id
);
2871 else if (type
== DBM_RTBITMAP
)
2872 process_rtbitmap(blkmap
);
2873 else if (type
== DBM_RTSUM
)
2874 process_rtsummary(blkmap
);
2876 * If the CHKD flag is not set, this can legitimately contain garbage;
2877 * xfs_repair may have cleared that bit.
2879 else if (type
== DBM_QUOTA
) {
2880 if (id
->ino
== mp
->m_sb
.sb_uquotino
&&
2881 (mp
->m_sb
.sb_qflags
& XFS_UQUOTA_ACCT
) &&
2882 (mp
->m_sb
.sb_qflags
& XFS_UQUOTA_CHKD
))
2883 process_quota(IS_USER_QUOTA
, id
, blkmap
);
2884 else if (id
->ino
== mp
->m_sb
.sb_gquotino
&&
2885 (mp
->m_sb
.sb_qflags
& XFS_GQUOTA_ACCT
) &&
2886 (mp
->m_sb
.sb_qflags
& XFS_OQUOTA_CHKD
))
2887 process_quota(IS_GROUP_QUOTA
, id
, blkmap
);
2888 else if (id
->ino
== mp
->m_sb
.sb_gquotino
&&
2889 (mp
->m_sb
.sb_qflags
& XFS_PQUOTA_ACCT
) &&
2890 (mp
->m_sb
.sb_qflags
& XFS_OQUOTA_CHKD
))
2891 process_quota(IS_PROJECT_QUOTA
, id
, blkmap
);
2894 blkmap_free(blkmap
);
2903 xfs_drfsbno_t
*totd
,
2904 xfs_drfsbno_t
*toti
,
2909 xfs_attr_shortform_t
*asf
;
2912 bno
= XFS_INO_TO_FSB(mp
, id
->ino
);
2913 if (whichfork
== XFS_DATA_FORK
&& be64_to_cpu(dip
->di_size
) >
2914 XFS_DFORK_DSIZE(dip
, mp
)) {
2915 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
2916 dbprintf(_("local inode %lld data is too large (size "
2918 id
->ino
, be64_to_cpu(dip
->di_size
));
2921 else if (whichfork
== XFS_ATTR_FORK
) {
2922 asf
= (xfs_attr_shortform_t
*)XFS_DFORK_APTR(dip
);
2923 if (be16_to_cpu(asf
->hdr
.totsize
) > XFS_DFORK_ASIZE(dip
, mp
)) {
2924 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
2925 dbprintf(_("local inode %lld attr is too large "
2927 id
->ino
, be16_to_cpu(asf
->hdr
.totsize
));
2934 process_leaf_dir_v1(
2943 bno
= blkmap_get(blkmap
, 0);
2944 if (bno
== NULLFSBLOCK
) {
2945 if (!sflag
|| id
->ilist
)
2946 dbprintf(_("block 0 for directory inode %lld is "
2953 set_cur(&typtab
[TYP_DIR
], XFS_FSB_TO_DADDR(mp
, bno
), blkbb
, DB_RING_IGN
,
2955 if (iocur_top
->data
== NULL
) {
2956 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
2957 dbprintf(_("can't read block 0 for directory inode "
2964 parent
= process_leaf_dir_v1_int(dot
, dotdot
, id
);
2970 process_leaf_dir_v1_int(
2977 xfs_dir_leaf_entry_t
*entry
;
2979 xfs_dir_leafblock_t
*leaf
;
2981 xfs_dir_leaf_name_t
*namest
;
2982 xfs_ino_t parent
= 0;
2985 bno
= XFS_DADDR_TO_FSB(mp
, iocur_top
->bb
);
2986 v
= verbose
|| id
->ilist
|| CHECK_BLIST(bno
);
2987 leaf
= iocur_top
->data
;
2988 if (be16_to_cpu(leaf
->hdr
.info
.magic
) != XFS_DIR_LEAF_MAGIC
) {
2989 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
2990 dbprintf(_("bad directory leaf magic # %#x for dir ino "
2992 be16_to_cpu(leaf
->hdr
.info
.magic
), id
->ino
);
2996 entry
= &leaf
->entries
[0];
2997 for (i
= 0; i
< be16_to_cpu(leaf
->hdr
.count
); entry
++, i
++) {
2998 namest
= xfs_dir_leaf_namestruct(leaf
,
2999 be16_to_cpu(entry
->nameidx
));
3000 lino
= XFS_GET_DIR_INO8(namest
->inumber
);
3001 cid
= find_inode(lino
, 1);
3003 dbprintf(_("dir %lld entry %*.*s %lld\n"), id
->ino
,
3004 entry
->namelen
, entry
->namelen
, namest
->name
,
3010 dbprintf(_("dir %lld entry %*.*s bad inode "
3012 id
->ino
, entry
->namelen
, entry
->namelen
,
3013 namest
->name
, lino
);
3016 if (entry
->namelen
== 2 && namest
->name
[0] == '.' &&
3017 namest
->name
[1] == '.') {
3019 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
3020 dbprintf(_("multiple .. entries in dir "
3021 "%lld (%lld, %lld)\n"),
3022 id
->ino
, parent
, lino
);
3025 parent
= cid
? lino
: NULLFSINO
;
3027 } else if (entry
->namelen
!= 1 || namest
->name
[0] != '.') {
3031 addname_inode(cid
, (char *)namest
->name
,
3035 if (lino
!= id
->ino
) {
3037 dbprintf(_("dir %lld entry . inode "
3038 "number mismatch (%lld)\n"),
3049 process_leaf_node_dir_v2(
3054 xfs_fsize_t dirsize
)
3070 v2
= verbose
|| id
->ilist
;
3073 freetab
= malloc(FREETAB_SIZE(dirsize
/ mp
->m_dirblksize
));
3074 freetab
->naents
= (int)(dirsize
/ mp
->m_dirblksize
);
3076 for (i
= 0; i
< freetab
->naents
; i
++)
3077 freetab
->ents
[i
] = NULLDATAOFF
;
3079 while ((dbno
= blkmap_next_off(blkmap
, dbno
, &t
)) != NULLFILEOFF
) {
3080 nex
= blkmap_getn(blkmap
, dbno
, mp
->m_dirblkfsbs
, &bmp
);
3082 for (v
= v2
, x
= 0; !v
&& x
< nex
; x
++) {
3083 for (b
= bmp
[x
].startblock
;
3084 !v
&& b
< bmp
[x
].startblock
+ bmp
[x
].blockcount
;
3089 dbprintf(_("dir inode %lld block %u=%llu\n"), id
->ino
,
3091 (xfs_dfsbno_t
)bmp
->startblock
);
3094 make_bbmap(&bbmap
, nex
, bmp
);
3095 set_cur(&typtab
[TYP_DIR
], XFS_FSB_TO_DADDR(mp
, bmp
->startblock
),
3096 mp
->m_dirblkfsbs
* blkbb
, DB_RING_IGN
,
3097 nex
> 1 ? &bbmap
: NULL
);
3099 if (iocur_top
->data
== NULL
) {
3101 dbprintf(_("can't read block %u for directory "
3103 (__uint32_t
)dbno
, id
->ino
);
3106 dbno
+= mp
->m_dirblkfsbs
- 1;
3109 if (dbno
< mp
->m_dirleafblk
) {
3110 lino
= process_data_dir_v2(dot
, dotdot
, id
, v
,
3111 (xfs_dablk_t
)dbno
, &freetab
);
3115 dbprintf(_("multiple .. entries "
3122 } else if (dbno
< mp
->m_dirfreeblk
) {
3123 process_leaf_node_dir_v2_int(id
, v
, (xfs_dablk_t
)dbno
,
3126 process_leaf_node_dir_v2_free(id
, v
, (xfs_dablk_t
)dbno
,
3130 dbno
+= mp
->m_dirblkfsbs
- 1;
3132 dir_hash_check(id
, v
);
3134 for (i
= 0; i
< freetab
->nents
; i
++) {
3135 if (freetab
->ents
[i
] != NULLDATAOFF
) {
3137 dbprintf(_("missing free index for data block %d "
3138 "in dir ino %lld\n"),
3139 xfs_dir2_db_to_da(mp
, i
), id
->ino
);
3148 process_leaf_node_dir_v2_free(
3154 xfs_dir2_data_off_t ent
;
3155 xfs_dir2_free_t
*free
;
3160 free
= iocur_top
->data
;
3161 if (be32_to_cpu(free
->hdr
.magic
) != XFS_DIR2_FREE_MAGIC
) {
3163 dbprintf(_("bad free block magic # %#x for dir ino %lld "
3165 be32_to_cpu(free
->hdr
.magic
), id
->ino
, dabno
);
3169 maxent
= XFS_DIR2_MAX_FREE_BESTS(mp
);
3170 if (be32_to_cpu(free
->hdr
.firstdb
) != xfs_dir2_da_to_db(mp
,
3171 dabno
- mp
->m_dirfreeblk
) * maxent
) {
3173 dbprintf(_("bad free block firstdb %d for dir ino %lld "
3175 be32_to_cpu(free
->hdr
.firstdb
), id
->ino
, dabno
);
3179 if (be32_to_cpu(free
->hdr
.nvalid
) > maxent
||
3180 be32_to_cpu(free
->hdr
.nvalid
) < 0 ||
3181 be32_to_cpu(free
->hdr
.nused
) > maxent
||
3182 be32_to_cpu(free
->hdr
.nused
) < 0 ||
3183 be32_to_cpu(free
->hdr
.nused
) >
3184 be32_to_cpu(free
->hdr
.nvalid
)) {
3186 dbprintf(_("bad free block nvalid/nused %d/%d for dir "
3187 "ino %lld block %d\n"),
3188 be32_to_cpu(free
->hdr
.nvalid
),
3189 be32_to_cpu(free
->hdr
.nused
), id
->ino
, dabno
);
3193 for (used
= i
= 0; i
< be32_to_cpu(free
->hdr
.nvalid
); i
++) {
3194 if (freetab
->nents
<= be32_to_cpu(free
->hdr
.firstdb
) + i
)
3197 ent
= freetab
->ents
[be32_to_cpu(free
->hdr
.firstdb
) + i
];
3198 if (ent
!= be16_to_cpu(free
->bests
[i
])) {
3200 dbprintf(_("bad free block ent %d is %d should "
3201 "be %d for dir ino %lld block %d\n"),
3202 i
, be16_to_cpu(free
->bests
[i
]), ent
,
3206 if (be16_to_cpu(free
->bests
[i
]) != NULLDATAOFF
)
3208 if (ent
!= NULLDATAOFF
)
3209 freetab
->ents
[be32_to_cpu(free
->hdr
.firstdb
) + i
] =
3212 if (used
!= be32_to_cpu(free
->hdr
.nused
)) {
3214 dbprintf(_("bad free block nused %d should be %d for dir "
3215 "ino %lld block %d\n"),
3216 be32_to_cpu(free
->hdr
.nused
), used
, id
->ino
,
3223 process_leaf_node_dir_v2_int(
3231 xfs_dir2_leaf_t
*leaf
;
3232 xfs_dir2_leaf_entry_t
*lep
;
3233 xfs_dir2_leaf_tail_t
*ltp
;
3234 xfs_da_intnode_t
*node
;
3237 leaf
= iocur_top
->data
;
3238 switch (be16_to_cpu(leaf
->hdr
.info
.magic
)) {
3239 case XFS_DIR2_LEAF1_MAGIC
:
3240 if (be32_to_cpu(leaf
->hdr
.info
.forw
) ||
3241 be32_to_cpu(leaf
->hdr
.info
.back
)) {
3243 dbprintf(_("bad leaf block forw/back pointers "
3244 "%d/%d for dir ino %lld block %d\n"),
3245 be32_to_cpu(leaf
->hdr
.info
.forw
),
3246 be32_to_cpu(leaf
->hdr
.info
.back
),
3250 if (dabno
!= mp
->m_dirleafblk
) {
3252 dbprintf(_("single leaf block for dir ino %lld "
3253 "block %d should be at block %d\n"),
3255 (xfs_dablk_t
)mp
->m_dirleafblk
);
3258 ltp
= xfs_dir2_leaf_tail_p(mp
, leaf
);
3259 lbp
= xfs_dir2_leaf_bests_p(ltp
);
3260 for (i
= 0; i
< be32_to_cpu(ltp
->bestcount
); i
++) {
3261 if (freetab
->nents
<= i
|| freetab
->ents
[i
] !=
3262 be16_to_cpu(lbp
[i
])) {
3264 dbprintf(_("bestfree %d for dir ino %lld "
3265 "block %d doesn't match table "
3267 freetab
->nents
<= i
?
3271 xfs_dir2_db_to_da(mp
, i
),
3272 be16_to_cpu(lbp
[i
]));
3274 if (freetab
->nents
> i
)
3275 freetab
->ents
[i
] = NULLDATAOFF
;
3278 case XFS_DIR2_LEAFN_MAGIC
:
3279 /* if it's at the root location then we can check the
3280 * pointers are null XXX */
3282 case XFS_DA_NODE_MAGIC
:
3283 node
= iocur_top
->data
;
3284 if (be16_to_cpu(node
->hdr
.level
) < 1 ||
3285 be16_to_cpu(node
->hdr
.level
) >
3286 XFS_DA_NODE_MAXDEPTH
) {
3288 dbprintf(_("bad node block level %d for dir ino "
3290 be16_to_cpu(node
->hdr
.level
), id
->ino
,
3297 dbprintf(_("bad directory data magic # %#x for dir ino "
3299 be16_to_cpu(leaf
->hdr
.info
.magic
), id
->ino
,
3305 for (i
= stale
= 0; i
< be16_to_cpu(leaf
->hdr
.count
); i
++) {
3306 if (be32_to_cpu(lep
[i
].address
) == XFS_DIR2_NULL_DATAPTR
)
3308 else if (dir_hash_see(be32_to_cpu(lep
[i
].hashval
),
3309 be32_to_cpu(lep
[i
].address
))) {
3311 dbprintf(_("dir %lld block %d extra leaf entry "
3312 "%x %x\n"), id
->ino
, dabno
,
3313 be32_to_cpu(lep
[i
].hashval
),
3314 be32_to_cpu(lep
[i
].address
));
3318 if (stale
!= be16_to_cpu(leaf
->hdr
.stale
)) {
3320 dbprintf(_("dir %lld block %d stale mismatch "
3322 id
->ino
, dabno
, stale
,
3323 be16_to_cpu(leaf
->hdr
.stale
));
3329 process_node_dir_v1(
3343 v
= verbose
|| id
->ilist
;
3347 while ((dbno
= blkmap_next_off(blkmap
, dbno
, &t
)) != NULLFILEOFF
) {
3348 bno
= blkmap_get(blkmap
, dbno
);
3349 v2
= bno
!= NULLFSBLOCK
&& CHECK_BLIST(bno
);
3350 if (bno
== NULLFSBLOCK
&& dbno
== 0) {
3352 dbprintf(_("can't read root block for directory "
3358 dbprintf(_("dir inode %lld block %u=%llu\n"), id
->ino
,
3359 (__uint32_t
)dbno
, (xfs_dfsbno_t
)bno
);
3360 if (bno
== NULLFSBLOCK
)
3364 set_cur(&typtab
[TYP_DIR
], XFS_FSB_TO_DADDR(mp
, bno
), blkbb
,
3366 if (iocur_top
->data
== NULL
) {
3367 if (!sflag
|| v
|| v2
)
3368 dbprintf(_("can't read block %u for directory "
3370 (__uint32_t
)dbno
, id
->ino
);
3374 if (be16_to_cpu(((xfs_da_intnode_t
*)iocur_top
->data
)->
3375 hdr
.info
.magic
) == XFS_DA_NODE_MAGIC
)
3377 lino
= process_leaf_dir_v1_int(dot
, dotdot
, id
);
3380 if (!sflag
|| v
|| v2
)
3381 dbprintf(_("multiple .. entries in dir "
3403 u_int8_t exp_flags
= 0;
3414 exp_flags
= XFS_DQ_USER
;
3416 case IS_PROJECT_QUOTA
:
3418 exp_flags
= XFS_DQ_PROJ
;
3420 case IS_GROUP_QUOTA
:
3422 exp_flags
= XFS_DQ_GROUP
;
3428 perblock
= (uint
)(mp
->m_sb
.sb_blocksize
/ sizeof(*dqb
));
3431 while ((qbno
= blkmap_next_off(blkmap
, qbno
, &t
)) != NULLFILEOFF
) {
3432 bno
= blkmap_get(blkmap
, qbno
);
3433 dqid
= (xfs_dqid_t
)qbno
* perblock
;
3434 cb
= CHECK_BLIST(bno
);
3435 scicb
= !sflag
|| id
->ilist
|| cb
;
3437 set_cur(&typtab
[TYP_DQBLK
], XFS_FSB_TO_DADDR(mp
, bno
), blkbb
,
3439 if ((dqb
= iocur_top
->data
) == NULL
) {
3441 dbprintf(_("can't read block %lld for %s quota "
3442 "inode (fsblock %lld)\n"),
3443 (xfs_dfiloff_t
)qbno
, s
,
3449 for (i
= 0; i
< perblock
; i
++, dqid
++, dqb
++) {
3450 if (verbose
|| id
->ilist
|| cb
)
3451 dbprintf(_("%s dqblk %lld entry %d id %u bc "
3452 "%lld ic %lld rc %lld\n"),
3453 s
, (xfs_dfiloff_t
)qbno
, i
, dqid
,
3454 be64_to_cpu(dqb
->dd_diskdq
.d_bcount
),
3455 be64_to_cpu(dqb
->dd_diskdq
.d_icount
),
3456 be64_to_cpu(dqb
->dd_diskdq
.d_rtbcount
));
3457 if (be16_to_cpu(dqb
->dd_diskdq
.d_magic
) != XFS_DQUOT_MAGIC
) {
3459 dbprintf(_("bad magic number %#x for %s "
3460 "dqblk %lld entry %d id %u\n"),
3461 be16_to_cpu(dqb
->dd_diskdq
.d_magic
), s
,
3462 (xfs_dfiloff_t
)qbno
, i
, dqid
);
3466 if (dqb
->dd_diskdq
.d_version
!= XFS_DQUOT_VERSION
) {
3468 dbprintf(_("bad version number %#x for "
3469 "%s dqblk %lld entry %d id "
3471 dqb
->dd_diskdq
.d_version
, s
,
3472 (xfs_dfiloff_t
)qbno
, i
, dqid
);
3476 if (dqb
->dd_diskdq
.d_flags
!= exp_flags
) {
3478 dbprintf(_("bad flags %#x for %s dqblk "
3479 "%lld entry %d id %u\n"),
3480 dqb
->dd_diskdq
.d_flags
, s
,
3481 (xfs_dfiloff_t
)qbno
, i
, dqid
);
3485 if (be32_to_cpu(dqb
->dd_diskdq
.d_id
) != dqid
) {
3487 dbprintf(_("bad id %u for %s dqblk %lld "
3488 "entry %d id %u\n"),
3489 be32_to_cpu(dqb
->dd_diskdq
.d_id
), s
,
3490 (xfs_dfiloff_t
)qbno
, i
, dqid
);
3494 quota_add((qtype
== IS_PROJECT_QUOTA
) ? &dqid
: NULL
,
3495 (qtype
== IS_GROUP_QUOTA
) ? &dqid
: NULL
,
3496 (qtype
== IS_USER_QUOTA
) ? &dqid
: NULL
,
3498 be64_to_cpu(dqb
->dd_diskdq
.d_bcount
),
3499 be64_to_cpu(dqb
->dd_diskdq
.d_icount
),
3500 be64_to_cpu(dqb
->dd_diskdq
.d_rtbcount
));
3512 xfs_fileoff_t bmbno
;
3519 xfs_drfsbno_t rtbno
;
3523 xfs_rtword_t
*words
;
3525 bitsperblock
= mp
->m_sb
.sb_blocksize
* NBBY
;
3526 bit
= extno
= prevbit
= start_bmbno
= start_bit
= 0;
3527 bmbno
= NULLFILEOFF
;
3528 while ((bmbno
= blkmap_next_off(blkmap
, bmbno
, &t
)) !=
3530 bno
= blkmap_get(blkmap
, bmbno
);
3531 if (bno
== NULLFSBLOCK
) {
3533 dbprintf(_("block %lld for rtbitmap inode is "
3535 (xfs_dfiloff_t
)bmbno
);
3540 set_cur(&typtab
[TYP_RTBITMAP
], XFS_FSB_TO_DADDR(mp
, bno
), blkbb
,
3542 if ((words
= iocur_top
->data
) == NULL
) {
3544 dbprintf(_("can't read block %lld for rtbitmap "
3546 (xfs_dfiloff_t
)bmbno
);
3552 bit
< bitsperblock
&& extno
< mp
->m_sb
.sb_rextents
;
3554 if (xfs_isset(words
, bit
)) {
3555 rtbno
= extno
* mp
->m_sb
.sb_rextsize
;
3556 set_rdbmap(rtbno
, mp
->m_sb
.sb_rextsize
,
3560 start_bmbno
= (int)bmbno
;
3564 } else if (prevbit
== 1) {
3565 len
= ((int)bmbno
- start_bmbno
) *
3566 bitsperblock
+ (bit
- start_bit
);
3567 log
= XFS_RTBLOCKLOG(len
);
3568 offs
= XFS_SUMOFFS(mp
, log
, start_bmbno
);
3574 if (extno
== mp
->m_sb
.sb_rextents
)
3578 len
= ((int)bmbno
- start_bmbno
) * bitsperblock
+
3580 log
= XFS_RTBLOCKLOG(len
);
3581 offs
= XFS_SUMOFFS(mp
, log
, start_bmbno
);
3592 xfs_fileoff_t sumbno
;
3595 sumbno
= NULLFILEOFF
;
3596 while ((sumbno
= blkmap_next_off(blkmap
, sumbno
, &t
)) != NULLFILEOFF
) {
3597 bno
= blkmap_get(blkmap
, sumbno
);
3598 if (bno
== NULLFSBLOCK
) {
3600 dbprintf(_("block %lld for rtsummary inode is "
3602 (xfs_dfiloff_t
)sumbno
);
3607 set_cur(&typtab
[TYP_RTSUMMARY
], XFS_FSB_TO_DADDR(mp
, bno
),
3608 blkbb
, DB_RING_IGN
, NULL
);
3609 if ((bytes
= iocur_top
->data
) == NULL
) {
3611 dbprintf(_("can't read block %lld for rtsummary "
3613 (xfs_dfiloff_t
)sumbno
);
3618 memcpy((char *)sumfile
+ sumbno
* mp
->m_sb
.sb_blocksize
, bytes
,
3619 mp
->m_sb
.sb_blocksize
);
3637 xfs_dir2_sf_entry_t
*sfe
;
3640 sf
= (xfs_dir2_sf_t
*)XFS_DFORK_DPTR(dip
);
3642 v
= verbose
|| id
->ilist
;
3644 dbprintf(_("dir %lld entry . %lld\n"), id
->ino
, id
->ino
);
3646 sfe
= xfs_dir2_sf_firstentry(sf
);
3647 offset
= XFS_DIR2_DATA_FIRST_OFFSET
;
3648 for (i
= sf
->hdr
.count
- 1, i8
= 0; i
>= 0; i
--) {
3649 if ((__psint_t
)sfe
+ xfs_dir2_sf_entsize_byentry(sf
, sfe
) -
3650 (__psint_t
)sf
> be64_to_cpu(dip
->di_size
)) {
3652 dbprintf(_("dir %llu bad size in entry at %d\n"),
3654 (int)((char *)sfe
- (char *)sf
));
3658 lino
= xfs_dir2_sf_get_inumber(sf
, xfs_dir2_sf_inumberp(sfe
));
3659 if (lino
> XFS_DIR2_MAX_SHORT_INUM
)
3661 cid
= find_inode(lino
, 1);
3664 dbprintf(_("dir %lld entry %*.*s bad inode "
3666 id
->ino
, sfe
->namelen
, sfe
->namelen
,
3673 addname_inode(cid
, (char *)sfe
->name
, sfe
->namelen
);
3676 dbprintf(_("dir %lld entry %*.*s offset %d %lld\n"),
3677 id
->ino
, sfe
->namelen
, sfe
->namelen
, sfe
->name
,
3678 xfs_dir2_sf_get_offset(sfe
), lino
);
3679 if (xfs_dir2_sf_get_offset(sfe
) < offset
) {
3681 dbprintf(_("dir %lld entry %*.*s bad offset %d\n"),
3682 id
->ino
, sfe
->namelen
, sfe
->namelen
,
3683 sfe
->name
, xfs_dir2_sf_get_offset(sfe
));
3687 xfs_dir2_sf_get_offset(sfe
) +
3688 xfs_dir2_data_entsize(sfe
->namelen
);
3689 sfe
= xfs_dir2_sf_nextentry(sf
, sfe
);
3691 if (i
< 0 && (__psint_t
)sfe
- (__psint_t
)sf
!=
3692 be64_to_cpu(dip
->di_size
)) {
3694 dbprintf(_("dir %llu size is %lld, should be %u\n"),
3695 id
->ino
, be64_to_cpu(dip
->di_size
),
3696 (uint
)((char *)sfe
- (char *)sf
));
3699 if (offset
+ (sf
->hdr
.count
+ 2) * sizeof(xfs_dir2_leaf_entry_t
) +
3700 sizeof(xfs_dir2_block_tail_t
) > mp
->m_dirblksize
) {
3702 dbprintf(_("dir %llu offsets too high\n"), id
->ino
);
3705 lino
= xfs_dir2_sf_get_inumber(sf
, &sf
->hdr
.parent
);
3706 if (lino
> XFS_DIR2_MAX_SHORT_INUM
)
3708 cid
= find_inode(lino
, 1);
3713 dbprintf(_("dir %lld entry .. bad inode number %lld\n"),
3718 dbprintf(_("dir %lld entry .. %lld\n"), id
->ino
, lino
);
3719 if (i8
!= sf
->hdr
.i8count
) {
3721 dbprintf(_("dir %lld i8count mismatch is %d should be "
3723 id
->ino
, sf
->hdr
.i8count
, i8
);
3727 return cid
? lino
: NULLFSINO
;
3731 process_shortform_dir_v1(
3740 xfs_dir_shortform_t
*sf
;
3741 xfs_dir_sf_entry_t
*sfe
;
3744 sf
= (xfs_dir_shortform_t
*)XFS_DFORK_DPTR(dip
);
3746 v
= verbose
|| id
->ilist
;
3748 dbprintf(_("dir %lld entry . %lld\n"), id
->ino
, id
->ino
);
3751 for (i
= sf
->hdr
.count
- 1; i
>= 0; i
--) {
3752 lino
= XFS_GET_DIR_INO8(sfe
->inumber
);
3753 cid
= find_inode(lino
, 1);
3756 dbprintf(_("dir %lld entry %*.*s bad inode "
3758 id
->ino
, sfe
->namelen
, sfe
->namelen
,
3765 addname_inode(cid
, (char *)sfe
->name
, sfe
->namelen
);
3768 dbprintf(_("dir %lld entry %*.*s %lld\n"), id
->ino
,
3769 sfe
->namelen
, sfe
->namelen
, sfe
->name
, lino
);
3770 sfe
= xfs_dir_sf_nextentry(sfe
);
3772 if ((__psint_t
)sfe
- (__psint_t
)sf
!= be64_to_cpu(dip
->di_size
))
3773 dbprintf(_("dir %llu size is %lld, should be %d\n"),
3774 id
->ino
, be64_to_cpu(dip
->di_size
),
3775 (int)((char *)sfe
- (char *)sf
));
3776 lino
= XFS_GET_DIR_INO8(sf
->hdr
.parent
);
3777 cid
= find_inode(lino
, 1);
3782 dbprintf(_("dir %lld entry .. bad inode number %lld\n"),
3787 dbprintf(_("dir %lld entry .. %lld\n"), id
->ino
, lino
);
3789 return cid
? lino
: NULLFSINO
;
3802 if (qudo
&& usrid
!= NULL
)
3803 quota_add1(qudata
, *usrid
, dq
, bc
, ic
, rc
);
3804 if (qgdo
&& grpid
!= NULL
)
3805 quota_add1(qgdata
, *grpid
, dq
, bc
, ic
, rc
);
3806 if (qpdo
&& prjid
!= NULL
)
3807 quota_add1(qpdata
, *prjid
, dq
, bc
, ic
, rc
);
3823 qh
= (int)(id
% QDATA_HASH_SIZE
);
3827 qi
= dq
? &qe
->dq
: &qe
->count
;
3835 qe
= xmalloc(sizeof(*qe
));
3837 qi
= dq
? &qe
->dq
: &qe
->count
;
3841 qi
= dq
? &qe
->count
: &qe
->dq
;
3842 qi
->bc
= qi
->ic
= qi
->rc
= 0;
3856 for (i
= 0; i
< QDATA_HASH_SIZE
; i
++) {
3860 if (qp
->count
.bc
!= qp
->dq
.bc
||
3861 qp
->count
.ic
!= qp
->dq
.ic
||
3862 qp
->count
.rc
!= qp
->dq
.rc
) {
3864 dbprintf(_("%s quota id %u, have/exp"),
3866 if (qp
->count
.bc
!= qp
->dq
.bc
)
3867 dbprintf(_(" bc %lld/%lld"),
3870 if (qp
->count
.ic
!= qp
->dq
.ic
)
3871 dbprintf(_(" ic %lld/%lld"),
3874 if (qp
->count
.rc
!= qp
->dq
.rc
)
3875 dbprintf(_(" rc %lld/%lld"),
3892 qudo
= mp
->m_sb
.sb_uquotino
!= 0 &&
3893 mp
->m_sb
.sb_uquotino
!= NULLFSINO
&&
3894 (mp
->m_sb
.sb_qflags
& XFS_UQUOTA_ACCT
) &&
3895 (mp
->m_sb
.sb_qflags
& XFS_UQUOTA_CHKD
);
3896 qgdo
= mp
->m_sb
.sb_gquotino
!= 0 &&
3897 mp
->m_sb
.sb_gquotino
!= NULLFSINO
&&
3898 (mp
->m_sb
.sb_qflags
& XFS_GQUOTA_ACCT
) &&
3899 (mp
->m_sb
.sb_qflags
& XFS_OQUOTA_CHKD
);
3900 qpdo
= mp
->m_sb
.sb_gquotino
!= 0 &&
3901 mp
->m_sb
.sb_gquotino
!= NULLFSINO
&&
3902 (mp
->m_sb
.sb_qflags
& XFS_PQUOTA_ACCT
) &&
3903 (mp
->m_sb
.sb_qflags
& XFS_OQUOTA_CHKD
);
3905 qudata
= xcalloc(QDATA_HASH_SIZE
, sizeof(qdata_t
*));
3907 qgdata
= xcalloc(QDATA_HASH_SIZE
, sizeof(qdata_t
*));
3909 qpdata
= xcalloc(QDATA_HASH_SIZE
, sizeof(qdata_t
*));
3914 xfs_agnumber_t agno
)
3920 xfs_sb_t
*sb
= &tsb
;
3922 agffreeblks
= agflongest
= 0;
3924 agicount
= agifreecount
= 0;
3925 push_cur(); /* 1 pushed */
3926 set_cur(&typtab
[TYP_SB
],
3927 XFS_AG_DADDR(mp
, agno
, XFS_SB_DADDR
),
3928 XFS_FSS_TO_BB(mp
, 1), DB_RING_IGN
, NULL
);
3930 if (!iocur_top
->data
) {
3931 dbprintf(_("can't read superblock for ag %u\n"), agno
);
3936 libxfs_sb_from_disk(sb
, iocur_top
->data
);
3938 if (sb
->sb_magicnum
!= XFS_SB_MAGIC
) {
3940 dbprintf(_("bad sb magic # %#x in ag %u\n"),
3941 sb
->sb_magicnum
, agno
);
3944 if (!xfs_sb_good_version(sb
)) {
3946 dbprintf(_("bad sb version # %#x in ag %u\n"),
3947 sb
->sb_versionnum
, agno
);
3951 if (!lazycount
&& xfs_sb_version_haslazysbcount(sb
)) {
3954 if (agno
== 0 && sb
->sb_inprogress
!= 0) {
3956 dbprintf(_("mkfs not completed successfully\n"));
3959 set_dbmap(agno
, XFS_SB_BLOCK(mp
), 1, DBM_SB
, agno
, XFS_SB_BLOCK(mp
));
3960 if (sb
->sb_logstart
&& XFS_FSB_TO_AGNO(mp
, sb
->sb_logstart
) == agno
)
3961 set_dbmap(agno
, XFS_FSB_TO_AGBNO(mp
, sb
->sb_logstart
),
3962 sb
->sb_logblocks
, DBM_LOG
, agno
, XFS_SB_BLOCK(mp
));
3963 push_cur(); /* 2 pushed */
3964 set_cur(&typtab
[TYP_AGF
],
3965 XFS_AG_DADDR(mp
, agno
, XFS_AGF_DADDR(mp
)),
3966 XFS_FSS_TO_BB(mp
, 1), DB_RING_IGN
, NULL
);
3967 if ((agf
= iocur_top
->data
) == NULL
) {
3968 dbprintf(_("can't read agf block for ag %u\n"), agno
);
3972 if (be32_to_cpu(agf
->agf_magicnum
) != XFS_AGF_MAGIC
) {
3974 dbprintf(_("bad agf magic # %#x in ag %u\n"),
3975 be32_to_cpu(agf
->agf_magicnum
), agno
);
3978 if (!XFS_AGF_GOOD_VERSION(be32_to_cpu(agf
->agf_versionnum
))) {
3980 dbprintf(_("bad agf version # %#x in ag %u\n"),
3981 be32_to_cpu(agf
->agf_versionnum
), agno
);
3984 if (XFS_SB_BLOCK(mp
) != XFS_AGF_BLOCK(mp
))
3985 set_dbmap(agno
, XFS_AGF_BLOCK(mp
), 1, DBM_AGF
, agno
,
3987 if (sb
->sb_agblocks
> be32_to_cpu(agf
->agf_length
))
3988 set_dbmap(agno
, be32_to_cpu(agf
->agf_length
),
3989 sb
->sb_agblocks
- be32_to_cpu(agf
->agf_length
),
3990 DBM_MISSING
, agno
, XFS_SB_BLOCK(mp
));
3991 push_cur(); /* 3 pushed */
3992 set_cur(&typtab
[TYP_AGI
],
3993 XFS_AG_DADDR(mp
, agno
, XFS_AGI_DADDR(mp
)),
3994 XFS_FSS_TO_BB(mp
, 1), DB_RING_IGN
, NULL
);
3995 if ((agi
= iocur_top
->data
) == NULL
) {
3996 dbprintf(_("can't read agi block for ag %u\n"), agno
);
4000 if (be32_to_cpu(agi
->agi_magicnum
) != XFS_AGI_MAGIC
) {
4002 dbprintf(_("bad agi magic # %#x in ag %u\n"),
4003 be32_to_cpu(agi
->agi_magicnum
), agno
);
4006 if (!XFS_AGI_GOOD_VERSION(be32_to_cpu(agi
->agi_versionnum
))) {
4008 dbprintf(_("bad agi version # %#x in ag %u\n"),
4009 be32_to_cpu(agi
->agi_versionnum
), agno
);
4012 if (XFS_SB_BLOCK(mp
) != XFS_AGI_BLOCK(mp
) &&
4013 XFS_AGF_BLOCK(mp
) != XFS_AGI_BLOCK(mp
))
4014 set_dbmap(agno
, XFS_AGI_BLOCK(mp
), 1, DBM_AGI
, agno
,
4019 be32_to_cpu(agf
->agf_roots
[XFS_BTNUM_BNO
]),
4020 be32_to_cpu(agf
->agf_levels
[XFS_BTNUM_BNO
]),
4021 1, scanfunc_bno
, TYP_BNOBT
);
4024 be32_to_cpu(agf
->agf_roots
[XFS_BTNUM_CNT
]),
4025 be32_to_cpu(agf
->agf_levels
[XFS_BTNUM_CNT
]),
4026 1, scanfunc_cnt
, TYP_CNTBT
);
4028 be32_to_cpu(agi
->agi_root
),
4029 be32_to_cpu(agi
->agi_level
),
4030 1, scanfunc_ino
, TYP_INOBT
);
4031 if (be32_to_cpu(agf
->agf_freeblks
) != agffreeblks
) {
4033 dbprintf(_("agf_freeblks %u, counted %u in ag %u\n"),
4034 be32_to_cpu(agf
->agf_freeblks
),
4038 if (be32_to_cpu(agf
->agf_longest
) != agflongest
) {
4040 dbprintf(_("agf_longest %u, counted %u in ag %u\n"),
4041 be32_to_cpu(agf
->agf_longest
),
4046 be32_to_cpu(agf
->agf_btreeblks
) != agfbtreeblks
) {
4048 dbprintf(_("agf_btreeblks %u, counted %u in ag %u\n"),
4049 be32_to_cpu(agf
->agf_btreeblks
),
4050 agfbtreeblks
, agno
);
4053 agf_aggr_freeblks
+= agffreeblks
+ agfbtreeblks
;
4054 if (be32_to_cpu(agi
->agi_count
) != agicount
) {
4056 dbprintf(_("agi_count %u, counted %u in ag %u\n"),
4057 be32_to_cpu(agi
->agi_count
),
4061 if (be32_to_cpu(agi
->agi_freecount
) != agifreecount
) {
4063 dbprintf(_("agi_freecount %u, counted %u in ag %u\n"),
4064 be32_to_cpu(agi
->agi_freecount
),
4065 agifreecount
, agno
);
4068 for (i
= 0; i
< XFS_AGI_UNLINKED_BUCKETS
; i
++) {
4069 if (be32_to_cpu(agi
->agi_unlinked
[i
]) != NULLAGINO
) {
4071 xfs_agino_t agino
=be32_to_cpu(agi
->agi_unlinked
[i
]);
4072 dbprintf(_("agi unlinked bucket %d is %u in ag "
4073 "%u (inode=%lld)\n"), i
, agino
, agno
,
4074 XFS_AGINO_TO_INO(mp
, agno
, agino
));
4091 xfs_agnumber_t seqno
= be32_to_cpu(agf
->agf_seqno
);
4097 if (XFS_SB_BLOCK(mp
) != XFS_AGFL_BLOCK(mp
) &&
4098 XFS_AGF_BLOCK(mp
) != XFS_AGFL_BLOCK(mp
) &&
4099 XFS_AGI_BLOCK(mp
) != XFS_AGFL_BLOCK(mp
))
4100 set_dbmap(seqno
, XFS_AGFL_BLOCK(mp
), 1, DBM_AGFL
, seqno
,
4102 if (be32_to_cpu(agf
->agf_flcount
) == 0)
4105 set_cur(&typtab
[TYP_AGFL
],
4106 XFS_AG_DADDR(mp
, seqno
, XFS_AGFL_DADDR(mp
)),
4107 XFS_FSS_TO_BB(mp
, 1), DB_RING_IGN
, NULL
);
4108 if ((agfl
= iocur_top
->data
) == NULL
) {
4109 dbprintf(_("can't read agfl block for ag %u\n"), seqno
);
4114 i
= be32_to_cpu(agf
->agf_flfirst
);
4117 bno
= be32_to_cpu(agfl
->agfl_bno
[i
]);
4118 set_dbmap(seqno
, bno
, 1, DBM_FREELIST
, seqno
,
4119 XFS_AGFL_BLOCK(mp
));
4121 if (i
== be32_to_cpu(agf
->agf_fllast
))
4123 if (++i
== XFS_AGFL_SIZE(mp
))
4126 if (count
!= be32_to_cpu(agf
->agf_flcount
)) {
4128 dbprintf(_("freeblk count %u != flcount %u in ag %u\n"),
4129 count
, be32_to_cpu(agf
->agf_flcount
),
4134 agf_aggr_freeblks
+= count
;
4142 scan_lbtree_f_t func
,
4145 xfs_drfsbno_t
*totd
,
4146 xfs_drfsbno_t
*toti
,
4153 set_cur(&typtab
[btype
], XFS_FSB_TO_DADDR(mp
, root
), blkbb
, DB_RING_IGN
,
4155 if (iocur_top
->data
== NULL
) {
4157 dbprintf(_("can't read btree block %u/%u\n"),
4158 XFS_FSB_TO_AGNO(mp
, root
),
4159 XFS_FSB_TO_AGBNO(mp
, root
));
4164 (*func
)(iocur_top
->data
, nlevels
- 1, type
, root
, id
, totd
, toti
, nex
,
4165 blkmapp
, isroot
, btype
);
4175 scan_sbtree_f_t func
,
4178 xfs_agnumber_t seqno
= be32_to_cpu(agf
->agf_seqno
);
4181 set_cur(&typtab
[btype
],
4182 XFS_AGB_TO_DADDR(mp
, seqno
, root
), blkbb
, DB_RING_IGN
, NULL
);
4183 if (iocur_top
->data
== NULL
) {
4185 dbprintf(_("can't read btree block %u/%u\n"), seqno
, root
);
4190 (*func
)(iocur_top
->data
, nlevels
- 1, agf
, root
, isroot
);
4196 struct xfs_btree_block
*block
,
4201 xfs_drfsbno_t
*totd
,
4202 xfs_drfsbno_t
*toti
,
4208 xfs_agblock_t agbno
;
4209 xfs_agnumber_t agno
;
4214 agno
= XFS_FSB_TO_AGNO(mp
, bno
);
4215 agbno
= XFS_FSB_TO_AGBNO(mp
, bno
);
4216 if (be32_to_cpu(block
->bb_magic
) != XFS_BMAP_MAGIC
) {
4217 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
4218 dbprintf(_("bad magic # %#x in inode %lld bmbt block "
4220 be32_to_cpu(block
->bb_magic
), id
->ino
, agno
, agbno
);
4223 if (be16_to_cpu(block
->bb_level
) != level
) {
4224 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
4225 dbprintf(_("expected level %d got %d in inode %lld bmbt "
4227 level
, be16_to_cpu(block
->bb_level
), id
->ino
, agno
, agbno
);
4230 set_dbmap(agno
, agbno
, 1, type
, agno
, agbno
);
4231 set_inomap(agno
, agbno
, 1, id
);
4234 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_bmap_dmxr
[0] ||
4235 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_bmap_dmnr
[0])) {
4236 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
4237 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) "
4238 "in inode %lld bmap block %lld\n"),
4239 be16_to_cpu(block
->bb_numrecs
), mp
->m_bmap_dmnr
[0],
4240 mp
->m_bmap_dmxr
[0], id
->ino
,
4245 rp
= XFS_BMBT_REC_ADDR(mp
, block
, 1);
4246 *nex
+= be16_to_cpu(block
->bb_numrecs
);
4247 process_bmbt_reclist(rp
, be16_to_cpu(block
->bb_numrecs
), type
, id
, totd
,
4251 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_bmap_dmxr
[1] ||
4252 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_bmap_dmnr
[1])) {
4253 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
4254 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in "
4255 "inode %lld bmap block %lld\n"),
4256 be16_to_cpu(block
->bb_numrecs
), mp
->m_bmap_dmnr
[1],
4257 mp
->m_bmap_dmxr
[1], id
->ino
, (xfs_dfsbno_t
)bno
);
4261 pp
= XFS_BMBT_PTR_ADDR(mp
, block
, 1, mp
->m_bmap_dmxr
[0]);
4262 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++)
4263 scan_lbtree(be64_to_cpu(pp
[i
]), level
, scanfunc_bmap
, type
, id
,
4264 totd
, toti
, nex
, blkmapp
, 0, btype
);
4269 struct xfs_btree_block
*block
,
4276 xfs_alloc_ptr_t
*pp
;
4277 xfs_alloc_rec_t
*rp
;
4278 xfs_agnumber_t seqno
= be32_to_cpu(agf
->agf_seqno
);
4279 xfs_agblock_t lastblock
;
4281 if (be32_to_cpu(block
->bb_magic
) != XFS_ABTB_MAGIC
) {
4282 dbprintf(_("bad magic # %#x in btbno block %u/%u\n"),
4283 be32_to_cpu(block
->bb_magic
), seqno
, bno
);
4289 if (be16_to_cpu(block
->bb_level
) != level
) {
4291 dbprintf(_("expected level %d got %d in btbno block "
4293 level
, be16_to_cpu(block
->bb_level
), seqno
, bno
);
4296 set_dbmap(seqno
, bno
, 1, DBM_BTBNO
, seqno
, bno
);
4298 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_alloc_mxr
[0] ||
4299 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_alloc_mnr
[0])) {
4300 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in "
4301 "btbno block %u/%u\n"),
4302 be16_to_cpu(block
->bb_numrecs
), mp
->m_alloc_mnr
[0],
4303 mp
->m_alloc_mxr
[0], seqno
, bno
);
4307 rp
= XFS_ALLOC_REC_ADDR(mp
, block
, 1);
4309 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++) {
4310 set_dbmap(seqno
, be32_to_cpu(rp
[i
].ar_startblock
),
4311 be32_to_cpu(rp
[i
].ar_blockcount
), DBM_FREE1
,
4313 if (be32_to_cpu(rp
[i
].ar_startblock
) <= lastblock
) {
4315 "out-of-order bno btree record %d (%u %u) block %u/%u\n"),
4316 i
, be32_to_cpu(rp
[i
].ar_startblock
),
4317 be32_to_cpu(rp
[i
].ar_blockcount
),
4318 be32_to_cpu(agf
->agf_seqno
), bno
);
4321 lastblock
= be32_to_cpu(rp
[i
].ar_startblock
);
4326 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_alloc_mxr
[1] ||
4327 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_alloc_mnr
[1])) {
4328 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in btbno block "
4330 be16_to_cpu(block
->bb_numrecs
), mp
->m_alloc_mnr
[1],
4331 mp
->m_alloc_mxr
[1], seqno
, bno
);
4335 pp
= XFS_ALLOC_PTR_ADDR(mp
, block
, 1, mp
->m_alloc_mxr
[1]);
4336 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++)
4337 scan_sbtree(agf
, be32_to_cpu(pp
[i
]), level
, 0, scanfunc_bno
, TYP_BNOBT
);
4342 struct xfs_btree_block
*block
,
4348 xfs_agnumber_t seqno
= be32_to_cpu(agf
->agf_seqno
);
4350 xfs_alloc_ptr_t
*pp
;
4351 xfs_alloc_rec_t
*rp
;
4352 xfs_extlen_t lastcount
;
4354 if (be32_to_cpu(block
->bb_magic
) != XFS_ABTC_MAGIC
) {
4355 dbprintf(_("bad magic # %#x in btcnt block %u/%u\n"),
4356 be32_to_cpu(block
->bb_magic
), seqno
, bno
);
4362 if (be16_to_cpu(block
->bb_level
) != level
) {
4364 dbprintf(_("expected level %d got %d in btcnt block "
4366 level
, be16_to_cpu(block
->bb_level
), seqno
, bno
);
4369 set_dbmap(seqno
, bno
, 1, DBM_BTCNT
, seqno
, bno
);
4371 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_alloc_mxr
[0] ||
4372 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_alloc_mnr
[0])) {
4373 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in "
4374 "btbno block %u/%u\n"),
4375 be16_to_cpu(block
->bb_numrecs
), mp
->m_alloc_mnr
[0],
4376 mp
->m_alloc_mxr
[0], seqno
, bno
);
4380 rp
= XFS_ALLOC_REC_ADDR(mp
, block
, 1);
4382 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++) {
4383 check_set_dbmap(seqno
, be32_to_cpu(rp
[i
].ar_startblock
),
4384 be32_to_cpu(rp
[i
].ar_blockcount
), DBM_FREE1
, DBM_FREE2
,
4386 fdblocks
+= be32_to_cpu(rp
[i
].ar_blockcount
);
4387 agffreeblks
+= be32_to_cpu(rp
[i
].ar_blockcount
);
4388 if (be32_to_cpu(rp
[i
].ar_blockcount
) > agflongest
)
4389 agflongest
= be32_to_cpu(rp
[i
].ar_blockcount
);
4390 if (be32_to_cpu(rp
[i
].ar_blockcount
) < lastcount
) {
4392 "out-of-order cnt btree record %d (%u %u) block %u/%u\n"),
4393 i
, be32_to_cpu(rp
[i
].ar_startblock
),
4394 be32_to_cpu(rp
[i
].ar_blockcount
),
4395 be32_to_cpu(agf
->agf_seqno
), bno
);
4397 lastcount
= be32_to_cpu(rp
[i
].ar_blockcount
);
4402 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_alloc_mxr
[1] ||
4403 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_alloc_mnr
[1])) {
4404 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in btbno block "
4406 be16_to_cpu(block
->bb_numrecs
), mp
->m_alloc_mnr
[1],
4407 mp
->m_alloc_mxr
[1], seqno
, bno
);
4411 pp
= XFS_ALLOC_PTR_ADDR(mp
, block
, 1, mp
->m_alloc_mxr
[1]);
4412 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++)
4413 scan_sbtree(agf
, be32_to_cpu(pp
[i
]), level
, 0, scanfunc_cnt
, TYP_CNTBT
);
4418 struct xfs_btree_block
*block
,
4425 xfs_agnumber_t seqno
= be32_to_cpu(agf
->agf_seqno
);
4431 xfs_inobt_ptr_t
*pp
;
4432 xfs_inobt_rec_t
*rp
;
4434 if (be32_to_cpu(block
->bb_magic
) != XFS_IBT_MAGIC
) {
4435 dbprintf(_("bad magic # %#x in inobt block %u/%u\n"),
4436 be32_to_cpu(block
->bb_magic
), seqno
, bno
);
4440 if (be16_to_cpu(block
->bb_level
) != level
) {
4442 dbprintf(_("expected level %d got %d in inobt block "
4444 level
, be16_to_cpu(block
->bb_level
), seqno
, bno
);
4447 set_dbmap(seqno
, bno
, 1, DBM_BTINO
, seqno
, bno
);
4449 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_inobt_mxr
[0] ||
4450 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_inobt_mnr
[0])) {
4451 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in "
4452 "inobt block %u/%u\n"),
4453 be16_to_cpu(block
->bb_numrecs
), mp
->m_inobt_mnr
[0],
4454 mp
->m_inobt_mxr
[0], seqno
, bno
);
4458 rp
= XFS_INOBT_REC_ADDR(mp
, block
, 1);
4459 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++) {
4460 agino
= be32_to_cpu(rp
[i
].ir_startino
);
4461 off
= XFS_INO_TO_OFFSET(mp
, agino
);
4463 if ((sbversion
& XFS_SB_VERSION_ALIGNBIT
) &&
4464 mp
->m_sb
.sb_inoalignmt
&&
4465 (XFS_INO_TO_AGBNO(mp
, agino
) %
4466 mp
->m_sb
.sb_inoalignmt
))
4467 sbversion
&= ~XFS_SB_VERSION_ALIGNBIT
;
4468 set_dbmap(seqno
, XFS_AGINO_TO_AGBNO(mp
, agino
),
4469 (xfs_extlen_t
)MAX(1,
4470 XFS_INODES_PER_CHUNK
>>
4471 mp
->m_sb
.sb_inopblog
),
4472 DBM_INODE
, seqno
, bno
);
4474 icount
+= XFS_INODES_PER_CHUNK
;
4475 agicount
+= XFS_INODES_PER_CHUNK
;
4476 ifree
+= be32_to_cpu(rp
[i
].ir_freecount
);
4477 agifreecount
+= be32_to_cpu(rp
[i
].ir_freecount
);
4479 set_cur(&typtab
[TYP_INODE
],
4480 XFS_AGB_TO_DADDR(mp
, seqno
,
4481 XFS_AGINO_TO_AGBNO(mp
, agino
)),
4482 (int)XFS_FSB_TO_BB(mp
, XFS_IALLOC_BLOCKS(mp
)),
4484 if (iocur_top
->data
== NULL
) {
4486 dbprintf(_("can't read inode block "
4489 XFS_AGINO_TO_AGBNO(mp
, agino
));
4494 for (j
= 0, nfree
= 0; j
< XFS_INODES_PER_CHUNK
; j
++) {
4495 isfree
= XFS_INOBT_IS_FREE_DISK(&rp
[i
], j
);
4498 process_inode(agf
, agino
+ j
,
4499 (xfs_dinode_t
*)((char *)iocur_top
->data
+ ((off
+ j
) << mp
->m_sb
.sb_inodelog
)),
4502 if (nfree
!= be32_to_cpu(rp
[i
].ir_freecount
)) {
4504 dbprintf(_("ir_freecount/free mismatch, "
4505 "inode chunk %u/%u, freecount "
4508 be32_to_cpu(rp
[i
].ir_freecount
), nfree
);
4515 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_inobt_mxr
[1] ||
4516 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_inobt_mnr
[1])) {
4517 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in inobt block "
4519 be16_to_cpu(block
->bb_numrecs
), mp
->m_inobt_mnr
[1],
4520 mp
->m_inobt_mxr
[1], seqno
, bno
);
4524 pp
= XFS_INOBT_PTR_ADDR(mp
, block
, 1, mp
->m_inobt_mxr
[1]);
4525 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++)
4526 scan_sbtree(agf
, be32_to_cpu(pp
[i
]), level
, 0, scanfunc_ino
, TYP_INOBT
);
4531 xfs_agnumber_t agno
,
4532 xfs_agblock_t agbno
,
4535 xfs_agnumber_t c_agno
,
4536 xfs_agblock_t c_agbno
)
4538 check_set_dbmap(agno
, agbno
, len
, DBM_UNKNOWN
, type
, c_agno
, c_agbno
);
4543 xfs_agnumber_t agno
,
4544 xfs_agblock_t agbno
,
4552 if (!check_inomap(agno
, agbno
, len
, id
->ino
))
4554 mayprint
= verbose
| id
->ilist
| blist_size
;
4555 for (i
= 0, idp
= &inomap
[agno
][agbno
]; i
< len
; i
++, idp
++) {
4558 (verbose
|| id
->ilist
|| CHECK_BLISTA(agno
, agbno
+ i
)))
4559 dbprintf(_("setting inode to %lld for block %u/%u\n"),
4560 id
->ino
, agno
, agbno
+ i
);
4570 check_set_rdbmap(bno
, len
, DBM_UNKNOWN
, type
);
4583 if (!check_rinomap(bno
, len
, id
->ino
))
4585 mayprint
= verbose
| id
->ilist
| blist_size
;
4586 for (i
= 0, idp
= &inomap
[mp
->m_sb
.sb_agcount
][bno
];
4590 if (mayprint
&& (verbose
|| id
->ilist
|| CHECK_BLIST(bno
+ i
)))
4591 dbprintf(_("setting inode to %lld for rtblock %llu\n"),
4603 id
->link_set
= nlink
;
4605 id
->security
= security
;
4606 if (verbose
|| id
->ilist
)
4607 dbprintf(_("inode %lld nlink %u %s dir\n"), id
->ino
, nlink
,
4608 isdir
? "is" : "not");