summaryrefslogtreecommitdiff
path: root/fs/xfs/libxfs/xfs_btree.c
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2021-09-23 10:32:06 -0700
committerDarrick J. Wong <djwong@kernel.org>2021-09-23 18:20:31 -0700
commitc0ef00d1e835bfd24399aaa069b2b608dd60b485 (patch)
tree74ff1eab8a9c47a1db95799eea6d6024c28c4171 /fs/xfs/libxfs/xfs_btree.c
parent02f8e763f1da078cc23d5f7cc4310f015c939645 (diff)
xfs: check absolute maximum nlevels for each btree type
Add code for all five btree types so that we can compute the absolute maximum possible btree height for each btree type, and then check that none of them exceed XFS_BTREE_CUR_ZONE_MAXLEVELS. The code to do the actual checking is a little excessive, but it sets us up for per-type cursor zones in the next patch. Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Diffstat (limited to 'fs/xfs/libxfs/xfs_btree.c')
-rw-r--r--fs/xfs/libxfs/xfs_btree.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c
index 619319ff41e5..120280c998f8 100644
--- a/fs/xfs/libxfs/xfs_btree.c
+++ b/fs/xfs/libxfs/xfs_btree.c
@@ -27,6 +27,13 @@
* Cursor allocation zone.
*/
kmem_zone_t *xfs_btree_cur_zone;
+struct xfs_btree_cur_zone xfs_btree_cur_zones[XFS_BTNUM_MAX] = {
+ [XFS_BTNUM_BNO] = { .name = "xfs_alloc_btree_cur" },
+ [XFS_BTNUM_INO] = { .name = "xfs_ialloc_btree_cur" },
+ [XFS_BTNUM_RMAP] = { .name = "xfs_rmap_btree_cur" },
+ [XFS_BTNUM_REFC] = { .name = "xfs_refc_btree_cur" },
+ [XFS_BTNUM_BMAP] = { .name = "xfs_bmap_btree_cur" },
+};
/*
* Btree magic numbers.
@@ -5027,3 +5034,44 @@ xfs_btree_alloc_cursor(
return cur;
}
+
+/*
+ * Compute absolute minrecs for leaf and node btree blocks. Callers should set
+ * BTREE_LONG_PTRS and BTREE_OVERLAPPING as they would for regular cursors.
+ * Set BTREE_CRC_BLOCKS if the btree type is supported on V5 or newer
+ * filesystems.
+ */
+void
+xfs_btree_absolute_minrecs(
+ unsigned int *minrecs,
+ unsigned int bc_flags,
+ unsigned int leaf_recbytes,
+ unsigned int node_recbytes)
+{
+ unsigned int min_recbytes;
+
+ /*
+ * If this btree type is supported on V4, we use the smaller V4 min
+ * block size along with the V4 header size. If the btree type is only
+ * supported on V5, use the (twice as large) V5 min block size along
+ * with the V5 header size.
+ */
+ if (!(bc_flags & XFS_BTREE_CRC_BLOCKS)) {
+ if (bc_flags & XFS_BTREE_LONG_PTRS)
+ min_recbytes = XFS_MIN_BLOCKSIZE -
+ XFS_BTREE_LBLOCK_LEN;
+ else
+ min_recbytes = XFS_MIN_BLOCKSIZE -
+ XFS_BTREE_SBLOCK_LEN;
+ } else if (bc_flags & XFS_BTREE_LONG_PTRS) {
+ min_recbytes = XFS_MIN_CRC_BLOCKSIZE - XFS_BTREE_LBLOCK_CRC_LEN;
+ } else {
+ min_recbytes = XFS_MIN_CRC_BLOCKSIZE - XFS_BTREE_SBLOCK_CRC_LEN;
+ }
+
+ if (bc_flags & XFS_BTREE_OVERLAPPING)
+ node_recbytes <<= 1;
+
+ minrecs[0] = min_recbytes / (2 * leaf_recbytes);
+ minrecs[1] = min_recbytes / (2 * node_recbytes);
+}