]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blobdiff - repair/phase6.c
xfs_repair: reinitialize the root directory nlink correctly
[thirdparty/xfsprogs-dev.git] / repair / phase6.c
index 0a711640cf08d922df88522b2bdf9c06b729dd39..8a50b350a0de616a3a31cf13528112570bb00bc2 100644 (file)
@@ -1,19 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (c) 2000-2005 Silicon Graphics, Inc.
  * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write the Free Software Foundation,
- * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
 #include "libxfs.h"
@@ -38,6 +26,61 @@ static struct xfs_name               xfs_name_dot = {(unsigned char *)".",
                                                1,
                                                XFS_DIR3_FT_DIR};
 
+/*
+ * When we're checking directory inodes, we're allowed to set a directory's
+ * dotdot entry to zero to signal that the parent needs to be reconnected
+ * during phase 6.  If we're handling a shortform directory the ifork
+ * verifiers will fail, so temporarily patch out this canary so that we can
+ * verify the rest of the fork and move on to fixing the dir.
+ */
+static xfs_failaddr_t
+phase6_verify_dir(
+       struct xfs_inode                *ip)
+{
+       struct xfs_mount                *mp = ip->i_mount;
+       const struct xfs_dir_ops        *dops;
+       struct xfs_ifork                *ifp;
+       struct xfs_dir2_sf_hdr          *sfp;
+       xfs_failaddr_t                  fa;
+       xfs_ino_t                       old_parent;
+       bool                            parent_bypass = false;
+       int                             size;
+
+       dops = libxfs_dir_get_ops(mp, NULL);
+
+       ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
+       sfp = (struct xfs_dir2_sf_hdr *)ifp->if_u1.if_data;
+       size = ifp->if_bytes;
+
+       /*
+        * If this is a shortform directory, phase4 may have set the parent
+        * inode to zero to indicate that it must be fixed.  Temporarily
+        * set a valid parent so that the directory verifier will pass.
+        */
+       if (size > offsetof(struct xfs_dir2_sf_hdr, parent) &&
+           size >= xfs_dir2_sf_hdr_size(sfp->i8count)) {
+               old_parent = dops->sf_get_parent_ino(sfp);
+               if (old_parent == 0) {
+                       dops->sf_put_parent_ino(sfp, mp->m_sb.sb_rootino);
+                       parent_bypass = true;
+               }
+       }
+
+       fa = libxfs_default_ifork_ops.verify_dir(ip);
+
+       /* Put it back. */
+       if (parent_bypass)
+               dops->sf_put_parent_ino(sfp, old_parent);
+
+       return fa;
+}
+
+static struct xfs_ifork_ops phase6_ifork_ops = {
+       .verify_attr    = xfs_attr_shortform_verify,
+       .verify_dir     = phase6_verify_dir,
+       .verify_symlink = xfs_symlink_shortform_verify,
+};
+
 /*
  * Data structures used to keep track of directories where the ".."
  * entries are updated. These must be rebuilt after the initial pass
@@ -82,7 +125,7 @@ typedef struct dir_hash_ent {
        struct dir_hash_ent     *nextbyhash;    /* next in name bucket */
        struct dir_hash_ent     *nextbyorder;   /* next in order added */
        xfs_dahash_t            hashval;        /* hash value of name */
-       __uint32_t              address;        /* offset of data entry */
+       uint32_t                address;        /* offset of data entry */
        xfs_ino_t               inum;           /* inode num of entry */
        short                   junkit;         /* name starts with / */
        short                   seen;           /* have seen leaf entry */
@@ -170,11 +213,11 @@ static int
 dir_hash_add(
        xfs_mount_t             *mp,
        dir_hash_tab_t          *hashtab,
-       __uint32_t              addr,
+       uint32_t                addr,
        xfs_ino_t               inum,
        int                     namelen,
        unsigned char           *name,
-       __uint8_t               ftype)
+       uint8_t                 ftype)
 {
        xfs_dahash_t            hash = 0;
        int                     byaddr;
@@ -357,7 +400,7 @@ static void
 dir_hash_update_ftype(
        dir_hash_tab_t          *hashtab,
        xfs_dir2_dataptr_t      addr,
-       __uint8_t               ftype)
+       uint8_t                 ftype)
 {
        int                     i;
        dir_hash_ent_t          *p;
@@ -434,12 +477,10 @@ bmap_next_offset(
        int             whichfork)              /* data or attr fork */
 {
        xfs_fileoff_t   bno;                    /* current block */
-       int             eof;                    /* hit end of file */
        int             error;                  /* error return value */
        xfs_bmbt_irec_t got;                    /* current extent value */
-       xfs_ifork_t     *ifp;                   /* inode fork pointer */
-       xfs_extnum_t    lastx;                  /* last extent used */
-       xfs_bmbt_irec_t prev;                   /* previous extent value */
+       struct xfs_ifork        *ifp;           /* inode fork pointer */
+       struct xfs_iext_cursor  icur;
 
        if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE &&
            XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
@@ -451,12 +492,10 @@ bmap_next_offset(
        }
        ifp = XFS_IFORK_PTR(ip, whichfork);
        if (!(ifp->if_flags & XFS_IFEXTENTS) &&
-           (error = xfs_iread_extents(tp, ip, whichfork)))
+           (error = -libxfs_iread_extents(tp, ip, whichfork)))
                return error;
        bno = *bnop + 1;
-       libxfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx,
-                                  &got, &prev);
-       if (eof)
+       if (!libxfs_iext_lookup_extent(ip, ifp, bno, &icur, &got))
                *bnop = NULLFILEOFF;
        else
                *bnop = got.br_startoff < bno ? bno : got.br_startoff;
@@ -474,29 +513,25 @@ res_failed(
                do_error(_("xfs_trans_reserve returned %d\n"), err);
 }
 
