]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
These changes fall into three categores which are:
authorMadan Valluri <mvalluri@sgi.com>
Fri, 12 May 2006 16:03:02 +0000 (16:03 +0000)
committerMadan Valluri <mvalluri@sgi.com>
Fri, 12 May 2006 16:03:02 +0000 (16:03 +0000)
1) Eliminate compiler warning (COMP)
2) Bug fixes (BUG)
3) Reduce CPU cycles. (CPU)
1) Supply cast to libxfs_da_hashname (COMP)

14 files changed:
repair/attr_repair.c
repair/avl.c
repair/avl.h
repair/bmap.c
repair/bmap.h
repair/dinode.c
repair/dir.c
repair/dir2.c
repair/incore.h
repair/incore_ext.c
repair/incore_ino.c
repair/phase4.c
repair/phase5.c
repair/phase6.c

index ce98a2ef681754e766119946c36fbfc94f99e530..587c1dd343053d35546c8c3067b8b97a74287a55 100644 (file)
@@ -476,7 +476,7 @@ process_leaf_attr_block(
                         * 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) <
@@ -517,7 +517,7 @@ process_leaf_attr_block(
                                        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) ||
index 8316dc466845aef03da50e75b6521ed93959276c..169c85993db35ba8b5feb490c72af65e9927c21c 100644 (file)
@@ -654,34 +654,6 @@ avl_findanyrange(
        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.
  */
index e5f9a0601ed75c4010615ab24f22da567fd8590f..d65a76ff61ef9e028c08b76febeac99c5492f409 100644 (file)
@@ -84,10 +84,28 @@ avl_init_tree(
        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(
index c82219cff080cd965e3582f1aa410fabe22c64ce..05d5da89b043fe4c8ae4f509b53340a41ba13c98 100644 (file)
@@ -169,7 +169,8 @@ blkmap_getn(
        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;
@@ -178,6 +179,18 @@ blkmap_getn(
        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++) {
index 1f400e774b1303a80c797824b83a48af9cc826a6..eba1799f5d0ab534c046a2343e1031f055f9aa8d 100644 (file)
@@ -61,7 +61,8 @@ blkmap_t      *blkmap_alloc(xfs_extnum_t);
 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);
index a475f159ea4a1058d4c64038f5264ebeeee070c4..4395aa0770ac6651d2db32c9e91668d2e853c655 100644 (file)
@@ -306,6 +306,33 @@ clear_dinode(xfs_mount_t *mp, xfs_dinode_t *dino, xfs_ino_t ino_num)
  * 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
  */
@@ -323,6 +350,8 @@ verify_inum(xfs_mount_t             *mp,
        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);
@@ -330,14 +359,7 @@ verify_inum(xfs_mount_t            *mp,
        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);
 }
 
 /*
@@ -366,15 +388,10 @@ verify_aginum(xfs_mount_t *mp,
         * 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);
 }
 
 /*
@@ -393,13 +410,40 @@ verify_dfsbno(xfs_mount_t *mp,
        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
@@ -410,14 +454,7 @@ verify_agbno(xfs_mount_t   *mp,
        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
@@ -512,6 +549,9 @@ process_bmbt_reclist_int(
        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");
@@ -570,20 +610,22 @@ process_bmbt_reclist_int(
                                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);
@@ -699,7 +741,14 @@ process_bmbt_reclist_int(
                 */
                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,
@@ -707,9 +756,7 @@ process_bmbt_reclist_int(
                                 * 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"),
@@ -724,11 +771,24 @@ process_bmbt_reclist_int(
                         * 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:
@@ -737,7 +797,7 @@ process_bmbt_reclist_int(
                                        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);
@@ -752,7 +812,7 @@ process_bmbt_reclist_int(
                                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);
@@ -898,7 +958,9 @@ getfunc_btree(xfs_mount_t           *mp,
                int                     whichfork)
 {
        int                     i;
+#ifdef DEBUG
        int                     prev_level;
+#endif
        int                     flag;
        int                     found;
        xfs_bmbt_rec_32_t       *rec;
@@ -961,12 +1023,16 @@ getfunc_btree(xfs_mount_t                *mp,
        /*
         * 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]) {
@@ -1647,7 +1713,7 @@ process_misc_ino_types(xfs_mount_t        *mp,
        return(0);
 }
 
-int
+static __inline int
 process_misc_ino_types_blocks(xfs_drfsbno_t totblocks, xfs_ino_t lino, int type)
 {
        /*
@@ -1901,8 +1967,7 @@ process_dinode_int(xfs_mount_t *mp,
         */
        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 */
@@ -2385,7 +2450,6 @@ _("mismatch between format (%d) and size (%lld) in directory ino %llu\n"),
                *used = is_free;
                *isa_dir = 0;
                blkmap_free(dblkmap);
-
                return(1);
        }
 
@@ -2426,7 +2490,6 @@ _("mismatch between format (%d) and size (%lld) in directory ino %llu\n"),
                        *used = is_free;
                        *isa_dir = 0;
                        blkmap_free(dblkmap);
-
                        return(1);
                }
 
@@ -2549,7 +2612,6 @@ _("mismatch between format (%d) and size (%lld) in directory ino %llu\n"),
                                *isa_dir = 0;
                                blkmap_free(dblkmap);
                                blkmap_free(ablkmap);
-
                                return(1);
                        }
 
@@ -2602,7 +2664,6 @@ _("mismatch between format (%d) and size (%lld) in directory ino %llu\n"),
                *used = is_free;
                *isa_dir = 0;
                blkmap_free(dblkmap);
-
                return(1);
        }
 
@@ -2669,7 +2730,6 @@ _("mismatch between format (%d) and size (%lld) in directory ino %llu\n"),
                *used = is_free;
                *isa_dir = 0;
                blkmap_free(dblkmap);
-
                return(1);
        }
        if (anextents != INT_GET(dinoc->di_anextents, ARCH_CONVERT))  {
@@ -2732,7 +2792,8 @@ _("mismatch between format (%d) and size (%lld) in directory ino %llu\n"),
                abort();
        }
 
-       blkmap_free(dblkmap);
+       if (dblkmap)
+               blkmap_free(dblkmap);
 
        if (err)  {
                /*
index d37693b796855eb11c73a9941541804ac564b274..011cacfeadfd16a4756eaa4f6eb5a57ea4a93709 100644 (file)
@@ -2138,7 +2138,7 @@ _("dir entry slot %d in block %u conflicts with used space in dir inode %llu\n")
                 */
                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
index 401d4b62df8594482f40fa366ab5bc5c04140829..0dc82ae44bc684452f823d63055cfee4835d1ed6 100644 (file)
@@ -83,15 +83,22 @@ da_read_buf(
        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,
@@ -128,12 +135,14 @@ da_read_buf(
                                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;
 }
 
@@ -249,6 +258,7 @@ traverse_int_dir2block(xfs_mount_t  *mp,
        int                     i;
        int                     nex;
        xfs_da_intnode_t        *node;
+       bmap_ext_t              lbmp;
 
        /*
         * traverse down left-side of tree until we hit the
@@ -265,13 +275,14 @@ traverse_int_dir2block(xfs_mount_t        *mp,
                 * 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"),
@@ -578,6 +589,7 @@ verify_dir2_path(xfs_mount_t        *mp,
        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
@@ -619,7 +631,7 @@ verify_dir2_path(xfs_mount_t        *mp,
                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"),
@@ -628,6 +640,8 @@ verify_dir2_path(xfs_mount_t        *mp,
                }
 
                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 "
@@ -1674,17 +1688,19 @@ process_block_dir2(
        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);
@@ -1786,6 +1802,7 @@ process_leaf_level_dir2(
        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;
@@ -1796,7 +1813,7 @@ process_leaf_level_dir2(
 
        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
@@ -1811,7 +1828,8 @@ process_leaf_level_dir2(
                        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 "
@@ -1895,7 +1913,7 @@ error_out:
         * 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;
 }
@@ -1976,12 +1994,13 @@ process_leaf_node_dir2(
        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 "
@@ -1990,7 +2009,8 @@ process_leaf_node_dir2(
                        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"),
index eef8f6cd6894eee5d9fd932e6eeceab83e90300e..25eabdc19f6432f7ee176dccdfe90a50d3b3fff5 100644 (file)
@@ -167,6 +167,16 @@ typedef struct rt_extent_tree_node  {
 #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 */
@@ -227,9 +237,18 @@ void               add_dup_extent(xfs_agnumber_t agno,
                                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);
@@ -348,8 +367,18 @@ void               free_inode_rec(xfs_agnumber_t agno, ino_tree_node_t *ino_rec);
  */
 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);
@@ -486,12 +515,55 @@ void                      clear_uncertain_ino_cache(xfs_agnumber_t agno);
  * 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)?
index de0154ccf381892d1a1a60485396a18bd3de5a25..d98f246e9a0b75308602cb0264f494a1a06f0618 100644 (file)
@@ -71,7 +71,7 @@ static rt_ext_flist_t rt_ext_flist;
 
 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
@@ -573,21 +573,6 @@ add_dup_extent(xfs_agnumber_t agno, xfs_agblock_t startblock,
        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)
 {
index 08f0eef568150741c0ca3192f382c071c613e919..39093fc195e6aa36b7f74a26451f1d62cf40e257 100644 (file)
@@ -29,7 +29,7 @@ extern avlnode_t      *avl_firstino(avlnode_t *root);
 /*
  * 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
@@ -323,18 +323,6 @@ free_inode_rec(xfs_agnumber_t agno, ino_tree_node_t *ino_rec)
        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,
@@ -389,12 +377,6 @@ set_inode_free_alloc(xfs_agnumber_t agno, xfs_agino_t ino)
        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)
 {
@@ -589,6 +571,7 @@ get_inode_parent(ino_tree_node_t *irec, int offset)
  * 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)
 {
@@ -644,6 +627,7 @@ 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]);
 }
+#endif /* DEBUG */
 
 #if 0
 static backptrs_t      *bptrs;
index cfc286bc8f27b6104ca1ff2131983baeaeb568d5..492bd86a7b9bc8b55c3382ca4c9ffc28e7fc8b59 100644 (file)
@@ -1176,6 +1176,21 @@ phase4(xfs_mount_t *mp)
                 */
                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)  {
index f96b773e8a76261d405894413d9ca73f1c50567a..6c79162d2b78bea70141912bd9f4118162229f99 100644 (file)
@@ -123,6 +123,19 @@ mk_incore_fstree(xfs_mount_t *mp, xfs_agnumber_t agno)
                                        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)  {
@@ -1413,7 +1426,9 @@ phase5(xfs_mount_t *mp)
        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 *);
@@ -1564,8 +1579,13 @@ phase5(xfs_mount_t *mp)
 #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);
index 6acc148d21cc677cd3639fa931ac27b639f33869..5134282d3de09f47bc08abd64def3c285d714f70 100644 (file)
@@ -1896,7 +1896,7 @@ longform_dir2_entry_check_data(
                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