diff options
author | Darrick J. Wong <djwong@kernel.org> | 2021-09-28 17:58:09 -0700 |
---|---|---|
committer | Darrick J. Wong <djwong@kernel.org> | 2021-10-22 16:41:16 -0700 |
commit | c0f26249c5af3ed541cab86313f6ebaf62e7c9a3 (patch) | |
tree | aad6408ea3242554e57a1daf79de51cde207fd70 /fs/xfs/libxfs | |
parent | 610994091f8dbbb01483bd42abeae4ab7f941191 (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.c | 70 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_rtrmap_btree.h | 6 |
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__ */ |