-void
+static void
 mk_rbmino(xfs_mount_t *mp)
 {
        xfs_trans_t     *tp;
        xfs_inode_t     *ip;
        xfs_bmbt_irec_t *ep;
-       xfs_fsblock_t   first;
        int             i;
        int             nmap;
        int             error;
-       xfs_bmap_free_t flist;
        xfs_fileoff_t   bno;
        xfs_bmbt_irec_t map[XFS_BMAP_MAX_NMAP];
        int             vers;
        int             times;
-       struct xfs_trans_res tres = {0};
+       uint            blocks;
 
        /*
         * first set up inode
         */
-       tp = libxfs_trans_alloc(mp, 0);
-
-       i = -libxfs_trans_reserve(tp, &tres, 10, 0);
+       i = -libxfs_trans_alloc_rollable(mp, 10, &tp);
        if (i)
                res_failed(i);
 
@@ -529,8 +564,8 @@ mk_rbmino(xfs_mount_t *mp)
         * now the ifork
         */
        ip->i_df.if_flags = XFS_IFEXTENTS;
-       ip->i_df.if_bytes = ip->i_df.if_real_bytes = 0;
-       ip->i_df.if_u1.if_extents = NULL;
+       ip->i_df.if_bytes = 0;
+       ip->i_df.if_u1.if_root = NULL;
 
        ip->i_d.di_size = mp->m_sb.sb_rbmblocks * mp->m_sb.sb_blocksize;
 
@@ -538,27 +573,27 @@ mk_rbmino(xfs_mount_t *mp)
         * commit changes
         */
        libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
-       libxfs_trans_commit(tp);
+       error = -libxfs_trans_commit(tp);
+       if (error)
+               do_error(_("%s: commit failed, error %d\n"), __func__, error);
 
        /*
         * then allocate blocks for file and fill with zeroes (stolen
         * from mkfs)
         */
-       tp = libxfs_trans_alloc(mp, 0);
-       error = -libxfs_trans_reserve(tp, &tres, mp->m_sb.sb_rbmblocks +
-                               (XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1), 0);
+       blocks = mp->m_sb.sb_rbmblocks +
+                       XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1;
+       error = -libxfs_trans_alloc_rollable(mp, blocks, &tp);
        if (error)
                res_failed(error);
 
        libxfs_trans_ijoin(tp, ip, 0);
        bno = 0;
-       xfs_bmap_init(&flist, &first);
        while (bno < mp->m_sb.sb_rbmblocks) {
                nmap = XFS_BMAP_MAX_NMAP;
                error = -libxfs_bmapi_write(tp, ip, bno,
                          (xfs_extlen_t)(mp->m_sb.sb_rbmblocks - bno),
-                         0, &first, mp->m_sb.sb_rbmblocks,
-                         map, &nmap, &flist);
+                         0, mp->m_sb.sb_rbmblocks, map, &nmap);
                if (error) {
                        do_error(
                        _("couldn't allocate realtime bitmap, error = %d\n"),
@@ -571,14 +606,13 @@ mk_rbmino(xfs_mount_t *mp)
                        bno += ep->br_blockcount;
                }
        }
-       error = -libxfs_bmap_finish(&tp, &flist, ip);
+       error = -libxfs_trans_commit(tp);
        if (error) {
                do_error(
                _("allocation of the realtime bitmap failed, error = %d\n"),
                        error);
        }
-       libxfs_trans_commit(tp);
-       IRELE(ip);
+       libxfs_irele(ip);
 }
 
 static int
@@ -588,19 +622,15 @@ fill_rbmino(xfs_mount_t *mp)
        xfs_trans_t     *tp;
        xfs_inode_t     *ip;
        xfs_rtword_t    *bmp;
-       xfs_fsblock_t   first;
        int             nmap;
        int             error;
        xfs_fileoff_t   bno;
        xfs_bmbt_irec_t map;
-       struct xfs_trans_res tres = {0};
 
        bmp = btmcompute;
        bno = 0;
 
-       tp = libxfs_trans_alloc(mp, 0);
-
-       error = -libxfs_trans_reserve(tp, &tres, 10, 0);
+       error = -libxfs_trans_alloc_rollable(mp, 10, &tp);
        if (error)
                res_failed(error);
 
@@ -611,14 +641,12 @@ fill_rbmino(xfs_mount_t *mp)
                        error);
        }
 
-       first = NULLFSBLOCK;
        while (bno < mp->m_sb.sb_rbmblocks)  {
                /*
                 * fill the file one block at a time
                 */
                nmap = 1;
-               error = -libxfs_bmapi_write(tp, ip, bno, 1, 0,
-                                       &first, 1, &map, &nmap, NULL);
+               error = -libxfs_bmapi_write(tp, ip, bno, 1, 0, 1, &map, &nmap);
                if (error || nmap != 1) {
                        do_error(
        _("couldn't map realtime bitmap block %" PRIu64 ", error = %d\n"),
@@ -639,7 +667,7 @@ _("can't access block %" PRIu64 " (fsbno %" PRIu64 ") of realtime bitmap inode %
                        return(1);
                }
 
-               memmove(XFS_BUF_PTR(bp), bmp, mp->m_sb.sb_blocksize);
+               memmove(bp->b_addr, bmp, mp->m_sb.sb_blocksize);
 
                libxfs_trans_log_buf(tp, bp, 0, mp->m_sb.sb_blocksize - 1);
 
@@ -647,8 +675,10 @@ _("can't access block %" PRIu64 " (fsbno %" PRIu64 ") of realtime bitmap inode %
                bno++;
        }
 
-       libxfs_trans_commit(tp);
-       IRELE(ip);
+       error = -libxfs_trans_commit(tp);
+       if (error)
+               do_error(_("%s: commit failed, error %d\n"), __func__, error);
+       libxfs_irele(ip);
        return(0);
 }
 
@@ -659,21 +689,17 @@ fill_rsumino(xfs_mount_t *mp)
        xfs_trans_t     *tp;
        xfs_inode_t     *ip;
        xfs_suminfo_t   *smp;
-       xfs_fsblock_t   first;
        int             nmap;
        int             error;
        xfs_fileoff_t   bno;
        xfs_fileoff_t   end_bno;
        xfs_bmbt_irec_t map;
-       struct xfs_trans_res tres = {0};
 
        smp = sumcompute;
        bno = 0;
        end_bno = mp->m_rsumsize >> mp->m_sb.sb_blocklog;
 
-       tp = libxfs_trans_alloc(mp, 0);
-
-       error = -libxfs_trans_reserve(tp, &tres, 10, 0);
+       error = -libxfs_trans_alloc_rollable(mp, 10, &tp);
        if (error)
                res_failed(error);
 
@@ -684,14 +710,12 @@ fill_rsumino(xfs_mount_t *mp)
                        error);
        }
 
