@@ -88,6 +88,7 @@ struct iomap;
#include "xfs_rtbitmap.h"
#include "xfs_rtgroup.h"
#include "xfs_rtrmap_btree.h"
+#include "xfs_ag_resv.h"
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
@@ -3813,10 +3813,43 @@ reset_rt_metadata_inodes(
}
}
+static int
+reserve_ag_blocks(
+ struct xfs_mount *mp)
+{
+ struct xfs_perag *pag;
+ xfs_agnumber_t agno;
+ int error = 0;
+ int err2;
+
+ mp->m_finobt_nores = false;
+
+ for_each_perag(mp, agno, pag) {
+ err2 = -libxfs_ag_resv_init(pag, NULL);
+ if (err2 && !error)
+ error = err2;
+ }
+
+ return error;
+}
+
+static void
+unreserve_ag_blocks(
+ struct xfs_mount *mp)
+{
+ struct xfs_perag *pag;
+ xfs_agnumber_t agno;
+
+ for_each_perag(mp, agno, pag)
+ libxfs_ag_resv_free(pag);
+}
+
void
phase6(xfs_mount_t *mp)
{
ino_tree_node_t *irec;
+ bool reserve_perag;
+ int error;
int i;
orphanage_ino = 0;
@@ -3854,6 +3887,17 @@ phase6(xfs_mount_t *mp)
do_warn(_("would reinitialize metadata root directory\n"));
}
+ reserve_perag = xfs_has_realtime(mp) && !no_modify;
+ if (reserve_perag) {
+ error = reserve_ag_blocks(mp);
+ if (error) {
+ if (error != ENOSPC)
+ do_warn(
+ _("could not reserve per-AG space to rebuild realtime metadata"));
+ reserve_perag = false;
+ }
+ }
+
if (need_rbmino) {
if (!no_modify) {
if (need_rbmino > 0)
@@ -3892,6 +3936,9 @@ _(" - resetting contents of realtime bitmap and summary inodes\n"));
}
}
+ if (reserve_perag)
+ unreserve_ag_blocks(mp);
+
reattach_metadir_quota_inodes(mp);
mark_standalone_inodes(mp);