summaryrefslogtreecommitdiffstats
path: root/fs/xfs/libxfs
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2024-11-20 16:20:28 -0800
committerDarrick J. Wong <djwong@kernel.org>2024-12-23 13:06:05 -0800
commit8491a55cfc73ff5c2c637a70ade51d4d08abb90a (patch)
tree9073d76fe8600954e51c6b6d44b1b5692738b3d2 /fs/xfs/libxfs
parent6b08901a6e8fcda555f3ad39abd73bb0dd37f231 (diff)
downloadlinux-8491a55cfc73ff5c2c637a70ade51d4d08abb90a.tar.gz
linux-8491a55cfc73ff5c2c637a70ade51d4d08abb90a.tar.bz2
linux-8491a55cfc73ff5c2c637a70ade51d4d08abb90a.zip
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> Reviewed-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'fs/xfs/libxfs')
-rw-r--r--fs/xfs/libxfs/xfs_rtrmap_btree.c41
-rw-r--r--fs/xfs/libxfs/xfs_rtrmap_btree.h2
2 files changed, 43 insertions, 0 deletions
diff --git a/fs/xfs/libxfs/xfs_rtrmap_btree.c b/fs/xfs/libxfs/xfs_rtrmap_btree.c
index 22aabf326b2c..066deadcaac9 100644
--- a/fs/xfs/libxfs/xfs_rtrmap_btree.c
+++ b/fs/xfs/libxfs/xfs_rtrmap_btree.c
@@ -540,3 +540,44 @@ xfs_rtrmapbt_compute_maxlevels(
/* Add one level to handle the inode root level. */
mp->m_rtrmap_maxlevels = 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)
+{
+ uint32_t blocks = mp->m_groups[XG_TYPE_RTG].blocks;
+
+ if (!xfs_has_rtrmapbt(mp))
+ return 0;
+
+ /* Reserve 1% of the rtgroup or enough for 1 block per record. */
+ return max_t(xfs_filblks_t, blocks / 100,
+ xfs_rtrmapbt_max_size(mp, blocks));
+}
diff --git a/fs/xfs/libxfs/xfs_rtrmap_btree.h b/fs/xfs/libxfs/xfs_rtrmap_btree.h
index 7d1a3a49a2d6..eaa2942297e2 100644
--- a/fs/xfs/libxfs/xfs_rtrmap_btree.h
+++ b/fs/xfs/libxfs/xfs_rtrmap_btree.h
@@ -79,4 +79,6 @@ unsigned int xfs_rtrmapbt_maxlevels_ondisk(void);
int __init xfs_rtrmapbt_init_cur_cache(void);
void xfs_rtrmapbt_destroy_cur_cache(void);
+xfs_filblks_t xfs_rtrmapbt_calc_reserves(struct xfs_mount *mp);
+
#endif /* __XFS_RTRMAP_BTREE_H__ */