-       first = NULLFSBLOCK;
        while (bno < end_bno)  {
                /*
                 * fill the file one block at a time
                 */
                nmap = 1;
-               error = -libxfs_bmapi_write(tp, ip, bno, 1, 0,
-                                       &first, 1, &map, &nmap, NULL);
+               error = -libxfs_bmapi_write(tp, ip, bno, 1, 0, 1, &map, &nmap);
                if (error || nmap != 1) {
                        do_error(
        _("couldn't map realtime summary inode block %" PRIu64 ", error = %d\n"),
@@ -709,11 +733,11 @@ fill_rsumino(xfs_mount_t *mp)
                        do_warn(
 _("can't access block %" PRIu64 " (fsbno %" PRIu64 ") of realtime summary inode %" PRIu64 "\n"),
                                bno, map.br_startblock, mp->m_sb.sb_rsumino);
-                       IRELE(ip);
+                       libxfs_irele(ip);
                        return(1);
                }
 
-               memmove(XFS_BUF_PTR(bp), smp, mp->m_sb.sb_blocksize);
+               memmove(bp->b_addr, smp, mp->m_sb.sb_blocksize);
 
                libxfs_trans_log_buf(tp, bp, 0, mp->m_sb.sb_blocksize - 1);
 
@@ -721,8 +745,10 @@ _("can't access block %" PRIu64 " (fsbno %" PRIu64 ") of realtime summary inode
                bno++;
        }
 
-       libxfs_trans_commit(tp);
-       IRELE(ip);
+       error = -libxfs_trans_commit(tp);
+       if (error)
+               do_error(_("%s: commit failed, error %d\n"), __func__, error);
+       libxfs_irele(ip);
        return(0);
 }
 
@@ -732,24 +758,20 @@ mk_rsumino(xfs_mount_t *mp)
        xfs_trans_t     *tp;
        xfs_inode_t     *ip;
        xfs_bmbt_irec_t *ep;
-       xfs_fsblock_t   first;
        int             i;
        int             nmap;
        int             error;
        int             nsumblocks;
-       xfs_bmap_free_t flist;
        xfs_fileoff_t   bno;
        xfs_bmbt_irec_t map[XFS_BMAP_MAX_NMAP];
        int             vers;
        int             times;
-       struct xfs_trans_res tres = {0};
+       uint            blocks;
 
        /*
         * first set up inode
         */
-       tp = libxfs_trans_alloc(mp, 0);
-
-       i = -libxfs_trans_reserve(tp, &M_RES(mp)->tr_ichange, 10, 0);
+       i = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 10, 0, 0, &tp);
        if (i)
                res_failed(i);
 
@@ -760,7 +782,7 @@ mk_rsumino(xfs_mount_t *mp)
                        error);
        }
 
-       vers = xfs_sb_version_hascrc(&mp->m_sb) ? 3 : 1;
+       vers = xfs_sb_version_hascrc(&mp->m_sb) ? 3 : 2;
        memset(&ip->i_d, 0, sizeof(ip->i_d));
 
        VFS_I(ip)->i_mode = S_IFREG;
@@ -782,8 +804,8 @@ mk_rsumino(xfs_mount_t *mp)
         * now the ifork
         */
        ip->i_df.if_flags = XFS_IFEXTENTS;
-       ip->i_df.if_bytes = ip->i_df.if_real_bytes = 0;
-       ip->i_df.if_u1.if_extents = NULL;
+       ip->i_df.if_bytes = 0;
+       ip->i_df.if_u1.if_root = NULL;
 
        ip->i_d.di_size = mp->m_rsumsize;
 
@@ -791,32 +813,27 @@ mk_rsumino(xfs_mount_t *mp)
         * commit changes
         */
        libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
-       libxfs_trans_commit(tp);
+       error = -libxfs_trans_commit(tp);
+       if (error)
+               do_error(_("%s: commit failed, error %d\n"), __func__, error);
 
        /*
         * then allocate blocks for file and fill with zeroes (stolen
         * from mkfs)
         */
-       tp = libxfs_trans_alloc(mp, 0);
-       xfs_bmap_init(&flist, &first);
-
        nsumblocks = mp->m_rsumsize >> mp->m_sb.sb_blocklog;
-       tres.tr_logres = BBTOB(128);
-       tres.tr_logcount = XFS_DEFAULT_PERM_LOG_COUNT;
-       tres.tr_logflags = XFS_TRANS_PERM_LOG_RES;
-       error = -libxfs_trans_reserve(tp, &tres, mp->m_sb.sb_rbmblocks +
-                             (XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1), 0);
+       blocks = nsumblocks + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1;
+       error = -libxfs_trans_alloc_rollable(mp, blocks, &tp);
        if (error)
                res_failed(error);
 
        libxfs_trans_ijoin(tp, ip, 0);
        bno = 0;
-       xfs_bmap_init(&flist, &first);
        while (bno < nsumblocks) {
                nmap = XFS_BMAP_MAX_NMAP;
                error = -libxfs_bmapi_write(tp, ip, bno,
                          (xfs_extlen_t)(nsumblocks - bno),
-                         0, &first, nsumblocks, map, &nmap, &flist);
+                         0, nsumblocks, map, &nmap);
                if (error) {
                        do_error(
                _("couldn't allocate realtime summary inode, error = %d\n"),
@@ -829,14 +846,13 @@ mk_rsumino(xfs_mount_t *mp)
                        bno += ep->br_blockcount;
                }
        }
-       error = -libxfs_bmap_finish(&tp, &flist, ip);
+       error = -libxfs_trans_commit(tp);
        if (error) {
                do_error(
        _("allocation of the realtime summary ino failed, error = %d\n"),
                        error);
        }
