]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blobdiff - repair/phase6.c
libxfs: refactor manage_zones()
[thirdparty/xfsprogs-dev.git] / repair / phase6.c
index f011e24e159866eeb6cc5451f9392200fe6c83cc..28e633deb2cd4c0534da882f86be2907a2783b8b 100644 (file)
@@ -479,7 +479,7 @@ bmap_next_offset(
        xfs_fileoff_t   bno;                    /* current block */
        int             error;                  /* error return value */
        xfs_bmbt_irec_t got;                    /* current extent value */
-       xfs_ifork_t     *ifp;                   /* inode fork pointer */
+       struct xfs_ifork        *ifp;           /* inode fork pointer */
        struct xfs_iext_cursor  icur;
 
        if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE &&
@@ -513,17 +513,15 @@ 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;
-       struct xfs_defer_ops    dfops;
        xfs_fileoff_t   bno;
        xfs_bmbt_irec_t map[XFS_BMAP_MAX_NMAP];
        int             vers;
@@ -537,7 +535,8 @@ mk_rbmino(xfs_mount_t *mp)
        if (i)
                res_failed(i);
 
-       error = -libxfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0, 0, &ip);
+       error = -libxfs_iget(mp, tp, mp->m_sb.sb_rbmino, 0, &ip,
+                       &xfs_default_ifork_ops);
        if (error) {
                do_error(
                _("couldn't iget realtime bitmap inode -- error - %d\n"),
@@ -566,7 +565,7 @@ 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_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;
@@ -574,8 +573,11 @@ mk_rbmino(xfs_mount_t *mp)
        /*
         * commit changes
         */
+       libxfs_trans_ijoin(tp, ip, 0);
        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
@@ -589,13 +591,11 @@ mk_rbmino(xfs_mount_t *mp)
 
        libxfs_trans_ijoin(tp, ip, 0);
        bno = 0;
-       libxfs_defer_init(&dfops, &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, &dfops);
+                         0, mp->m_sb.sb_rbmblocks, map, &nmap);
                if (error) {
                        do_error(
                        _("couldn't allocate realtime bitmap, error = %d\n"),
@@ -608,15 +608,13 @@ mk_rbmino(xfs_mount_t *mp)
                        bno += ep->br_blockcount;
                }
        }
-       libxfs_defer_ijoin(&dfops, ip);
-       error = -libxfs_defer_finish(&tp, &dfops);
+       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
@@ -626,7 +624,6 @@ 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;
@@ -639,21 +636,21 @@ fill_rbmino(xfs_mount_t *mp)
        if (error)
                res_failed(error);
 
-       error = -libxfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0, 0, &ip);
+       error = -libxfs_iget(mp, tp, mp->m_sb.sb_rbmino, 0, &ip,
+                       &xfs_default_ifork_ops);
        if (error) {
                do_error(
                _("couldn't iget realtime bitmap inode -- error - %d\n"),
                        error);
        }
 
-       first = NULLFSBLOCK;
        while (bno < mp->m_sb.sb_rbmblocks)  {
                /*
                 * fill the file one block at a time
                 */
+               libxfs_trans_ijoin(tp, ip, 0);
                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"),
@@ -682,8 +679,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);
 }
 
@@ -694,7 +693,6 @@ 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;
@@ -709,21 +707,21 @@ fill_rsumino(xfs_mount_t *mp)
        if (error)
                res_failed(error);
 
-       error = -libxfs_trans_iget(mp, tp, mp->m_sb.sb_rsumino, 0, 0, &ip);
+       error = -libxfs_iget(mp, tp, mp->m_sb.sb_rsumino, 0, &ip,
+                       &xfs_default_ifork_ops);
        if (error) {
                do_error(
                _("couldn't iget realtime summary inode -- error - %d\n"),
                        error);
        }
 
