summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2021-09-01 11:16:50 -0700
committerDarrick J. Wong <djwong@kernel.org>2021-10-22 16:41:01 -0700
commit4fa05698d8e2fa78a393b1c679bac040e0201472 (patch)
treea2c315b54b88f5bc7307fc328282fe549d916f06 /fs
parent05223314efccc32d9f635f80fad3cc63d78015ee (diff)
xfs: add metadata reservations for realtime rmap btrees
Reserve some free blocks so that we will always have enough free blocks in the data volume to handle expansion of the realtime rmap btree. Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/libxfs/xfs_rtrmap_btree.c39
-rw-r--r--fs/xfs/libxfs/xfs_rtrmap_btree.h1
-rw-r--r--fs/xfs/xfs_rtalloc.c7
3 files changed, 46 insertions, 1 deletions
diff --git a/fs/xfs/libxfs/xfs_rtrmap_btree.c b/fs/xfs/libxfs/xfs_rtrmap_btree.c
index 04fb5f4de1aa..02550b9a2011 100644
--- a/fs/xfs/libxfs/xfs_rtrmap_btree.c
+++ b/fs/xfs/libxfs/xfs_rtrmap_btree.c
@@ -508,3 +508,42 @@ xfs_rtrmapbt_compute_maxlevels(
/* Add one level to handle the inode root level. */
return min(d_maxlevels, r_maxlevels) + 1;
}
+
+/* Calculate the rtrmap btree size for some records. */
+static unsigned long long
+xfs_rtrmapbt_calc_size(
+ struct xfs_mount *mp,
+ unsigned long long len)
+{
+ return xfs_btree_calc_size(mp->m_rtrmap_mnr, len);
+}
+
+/*
+ * Calculate the maximum rmap btree size.
+ */
+static unsigned long long
+xfs_rtrmapbt_max_size(
+ struct xfs_mount *mp,
+ xfs_rtblock_t rtblocks)
+{
+ /* Bail out if we're uninitialized, which can happen in mkfs. */
+ if (mp->m_rtrmap_mxr[0] == 0)
+ return 0;
+
+ return xfs_rtrmapbt_calc_size(mp, rtblocks);
+}
+
+/*
+ * Figure out how many blocks to reserve and how many are used by this btree.
+ */
+xfs_filblks_t
+xfs_rtrmapbt_calc_reserves(
+ struct xfs_mount *mp)
+{
+ if (!xfs_has_rtrmapbt(mp))
+ return 0;
+
+ /* 1/64th (~1.5%) of the space, and enough for 1 record per block. */
+ return max(mp->m_sb.sb_rblocks >> 6,
+ xfs_rtrmapbt_max_size(mp, mp->m_sb.sb_rblocks));
+}
diff --git a/fs/xfs/libxfs/xfs_rtrmap_btree.h b/fs/xfs/libxfs/xfs_rtrmap_btree.h
index 0ab5e62fc9a8..151020cdf09a 100644
--- a/fs/xfs/libxfs/xfs_rtrmap_btree.h
+++ b/fs/xfs/libxfs/xfs_rtrmap_btree.h
@@ -74,5 +74,6 @@ xfs_rtrmap_ptr_addr(
}
int __init xfs_rtrmapbt_create_cursor_cache(void);
+xfs_filblks_t xfs_rtrmapbt_calc_reserves(struct xfs_mount *mp);
#endif /* __XFS_RTRMAP_BTREE_H__ */
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index edf4bdefe36e..ce135c2e2054 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -25,6 +25,7 @@
#include "xfs_imeta.h"
#include "xfs_quota.h"
#include "xfs_error.h"
+#include "xfs_rtrmap_btree.h"
/*
* Read and return the summary information for a given extent size,
@@ -1298,6 +1299,7 @@ void
xfs_rt_resv_free(
struct xfs_mount *mp)
{
+ xfs_imeta_resv_free_inode(mp, mp->m_rrmapip);
}
/* Reserve space for rt metadata inodes' space expansion. */
@@ -1305,7 +1307,10 @@ int
xfs_rt_resv_init(
struct xfs_mount *mp)
{
- return 0;
+ xfs_filblks_t ask;
+
+ ask = xfs_rtrmapbt_calc_reserves(mp);
+ return xfs_imeta_resv_init_inode(mp, mp->m_rrmapip, ask);
}
/*