-       libxfs_trans_commit(tp);
-       IRELE(ip);
+       libxfs_irele(ip);
 }
 
 /*
@@ -854,10 +870,8 @@ mk_root_dir(xfs_mount_t *mp)
        int             vers;
        int             times;
 
-       tp = libxfs_trans_alloc(mp, 0);
        ip = NULL;
-
-       i = -libxfs_trans_reserve(tp, &M_RES(mp)->tr_ichange, 10, 0);
+       i = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 10, 0, 0, &tp);
        if (i)
                res_failed(i);
 
@@ -877,7 +891,7 @@ mk_root_dir(xfs_mount_t *mp)
        ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS;
        ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
 
-       set_nlink(VFS_I(ip), 1);        /* account for . */
+       set_nlink(VFS_I(ip), 2);        /* account for . and .. */
 
        times = XFS_ICHGTIME_CHG | XFS_ICHGTIME_MOD;
        if (ip->i_d.di_version == 3) {
@@ -893,10 +907,8 @@ mk_root_dir(xfs_mount_t *mp)
         * now the ifork
         */
        ip->i_df.if_flags = XFS_IFEXTENTS;
-       ip->i_df.if_bytes = ip->i_df.if_real_bytes = 0;
-       ip->i_df.if_u1.if_extents = NULL;
-
-
+       ip->i_df.if_bytes = 0;
+       ip->i_df.if_u1.if_root = NULL;
 
        /*
         * initialize the directory
@@ -904,8 +916,11 @@ mk_root_dir(xfs_mount_t *mp)
        ip->d_ops = mp->m_dir_inode_ops;
        libxfs_dir_init(tp, ip, ip);
 
-       libxfs_trans_commit(tp);
-       IRELE(ip);
+       error = -libxfs_trans_commit(tp);
+       if (error)
+               do_error(_("%s: commit failed, error %d\n"), __func__, error);
+
+       libxfs_irele(ip);
 
        irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino),
                                XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rootino));
@@ -923,12 +938,10 @@ mk_orphanage(xfs_mount_t *mp)
        xfs_trans_t     *tp;
        xfs_inode_t     *ip;
        xfs_inode_t     *pip;
-       xfs_fsblock_t   first;
        ino_tree_node_t *irec;
        int             ino_offset = 0;
        int             i;
        int             error;
-       xfs_bmap_free_t flist;
        const int       mode = 0755;
        int             nres;
        struct xfs_name xname;
@@ -939,7 +952,9 @@ mk_orphanage(xfs_mount_t *mp)
         * would have been cleared in phase3 and phase4.
         */
 
-       if ((i = -libxfs_iget(mp, NULL, mp->m_sb.sb_rootino, 0, &pip, 0)))
+       i = -libxfs_iget(mp, NULL, mp->m_sb.sb_rootino, 0, &pip,
+                       &xfs_default_ifork_ops);
+       if (i)
                do_error(_("%d - couldn't iget root inode to obtain %s\n"),
                        i, ORPHANAGE);
 
@@ -953,12 +968,8 @@ mk_orphanage(xfs_mount_t *mp)
        /*
         * could not be found, create it
         */
-
-       tp = libxfs_trans_alloc(mp, 0);
-       xfs_bmap_init(&flist, &first);
-
        nres = XFS_MKDIR_SPACE_RES(mp, xname.len);
-       i = -libxfs_trans_reserve(tp, &M_RES(mp)->tr_mkdir, nres, 0);
+       i = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_mkdir, nres, 0, 0, &tp);
        if (i)
                res_failed(i);
 
@@ -966,7 +977,9 @@ mk_orphanage(xfs_mount_t *mp)
         * use iget/ijoin instead of trans_iget because the ialloc
         * wrapper can commit the transaction and start a new one
         */
-/*     if ((i = -libxfs_iget(mp, NULL, mp->m_sb.sb_rootino, 0, &pip, 0)))
+/*     i = -libxfs_iget(mp, NULL, mp->m_sb.sb_rootino, 0, &pip,
+                       &xfs_default_ifork_ops);
+       if (i)
                do_error(_("%d - couldn't iget root inode to make %s\n"),
                        i, ORPHANAGE);*/
 
@@ -1016,8 +1029,7 @@ mk_orphanage(xfs_mount_t *mp)
        /*
         * create the actual entry
         */