-       first = NULLFSBLOCK;
        while (bno < end_bno)  {
                /*
                 * fill the file one block at a time
                 */
+               libxfs_trans_ijoin(tp, ip, 0);
                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"),
@@ -741,7 +739,7 @@ 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);
                }
 
@@ -753,8 +751,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);
 }
 
@@ -764,12 +764,10 @@ 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;
-       struct xfs_defer_ops    dfops;
        xfs_fileoff_t   bno;
        xfs_bmbt_irec_t map[XFS_BMAP_MAX_NMAP];
        int             vers;
@@ -783,7 +781,8 @@ mk_rsumino(xfs_mount_t *mp)
        if (i)
                res_failed(i);
 
-       error = -libxfs_trans_iget(mp, tp, mp->m_sb.sb_rsumino, 0, 0, &ip);
+       error = -libxfs_iget(mp, tp, mp->m_sb.sb_rsumino, 0, &ip,
+                       &xfs_default_ifork_ops);
        if (error) {
                do_error(
                _("couldn't iget realtime summary inode -- error - %d\n"),
@@ -812,7 +811,7 @@ 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_bytes = 0;
        ip->i_df.if_u1.if_root = NULL;
 
        ip->i_d.di_size = mp->m_rsumsize;
@@ -820,15 +819,16 @@ mk_rsumino(xfs_mount_t *mp)
        /*
         * commit changes
         */
+       libxfs_trans_ijoin(tp, ip, 0);
        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)
         */
-       libxfs_defer_init(&dfops, &first);
-
        nsumblocks = mp->m_rsumsize >> mp->m_sb.sb_blocklog;
        blocks = nsumblocks + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1;
        error = -libxfs_trans_alloc_rollable(mp, blocks, &tp);
@@ -837,12 +837,11 @@ mk_rsumino(xfs_mount_t *mp)
 
        libxfs_trans_ijoin(tp, ip, 0);
        bno = 0;
-       libxfs_defer_init(&dfops, &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, &dfops);
+                         0, nsumblocks, map, &nmap);
                if (error) {
                        do_error(
                _("couldn't allocate realtime summary inode, error = %d\n"),
@@ -855,15 +854,13 @@ mk_rsumino(xfs_mount_t *mp)
                        bno += ep->br_blockcount;
                }
        }
-       libxfs_defer_ijoin(&dfops, ip);
-       error = -libxfs_defer_finish(&tp, &dfops);
+       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);
 }
 
 /*
@@ -886,7 +883,8 @@ mk_root_dir(xfs_mount_t *mp)
        if (i)
                res_failed(i);
 
-       error = -libxfs_trans_iget(mp, tp, mp->m_sb.sb_rootino, 0, 0, &ip);
+       error = -libxfs_iget(mp, tp, mp->m_sb.sb_rootino, 0, &ip,
+                       &xfs_default_ifork_ops);
        if (error) {
                do_error(_("could not iget root inode -- error - %d\n"), error);
        }
@@ -902,7 +900,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) {
@@ -911,26 +909,27 @@ mk_root_dir(xfs_mount_t *mp)
                times |= XFS_ICHGTIME_CREATE;
        }
        libxfs_trans_ichgtime(tp, ip, times);
-
+       libxfs_trans_ijoin(tp, ip, 0);
        libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
 
        /*
         * 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_bytes = 0;
        ip->i_df.if_u1.if_root = NULL;
 
-
-
        /*
         * initialize the directory
         */
        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));
@@ -948,12 +947,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;
-       struct xfs_defer_ops    dfops;
        const int       mode = 0755;
        int             nres;
        struct xfs_name xname;
@@ -980,7 +977,6 @@ mk_orphanage(xfs_mount_t *mp)
        /*
         * could not be found, create it
         */
-       libxfs_defer_init(&dfops, &first);
        nres = XFS_MKDIR_SPACE_RES(mp, xname.len);
        i = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_mkdir, nres, 0, 0, &tp);
        if (i)
