summaryrefslogtreecommitdiff
path: root/fs/xfs/libxfs
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2021-09-28 17:58:09 -0700
committerDarrick J. Wong <djwong@kernel.org>2021-10-22 16:41:16 -0700
commitc0f26249c5af3ed541cab86313f6ebaf62e7c9a3 (patch)
treeaad6408ea3242554e57a1daf79de51cde207fd70 /fs/xfs/libxfs
parent610994091f8dbbb01483bd42abeae4ab7f941191 (diff)
xfs: create a shadow rmap btree during realtime rmap repair
Create an in-memory btree of rmap records instead of an array. This enables us to do live record collection instead of freezing the fs. Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Diffstat (limited to 'fs/xfs/libxfs')
-rw-r--r--fs/xfs/libxfs/xfs_rtrmap_btree.c70
-rw-r--r--fs/xfs/libxfs/xfs_rtrmap_btree.h6
2 files changed, 76 insertions, 0 deletions
diff --git a/fs/xfs/libxfs/xfs_rtrmap_btree.c b/fs/xfs/libxfs/xfs_rtrmap_btree.c
index a1584784991e..29de9bfbde20 100644
--- a/fs/xfs/libxfs/xfs_rtrmap_btree.c
+++ b/fs/xfs/libxfs/xfs_rtrmap_btree.c
@@ -18,6 +18,7 @@
#include "xfs_alloc.h"
#include "xfs_btree.h"
#include "xfs_btree_staging.h"
+#include "xfs_btree_mem.h"
#include "xfs_rmap.h"
#include "xfs_rtrmap_btree.h"
#include "xfs_trace.h"
@@ -499,6 +500,75 @@ xfs_rtrmapbt_stage_cursor(
return cur;
}
+STATIC int
+xfs_rtrmapbt_get_mem_minrecs(
+ struct xfs_btree_cur *cur,
+ int level)
+{
+ return cur->bc_mp->m_rtrmap_mnr[level != 0];
+}
+
+STATIC int
+xfs_rtrmapbt_get_mem_maxrecs(
+ struct xfs_btree_cur *cur,
+ int level)
+{
+ return cur->bc_mp->m_rtrmap_mxr[level != 0];
+}
+
+static const struct xfs_btree_ops xfs_rtrmapbt_mem_ops = {
+ .rec_len = sizeof(struct xfs_rtrmap_rec),
+ .key_len = 2 * sizeof(struct xfs_rtrmap_key),
+
+ .dup_cursor = xfs_btree_mem_dup_cursor,
+ .set_root = xfs_btree_mem_set_root,
+ .alloc_block = xfbtree_alloc_block,
+ .free_block = xfbtree_free_block,
+ .get_minrecs = xfs_rtrmapbt_get_mem_minrecs,
+ .get_maxrecs = xfs_rtrmapbt_get_mem_maxrecs,
+ .init_key_from_rec = xfs_rtrmapbt_init_key_from_rec,
+ .init_high_key_from_rec = xfs_rtrmapbt_init_high_key_from_rec,
+ .init_rec_from_cur = xfs_rtrmapbt_init_rec_from_cur,
+ .init_ptr_from_cur = xfs_btree_mem_init_ptr_from_cur,
+ .key_diff = xfs_rtrmapbt_key_diff,
+ .buf_ops = &xfs_rtrmapbt_buf_ops,
+ .diff_two_keys = xfs_rtrmapbt_diff_two_keys,
+ .keys_inorder = xfs_rtrmapbt_keys_inorder,
+ .recs_inorder = xfs_rtrmapbt_recs_inorder,
+};
+
+/* Create a cursor for an in-memory btree. */
+struct xfs_btree_cur *
+xfs_rtrmapbt_mem_cursor(
+ struct xfs_mount *mp,
+ struct xfs_trans *tp,
+ struct xfs_buf *head_bp,
+ struct xfbtree *xfbtree)
+{
+ struct xfs_btree_cur *cur;
+
+ /* Overlapping btree; 2 keys per pointer. */
+ cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_RTRMAP);
+ cur->bc_flags = XFS_BTREE_CRC_BLOCKS | XFS_BTREE_OVERLAPPING |
+ XFS_BTREE_LONG_PTRS | XFS_BTREE_IN_MEMORY;
+ cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_rmap_2);
+ cur->bc_ops = &xfs_rtrmapbt_mem_ops;
+ cur->bc_mem.xfbtree = xfbtree;
+ cur->bc_mem.head_bp = head_bp;
+ cur->bc_nlevels = xfs_btree_mem_head_nlevels(head_bp);
+
+ return cur;
+}
+
+struct xfbtree *
+xfs_rtrmapbt_mem_create(
+ struct xfs_mount *mp,
+ const char *name)
+{
+ return xfbtree_create(mp, XFS_BTNUM_RTRMAP, &xfs_rtrmapbt_buf_ops,
+ XFBTREE_CREATE_LONG_PTRS, name);
+}
+
/*
* Install a new rt reverse mapping btree root. Caller is responsible for
* invalidating and freeing the old btree blocks.
diff --git a/fs/xfs/libxfs/xfs_rtrmap_btree.h b/fs/xfs/libxfs/xfs_rtrmap_btree.h
index d1ae7bc1d7e8..40226138413f 100644
--- a/fs/xfs/libxfs/xfs_rtrmap_btree.h
+++ b/fs/xfs/libxfs/xfs_rtrmap_btree.h
@@ -193,4 +193,10 @@ struct xfs_imeta_end;
int xfs_rtrmapbt_create(struct xfs_trans **tpp, struct xfs_imeta_end *ic,
struct xfs_inode **ipp);
+struct xfbtree;
+struct xfs_btree_cur *xfs_rtrmapbt_mem_cursor(struct xfs_mount *mp,
+ struct xfs_trans *tp, struct xfs_buf *mhead_bp,
+ struct xfbtree *xfbtree);
+struct xfbtree *xfs_rtrmapbt_mem_create(struct xfs_mount *mp, const char *name);
+
#endif /* __XFS_RTRMAP_BTREE_H__ */