-       error = -libxfs_dir_createname(tp, pip, &xname, ip->i_ino, &first,
-                                       &flist, nres);
+       error = -libxfs_dir_createname(tp, pip, &xname, ip->i_ino, nres);
        if (error)
                do_error(
                _("can't make %s, createname error %d\n"),
@@ -1037,17 +1049,13 @@ mk_orphanage(xfs_mount_t *mp)
        libxfs_trans_log_inode(tp, pip, XFS_ILOG_CORE);
        libxfs_dir_init(tp, ip, pip);
        libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
-
-       error = -libxfs_bmap_finish(&tp, &flist, ip);
+       error = -libxfs_trans_commit(tp);
        if (error) {
                do_error(_("%s directory creation failed -- bmapf error %d\n"),
                        ORPHANAGE, error);
        }
-
-
-       libxfs_trans_commit(tp);
-       IRELE(ip);
-       IRELE(pip);
+       libxfs_irele(ip);
+       libxfs_irele(pip);
        add_inode_reached(irec,ino_offset);
 
        return(ino);
@@ -1066,8 +1074,6 @@ mv_orphanage(
        xfs_ino_t               entry_ino_num;
        xfs_inode_t             *ino_p;
        xfs_trans_t             *tp;
-       xfs_fsblock_t           first;
-       xfs_bmap_free_t         flist;
        int                     err;
        unsigned char           fname[MAXPATHLEN + 1];
        int                     nres;
@@ -1080,7 +1086,8 @@ mv_orphanage(
        xname.len = snprintf((char *)fname, sizeof(fname), "%llu",
                                (unsigned long long)ino);
 
-       err = -libxfs_iget(mp, NULL, orphanage_ino, 0, &orphanage_ip, 0);
+       err = -libxfs_iget(mp, NULL, orphanage_ino, 0, &orphanage_ip,
+                       &xfs_default_ifork_ops);
        if (err)
                do_error(_("%d - couldn't iget orphanage inode\n"), err);
        /*
@@ -1092,12 +1099,12 @@ mv_orphanage(
                xname.len = snprintf((char *)fname, sizeof(fname), "%llu.%d",
                                        (unsigned long long)ino, ++incr);
 
-       tp = libxfs_trans_alloc(mp, 0);
-
-       if ((err = -libxfs_iget(mp, NULL, ino, 0, &ino_p, 0)))
+       /* Orphans may not have a proper parent, so use custom ops here */
+       err = -libxfs_iget(mp, NULL, ino, 0, &ino_p, &phase6_ifork_ops);
+       if (err)
                do_error(_("%d - couldn't iget disconnected inode\n"), err);
 
-       xname.type = xfs_mode_to_ftype[(VFS_I(ino_p)->i_mode & S_IFMT)>>S_SHIFT];
+       xname.type = libxfs_mode_to_ftype(VFS_I(ino_p)->i_mode);
 
        if (isa_dir)  {
                irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, orphanage_ino),
@@ -1107,13 +1114,13 @@ mv_orphanage(
                                        irec->ino_startnum;
                nres = XFS_DIRENTER_SPACE_RES(mp, fnamelen) +
                       XFS_DIRENTER_SPACE_RES(mp, 2);
-               err = -libxfs_dir_lookup(tp, ino_p, &xfs_name_dotdot,
+               err = -libxfs_dir_lookup(NULL, ino_p, &xfs_name_dotdot,
                                        &entry_ino_num, NULL);
                if (err) {
                        ASSERT(err == ENOENT);
 
-                       err = -libxfs_trans_reserve(tp, &M_RES(mp)->tr_rename,
-                                                  nres, 0);
+                       err = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_rename,
+                                                 nres, 0, 0, &tp);
                        if (err)
                                do_error(
        _("space reservation failed (%d), filesystem may be out of space\n"),
@@ -1122,9 +1129,8 @@ mv_orphanage(
                        libxfs_trans_ijoin(tp, orphanage_ip, 0);
                        libxfs_trans_ijoin(tp, ino_p, 0);
 
-                       xfs_bmap_init(&flist, &first);
                        err = -libxfs_dir_createname(tp, orphanage_ip, &xname,
-                                               ino, &first, &flist, nres);
+                                               ino, nres);
                        if (err)
                                do_error(
        _("name create failed in %s (%d), filesystem may be out of space\n"),
@@ -1137,7 +1143,7 @@ mv_orphanage(
                        libxfs_trans_log_inode(tp, orphanage_ip, XFS_ILOG_CORE);
 
                        err = -libxfs_dir_createname(tp, ino_p, &xfs_name_dotdot,
-                                       orphanage_ino, &first, &flist, nres);
+                                       orphanage_ino, nres);
                        if (err)
                                do_error(
        _("creation of .. entry failed (%d), filesystem may be out of space\n"),
@@ -1145,17 +1151,13 @@ mv_orphanage(
 
                        inc_nlink(VFS_I(ino_p));
                        libxfs_trans_log_inode(tp, ino_p, XFS_ILOG_CORE);
-
-                       err = -libxfs_bmap_finish(&tp, &flist, ino_p);
+                       err = -libxfs_trans_commit(tp);
                        if (err)
                                do_error(
-       _("bmap finish failed (err - %d), filesystem may be out of space\n"),
-                                       err);
-
-                       libxfs_trans_commit(tp);
+       _("creation of .. entry failed (%d)\n"), err);
                } else  {
-                       err = -libxfs_trans_reserve(tp, &M_RES(mp)->tr_rename,
-                                                  nres, 0);
+                       err = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_rename,
+                                                 nres, 0, 0, &tp);
                        if (err)
                                do_error(
        _("space reservation failed (%d), filesystem may be out of space\n"),
@@ -1164,10 +1166,9 @@ mv_orphanage(
                        libxfs_trans_ijoin(tp, orphanage_ip, 0);
                        libxfs_trans_ijoin(tp, ino_p, 0);
 
-                       xfs_bmap_init(&flist, &first);
 
                        err = -libxfs_dir_createname(tp, orphanage_ip, &xname,
-                                               ino, &first, &flist, nres);
+                                               ino, nres);
                        if (err)
                                do_error(
        _("name create failed in %s (%d), filesystem may be out of space\n"),
@@ -1186,20 +1187,17 @@ mv_orphanage(
                        if (entry_ino_num != orphanage_ino)  {
                                err = -libxfs_dir_replace(tp, ino_p,
                                                &xfs_name_dotdot, orphanage_ino,
-                                               &first, &flist, nres);
+                                               nres);
                                if (err)
                                        do_error(
        _("name replace op failed (%d), filesystem may be out of space\n"),
                                                err);
                        }
 
-                       err = -libxfs_bmap_finish(&tp, &flist, ino_p);
+                       err = -libxfs_trans_commit(tp);
                        if (err)
                                do_error(
-       _("bmap finish failed (%d), filesystem may be out of space\n"),
-                                       err);
-
-                       libxfs_trans_commit(tp);
+       _("orphanage name replace op failed (%d)\n"), err);
                }
 
        } else  {
@@ -1210,8 +1208,8 @@ mv_orphanage(
                 * also accounted for in the create
                 */
                nres = XFS_DIRENTER_SPACE_RES(mp, xname.len);
-               err = -libxfs_trans_reserve(tp, &M_RES(mp)->tr_remove,
-                                          nres, 0);
+               err = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_remove,
+                                         nres, 0, 0, &tp);
                if (err)
                        do_error(
        _("space reservation failed (%d), filesystem may be out of space\n"),
@@ -1220,9 +1218,8 @@ mv_orphanage(
                libxfs_trans_ijoin(tp, orphanage_ip, 0);
                libxfs_trans_ijoin(tp, ino_p, 0);
 
-               xfs_bmap_init(&flist, &first);
                err = -libxfs_dir_createname(tp, orphanage_ip, &xname, ino,
-                                               &first, &flist, nres);
+                                               nres);
                if (err)
                        do_error(
        _("name create failed in %s (%d), filesystem may be out of space\n"),
@@ -1231,17 +1228,13 @@ mv_orphanage(
 
                set_nlink(VFS_I(ino_p), 1);
                libxfs_trans_log_inode(tp, ino_p, XFS_ILOG_CORE);
-
-               err = -libxfs_bmap_finish(&tp, &flist, ino_p);
+               err = -libxfs_trans_commit(tp);
                if (err)
                        do_error(
-       _("bmap finish failed (%d), filesystem may be out of space\n"),
-                               err);
-
-               libxfs_trans_commit(tp);
+       _("orphanage name create failed (%d)\n"), err);
        }
-       IRELE(ino_p);
-       IRELE(orphanage_ip);
+       libxfs_irele(ino_p);
+       libxfs_irele(orphanage_ip);
 }
 
 static int
@@ -1262,6 +1255,48 @@ entry_junked(
        return !no_modify;
 }
 
+/* Find and invalidate all the directory's buffers. */
+static int
+dir_binval(
+       struct xfs_trans        *tp,
+       struct xfs_inode        *ip,
+       int                     whichfork)
+{
+       struct xfs_iext_cursor  icur;
+       struct xfs_bmbt_irec    rec;
+       struct xfs_ifork        *ifp;
+       struct xfs_da_geometry  *geo;
+       struct xfs_buf          *bp;
+       xfs_dablk_t             dabno, end_dabno;
+       int                     error = 0;
+
+       if (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS &&
+           ip->i_d.di_format != XFS_DINODE_FMT_BTREE)
+               return 0;
+
+       geo = tp->t_mountp->m_dir_geo;
+       ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
+       for_each_xfs_iext(ifp, &icur, &rec) {
+               dabno = xfs_dir2_db_to_da(geo, rec.br_startoff +
+                               geo->fsbcount - 1);
+               end_dabno = xfs_dir2_db_to_da(geo, rec.br_startoff +
+                               rec.br_blockcount);
+               for (; dabno <= end_dabno; dabno += geo->fsbcount) {
+                       bp = NULL;
+                       error = -libxfs_da_get_buf(tp, ip, dabno, -2, &bp,
+                                       whichfork);
+                       if (error)
+                               return error;
+                       if (!bp)
+                               continue;
+                       libxfs_trans_binval(tp, bp);
+                       libxfs_trans_brelse(tp, bp);
+               }
+       }
+
+       return error;
+}
+
 /*
  * Unexpected failure during the rebuild will leave the entries in
  * lost+found on the next run
@@ -1280,11 +1315,9 @@ longform_dir2_rebuild(
        int                     nres;
        xfs_trans_t             *tp;
        xfs_fileoff_t           lastblock;
-       xfs_fsblock_t           firstblock;
-       xfs_bmap_free_t         flist;
        xfs_inode_t             pip;
        dir_hash_ent_t          *p;
-       int                     done;
+       int                     done = 0;
 
        /*
         * trash directory completely and rebuild from scratch using the
@@ -1301,41 +1334,54 @@ longform_dir2_rebuild(
         */
        pip.i_ino = get_inode_parent(irec, ino_offset);
        if (pip.i_ino == NULLFSINO ||
-           xfs_dir_ino_validate(mp, pip.i_ino))
+           libxfs_dir_ino_validate(mp, pip.i_ino))
                pip.i_ino = mp->m_sb.sb_rootino;
 
-       xfs_bmap_init(&flist, &firstblock);
-
-       tp = libxfs_trans_alloc(mp, 0);
        nres = XFS_REMOVE_SPACE_RES(mp);
-       error = -libxfs_trans_reserve(tp, &M_RES(mp)->tr_remove, nres, 0);
+       error = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_remove, nres, 0, 0, &tp);
        if (error)
                res_failed(error);
        libxfs_trans_ijoin(tp, ip, 0);
 
+       error = dir_binval(tp, ip, XFS_DATA_FORK);
+       if (error)
+               res_failed(error);
+
        if ((error = -libxfs_bmap_last_offset(ip, &lastblock, XFS_DATA_FORK)))
                do_error(_("xfs_bmap_last_offset failed -- error - %d\n"),
                        error);
 
        /* free all data, leaf, node and freespace blocks */
-       error = -libxfs_bunmapi(tp, ip, 0, lastblock, XFS_BMAPI_METADATA, 0,
-                               &firstblock, &flist, &done);
-       if (error) {
-               do_warn(_("xfs_bunmapi failed -- error - %d\n"), error);
-               goto out_bmap_cancel;
-       }
-
-       ASSERT(done);
+       while (!done) {
+              error = -libxfs_bunmapi(tp, ip, 0, lastblock, XFS_BMAPI_METADATA,
+                                      0, &done);
+              if (error) {
+                      do_warn(_("xfs_bunmapi failed -- error - %d\n"), error);
+                      goto out_bmap_cancel;
+              }
+              error = -libxfs_defer_finish(&tp);
+              if (error) {
+                      do_warn(("defer_finish failed -- error - %d\n"), error);
+                      goto out_bmap_cancel;
+              }
+              /*
+               * Close out trans and start the next one in the chain.
+               */
+              error = -libxfs_trans_roll_inode(&tp, ip);
+              if (error)
+                       goto out_bmap_cancel;
+        }
 
-       error = libxfs_dir_init(tp, ip, &pip);
+       error = -libxfs_dir_init(tp, ip, &pip);
        if (error) {
                do_warn(_("xfs_dir_init failed -- error - %d\n"), error);
                goto out_bmap_cancel;
        }
 
-       error = -libxfs_bmap_finish(&tp, &flist, ip);
-
-       libxfs_trans_commit(tp);
+       error = -libxfs_trans_commit(tp);
+       if (error)
+               do_error(
+       _("dir init failed (%d)\n"), error);
 
        if (ino == mp->m_sb.sb_rootino)
                need_root_dotdot = 0;
@@ -1349,18 +1395,16 @@ longform_dir2_rebuild(
                                                p->name.name[1] == '.'))))
                        continue;
 
-               tp = libxfs_trans_alloc(mp, 0);
                nres = XFS_CREATE_SPACE_RES(mp, p->name.len);
-               error = -libxfs_trans_reserve(tp, &M_RES(mp)->tr_create,
-                                            nres, 0);
+               error = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_create,
+                                           nres, 0, 0, &tp);
                if (error)
                        res_failed(error);
 
                libxfs_trans_ijoin(tp, ip, 0);
 
-               xfs_bmap_init(&flist, &firstblock);
                error = -libxfs_dir_createname(tp, ip, &p->name, p->inum,
-                                               &firstblock, &flist, nres);
+                                               nres);
                if (error) {
                        do_warn(
 _("name create failed in ino %" PRIu64 " (%d), filesystem may be out of space\n"),
@@ -1368,21 +1412,15 @@ _("name create failed in ino %" PRIu64 " (%d), filesystem may be out of space\n"
                        goto out_bmap_cancel;
                }
 
-               error = -libxfs_bmap_finish(&tp, &flist, ip);
-               if (error) {
-                       do_warn(
-       _("bmap finish failed (%d), filesystem may be out of space\n"),
-                               error);
-                       goto out_bmap_cancel;
-               }
-
-               libxfs_trans_commit(tp);
+               error = -libxfs_trans_commit(tp);
+               if (error)
+                       do_error(
+_("name create failed (%d) during rebuild\n"), error);
        }
 
        return;
 
 out_bmap_cancel:
-       libxfs_bmap_cancel(&flist);
        libxfs_trans_cancel(tp);
        return;
 }