@@ -1032,6 +1028,7 @@ mk_orphanage(xfs_mount_t *mp)
         */
        set_inode_used(irec, ino_offset);
        add_inode_ref(irec, ino_offset);
+       add_inode_reached(irec, ino_offset);
 
        /*
         * now that we know the transaction will stay around,
@@ -1042,8 +1039,7 @@ mk_orphanage(xfs_mount_t *mp)
        /*
         * create the actual entry
         */
-       error = -libxfs_dir_createname(tp, pip, &xname, ip->i_ino, &first,
-                                       nres);
+       error = -libxfs_dir_createname(tp, pip, &xname, ip->i_ino, nres);
        if (error)
                do_error(
                _("can't make %s, createname error %d\n"),
@@ -1051,31 +1047,25 @@ mk_orphanage(xfs_mount_t *mp)
 
        /*
         * bump up the link count in the root directory to account
-        * for .. in the new directory
+        * for .. in the new directory, and update the irec copy of the
+        * on-disk nlink so we don't fail the link count check later.
         */
        inc_nlink(VFS_I(pip));
-       add_inode_ref(find_inode_rec(mp,
-                               XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino),
-                               XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rootino)), 0);
-
-
+       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));
+       add_inode_ref(irec, 0);
+       set_inode_disk_nlinks(irec, 0, get_inode_disk_nlinks(irec, 0) + 1);
 
        libxfs_trans_log_inode(tp, pip, XFS_ILOG_CORE);
        libxfs_dir_init(tp, ip, pip);
        libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
-
-       libxfs_defer_ijoin(&dfops, ip);
-       error = -libxfs_defer_finish(&tp, &dfops);
+       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);
-       add_inode_reached(irec,ino_offset);
+       libxfs_irele(ip);
+       libxfs_irele(pip);
 
        return(ino);
 }
