summaryrefslogtreecommitdiff
path: root/fs/xfs/libxfs/xfs_btree.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/libxfs/xfs_btree.c')
-rw-r--r--fs/xfs/libxfs/xfs_btree.c100
1 files changed, 100 insertions, 0 deletions
diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c
index b610f2f97687..31826a4c98f0 100644
--- a/fs/xfs/libxfs/xfs_btree.c
+++ b/fs/xfs/libxfs/xfs_btree.c
@@ -29,6 +29,14 @@
*/
kmem_zone_t *xfs_btree_cur_zone;
+struct xfs_btree_cur_cache {
+ const char *name;
+ unsigned short maxlevels;
+ bool alias;
+};
+
+static struct xfs_btree_cur_cache xfs_btree_cur_caches[XFS_BTNUM_MAX];
+
/*
* Btree magic numbers.
*/
@@ -5332,3 +5340,95 @@ 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 /only/ on V5 or newer
+ * filesystems.
+ */
+void __init
+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);
+}
+
+/* Set up a btree cursor cache for a given btree type. */
+int __init
+xfs_btree_create_cursor_cache(
+ xfs_btnum_t btnum,
+ const char *name,
+ unsigned int maxlevels)
+{
+ struct xfs_btree_cur_cache *cc;
+
+ cc = &xfs_btree_cur_caches[btnum];
+
+ ASSERT(cc->maxlevels == 0);
+
+ cc->name = name;
+ cc->maxlevels = maxlevels;
+ cc->alias = false;
+
+ return 0;
+}
+
+/* Set up a btree cursor cache to reuse the cache of another btree type. */
+int __init
+xfs_btree_alias_cursor_cache(
+ xfs_btnum_t btnum,
+ xfs_btnum_t src)
+{
+ struct xfs_btree_cur_cache *cd;
+ const struct xfs_btree_cur_cache *cs;
+
+
+ cd = &xfs_btree_cur_caches[btnum];
+ cs = &xfs_btree_cur_caches[src];
+
+ ASSERT(cd->maxlevels == 0);
+ ASSERT(cs->maxlevels > 0);
+
+ cd->name = cs->name;
+ cd->maxlevels = cs->maxlevels;
+ cd->alias = true;
+
+ return 0;
+}
+
+/* Return the maximum possible height for a given type of btree. */
+unsigned int
+xfs_btree_absolute_maxlevels(
+ xfs_btnum_t btnum)
+{
+ return xfs_btree_cur_caches[btnum].maxlevels;
+}