@@ -1401,24 +1439,18 @@ dir2_kill_block(
 {
        xfs_da_args_t   args;
        int             error;
-       xfs_fsblock_t   firstblock;
-       xfs_bmap_free_t flist;
        int             nres;
        xfs_trans_t     *tp;
 
-       tp = libxfs_trans_alloc(mp, 0);
        nres = XFS_REMOVE_SPACE_RES(mp);
-       error = -libxfs_trans_reserve(tp, &M_RES(mp)->tr_remove, nres, 0);
+       error = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_remove, nres, 0, 0, &tp);
        if (error)
                res_failed(error);
        libxfs_trans_ijoin(tp, ip, 0);
        libxfs_trans_bjoin(tp, bp);
        memset(&args, 0, sizeof(args));
-       xfs_bmap_init(&flist, &firstblock);
        args.dp = ip;
        args.trans = tp;
-       args.firstblock = &firstblock;
-       args.flist = &flist;
        args.whichfork = XFS_DATA_FORK;
        args.geo = mp->m_dir_geo;
        if (da_bno >= mp->m_dir_geo->leafblk && da_bno < mp->m_dir_geo->freeblk)
@@ -1429,8 +1461,10 @@ dir2_kill_block(
        if (error)
                do_error(_("shrink_inode failed inode %" PRIu64 " block %u\n"),
                        ip->i_ino, da_bno);
-       libxfs_bmap_finish(&tp, &flist, ip);
-       libxfs_trans_commit(tp);
+       error = -libxfs_trans_commit(tp);
+       if (error)
+               do_error(
+_("directory shrink failed (%d)\n"), error);
 }
 
 /*
@@ -1462,8 +1496,6 @@ longform_dir2_entry_check_data(
        struct xfs_dir2_data_free *bf;
        char                    *endptr;
        int                     error;
-       xfs_fsblock_t           firstblock;
-       xfs_bmap_free_t         flist;
        char                    fname[MAXNAMELEN + 1];
        freetab_t               *freetab;
        int                     i;
@@ -1598,15 +1630,13 @@ longform_dir2_entry_check_data(
        if (freetab->nents < db + 1)
                freetab->nents = db + 1;
 
-       tp = libxfs_trans_alloc(mp, 0);
-       error = -libxfs_trans_reserve(tp, &M_RES(mp)->tr_remove, 0, 0);
+       error = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_remove, 0, 0, 0, &tp);
        if (error)
                res_failed(error);
        da.trans = tp;
        libxfs_trans_ijoin(tp, ip, 0);
        libxfs_trans_bjoin(tp, bp);
        libxfs_trans_bhold(tp, bp);
-       xfs_bmap_init(&flist, &firstblock);
        if (be32_to_cpu(d->magic) != wantmagic) {
                do_warn(
        _("bad directory block magic # %#x for directory inode %" PRIu64 " block %d: "),
@@ -1790,7 +1820,8 @@ longform_dir2_entry_check_data(
                 * of when directory is moved to orphanage.
                 */
                if (ip->i_ino == inum)  {
-                       ASSERT(dep->name[0] == '.' && dep->namelen == 1);
+                       ASSERT(no_modify ||
+                              (dep->name[0] == '.' && dep->namelen == 1));
                        add_inode_ref(current_irec, current_ino_offset);
                        if (da_bno != 0 ||
                            dep != M_DIROPS(mp)->data_entry_p(d)) {
@@ -1814,8 +1845,8 @@ longform_dir2_entry_check_data(
 
                /* validate ftype field if supported */
                if (xfs_sb_version_hasftype(&mp->m_sb)) {
-                       __uint8_t dir_ftype;
-                       __uint8_t ino_ftype;
+                       uint8_t dir_ftype;
+                       uint8_t ino_ftype;
 
                        dir_ftype = M_DIROPS(mp)->data_get_ftype(dep);
                        ino_ftype = get_inode_ftype(irec, ino_offset);
@@ -1902,11 +1933,14 @@ _("entry \"%s\" in dir inode %" PRIu64 " inconsistent with .. value (%" PRIu64 "
        }
        *num_illegal += nbad;
        if (needscan)
-               libxfs_dir2_data_freescan(mp->m_dir_geo, M_DIROPS(mp), d, &i);
+               libxfs_dir2_data_freescan_int(mp->m_dir_geo, M_DIROPS(mp),
+                               d, &i);
        if (needlog)
                libxfs_dir2_data_log_header(&da, bp);
-       libxfs_bmap_finish(&tp, &flist, ip);
-       libxfs_trans_commit(tp);
+       error = -libxfs_trans_commit(tp);
+       if (error)
+               do_error(
+_("directory block fixing failed (%d)\n"), error);
 
        /* record the largest free space in the freetab for later checking */
        bf = M_DIROPS(mp)->data_bestfree_p(d);
@@ -1929,14 +1963,14 @@ __check_dir3_header(
        if (be64_to_cpu(owner) != ino) {
                do_warn(
 _("expected owner inode %" PRIu64 ", got %llu, directory block %" PRIu64 "\n"),
-                       ino, be64_to_cpu(owner), bp->b_bn);
+                       ino, (unsigned long long)be64_to_cpu(owner), bp->b_bn);
                return 1;
        }
        /* verify block number */
        if (be64_to_cpu(blkno) != bp->b_bn) {
                do_warn(
 _("expected block %" PRIu64 ", got %llu, directory inode %" PRIu64 "\n"),
-                       bp->b_bn, be64_to_cpu(blkno), ino);
+                       bp->b_bn, (unsigned long long)be64_to_cpu(blkno), ino);
                return 1;
        }
        /* verify uuid */
@@ -2312,6 +2346,8 @@ longform_dir2_entry_check(xfs_mount_t     *mp,
 
                db = xfs_dir2_da_to_db(mp->m_dir_geo, da_bno);
                if (db >= num_bps) {
+                       int last_size = num_bps;
+
                        /* more data blocks than expected */
                        num_bps = db + 1;
                        bplist = realloc(bplist, num_bps * sizeof(struct xfs_buf*));
@@ -2319,6 +2355,9 @@ longform_dir2_entry_check(xfs_mount_t     *mp,
                                do_error(_("realloc failed in %s (%zu bytes)\n"),
                                        __func__,
                                        num_bps * sizeof(struct xfs_buf*));
+                       /* Initialize the new elements */
+                       for (i = last_size; i < num_bps; i++)
+                               bplist[i] = NULL;
                }
 
                if (isblock)
@@ -2725,8 +2764,8 @@ _("entry \"%s\" (ino %" PRIu64 ") in dir %" PRIu64 " is a duplicate name"),
 
                /* validate ftype field if supported */
                if (xfs_sb_version_hasftype(&mp->m_sb)) {
-                       __uint8_t dir_ftype;
-                       __uint8_t ino_ftype;
+                       uint8_t dir_ftype;
+                       uint8_t ino_ftype;
 
                        dir_ftype = M_DIROPS(mp)->sf_get_ftype(sfep);
                        ino_ftype = get_inode_ftype(irec, ino_offset);
@@ -2821,8 +2860,6 @@ process_dir_inode(
        int                     ino_offset)
 {
        xfs_ino_t               ino;
-       xfs_bmap_free_t         flist;
-       xfs_fsblock_t           first;
        xfs_inode_t             *ip;
        xfs_trans_t             *tp;
        dir_hash_tab_t          *hashtab;
@@ -2839,7 +2876,7 @@ process_dir_inode(
 
        ASSERT(!is_inode_refchecked(irec, ino_offset) || dotdot_update);
 
-       error = -libxfs_iget(mp, NULL, ino, 0, &ip, 0);
+       error = -libxfs_iget(mp, NULL, ino, 0, &ip, &phase6_ifork_ops);
        if (error) {
                if (!no_modify)
                        do_error(
@@ -2902,7 +2939,6 @@ process_dir_inode(
                        break;
 
                case XFS_DINODE_FMT_LOCAL:
-                       tp = libxfs_trans_alloc(mp, 0);
                        /*
                         * using the remove reservation is overkill
                         * since at most we'll only need to log the
@@ -2910,8 +2946,8 @@ process_dir_inode(
                         * new define in ourselves.
                         */
                        nres = no_modify ? 0 : XFS_REMOVE_SPACE_RES(mp);
-                       error = -libxfs_trans_reserve(tp, &M_RES(mp)->tr_remove,
-                                                    nres, 0);
+                       error = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_remove,
+                                                   nres, 0, 0, &tp);
                        if (error)
                                res_failed(error);
 
@@ -2925,7 +2961,9 @@ process_dir_inode(
                        if (dirty)  {
                                libxfs_trans_log_inode(tp, ip,
                                        XFS_ILOG_CORE | XFS_ILOG_DDATA);
-                               libxfs_trans_commit(tp);
+                               error = -libxfs_trans_commit(tp);
+                               if (error)
+                                       res_failed(error);
                        } else  {
                                libxfs_trans_cancel(tp);
                        }
@@ -2951,29 +2989,25 @@ process_dir_inode(
 
                do_warn(_("recreating root directory .. entry\n"));
 
-               tp = libxfs_trans_alloc(mp, 0);
-               ASSERT(tp != NULL);
-
                nres = XFS_MKDIR_SPACE_RES(mp, 2);
-               error = -libxfs_trans_reserve(tp, &M_RES(mp)->tr_mkdir, nres, 0);
+               error = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_mkdir,
+                                           nres, 0, 0, &tp);
                if (error)
                        res_failed(error);
 
                libxfs_trans_ijoin(tp, ip, 0);
 
-               xfs_bmap_init(&flist, &first);
-
                error = -libxfs_dir_createname(tp, ip, &xfs_name_dotdot,
-                                       ip->i_ino, &first, &flist, nres);
+                                       ip->i_ino, nres);
                if (error)
                        do_error(
        _("can't make \"..\" entry in root inode %" PRIu64 ", createname error %d\n"), ino, error);
 
                libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
-
-               error = -libxfs_bmap_finish(&tp, &flist, ip);
-               ASSERT(error == 0);
-               libxfs_trans_commit(tp);
+               error = -libxfs_trans_commit(tp);
+               if (error)
+                       do_error(
+       _("root inode \"..\" entry recreation failed (%d)\n"), error);
 
                need_root_dotdot = 0;
        } else if (need_root_dotdot && ino == mp->m_sb.sb_rootino)  {
@@ -3010,34 +3044,29 @@ process_dir_inode(
                        do_warn(
        _("creating missing \".\" entry in dir ino %" PRIu64 "\n"), ino);
 
-                       tp = libxfs_trans_alloc(mp, 0);
-                       ASSERT(tp != NULL);
-
                        nres = XFS_MKDIR_SPACE_RES(mp, 1);
-                       error = -libxfs_trans_reserve(tp, &M_RES(mp)->tr_mkdir,
-                                                    nres, 0);
+                       error = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_mkdir,
+                                                   nres, 0, 0, &tp);
                        if (error)
                                res_failed(error);
 
                        libxfs_trans_ijoin(tp, ip, 0);
 
-                       xfs_bmap_init(&flist, &first);
-
                        error = -libxfs_dir_createname(tp, ip, &xfs_name_dot,
-                                       ip->i_ino, &first, &flist, nres);
+                                       ip->i_ino, nres);
                        if (error)
                                do_error(
        _("can't make \".\" entry in dir ino %" PRIu64 ", createname error %d\n"),
                                        ino, error);
 
                        libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
-
-                       error = -libxfs_bmap_finish(&tp, &flist, ip);
-                       ASSERT(error == 0);
-                       libxfs_trans_commit(tp);
+                       error = -libxfs_trans_commit(tp);
+                       if (error)
+                               do_error(
+       _("root inode \".\" entry recreation failed (%d)\n"), error);
                }
        }
-       IRELE(ip);
+       libxfs_irele(ip);
 }
 
 /*
@@ -3053,8 +3082,6 @@ mark_standalone_inodes(xfs_mount_t *mp)
        irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rbmino),
                        XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rbmino));
 
-       ASSERT(irec != NULL);
-
        offset = XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rbmino) -
                        irec->ino_startnum;
 
@@ -3066,8 +3093,6 @@ mark_standalone_inodes(xfs_mount_t *mp)
        offset = XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rsumino) -
                        irec->ino_startnum;
 
-       ASSERT(irec != NULL);
-
        add_inode_reached(irec, offset);
 
        if (fs_quotas)  {
@@ -3145,7 +3170,7 @@ check_for_orphaned_inodes(
 
 static void
 traverse_function(
-       work_queue_t            *wq,
+       struct workqueue        *wq,
        xfs_agnumber_t          agno,
        void                    *arg)
 {
@@ -3174,7 +3199,7 @@ traverse_function(
 
                for (i = 0; i < XFS_INODES_PER_CHUNK; i++)  {
                        if (inode_isadir(irec, i))
-                               process_dir_inode(wq->mp, agno, irec, i);
+                               process_dir_inode(wq->wq_ctx, agno, irec, i);
                }
        }
        cleanup_inode_prefetch(pf_args);