@@ -1093,8 +1083,6 @@ mv_orphanage(
        xfs_ino_t               entry_ino_num;
        xfs_inode_t             *ino_p;
        xfs_trans_t             *tp;
-       xfs_fsblock_t           first;
-       struct xfs_defer_ops            dfops;
        int                     err;
        unsigned char           fname[MAXPATHLEN + 1];
        int                     nres;
@@ -1150,9 +1138,8 @@ mv_orphanage(
                        libxfs_trans_ijoin(tp, orphanage_ip, 0);
                        libxfs_trans_ijoin(tp, ino_p, 0);
 
-                       libxfs_defer_init(&dfops, &first);
                        err = -libxfs_dir_createname(tp, orphanage_ip, &xname,
-                                               ino, &first, nres);
+                                               ino, nres);
                        if (err)
                                do_error(
        _("name create failed in %s (%d), filesystem may be out of space\n"),
@@ -1165,7 +1152,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, nres);
+                                       orphanage_ino, nres);
                        if (err)
                                do_error(
        _("creation of .. entry failed (%d), filesystem may be out of space\n"),
@@ -1173,15 +1160,10 @@ mv_orphanage(
 
                        inc_nlink(VFS_I(ino_p));
                        libxfs_trans_log_inode(tp, ino_p, XFS_ILOG_CORE);
-
-                       libxfs_defer_ijoin(&dfops, ino_p);
-                       err = -libxfs_defer_finish(&tp, &dfops);
+                       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_alloc(mp, &M_RES(mp)->tr_rename,
                                                  nres, 0, 0, &tp);
@@ -1193,10 +1175,9 @@ mv_orphanage(
                        libxfs_trans_ijoin(tp, orphanage_ip, 0);
                        libxfs_trans_ijoin(tp, ino_p, 0);
 
-                       libxfs_defer_init(&dfops, &first);
 
                        err = -libxfs_dir_createname(tp, orphanage_ip, &xname,
-                                               ino, &first, nres);
+                                               ino, nres);
                        if (err)
                                do_error(
        _("name create failed in %s (%d), filesystem may be out of space\n"),
@@ -1215,21 +1196,17 @@ mv_orphanage(
                        if (entry_ino_num != orphanage_ino)  {
                                err = -libxfs_dir_replace(tp, ino_p,
                                                &xfs_name_dotdot, orphanage_ino,
-                                               &first, nres);
+                                               nres);
                                if (err)
                                        do_error(
        _("name replace op failed (%d), filesystem may be out of space\n"),
                                                err);
                        }
 
-                       libxfs_defer_ijoin(&dfops, ino_p);
-                       err = -libxfs_defer_finish(&tp, &dfops);
+                       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  {
@@ -1250,9 +1227,8 @@ mv_orphanage(
                libxfs_trans_ijoin(tp, orphanage_ip, 0);
                libxfs_trans_ijoin(tp, ino_p, 0);
 
-               libxfs_defer_init(&dfops, &first);
                err = -libxfs_dir_createname(tp, orphanage_ip, &xname, ino,
-                                               &first, nres);
+                                               nres);
                if (err)
                        do_error(
        _("name create failed in %s (%d), filesystem may be out of space\n"),
@@ -1261,18 +1237,13 @@ mv_orphanage(
 
                set_nlink(VFS_I(ino_p), 1);
                libxfs_trans_log_inode(tp, ino_p, XFS_ILOG_CORE);
-
-               libxfs_defer_ijoin(&dfops, ino_p);
-               err = -libxfs_defer_finish(&tp, &dfops);
+               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
@@ -1353,11 +1324,9 @@ longform_dir2_rebuild(
        int                     nres;
        xfs_trans_t             *tp;
        xfs_fileoff_t           lastblock;
-       xfs_fsblock_t           firstblock;
-       struct xfs_defer_ops            dfops;
        xfs_inode_t             pip;
        dir_hash_ent_t          *p;
-       int                     done;
+       int                     done = 0;
 
        /*
         * trash directory completely and rebuild from scratch using the
@@ -1377,8 +1346,6 @@ longform_dir2_rebuild(
            libxfs_dir_ino_validate(mp, pip.i_ino))
                pip.i_ino = mp->m_sb.sb_rootino;
 
-       libxfs_defer_init(&dfops, &firstblock);
-
        nres = XFS_REMOVE_SPACE_RES(mp);
        error = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_remove, nres, 0, 0, &tp);
        if (error)
@@ -1394,14 +1361,25 @@ longform_dir2_rebuild(
                        error);
 
        /* free all data, leaf, node and freespace blocks */
-       error = -libxfs_bunmapi(tp, ip, 0, lastblock, XFS_BMAPI_METADATA, 0,
-                               &firstblock, &dfops, &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);
        if (error) {
@@ -1409,10 +1387,10 @@ longform_dir2_rebuild(
                goto out_bmap_cancel;
        }
 
-       libxfs_defer_ijoin(&dfops, ip);
-       error = -libxfs_defer_finish(&tp, &dfops);
-
-       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;
@@ -1434,9 +1412,8 @@ longform_dir2_rebuild(
 
                libxfs_trans_ijoin(tp, ip, 0);
 
-               libxfs_defer_init(&dfops, &firstblock);
                error = -libxfs_dir_createname(tp, ip, &p->name, p->inum,
-                                               &firstblock, nres);
+                                               nres);
                if (error) {
                        do_warn(
 _("name create failed in ino %" PRIu64 " (%d), filesystem may be out of space\n"),
@@ -1444,22 +1421,15 @@ _("name create failed in ino %" PRIu64 " (%d), filesystem may be out of space\n"
                        goto out_bmap_cancel;
                }
 
-               libxfs_defer_ijoin(&dfops, ip);
-               error = -libxfs_defer_finish(&tp, &dfops);
-               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_defer_cancel(&dfops);
        libxfs_trans_cancel(tp);
        return;
 }
@@ -1478,8 +1448,6 @@ dir2_kill_block(
 {
        xfs_da_args_t   args;
        int             error;
-       xfs_fsblock_t   firstblock;
-       struct xfs_defer_ops    dfops;
        int             nres;
        xfs_trans_t     *tp;
 
@@ -1490,11 +1458,8 @@ dir2_kill_block(
        libxfs_trans_ijoin(tp, ip, 0);
        libxfs_trans_bjoin(tp, bp);
        memset(&args, 0, sizeof(args));
-       libxfs_defer_init(&dfops, &firstblock);
        args.dp = ip;
        args.trans = tp;
-       args.firstblock = &firstblock;
-       args.dfops = &dfops;
        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)
@@ -1505,9 +1470,10 @@ dir2_kill_block(
        if (error)
                do_error(_("shrink_inode failed inode %" PRIu64 " block %u\n"),
                        ip->i_ino, da_bno);
-       libxfs_defer_ijoin(&dfops, ip);
-       libxfs_defer_finish(&tp, &dfops);
-       libxfs_trans_commit(tp);
+       error = -libxfs_trans_commit(tp);
+       if (error)
+               do_error(
+_("directory shrink failed (%d)\n"), error);
 }
 
 /*
@@ -1539,8 +1505,6 @@ longform_dir2_entry_check_data(
        struct xfs_dir2_data_free *bf;
        char                    *endptr;
        int                     error;
-       xfs_fsblock_t           firstblock;
-       struct xfs_defer_ops            dfops;
        char                    fname[MAXNAMELEN + 1];
        freetab_t               *freetab;
        int                     i;
@@ -1682,7 +1646,6 @@ longform_dir2_entry_check_data(
        libxfs_trans_ijoin(tp, ip, 0);
        libxfs_trans_bjoin(tp, bp);
        libxfs_trans_bhold(tp, bp);
-       libxfs_defer_init(&dfops, &firstblock);
        if (be32_to_cpu(d->magic) != wantmagic) {
                do_warn(
        _("bad directory block magic # %#x for directory inode %" PRIu64 " block %d: "),
@@ -1983,9 +1946,10 @@ _("entry \"%s\" in dir inode %" PRIu64 " inconsistent with .. value (%" PRIu64 "
                                d, &i);
        if (needlog)
                libxfs_dir2_data_log_header(&da, bp);
-       libxfs_defer_ijoin(&dfops, ip);
-       libxfs_defer_finish(&tp, &dfops);
-       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);
@@ -2391,6 +2355,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*));
@@ -2398,6 +2364,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)
@@ -2900,8 +2869,6 @@ process_dir_inode(
        int                     ino_offset)
 {
        xfs_ino_t               ino;
-       struct xfs_defer_ops            dfops;
-       xfs_fsblock_t           first;
        xfs_inode_t             *ip;
        xfs_trans_t             *tp;
        dir_hash_tab_t          *hashtab;
@@ -3003,7 +2970,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);
                        }
@@ -3037,20 +3006,17 @@ process_dir_inode(
 
                libxfs_trans_ijoin(tp, ip, 0);
 
-               libxfs_defer_init(&dfops, &first);
-
                error = -libxfs_dir_createname(tp, ip, &xfs_name_dotdot,
-                                       ip->i_ino, &first, 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);
-
-               libxfs_defer_ijoin(&dfops, ip);
-               error = -libxfs_defer_finish(&tp, &dfops);
-               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)  {
@@ -3095,24 +3061,21 @@ process_dir_inode(
 
                        libxfs_trans_ijoin(tp, ip, 0);
 
-                       libxfs_defer_init(&dfops, &first);
-
                        error = -libxfs_dir_createname(tp, ip, &xfs_name_dot,
-                                       ip->i_ino, &first, 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);
-
-                       libxfs_defer_ijoin(&dfops, ip);
-                       error = -libxfs_defer_finish(&tp, &dfops);
-                       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);
 }
 
 /*