* hashvalue were wrong but matched. Unlikely, however.
*/
if (INT_GET(entry->hashval, ARCH_CONVERT) !=
- libxfs_da_hashname((char *)&local->nameval[0],
+ libxfs_da_hashname((uchar_t *)&local->nameval[0],
INT_GET(local->namelen,
ARCH_CONVERT)) ||
(INT_GET(entry->hashval, ARCH_CONVERT) <
INT_GET(remotep->namelen, ARCH_CONVERT))) ||
(INT_GET(entry->hashval, ARCH_CONVERT)
!= libxfs_da_hashname(
- (char *)&remotep->name[0],
+ (uchar_t *)&remotep->name[0],
INT_GET(remotep->namelen, ARCH_CONVERT))) ||
(INT_GET(entry->hashval, ARCH_CONVERT)
< last_hashval) ||
return NULL;
}
-
-/*
- * Returns a pointer to range which contains value.
- */
-avlnode_t *
-avl_findrange(
- register avltree_desc_t *tree,
- register __psunsigned_t value)
-{
- register avlnode_t *np = tree->avl_root;
-
- while (np) {
- if (value < AVL_START(tree, np)) {
- np = np->avl_back;
- continue;
- }
- if (value >= AVL_END(tree, np)) {
- np = np->avl_forw;
- continue;
- }
- ASSERT(AVL_START(tree, np) <= value &&
- value < AVL_END(tree, np));
- return np;
- }
- return NULL;
-}
-
-
/*
* Returns a pointer to node which contains exact value.
*/
avltree_desc_t *tree,
avlops_t *ops);
-avlnode_t *
+__inline avlnode_t *
avl_findrange(
avltree_desc_t *tree,
- __psunsigned_t value);
+ __psunsigned_t value)
+{
+ register avlnode_t *np = tree->avl_root;
+
+ while (np) {
+ if (value < AVL_START(tree, np)) {
+ np = np->avl_back;
+ continue;
+ }
+ if (value >= AVL_END(tree, np)) {
+ np = np->avl_forw;
+ continue;
+ }
+ ASSERT(AVL_START(tree, np) <= value &&
+ value < AVL_END(tree, np));
+ return np;
+ }
+ return NULL;
+}
avlnode_t *
avl_find(
blkmap_t *blkmap,
xfs_dfiloff_t o,
xfs_dfilblks_t nb,
- bmap_ext_t **bmpp)
+ bmap_ext_t **bmpp,
+ bmap_ext_t *bmpp_single)
{
bmap_ext_t *bmp;
blkent_t *ent;
int i;
int nex;
+ if (nb == 1) {
+ /*
+ * in the common case, when mp->m_dirblkfsbs == 1,
+ * avoid additional malloc/free overhead
+ */
+ bmpp_single->startblock = blkmap_get(blkmap, o);
+ bmpp_single->blockcount = 1;
+ bmpp_single->startoff = 0;
+ bmpp_single->flag = 0;
+ *bmpp = bmpp_single;
+ return (bmpp_single->startblock != NULLDFSBNO) ? 1 : 0;
+ }
for (i = nex = 0, bmp = NULL, entp = blkmap->ents;
i < blkmap->nents;
i++, entp++) {
void blkmap_free(blkmap_t *blkmap);
xfs_dfsbno_t blkmap_get(blkmap_t *blkmap, xfs_dfiloff_t o);
int blkmap_getn(blkmap_t *blkmap, xfs_dfiloff_t o,
- xfs_dfilblks_t nb, bmap_ext_t **bmpp);
+ xfs_dfilblks_t nb, bmap_ext_t **bmpp,
+ bmap_ext_t *bmpp_single);
void blkmap_grow(blkmap_t **blkmapp, blkent_t **entp,
blkent_t *newent);
xfs_dfiloff_t blkmap_last_off(blkmap_t *blkmap);
* misc. inode-related utility routines
*/
+/*
+ * verify_ag_bno is heavily used. In the common case, it
+ * performs just two number of compares
+ */
+static __inline int
+verify_ag_bno(xfs_sb_t *sbp,
+ xfs_agnumber_t agno,
+ xfs_agblock_t agbno)
+{
+ if (agno < sbp->sb_agcount) {
+ if (agbno >= sbp->sb_agblocks) {
+ return 1; /* bad */
+ }
+ return 0; /* good */
+ }
+ if (agno == sbp->sb_agcount) {
+ if (agbno >=
+ (sbp->sb_dblocks -
+ (sbp->sb_agcount-1) *
+ sbp->sb_agblocks)) {
+ return 1; /* bad */
+ }
+ return 0; /* good */
+ }
+ return 1; /* bad */
+}
+
/*
* returns 0 if inode number is valid, 1 if bogus
*/
agno = XFS_INO_TO_AGNO(mp, ino);
agino = XFS_INO_TO_AGINO(mp, ino);
agbno = XFS_AGINO_TO_AGBNO(mp, agino);
+ if (agbno == 0)
+ return 1;
if (ino == 0 || ino == NULLFSINO)
return(1);
if (ino != XFS_AGINO_TO_INO(mp, agno, agino))
return(1);
- if (agno >= sbp->sb_agcount ||
- (agno < sbp->sb_agcount && agbno >= sbp->sb_agblocks) ||
- (agno == sbp->sb_agcount && agbno >= sbp->sb_dblocks -
- (sbp->sb_agcount-1) * sbp->sb_agblocks) ||
- (agbno == 0))
- return(1);
-
- return(0);
+ return verify_ag_bno(sbp, agno, agbno);
}
/*
* will be extra bits set at the top that shouldn't be set.
*/
agbno = XFS_AGINO_TO_AGBNO(mp, agino);
+ if (agbno == 0)
+ return 1;
- if (agno >= sbp->sb_agcount ||
- (agno < sbp->sb_agcount && agbno >= sbp->sb_agblocks) ||
- (agno == sbp->sb_agcount && agbno >= sbp->sb_dblocks -
- (sbp->sb_agcount-1) * sbp->sb_agblocks) ||
- (agbno == 0))
- return(1);
-
- return(0);
+ return verify_ag_bno(sbp, agno, agbno);
}
/*
agno = XFS_FSB_TO_AGNO(mp, fsbno);
agbno = XFS_FSB_TO_AGBNO(mp, fsbno);
- if (agno >= sbp->sb_agcount ||
- (agno < sbp->sb_agcount && agbno >= sbp->sb_agblocks) ||
- (agno == sbp->sb_agcount && agbno >= sbp->sb_dblocks -
- (sbp->sb_agcount-1) * sbp->sb_agblocks))
- return(0);
+ return verify_ag_bno(sbp, agno, agbno) == 0;
+}
- return(1);
+#define XR_DFSBNORANGE_VALID 0
+#define XR_DFSBNORANGE_BADSTART 1
+#define XR_DFSBNORANGE_BADEND 2
+#define XR_DFSBNORANGE_OVERFLOW 3
+
+static __inline int
+verify_dfsbno_range(xfs_mount_t *mp,
+ xfs_dfsbno_t fsbno,
+ xfs_dfilblks_t count)
+{
+ xfs_agnumber_t agno;
+ xfs_agblock_t agbno;
+ xfs_sb_t *sbp = &mp->m_sb;;
+
+ /* the start and end blocks better be in the same allocation group */
+ agno = XFS_FSB_TO_AGNO(mp, fsbno);
+ if (agno != XFS_FSB_TO_AGNO(mp, fsbno + count - 1)) {
+ return XR_DFSBNORANGE_OVERFLOW;
+ }
+
+ agbno = XFS_FSB_TO_AGBNO(mp, fsbno);
+ if (verify_ag_bno(sbp, agno, agbno)) {
+ return XR_DFSBNORANGE_BADSTART;
+ }
+
+ agbno = XFS_FSB_TO_AGBNO(mp, fsbno + count - 1);
+ if (verify_ag_bno(sbp, agno, agbno)) {
+ return XR_DFSBNORANGE_BADEND;
+ }
+
+ return (XR_DFSBNORANGE_VALID);
}
int
xfs_sb_t *sbp = &mp->m_sb;;
/* range check ag #, ag block. range-checking offset is pointless */
-
- if (agno >= sbp->sb_agcount ||
- (agno < sbp->sb_agcount && agbno >= sbp->sb_agblocks) ||
- (agno == sbp->sb_agcount && agbno >= sbp->sb_dblocks -
- (sbp->sb_agcount-1) * sbp->sb_agblocks))
- return(0);
-
- return(1);
+ return verify_ag_bno(sbp, agno, agbno) == 0;
}
void
int state;
int flag; /* extent flag */
int pwe; /* partially-written extent */
+ xfs_dfsbno_t e;
+ xfs_agnumber_t agno;
+ xfs_agblock_t agbno;
if (whichfork == XFS_DATA_FORK)
forkname = _("data");
return(1);
}
} else {
- if (!verify_dfsbno(mp, s)) {
+ switch (verify_dfsbno_range(mp, s, c)) {
+ case XR_DFSBNORANGE_VALID:
+ break;
+ case XR_DFSBNORANGE_BADSTART:
do_warn(
_("inode %llu - bad extent starting block number %llu, offset %llu\n"),
ino, s, o);
return(1);
- }
- if (!verify_dfsbno(mp, s + c - 1)) {
+ case XR_DFSBNORANGE_BADEND:
do_warn(
_("inode %llu - bad extent last block number %llu, offset %llu\n"),
ino, s + c - 1, o);
return(1);
- }
- if (s + c - 1 < s) {
+ case XR_DFSBNORANGE_OVERFLOW:
do_warn(
+
_("inode %llu - bad extent overflows - start %llu, end %llu, "
"offset %llu\n"),
ino, s, s + c - 1, o);
*/
if (blkmapp && *blkmapp)
blkmap_set_ext(blkmapp, o, s, c);
- for (b = s; b < s + c; b++) {
+ /*
+ * Profiling shows that the following loop takes the
+ * most time in all of xfs_repair.
+ */
+ agno = XFS_FSB_TO_AGNO(mp, s);
+ agbno = XFS_FSB_TO_AGBNO(mp, s);
+ e = s + c;
+ for (b = s; b < e; b++, agbno++) {
if (check_dups == 1) {
/*
* if we're just checking the bmap for dups,
* checking each entry without setting the
* block bitmap
*/
- if (search_dup_extent(mp,
- XFS_FSB_TO_AGNO(mp, b),
- XFS_FSB_TO_AGBNO(mp, b))) {
+ if (search_dup_extent(mp, agno, agbno)) {
do_warn(
_("%s fork in ino %llu claims dup extent, off - %llu, "
"start - %llu, cnt %llu\n"),
* in regular data space, not realtime partion.
*/
if (type == XR_INO_RTDATA && whichfork == XFS_ATTR_FORK) {
- if (mp->m_sb.sb_agcount < XFS_FSB_TO_AGNO(mp, b))
+ if (mp->m_sb.sb_agcount < agno)
return(1);
}
- state = get_fsbno_state(mp, b);
+ /* Process in chunks of 16 (XR_BB_UNIT/XR_BB)
+ * for common XR_E_UNKNOWN to XR_E_INUSE transition
+ */
+ if (((agbno & XR_BB_MASK) == 0) && ((s + c - b) >= (XR_BB_UNIT/XR_BB))) {
+ if (ba_bmap[agno][agbno>>XR_BB] == XR_E_UNKNOWN_LL) {
+ ba_bmap[agno][agbno>>XR_BB] = XR_E_INUSE_LL;
+ agbno += (XR_BB_UNIT/XR_BB) - 1;
+ b += (XR_BB_UNIT/XR_BB) - 1;
+ continue;
+ }
+
+ }
+
+ state = get_agbno_state(mp, agno, agbno);
switch (state) {
case XR_E_FREE:
case XR_E_FREE1:
forkname, ino, (__uint64_t) b);
/* fall through ... */
case XR_E_UNKNOWN:
- set_fsbno_state(mp, b, XR_E_INUSE);
+ set_agbno_state(mp, agno, agbno, XR_E_INUSE);
break;
case XR_E_BAD_STATE:
do_error(_("bad state in block map %llu\n"), b);
return(1);
case XR_E_INUSE:
case XR_E_MULT:
- set_fsbno_state(mp, b, XR_E_MULT);
+ set_agbno_state(mp, agno, agbno, XR_E_MULT);
do_warn(
_("%s fork in %s inode %llu claims used block %llu\n"),
forkname, ftype, ino, (__uint64_t) b);
int whichfork)
{
int i;
+#ifdef DEBUG
int prev_level;
+#endif
int flag;
int found;
xfs_bmbt_rec_32_t *rec;
/*
* ok, now traverse any interior btree nodes
*/
- prev_level = rootblock->bb_level;
+#ifdef DEBUG
+ prev_level = INT_GET(block->bb_level, ARCH_CONVERT);
+#endif
while (INT_GET(block->bb_level, ARCH_CONVERT) > 0) {
+#ifdef DEBUG
ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) < prev_level);
prev_level = INT_GET(block->bb_level, ARCH_CONVERT);
+#endif
if (INT_GET(block->bb_numrecs, ARCH_CONVERT) >
mp->m_bmap_dmxr[1]) {
return(0);
}
-int
+static __inline int
process_misc_ino_types_blocks(xfs_drfsbno_t totblocks, xfs_ino_t lino, int type)
{
/*
*/
if (INT_GET(dinoc->di_mode, ARCH_CONVERT) != 0 &&
((((INT_GET(dinoc->di_mode, ARCH_CONVERT) & S_IFMT) >> 12) > 15) ||
- dinoc->di_format < XFS_DINODE_FMT_DEV ||
- dinoc->di_format > XFS_DINODE_FMT_UUID ||
+ (uchar_t) dinoc->di_format > XFS_DINODE_FMT_UUID ||
(!(okfmts[(INT_GET(dinoc->di_mode, ARCH_CONVERT) & S_IFMT) >> 12] &
(1 << dinoc->di_format))))) {
/* bad inode format */
*used = is_free;
*isa_dir = 0;
blkmap_free(dblkmap);
-
return(1);
}
*used = is_free;
*isa_dir = 0;
blkmap_free(dblkmap);
-
return(1);
}
*isa_dir = 0;
blkmap_free(dblkmap);
blkmap_free(ablkmap);
-
return(1);
}
*used = is_free;
*isa_dir = 0;
blkmap_free(dblkmap);
-
return(1);
}
*used = is_free;
*isa_dir = 0;
blkmap_free(dblkmap);
-
return(1);
}
if (anextents != INT_GET(dinoc->di_anextents, ARCH_CONVERT)) {
abort();
}
- blkmap_free(dblkmap);
+ if (dblkmap)
+ blkmap_free(dblkmap);
if (err) {
/*
*/
bcopy(namest->name, fname, entry->namelen);
fname[entry->namelen] = '\0';
- hashval = libxfs_da_hashname(fname, entry->namelen);
+ hashval = libxfs_da_hashname((uchar_t *) fname, entry->namelen);
/*
* only complain about illegal names in phase 3 (when
bmap_ext_t *bmp)
{
xfs_buf_t *bp;
+ xfs_buf_t *bparray[4];
xfs_buf_t **bplist;
xfs_dabuf_t *dabuf;
int i;
int off;
- bplist = calloc(nex, sizeof(*bplist));
- if (bplist == NULL) {
- do_error(_("couldn't malloc dir2 buffer list\n"));
- exit(1);
+ if (nex > (sizeof(bparray)/sizeof(xfs_buf_t *))) {
+ bplist = calloc(nex, sizeof(*bplist));
+ if (bplist == NULL) {
+ do_error(_("couldn't malloc dir2 buffer list\n"));
+ exit(1);
+ }
+ }
+ else {
+ /* common case avoids calloc/free */
+ bplist = bparray;
}
for (i = 0; i < nex; i++) {
bplist[i] = libxfs_readbuf(mp->m_dev,
XFS_BUF_COUNT(bp));
}
}
- free(bplist);
+ if (bplist != bparray)
+ free(bplist);
return dabuf;
failed:
for (i = 0; i < nex; i++)
libxfs_putbuf(bplist[i]);
- free(bplist);
+ if (bplist != bparray)
+ free(bplist);
return NULL;
}
int i;
int nex;
xfs_da_intnode_t *node;
+ bmap_ext_t lbmp;
/*
* traverse down left-side of tree until we hit the
* read in each block along the way and set up cursor
*/
nex = blkmap_getn(da_cursor->blkmap, bno, mp->m_dirblkfsbs,
- &bmp);
+ &bmp, &lbmp);
if (nex == 0)
goto error_out;
bp = da_read_buf(mp, nex, bmp);
- free(bmp);
+ if (bmp != &lbmp)
+ free(bmp);
if (bp == NULL) {
do_warn(_("can't read block %u for directory inode "
"%llu\n"),
int this_level = p_level + 1;
bmap_ext_t *bmp;
int nex;
+ bmap_ext_t lbmp;
/*
* index is currently set to point to the entry that
dabno = INT_GET(node->hdr.info.forw, ARCH_CONVERT);
ASSERT(dabno != 0);
nex = blkmap_getn(cursor->blkmap, dabno, mp->m_dirblkfsbs,
- &bmp);
+ &bmp, &lbmp);
if (nex == 0) {
do_warn(_("can't get map info for block %u of "
"directory inode %llu\n"),
}
bp = da_read_buf(mp, nex, bmp);
+ if (bmp != &lbmp)
+ free(bmp);
if (bp == NULL) {
do_warn(_("can't read block %u for directory inode "
xfs_dir2_block_tail_t *btp;
int nex;
int rval;
+ bmap_ext_t lbmp;
*repair = *dot = *dotdot = 0;
*parent = NULLFSINO;
- nex = blkmap_getn(blkmap, mp->m_dirdatablk, mp->m_dirblkfsbs, &bmp);
+ nex = blkmap_getn(blkmap, mp->m_dirdatablk, mp->m_dirblkfsbs, &bmp, &lbmp);
if (nex == 0) {
do_warn(_("block %u for directory inode %llu is missing\n"),
mp->m_dirdatablk, ino);
return 1;
}
bp = da_read_buf(mp, nex, bmp);
- free(bmp);
+ if (bmp != &lbmp)
+ free(bmp);
if (bp == NULL) {
do_warn(_("can't read block %u for directory inode %llu\n"),
mp->m_dirdatablk, ino);
xfs_dir2_leaf_t *leaf;
int nex;
xfs_dablk_t prev_bno;
+ bmap_ext_t lbmp;
da_bno = da_cursor->level[0].bno;
ino = da_cursor->ino;
do {
nex = blkmap_getn(da_cursor->blkmap, da_bno, mp->m_dirblkfsbs,
- &bmp);
+ &bmp, &lbmp);
/*
* Directory code uses 0 as the NULL block pointer since 0
* is the root block and no directory block pointer can point
goto error_out;
}
bp = da_read_buf(mp, nex, bmp);
- free(bmp);
+ if (bmp != &lbmp)
+ free(bmp);
bmp = NULL;
if (bp == NULL) {
do_warn(_("can't read file block %u for directory "
* Release all buffers holding interior btree blocks.
*/
err_release_dir2_cursor(mp, da_cursor, 0);
- if (bmp)
+ if (bmp && (bmp != &lbmp))
free(bmp);
return 1;
}
xfs_dfiloff_t ndbno;
int nex;
int t;
+ bmap_ext_t lbmp;
*repair = *dot = *dotdot = good = 0;
*parent = NULLFSINO;
ndbno = NULLDFILOFF;
while ((dbno = blkmap_next_off(blkmap, ndbno, &t)) < mp->m_dirleafblk) {
- nex = blkmap_getn(blkmap, dbno, mp->m_dirblkfsbs, &bmp);
+ nex = blkmap_getn(blkmap, dbno, mp->m_dirblkfsbs, &bmp, &lbmp);
ndbno = dbno + mp->m_dirblkfsbs - 1;
if (nex == 0) {
do_warn(_("block %llu for directory inode %llu is "
continue;
}
bp = da_read_buf(mp, nex, bmp);
- free(bmp);
+ if (bmp != &lbmp)
+ free(bmp);
if (bp == NULL) {
do_warn(_("can't read block %llu for directory inode "
"%llu\n"),
#define XR_E_FS_MAP 7 /* extent used by fs space/inode maps */
#define XR_E_BAD_STATE 8
+/* extent states, in 64 bit word chunks */
+#define XR_E_UNKNOWN_LL 0x0000000000000000LL
+#define XR_E_FREE1_LL 0x1111111111111111LL
+#define XR_E_FREE_LL 0x2222222222222222LL
+#define XR_E_INUSE_LL 0x3333333333333333LL
+#define XR_E_INUSE_FS_LL 0x4444444444444444LL
+#define XR_E_MULT_LL 0x5555555555555555LL
+#define XR_E_INO_LL 0x6666666666666666LL
+#define XR_E_FS_MAP_LL 0x7777777777777777LL
+
/* separate state bit, OR'ed into high (4th) bit of ex_state field */
#define XR_E_WRITTEN 0x8 /* extent has been written out, can't reclaim */
xfs_agblock_t startblock,
xfs_extlen_t blockcount);
-int search_dup_extent(xfs_mount_t *mp,
- xfs_agnumber_t agno,
- xfs_agblock_t agbno);
+extern avltree_desc_t **extent_tree_ptrs;
+/* ARGSUSED */
+static __inline int
+search_dup_extent(xfs_mount_t *mp, xfs_agnumber_t agno, xfs_agblock_t agbno)
+{
+ ASSERT(agno < glob_agcount);
+
+ if (avl_findrange(extent_tree_ptrs[agno], agbno) != NULL)
+ return(1);
+
+ return(0);
+}
void add_rt_dup_extent(xfs_drtbno_t startblock,
xfs_extlen_t blockcount);
*/
void get_inode_rec(xfs_agnumber_t agno, ino_tree_node_t *ino_rec);
-ino_tree_node_t *findfirst_inode_rec(xfs_agnumber_t agno);
-ino_tree_node_t *find_inode_rec(xfs_agnumber_t agno, xfs_agino_t ino);
+extern avltree_desc_t **inode_tree_ptrs;
+static __inline ino_tree_node_t *
+findfirst_inode_rec(xfs_agnumber_t agno)
+{
+ return((ino_tree_node_t *) inode_tree_ptrs[agno]->avl_firstino);
+}
+static __inline ino_tree_node_t *
+find_inode_rec(xfs_agnumber_t agno, xfs_agino_t ino)
+{
+ return((ino_tree_node_t *)
+ avl_findrange(inode_tree_ptrs[agno], ino));
+}
void find_inode_rec_range(xfs_agnumber_t agno,
xfs_agino_t start_ino, xfs_agino_t end_ino,
ino_tree_node_t **first, ino_tree_node_t **last);
* an inode that we've counted is removed.
*/
-void add_inode_reached(ino_tree_node_t *ino_rec, int ino_offset);
-void add_inode_ref(ino_tree_node_t *ino_rec, int ino_offset);
-void drop_inode_ref(ino_tree_node_t *ino_rec, int ino_offset);
-int is_inode_reached(ino_tree_node_t *ino_rec, int ino_offset);
-int is_inode_referenced(ino_tree_node_t *ino_rec, int ino_offset);
-__uint32_t num_inode_references(ino_tree_node_t *ino_rec, int ino_offset);
+static __inline int
+is_inode_reached(ino_tree_node_t *ino_rec, int ino_offset)
+{
+ ASSERT(ino_rec->ino_un.backptrs != NULL);
+ return(XFS_INO_RCHD_IS_RCHD(ino_rec, ino_offset));
+}
+
+static __inline void
+add_inode_reached(ino_tree_node_t *ino_rec, int ino_offset)
+{
+ ASSERT(ino_rec->ino_un.backptrs != NULL);
+
+ ino_rec->ino_un.backptrs->nlinks[ino_offset]++;
+ XFS_INO_RCHD_SET_RCHD(ino_rec, ino_offset);
+
+ ASSERT(is_inode_reached(ino_rec, ino_offset));
+}
+
+static __inline void
+add_inode_ref(ino_tree_node_t *ino_rec, int ino_offset)
+{
+ ASSERT(ino_rec->ino_un.backptrs != NULL);
+
+ ino_rec->ino_un.backptrs->nlinks[ino_offset]++;
+}
+
+static __inline void
+drop_inode_ref(ino_tree_node_t *ino_rec, int ino_offset)
+{
+ ASSERT(ino_rec->ino_un.backptrs != NULL);
+ ASSERT(ino_rec->ino_un.backptrs->nlinks[ino_offset] > 0);
+
+ if (--ino_rec->ino_un.backptrs->nlinks[ino_offset] == 0)
+ XFS_INO_RCHD_CLR_RCHD(ino_rec, ino_offset);
+}
+
+static __inline int
+is_inode_referenced(ino_tree_node_t *ino_rec, int ino_offset)
+{
+ ASSERT(ino_rec->ino_un.backptrs != NULL);
+ return(ino_rec->ino_un.backptrs->nlinks[ino_offset] > 0);
+}
+
+static __inline __uint32_t
+num_inode_references(ino_tree_node_t *ino_rec, int ino_offset)
+{
+ ASSERT(ino_rec->ino_un.backptrs != NULL);
+ return(ino_rec->ino_un.backptrs->nlinks[ino_offset]);
+}
/*
* has an inode been processed for phase 6 (reference count checking)?
static avl64tree_desc_t *rt_ext_tree_ptr; /* dup extent tree for rt */
-static avltree_desc_t **extent_tree_ptrs; /* array of extent tree ptrs */
+avltree_desc_t **extent_tree_ptrs; /* array of extent tree ptrs */
/* one per ag for dups */
static avltree_desc_t **extent_bno_ptrs; /*
* array of extent tree ptrs
return;
}
-/*
- * returns 1 if block is a dup, 0 if not
- */
-/* ARGSUSED */
-int
-search_dup_extent(xfs_mount_t *mp, xfs_agnumber_t agno, xfs_agblock_t agbno)
-{
- ASSERT(agno < glob_agcount);
-
- if (avl_findrange(extent_tree_ptrs[agno], agbno) != NULL)
- return(1);
-
- return(0);
-}
-
static __psunsigned_t
avl_ext_start(avlnode_t *node)
{
/*
* array of inode tree ptrs, one per ag
*/
-static avltree_desc_t **inode_tree_ptrs;
+avltree_desc_t **inode_tree_ptrs;
/*
* ditto for uncertain inodes
return;
}
-/*
- * returns the inode record desired containing the inode
- * returns NULL if inode doesn't exist. The tree-based find
- * routines do NOT pull records out of the tree.
- */
-ino_tree_node_t *
-find_inode_rec(xfs_agnumber_t agno, xfs_agino_t ino)
-{
- return((ino_tree_node_t *)
- avl_findrange(inode_tree_ptrs[agno], ino));
-}
-
void
find_inode_rec_range(xfs_agnumber_t agno, xfs_agino_t start_ino,
xfs_agino_t end_ino, ino_tree_node_t **first,
return(ino_rec);
}
-ino_tree_node_t *
-findfirst_inode_rec(xfs_agnumber_t agno)
-{
- return((ino_tree_node_t *) inode_tree_ptrs[agno]->avl_firstino);
-}
-
void
print_inode_list_int(xfs_agnumber_t agno, int uncertain)
{
* pointers, link counts and reached bits for phase 6 and phase 7.
*/
+#ifdef DEBUG
void
add_inode_reached(ino_tree_node_t *ino_rec, int ino_offset)
{
ASSERT(ino_rec->ino_un.backptrs != NULL);
return(ino_rec->ino_un.backptrs->nlinks[ino_offset]);
}
+#endif /* DEBUG */
#if 0
static backptrs_t *bptrs;
*/
for (j = ag_hdr_block; j < ag_end; j++) {
+ /* Process in chunks of 16 (XR_BB_UNIT/XR_BB) */
+ if ((extent_start == 0) && ((j & XR_BB_MASK) == 0)) {
+ switch(ba_bmap[i][j>>XR_BB]) {
+ case XR_E_UNKNOWN_LL:
+ case XR_E_FREE1_LL:
+ case XR_E_FREE_LL:
+ case XR_E_INUSE_LL:
+ case XR_E_INUSE_FS_LL:
+ case XR_E_INO_LL:
+ case XR_E_FS_MAP_LL:
+ j += (XR_BB_UNIT/XR_BB) - 1;
+ continue;
+ }
+ }
+
bstate = get_agbno_state(mp, i, j);
switch (bstate) {
agbno, state);
}
#endif
+ /* Process in chunks of 16 (XR_BB_UNIT/XR_BB) */
+ if ((in_extent == 0) && ((agbno & XR_BB_MASK) == 0)) {
+ /* testing >= XR_E_INUSE */
+ switch (ba_bmap[agno][agbno>>XR_BB]) {
+ case XR_E_INUSE_LL:
+ case XR_E_INUSE_FS_LL:
+ case XR_E_INO_LL:
+ case XR_E_FS_MAP_LL:
+ agbno += (XR_BB_UNIT/XR_BB) - 1;
+ continue;
+ }
+
+ }
if (get_agbno_state(mp, agno, agbno) < XR_E_INUSE) {
free_blocks++;
if (in_extent == 0) {
int extra_blocks = 0;
uint num_freeblocks;
xfs_extlen_t freeblks1;
+#ifdef DEBUG
xfs_extlen_t freeblks2;
+#endif
xfs_agblock_t num_extents;
extern int count_bno_extents(xfs_agnumber_t);
extern int count_bno_extents_blocks(xfs_agnumber_t, uint *);
#endif
write_cursor(&bno_btree_curs);
+#ifdef DEBUG
freeblks2 = build_freespace_tree(mp, agno,
&bcnt_btree_curs, XFS_ABTC_MAGIC);
+#else
+ (void) build_freespace_tree(mp, agno,
+ &bcnt_btree_curs, XFS_ABTC_MAGIC);
+#endif
write_cursor(&bcnt_btree_curs);
ASSERT(freeblks1 == freeblks2);
ptr += XFS_DIR2_DATA_ENTSIZE(dep->namelen);
lastfree = 0;
dir_hash_add(hashtab,
- libxfs_da_hashname((char *)dep->name, dep->namelen),
+ libxfs_da_hashname((uchar_t *)dep->name, dep->namelen),
addr, dep->name[0] == '/');
/*
* skip bogus entries (leading '/'). they'll be deleted