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>
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
,
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
[] = {
177 #define CHECK_BLIST(b) (blist_size && check_blist(b))
178 #define CHECK_BLISTA(a,b) \
179 (blist_size && check_blist(XFS_AGB_TO_FSB(mp, a, b)))
181 typedef void (*scan_lbtree_f_t
)(struct xfs_btree_block
*block
,
193 typedef void (*scan_sbtree_f_t
)(struct xfs_btree_block
*block
,
199 static void add_blist(xfs_fsblock_t bno
);
200 static void add_ilist(xfs_ino_t ino
);
201 static void addlink_inode(inodata_t
*id
);
202 static void addname_inode(inodata_t
*id
, char *name
, int namelen
);
203 static void addparent_inode(inodata_t
*id
, xfs_ino_t parent
);
204 static void blkent_append(blkent_t
**entp
, xfs_fsblock_t b
,
206 static blkent_t
*blkent_new(xfs_fileoff_t o
, xfs_fsblock_t b
,
208 static void blkent_prepend(blkent_t
**entp
, xfs_fsblock_t b
,
210 static blkmap_t
*blkmap_alloc(xfs_extnum_t
);
211 static void blkmap_free(blkmap_t
*blkmap
);
212 static xfs_fsblock_t
blkmap_get(blkmap_t
*blkmap
, xfs_fileoff_t o
);
213 static int blkmap_getn(blkmap_t
*blkmap
, xfs_fileoff_t o
, int nb
,
215 static void blkmap_grow(blkmap_t
**blkmapp
, blkent_t
**entp
,
217 static xfs_fileoff_t
blkmap_next_off(blkmap_t
*blkmap
, xfs_fileoff_t o
,
219 static void blkmap_set_blk(blkmap_t
**blkmapp
, xfs_fileoff_t o
,
221 static void blkmap_set_ext(blkmap_t
**blkmapp
, xfs_fileoff_t o
,
222 xfs_fsblock_t b
, xfs_extlen_t c
);
223 static void blkmap_shrink(blkmap_t
*blkmap
, blkent_t
**entp
);
224 static int blockfree_f(int argc
, char **argv
);
225 static int blockget_f(int argc
, char **argv
);
226 static int blocktrash_f(int argc
, char **argv
);
227 static int blockuse_f(int argc
, char **argv
);
228 static int check_blist(xfs_fsblock_t bno
);
229 static void check_dbmap(xfs_agnumber_t agno
, xfs_agblock_t agbno
,
230 xfs_extlen_t len
, dbm_t type
);
231 static int check_inomap(xfs_agnumber_t agno
, xfs_agblock_t agbno
,
232 xfs_extlen_t len
, xfs_ino_t c_ino
);
233 static void check_linkcounts(xfs_agnumber_t agno
);
234 static int check_range(xfs_agnumber_t agno
, xfs_agblock_t agbno
,
236 static void check_rdbmap(xfs_drfsbno_t bno
, xfs_extlen_t len
,
238 static int check_rinomap(xfs_drfsbno_t bno
, xfs_extlen_t len
,
240 static void check_rootdir(void);
241 static int check_rrange(xfs_drfsbno_t bno
, xfs_extlen_t len
);
242 static void check_set_dbmap(xfs_agnumber_t agno
,
243 xfs_agblock_t agbno
, xfs_extlen_t len
,
244 dbm_t type1
, dbm_t type2
,
245 xfs_agnumber_t c_agno
,
246 xfs_agblock_t c_agbno
);
247 static void check_set_rdbmap(xfs_drfsbno_t bno
, xfs_extlen_t len
,
248 dbm_t type1
, dbm_t type2
);
249 static void check_summary(void);
250 static void checknot_dbmap(xfs_agnumber_t agno
, xfs_agblock_t agbno
,
251 xfs_extlen_t len
, int typemask
);
252 static void checknot_rdbmap(xfs_drfsbno_t bno
, xfs_extlen_t len
,
254 static void dir_hash_add(xfs_dahash_t hash
,
255 xfs_dir2_dataptr_t addr
);
256 static void dir_hash_check(inodata_t
*id
, int v
);
257 static void dir_hash_done(void);
258 static void dir_hash_init(void);
259 static int dir_hash_see(xfs_dahash_t hash
,
260 xfs_dir2_dataptr_t addr
);
261 static inodata_t
*find_inode(xfs_ino_t ino
, int add
);
262 static void free_inodata(xfs_agnumber_t agno
);
263 static int init(int argc
, char **argv
);
264 static char *inode_name(xfs_ino_t ino
, inodata_t
**ipp
);
265 static int ncheck_f(int argc
, char **argv
);
266 static char *prepend_path(char *oldpath
, char *parent
);
267 static xfs_ino_t
process_block_dir_v2(blkmap_t
*blkmap
, int *dot
,
268 int *dotdot
, inodata_t
*id
);
269 static void process_bmbt_reclist(xfs_bmbt_rec_t
*rp
, int numrecs
,
270 dbm_t type
, inodata_t
*id
,
273 static void process_btinode(inodata_t
*id
, xfs_dinode_t
*dip
,
274 dbm_t type
, xfs_drfsbno_t
*totd
,
275 xfs_drfsbno_t
*toti
, xfs_extnum_t
*nex
,
276 blkmap_t
**blkmapp
, int whichfork
);
277 static xfs_ino_t
process_data_dir_v2(int *dot
, int *dotdot
,
278 inodata_t
*id
, int v
,
280 freetab_t
**freetabp
);
281 static xfs_dir2_data_free_t
*process_data_dir_v2_freefind(
282 struct xfs_dir2_data_hdr
*data
,
283 struct xfs_dir2_data_unused
*dup
);
284 static void process_dir(xfs_dinode_t
*dip
, blkmap_t
*blkmap
,
286 static int process_dir_v2(xfs_dinode_t
*dip
, blkmap_t
*blkmap
,
287 int *dot
, int *dotdot
, inodata_t
*id
,
289 static void process_exinode(inodata_t
*id
, xfs_dinode_t
*dip
,
290 dbm_t type
, xfs_drfsbno_t
*totd
,
291 xfs_drfsbno_t
*toti
, xfs_extnum_t
*nex
,
292 blkmap_t
**blkmapp
, int whichfork
);
293 static void process_inode(xfs_agf_t
*agf
, xfs_agino_t agino
,
294 xfs_dinode_t
*dip
, int isfree
);
295 static void process_lclinode(inodata_t
*id
, xfs_dinode_t
*dip
,
296 dbm_t type
, xfs_drfsbno_t
*totd
,
297 xfs_drfsbno_t
*toti
, xfs_extnum_t
*nex
,
298 blkmap_t
**blkmapp
, int whichfork
);
299 static xfs_ino_t
process_leaf_node_dir_v2(blkmap_t
*blkmap
, int *dot
,
300 int *dotdot
, inodata_t
*id
,
301 xfs_fsize_t dirsize
);
302 static void process_leaf_node_dir_v2_free(inodata_t
*id
, int v
,
305 static void process_leaf_node_dir_v2_int(inodata_t
*id
, int v
,
308 static void process_quota(qtype_t qtype
, inodata_t
*id
,
310 static void process_rtbitmap(blkmap_t
*blkmap
);
311 static void process_rtsummary(blkmap_t
*blkmap
);
312 static xfs_ino_t
process_sf_dir_v2(xfs_dinode_t
*dip
, int *dot
,
313 int *dotdot
, inodata_t
*id
);
314 static void quota_add(xfs_dqid_t
*p
, xfs_dqid_t
*g
, xfs_dqid_t
*u
,
315 int dq
, xfs_qcnt_t bc
, xfs_qcnt_t ic
,
317 static void quota_add1(qdata_t
**qt
, xfs_dqid_t id
, int dq
,
318 xfs_qcnt_t bc
, xfs_qcnt_t ic
,
320 static void quota_check(char *s
, qdata_t
**qt
);
321 static void quota_init(void);
322 static void scan_ag(xfs_agnumber_t agno
);
323 static void scan_freelist(xfs_agf_t
*agf
);
324 static void scan_lbtree(xfs_fsblock_t root
, int nlevels
,
325 scan_lbtree_f_t func
, dbm_t type
,
326 inodata_t
*id
, xfs_drfsbno_t
*totd
,
327 xfs_drfsbno_t
*toti
, xfs_extnum_t
*nex
,
328 blkmap_t
**blkmapp
, int isroot
,
330 static void scan_sbtree(xfs_agf_t
*agf
, xfs_agblock_t root
,
331 int nlevels
, int isroot
,
332 scan_sbtree_f_t func
, typnm_t btype
);
333 static void scanfunc_bmap(struct xfs_btree_block
*block
,
334 int level
, dbm_t type
, xfs_fsblock_t bno
,
335 inodata_t
*id
, xfs_drfsbno_t
*totd
,
336 xfs_drfsbno_t
*toti
, xfs_extnum_t
*nex
,
337 blkmap_t
**blkmapp
, int isroot
,
339 static void scanfunc_bno(struct xfs_btree_block
*block
, int level
,
340 xfs_agf_t
*agf
, xfs_agblock_t bno
,
342 static void scanfunc_cnt(struct xfs_btree_block
*block
, int level
,
343 xfs_agf_t
*agf
, xfs_agblock_t bno
,
345 static void scanfunc_ino(struct xfs_btree_block
*block
, int level
,
346 xfs_agf_t
*agf
, xfs_agblock_t bno
,
348 static void set_dbmap(xfs_agnumber_t agno
, xfs_agblock_t agbno
,
349 xfs_extlen_t len
, dbm_t type
,
350 xfs_agnumber_t c_agno
, xfs_agblock_t c_agbno
);
351 static void set_inomap(xfs_agnumber_t agno
, xfs_agblock_t agbno
,
352 xfs_extlen_t len
, inodata_t
*id
);
353 static void set_rdbmap(xfs_drfsbno_t bno
, xfs_extlen_t len
,
355 static void set_rinomap(xfs_drfsbno_t bno
, xfs_extlen_t len
,
357 static void setlink_inode(inodata_t
*id
, nlink_t nlink
, int isdir
,
360 static const cmdinfo_t blockfree_cmd
=
361 { "blockfree", NULL
, blockfree_f
, 0, 0, 0,
362 NULL
, N_("free block usage information"), NULL
};
363 static const cmdinfo_t blockget_cmd
=
364 { "blockget", "check", blockget_f
, 0, -1, 0,
365 N_("[-s|-v] [-n] [-t] [-b bno]... [-i ino] ..."),
366 N_("get block usage and check consistency"), NULL
};
367 static const cmdinfo_t blocktrash_cmd
=
368 { "blocktrash", NULL
, blocktrash_f
, 0, -1, 0,
369 N_("[-n count] [-x minlen] [-y maxlen] [-s seed] [-0123] [-t type] ..."),
370 N_("trash randomly selected block(s)"), NULL
};
371 static const cmdinfo_t blockuse_cmd
=
372 { "blockuse", NULL
, blockuse_f
, 0, 3, 0,
373 N_("[-n] [-c blockcount]"),
374 N_("print usage for current block(s)"), NULL
};
375 static const cmdinfo_t ncheck_cmd
=
376 { "ncheck", NULL
, ncheck_f
, 0, -1, 0,
377 N_("[-s] [-i ino] ..."),
378 N_("print inode-name pairs"), NULL
};
386 blist
= xrealloc(blist
, blist_size
* sizeof(bno
));
387 blist
[blist_size
- 1] = bno
;
396 id
= find_inode(ino
, 1);
398 dbprintf(_("-i %lld bad inode number\n"), ino
);
409 if (verbose
|| id
->ilist
)
410 dbprintf(_("inode %lld add link, now %u\n"), id
->ino
,
420 if (!nflag
|| id
->name
)
422 id
->name
= xmalloc(namelen
+ 1);
423 memcpy(id
->name
, name
, namelen
);
424 id
->name
[namelen
] = '\0';
434 pid
= find_inode(parent
, 1);
436 if (verbose
|| id
->ilist
|| (pid
&& pid
->ilist
))
437 dbprintf(_("inode %lld parent %lld\n"), id
->ino
, parent
);
450 *entp
= ent
= xrealloc(ent
, BLKENT_SIZE(c
+ ent
->nblks
));
451 for (i
= 0; i
< c
; i
++)
452 ent
->blks
[ent
->nblks
+ i
] = b
+ i
;
465 ent
= xmalloc(BLKENT_SIZE(c
));
468 for (i
= 0; i
< c
; i
++)
469 ent
->blks
[i
] = b
+ i
;
484 newent
= xmalloc(BLKENT_SIZE(oldent
->nblks
+ c
));
485 newent
->nblks
= oldent
->nblks
+ c
;
486 newent
->startoff
= oldent
->startoff
- c
;
487 for (i
= 0; i
< c
; i
++)
488 newent
->blks
[i
] = b
+ c
;
489 for (; i
< oldent
->nblks
+ c
; i
++)
490 newent
->blks
[i
] = oldent
->blks
[i
- c
];
503 blkmap
= xmalloc(BLKMAP_SIZE(nex
));
504 blkmap
->naents
= nex
;
516 for (i
= 0, entp
= blkmap
->ents
; i
< blkmap
->nents
; i
++, entp
++)
530 for (i
= 0, entp
= blkmap
->ents
; i
< blkmap
->nents
; i
++, entp
++) {
532 if (o
>= ent
->startoff
&& o
< ent
->startoff
+ ent
->nblks
)
533 return ent
->blks
[o
- ent
->startoff
];
552 for (i
= nex
= 0, bmp
= NULL
, entp
= blkmap
->ents
;
556 if (ent
->startoff
>= o
+ nb
)
558 if (ent
->startoff
+ ent
->nblks
<= o
)
560 for (ento
= ent
->startoff
;
561 ento
< ent
->startoff
+ ent
->nblks
&& ento
< o
+ nb
;
566 bmp
[nex
- 1].startoff
+ bmp
[nex
- 1].blockcount
==
568 bmp
[nex
- 1].startblock
+ bmp
[nex
- 1].blockcount
==
569 ent
->blks
[ento
- ent
->startoff
])
570 bmp
[nex
- 1].blockcount
++;
572 bmp
= realloc(bmp
, ++nex
* sizeof(*bmp
));
573 bmp
[nex
- 1].startoff
= ento
;
574 bmp
[nex
- 1].startblock
=
575 ent
->blks
[ento
- ent
->startoff
];
576 bmp
[nex
- 1].blockcount
= 1;
577 bmp
[nex
- 1].flag
= 0;
596 idx
= (int)(entp
- blkmap
->ents
);
597 if (blkmap
->naents
== blkmap
->nents
) {
598 blkmap
= xrealloc(blkmap
, BLKMAP_SIZE(blkmap
->nents
+ 1));
602 for (i
= blkmap
->nents
; i
> idx
; i
--)
603 blkmap
->ents
[i
] = blkmap
->ents
[i
- 1];
604 blkmap
->ents
[idx
] = newent
;
616 ent
= blkmap
->ents
[blkmap
->nents
- 1];
617 return ent
->startoff
+ ent
->nblks
;
631 if (o
== NULLFILEOFF
) {
633 ent
= blkmap
->ents
[0];
634 return ent
->startoff
;
636 entp
= &blkmap
->ents
[*t
];
638 if (o
< ent
->startoff
+ ent
->nblks
- 1)
641 if (entp
>= &blkmap
->ents
[blkmap
->nents
])
645 return ent
->startoff
;
660 for (entp
= blkmap
->ents
; entp
< &blkmap
->ents
[blkmap
->nents
]; entp
++) {
662 if (o
< ent
->startoff
- 1) {
663 ent
= blkent_new(o
, b
, 1);
664 blkmap_grow(blkmapp
, entp
, ent
);
667 if (o
== ent
->startoff
- 1) {
668 blkent_prepend(entp
, b
, 1);
671 if (o
>= ent
->startoff
&& o
< ent
->startoff
+ ent
->nblks
) {
672 ent
->blks
[o
- ent
->startoff
] = b
;
675 if (o
> ent
->startoff
+ ent
->nblks
)
677 blkent_append(entp
, b
, 1);
678 if (entp
== &blkmap
->ents
[blkmap
->nents
- 1])
682 if (ent
->startoff
+ ent
->nblks
< nextent
->startoff
)
684 blkent_append(entp
, nextent
->blks
[0], nextent
->nblks
);
685 blkmap_shrink(blkmap
, &entp
[1]);
688 ent
= blkent_new(o
, b
, 1);
689 blkmap_grow(blkmapp
, entp
, ent
);
705 if (!blkmap
->nents
) {
706 blkmap
->ents
[0] = blkent_new(o
, b
, c
);
710 entp
= &blkmap
->ents
[blkmap
->nents
- 1];
712 if (ent
->startoff
+ ent
->nblks
== o
) {
713 blkent_append(entp
, b
, c
);
716 if (ent
->startoff
+ ent
->nblks
< o
) {
717 ent
= blkent_new(o
, b
, c
);
718 blkmap_grow(blkmapp
, &blkmap
->ents
[blkmap
->nents
], ent
);
721 for (i
= 0; i
< c
; i
++)
722 blkmap_set_blk(blkmapp
, o
+ i
, b
+ i
);
734 idx
= (int)(entp
- blkmap
->ents
);
735 for (i
= idx
+ 1; i
< blkmap
->nents
; i
++)
736 blkmap
->ents
[i
] = blkmap
->ents
[i
- 1];
750 dbprintf(_("block usage information not allocated\n"));
753 rt
= mp
->m_sb
.sb_rextents
!= 0;
754 for (c
= 0; c
< mp
->m_sb
.sb_agcount
; c
++) {
764 sumcompute
= sumfile
= NULL
;
776 * Check consistency of xfs filesystem contents.
788 dbprintf(_("already have block usage information\n"));
793 * XXX: check does not support CRC enabled filesystems. Return
794 * immediately, silently, with success but without doing anything here
795 * initially so that xfstests can run without modification on metadata
796 * enabled filesystems.
798 * XXX: ultimately we need to dump an error message here that xfstests
799 * filters out, or we need to actually do the work to make check support
800 * crc enabled filesystems.
802 if (xfs_sb_version_hascrc(&mp
->m_sb
))
805 if (!init(argc
, argv
)) {
812 oldprefix
= dbprefix
;
814 for (agno
= 0, sbyell
= 0; agno
< mp
->m_sb
.sb_agcount
; agno
++) {
816 if (sbver_err
> 4 && !sbyell
&& sbver_err
>= agno
) {
818 dbprintf(_("WARNING: this may be a newer XFS "
829 dbprefix
= oldprefix
;
834 * Check that there are no blocks either
835 * a) unaccounted for or
836 * b) bno-free but not cnt-free
838 if (!tflag
) { /* are we in test mode, faking out freespace? */
839 for (agno
= 0; agno
< mp
->m_sb
.sb_agcount
; agno
++)
840 checknot_dbmap(agno
, 0, mp
->m_sb
.sb_agblocks
,
841 (1 << DBM_UNKNOWN
) | (1 << DBM_FREE1
));
843 for (agno
= 0; agno
< mp
->m_sb
.sb_agcount
; agno
++)
844 check_linkcounts(agno
);
845 if (mp
->m_sb
.sb_rblocks
) {
847 (xfs_extlen_t
)(mp
->m_sb
.sb_rextents
*
848 mp
->m_sb
.sb_rextsize
),
852 if (mp
->m_sb
.sb_icount
!= icount
) {
854 dbprintf(_("sb_icount %lld, counted %lld\n"),
855 mp
->m_sb
.sb_icount
, icount
);
858 if (mp
->m_sb
.sb_ifree
!= ifree
) {
860 dbprintf(_("sb_ifree %lld, counted %lld\n"),
861 mp
->m_sb
.sb_ifree
, ifree
);
864 if (mp
->m_sb
.sb_fdblocks
!= fdblocks
) {
866 dbprintf(_("sb_fdblocks %lld, counted %lld\n"),
867 mp
->m_sb
.sb_fdblocks
, fdblocks
);
870 if (lazycount
&& mp
->m_sb
.sb_fdblocks
!= agf_aggr_freeblks
) {
872 dbprintf(_("sb_fdblocks %lld, aggregate AGF count %lld\n"),
873 mp
->m_sb
.sb_fdblocks
, agf_aggr_freeblks
);
876 if (mp
->m_sb
.sb_frextents
!= frextents
) {
878 dbprintf(_("sb_frextents %lld, counted %lld\n"),
879 mp
->m_sb
.sb_frextents
, frextents
);
882 if (mp
->m_sb
.sb_bad_features2
!= 0 &&
883 mp
->m_sb
.sb_bad_features2
!= mp
->m_sb
.sb_features2
) {
885 dbprintf(_("sb_features2 (0x%x) not same as "
886 "sb_bad_features2 (0x%x)\n"),
887 mp
->m_sb
.sb_features2
,
888 mp
->m_sb
.sb_bad_features2
);
891 if ((sbversion
& XFS_SB_VERSION_ATTRBIT
) &&
892 !xfs_sb_version_hasattr(&mp
->m_sb
)) {
894 dbprintf(_("sb versionnum missing attr bit %x\n"),
895 XFS_SB_VERSION_ATTRBIT
);
898 if ((sbversion
& XFS_SB_VERSION_QUOTABIT
) &&
899 !xfs_sb_version_hasquota(&mp
->m_sb
)) {
901 dbprintf(_("sb versionnum missing quota bit %x\n"),
902 XFS_SB_VERSION_QUOTABIT
);
905 if (!(sbversion
& XFS_SB_VERSION_ALIGNBIT
) &&
906 xfs_sb_version_hasalign(&mp
->m_sb
)) {
908 dbprintf(_("sb versionnum extra align bit %x\n"),
909 XFS_SB_VERSION_ALIGNBIT
);
913 quota_check("user", qudata
);
915 quota_check("project", qpdata
);
917 quota_check("group", qgdata
);
918 if (sbver_err
> mp
->m_sb
.sb_agcount
/ 2)
919 dbprintf(_("WARNING: this may be a newer XFS filesystem.\n"));
922 dbprefix
= oldprefix
;
926 typedef struct ltab
{
947 static char *modestr
[] = {
948 N_("zeroed"), N_("set"), N_("flipped"), N_("randomized")
951 len
= (int)((random() % (ltabp
->max
- ltabp
->min
+ 1)) + ltabp
->min
);
952 offset
= (int)(random() % (int)(mp
->m_sb
.sb_blocksize
* NBBY
));
955 set_cur(&typtab
[DBM_UNKNOWN
],
956 XFS_AGB_TO_DADDR(mp
, agno
, agbno
), blkbb
, DB_RING_IGN
, NULL
);
957 if ((buf
= iocur_top
->data
) == NULL
) {
958 dbprintf(_("can't read block %u/%u for trashing\n"), agno
, agbno
);
962 for (bitno
= 0; bitno
< len
; bitno
++) {
963 bit
= (offset
+ bitno
) % (mp
->m_sb
.sb_blocksize
* NBBY
);
975 newbit
= (buf
[byte
] & mask
) == 0;
978 newbit
= (int)random() & 1;
988 printf(_("blocktrash: %u/%u %s block %d bit%s starting %d:%d %s\n"),
989 agno
, agbno
, typename
[type
], len
, len
== 1 ? "" : "s",
990 offset
/ NBBY
, offset
% NBBY
, modestr
[mode
]);
1001 xfs_drfsbno_t blocks
;
1014 xfs_drfsbno_t randb
;
1020 dbprintf(_("must run blockget first\n"));
1028 gettimeofday(&now
, NULL
);
1029 seed
= (unsigned int)(now
.tv_sec
^ now
.tv_usec
);
1032 goodmask
= (1 << DBM_AGF
) |
1036 (1 << DBM_BTBMAPA
) |
1037 (1 << DBM_BTBMAPD
) |
1044 (1 << DBM_RTBITMAP
) |
1047 while ((c
= getopt(argc
, argv
, "0123n:s:t:x:y:")) != EOF
) {
1062 count
= (int)strtol(optarg
, &p
, 0);
1063 if (*p
!= '\0' || count
<= 0) {
1064 dbprintf(_("bad blocktrash count %s\n"), optarg
);
1069 seed
= (uint
)strtoul(optarg
, &p
, 0);
1073 for (i
= 0; typename
[i
]; i
++) {
1074 if (strcmp(typename
[i
], optarg
) == 0)
1077 if (!typename
[i
] || (((1 << i
) & goodmask
) == 0)) {
1078 dbprintf(_("bad blocktrash type %s\n"), optarg
);
1084 min
= (int)strtol(optarg
, &p
, 0);
1085 if (*p
!= '\0' || min
<= 0 ||
1086 min
> mp
->m_sb
.sb_blocksize
* NBBY
) {
1087 dbprintf(_("bad blocktrash min %s\n"), optarg
);
1092 max
= (int)strtol(optarg
, &p
, 0);
1093 if (*p
!= '\0' || max
<= 0 ||
1094 max
> mp
->m_sb
.sb_blocksize
* NBBY
) {
1095 dbprintf(_("bad blocktrash max %s\n"), optarg
);
1100 dbprintf(_("bad option for blocktrash command\n"));
1105 dbprintf(_("bad min/max for blocktrash command\n"));
1110 lentab
= xmalloc(sizeof(ltab_t
));
1111 lentab
->min
= lentab
->max
= min
;
1113 for (i
= min
+ 1; i
<= max
; i
++) {
1114 if ((i
& (i
- 1)) == 0) {
1115 lentab
= xrealloc(lentab
,
1116 sizeof(ltab_t
) * (lentablen
+ 1));
1117 lentab
[lentablen
].min
= lentab
[lentablen
].max
= i
;
1120 lentab
[lentablen
- 1].max
= i
;
1122 for (blocks
= 0, agno
= 0; agno
< mp
->m_sb
.sb_agcount
; agno
++) {
1123 for (agbno
= 0, p
= dbmap
[agno
];
1124 agbno
< mp
->m_sb
.sb_agblocks
;
1126 if ((1 << *p
) & tmask
)
1131 dbprintf(_("blocktrash: no matching blocks\n"));
1135 dbprintf(_("blocktrash: seed %u\n"), seed
);
1137 for (i
= 0; i
< count
; i
++) {
1138 randb
= (xfs_drfsbno_t
)((((__int64_t
)random() << 32) |
1139 random()) % blocks
);
1140 for (bi
= 0, agno
= 0, done
= 0;
1141 !done
&& agno
< mp
->m_sb
.sb_agcount
;
1143 for (agbno
= 0, p
= dbmap
[agno
];
1144 agbno
< mp
->m_sb
.sb_agblocks
;
1146 if (!((1 << *p
) & tmask
))
1150 blocktrash_b(agno
, agbno
, (dbm_t
)*p
,
1151 &lentab
[random() % lentablen
], mode
);
1167 xfs_agblock_t agbno
;
1168 xfs_agnumber_t agno
;
1178 dbprintf(_("must run blockget first\n"));
1183 fsb
= XFS_DADDR_TO_FSB(mp
, iocur_top
->off
>> BBSHIFT
);
1184 agno
= XFS_FSB_TO_AGNO(mp
, fsb
);
1185 end
= agbno
= XFS_FSB_TO_AGBNO(mp
, fsb
);
1186 while ((c
= getopt(argc
, argv
, "c:n")) != EOF
) {
1189 count
= (int)strtol(optarg
, &p
, 0);
1190 end
= agbno
+ count
- 1;
1191 if (*p
!= '\0' || count
<= 0 ||
1192 end
>= mp
->m_sb
.sb_agblocks
) {
1193 dbprintf(_("bad blockuse count %s\n"), optarg
);
1199 dbprintf(_("must run blockget -n first\n"));
1205 dbprintf(_("bad option for blockuse command\n"));
1209 while (agbno
<= end
) {
1210 p
= &dbmap
[agno
][agbno
];
1211 i
= inomap
[agno
][agbno
];
1212 dbprintf(_("block %llu (%u/%u) type %s"),
1213 (xfs_dfsbno_t
)XFS_AGB_TO_FSB(mp
, agno
, agbno
),
1214 agno
, agbno
, typename
[(dbm_t
)*p
]);
1216 dbprintf(_(" inode %lld"), i
->ino
);
1217 if (shownames
&& (p
= inode_name(i
->ino
, NULL
))) {
1234 for (i
= 0; i
< blist_size
; i
++) {
1235 if (blist
[i
] == bno
)
1243 xfs_agnumber_t agno
,
1244 xfs_agblock_t agbno
,
1251 for (i
= 0, p
= &dbmap
[agno
][agbno
]; i
< len
; i
++, p
++) {
1252 if ((dbm_t
)*p
!= type
) {
1253 if (!sflag
|| CHECK_BLISTA(agno
, agbno
+ i
))
1254 dbprintf(_("block %u/%u expected type %s got "
1256 agno
, agbno
+ i
, typename
[type
],
1257 typename
[(dbm_t
)*p
]);
1266 add_command(&blockfree_cmd
);
1267 add_command(&blockget_cmd
);
1269 add_command(&blocktrash_cmd
);
1270 add_command(&blockuse_cmd
);
1271 add_command(&ncheck_cmd
);
1276 xfs_agnumber_t agno
,
1277 xfs_agblock_t agbno
,
1285 if (!check_range(agno
, agbno
, len
)) {
1286 dbprintf(_("blocks %u/%u..%u claimed by inode %lld\n"),
1287 agno
, agbno
, agbno
+ len
- 1, c_ino
);
1290 for (i
= 0, rval
= 1, idp
= &inomap
[agno
][agbno
]; i
< len
; i
++, idp
++) {
1292 if (!sflag
|| (*idp
)->ilist
||
1293 CHECK_BLISTA(agno
, agbno
+ i
))
1294 dbprintf(_("block %u/%u claimed by inode %lld, "
1295 "previous inum %lld\n"),
1296 agno
, agbno
+ i
, c_ino
, (*idp
)->ino
);
1306 xfs_agnumber_t agno
)
1314 for (idx
= 0; idx
< inodata_hash_size
; ht
++, idx
++) {
1317 if (ep
->link_set
!= ep
->link_add
|| ep
->link_set
== 0) {
1318 path
= inode_name(ep
->ino
, NULL
);
1319 if (!path
&& ep
->link_add
)
1320 path
= xstrdup("?");
1321 if (!sflag
|| ep
->ilist
) {
1323 dbprintf(_("link count mismatch "
1324 "for inode %lld (name "
1330 else if (ep
->link_set
)
1331 dbprintf(_("disconnected inode "
1332 "%lld, nlink %d\n"),
1333 ep
->ino
, ep
->link_set
);
1335 dbprintf(_("allocated inode %lld "
1336 "has 0 link count\n"),
1342 } else if (verbose
|| ep
->ilist
) {
1343 path
= inode_name(ep
->ino
, NULL
);
1345 dbprintf(_("inode %lld name %s\n"),
1358 xfs_agnumber_t agno
,
1359 xfs_agblock_t agbno
,
1363 xfs_agblock_t low
= 0;
1364 xfs_agblock_t high
= 0;
1365 int valid_range
= 0;
1368 if (agno
>= mp
->m_sb
.sb_agcount
||
1369 agbno
+ len
- 1 >= mp
->m_sb
.sb_agblocks
) {
1370 for (i
= 0; i
< len
; i
++) {
1371 cur
= !sflag
|| CHECK_BLISTA(agno
, agbno
+ i
) ? 1 : 0;
1372 if (cur
== 1 && prev
== 0) {
1373 low
= high
= agbno
+ i
;
1375 } else if (cur
== 0 && prev
== 0) {
1377 } else if (cur
== 0 && prev
== 1) {
1379 dbprintf(_("block %u/%u out of range\n"),
1382 dbprintf(_("blocks %u/%u..%u "
1387 } else if (cur
== 1 && prev
== 1) {
1394 dbprintf(_("block %u/%u out of range\n"),
1397 dbprintf(_("blocks %u/%u..%u "
1417 for (i
= 0, p
= &dbmap
[mp
->m_sb
.sb_agcount
][bno
]; i
< len
; i
++, p
++) {
1418 if ((dbm_t
)*p
!= type
) {
1419 if (!sflag
|| CHECK_BLIST(bno
+ i
))
1420 dbprintf(_("rtblock %llu expected type %s got "
1422 bno
+ i
, typename
[type
],
1423 typename
[(dbm_t
)*p
]);
1439 if (!check_rrange(bno
, len
)) {
1440 dbprintf(_("rtblocks %llu..%llu claimed by inode %lld\n"),
1441 bno
, bno
+ len
- 1, c_ino
);
1444 for (i
= 0, rval
= 1, idp
= &inomap
[mp
->m_sb
.sb_agcount
][bno
];
1448 if (!sflag
|| (*idp
)->ilist
|| CHECK_BLIST(bno
+ i
))
1449 dbprintf(_("rtblock %llu claimed by inode %lld, "
1450 "previous inum %lld\n"),
1451 bno
+ i
, c_ino
, (*idp
)->ino
);
1464 id
= find_inode(mp
->m_sb
.sb_rootino
, 0);
1467 dbprintf(_("root inode %lld is missing\n"),
1468 mp
->m_sb
.sb_rootino
);
1470 } else if (!id
->isdir
) {
1471 if (!sflag
|| id
->ilist
)
1472 dbprintf(_("root inode %lld is not a directory\n"),
1473 mp
->m_sb
.sb_rootino
);
1485 if (bno
+ len
- 1 >= mp
->m_sb
.sb_rblocks
) {
1486 for (i
= 0; i
< len
; i
++) {
1487 if (!sflag
|| CHECK_BLIST(bno
+ i
))
1488 dbprintf(_("rtblock %llu out of range\n"),
1499 xfs_agnumber_t agno
,
1500 xfs_agblock_t agbno
,
1504 xfs_agnumber_t c_agno
,
1505 xfs_agblock_t c_agbno
)
1511 if (!check_range(agno
, agbno
, len
)) {
1512 dbprintf(_("blocks %u/%u..%u claimed by block %u/%u\n"), agno
,
1513 agbno
, agbno
+ len
- 1, c_agno
, c_agbno
);
1516 check_dbmap(agno
, agbno
, len
, type1
);
1517 mayprint
= verbose
| blist_size
;
1518 for (i
= 0, p
= &dbmap
[agno
][agbno
]; i
< len
; i
++, p
++) {
1520 if (mayprint
&& (verbose
|| CHECK_BLISTA(agno
, agbno
+ i
)))
1521 dbprintf(_("setting block %u/%u to %s\n"), agno
, agbno
+ i
,
1537 if (!check_rrange(bno
, len
))
1539 check_rdbmap(bno
, len
, type1
);
1540 mayprint
= verbose
| blist_size
;
1541 for (i
= 0, p
= &dbmap
[mp
->m_sb
.sb_agcount
][bno
]; i
< len
; i
++, p
++) {
1543 if (mayprint
&& (verbose
|| CHECK_BLIST(bno
+ i
)))
1544 dbprintf(_("setting rtblock %llu to %s\n"),
1545 bno
+ i
, typename
[type2
]);
1559 for (log
= 0; log
< mp
->m_rsumlevels
; log
++) {
1561 bno
< mp
->m_sb
.sb_rbmblocks
;
1562 bno
++, csp
++, fsp
++) {
1565 dbprintf(_("rt summary mismatch, size %d "
1566 "block %llu, file: %d, "
1568 log
, bno
, *fsp
, *csp
);
1577 xfs_agnumber_t agno
,
1578 xfs_agblock_t agbno
,
1585 if (!check_range(agno
, agbno
, len
))
1587 for (i
= 0, p
= &dbmap
[agno
][agbno
]; i
< len
; i
++, p
++) {
1588 if ((1 << *p
) & typemask
) {
1589 if (!sflag
|| CHECK_BLISTA(agno
, agbno
+ i
))
1590 dbprintf(_("block %u/%u type %s not expected\n"),
1591 agno
, agbno
+ i
, typename
[(dbm_t
)*p
]);
1606 if (!check_rrange(bno
, len
))
1608 for (i
= 0, p
= &dbmap
[mp
->m_sb
.sb_agcount
][bno
]; i
< len
; i
++, p
++) {
1609 if ((1 << *p
) & typemask
) {
1610 if (!sflag
|| CHECK_BLIST(bno
+ i
))
1611 dbprintf(_("rtblock %llu type %s not expected\n"),
1612 bno
+ i
, typename
[(dbm_t
)*p
]);
1621 xfs_dir2_dataptr_t addr
)
1626 i
= DIR_HASH_FUNC(hash
, addr
);
1627 p
= malloc(sizeof(*p
));
1628 p
->next
= dirhash
[i
];
1643 for (i
= 0; i
< DIR_HASH_SIZE
; i
++) {
1644 for (p
= dirhash
[i
]; p
; p
= p
->next
) {
1647 if (!sflag
|| id
->ilist
|| v
)
1648 dbprintf(_("dir ino %lld missing leaf entry for "
1650 id
->ino
, p
->hashval
, p
->address
);
1663 for (i
= 0; i
< DIR_HASH_SIZE
; i
++) {
1664 for (p
= dirhash
[i
]; p
; p
= n
) {
1676 dirhash
= calloc(DIR_HASH_SIZE
, sizeof(*dirhash
));
1682 xfs_dir2_dataptr_t addr
)
1687 i
= DIR_HASH_FUNC(hash
, addr
);
1688 for (p
= dirhash
[i
]; p
; p
= p
->next
) {
1689 if (p
->hashval
== hash
&& p
->address
== addr
) {
1705 xfs_agnumber_t agno
;
1710 agno
= XFS_INO_TO_AGNO(mp
, ino
);
1711 agino
= XFS_INO_TO_AGINO(mp
, ino
);
1712 if (agno
>= mp
->m_sb
.sb_agcount
||
1713 XFS_AGINO_TO_INO(mp
, agno
, agino
) != ino
)
1715 htab
= inodata
[agno
];
1716 ih
= agino
% inodata_hash_size
;
1719 if (ent
->ino
== ino
)
1725 ent
= xcalloc(1, sizeof(*ent
));
1727 ent
->next
= htab
[ih
];
1734 xfs_agnumber_t agno
)
1742 for (i
= 0; i
< inodata_hash_size
; i
++) {
1766 if (mp
->m_sb
.sb_magicnum
!= XFS_SB_MAGIC
) {
1767 dbprintf(_("bad superblock magic number %x, giving up\n"),
1768 mp
->m_sb
.sb_magicnum
);
1774 rt
= mp
->m_sb
.sb_rextents
!= 0;
1775 dbmap
= xmalloc((mp
->m_sb
.sb_agcount
+ rt
) * sizeof(*dbmap
));
1776 inomap
= xmalloc((mp
->m_sb
.sb_agcount
+ rt
) * sizeof(*inomap
));
1777 inodata
= xmalloc(mp
->m_sb
.sb_agcount
* sizeof(*inodata
));
1779 (int)MAX(MIN(mp
->m_sb
.sb_icount
/
1780 (INODATA_AVG_HASH_LENGTH
* mp
->m_sb
.sb_agcount
),
1781 MAX_INODATA_HASH_SIZE
),
1782 MIN_INODATA_HASH_SIZE
);
1783 for (c
= 0; c
< mp
->m_sb
.sb_agcount
; c
++) {
1784 dbmap
[c
] = xcalloc(mp
->m_sb
.sb_agblocks
, sizeof(**dbmap
));
1785 inomap
[c
] = xcalloc(mp
->m_sb
.sb_agblocks
, sizeof(**inomap
));
1786 inodata
[c
] = xcalloc(inodata_hash_size
, sizeof(**inodata
));
1789 dbmap
[c
] = xcalloc(mp
->m_sb
.sb_rblocks
, sizeof(**dbmap
));
1790 inomap
[c
] = xcalloc(mp
->m_sb
.sb_rblocks
, sizeof(**inomap
));
1791 sumfile
= xcalloc(mp
->m_rsumsize
, 1);
1792 sumcompute
= xcalloc(mp
->m_rsumsize
, 1);
1794 nflag
= sflag
= tflag
= verbose
= optind
= 0;
1795 while ((c
= getopt(argc
, argv
, "b:i:npstv")) != EOF
) {
1798 bno
= strtoll(optarg
, NULL
, 10);
1802 ino
= strtoll(optarg
, NULL
, 10);
1821 dbprintf(_("bad option for blockget command\n"));
1825 error
= sbver_err
= serious_error
= 0;
1826 fdblocks
= frextents
= icount
= ifree
= 0;
1827 sbversion
= XFS_SB_VERSION_4
;
1829 * Note that inoalignmt == 0 is valid when fsb size is large enough for
1830 * at least one full inode record per block. Check this case explicitly.
1832 if (mp
->m_sb
.sb_inoalignmt
||
1833 (xfs_sb_version_hasalign(&mp
->m_sb
) &&
1834 mp
->m_sb
.sb_inopblock
>= XFS_INODES_PER_CHUNK
))
1835 sbversion
|= XFS_SB_VERSION_ALIGNBIT
;
1836 if ((mp
->m_sb
.sb_uquotino
&& mp
->m_sb
.sb_uquotino
!= NULLFSINO
) ||
1837 (mp
->m_sb
.sb_gquotino
&& mp
->m_sb
.sb_gquotino
!= NULLFSINO
) ||
1838 (mp
->m_sb
.sb_pquotino
&& mp
->m_sb
.sb_pquotino
!= NULLFSINO
))
1839 sbversion
|= XFS_SB_VERSION_QUOTABIT
;
1853 id
= find_inode(ino
, 0);
1858 if (id
->name
== NULL
)
1860 path
= xstrdup(id
->name
);
1861 while (id
->parent
) {
1863 if (id
->name
== NULL
)
1865 npath
= prepend_path(path
, id
->name
);
1877 xfs_agnumber_t agno
;
1890 if (!inodata
|| !nflag
) {
1891 dbprintf(_("must run blockget -n first\n"));
1894 security
= optind
= ilist_size
= 0;
1896 while ((c
= getopt(argc
, argv
, "i:s")) != EOF
) {
1899 ino
= strtoll(optarg
, NULL
, 10);
1900 ilist
= xrealloc(ilist
, (ilist_size
+ 1) *
1902 ilist
[ilist_size
++] = ino
;
1908 dbprintf(_("bad option -%c for ncheck command\n"), c
);
1914 for (ilp
= ilist
; ilp
< &ilist
[ilist_size
]; ilp
++) {
1916 if ((p
= inode_name(ino
, &hp
))) {
1917 dbprintf("%11llu %s", ino
, p
);
1927 for (agno
= 0; agno
< mp
->m_sb
.sb_agcount
; agno
++) {
1929 for (i
= 0; i
< inodata_hash_size
; i
++) {
1931 for (hp
= ht
[i
]; hp
; hp
= hp
->next
) {
1932 ino
= XFS_AGINO_TO_INO(mp
, agno
, hp
->ino
);
1933 p
= inode_name(ino
, &id
);
1936 if (!security
|| id
->security
) {
1937 dbprintf("%11llu %s", ino
, p
);
1957 len
= (int)(strlen(oldpath
) + strlen(parent
) + 2);
1958 path
= xmalloc(len
);
1959 snprintf(path
, len
, "%s/%s", parent
, oldpath
);
1964 process_block_dir_v2(
1978 nex
= blkmap_getn(blkmap
, 0, mp
->m_dir_geo
->fsbcount
, &bmp
);
1979 v
= id
->ilist
|| verbose
;
1982 dbprintf(_("block 0 for directory inode %lld is "
1990 make_bbmap(&bbmap
, nex
, bmp
);
1991 set_cur(&typtab
[TYP_DIR2
], XFS_FSB_TO_DADDR(mp
, bmp
->startblock
),
1992 mp
->m_dir_geo
->fsbcount
* blkbb
, DB_RING_IGN
, nex
> 1 ? &bbmap
: NULL
);
1993 for (x
= 0; !v
&& x
< nex
; x
++) {
1994 for (b
= bmp
[x
].startblock
;
1995 !v
&& b
< bmp
[x
].startblock
+ bmp
[x
].blockcount
;
2000 if (iocur_top
->data
== NULL
) {
2001 if (!sflag
|| id
->ilist
|| v
)
2002 dbprintf(_("can't read block 0 for directory inode "
2010 parent
= process_data_dir_v2(dot
, dotdot
, id
, v
, mp
->m_dir_geo
->datablk
,
2012 dir_hash_check(id
, v
);
2019 process_bmbt_reclist(
2027 xfs_agblock_t agbno
;
2028 xfs_agnumber_t agno
;
2034 xfs_agblock_t iagbno
;
2035 xfs_agnumber_t iagno
;
2042 v
= verbose
|| id
->ilist
;
2043 iagno
= XFS_INO_TO_AGNO(mp
, id
->ino
);
2044 iagbno
= XFS_INO_TO_AGBNO(mp
, id
->ino
);
2045 for (i
= 0; i
< numrecs
; i
++, rp
++) {
2046 convert_extent(rp
, &o
, &s
, &c
, &f
);
2048 dbprintf(_("inode %lld extent [%lld,%lld,%lld,%d]\n"),
2049 id
->ino
, o
, s
, c
, f
);
2050 if (!sflag
&& i
> 0 && op
+ cp
> o
)
2051 dbprintf(_("bmap rec out of order, inode %lld entry %d\n"),
2055 if (type
== DBM_RTDATA
) {
2056 if (!sflag
&& s
>= mp
->m_sb
.sb_rblocks
) {
2057 dbprintf(_("inode %lld bad rt block number %lld, "
2062 } else if (!sflag
) {
2063 agno
= XFS_FSB_TO_AGNO(mp
, s
);
2064 agbno
= XFS_FSB_TO_AGBNO(mp
, s
);
2065 if (agno
>= mp
->m_sb
.sb_agcount
||
2066 agbno
>= mp
->m_sb
.sb_agblocks
) {
2067 dbprintf(_("inode %lld bad block number %lld "
2068 "[%d,%d], offset %lld\n"),
2069 id
->ino
, s
, agno
, agbno
, o
);
2072 if (agbno
+ c
- 1 >= mp
->m_sb
.sb_agblocks
) {
2073 dbprintf(_("inode %lld bad block number %lld "
2074 "[%d,%d], offset %lld\n"),
2075 id
->ino
, s
+ c
- 1, agno
,
2076 agbno
+ (xfs_agblock_t
)c
- 1, o
);
2080 if (blkmapp
&& *blkmapp
)
2081 blkmap_set_ext(blkmapp
, (xfs_fileoff_t
)o
,
2082 (xfs_fsblock_t
)s
, (xfs_extlen_t
)c
);
2083 if (type
== DBM_RTDATA
) {
2084 set_rdbmap((xfs_fsblock_t
)s
, (xfs_extlen_t
)c
,
2086 set_rinomap((xfs_fsblock_t
)s
, (xfs_extlen_t
)c
, id
);
2087 for (b
= (xfs_fsblock_t
)s
;
2088 blist_size
&& b
< s
+ c
;
2091 dbprintf(_("inode %lld block %lld at "
2093 id
->ino
, (xfs_dfsbno_t
)b
, o
);
2096 agno
= XFS_FSB_TO_AGNO(mp
, (xfs_fsblock_t
)s
);
2097 agbno
= XFS_FSB_TO_AGBNO(mp
, (xfs_fsblock_t
)s
);
2098 set_dbmap(agno
, agbno
, (xfs_extlen_t
)c
, type
, iagno
,
2100 set_inomap(agno
, agbno
, (xfs_extlen_t
)c
, id
);
2101 for (b
= (xfs_fsblock_t
)s
;
2102 blist_size
&& b
< s
+ c
;
2103 b
++, o
++, agbno
++) {
2105 dbprintf(_("inode %lld block %lld at "
2107 id
->ino
, (xfs_dfsbno_t
)b
, o
);
2119 xfs_drfsbno_t
*totd
,
2120 xfs_drfsbno_t
*toti
,
2125 xfs_bmdr_block_t
*dib
;
2129 dib
= (xfs_bmdr_block_t
*)XFS_DFORK_PTR(dip
, whichfork
);
2130 if (be16_to_cpu(dib
->bb_level
) >= XFS_BM_MAXLEVELS(mp
, whichfork
)) {
2131 if (!sflag
|| id
->ilist
)
2132 dbprintf(_("level for ino %lld %s fork bmap root too "
2135 whichfork
== XFS_DATA_FORK
? _("data") : _("attr"),
2136 be16_to_cpu(dib
->bb_level
));
2140 if (be16_to_cpu(dib
->bb_numrecs
) >
2141 xfs_bmdr_maxrecs(XFS_DFORK_SIZE(dip
, mp
, whichfork
),
2142 be16_to_cpu(dib
->bb_level
) == 0)) {
2143 if (!sflag
|| id
->ilist
)
2144 dbprintf(_("numrecs for ino %lld %s fork bmap root too "
2147 whichfork
== XFS_DATA_FORK
? _("data") : _("attr"),
2148 be16_to_cpu(dib
->bb_numrecs
));
2152 if (be16_to_cpu(dib
->bb_level
) == 0) {
2153 xfs_bmbt_rec_t
*rp
= XFS_BMDR_REC_ADDR(dib
, 1);
2154 process_bmbt_reclist(rp
, be16_to_cpu(dib
->bb_numrecs
), type
,
2156 *nex
+= be16_to_cpu(dib
->bb_numrecs
);
2159 pp
= XFS_BMDR_PTR_ADDR(dib
, 1, xfs_bmdr_maxrecs(
2160 XFS_DFORK_SIZE(dip
, mp
, whichfork
), 0));
2161 for (i
= 0; i
< be16_to_cpu(dib
->bb_numrecs
); i
++)
2162 scan_lbtree(be64_to_cpu(pp
[i
]),
2163 be16_to_cpu(dib
->bb_level
),
2164 scanfunc_bmap
, type
, id
, totd
, toti
,
2166 whichfork
== XFS_DATA_FORK
?
2167 TYP_BMAPBTD
: TYP_BMAPBTA
);
2169 if (*nex
<= XFS_DFORK_SIZE(dip
, mp
, whichfork
) / sizeof(xfs_bmbt_rec_t
)) {
2170 if (!sflag
|| id
->ilist
)
2171 dbprintf(_("extent count for ino %lld %s fork too low "
2172 "(%d) for file format\n"),
2174 whichfork
== XFS_DATA_FORK
? _("data") : _("attr"),
2181 process_data_dir_v2(
2187 freetab_t
**freetabp
)
2189 xfs_dir2_dataptr_t addr
;
2190 xfs_dir2_data_free_t
*bf
;
2192 struct xfs_dir2_data_hdr
*block
;
2193 xfs_dir2_block_tail_t
*btp
= NULL
;
2196 struct xfs_dir2_data_hdr
*data
;
2198 xfs_dir2_data_entry_t
*dep
;
2199 xfs_dir2_data_free_t
*dfp
;
2200 xfs_dir2_data_unused_t
*dup
;
2207 xfs_dir2_leaf_entry_t
*lep
= NULL
;
2209 xfs_ino_t parent
= 0;
2214 struct xfs_name xname
;
2216 data
= iocur_top
->data
;
2217 block
= iocur_top
->data
;
2218 if (be32_to_cpu(block
->magic
) != XFS_DIR2_BLOCK_MAGIC
&&
2219 be32_to_cpu(data
->magic
) != XFS_DIR2_DATA_MAGIC
) {
2221 dbprintf(_("bad directory data magic # %#x for dir ino "
2223 be32_to_cpu(data
->magic
), id
->ino
, dabno
);
2227 db
= xfs_dir2_da_to_db(mp
->m_dir_geo
, dabno
);
2228 bf
= M_DIROPS(mp
)->data_bestfree_p(data
);
2229 ptr
= (char *)M_DIROPS(mp
)->data_unused_p(data
);
2230 if (be32_to_cpu(block
->magic
) == XFS_DIR2_BLOCK_MAGIC
) {
2231 btp
= xfs_dir2_block_tail_p(mp
->m_dir_geo
, block
);
2232 lep
= xfs_dir2_block_leaf_p(btp
);
2233 endptr
= (char *)lep
;
2234 if (endptr
<= ptr
|| endptr
> (char *)btp
) {
2235 endptr
= (char *)data
+ mp
->m_dir_geo
->blksize
;
2238 dbprintf(_("bad block directory tail for dir ino "
2244 endptr
= (char *)data
+ mp
->m_dir_geo
->blksize
;
2245 bf_err
= lastfree_err
= tag_err
= 0;
2246 count
= lastfree
= freeseen
= 0;
2247 if (be16_to_cpu(bf
[0].length
) == 0) {
2248 bf_err
+= be16_to_cpu(bf
[0].offset
) != 0;
2251 if (be16_to_cpu(bf
[1].length
) == 0) {
2252 bf_err
+= be16_to_cpu(bf
[1].offset
) != 0;
2255 if (be16_to_cpu(bf
[2].length
) == 0) {
2256 bf_err
+= be16_to_cpu(bf
[2].offset
) != 0;
2259 bf_err
+= be16_to_cpu(bf
[0].length
) < be16_to_cpu(bf
[1].length
);
2260 bf_err
+= be16_to_cpu(bf
[1].length
) < be16_to_cpu(bf
[2].length
);
2262 freetab
= *freetabp
;
2263 if (freetab
->naents
<= db
) {
2264 *freetabp
= freetab
=
2265 realloc(freetab
, FREETAB_SIZE(db
+ 1));
2266 for (i
= freetab
->naents
; i
< db
; i
++)
2267 freetab
->ents
[i
] = NULLDATAOFF
;
2268 freetab
->naents
= db
+ 1;
2270 if (freetab
->nents
< db
+ 1)
2271 freetab
->nents
= db
+ 1;
2272 freetab
->ents
[db
] = be16_to_cpu(bf
[0].length
);
2274 while (ptr
< endptr
) {
2275 dup
= (xfs_dir2_data_unused_t
*)ptr
;
2276 if (be16_to_cpu(dup
->freetag
) == XFS_DIR2_DATA_FREE_TAG
) {
2277 lastfree_err
+= lastfree
!= 0;
2278 tagp
= xfs_dir2_data_unused_tag_p(dup
);
2279 if ((be16_to_cpu(dup
->length
) & (XFS_DIR2_DATA_ALIGN
- 1)) ||
2280 be16_to_cpu(dup
->length
) == 0 ||
2281 (char *)tagp
>= endptr
) {
2283 dbprintf(_("dir %lld block %d bad free "
2291 tag_err
+= be16_to_cpu(*tagp
) != (char *)dup
- (char *)data
;
2292 dfp
= process_data_dir_v2_freefind(data
, dup
);
2294 i
= (int)(dfp
- bf
);
2295 bf_err
+= (freeseen
& (1 << i
)) != 0;
2298 bf_err
+= be16_to_cpu(dup
->length
) >
2299 be16_to_cpu(bf
[2].length
);
2300 ptr
+= be16_to_cpu(dup
->length
);
2304 dep
= (xfs_dir2_data_entry_t
*)dup
;
2305 if (dep
->namelen
== 0) {
2307 dbprintf(_("dir %lld block %d zero length entry "
2310 (int)((char *)dep
- (char *)data
));
2313 tagp
= M_DIROPS(mp
)->data_entry_tag_p(dep
);
2314 if ((char *)tagp
>= endptr
) {
2316 dbprintf(_("dir %lld block %d bad entry at %d\n"),
2318 (int)((char *)dep
- (char *)data
));
2322 tag_err
+= be16_to_cpu(*tagp
) != (char *)dep
- (char *)data
;
2323 addr
= xfs_dir2_db_off_to_dataptr(mp
->m_dir_geo
, db
,
2324 (char *)dep
- (char *)data
);
2325 xname
.name
= dep
->name
;
2326 xname
.len
= dep
->namelen
;
2327 dir_hash_add(mp
->m_dirnameops
->hashname(&xname
), addr
);
2328 ptr
+= M_DIROPS(mp
)->data_entsize(dep
->namelen
);
2331 lino
= be64_to_cpu(dep
->inumber
);
2332 cid
= find_inode(lino
, 1);
2334 dbprintf(_("dir %lld block %d entry %*.*s %lld\n"),
2335 id
->ino
, dabno
, dep
->namelen
, dep
->namelen
,
2341 dbprintf(_("dir %lld block %d entry %*.*s bad "
2342 "inode number %lld\n"),
2343 id
->ino
, dabno
, dep
->namelen
,
2344 dep
->namelen
, dep
->name
, lino
);
2347 if (dep
->namelen
== 2 && dep
->name
[0] == '.' &&
2348 dep
->name
[1] == '.') {
2351 dbprintf(_("multiple .. entries in dir "
2352 "%lld (%lld, %lld)\n"),
2353 id
->ino
, parent
, lino
);
2356 parent
= cid
? lino
: NULLFSINO
;
2358 } else if (dep
->namelen
!= 1 || dep
->name
[0] != '.') {
2362 addname_inode(cid
, (char *)dep
->name
,
2366 if (lino
!= id
->ino
) {
2368 dbprintf(_("dir %lld entry . inode "
2369 "number mismatch (%lld)\n"),
2376 if (be32_to_cpu(data
->magic
) == XFS_DIR2_BLOCK_MAGIC
) {
2377 endptr
= (char *)data
+ mp
->m_dir_geo
->blksize
;
2378 for (i
= stale
= 0; lep
&& i
< be32_to_cpu(btp
->count
); i
++) {
2379 if ((char *)&lep
[i
] >= endptr
) {
2381 dbprintf(_("dir %lld block %d bad count "
2382 "%u\n"), id
->ino
, dabno
,
2383 be32_to_cpu(btp
->count
));
2387 if (be32_to_cpu(lep
[i
].address
) == XFS_DIR2_NULL_DATAPTR
)
2389 else if (dir_hash_see(be32_to_cpu(lep
[i
].hashval
),
2390 be32_to_cpu(lep
[i
].address
))) {
2392 dbprintf(_("dir %lld block %d extra leaf "
2395 be32_to_cpu(lep
[i
].hashval
),
2396 be32_to_cpu(lep
[i
].address
));
2401 bf_err
+= freeseen
!= 7;
2404 dbprintf(_("dir %lld block %d bad bestfree data\n"),
2408 if (be32_to_cpu(data
->magic
) == XFS_DIR2_BLOCK_MAGIC
&&
2409 count
!= be32_to_cpu(btp
->count
) - be32_to_cpu(btp
->stale
)) {
2411 dbprintf(_("dir %lld block %d bad block tail count %d "
2413 id
->ino
, dabno
, be32_to_cpu(btp
->count
),
2414 be32_to_cpu(btp
->stale
));
2417 if (be32_to_cpu(data
->magic
) == XFS_DIR2_BLOCK_MAGIC
&&
2418 stale
!= be32_to_cpu(btp
->stale
)) {
2420 dbprintf(_("dir %lld block %d bad stale tail count %d\n"),
2421 id
->ino
, dabno
, be32_to_cpu(btp
->stale
));
2426 dbprintf(_("dir %lld block %d consecutive free entries\n"),
2432 dbprintf(_("dir %lld block %d entry/unused tag "
2440 static xfs_dir2_data_free_t
*
2441 process_data_dir_v2_freefind(
2442 struct xfs_dir2_data_hdr
*data
,
2443 xfs_dir2_data_unused_t
*dup
)
2445 struct xfs_dir2_data_free
*bf
;
2446 struct xfs_dir2_data_free
*dfp
;
2447 xfs_dir2_data_aoff_t off
;
2449 off
= (xfs_dir2_data_aoff_t
)((char *)dup
- (char *)data
);
2450 bf
= M_DIROPS(mp
)->data_bestfree_p(data
);
2451 if (be16_to_cpu(dup
->length
) <
2452 be16_to_cpu(bf
[XFS_DIR2_DATA_FD_COUNT
- 1].length
))
2454 for (dfp
= bf
; dfp
< &bf
[XFS_DIR2_DATA_FD_COUNT
]; dfp
++) {
2455 if (be16_to_cpu(dfp
->offset
) == 0)
2457 if (be16_to_cpu(dfp
->offset
) == off
)
2475 if (process_dir_v2(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_fileoff_t last
= 0;
2512 xfs_fsize_t size
= be64_to_cpu(dip
->di_size
);
2515 last
= blkmap_last_off(blkmap
);
2516 if (size
<= XFS_DFORK_DSIZE(dip
, mp
) &&
2517 dip
->di_format
== XFS_DINODE_FMT_LOCAL
)
2518 *parent
= process_sf_dir_v2(dip
, dot
, dotdot
, id
);
2519 else if (last
== mp
->m_dir_geo
->fsbcount
&&
2520 (dip
->di_format
== XFS_DINODE_FMT_EXTENTS
||
2521 dip
->di_format
== XFS_DINODE_FMT_BTREE
))
2522 *parent
= process_block_dir_v2(blkmap
, dot
, dotdot
, id
);
2523 else if (last
>= mp
->m_dir_geo
->leafblk
+ mp
->m_dir_geo
->fsbcount
&&
2524 (dip
->di_format
== XFS_DINODE_FMT_EXTENTS
||
2525 dip
->di_format
== XFS_DINODE_FMT_BTREE
))
2526 *parent
= process_leaf_node_dir_v2(blkmap
, dot
, dotdot
, id
, size
);
2528 dbprintf(_("bad size (%lld) or format (%d) for directory inode "
2530 size
, dip
->di_format
, id
->ino
);
2543 xfs_drfsbno_t
*totd
,
2544 xfs_drfsbno_t
*toti
,
2551 rp
= (xfs_bmbt_rec_t
*)XFS_DFORK_PTR(dip
, whichfork
);
2552 *nex
= XFS_DFORK_NEXTENTS(dip
, whichfork
);
2553 if (*nex
< 0 || *nex
> XFS_DFORK_SIZE(dip
, mp
, whichfork
) /
2554 sizeof(xfs_bmbt_rec_t
)) {
2555 if (!sflag
|| id
->ilist
)
2556 dbprintf(_("bad number of extents %d for inode %lld\n"),
2561 process_bmbt_reclist(rp
, *nex
, type
, id
, totd
, blkmapp
);
2572 xfs_fsblock_t bno
= 0;
2573 xfs_icdinode_t idic
;
2574 inodata_t
*id
= NULL
;
2576 xfs_extnum_t nextents
= 0;
2579 xfs_drfsbno_t totblocks
;
2580 xfs_drfsbno_t totdblocks
= 0;
2581 xfs_drfsbno_t totiblocks
= 0;
2583 xfs_extnum_t anextents
= 0;
2584 xfs_drfsbno_t atotdblocks
= 0;
2585 xfs_drfsbno_t atotiblocks
= 0;
2591 static char okfmts
[] = {
2592 0, /* type 0 unused */
2593 1 << XFS_DINODE_FMT_DEV
, /* FIFO */
2594 1 << XFS_DINODE_FMT_DEV
, /* CHR */
2595 0, /* type 3 unused */
2596 (1 << XFS_DINODE_FMT_LOCAL
) |
2597 (1 << XFS_DINODE_FMT_EXTENTS
) |
2598 (1 << XFS_DINODE_FMT_BTREE
), /* DIR */
2599 0, /* type 5 unused */
2600 1 << XFS_DINODE_FMT_DEV
, /* BLK */
2601 0, /* type 7 unused */
2602 (1 << XFS_DINODE_FMT_EXTENTS
) |
2603 (1 << XFS_DINODE_FMT_BTREE
), /* REG */
2604 0, /* type 9 unused */
2605 (1 << XFS_DINODE_FMT_LOCAL
) |
2606 (1 << XFS_DINODE_FMT_EXTENTS
), /* LNK */
2607 0, /* type 11 unused */
2608 1 << XFS_DINODE_FMT_DEV
, /* SOCK */
2609 0, /* type 13 unused */
2610 1 << XFS_DINODE_FMT_UUID
, /* MNT */
2611 0 /* type 15 unused */
2613 static char *fmtnames
[] = {
2614 "dev", "local", "extents", "btree", "uuid"
2617 libxfs_dinode_from_disk(&idic
, dip
);
2619 ino
= XFS_AGINO_TO_INO(mp
, be32_to_cpu(agf
->agf_seqno
), agino
);
2621 id
= find_inode(ino
, 1);
2622 bno
= XFS_INO_TO_FSB(mp
, ino
);
2625 v
= (!sflag
|| (id
&& id
->ilist
) || CHECK_BLIST(bno
));
2626 if (idic
.di_magic
!= XFS_DINODE_MAGIC
) {
2628 dbprintf(_("bad magic number %#x for inode %lld\n"),
2629 idic
.di_magic
, ino
);
2633 if (!XFS_DINODE_GOOD_VERSION(idic
.di_version
)) {
2635 dbprintf(_("bad version number %#x for inode %lld\n"),
2636 idic
.di_version
, ino
);
2641 if (idic
.di_nblocks
!= 0) {
2643 dbprintf(_("bad nblocks %lld for free inode "
2645 idic
.di_nblocks
, ino
);
2648 if (idic
.di_version
== 1)
2649 nlink
= idic
.di_onlink
;
2651 nlink
= idic
.di_nlink
;
2654 dbprintf(_("bad nlink %d for free inode %lld\n"),
2658 if (idic
.di_mode
!= 0) {
2660 dbprintf(_("bad mode %#o for free inode %lld\n"),
2667 if (be32_to_cpu(dip
->di_next_unlinked
) != NULLAGINO
) {
2669 dbprintf(_("bad next unlinked %#x for inode %lld\n"),
2670 be32_to_cpu(dip
->di_next_unlinked
), ino
);
2674 * di_mode is a 16-bit uint so no need to check the < 0 case
2676 if ((((idic
.di_mode
& S_IFMT
) >> 12) > 15) ||
2677 (!(okfmts
[(idic
.di_mode
& S_IFMT
) >> 12] & (1 << idic
.di_format
)))) {
2679 dbprintf(_("bad format %d for inode %lld type %#o\n"),
2680 idic
.di_format
, id
->ino
, idic
.di_mode
& S_IFMT
);
2684 if ((unsigned int)XFS_DFORK_ASIZE(dip
, mp
) >=
2685 XFS_LITINO(mp
, idic
.di_version
)) {
2687 dbprintf(_("bad fork offset %d for inode %lld\n"),
2688 idic
.di_forkoff
, id
->ino
);
2692 if ((unsigned int)idic
.di_aformat
> XFS_DINODE_FMT_BTREE
) {
2694 dbprintf(_("bad attribute format %d for inode %lld\n"),
2695 idic
.di_aformat
, id
->ino
);
2699 if (verbose
|| (id
&& id
->ilist
) || CHECK_BLIST(bno
))
2700 dbprintf(_("inode %lld mode %#o fmt %s "
2702 "nex %d anex %d nblk %lld sz %lld%s%s%s%s%s%s%s\n"),
2703 id
->ino
, idic
.di_mode
, fmtnames
[(int)idic
.di_format
],
2704 fmtnames
[(int)idic
.di_aformat
],
2707 idic
.di_nblocks
, idic
.di_size
,
2708 idic
.di_flags
& XFS_DIFLAG_REALTIME
? " rt" : "",
2709 idic
.di_flags
& XFS_DIFLAG_PREALLOC
? " pre" : "",
2710 idic
.di_flags
& XFS_DIFLAG_IMMUTABLE
? " imm" : "",
2711 idic
.di_flags
& XFS_DIFLAG_APPEND
? " app" : "",
2712 idic
.di_flags
& XFS_DIFLAG_SYNC
? " syn" : "",
2713 idic
.di_flags
& XFS_DIFLAG_NOATIME
? " noa" : "",
2714 idic
.di_flags
& XFS_DIFLAG_NODUMP
? " nod" : "");
2716 switch (idic
.di_mode
& S_IFMT
) {
2719 if (idic
.di_format
== XFS_DINODE_FMT_LOCAL
)
2721 blkmap
= blkmap_alloc(idic
.di_nextents
);
2724 if (idic
.di_flags
& XFS_DIFLAG_REALTIME
)
2726 else if (id
->ino
== mp
->m_sb
.sb_rbmino
) {
2727 type
= DBM_RTBITMAP
;
2728 blkmap
= blkmap_alloc(idic
.di_nextents
);
2730 } else if (id
->ino
== mp
->m_sb
.sb_rsumino
) {
2732 blkmap
= blkmap_alloc(idic
.di_nextents
);
2735 else if (id
->ino
== mp
->m_sb
.sb_uquotino
||
2736 id
->ino
== mp
->m_sb
.sb_gquotino
||
2737 id
->ino
== mp
->m_sb
.sb_pquotino
) {
2739 blkmap
= blkmap_alloc(idic
.di_nextents
);
2744 if (idic
.di_mode
& (S_ISUID
| S_ISGID
))
2755 if (idic
.di_version
== 1)
2756 setlink_inode(id
, idic
.di_onlink
, type
== DBM_DIR
, security
);
2758 sbversion
|= XFS_SB_VERSION_NLINKBIT
;
2759 setlink_inode(id
, idic
.di_nlink
, type
== DBM_DIR
, security
);
2761 switch (idic
.di_format
) {
2762 case XFS_DINODE_FMT_LOCAL
:
2763 process_lclinode(id
, dip
, type
, &totdblocks
, &totiblocks
,
2764 &nextents
, &blkmap
, XFS_DATA_FORK
);
2766 case XFS_DINODE_FMT_EXTENTS
:
2767 process_exinode(id
, dip
, type
, &totdblocks
, &totiblocks
,
2768 &nextents
, &blkmap
, XFS_DATA_FORK
);
2770 case XFS_DINODE_FMT_BTREE
:
2771 process_btinode(id
, dip
, type
, &totdblocks
, &totiblocks
,
2772 &nextents
, &blkmap
, XFS_DATA_FORK
);
2775 if (XFS_DFORK_Q(dip
)) {
2776 sbversion
|= XFS_SB_VERSION_ATTRBIT
;
2777 switch (idic
.di_aformat
) {
2778 case XFS_DINODE_FMT_LOCAL
:
2779 process_lclinode(id
, dip
, DBM_ATTR
, &atotdblocks
,
2780 &atotiblocks
, &anextents
, NULL
, XFS_ATTR_FORK
);
2782 case XFS_DINODE_FMT_EXTENTS
:
2783 process_exinode(id
, dip
, DBM_ATTR
, &atotdblocks
,
2784 &atotiblocks
, &anextents
, NULL
, XFS_ATTR_FORK
);
2786 case XFS_DINODE_FMT_BTREE
:
2787 process_btinode(id
, dip
, DBM_ATTR
, &atotdblocks
,
2788 &atotiblocks
, &anextents
, NULL
, XFS_ATTR_FORK
);
2792 if (qgdo
|| qpdo
|| qudo
) {
2800 bc
= totdblocks
+ totiblocks
+
2801 atotdblocks
+ atotiblocks
;
2805 bc
= totiblocks
+ atotdblocks
+ atotiblocks
;
2813 dqprid
= xfs_get_projid(&idic
); /* dquot ID is u32 */
2814 quota_add(&dqprid
, &idic
.di_gid
, &idic
.di_uid
,
2818 totblocks
= totdblocks
+ totiblocks
+ atotdblocks
+ atotiblocks
;
2819 if (totblocks
!= idic
.di_nblocks
) {
2821 dbprintf(_("bad nblocks %lld for inode %lld, counted "
2823 idic
.di_nblocks
, id
->ino
, totblocks
);
2826 if (nextents
!= idic
.di_nextents
) {
2828 dbprintf(_("bad nextents %d for inode %lld, counted %d\n"),
2829 idic
.di_nextents
, id
->ino
, nextents
);
2832 if (anextents
!= idic
.di_anextents
) {
2834 dbprintf(_("bad anextents %d for inode %lld, counted "
2836 idic
.di_anextents
, id
->ino
, anextents
);
2839 if (type
== DBM_DIR
)
2840 process_dir(dip
, blkmap
, id
);
2841 else if (type
== DBM_RTBITMAP
)
2842 process_rtbitmap(blkmap
);
2843 else if (type
== DBM_RTSUM
)
2844 process_rtsummary(blkmap
);
2846 * If the CHKD flag is not set, this can legitimately contain garbage;
2847 * xfs_repair may have cleared that bit.
2849 else if (type
== DBM_QUOTA
) {
2850 if (id
->ino
== mp
->m_sb
.sb_uquotino
&&
2851 (mp
->m_sb
.sb_qflags
& XFS_UQUOTA_ACCT
) &&
2852 (mp
->m_sb
.sb_qflags
& XFS_UQUOTA_CHKD
))
2853 process_quota(IS_USER_QUOTA
, id
, blkmap
);
2854 else if (id
->ino
== mp
->m_sb
.sb_gquotino
&&
2855 (mp
->m_sb
.sb_qflags
& XFS_GQUOTA_ACCT
) &&
2856 (mp
->m_sb
.sb_qflags
& XFS_GQUOTA_CHKD
))
2857 process_quota(IS_GROUP_QUOTA
, id
, blkmap
);
2858 else if (id
->ino
== mp
->m_sb
.sb_pquotino
&&
2859 (mp
->m_sb
.sb_qflags
& XFS_PQUOTA_ACCT
) &&
2860 (mp
->m_sb
.sb_qflags
& XFS_PQUOTA_CHKD
))
2861 process_quota(IS_PROJECT_QUOTA
, id
, blkmap
);
2864 blkmap_free(blkmap
);
2873 xfs_drfsbno_t
*totd
,
2874 xfs_drfsbno_t
*toti
,
2879 xfs_attr_shortform_t
*asf
;
2882 bno
= XFS_INO_TO_FSB(mp
, id
->ino
);
2883 if (whichfork
== XFS_DATA_FORK
&& be64_to_cpu(dip
->di_size
) >
2884 XFS_DFORK_DSIZE(dip
, mp
)) {
2885 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
2886 dbprintf(_("local inode %lld data is too large (size "
2888 id
->ino
, be64_to_cpu(dip
->di_size
));
2891 else if (whichfork
== XFS_ATTR_FORK
) {
2892 asf
= (xfs_attr_shortform_t
*)XFS_DFORK_APTR(dip
);
2893 if (be16_to_cpu(asf
->hdr
.totsize
) > XFS_DFORK_ASIZE(dip
, mp
)) {
2894 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
2895 dbprintf(_("local inode %lld attr is too large "
2897 id
->ino
, be16_to_cpu(asf
->hdr
.totsize
));
2904 process_leaf_node_dir_v2(
2909 xfs_fsize_t dirsize
)
2925 v2
= verbose
|| id
->ilist
;
2928 freetab
= malloc(FREETAB_SIZE(dirsize
/ mp
->m_dir_geo
->blksize
));
2929 freetab
->naents
= (int)(dirsize
/ mp
->m_dir_geo
->blksize
);
2931 for (i
= 0; i
< freetab
->naents
; i
++)
2932 freetab
->ents
[i
] = NULLDATAOFF
;
2934 while ((dbno
= blkmap_next_off(blkmap
, dbno
, &t
)) != NULLFILEOFF
) {
2935 nex
= blkmap_getn(blkmap
, dbno
, mp
->m_dir_geo
->fsbcount
, &bmp
);
2937 for (v
= v2
, x
= 0; !v
&& x
< nex
; x
++) {
2938 for (b
= bmp
[x
].startblock
;
2939 !v
&& b
< bmp
[x
].startblock
+ bmp
[x
].blockcount
;
2944 dbprintf(_("dir inode %lld block %u=%llu\n"), id
->ino
,
2946 (xfs_dfsbno_t
)bmp
->startblock
);
2949 make_bbmap(&bbmap
, nex
, bmp
);
2950 set_cur(&typtab
[TYP_DIR2
], XFS_FSB_TO_DADDR(mp
, bmp
->startblock
),
2951 mp
->m_dir_geo
->fsbcount
* blkbb
, DB_RING_IGN
,
2952 nex
> 1 ? &bbmap
: NULL
);
2954 if (iocur_top
->data
== NULL
) {
2956 dbprintf(_("can't read block %u for directory "
2958 (__uint32_t
)dbno
, id
->ino
);
2961 dbno
+= mp
->m_dir_geo
->fsbcount
- 1;
2964 if (dbno
< mp
->m_dir_geo
->leafblk
) {
2965 lino
= process_data_dir_v2(dot
, dotdot
, id
, v
,
2966 (xfs_dablk_t
)dbno
, &freetab
);
2970 dbprintf(_("multiple .. entries "
2977 } else if (dbno
< mp
->m_dir_geo
->freeblk
) {
2978 process_leaf_node_dir_v2_int(id
, v
, (xfs_dablk_t
)dbno
,
2981 process_leaf_node_dir_v2_free(id
, v
, (xfs_dablk_t
)dbno
,
2985 dbno
+= mp
->m_dir_geo
->fsbcount
- 1;
2987 dir_hash_check(id
, v
);
2989 for (i
= 0; i
< freetab
->nents
; i
++) {
2990 if (freetab
->ents
[i
] != NULLDATAOFF
) {
2992 dbprintf(_("missing free index for data block %d "
2993 "in dir ino %lld\n"),
2994 xfs_dir2_db_to_da(mp
->m_dir_geo
, i
), id
->ino
);
3003 process_leaf_node_dir_v2_free(
3009 xfs_dir2_data_off_t ent
;
3010 xfs_dir2_free_t
*free
;
3015 free
= iocur_top
->data
;
3016 if (be32_to_cpu(free
->hdr
.magic
) != XFS_DIR2_FREE_MAGIC
) {
3018 dbprintf(_("bad free block magic # %#x for dir ino %lld "
3020 be32_to_cpu(free
->hdr
.magic
), id
->ino
, dabno
);
3024 maxent
= M_DIROPS(mp
)->free_max_bests(mp
->m_dir_geo
);
3025 if (be32_to_cpu(free
->hdr
.firstdb
) != xfs_dir2_da_to_db(mp
->m_dir_geo
,
3026 dabno
- mp
->m_dir_geo
->freeblk
) * maxent
) {
3028 dbprintf(_("bad free block firstdb %d for dir ino %lld "
3030 be32_to_cpu(free
->hdr
.firstdb
), id
->ino
, dabno
);
3034 if (be32_to_cpu(free
->hdr
.nvalid
) > maxent
||
3035 be32_to_cpu(free
->hdr
.nvalid
) < 0 ||
3036 be32_to_cpu(free
->hdr
.nused
) > maxent
||
3037 be32_to_cpu(free
->hdr
.nused
) < 0 ||
3038 be32_to_cpu(free
->hdr
.nused
) >
3039 be32_to_cpu(free
->hdr
.nvalid
)) {
3041 dbprintf(_("bad free block nvalid/nused %d/%d for dir "
3042 "ino %lld block %d\n"),
3043 be32_to_cpu(free
->hdr
.nvalid
),
3044 be32_to_cpu(free
->hdr
.nused
), id
->ino
, dabno
);
3048 for (used
= i
= 0; i
< be32_to_cpu(free
->hdr
.nvalid
); i
++) {
3049 if (freetab
->nents
<= be32_to_cpu(free
->hdr
.firstdb
) + i
)
3052 ent
= freetab
->ents
[be32_to_cpu(free
->hdr
.firstdb
) + i
];
3053 if (ent
!= be16_to_cpu(free
->bests
[i
])) {
3055 dbprintf(_("bad free block ent %d is %d should "
3056 "be %d for dir ino %lld block %d\n"),
3057 i
, be16_to_cpu(free
->bests
[i
]), ent
,
3061 if (be16_to_cpu(free
->bests
[i
]) != NULLDATAOFF
)
3063 if (ent
!= NULLDATAOFF
)
3064 freetab
->ents
[be32_to_cpu(free
->hdr
.firstdb
) + i
] =
3067 if (used
!= be32_to_cpu(free
->hdr
.nused
)) {
3069 dbprintf(_("bad free block nused %d should be %d for dir "
3070 "ino %lld block %d\n"),
3071 be32_to_cpu(free
->hdr
.nused
), used
, id
->ino
,
3078 process_leaf_node_dir_v2_int(
3086 xfs_dir2_leaf_t
*leaf
;
3087 xfs_dir2_leaf_entry_t
*lep
;
3088 xfs_dir2_leaf_tail_t
*ltp
;
3089 xfs_da_intnode_t
*node
;
3091 struct xfs_da3_icnode_hdr nodehdr
;
3093 leaf
= iocur_top
->data
;
3094 switch (be16_to_cpu(leaf
->hdr
.info
.magic
)) {
3095 case XFS_DIR2_LEAF1_MAGIC
:
3096 if (be32_to_cpu(leaf
->hdr
.info
.forw
) ||
3097 be32_to_cpu(leaf
->hdr
.info
.back
)) {
3099 dbprintf(_("bad leaf block forw/back pointers "
3100 "%d/%d for dir ino %lld block %d\n"),
3101 be32_to_cpu(leaf
->hdr
.info
.forw
),
3102 be32_to_cpu(leaf
->hdr
.info
.back
),
3106 if (dabno
!= mp
->m_dir_geo
->leafblk
) {
3108 dbprintf(_("single leaf block for dir ino %lld "
3109 "block %d should be at block %d\n"),
3111 (xfs_dablk_t
)mp
->m_dir_geo
->leafblk
);
3114 ltp
= xfs_dir2_leaf_tail_p(mp
->m_dir_geo
, leaf
);
3115 lbp
= xfs_dir2_leaf_bests_p(ltp
);
3116 for (i
= 0; i
< be32_to_cpu(ltp
->bestcount
); i
++) {
3117 if (freetab
->nents
<= i
|| freetab
->ents
[i
] !=
3118 be16_to_cpu(lbp
[i
])) {
3120 dbprintf(_("bestfree %d for dir ino %lld "
3121 "block %d doesn't match table "
3123 freetab
->nents
<= i
?
3127 xfs_dir2_db_to_da(mp
->m_dir_geo
, i
),
3128 be16_to_cpu(lbp
[i
]));
3130 if (freetab
->nents
> i
)
3131 freetab
->ents
[i
] = NULLDATAOFF
;
3134 case XFS_DIR2_LEAFN_MAGIC
:
3135 /* if it's at the root location then we can check the
3136 * pointers are null XXX */
3138 case XFS_DA_NODE_MAGIC
:
3139 node
= iocur_top
->data
;
3140 M_DIROPS(mp
)->node_hdr_from_disk(&nodehdr
, node
);
3141 if (nodehdr
.level
< 1 || nodehdr
.level
> XFS_DA_NODE_MAXDEPTH
) {
3143 dbprintf(_("bad node block level %d for dir ino "
3145 nodehdr
.level
, id
->ino
,
3152 dbprintf(_("bad directory data magic # %#x for dir ino "
3154 be16_to_cpu(leaf
->hdr
.info
.magic
), id
->ino
,
3159 lep
= M_DIROPS(mp
)->leaf_ents_p(leaf
);
3160 for (i
= stale
= 0; i
< be16_to_cpu(leaf
->hdr
.count
); i
++) {
3161 if (be32_to_cpu(lep
[i
].address
) == XFS_DIR2_NULL_DATAPTR
)
3163 else if (dir_hash_see(be32_to_cpu(lep
[i
].hashval
),
3164 be32_to_cpu(lep
[i
].address
))) {
3166 dbprintf(_("dir %lld block %d extra leaf entry "
3167 "%x %x\n"), id
->ino
, dabno
,
3168 be32_to_cpu(lep
[i
].hashval
),
3169 be32_to_cpu(lep
[i
].address
));
3173 if (stale
!= be16_to_cpu(leaf
->hdr
.stale
)) {
3175 dbprintf(_("dir %lld block %d stale mismatch "
3177 id
->ino
, dabno
, stale
,
3178 be16_to_cpu(leaf
->hdr
.stale
));
3193 u_int8_t exp_flags
= 0;
3204 exp_flags
= XFS_DQ_USER
;
3206 case IS_PROJECT_QUOTA
:
3208 exp_flags
= XFS_DQ_PROJ
;
3210 case IS_GROUP_QUOTA
:
3212 exp_flags
= XFS_DQ_GROUP
;
3218 perblock
= (uint
)(mp
->m_sb
.sb_blocksize
/ sizeof(*dqb
));
3221 while ((qbno
= blkmap_next_off(blkmap
, qbno
, &t
)) != NULLFILEOFF
) {
3222 bno
= blkmap_get(blkmap
, qbno
);
3223 dqid
= (xfs_dqid_t
)qbno
* perblock
;
3224 cb
= CHECK_BLIST(bno
);
3225 scicb
= !sflag
|| id
->ilist
|| cb
;
3227 set_cur(&typtab
[TYP_DQBLK
], XFS_FSB_TO_DADDR(mp
, bno
), blkbb
,
3229 if ((dqb
= iocur_top
->data
) == NULL
) {
3231 dbprintf(_("can't read block %lld for %s quota "
3232 "inode (fsblock %lld)\n"),
3233 (xfs_dfiloff_t
)qbno
, s
,
3239 for (i
= 0; i
< perblock
; i
++, dqid
++, dqb
++) {
3240 if (verbose
|| id
->ilist
|| cb
)
3241 dbprintf(_("%s dqblk %lld entry %d id %u bc "
3242 "%lld ic %lld rc %lld\n"),
3243 s
, (xfs_dfiloff_t
)qbno
, i
, dqid
,
3244 be64_to_cpu(dqb
->dd_diskdq
.d_bcount
),
3245 be64_to_cpu(dqb
->dd_diskdq
.d_icount
),
3246 be64_to_cpu(dqb
->dd_diskdq
.d_rtbcount
));
3247 if (be16_to_cpu(dqb
->dd_diskdq
.d_magic
) != XFS_DQUOT_MAGIC
) {
3249 dbprintf(_("bad magic number %#x for %s "
3250 "dqblk %lld entry %d id %u\n"),
3251 be16_to_cpu(dqb
->dd_diskdq
.d_magic
), s
,
3252 (xfs_dfiloff_t
)qbno
, i
, dqid
);
3256 if (dqb
->dd_diskdq
.d_version
!= XFS_DQUOT_VERSION
) {
3258 dbprintf(_("bad version number %#x for "
3259 "%s dqblk %lld entry %d id "
3261 dqb
->dd_diskdq
.d_version
, s
,
3262 (xfs_dfiloff_t
)qbno
, i
, dqid
);
3266 if (dqb
->dd_diskdq
.d_flags
!= exp_flags
) {
3268 dbprintf(_("bad flags %#x for %s dqblk "
3269 "%lld entry %d id %u\n"),
3270 dqb
->dd_diskdq
.d_flags
, s
,
3271 (xfs_dfiloff_t
)qbno
, i
, dqid
);
3275 if (be32_to_cpu(dqb
->dd_diskdq
.d_id
) != dqid
) {
3277 dbprintf(_("bad id %u for %s dqblk %lld "
3278 "entry %d id %u\n"),
3279 be32_to_cpu(dqb
->dd_diskdq
.d_id
), s
,
3280 (xfs_dfiloff_t
)qbno
, i
, dqid
);
3284 quota_add((qtype
== IS_PROJECT_QUOTA
) ? &dqid
: NULL
,
3285 (qtype
== IS_GROUP_QUOTA
) ? &dqid
: NULL
,
3286 (qtype
== IS_USER_QUOTA
) ? &dqid
: NULL
,
3288 be64_to_cpu(dqb
->dd_diskdq
.d_bcount
),
3289 be64_to_cpu(dqb
->dd_diskdq
.d_icount
),
3290 be64_to_cpu(dqb
->dd_diskdq
.d_rtbcount
));
3302 xfs_fileoff_t bmbno
;
3309 xfs_drfsbno_t rtbno
;
3313 xfs_rtword_t
*words
;
3315 bitsperblock
= mp
->m_sb
.sb_blocksize
* NBBY
;
3316 bit
= extno
= prevbit
= start_bmbno
= start_bit
= 0;
3317 bmbno
= NULLFILEOFF
;
3318 while ((bmbno
= blkmap_next_off(blkmap
, bmbno
, &t
)) !=
3320 bno
= blkmap_get(blkmap
, bmbno
);
3321 if (bno
== NULLFSBLOCK
) {
3323 dbprintf(_("block %lld for rtbitmap inode is "
3325 (xfs_dfiloff_t
)bmbno
);
3330 set_cur(&typtab
[TYP_RTBITMAP
], XFS_FSB_TO_DADDR(mp
, bno
), blkbb
,
3332 if ((words
= iocur_top
->data
) == NULL
) {
3334 dbprintf(_("can't read block %lld for rtbitmap "
3336 (xfs_dfiloff_t
)bmbno
);
3342 bit
< bitsperblock
&& extno
< mp
->m_sb
.sb_rextents
;
3344 if (xfs_isset(words
, bit
)) {
3345 rtbno
= extno
* mp
->m_sb
.sb_rextsize
;
3346 set_rdbmap(rtbno
, mp
->m_sb
.sb_rextsize
,
3350 start_bmbno
= (int)bmbno
;
3354 } else if (prevbit
== 1) {
3355 len
= ((int)bmbno
- start_bmbno
) *
3356 bitsperblock
+ (bit
- start_bit
);
3357 log
= XFS_RTBLOCKLOG(len
);
3358 offs
= XFS_SUMOFFS(mp
, log
, start_bmbno
);
3364 if (extno
== mp
->m_sb
.sb_rextents
)
3368 len
= ((int)bmbno
- start_bmbno
) * bitsperblock
+
3370 log
= XFS_RTBLOCKLOG(len
);
3371 offs
= XFS_SUMOFFS(mp
, log
, start_bmbno
);
3382 xfs_fileoff_t sumbno
;
3385 sumbno
= NULLFILEOFF
;
3386 while ((sumbno
= blkmap_next_off(blkmap
, sumbno
, &t
)) != NULLFILEOFF
) {
3387 bno
= blkmap_get(blkmap
, sumbno
);
3388 if (bno
== NULLFSBLOCK
) {
3390 dbprintf(_("block %lld for rtsummary inode is "
3392 (xfs_dfiloff_t
)sumbno
);
3397 set_cur(&typtab
[TYP_RTSUMMARY
], XFS_FSB_TO_DADDR(mp
, bno
),
3398 blkbb
, DB_RING_IGN
, NULL
);
3399 if ((bytes
= iocur_top
->data
) == NULL
) {
3401 dbprintf(_("can't read block %lld for rtsummary "
3403 (xfs_dfiloff_t
)sumbno
);
3408 memcpy((char *)sumfile
+ sumbno
* mp
->m_sb
.sb_blocksize
, bytes
,
3409 mp
->m_sb
.sb_blocksize
);
3426 struct xfs_dir2_sf_hdr
*sf
;
3427 xfs_dir2_sf_entry_t
*sfe
;
3430 sf
= (struct xfs_dir2_sf_hdr
*)XFS_DFORK_DPTR(dip
);
3432 v
= verbose
|| id
->ilist
;
3434 dbprintf(_("dir %lld entry . %lld\n"), id
->ino
, id
->ino
);
3436 sfe
= xfs_dir2_sf_firstentry(sf
);
3437 offset
= M_DIROPS(mp
)->data_first_offset
;
3438 for (i
= sf
->count
- 1, i8
= 0; i
>= 0; i
--) {
3439 if ((__psint_t
)sfe
+ M_DIROPS(mp
)->sf_entsize(sf
, sfe
->namelen
) -
3440 (__psint_t
)sf
> be64_to_cpu(dip
->di_size
)) {
3442 dbprintf(_("dir %llu bad size in entry at %d\n"),
3444 (int)((char *)sfe
- (char *)sf
));
3448 lino
= M_DIROPS(mp
)->sf_get_ino(sf
, sfe
);
3449 if (lino
> XFS_DIR2_MAX_SHORT_INUM
)
3451 cid
= find_inode(lino
, 1);
3454 dbprintf(_("dir %lld entry %*.*s bad inode "
3456 id
->ino
, sfe
->namelen
, sfe
->namelen
,
3463 addname_inode(cid
, (char *)sfe
->name
, sfe
->namelen
);
3466 dbprintf(_("dir %lld entry %*.*s offset %d %lld\n"),
3467 id
->ino
, sfe
->namelen
, sfe
->namelen
, sfe
->name
,
3468 xfs_dir2_sf_get_offset(sfe
), lino
);
3469 if (xfs_dir2_sf_get_offset(sfe
) < offset
) {
3471 dbprintf(_("dir %lld entry %*.*s bad offset %d\n"),
3472 id
->ino
, sfe
->namelen
, sfe
->namelen
,
3473 sfe
->name
, xfs_dir2_sf_get_offset(sfe
));
3477 xfs_dir2_sf_get_offset(sfe
) +
3478 M_DIROPS(mp
)->sf_entsize(sf
, sfe
->namelen
);
3479 sfe
= M_DIROPS(mp
)->sf_nextentry(sf
, sfe
);
3481 if (i
< 0 && (__psint_t
)sfe
- (__psint_t
)sf
!=
3482 be64_to_cpu(dip
->di_size
)) {
3484 dbprintf(_("dir %llu size is %lld, should be %u\n"),
3485 id
->ino
, be64_to_cpu(dip
->di_size
),
3486 (uint
)((char *)sfe
- (char *)sf
));
3489 if (offset
+ (sf
->count
+ 2) * sizeof(xfs_dir2_leaf_entry_t
) +
3490 sizeof(xfs_dir2_block_tail_t
) > mp
->m_dir_geo
->blksize
) {
3492 dbprintf(_("dir %llu offsets too high\n"), id
->ino
);
3495 lino
= M_DIROPS(mp
)->sf_get_parent_ino(sf
);
3496 if (lino
> XFS_DIR2_MAX_SHORT_INUM
)
3498 cid
= find_inode(lino
, 1);
3503 dbprintf(_("dir %lld entry .. bad inode number %lld\n"),
3508 dbprintf(_("dir %lld entry .. %lld\n"), id
->ino
, lino
);
3509 if (i8
!= sf
->i8count
) {
3511 dbprintf(_("dir %lld i8count mismatch is %d should be "
3513 id
->ino
, sf
->i8count
, i8
);
3517 return cid
? lino
: NULLFSINO
;
3531 if (qudo
&& usrid
!= NULL
)
3532 quota_add1(qudata
, *usrid
, dq
, bc
, ic
, rc
);
3533 if (qgdo
&& grpid
!= NULL
)
3534 quota_add1(qgdata
, *grpid
, dq
, bc
, ic
, rc
);
3535 if (qpdo
&& prjid
!= NULL
)
3536 quota_add1(qpdata
, *prjid
, dq
, bc
, ic
, rc
);
3552 qh
= (int)(id
% QDATA_HASH_SIZE
);
3556 qi
= dq
? &qe
->dq
: &qe
->count
;
3564 qe
= xmalloc(sizeof(*qe
));
3566 qi
= dq
? &qe
->dq
: &qe
->count
;
3570 qi
= dq
? &qe
->count
: &qe
->dq
;
3571 qi
->bc
= qi
->ic
= qi
->rc
= 0;
3585 for (i
= 0; i
< QDATA_HASH_SIZE
; i
++) {
3589 if (qp
->count
.bc
!= qp
->dq
.bc
||
3590 qp
->count
.ic
!= qp
->dq
.ic
||
3591 qp
->count
.rc
!= qp
->dq
.rc
) {
3593 dbprintf(_("%s quota id %u, have/exp"),
3595 if (qp
->count
.bc
!= qp
->dq
.bc
)
3596 dbprintf(_(" bc %lld/%lld"),
3599 if (qp
->count
.ic
!= qp
->dq
.ic
)
3600 dbprintf(_(" ic %lld/%lld"),
3603 if (qp
->count
.rc
!= qp
->dq
.rc
)
3604 dbprintf(_(" rc %lld/%lld"),
3621 qudo
= mp
->m_sb
.sb_uquotino
!= 0 &&
3622 mp
->m_sb
.sb_uquotino
!= NULLFSINO
&&
3623 (mp
->m_sb
.sb_qflags
& XFS_UQUOTA_ACCT
) &&
3624 (mp
->m_sb
.sb_qflags
& XFS_UQUOTA_CHKD
);
3625 qgdo
= mp
->m_sb
.sb_gquotino
!= 0 &&
3626 mp
->m_sb
.sb_gquotino
!= NULLFSINO
&&
3627 (mp
->m_sb
.sb_qflags
& XFS_GQUOTA_ACCT
) &&
3628 (mp
->m_sb
.sb_qflags
& XFS_GQUOTA_CHKD
);
3629 qpdo
= mp
->m_sb
.sb_pquotino
!= 0 &&
3630 mp
->m_sb
.sb_pquotino
!= NULLFSINO
&&
3631 (mp
->m_sb
.sb_qflags
& XFS_PQUOTA_ACCT
) &&
3632 (mp
->m_sb
.sb_qflags
& XFS_PQUOTA_CHKD
);
3634 qudata
= xcalloc(QDATA_HASH_SIZE
, sizeof(qdata_t
*));
3636 qgdata
= xcalloc(QDATA_HASH_SIZE
, sizeof(qdata_t
*));
3638 qpdata
= xcalloc(QDATA_HASH_SIZE
, sizeof(qdata_t
*));
3643 xfs_agnumber_t agno
)
3649 xfs_sb_t
*sb
= &tsb
;
3651 agffreeblks
= agflongest
= 0;
3653 agicount
= agifreecount
= 0;
3654 push_cur(); /* 1 pushed */
3655 set_cur(&typtab
[TYP_SB
],
3656 XFS_AG_DADDR(mp
, agno
, XFS_SB_DADDR
),
3657 XFS_FSS_TO_BB(mp
, 1), DB_RING_IGN
, NULL
);
3659 if (!iocur_top
->data
) {
3660 dbprintf(_("can't read superblock for ag %u\n"), agno
);
3665 libxfs_sb_from_disk(sb
, iocur_top
->data
);
3667 if (sb
->sb_magicnum
!= XFS_SB_MAGIC
) {
3669 dbprintf(_("bad sb magic # %#x in ag %u\n"),
3670 sb
->sb_magicnum
, agno
);
3673 if (!xfs_sb_good_version(sb
)) {
3675 dbprintf(_("bad sb version # %#x in ag %u\n"),
3676 sb
->sb_versionnum
, agno
);
3680 if (!lazycount
&& xfs_sb_version_haslazysbcount(sb
)) {
3683 if (agno
== 0 && sb
->sb_inprogress
!= 0) {
3685 dbprintf(_("mkfs not completed successfully\n"));
3688 set_dbmap(agno
, XFS_SB_BLOCK(mp
), 1, DBM_SB
, agno
, XFS_SB_BLOCK(mp
));
3689 if (sb
->sb_logstart
&& XFS_FSB_TO_AGNO(mp
, sb
->sb_logstart
) == agno
)
3690 set_dbmap(agno
, XFS_FSB_TO_AGBNO(mp
, sb
->sb_logstart
),
3691 sb
->sb_logblocks
, DBM_LOG
, agno
, XFS_SB_BLOCK(mp
));
3692 push_cur(); /* 2 pushed */
3693 set_cur(&typtab
[TYP_AGF
],
3694 XFS_AG_DADDR(mp
, agno
, XFS_AGF_DADDR(mp
)),
3695 XFS_FSS_TO_BB(mp
, 1), DB_RING_IGN
, NULL
);
3696 if ((agf
= iocur_top
->data
) == NULL
) {
3697 dbprintf(_("can't read agf block for ag %u\n"), agno
);
3701 if (be32_to_cpu(agf
->agf_magicnum
) != XFS_AGF_MAGIC
) {
3703 dbprintf(_("bad agf magic # %#x in ag %u\n"),
3704 be32_to_cpu(agf
->agf_magicnum
), agno
);
3707 if (!XFS_AGF_GOOD_VERSION(be32_to_cpu(agf
->agf_versionnum
))) {
3709 dbprintf(_("bad agf version # %#x in ag %u\n"),
3710 be32_to_cpu(agf
->agf_versionnum
), agno
);
3713 if (XFS_SB_BLOCK(mp
) != XFS_AGF_BLOCK(mp
))
3714 set_dbmap(agno
, XFS_AGF_BLOCK(mp
), 1, DBM_AGF
, agno
,
3716 if (sb
->sb_agblocks
> be32_to_cpu(agf
->agf_length
))
3717 set_dbmap(agno
, be32_to_cpu(agf
->agf_length
),
3718 sb
->sb_agblocks
- be32_to_cpu(agf
->agf_length
),
3719 DBM_MISSING
, agno
, XFS_SB_BLOCK(mp
));
3720 push_cur(); /* 3 pushed */
3721 set_cur(&typtab
[TYP_AGI
],
3722 XFS_AG_DADDR(mp
, agno
, XFS_AGI_DADDR(mp
)),
3723 XFS_FSS_TO_BB(mp
, 1), DB_RING_IGN
, NULL
);
3724 if ((agi
= iocur_top
->data
) == NULL
) {
3725 dbprintf(_("can't read agi block for ag %u\n"), agno
);
3729 if (be32_to_cpu(agi
->agi_magicnum
) != XFS_AGI_MAGIC
) {
3731 dbprintf(_("bad agi magic # %#x in ag %u\n"),
3732 be32_to_cpu(agi
->agi_magicnum
), agno
);
3735 if (!XFS_AGI_GOOD_VERSION(be32_to_cpu(agi
->agi_versionnum
))) {
3737 dbprintf(_("bad agi version # %#x in ag %u\n"),
3738 be32_to_cpu(agi
->agi_versionnum
), agno
);
3741 if (XFS_SB_BLOCK(mp
) != XFS_AGI_BLOCK(mp
) &&
3742 XFS_AGF_BLOCK(mp
) != XFS_AGI_BLOCK(mp
))
3743 set_dbmap(agno
, XFS_AGI_BLOCK(mp
), 1, DBM_AGI
, agno
,
3748 be32_to_cpu(agf
->agf_roots
[XFS_BTNUM_BNO
]),
3749 be32_to_cpu(agf
->agf_levels
[XFS_BTNUM_BNO
]),
3750 1, scanfunc_bno
, TYP_BNOBT
);
3753 be32_to_cpu(agf
->agf_roots
[XFS_BTNUM_CNT
]),
3754 be32_to_cpu(agf
->agf_levels
[XFS_BTNUM_CNT
]),
3755 1, scanfunc_cnt
, TYP_CNTBT
);
3757 be32_to_cpu(agi
->agi_root
),
3758 be32_to_cpu(agi
->agi_level
),
3759 1, scanfunc_ino
, TYP_INOBT
);
3760 if (be32_to_cpu(agf
->agf_freeblks
) != agffreeblks
) {
3762 dbprintf(_("agf_freeblks %u, counted %u in ag %u\n"),
3763 be32_to_cpu(agf
->agf_freeblks
),
3767 if (be32_to_cpu(agf
->agf_longest
) != agflongest
) {
3769 dbprintf(_("agf_longest %u, counted %u in ag %u\n"),
3770 be32_to_cpu(agf
->agf_longest
),
3775 be32_to_cpu(agf
->agf_btreeblks
) != agfbtreeblks
) {
3777 dbprintf(_("agf_btreeblks %u, counted %u in ag %u\n"),
3778 be32_to_cpu(agf
->agf_btreeblks
),
3779 agfbtreeblks
, agno
);
3782 agf_aggr_freeblks
+= agffreeblks
+ agfbtreeblks
;
3783 if (be32_to_cpu(agi
->agi_count
) != agicount
) {
3785 dbprintf(_("agi_count %u, counted %u in ag %u\n"),
3786 be32_to_cpu(agi
->agi_count
),
3790 if (be32_to_cpu(agi
->agi_freecount
) != agifreecount
) {
3792 dbprintf(_("agi_freecount %u, counted %u in ag %u\n"),
3793 be32_to_cpu(agi
->agi_freecount
),
3794 agifreecount
, agno
);
3797 for (i
= 0; i
< XFS_AGI_UNLINKED_BUCKETS
; i
++) {
3798 if (be32_to_cpu(agi
->agi_unlinked
[i
]) != NULLAGINO
) {
3800 xfs_agino_t agino
=be32_to_cpu(agi
->agi_unlinked
[i
]);
3801 dbprintf(_("agi unlinked bucket %d is %u in ag "
3802 "%u (inode=%lld)\n"), i
, agino
, agno
,
3803 XFS_AGINO_TO_INO(mp
, agno
, agino
));
3820 xfs_agnumber_t seqno
= be32_to_cpu(agf
->agf_seqno
);
3827 if (XFS_SB_BLOCK(mp
) != XFS_AGFL_BLOCK(mp
) &&
3828 XFS_AGF_BLOCK(mp
) != XFS_AGFL_BLOCK(mp
) &&
3829 XFS_AGI_BLOCK(mp
) != XFS_AGFL_BLOCK(mp
))
3830 set_dbmap(seqno
, XFS_AGFL_BLOCK(mp
), 1, DBM_AGFL
, seqno
,
3832 if (be32_to_cpu(agf
->agf_flcount
) == 0)
3835 set_cur(&typtab
[TYP_AGFL
],
3836 XFS_AG_DADDR(mp
, seqno
, XFS_AGFL_DADDR(mp
)),
3837 XFS_FSS_TO_BB(mp
, 1), DB_RING_IGN
, NULL
);
3838 if ((agfl
= iocur_top
->data
) == NULL
) {
3839 dbprintf(_("can't read agfl block for ag %u\n"), seqno
);
3844 i
= be32_to_cpu(agf
->agf_flfirst
);
3846 /* verify agf values before proceeding */
3847 if (be32_to_cpu(agf
->agf_flfirst
) >= XFS_AGFL_SIZE(mp
) ||
3848 be32_to_cpu(agf
->agf_fllast
) >= XFS_AGFL_SIZE(mp
)) {
3849 dbprintf(_("agf %d freelist blocks bad, skipping "
3850 "freelist scan\n"), i
);
3855 /* open coded XFS_BUF_TO_AGFL_BNO */
3856 freelist
= xfs_sb_version_hascrc(&((mp
)->m_sb
)) ? &agfl
->agfl_bno
[0]
3860 bno
= be32_to_cpu(freelist
[i
]);
3861 set_dbmap(seqno
, bno
, 1, DBM_FREELIST
, seqno
,
3862 XFS_AGFL_BLOCK(mp
));
3864 if (i
== be32_to_cpu(agf
->agf_fllast
))
3866 if (++i
== XFS_AGFL_SIZE(mp
))
3869 if (count
!= be32_to_cpu(agf
->agf_flcount
)) {
3871 dbprintf(_("freeblk count %u != flcount %u in ag %u\n"),
3872 count
, be32_to_cpu(agf
->agf_flcount
),
3877 agf_aggr_freeblks
+= count
;
3885 scan_lbtree_f_t func
,
3888 xfs_drfsbno_t
*totd
,
3889 xfs_drfsbno_t
*toti
,
3896 set_cur(&typtab
[btype
], XFS_FSB_TO_DADDR(mp
, root
), blkbb
, DB_RING_IGN
,
3898 if (iocur_top
->data
== NULL
) {
3900 dbprintf(_("can't read btree block %u/%u\n"),
3901 XFS_FSB_TO_AGNO(mp
, root
),
3902 XFS_FSB_TO_AGBNO(mp
, root
));
3907 (*func
)(iocur_top
->data
, nlevels
- 1, type
, root
, id
, totd
, toti
, nex
,
3908 blkmapp
, isroot
, btype
);
3918 scan_sbtree_f_t func
,
3921 xfs_agnumber_t seqno
= be32_to_cpu(agf
->agf_seqno
);
3924 set_cur(&typtab
[btype
],
3925 XFS_AGB_TO_DADDR(mp
, seqno
, root
), blkbb
, DB_RING_IGN
, NULL
);
3926 if (iocur_top
->data
== NULL
) {
3928 dbprintf(_("can't read btree block %u/%u\n"), seqno
, root
);
3933 (*func
)(iocur_top
->data
, nlevels
- 1, agf
, root
, isroot
);
3939 struct xfs_btree_block
*block
,
3944 xfs_drfsbno_t
*totd
,
3945 xfs_drfsbno_t
*toti
,
3951 xfs_agblock_t agbno
;
3952 xfs_agnumber_t agno
;
3957 agno
= XFS_FSB_TO_AGNO(mp
, bno
);
3958 agbno
= XFS_FSB_TO_AGBNO(mp
, bno
);
3959 if (be32_to_cpu(block
->bb_magic
) != XFS_BMAP_MAGIC
) {
3960 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
3961 dbprintf(_("bad magic # %#x in inode %lld bmbt block "
3963 be32_to_cpu(block
->bb_magic
), id
->ino
, agno
, agbno
);
3966 if (be16_to_cpu(block
->bb_level
) != level
) {
3967 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
3968 dbprintf(_("expected level %d got %d in inode %lld bmbt "
3970 level
, be16_to_cpu(block
->bb_level
), id
->ino
, agno
, agbno
);
3973 set_dbmap(agno
, agbno
, 1, type
, agno
, agbno
);
3974 set_inomap(agno
, agbno
, 1, id
);
3977 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_bmap_dmxr
[0] ||
3978 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_bmap_dmnr
[0])) {
3979 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
3980 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) "
3981 "in inode %lld bmap block %lld\n"),
3982 be16_to_cpu(block
->bb_numrecs
), mp
->m_bmap_dmnr
[0],
3983 mp
->m_bmap_dmxr
[0], id
->ino
,
3988 rp
= XFS_BMBT_REC_ADDR(mp
, block
, 1);
3989 *nex
+= be16_to_cpu(block
->bb_numrecs
);
3990 process_bmbt_reclist(rp
, be16_to_cpu(block
->bb_numrecs
), type
, id
, totd
,
3994 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_bmap_dmxr
[1] ||
3995 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_bmap_dmnr
[1])) {
3996 if (!sflag
|| id
->ilist
|| CHECK_BLIST(bno
))
3997 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in "
3998 "inode %lld bmap block %lld\n"),
3999 be16_to_cpu(block
->bb_numrecs
), mp
->m_bmap_dmnr
[1],
4000 mp
->m_bmap_dmxr
[1], id
->ino
, (xfs_dfsbno_t
)bno
);
4004 pp
= XFS_BMBT_PTR_ADDR(mp
, block
, 1, mp
->m_bmap_dmxr
[0]);
4005 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++)
4006 scan_lbtree(be64_to_cpu(pp
[i
]), level
, scanfunc_bmap
, type
, id
,
4007 totd
, toti
, nex
, blkmapp
, 0, btype
);
4012 struct xfs_btree_block
*block
,
4019 xfs_alloc_ptr_t
*pp
;
4020 xfs_alloc_rec_t
*rp
;
4021 xfs_agnumber_t seqno
= be32_to_cpu(agf
->agf_seqno
);
4022 xfs_agblock_t lastblock
;
4024 if (be32_to_cpu(block
->bb_magic
) != XFS_ABTB_MAGIC
) {
4025 dbprintf(_("bad magic # %#x in btbno block %u/%u\n"),
4026 be32_to_cpu(block
->bb_magic
), seqno
, bno
);
4032 if (be16_to_cpu(block
->bb_level
) != level
) {
4034 dbprintf(_("expected level %d got %d in btbno block "
4036 level
, be16_to_cpu(block
->bb_level
), seqno
, bno
);
4039 set_dbmap(seqno
, bno
, 1, DBM_BTBNO
, seqno
, bno
);
4041 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_alloc_mxr
[0] ||
4042 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_alloc_mnr
[0])) {
4043 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in "
4044 "btbno block %u/%u\n"),
4045 be16_to_cpu(block
->bb_numrecs
), mp
->m_alloc_mnr
[0],
4046 mp
->m_alloc_mxr
[0], seqno
, bno
);
4050 rp
= XFS_ALLOC_REC_ADDR(mp
, block
, 1);
4052 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++) {
4053 set_dbmap(seqno
, be32_to_cpu(rp
[i
].ar_startblock
),
4054 be32_to_cpu(rp
[i
].ar_blockcount
), DBM_FREE1
,
4056 if (be32_to_cpu(rp
[i
].ar_startblock
) <= lastblock
) {
4058 "out-of-order bno btree record %d (%u %u) block %u/%u\n"),
4059 i
, be32_to_cpu(rp
[i
].ar_startblock
),
4060 be32_to_cpu(rp
[i
].ar_blockcount
),
4061 be32_to_cpu(agf
->agf_seqno
), bno
);
4064 lastblock
= be32_to_cpu(rp
[i
].ar_startblock
);
4069 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_alloc_mxr
[1] ||
4070 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_alloc_mnr
[1])) {
4071 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in btbno block "
4073 be16_to_cpu(block
->bb_numrecs
), mp
->m_alloc_mnr
[1],
4074 mp
->m_alloc_mxr
[1], seqno
, bno
);
4078 pp
= XFS_ALLOC_PTR_ADDR(mp
, block
, 1, mp
->m_alloc_mxr
[1]);
4079 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++)
4080 scan_sbtree(agf
, be32_to_cpu(pp
[i
]), level
, 0, scanfunc_bno
, TYP_BNOBT
);
4085 struct xfs_btree_block
*block
,
4091 xfs_agnumber_t seqno
= be32_to_cpu(agf
->agf_seqno
);
4093 xfs_alloc_ptr_t
*pp
;
4094 xfs_alloc_rec_t
*rp
;
4095 xfs_extlen_t lastcount
;
4097 if (be32_to_cpu(block
->bb_magic
) != XFS_ABTC_MAGIC
) {
4098 dbprintf(_("bad magic # %#x in btcnt block %u/%u\n"),
4099 be32_to_cpu(block
->bb_magic
), seqno
, bno
);
4105 if (be16_to_cpu(block
->bb_level
) != level
) {
4107 dbprintf(_("expected level %d got %d in btcnt block "
4109 level
, be16_to_cpu(block
->bb_level
), seqno
, bno
);
4112 set_dbmap(seqno
, bno
, 1, DBM_BTCNT
, seqno
, bno
);
4114 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_alloc_mxr
[0] ||
4115 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_alloc_mnr
[0])) {
4116 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in "
4117 "btbno block %u/%u\n"),
4118 be16_to_cpu(block
->bb_numrecs
), mp
->m_alloc_mnr
[0],
4119 mp
->m_alloc_mxr
[0], seqno
, bno
);
4123 rp
= XFS_ALLOC_REC_ADDR(mp
, block
, 1);
4125 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++) {
4126 check_set_dbmap(seqno
, be32_to_cpu(rp
[i
].ar_startblock
),
4127 be32_to_cpu(rp
[i
].ar_blockcount
), DBM_FREE1
, DBM_FREE2
,
4129 fdblocks
+= be32_to_cpu(rp
[i
].ar_blockcount
);
4130 agffreeblks
+= be32_to_cpu(rp
[i
].ar_blockcount
);
4131 if (be32_to_cpu(rp
[i
].ar_blockcount
) > agflongest
)
4132 agflongest
= be32_to_cpu(rp
[i
].ar_blockcount
);
4133 if (be32_to_cpu(rp
[i
].ar_blockcount
) < lastcount
) {
4135 "out-of-order cnt btree record %d (%u %u) block %u/%u\n"),
4136 i
, be32_to_cpu(rp
[i
].ar_startblock
),
4137 be32_to_cpu(rp
[i
].ar_blockcount
),
4138 be32_to_cpu(agf
->agf_seqno
), bno
);
4140 lastcount
= be32_to_cpu(rp
[i
].ar_blockcount
);
4145 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_alloc_mxr
[1] ||
4146 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_alloc_mnr
[1])) {
4147 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in btbno block "
4149 be16_to_cpu(block
->bb_numrecs
), mp
->m_alloc_mnr
[1],
4150 mp
->m_alloc_mxr
[1], seqno
, bno
);
4154 pp
= XFS_ALLOC_PTR_ADDR(mp
, block
, 1, mp
->m_alloc_mxr
[1]);
4155 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++)
4156 scan_sbtree(agf
, be32_to_cpu(pp
[i
]), level
, 0, scanfunc_cnt
, TYP_CNTBT
);
4161 struct xfs_btree_block
*block
,
4168 xfs_agnumber_t seqno
= be32_to_cpu(agf
->agf_seqno
);
4174 xfs_inobt_ptr_t
*pp
;
4175 xfs_inobt_rec_t
*rp
;
4177 if (be32_to_cpu(block
->bb_magic
) != XFS_IBT_MAGIC
) {
4178 dbprintf(_("bad magic # %#x in inobt block %u/%u\n"),
4179 be32_to_cpu(block
->bb_magic
), seqno
, bno
);
4183 if (be16_to_cpu(block
->bb_level
) != level
) {
4185 dbprintf(_("expected level %d got %d in inobt block "
4187 level
, be16_to_cpu(block
->bb_level
), seqno
, bno
);
4190 set_dbmap(seqno
, bno
, 1, DBM_BTINO
, seqno
, bno
);
4192 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_inobt_mxr
[0] ||
4193 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_inobt_mnr
[0])) {
4194 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in "
4195 "inobt block %u/%u\n"),
4196 be16_to_cpu(block
->bb_numrecs
), mp
->m_inobt_mnr
[0],
4197 mp
->m_inobt_mxr
[0], seqno
, bno
);
4201 rp
= XFS_INOBT_REC_ADDR(mp
, block
, 1);
4202 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++) {
4203 agino
= be32_to_cpu(rp
[i
].ir_startino
);
4204 off
= XFS_INO_TO_OFFSET(mp
, agino
);
4206 if ((sbversion
& XFS_SB_VERSION_ALIGNBIT
) &&
4207 mp
->m_sb
.sb_inoalignmt
&&
4208 (XFS_INO_TO_AGBNO(mp
, agino
) %
4209 mp
->m_sb
.sb_inoalignmt
))
4210 sbversion
&= ~XFS_SB_VERSION_ALIGNBIT
;
4211 set_dbmap(seqno
, XFS_AGINO_TO_AGBNO(mp
, agino
),
4212 (xfs_extlen_t
)MAX(1,
4213 XFS_INODES_PER_CHUNK
>>
4214 mp
->m_sb
.sb_inopblog
),
4215 DBM_INODE
, seqno
, bno
);
4217 icount
+= XFS_INODES_PER_CHUNK
;
4218 agicount
+= XFS_INODES_PER_CHUNK
;
4219 ifree
+= be32_to_cpu(rp
[i
].ir_freecount
);
4220 agifreecount
+= be32_to_cpu(rp
[i
].ir_freecount
);
4222 set_cur(&typtab
[TYP_INODE
],
4223 XFS_AGB_TO_DADDR(mp
, seqno
,
4224 XFS_AGINO_TO_AGBNO(mp
, agino
)),
4225 (int)XFS_FSB_TO_BB(mp
, mp
->m_ialloc_blks
),
4227 if (iocur_top
->data
== NULL
) {
4229 dbprintf(_("can't read inode block "
4232 XFS_AGINO_TO_AGBNO(mp
, agino
));
4237 for (j
= 0, nfree
= 0; j
< XFS_INODES_PER_CHUNK
; j
++) {
4238 isfree
= XFS_INOBT_IS_FREE_DISK(&rp
[i
], j
);
4241 process_inode(agf
, agino
+ j
,
4242 (xfs_dinode_t
*)((char *)iocur_top
->data
+ ((off
+ j
) << mp
->m_sb
.sb_inodelog
)),
4245 if (nfree
!= be32_to_cpu(rp
[i
].ir_freecount
)) {
4247 dbprintf(_("ir_freecount/free mismatch, "
4248 "inode chunk %u/%u, freecount "
4251 be32_to_cpu(rp
[i
].ir_freecount
), nfree
);
4258 if (be16_to_cpu(block
->bb_numrecs
) > mp
->m_inobt_mxr
[1] ||
4259 (isroot
== 0 && be16_to_cpu(block
->bb_numrecs
) < mp
->m_inobt_mnr
[1])) {
4260 dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in inobt block "
4262 be16_to_cpu(block
->bb_numrecs
), mp
->m_inobt_mnr
[1],
4263 mp
->m_inobt_mxr
[1], seqno
, bno
);
4267 pp
= XFS_INOBT_PTR_ADDR(mp
, block
, 1, mp
->m_inobt_mxr
[1]);
4268 for (i
= 0; i
< be16_to_cpu(block
->bb_numrecs
); i
++)
4269 scan_sbtree(agf
, be32_to_cpu(pp
[i
]), level
, 0, scanfunc_ino
, TYP_INOBT
);
4274 xfs_agnumber_t agno
,
4275 xfs_agblock_t agbno
,
4278 xfs_agnumber_t c_agno
,
4279 xfs_agblock_t c_agbno
)
4281 check_set_dbmap(agno
, agbno
, len
, DBM_UNKNOWN
, type
, c_agno
, c_agbno
);
4286 xfs_agnumber_t agno
,
4287 xfs_agblock_t agbno
,
4295 if (!check_inomap(agno
, agbno
, len
, id
->ino
))
4297 mayprint
= verbose
| id
->ilist
| blist_size
;
4298 for (i
= 0, idp
= &inomap
[agno
][agbno
]; i
< len
; i
++, idp
++) {
4301 (verbose
|| id
->ilist
|| CHECK_BLISTA(agno
, agbno
+ i
)))
4302 dbprintf(_("setting inode to %lld for block %u/%u\n"),
4303 id
->ino
, agno
, agbno
+ i
);
4313 check_set_rdbmap(bno
, len
, DBM_UNKNOWN
, type
);
4326 if (!check_rinomap(bno
, len
, id
->ino
))
4328 mayprint
= verbose
| id
->ilist
| blist_size
;
4329 for (i
= 0, idp
= &inomap
[mp
->m_sb
.sb_agcount
][bno
];
4333 if (mayprint
&& (verbose
|| id
->ilist
|| CHECK_BLIST(bno
+ i
)))
4334 dbprintf(_("setting inode to %lld for rtblock %llu\n"),
4346 id
->link_set
= nlink
;
4348 id
->security
= security
;
4349 if (verbose
|| id
->ilist
)
4350 dbprintf(_("inode %lld nlink %u %s dir\n"), id
->ino
, nlink
,
4351 isdir
? "is" : "not");