diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h
index 626c79f..b30228d 100644
--- a/libxfs/libxfs_api_defs.h
+++ b/libxfs/libxfs_api_defs.h
@@ -136,5 +136,6 @@
 #define xfs_perag_put			libxfs_perag_put
 #define xfs_prealloc_blocks		libxfs_prealloc_blocks
 #define xfs_dinode_good_version		libxfs_dinode_good_version
+#define xfs_free_extent			libxfs_free_extent
 
 #endif /* __LIBXFS_API_DEFS_H__ */
diff --git a/repair/phase5.c b/repair/phase5.c
index 28aaefe..f7c86d8 100644
--- a/repair/phase5.c
+++ b/repair/phase5.c
@@ -1708,15 +1708,17 @@ build_agf_agfl(
 	struct bt_status	*bcnt_bt,
 	xfs_extlen_t		freeblks,	/* # free blocks in tree */
 	int			lostblocks,	/* # blocks that will be lost */
-	struct bt_status	*rmap_bt)
+	struct bt_status	*rmap_bt,
+	struct xfs_slab		*lost_fsb)
 {
 	struct extent_tree_node	*ext_ptr;
 	struct xfs_buf		*agf_buf, *agfl_buf;
 	int			i;
-	int			j;
 	struct xfs_agfl		*agfl;
 	struct xfs_agf		*agf;
+	xfs_fsblock_t		fsb;
 	__be32			*freelist;
+	int			error;
 
 	agf_buf = libxfs_getbuf(mp->m_dev,
 			XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)),
@@ -1811,7 +1813,7 @@ build_agf_agfl(
 		/*
 		 * yes, now grab as many blocks as we can
 		 */
-		i = j = 0;
+		i = 0;
 		while (bno_bt->num_free_blocks > 0 && i < XFS_AGFL_SIZE(mp))  {
 			freelist[i] = cpu_to_be32(
 					get_next_blockaddr(agno, 0, bno_bt));
@@ -1826,24 +1828,21 @@ build_agf_agfl(
 		/*
 		 * now throw the rest of the blocks away and complain
 		 */
-		while (bno_bt->num_free_blocks > 0)  {
-			(void) get_next_blockaddr(agno, 0, bno_bt);
-			j++;
-		}
-		while (bcnt_bt->num_free_blocks > 0)  {
-			(void) get_next_blockaddr(agno, 0, bcnt_bt);
-			j++;
+		while (bno_bt->num_free_blocks > 0) {
+			fsb = XFS_AGB_TO_FSB(mp, agno,
+					get_next_blockaddr(agno, 0, bno_bt));
+			error = slab_add(lost_fsb, &fsb);
+			if (error)
+				do_error(
+_("Insufficient memory saving lost blocks.\n"));
 		}
-
-		if (j > 0)  {
-			if (j == lostblocks)
-				do_warn(_("lost %d blocks in ag %u\n"),
-					j, agno);
-			else
-				do_warn(_("thought we were going to lose %d "
-					  "blocks in ag %u, actually lost "
-					  "%d\n"),
-					lostblocks, j, agno);
+		while (bcnt_bt->num_free_blocks > 0) {
+			fsb = XFS_AGB_TO_FSB(mp, agno,
+					get_next_blockaddr(agno, 0, bcnt_bt));
+			error = slab_add(lost_fsb, &fsb);
+			if (error)
+				do_error(
+_("Insufficient memory saving lost blocks.\n"));
 		}
 
 		agf->agf_flfirst = 0;
@@ -1927,7 +1926,8 @@ keep_fsinos(xfs_mount_t *mp)
 static void
 phase5_func(
 	xfs_mount_t	*mp,
-	xfs_agnumber_t	agno)
+	xfs_agnumber_t	agno,
+	struct xfs_slab	*lost_fsb)
 {
 	__uint64_t	num_inos;
 	__uint64_t	num_free_inos;
@@ -2045,11 +2045,8 @@ phase5_func(
 				? extra_blocks - XFS_AGFL_SIZE(mp)
 				: 0;
 
-		if (extra_blocks > 0)  {
-			do_warn(_("lost %d blocks in agno %d, sorry.\n"),
-				extra_blocks, agno);
+		if (extra_blocks > 0)
 			sb_fdblocks_ag[agno] -= extra_blocks;
-		}
 
 		bcnt_btree_curs = bno_btree_curs;
 
@@ -2098,7 +2095,7 @@ phase5_func(
 		 */
 		build_agf_agfl(mp, agno, &bno_btree_curs,
 				&bcnt_btree_curs, freeblks1, extra_blocks,
-				&rmap_btree_curs);
+				&rmap_btree_curs, lost_fsb);
 		/*
 		 * build inode allocation tree.
 		 */
@@ -2151,10 +2148,52 @@ _("unable to add AG %u reverse-mapping data to btree.\n"), agno);
 	PROG_RPT_INC(prog_rpt_done[agno], 1);
 }
 
+/* Inject lost blocks back into the filesystem. */
+static int
+inject_lost_blocks(
+	struct xfs_mount	*mp,
+	struct xfs_slab		*lost_fsbs)
+{
+	struct xfs_trans	*tp = NULL;
+	struct xfs_slab_cursor	*cur = NULL;
+	xfs_fsblock_t		*fsb;
+	struct xfs_trans_res	tres = {0};
+	struct xfs_owner_info	oinfo;
+	int			error;
+
+	libxfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_AG);
+	error = init_slab_cursor(lost_fsbs, NULL, &cur);
+	if (error)
+		return error;
+
+	while ((fsb = pop_slab_cursor(cur)) != NULL) {
+		error = -libxfs_trans_alloc(mp, &tres, 16, 0, 0, &tp);
+		if (error)
+			goto out_cancel;
+
+		error = -libxfs_free_extent(tp, *fsb, 1, &oinfo);
+		if (error)
+			goto out_cancel;
+
+		error = -libxfs_trans_commit(tp);
+		if (error)
+			goto out_cancel;
+		tp = NULL;
+	}
+
+out_cancel:
+	if (tp)
+		libxfs_trans_cancel(tp);
+	free_slab_cursor(&cur);
+	return error;
+}
+
 void
 phase5(xfs_mount_t *mp)
 {
+	struct xfs_slab		*lost_fsb;
 	xfs_agnumber_t		agno;
+	int			error;
 
 	do_log(_("Phase 5 - rebuild AG headers and trees...\n"));
 	set_progress_msg(PROG_FMT_REBUILD_AG, (__uint64_t )glob_agcount);
@@ -2195,8 +2234,12 @@ phase5(xfs_mount_t *mp)
 	if (sb_fdblocks_ag == NULL)
 		do_error(_("cannot alloc sb_fdblocks_ag buffers\n"));
 
+	error = init_slab(&lost_fsb, sizeof(xfs_fsblock_t));
+	if (error)
+		do_error(_("cannot alloc lost block slab\n"));
+
 	for (agno = 0; agno < mp->m_sb.sb_agcount; agno++)
-		phase5_func(mp, agno);
+		phase5_func(mp, agno, lost_fsb);
 
 	print_final_rpt();
 
@@ -2224,6 +2267,11 @@ phase5(xfs_mount_t *mp)
 	 */
 	sync_sb(mp);
 
+	error = inject_lost_blocks(mp, lost_fsb);
+	if (error)
+		do_error(_("Unable to reinsert lost blocks into filesystem.\n"));
+	free_slab(&lost_fsb);
+
 	bad_ino_btree = 0;
 
 }
