]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blobdiff - db/check.c
progs: clean up libxfs.h includes
[thirdparty/xfsprogs-dev.git] / db / check.c
index a8939a40aa8a9df7b3a57d8fbbbfc70a2a892489..ce98360f43eb1e5c683e560c51c9b6fe38390965 100644 (file)
@@ -16,7 +16,7 @@
  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-#include <xfs/libxfs.h>
+#include "xfs/libxfs.h"
 #include <math.h>
 #include <sys/time.h>
 #include "bmap.h"
@@ -31,6 +31,7 @@
 #include "output.h"
 #include "init.h"
 #include "malloc.h"
+#include "dir2.h"
 
 typedef enum {
        IS_USER_QUOTA, IS_PROJECT_QUOTA, IS_GROUP_QUOTA,
@@ -182,8 +183,8 @@ typedef void        (*scan_lbtree_f_t)(struct xfs_btree_block *block,
                                   dbm_t                type,
                                   xfs_fsblock_t        bno,
                                   inodata_t            *id,
-                                  xfs_drfsbno_t        *totd,
-                                  xfs_drfsbno_t        *toti,
+                                  xfs_rfsblock_t       *totd,
+                                  xfs_rfsblock_t       *toti,
                                   xfs_extnum_t         *nex,
                                   blkmap_t             **blkmapp,
                                   int                  isroot,
@@ -232,23 +233,23 @@ static int                check_inomap(xfs_agnumber_t agno, xfs_agblock_t agbno,
 static void            check_linkcounts(xfs_agnumber_t agno);
 static int             check_range(xfs_agnumber_t agno, xfs_agblock_t agbno,
                                    xfs_extlen_t len);
-static void            check_rdbmap(xfs_drfsbno_t bno, xfs_extlen_t len,
+static void            check_rdbmap(xfs_rfsblock_t bno, xfs_extlen_t len,
                                     dbm_t type);
-static int             check_rinomap(xfs_drfsbno_t bno, xfs_extlen_t len,
+static int             check_rinomap(xfs_rfsblock_t bno, xfs_extlen_t len,
                                      xfs_ino_t c_ino);
 static void            check_rootdir(void);
-static int             check_rrange(xfs_drfsbno_t bno, xfs_extlen_t len);
+static int             check_rrange(xfs_rfsblock_t bno, xfs_extlen_t len);
 static void            check_set_dbmap(xfs_agnumber_t agno,
                                        xfs_agblock_t agbno, xfs_extlen_t len,
                                        dbm_t type1, dbm_t type2,
                                        xfs_agnumber_t c_agno,
                                        xfs_agblock_t c_agbno);
-static void            check_set_rdbmap(xfs_drfsbno_t bno, xfs_extlen_t len,
+static void            check_set_rdbmap(xfs_rfsblock_t bno, xfs_extlen_t len,
                                         dbm_t type1, dbm_t type2);
 static void            check_summary(void);
 static void            checknot_dbmap(xfs_agnumber_t agno, xfs_agblock_t agbno,
                                       xfs_extlen_t len, int typemask);
-static void            checknot_rdbmap(xfs_drfsbno_t bno, xfs_extlen_t len,
+static void            checknot_rdbmap(xfs_rfsblock_t bno, xfs_extlen_t len,
                                        int typemask);
 static void            dir_hash_add(xfs_dahash_t hash,
                                     xfs_dir2_dataptr_t addr);
@@ -267,41 +268,34 @@ static xfs_ino_t  process_block_dir_v2(blkmap_t *blkmap, int *dot,
                                             int *dotdot, inodata_t *id);
 static void            process_bmbt_reclist(xfs_bmbt_rec_t *rp, int numrecs,
                                             dbm_t type, inodata_t *id,
-                                            xfs_drfsbno_t *tot,
+                                            xfs_rfsblock_t *tot,
                                             blkmap_t **blkmapp);
 static void            process_btinode(inodata_t *id, xfs_dinode_t *dip,
-                                       dbm_t type, xfs_drfsbno_t *totd,
-                                       xfs_drfsbno_t *toti, xfs_extnum_t *nex,
+                                       dbm_t type, xfs_rfsblock_t *totd,
+                                       xfs_rfsblock_t *toti, xfs_extnum_t *nex,
                                        blkmap_t **blkmapp, int whichfork);
 static xfs_ino_t       process_data_dir_v2(int *dot, int *dotdot,
                                            inodata_t *id, int v,
                                            xfs_dablk_t dabno,
                                            freetab_t **freetabp);
-static xfs_dir2_data_free_t
-                       *process_data_dir_v2_freefind(xfs_dir2_data_t *data,
-                                                  xfs_dir2_data_unused_t *dup);
+static xfs_dir2_data_free_t *process_data_dir_v2_freefind(
+                                       struct xfs_dir2_data_hdr *data,
+                                       struct xfs_dir2_data_unused *dup);
 static void            process_dir(xfs_dinode_t *dip, blkmap_t *blkmap,
                                    inodata_t *id);
-static int             process_dir_v1(xfs_dinode_t *dip, blkmap_t *blkmap,
-                                      int *dot, int *dotdot, inodata_t *id,
-                                      xfs_ino_t *parent);
 static int             process_dir_v2(xfs_dinode_t *dip, blkmap_t *blkmap,
                                       int *dot, int *dotdot, inodata_t *id,
                                       xfs_ino_t *parent);
 static void            process_exinode(inodata_t *id, xfs_dinode_t *dip,
-                                       dbm_t type, xfs_drfsbno_t *totd,
-                                       xfs_drfsbno_t *toti, xfs_extnum_t *nex,
+                                       dbm_t type, xfs_rfsblock_t *totd,
+                                       xfs_rfsblock_t *toti, xfs_extnum_t *nex,
                                        blkmap_t **blkmapp, int whichfork);
 static void            process_inode(xfs_agf_t *agf, xfs_agino_t agino,
                                      xfs_dinode_t *dip, int isfree);
 static void            process_lclinode(inodata_t *id, xfs_dinode_t *dip,
-                                        dbm_t type, xfs_drfsbno_t *totd,
-                                        xfs_drfsbno_t *toti, xfs_extnum_t *nex,
+                                        dbm_t type, xfs_rfsblock_t *totd,
+                                        xfs_rfsblock_t *toti, xfs_extnum_t *nex,
                                         blkmap_t **blkmapp, int whichfork);
-static xfs_ino_t       process_leaf_dir_v1(blkmap_t *blkmap, int *dot,
-                                           int *dotdot, inodata_t *id);
-static xfs_ino_t       process_leaf_dir_v1_int(int *dot, int *dotdot,
-                                               inodata_t *id);
 static xfs_ino_t       process_leaf_node_dir_v2(blkmap_t *blkmap, int *dot,
                                                 int *dotdot, inodata_t *id,
                                                 xfs_fsize_t dirsize);
@@ -311,16 +305,12 @@ static void               process_leaf_node_dir_v2_free(inodata_t *id, int v,
 static void            process_leaf_node_dir_v2_int(inodata_t *id, int v,
                                                     xfs_dablk_t dbno,
                                                     freetab_t *freetab);
-static xfs_ino_t       process_node_dir_v1(blkmap_t *blkmap, int *dot,
-                                           int *dotdot, inodata_t *id);
 static void            process_quota(qtype_t qtype, inodata_t *id,
                                      blkmap_t *blkmap);
 static void            process_rtbitmap(blkmap_t *blkmap);
 static void            process_rtsummary(blkmap_t *blkmap);
 static xfs_ino_t       process_sf_dir_v2(xfs_dinode_t *dip, int *dot,
                                          int *dotdot, inodata_t *id);
-static xfs_ino_t       process_shortform_dir_v1(xfs_dinode_t *dip, int *dot,
-                                                int *dotdot, inodata_t *id);
 static void            quota_add(xfs_dqid_t *p, xfs_dqid_t *g, xfs_dqid_t *u,
                                  int dq, xfs_qcnt_t bc, xfs_qcnt_t ic,
                                  xfs_qcnt_t rc);
@@ -333,8 +323,8 @@ static void         scan_ag(xfs_agnumber_t agno);
 static void            scan_freelist(xfs_agf_t *agf);
 static void            scan_lbtree(xfs_fsblock_t root, int nlevels,
                                    scan_lbtree_f_t func, dbm_t type,
-                                   inodata_t *id, xfs_drfsbno_t *totd,
-                                   xfs_drfsbno_t *toti, xfs_extnum_t *nex,
+                                   inodata_t *id, xfs_rfsblock_t *totd,
+                                   xfs_rfsblock_t *toti, xfs_extnum_t *nex,
                                    blkmap_t **blkmapp, int isroot,
                                    typnm_t btype);
 static void            scan_sbtree(xfs_agf_t *agf, xfs_agblock_t root,
@@ -342,8 +332,8 @@ static void         scan_sbtree(xfs_agf_t *agf, xfs_agblock_t root,
                                    scan_sbtree_f_t func, typnm_t btype);
 static void            scanfunc_bmap(struct xfs_btree_block *block,
                                      int level, dbm_t type, xfs_fsblock_t bno,
-                                     inodata_t *id, xfs_drfsbno_t *totd,
-                                     xfs_drfsbno_t *toti, xfs_extnum_t *nex,
+                                     inodata_t *id, xfs_rfsblock_t *totd,
+                                     xfs_rfsblock_t *toti, xfs_extnum_t *nex,
                                      blkmap_t **blkmapp, int isroot,
                                      typnm_t btype);
 static void            scanfunc_bno(struct xfs_btree_block *block, int level,
@@ -360,9 +350,9 @@ static void         set_dbmap(xfs_agnumber_t agno, xfs_agblock_t agbno,
                                  xfs_agnumber_t c_agno, xfs_agblock_t c_agbno);
 static void            set_inomap(xfs_agnumber_t agno, xfs_agblock_t agbno,
                                   xfs_extlen_t len, inodata_t *id);
-static void            set_rdbmap(xfs_drfsbno_t bno, xfs_extlen_t len,
+static void            set_rdbmap(xfs_rfsblock_t bno, xfs_extlen_t len,
                                   dbm_t type);
-static void            set_rinomap(xfs_drfsbno_t bno, xfs_extlen_t len,
+static void            set_rinomap(xfs_rfsblock_t bno, xfs_extlen_t len,
                                    inodata_t *id);
 static void            setlink_inode(inodata_t *id, nlink_t nlink, int isdir,
                                       int security);
@@ -798,6 +788,20 @@ blockget_f(
                dbprintf(_("already have block usage information\n"));
                return 0;
        }
+
+       /*
+        * XXX: check does not support CRC enabled filesystems. Return
+        * immediately, silently, with success but  without doing anything here
+        * initially so that xfstests can run without modification on metadata
+        * enabled filesystems.
+        *
+        * XXX: ultimately we need to dump an error message here that xfstests
+        * filters out, or we need to actually do the work to make check support
+        * crc enabled filesystems.
+        */
+       if (xfs_sb_version_hascrc(&mp->m_sb))
+               return 0;
+
        if (!init(argc, argv)) {
                if (serious_error)
                        exitcode = 3;
@@ -891,13 +895,6 @@ blockget_f(
                                XFS_SB_VERSION_ATTRBIT);
                error++;
        }
-       if ((sbversion & XFS_SB_VERSION_NLINKBIT) &&
-                                       !xfs_sb_version_hasnlink(&mp->m_sb)) {
-               if (!sflag)
-                       dbprintf(_("sb versionnum missing nlink bit %x\n"),
-                               XFS_SB_VERSION_NLINKBIT);
-               error++;
-       }
        if ((sbversion & XFS_SB_VERSION_QUOTABIT) &&
                                        !xfs_sb_version_hasquota(&mp->m_sb)) {
                if (!sflag)
@@ -1000,8 +997,8 @@ blocktrash_f(
 {
        xfs_agblock_t   agbno;
        xfs_agnumber_t  agno;
-       xfs_drfsbno_t   bi;
-       xfs_drfsbno_t   blocks;
+       xfs_rfsblock_t  bi;
+       xfs_rfsblock_t  blocks;
        int             c;
        int             count;
        int             done;
@@ -1014,7 +1011,7 @@ blocktrash_f(
        int             mode;
        struct timeval  now;
        char            *p;
-       xfs_drfsbno_t   randb;
+       xfs_rfsblock_t  randb;
        uint            seed;
        int             sopt;
        int             tmask;
@@ -1132,13 +1129,13 @@ blocktrash_f(
        }
        if (blocks == 0) {
                dbprintf(_("blocktrash: no matching blocks\n"));
-               return 0;
+               goto out;
        }
        if (!sopt)
                dbprintf(_("blocktrash: seed %u\n"), seed);
        srandom(seed);
        for (i = 0; i < count; i++) {
-               randb = (xfs_drfsbno_t)((((__int64_t)random() << 32) |
+               randb = (xfs_rfsblock_t)((((__int64_t)random() << 32) |
                                         random()) % blocks);
                for (bi = 0, agno = 0, done = 0;
                     !done && agno < mp->m_sb.sb_agcount;
@@ -1157,6 +1154,7 @@ blocktrash_f(
                        }
                }
        }
+out:
        xfree(lentab);
        return 0;
 }
@@ -1181,7 +1179,6 @@ blockuse_f(
                return 0;
        }
        optind = 0;
-       count = 1;
        shownames = 0;
        fsb = XFS_DADDR_TO_FSB(mp, iocur_top->off >> BBSHIFT);
        agno = XFS_FSB_TO_AGNO(mp, fsb);
@@ -1213,7 +1210,7 @@ blockuse_f(
                p = &dbmap[agno][agbno];
                i = inomap[agno][agbno];
                dbprintf(_("block %llu (%u/%u) type %s"),
-                       (xfs_dfsbno_t)XFS_AGB_TO_FSB(mp, agno, agbno),
+                       (xfs_fsblock_t)XFS_AGB_TO_FSB(mp, agno, agbno),
                        agno, agbno, typename[(dbm_t)*p]);
                if (i) {
                        dbprintf(_(" inode %lld"), i->ino);
@@ -1410,7 +1407,7 @@ check_range(
 
 static void
 check_rdbmap(
-       xfs_drfsbno_t   bno,
+       xfs_rfsblock_t  bno,
        xfs_extlen_t    len,
        dbm_t           type)
 {
@@ -1431,7 +1428,7 @@ check_rdbmap(
 
 static int
 check_rinomap(
-       xfs_drfsbno_t   bno,
+       xfs_rfsblock_t  bno,
        xfs_extlen_t    len,
        xfs_ino_t       c_ino)
 {
@@ -1480,7 +1477,7 @@ check_rootdir(void)
 
 static int
 check_rrange(
-       xfs_drfsbno_t   bno,
+       xfs_rfsblock_t  bno,
        xfs_extlen_t    len)
 {
        xfs_extlen_t    i;
@@ -1528,7 +1525,7 @@ check_set_dbmap(
 
 static void
 check_set_rdbmap(
-       xfs_drfsbno_t   bno,
+       xfs_rfsblock_t  bno,
        xfs_extlen_t    len,
        dbm_t           type1,
        dbm_t           type2)
@@ -1552,7 +1549,7 @@ check_set_rdbmap(
 static void
 check_summary(void)
 {
-       xfs_drfsbno_t   bno;
+       xfs_rfsblock_t  bno;
        xfs_suminfo_t   *csp;
        xfs_suminfo_t   *fsp;
        int             log;
@@ -1599,7 +1596,7 @@ checknot_dbmap(
 
 static void
 checknot_rdbmap(
-       xfs_drfsbno_t   bno,
+       xfs_rfsblock_t  bno,
        xfs_extlen_t    len,
        int             typemask)
 {
@@ -1828,10 +1825,17 @@ init(
        error = sbver_err = serious_error = 0;
        fdblocks = frextents = icount = ifree = 0;
        sbversion = XFS_SB_VERSION_4;
-       if (mp->m_sb.sb_inoalignmt)
+       /*
+        * Note that inoalignmt == 0 is valid when fsb size is large enough for
+        * at least one full inode record per block. Check this case explicitly.
+        */
+       if (mp->m_sb.sb_inoalignmt ||
+           (xfs_sb_version_hasalign(&mp->m_sb) &&
+            mp->m_sb.sb_inopblock >= XFS_INODES_PER_CHUNK))
                sbversion |= XFS_SB_VERSION_ALIGNBIT;
        if ((mp->m_sb.sb_uquotino && mp->m_sb.sb_uquotino != NULLFSINO) ||
-           (mp->m_sb.sb_gquotino && mp->m_sb.sb_gquotino != NULLFSINO))
+           (mp->m_sb.sb_gquotino && mp->m_sb.sb_gquotino != NULLFSINO) ||
+           (mp->m_sb.sb_pquotino && mp->m_sb.sb_pquotino != NULLFSINO))
                sbversion |= XFS_SB_VERSION_QUOTABIT;
        quota_init();
        return 1;
@@ -1902,6 +1906,7 @@ ncheck_f(
                        break;
                default:
                        dbprintf(_("bad option -%c for ncheck command\n"), c);
+                       xfree(ilist);
                        return 0;
                }
        }
@@ -1970,7 +1975,7 @@ process_block_dir_v2(
        int             v;
        int             x;
 
-       nex = blkmap_getn(blkmap, 0, mp->m_dirblkfsbs, &bmp);
+       nex = blkmap_getn(blkmap, 0, mp->m_dir_geo->fsbcount, &bmp);
        v = id->ilist || verbose;
        if (nex == 0) {
                if (!sflag || v)
@@ -1983,8 +1988,8 @@ process_block_dir_v2(
        push_cur();
        if (nex > 1)
                make_bbmap(&bbmap, nex, bmp);
-       set_cur(&typtab[TYP_DIR], XFS_FSB_TO_DADDR(mp, bmp->startblock),
-               mp->m_dirblkfsbs * blkbb, DB_RING_IGN, nex > 1 ? &bbmap : NULL);
+       set_cur(&typtab[TYP_DIR2], XFS_FSB_TO_DADDR(mp, bmp->startblock),
+               mp->m_dir_geo->fsbcount * blkbb, DB_RING_IGN, nex > 1 ? &bbmap : NULL);
        for (x = 0; !v && x < nex; x++) {
                for (b = bmp[x].startblock;
                     !v && b < bmp[x].startblock + bmp[x].blockcount;
@@ -2002,7 +2007,7 @@ process_block_dir_v2(
                return 0;
        }
        dir_hash_init();
-       parent = process_data_dir_v2(dot, dotdot, id, v, mp->m_dirdatablk,
+       parent = process_data_dir_v2(dot, dotdot, id, v, mp->m_dir_geo->datablk,
                NULL);
        dir_hash_check(id, v);
        dir_hash_done();
@@ -2016,21 +2021,21 @@ process_bmbt_reclist(
        int                     numrecs,
        dbm_t                   type,
        inodata_t               *id,
-       xfs_drfsbno_t           *tot,
+       xfs_rfsblock_t          *tot,
        blkmap_t                **blkmapp)
 {
        xfs_agblock_t           agbno;
        xfs_agnumber_t          agno;
        xfs_fsblock_t           b;
-       xfs_dfilblks_t          c;
-       xfs_dfilblks_t          cp;
+       xfs_filblks_t           c;
+       xfs_filblks_t           cp;
        int                     f;
        int                     i;
        xfs_agblock_t           iagbno;
        xfs_agnumber_t          iagno;
-       xfs_dfiloff_t           o;
-       xfs_dfiloff_t           op;
-       xfs_dfsbno_t            s;
+       xfs_fileoff_t           o;
+       xfs_fileoff_t           op;
+       xfs_fsblock_t           s;
        int                     v;
 
        cp = op = 0;
@@ -2085,7 +2090,7 @@ process_bmbt_reclist(
                                if (CHECK_BLIST(b))
                                        dbprintf(_("inode %lld block %lld at "
                                                 "offset %lld\n"),
-                                               id->ino, (xfs_dfsbno_t)b, o);
+                                               id->ino, (xfs_fsblock_t)b, o);
                        }
                } else {
                        agno = XFS_FSB_TO_AGNO(mp, (xfs_fsblock_t)s);
@@ -2099,7 +2104,7 @@ process_bmbt_reclist(
                                if (CHECK_BLIST(b))
                                        dbprintf(_("inode %lld block %lld at "
                                                 "offset %lld\n"),
-                                               id->ino, (xfs_dfsbno_t)b, o);
+                                               id->ino, (xfs_fsblock_t)b, o);
                        }
                }
                *tot += c;
@@ -2111,8 +2116,8 @@ process_btinode(
        inodata_t               *id,
        xfs_dinode_t            *dip,
        dbm_t                   type,
-       xfs_drfsbno_t           *totd,
-       xfs_drfsbno_t           *toti,
+       xfs_rfsblock_t          *totd,
+       xfs_rfsblock_t          *toti,
        xfs_extnum_t            *nex,
        blkmap_t                **blkmapp,
        int                     whichfork)
@@ -2133,7 +2138,7 @@ process_btinode(
                return;
        }
        if (be16_to_cpu(dib->bb_numrecs) >
-                       xfs_bmdr_maxrecs(mp, XFS_DFORK_SIZE(dip, mp, whichfork),
+                       xfs_bmdr_maxrecs(XFS_DFORK_SIZE(dip, mp, whichfork),
                        be16_to_cpu(dib->bb_level) == 0)) {
                if (!sflag || id->ilist)
                        dbprintf(_("numrecs for ino %lld %s fork bmap root too "
@@ -2151,7 +2156,7 @@ process_btinode(
                *nex += be16_to_cpu(dib->bb_numrecs);
                return;
        } else {
-               pp = XFS_BMDR_PTR_ADDR(dib, 1, xfs_bmdr_maxrecs(mp,
+               pp = XFS_BMDR_PTR_ADDR(dib, 1, xfs_bmdr_maxrecs(
                                XFS_DFORK_SIZE(dip, mp, whichfork), 0));
                for (i = 0; i < be16_to_cpu(dib->bb_numrecs); i++)
                        scan_lbtree(be64_to_cpu(pp[i]), 
@@ -2184,11 +2189,11 @@ process_data_dir_v2(
        xfs_dir2_dataptr_t      addr;
        xfs_dir2_data_free_t    *bf;
        int                     bf_err;
-       xfs_dir2_block_t        *block;
+       struct xfs_dir2_data_hdr *block;
        xfs_dir2_block_tail_t   *btp = NULL;
        inodata_t               *cid;
        int                     count;
-       xfs_dir2_data_t         *data;
+       struct xfs_dir2_data_hdr *data;
        xfs_dir2_db_t           db;
        xfs_dir2_data_entry_t   *dep;
        xfs_dir2_data_free_t    *dfp;
@@ -2210,24 +2215,24 @@ process_data_dir_v2(
 
        data = iocur_top->data;
        block = iocur_top->data;
-       if (be32_to_cpu(block->hdr.magic) != XFS_DIR2_BLOCK_MAGIC &&
-                       be32_to_cpu(data->hdr.magic) != XFS_DIR2_DATA_MAGIC) {
+       if (be32_to_cpu(block->magic) != XFS_DIR2_BLOCK_MAGIC &&
+                       be32_to_cpu(data->magic) != XFS_DIR2_DATA_MAGIC) {
                if (!sflag || v)
                        dbprintf(_("bad directory data magic # %#x for dir ino "
                                 "%lld block %d\n"),
-                               be32_to_cpu(data->hdr.magic), id->ino, dabno);
+                               be32_to_cpu(data->magic), id->ino, dabno);
                error++;
                return NULLFSINO;
        }
-       db = xfs_dir2_da_to_db(mp, dabno);
-       bf = data->hdr.bestfree;
-       ptr = (char *)data->u;
-       if (be32_to_cpu(block->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) {
-               btp = xfs_dir2_block_tail_p(mp, block);
+       db = xfs_dir2_da_to_db(mp->m_dir_geo, dabno);
+       bf = M_DIROPS(mp)->data_bestfree_p(data);
+       ptr = (char *)M_DIROPS(mp)->data_unused_p(data);
+       if (be32_to_cpu(block->magic) == XFS_DIR2_BLOCK_MAGIC) {
+               btp = xfs_dir2_block_tail_p(mp->m_dir_geo, block);
                lep = xfs_dir2_block_leaf_p(btp);
                endptr = (char *)lep;
                if (endptr <= ptr || endptr > (char *)btp) {
-                       endptr = (char *)data + mp->m_dirblksize;
+                       endptr = (char *)data + mp->m_dir_geo->blksize;
                        lep = NULL;
                        if (!sflag || v)
                                dbprintf(_("bad block directory tail for dir ino "
@@ -2236,7 +2241,7 @@ process_data_dir_v2(
                        error++;
                }
        } else
-               endptr = (char *)data + mp->m_dirblksize;
+               endptr = (char *)data + mp->m_dir_geo->blksize;
        bf_err = lastfree_err = tag_err = 0;
        count = lastfree = freeseen = 0;
        if (be16_to_cpu(bf[0].length) == 0) {
@@ -2305,7 +2310,7 @@ process_data_dir_v2(
                                        (int)((char *)dep - (char *)data));
                        error++;
                }
-               tagp = xfs_dir2_data_entry_tag_p(dep);
+               tagp = M_DIROPS(mp)->data_entry_tag_p(dep);
                if ((char *)tagp >= endptr) {
                        if (!sflag || v)
                                dbprintf(_("dir %lld block %d bad entry at %d\n"),
@@ -2315,12 +2320,12 @@ process_data_dir_v2(
                        break;
                }
                tag_err += be16_to_cpu(*tagp) != (char *)dep - (char *)data;
-               addr = xfs_dir2_db_off_to_dataptr(mp, db,
+               addr = xfs_dir2_db_off_to_dataptr(mp->m_dir_geo, db,
                        (char *)dep - (char *)data);
-               xname.name = (char *)dep->name;
+               xname.name = dep->name;
                xname.len = dep->namelen;
                dir_hash_add(mp->m_dirnameops->hashname(&xname), addr);
-               ptr += xfs_dir2_data_entsize(dep->namelen);
+               ptr += M_DIROPS(mp)->data_entsize(dep->namelen);
                count++;
                lastfree = 0;
                lino = be64_to_cpu(dep->inumber);
@@ -2368,8 +2373,8 @@ process_data_dir_v2(
                        (*dot)++;
                }
        }
-       if (be32_to_cpu(data->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) {
-               endptr = (char *)data + mp->m_dirblksize;
+       if (be32_to_cpu(data->magic) == XFS_DIR2_BLOCK_MAGIC) {
+               endptr = (char *)data + mp->m_dir_geo->blksize;
                for (i = stale = 0; lep && i < be32_to_cpu(btp->count); i++) {
                        if ((char *)&lep[i] >= endptr) {
                                if (!sflag || v)
@@ -2400,9 +2405,8 @@ process_data_dir_v2(
                                id->ino, dabno);
                error++;
        }
-       if (be32_to_cpu(data->hdr.magic) == XFS_DIR2_BLOCK_MAGIC &&
-                               count != be32_to_cpu(btp->count) - 
-                                               be32_to_cpu(btp->stale)) {
+       if (be32_to_cpu(data->magic) == XFS_DIR2_BLOCK_MAGIC &&
+           count != be32_to_cpu(btp->count) - be32_to_cpu(btp->stale)) {
                if (!sflag || v)
                        dbprintf(_("dir %lld block %d bad block tail count %d "
                                 "(stale %d)\n"), 
@@ -2410,7 +2414,7 @@ process_data_dir_v2(
                                be32_to_cpu(btp->stale));
                error++;
        }
-       if (be32_to_cpu(data->hdr.magic) == XFS_DIR2_BLOCK_MAGIC && 
+       if (be32_to_cpu(data->magic) == XFS_DIR2_BLOCK_MAGIC && 
                                        stale != be32_to_cpu(btp->stale)) {
                if (!sflag || v)
                        dbprintf(_("dir %lld block %d bad stale tail count %d\n"),
@@ -2435,18 +2439,19 @@ process_data_dir_v2(
 
 static xfs_dir2_data_free_t *
 process_data_dir_v2_freefind(
-       xfs_dir2_data_t         *data,
+       struct xfs_dir2_data_hdr *data,
        xfs_dir2_data_unused_t  *dup)
 {
-       xfs_dir2_data_free_t    *dfp;
+       struct xfs_dir2_data_free *bf;
+       struct xfs_dir2_data_free *dfp;
        xfs_dir2_data_aoff_t    off;
 
        off = (xfs_dir2_data_aoff_t)((char *)dup - (char *)data);
-       if (be16_to_cpu(dup->length) < be16_to_cpu(data->hdr.
-                               bestfree[XFS_DIR2_DATA_FD_COUNT - 1].length))
+       bf = M_DIROPS(mp)->data_bestfree_p(data);
+       if (be16_to_cpu(dup->length) <
+                       be16_to_cpu(bf[XFS_DIR2_DATA_FD_COUNT - 1].length))
                return NULL;
-       for (dfp = &data->hdr.bestfree[0]; dfp < &data->hdr.
-                               bestfree[XFS_DIR2_DATA_FD_COUNT]; dfp++) {
+       for (dfp = bf; dfp < &bf[XFS_DIR2_DATA_FD_COUNT]; dfp++) {
                if (be16_to_cpu(dfp->offset) == 0)
                        return NULL;
                if (be16_to_cpu(dfp->offset) == off)
@@ -2467,14 +2472,9 @@ process_dir(
        xfs_ino_t       parent;
 
        dot = dotdot = 0;
-       if (xfs_sb_version_hasdirv2(&mp->m_sb)) {
-               if (process_dir_v2(dip, blkmap, &dot, &dotdot, id, &parent))
-                       return;
-       } else
-       {
-               if (process_dir_v1(dip, blkmap, &dot, &dotdot, id, &parent))
-                       return;
-       }
+       if (process_dir_v2(dip, blkmap, &dot, &dotdot, id, &parent))
+               return;
+
        bno = XFS_INO_TO_FSB(mp, id->ino);
        if (dot == 0) {
                if (!sflag || id->ilist || CHECK_BLIST(bno))
@@ -2499,38 +2499,6 @@ process_dir(
                addparent_inode(id, parent);
 }
 
-static int
-process_dir_v1(
-       xfs_dinode_t    *dip,
-       blkmap_t        *blkmap,
-       int             *dot,
-       int             *dotdot,
-       inodata_t       *id,
-       xfs_ino_t       *parent)
-{
-       xfs_fsize_t     size = be64_to_cpu(dip->di_core.di_size);
-
-       if (size <= XFS_DFORK_DSIZE(dip, mp) && 
-                               dip->di_core.di_format == XFS_DINODE_FMT_LOCAL)
-               *parent = process_shortform_dir_v1(dip, dot, dotdot, id);
-       else if (size == XFS_LBSIZE(mp) &&
-                       (dip->di_core.di_format == XFS_DINODE_FMT_EXTENTS ||
-                       dip->di_core.di_format == XFS_DINODE_FMT_BTREE))
-               *parent = process_leaf_dir_v1(blkmap, dot, dotdot, id);
-       else if (size >= XFS_LBSIZE(mp) &&
-                       (dip->di_core.di_format == XFS_DINODE_FMT_EXTENTS ||
-                       dip->di_core.di_format == XFS_DINODE_FMT_BTREE))
-               *parent = process_node_dir_v1(blkmap, dot, dotdot, id);
-       else  {
-               dbprintf(_("bad size (%lld) or format (%d) for directory inode "
-                        "%lld\n"),
-                       size, dip->di_core.di_format, id->ino);
-               error++;
-               return 1;
-       }
-       return 0;
-}
-
 static int
 process_dir_v2(
        xfs_dinode_t    *dip,
@@ -2541,25 +2509,25 @@ process_dir_v2(
        xfs_ino_t       *parent)
 {
        xfs_fileoff_t   last = 0;
-       xfs_fsize_t     size = be64_to_cpu(dip->di_core.di_size);
+       xfs_fsize_t     size = be64_to_cpu(dip->di_size);
 
        if (blkmap)
                last = blkmap_last_off(blkmap);
        if (size <= XFS_DFORK_DSIZE(dip, mp) &&
-                               dip->di_core.di_format == XFS_DINODE_FMT_LOCAL)
+                               dip->di_format == XFS_DINODE_FMT_LOCAL)
                *parent = process_sf_dir_v2(dip, dot, dotdot, id);
-       else if (last == mp->m_dirblkfsbs &&
-                       (dip->di_core.di_format == XFS_DINODE_FMT_EXTENTS ||
-                       dip->di_core.di_format == XFS_DINODE_FMT_BTREE))
+       else if (last == mp->m_dir_geo->fsbcount &&
+                       (dip->di_format == XFS_DINODE_FMT_EXTENTS ||
+                       dip->di_format == XFS_DINODE_FMT_BTREE))
                *parent = process_block_dir_v2(blkmap, dot, dotdot, id);
-       else if (last >= mp->m_dirleafblk + mp->m_dirblkfsbs &&
-                       (dip->di_core.di_format == XFS_DINODE_FMT_EXTENTS ||
-                       dip->di_core.di_format == XFS_DINODE_FMT_BTREE))
+       else if (last >= mp->m_dir_geo->leafblk + mp->m_dir_geo->fsbcount &&
+                       (dip->di_format == XFS_DINODE_FMT_EXTENTS ||
+                       dip->di_format == XFS_DINODE_FMT_BTREE))
                *parent = process_leaf_node_dir_v2(blkmap, dot, dotdot, id, size);
        else  {
                dbprintf(_("bad size (%lld) or format (%d) for directory inode "
                         "%lld\n"),
-                       size, dip->di_core.di_format, id->ino);
+                       size, dip->di_format, id->ino);
                error++;
                return 1;
        }
@@ -2572,8 +2540,8 @@ process_exinode(
        inodata_t               *id,
        xfs_dinode_t            *dip,
        dbm_t                   type,
-       xfs_drfsbno_t           *totd,
-       xfs_drfsbno_t           *toti,
+       xfs_rfsblock_t          *totd,
+       xfs_rfsblock_t          *toti,
        xfs_extnum_t            *nex,
        blkmap_t                **blkmapp,
        int                     whichfork)
@@ -2608,13 +2576,13 @@ process_inode(
        xfs_extnum_t            nextents = 0;
        int                     nlink;
        int                     security;
-       xfs_drfsbno_t           totblocks;
-       xfs_drfsbno_t           totdblocks = 0;
-       xfs_drfsbno_t           totiblocks = 0;
+       xfs_rfsblock_t          totblocks;
+       xfs_rfsblock_t          totdblocks = 0;
+       xfs_rfsblock_t          totiblocks = 0;
        dbm_t                   type;
        xfs_extnum_t            anextents = 0;
-       xfs_drfsbno_t           atotdblocks = 0;
-       xfs_drfsbno_t           atotiblocks = 0;
+       xfs_rfsblock_t          atotdblocks = 0;
+       xfs_rfsblock_t          atotiblocks = 0;
        xfs_qcnt_t              bc = 0;
        xfs_qcnt_t              ic = 0;
        xfs_qcnt_t              rc = 0;
@@ -2646,7 +2614,7 @@ process_inode(
                "dev", "local", "extents", "btree", "uuid"
        };
 
-       libxfs_dinode_from_disk(&idic, &dip->di_core);
+       libxfs_dinode_from_disk(&idic, dip);
 
        ino = XFS_AGINO_TO_INO(mp, be32_to_cpu(agf->agf_seqno), agino);
        if (!isfree) {
@@ -2677,7 +2645,7 @@ process_inode(
                                        idic.di_nblocks, ino);
                        error++;
                }
-               if (idic.di_version == XFS_DINODE_VERSION_1)
+               if (idic.di_version == 1)
                        nlink = idic.di_onlink;
                else
                        nlink = idic.di_nlink;
@@ -2713,7 +2681,8 @@ process_inode(
                error++;
                return;
        }
-       if ((unsigned int)XFS_DFORK_ASIZE(dip, mp) >= XFS_LITINO(mp))  {
+       if ((unsigned int)XFS_DFORK_ASIZE(dip, mp) >=
+                                       XFS_LITINO(mp, idic.di_version))  {
                if (v)
                        dbprintf(_("bad fork offset %d for inode %lld\n"),
                                idic.di_forkoff, id->ino);
@@ -2764,7 +2733,8 @@ process_inode(
                        addlink_inode(id);
                }
                else if (id->ino == mp->m_sb.sb_uquotino ||
-                        id->ino == mp->m_sb.sb_gquotino) {
+                        id->ino == mp->m_sb.sb_gquotino ||
+                        id->ino == mp->m_sb.sb_pquotino) {
                        type = DBM_QUOTA;
                        blkmap = blkmap_alloc(idic.di_nextents);
                        addlink_inode(id);
@@ -2782,7 +2752,7 @@ process_inode(
                type = DBM_UNKNOWN;
                break;
        }
-       if (idic.di_version == XFS_DINODE_VERSION_1)
+       if (idic.di_version == 1)
                setlink_inode(id, idic.di_onlink, type == DBM_DIR, security);
        else {
                sbversion |= XFS_SB_VERSION_NLINKBIT;
@@ -2840,7 +2810,7 @@ process_inode(
                        break;
                }
                if (ic) {
-                       dqprid = xfs_get_projid(idic);  /* dquot ID is u32 */
+                       dqprid = xfs_get_projid(&idic); /* dquot ID is u32 */
                        quota_add(&dqprid, &idic.di_gid, &idic.di_uid,
                                  0, bc, ic, rc);
                }
@@ -2883,11 +2853,11 @@ process_inode(
                        process_quota(IS_USER_QUOTA, id, blkmap);
                else if (id->ino == mp->m_sb.sb_gquotino &&
                         (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) &&
-                        (mp->m_sb.sb_qflags & XFS_OQUOTA_CHKD))
+                        (mp->m_sb.sb_qflags & XFS_GQUOTA_CHKD))
                        process_quota(IS_GROUP_QUOTA, id, blkmap);
-               else if (id->ino == mp->m_sb.sb_gquotino &&
+               else if (id->ino == mp->m_sb.sb_pquotino &&
                         (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) &&
-                        (mp->m_sb.sb_qflags & XFS_OQUOTA_CHKD))
+                        (mp->m_sb.sb_qflags & XFS_PQUOTA_CHKD))
                        process_quota(IS_PROJECT_QUOTA, id, blkmap);
        }
        if (blkmap)
@@ -2900,8 +2870,8 @@ process_lclinode(
        inodata_t               *id,
        xfs_dinode_t            *dip,
        dbm_t                   type,
-       xfs_drfsbno_t           *totd,
-       xfs_drfsbno_t           *toti,
+       xfs_rfsblock_t          *totd,
+       xfs_rfsblock_t          *toti,
        xfs_extnum_t            *nex,
        blkmap_t                **blkmapp,
        int                     whichfork)
@@ -2910,12 +2880,12 @@ process_lclinode(
        xfs_fsblock_t           bno;
 
        bno = XFS_INO_TO_FSB(mp, id->ino);
-       if (whichfork == XFS_DATA_FORK && be64_to_cpu(dip->di_core.di_size) >
+       if (whichfork == XFS_DATA_FORK && be64_to_cpu(dip->di_size) >
                                                XFS_DFORK_DSIZE(dip, mp)) {
                if (!sflag || id->ilist || CHECK_BLIST(bno))
                        dbprintf(_("local inode %lld data is too large (size "
                                 "%lld)\n"),
-                               id->ino, be64_to_cpu(dip->di_core.di_size));
+                               id->ino, be64_to_cpu(dip->di_size));
                error++;
        }
        else if (whichfork == XFS_ATTR_FORK) {
@@ -2930,121 +2900,6 @@ process_lclinode(
        }
 }
 
-static xfs_ino_t
-process_leaf_dir_v1(
-       blkmap_t        *blkmap,
-       int             *dot,
-       int             *dotdot,
-       inodata_t       *id)
-{
-       xfs_fsblock_t   bno;
-       xfs_ino_t       parent;
-
-       bno = blkmap_get(blkmap, 0);
-       if (bno == NULLFSBLOCK) {
-               if (!sflag || id->ilist)
-                       dbprintf(_("block 0 for directory inode %lld is "
-                                "missing\n"),
-                               id->ino);
-               error++;
-               return 0;
-       }
-       push_cur();
-       set_cur(&typtab[TYP_DIR], XFS_FSB_TO_DADDR(mp, bno), blkbb, DB_RING_IGN,
-               NULL);
-       if (iocur_top->data == NULL) {
-               if (!sflag || id->ilist || CHECK_BLIST(bno))
-                       dbprintf(_("can't read block 0 for directory inode "
-                                "%lld\n"),
-                               id->ino);
-               error++;
-               pop_cur();
-               return 0;
-       }
-       parent = process_leaf_dir_v1_int(dot, dotdot, id);
-       pop_cur();
-       return parent;
-}
-
-static xfs_ino_t
-process_leaf_dir_v1_int(
-       int                     *dot,
-       int                     *dotdot,
-       inodata_t               *id)
-{
-       xfs_fsblock_t           bno;
-       inodata_t               *cid;
-       xfs_dir_leaf_entry_t    *entry;
-       int                     i;
-       xfs_dir_leafblock_t     *leaf;
-       xfs_ino_t               lino;
-       xfs_dir_leaf_name_t     *namest;
-       xfs_ino_t               parent = 0;
-       int                     v;
-
-       bno = XFS_DADDR_TO_FSB(mp, iocur_top->bb);
-       v = verbose || id->ilist || CHECK_BLIST(bno);
-       leaf = iocur_top->data;
-       if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) {
-               if (!sflag || id->ilist || CHECK_BLIST(bno))
-                       dbprintf(_("bad directory leaf magic # %#x for dir ino "
-                                "%lld\n"),
-                               be16_to_cpu(leaf->hdr.info.magic), id->ino);
-               error++;
-               return NULLFSINO;
-       }
-       entry = &leaf->entries[0];
-       for (i = 0; i < be16_to_cpu(leaf->hdr.count); entry++, i++) {
-               namest = xfs_dir_leaf_namestruct(leaf, 
-                                               be16_to_cpu(entry->nameidx));
-               lino = XFS_GET_DIR_INO8(namest->inumber);
-               cid = find_inode(lino, 1);
-               if (v)
-                       dbprintf(_("dir %lld entry %*.*s %lld\n"), id->ino,
-                               entry->namelen, entry->namelen, namest->name,
-                               lino);
-               if (cid)
-                       addlink_inode(cid);
-               else {
-                       if (!sflag)
-                               dbprintf(_("dir %lld entry %*.*s bad inode "
-                                        "number %lld\n"),
-                                       id->ino, entry->namelen, entry->namelen,
-                                       namest->name, lino);
-                       error++;
-               }
-               if (entry->namelen == 2 && namest->name[0] == '.' &&
-                   namest->name[1] == '.') {
-                       if (parent) {
-                               if (!sflag || id->ilist || CHECK_BLIST(bno))
-                                       dbprintf(_("multiple .. entries in dir "
-                                                "%lld (%lld, %lld)\n"),
-                                               id->ino, parent, lino);
-                               error++;
-                       } else
-                               parent = cid ? lino : NULLFSINO;
-                       (*dotdot)++;
-               } else if (entry->namelen != 1 || namest->name[0] != '.') {
-                       if (cid != NULL) {
-                               if (!cid->parent)
-                                       cid->parent = id;
-                               addname_inode(cid, (char *)namest->name,
-                                       entry->namelen);
-                       }
-               } else {
-                       if (lino != id->ino) {
-                               if (!sflag)
-                                       dbprintf(_("dir %lld entry . inode "
-                                                "number mismatch (%lld)\n"),
-                                               id->ino, lino);
-                               error++;
-                       }
-                       (*dot)++;
-               }
-       }
-       return parent;
-}
-
 static xfs_ino_t
 process_leaf_node_dir_v2(
        blkmap_t                *blkmap,
@@ -3070,14 +2925,14 @@ process_leaf_node_dir_v2(
        v2 = verbose || id->ilist;
        v = parent = 0;
        dbno = NULLFILEOFF;
-       freetab = malloc(FREETAB_SIZE(dirsize / mp->m_dirblksize));
-       freetab->naents = (int)(dirsize / mp->m_dirblksize);
+       freetab = malloc(FREETAB_SIZE(dirsize / mp->m_dir_geo->blksize));
+       freetab->naents = (int)(dirsize / mp->m_dir_geo->blksize);
        freetab->nents = 0;
        for (i = 0; i < freetab->naents; i++)
                freetab->ents[i] = NULLDATAOFF;
        dir_hash_init();
        while ((dbno = blkmap_next_off(blkmap, dbno, &t)) != NULLFILEOFF) {
-               nex = blkmap_getn(blkmap, dbno, mp->m_dirblkfsbs, &bmp);
+               nex = blkmap_getn(blkmap, dbno, mp->m_dir_geo->fsbcount, &bmp);
                ASSERT(nex > 0);
                for (v = v2, x = 0; !v && x < nex; x++) {
                        for (b = bmp[x].startblock;
@@ -3088,12 +2943,12 @@ process_leaf_node_dir_v2(
                if (v)
                        dbprintf(_("dir inode %lld block %u=%llu\n"), id->ino,
                                (__uint32_t)dbno,
-                               (xfs_dfsbno_t)bmp->startblock);
+                               (xfs_fsblock_t)bmp->startblock);
                push_cur();
                if (nex > 1)
                        make_bbmap(&bbmap, nex, bmp);
-               set_cur(&typtab[TYP_DIR], XFS_FSB_TO_DADDR(mp, bmp->startblock),
-                       mp->m_dirblkfsbs * blkbb, DB_RING_IGN,
+               set_cur(&typtab[TYP_DIR2], XFS_FSB_TO_DADDR(mp, bmp->startblock),
+                       mp->m_dir_geo->fsbcount * blkbb, DB_RING_IGN,
                        nex > 1 ? &bbmap : NULL);
                free(bmp);
                if (iocur_top->data == NULL) {
@@ -3103,10 +2958,10 @@ process_leaf_node_dir_v2(
                                        (__uint32_t)dbno, id->ino);
                        error++;
                        pop_cur();
-                       dbno += mp->m_dirblkfsbs - 1;
+                       dbno += mp->m_dir_geo->fsbcount - 1;
                        continue;
                }
-               if (dbno < mp->m_dirleafblk) {
+               if (dbno < mp->m_dir_geo->leafblk) {
                        lino = process_data_dir_v2(dot, dotdot, id, v,
                                (xfs_dablk_t)dbno, &freetab);
                        if (lino) {
@@ -3119,7 +2974,7 @@ process_leaf_node_dir_v2(
                                } else
                                        parent = lino;
                        }
-               } else if (dbno < mp->m_dirfreeblk) {
+               } else if (dbno < mp->m_dir_geo->freeblk) {
                        process_leaf_node_dir_v2_int(id, v, (xfs_dablk_t)dbno,
                                freetab);
                } else {
@@ -3127,7 +2982,7 @@ process_leaf_node_dir_v2(
                                freetab);
                }
                pop_cur();
-               dbno += mp->m_dirblkfsbs - 1;
+               dbno += mp->m_dir_geo->fsbcount - 1;
        }
        dir_hash_check(id, v);
        dir_hash_done();
@@ -3136,7 +2991,7 @@ process_leaf_node_dir_v2(
                        if (!sflag || v)
                                dbprintf(_("missing free index for data block %d "
                                         "in dir ino %lld\n"),
-                                       xfs_dir2_db_to_da(mp, i), id->ino);
+                                       xfs_dir2_db_to_da(mp->m_dir_geo, i), id->ino);
                        error++;
                }
        }
@@ -3166,9 +3021,9 @@ process_leaf_node_dir_v2_free(
                error++;
                return;
        }
-       maxent = XFS_DIR2_MAX_FREE_BESTS(mp);
-       if (be32_to_cpu(free->hdr.firstdb) != xfs_dir2_da_to_db(mp, 
-                                       dabno - mp->m_dirfreeblk) * maxent) {
+       maxent = M_DIROPS(mp)->free_max_bests(mp->m_dir_geo);
+       if (be32_to_cpu(free->hdr.firstdb) != xfs_dir2_da_to_db(mp->m_dir_geo
+                                       dabno - mp->m_dir_geo->freeblk) * maxent) {
                if (!sflag || v)
                        dbprintf(_("bad free block firstdb %d for dir ino %lld "
                                 "block %d\n"),
@@ -3233,6 +3088,7 @@ process_leaf_node_dir_v2_int(
        xfs_dir2_leaf_tail_t    *ltp;
        xfs_da_intnode_t        *node;
        int                     stale;
+       struct xfs_da3_icnode_hdr nodehdr;
 
        leaf = iocur_top->data;
        switch (be16_to_cpu(leaf->hdr.info.magic)) {
@@ -3247,15 +3103,15 @@ process_leaf_node_dir_v2_int(
                                        id->ino, dabno);
                        error++;
                }
-               if (dabno != mp->m_dirleafblk) {
+               if (dabno != mp->m_dir_geo->leafblk) {
                        if (!sflag || v)
                                dbprintf(_("single leaf block for dir ino %lld "
                                         "block %d should be at block %d\n"),
                                        id->ino, dabno,
-                                       (xfs_dablk_t)mp->m_dirleafblk);
+                                       (xfs_dablk_t)mp->m_dir_geo->leafblk);
                        error++;
                }
-               ltp = xfs_dir2_leaf_tail_p(mp, leaf);
+               ltp = xfs_dir2_leaf_tail_p(mp->m_dir_geo, leaf);
                lbp = xfs_dir2_leaf_bests_p(ltp);
                for (i = 0; i < be32_to_cpu(ltp->bestcount); i++) {
                        if (freetab->nents <= i || freetab->ents[i] != 
@@ -3268,7 +3124,7 @@ process_leaf_node_dir_v2_int(
                                                        NULLDATAOFF :
                                                        freetab->ents[i],
                                                id->ino,
-                                               xfs_dir2_db_to_da(mp, i),
+                                               xfs_dir2_db_to_da(mp->m_dir_geo, i),
                                                be16_to_cpu(lbp[i]));
                        }
                        if (freetab->nents > i)
@@ -3281,13 +3137,12 @@ process_leaf_node_dir_v2_int(
                break;
        case XFS_DA_NODE_MAGIC:
                node = iocur_top->data;
-               if (be16_to_cpu(node->hdr.level) < 1 ||
-                                       be16_to_cpu(node->hdr.level) > 
-                                                       XFS_DA_NODE_MAXDEPTH) {
+               M_DIROPS(mp)->node_hdr_from_disk(&nodehdr, node);
+               if (nodehdr.level < 1 || nodehdr.level > XFS_DA_NODE_MAXDEPTH) {
                        if (!sflag || v)
                                dbprintf(_("bad node block level %d for dir ino "
                                         "%lld block %d\n"),
-                                       be16_to_cpu(node->hdr.level), id->ino, 
+                                       nodehdr.level, id->ino, 
                                        dabno);
                        error++;
                }
@@ -3301,7 +3156,7 @@ process_leaf_node_dir_v2_int(
                error++;
                return;
        }
-       lep = leaf->ents;
+       lep = M_DIROPS(mp)->leaf_ents_p(leaf);
        for (i = stale = 0; i < be16_to_cpu(leaf->hdr.count); i++) {
                if (be32_to_cpu(lep[i].address) == XFS_DIR2_NULL_DATAPTR)
                        stale++;
@@ -3325,71 +3180,6 @@ process_leaf_node_dir_v2_int(
        }
 }
 
-static xfs_ino_t
-process_node_dir_v1(
-       blkmap_t                *blkmap,
-       int                     *dot,
-       int                     *dotdot,
-       inodata_t               *id)
-{
-       xfs_fsblock_t           bno;
-       xfs_fileoff_t           dbno;
-       xfs_ino_t               lino;
-       xfs_ino_t               parent;
-       int                     t;
-       int                     v;
-       int                     v2;
-
-       v = verbose || id->ilist;
-       parent = 0;
-       dbno = NULLFILEOFF;
-       push_cur();
-       while ((dbno = blkmap_next_off(blkmap, dbno, &t)) != NULLFILEOFF) {
-               bno = blkmap_get(blkmap, dbno);
-               v2 = bno != NULLFSBLOCK && CHECK_BLIST(bno);
-               if (bno == NULLFSBLOCK && dbno == 0) {
-                       if (!sflag || v)
-                               dbprintf(_("can't read root block for directory "
-                                        "inode %lld\n"),
-                                       id->ino);
-                       error++;
-               }
-               if (v || v2)
-                       dbprintf(_("dir inode %lld block %u=%llu\n"), id->ino,
-                               (__uint32_t)dbno, (xfs_dfsbno_t)bno);
-               if (bno == NULLFSBLOCK)
-                       continue;
-               pop_cur();
-               push_cur();
-               set_cur(&typtab[TYP_DIR], XFS_FSB_TO_DADDR(mp, bno), blkbb,
-                       DB_RING_IGN, NULL);
-               if (iocur_top->data == NULL) {
-                       if (!sflag || v || v2)
-                               dbprintf(_("can't read block %u for directory "
-                                        "inode %lld\n"),
-                                       (__uint32_t)dbno, id->ino);
-                       error++;
-                       continue;
-               }
-               if (be16_to_cpu(((xfs_da_intnode_t *)iocur_top->data)->
-                                       hdr.info.magic) == XFS_DA_NODE_MAGIC)
-                       continue;
-               lino = process_leaf_dir_v1_int(dot, dotdot, id);
-               if (lino) {
-                       if (parent) {
-                               if (!sflag || v || v2)
-                                       dbprintf(_("multiple .. entries in dir "
-                                                "%lld\n"),
-                                               id->ino);
-                               error++;
-                       } else
-                               parent = lino;
-               }
-       }
-       pop_cur();
-       return parent;
-}
-
 static void
 process_quota(
        qtype_t         qtype,
@@ -3440,8 +3230,8 @@ process_quota(
                        if (scicb)
                                dbprintf(_("can't read block %lld for %s quota "
                                         "inode (fsblock %lld)\n"),
-                                       (xfs_dfiloff_t)qbno, s,
-                                       (xfs_dfsbno_t)bno);
+                                       (xfs_fileoff_t)qbno, s,
+                                       (xfs_fsblock_t)bno);
                        error++;
                        pop_cur();
                        continue;
@@ -3450,7 +3240,7 @@ process_quota(
                        if (verbose || id->ilist || cb)
                                dbprintf(_("%s dqblk %lld entry %d id %u bc "
                                         "%lld ic %lld rc %lld\n"),
-                                       s, (xfs_dfiloff_t)qbno, i, dqid,
+                                       s, (xfs_fileoff_t)qbno, i, dqid,
                                        be64_to_cpu(dqb->dd_diskdq.d_bcount),
                                        be64_to_cpu(dqb->dd_diskdq.d_icount),
                                        be64_to_cpu(dqb->dd_diskdq.d_rtbcount));
@@ -3459,7 +3249,7 @@ process_quota(
                                        dbprintf(_("bad magic number %#x for %s "
                                                 "dqblk %lld entry %d id %u\n"),
                                                be16_to_cpu(dqb->dd_diskdq.d_magic), s,
-                                               (xfs_dfiloff_t)qbno, i, dqid);
+                                               (xfs_fileoff_t)qbno, i, dqid);
                                error++;
                                continue;
                        }
@@ -3469,7 +3259,7 @@ process_quota(
                                                 "%s dqblk %lld entry %d id "
                                                 "%u\n"),
                                                dqb->dd_diskdq.d_version, s,
-                                               (xfs_dfiloff_t)qbno, i, dqid);
+                                               (xfs_fileoff_t)qbno, i, dqid);
                                error++;
                                continue;
                        }
@@ -3478,7 +3268,7 @@ process_quota(
                                        dbprintf(_("bad flags %#x for %s dqblk "
                                                 "%lld entry %d id %u\n"),
                                                dqb->dd_diskdq.d_flags, s,
-                                               (xfs_dfiloff_t)qbno, i, dqid);
+                                               (xfs_fileoff_t)qbno, i, dqid);
                                error++;
                                continue;
                        }
@@ -3487,7 +3277,7 @@ process_quota(
                                        dbprintf(_("bad id %u for %s dqblk %lld "
                                                 "entry %d id %u\n"),
                                                be32_to_cpu(dqb->dd_diskdq.d_id), s,
-                                               (xfs_dfiloff_t)qbno, i, dqid);
+                                               (xfs_fileoff_t)qbno, i, dqid);
                                error++;
                                continue;
                        }
@@ -3511,12 +3301,12 @@ process_rtbitmap(
        int             bitsperblock;
        xfs_fileoff_t   bmbno;
        xfs_fsblock_t   bno;
-       xfs_drtbno_t    extno;
+       xfs_rtblock_t   extno;
        int             len;
        int             log;
        int             offs;
        int             prevbit;
-       xfs_drfsbno_t   rtbno;
+       xfs_rfsblock_t  rtbno;
        int             start_bmbno;
        int             start_bit;
        int             t;
@@ -3532,7 +3322,7 @@ process_rtbitmap(
                        if (!sflag)
                                dbprintf(_("block %lld for rtbitmap inode is "
                                         "missing\n"),
-                                       (xfs_dfiloff_t)bmbno);
+                                       (xfs_fileoff_t)bmbno);
                        error++;
                        continue;
                }
@@ -3543,7 +3333,7 @@ process_rtbitmap(
                        if (!sflag)
                                dbprintf(_("can't read block %lld for rtbitmap "
                                         "inode\n"),
-                                       (xfs_dfiloff_t)bmbno);
+                                       (xfs_fileoff_t)bmbno);
                        error++;
                        pop_cur();
                        continue;
@@ -3599,7 +3389,7 @@ process_rtsummary(
                        if (!sflag)
                                dbprintf(_("block %lld for rtsummary inode is "
                                         "missing\n"),
-                                       (xfs_dfiloff_t)sumbno);
+                                       (xfs_fileoff_t)sumbno);
                        error++;
                        continue;
                }
@@ -3610,7 +3400,7 @@ process_rtsummary(
                        if (!sflag)
                                dbprintf(_("can't read block %lld for rtsummary "
                                         "inode\n"),
-                                       (xfs_dfiloff_t)sumbno);
+                                       (xfs_fileoff_t)sumbno);
                        error++;
                        pop_cur();
                        continue;
@@ -3633,21 +3423,21 @@ process_sf_dir_v2(
        int                     i8;
        xfs_ino_t               lino;
        int                     offset;
-       xfs_dir2_sf_t           *sf;
+       struct xfs_dir2_sf_hdr  *sf;
        xfs_dir2_sf_entry_t     *sfe;
        int                     v;
 
-       sf = (xfs_dir2_sf_t *)XFS_DFORK_DPTR(dip);
+       sf = (struct xfs_dir2_sf_hdr *)XFS_DFORK_DPTR(dip);
        addlink_inode(id);
        v = verbose || id->ilist;
        if (v)
                dbprintf(_("dir %lld entry . %lld\n"), id->ino, id->ino);
        (*dot)++;
        sfe = xfs_dir2_sf_firstentry(sf);
-       offset = XFS_DIR2_DATA_FIRST_OFFSET;
-       for (i = sf->hdr.count - 1, i8 = 0; i >= 0; i--) {
-               if ((__psint_t)sfe + xfs_dir2_sf_entsize_byentry(sf, sfe) -
-                   (__psint_t)sf > be64_to_cpu(dip->di_core.di_size)) {
+       offset = M_DIROPS(mp)->data_first_offset;
+       for (i = sf->count - 1, i8 = 0; i >= 0; i--) {
+               if ((__psint_t)sfe + M_DIROPS(mp)->sf_entsize(sf, sfe->namelen) -
+                   (__psint_t)sf > be64_to_cpu(dip->di_size)) {
                        if (!sflag)
                                dbprintf(_("dir %llu bad size in entry at %d\n"),
                                        id->ino,
@@ -3655,7 +3445,7 @@ process_sf_dir_v2(
                        error++;
                        break;
                }
-               lino = xfs_dir2_sf_get_inumber(sf, xfs_dir2_sf_inumberp(sfe));
+               lino = M_DIROPS(mp)->sf_get_ino(sf, sfe);
                if (lino > XFS_DIR2_MAX_SHORT_INUM)
                        i8++;
                cid = find_inode(lino, 1);
@@ -3685,24 +3475,24 @@ process_sf_dir_v2(
                }
                offset =
                        xfs_dir2_sf_get_offset(sfe) +
-                       xfs_dir2_data_entsize(sfe->namelen);
-               sfe = xfs_dir2_sf_nextentry(sf, sfe);
+                       M_DIROPS(mp)->sf_entsize(sf, sfe->namelen);
+               sfe = M_DIROPS(mp)->sf_nextentry(sf, sfe);
        }
        if (i < 0 && (__psint_t)sfe - (__psint_t)sf != 
-                                       be64_to_cpu(dip->di_core.di_size)) {
+                                       be64_to_cpu(dip->di_size)) {
                if (!sflag)
                        dbprintf(_("dir %llu size is %lld, should be %u\n"),
-                               id->ino, be64_to_cpu(dip->di_core.di_size),
+                               id->ino, be64_to_cpu(dip->di_size),
                                (uint)((char *)sfe - (char *)sf));
                error++;
        }
-       if (offset + (sf->hdr.count + 2) * sizeof(xfs_dir2_leaf_entry_t) +
-           sizeof(xfs_dir2_block_tail_t) > mp->m_dirblksize) {
+       if (offset + (sf->count + 2) * sizeof(xfs_dir2_leaf_entry_t) +
+           sizeof(xfs_dir2_block_tail_t) > mp->m_dir_geo->blksize) {
                if (!sflag)
                        dbprintf(_("dir %llu offsets too high\n"), id->ino);
                error++;
        }
-       lino = xfs_dir2_sf_get_inumber(sf, &sf->hdr.parent);
+       lino = M_DIROPS(mp)->sf_get_parent_ino(sf);
        if (lino > XFS_DIR2_MAX_SHORT_INUM)
                i8++;
        cid = find_inode(lino, 1);
@@ -3716,78 +3506,17 @@ process_sf_dir_v2(
        }
        if (v)
                dbprintf(_("dir %lld entry .. %lld\n"), id->ino, lino);
-       if (i8 != sf->hdr.i8count) {
+       if (i8 != sf->i8count) {
                if (!sflag)
                        dbprintf(_("dir %lld i8count mismatch is %d should be "
                                 "%d\n"),
-                               id->ino, sf->hdr.i8count, i8);
+                               id->ino, sf->i8count, i8);
                error++;
        }
        (*dotdot)++;
        return cid ? lino : NULLFSINO;
 }
 
-static xfs_ino_t
-process_shortform_dir_v1(
-       xfs_dinode_t            *dip,
-       int                     *dot,
-       int                     *dotdot,
-       inodata_t               *id)
-{
-       inodata_t               *cid;
-       int                     i;
-       xfs_ino_t               lino;
-       xfs_dir_shortform_t     *sf;
-       xfs_dir_sf_entry_t      *sfe;
-       int                     v;
-
-       sf = (xfs_dir_shortform_t *)XFS_DFORK_DPTR(dip);
-       addlink_inode(id);
-       v = verbose || id->ilist;
-       if (v)
-               dbprintf(_("dir %lld entry . %lld\n"), id->ino, id->ino);
-       (*dot)++;
-       sfe = &sf->list[0];
-       for (i = sf->hdr.count - 1; i >= 0; i--) {
-               lino = XFS_GET_DIR_INO8(sfe->inumber);
-               cid = find_inode(lino, 1);
-               if (cid == NULL) {
-                       if (!sflag)
-                               dbprintf(_("dir %lld entry %*.*s bad inode "
-                                        "number %lld\n"),
-                                       id->ino, sfe->namelen, sfe->namelen,
-                                       sfe->name, lino);
-                       error++;
-               } else {
-                       addlink_inode(cid);
-                       if (!cid->parent)
-                               cid->parent = id;
-                       addname_inode(cid, (char *)sfe->name, sfe->namelen);
-               }
-               if (v)
-                       dbprintf(_("dir %lld entry %*.*s %lld\n"), id->ino,
-                               sfe->namelen, sfe->namelen, sfe->name, lino);
-               sfe = xfs_dir_sf_nextentry(sfe);
-       }
-       if ((__psint_t)sfe - (__psint_t)sf != be64_to_cpu(dip->di_core.di_size))
-               dbprintf(_("dir %llu size is %lld, should be %d\n"),
-                       id->ino, be64_to_cpu(dip->di_core.di_size),
-                       (int)((char *)sfe - (char *)sf));
-       lino = XFS_GET_DIR_INO8(sf->hdr.parent);
-       cid = find_inode(lino, 1);
-       if (cid)
-               addlink_inode(cid);
-       else {
-               if (!sflag)
-                       dbprintf(_("dir %lld entry .. bad inode number %lld\n"),
-                               id->ino, lino);
-               error++;
-       }
-       if (v)
-               dbprintf(_("dir %lld entry .. %lld\n"), id->ino, lino);
-       (*dotdot)++;
-       return cid ? lino : NULLFSINO;
-}
 
 static void
 quota_add(
@@ -3896,11 +3625,11 @@ quota_init(void)
        qgdo = mp->m_sb.sb_gquotino != 0 &&
               mp->m_sb.sb_gquotino != NULLFSINO &&
               (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) &&
-              (mp->m_sb.sb_qflags & XFS_OQUOTA_CHKD);
-       qpdo = mp->m_sb.sb_gquotino != 0 &&
-              mp->m_sb.sb_gquotino != NULLFSINO &&
+              (mp->m_sb.sb_qflags & XFS_GQUOTA_CHKD);
+       qpdo = mp->m_sb.sb_pquotino != 0 &&
+              mp->m_sb.sb_pquotino != NULLFSINO &&
               (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) &&
-              (mp->m_sb.sb_qflags & XFS_OQUOTA_CHKD);
+              (mp->m_sb.sb_qflags & XFS_PQUOTA_CHKD);
        if (qudo)
                qudata = xcalloc(QDATA_HASH_SIZE, sizeof(qdata_t *));
        if (qgdo)
@@ -4093,6 +3822,7 @@ scan_freelist(
        xfs_agblock_t   bno;
        uint            count;
        int             i;
+       __be32          *freelist;
 
        if (XFS_SB_BLOCK(mp) != XFS_AGFL_BLOCK(mp) &&
            XFS_AGF_BLOCK(mp) != XFS_AGFL_BLOCK(mp) &&
@@ -4112,9 +3842,22 @@ scan_freelist(
                return;
        }
        i = be32_to_cpu(agf->agf_flfirst);
+
+       /* verify agf values before proceeding */
+       if (be32_to_cpu(agf->agf_flfirst) >= XFS_AGFL_SIZE(mp) ||
+           be32_to_cpu(agf->agf_fllast) >= XFS_AGFL_SIZE(mp)) {
+               dbprintf(_("agf %d freelist blocks bad, skipping "
+                         "freelist scan\n"), i);
+               pop_cur();
+               return;
+       }
+
+       /* open coded XFS_BUF_TO_AGFL_BNO */
+       freelist = xfs_sb_version_hascrc(&((mp)->m_sb)) ? &agfl->agfl_bno[0]
+                                                       : (__be32 *)agfl;
        count = 0;
        for (;;) {
-               bno = be32_to_cpu(agfl->agfl_bno[i]);
+               bno = be32_to_cpu(freelist[i]);
                set_dbmap(seqno, bno, 1, DBM_FREELIST, seqno,
                        XFS_AGFL_BLOCK(mp));
                count++;
@@ -4142,8 +3885,8 @@ scan_lbtree(
        scan_lbtree_f_t func,
        dbm_t           type,
        inodata_t       *id,
-       xfs_drfsbno_t   *totd,
-       xfs_drfsbno_t   *toti,
+       xfs_rfsblock_t  *totd,
+       xfs_rfsblock_t  *toti,
        xfs_extnum_t    *nex,
        blkmap_t        **blkmapp,
        int             isroot,
@@ -4198,8 +3941,8 @@ scanfunc_bmap(
        dbm_t                   type,
        xfs_fsblock_t           bno,
        inodata_t               *id,
-       xfs_drfsbno_t           *totd,
-       xfs_drfsbno_t           *toti,
+       xfs_rfsblock_t          *totd,
+       xfs_rfsblock_t          *toti,
        xfs_extnum_t            *nex,
        blkmap_t                **blkmapp,
        int                     isroot,
@@ -4238,7 +3981,7 @@ scanfunc_bmap(
                                         "in inode %lld bmap block %lld\n"),
                                        be16_to_cpu(block->bb_numrecs), mp->m_bmap_dmnr[0],
                                        mp->m_bmap_dmxr[0], id->ino,
-                                       (xfs_dfsbno_t)bno);
+                                       (xfs_fsblock_t)bno);
                        error++;
                        return;
                }
@@ -4254,7 +3997,7 @@ scanfunc_bmap(
                        dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in "
                                 "inode %lld bmap block %lld\n"),
                                be16_to_cpu(block->bb_numrecs), mp->m_bmap_dmnr[1],
-                               mp->m_bmap_dmxr[1], id->ino, (xfs_dfsbno_t)bno);
+                               mp->m_bmap_dmxr[1], id->ino, (xfs_fsblock_t)bno);
                error++;
                return;
        }
@@ -4479,7 +4222,7 @@ scanfunc_ino(
                        set_cur(&typtab[TYP_INODE],
                                XFS_AGB_TO_DADDR(mp, seqno,
                                                 XFS_AGINO_TO_AGBNO(mp, agino)),
-                               (int)XFS_FSB_TO_BB(mp, XFS_IALLOC_BLOCKS(mp)),
+                               (int)XFS_FSB_TO_BB(mp, mp->m_ialloc_blks),
                                DB_RING_IGN, NULL);
                        if (iocur_top->data == NULL) {
                                if (!sflag)
@@ -4563,7 +4306,7 @@ set_inomap(
 
 static void
 set_rdbmap(
-       xfs_drfsbno_t   bno,
+       xfs_rfsblock_t  bno,
        xfs_extlen_t    len,
        dbm_t           type)
 {
@@ -4572,7 +4315,7 @@ set_rdbmap(
 
 static void
 set_rinomap(
-       xfs_drfsbno_t   bno,
+       xfs_rfsblock_t  bno,
        xfs_extlen_t    len,
        inodata_t       *id)
 {