1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3 * Copyright (c) 2018-2024 Oracle. All Rights Reserved.
4 * Author: Darrick J. Wong <djwong@kernel.org>
5 */
6 #ifndef __XFS_RTRMAP_BTREE_H__
7 #define __XFS_RTRMAP_BTREE_H__
8
9 struct xfs_buf;
10 struct xfs_btree_cur;
11 struct xfs_mount;
12 struct xbtree_ifakeroot;
13 struct xfs_rtgroup;
14 struct xfbtree;
15
16 /* rmaps only exist on crc enabled filesystems */
17 #define XFS_RTRMAP_BLOCK_LEN XFS_BTREE_LBLOCK_CRC_LEN
18
19 struct xfs_btree_cur *xfs_rtrmapbt_init_cursor(struct xfs_trans *tp,
20 struct xfs_rtgroup *rtg);
21 struct xfs_btree_cur *xfs_rtrmapbt_stage_cursor(struct xfs_mount *mp,
22 struct xfs_rtgroup *rtg, struct xfs_inode *ip,
23 struct xbtree_ifakeroot *ifake);
24 void xfs_rtrmapbt_commit_staged_btree(struct xfs_btree_cur *cur,
25 struct xfs_trans *tp);
26 unsigned int xfs_rtrmapbt_maxrecs(struct xfs_mount *mp, unsigned int blocklen,
27 bool leaf);
28 void xfs_rtrmapbt_compute_maxlevels(struct xfs_mount *mp);
29 unsigned int xfs_rtrmapbt_droot_maxrecs(unsigned int blocklen, bool leaf);
30
31 /*
32 * Addresses of records, keys, and pointers within an incore rtrmapbt block.
33 *
34 * (note that some of these may appear unused, but they are used in userspace)
35 */
36 static inline struct xfs_rmap_rec *
xfs_rtrmap_rec_addr(struct xfs_btree_block * block,unsigned int index)37 xfs_rtrmap_rec_addr(
38 struct xfs_btree_block *block,
39 unsigned int index)
40 {
41 return (struct xfs_rmap_rec *)
42 ((char *)block + XFS_RTRMAP_BLOCK_LEN +
43 (index - 1) * sizeof(struct xfs_rmap_rec));
44 }
45
46 static inline struct xfs_rmap_key *
xfs_rtrmap_key_addr(struct xfs_btree_block * block,unsigned int index)47 xfs_rtrmap_key_addr(
48 struct xfs_btree_block *block,
49 unsigned int index)
50 {
51 return (struct xfs_rmap_key *)
52 ((char *)block + XFS_RTRMAP_BLOCK_LEN +
53 (index - 1) * 2 * sizeof(struct xfs_rmap_key));
54 }
55
56 static inline struct xfs_rmap_key *
xfs_rtrmap_high_key_addr(struct xfs_btree_block * block,unsigned int index)57 xfs_rtrmap_high_key_addr(
58 struct xfs_btree_block *block,
59 unsigned int index)
60 {
61 return (struct xfs_rmap_key *)
62 ((char *)block + XFS_RTRMAP_BLOCK_LEN +
63 sizeof(struct xfs_rmap_key) +
64 (index - 1) * 2 * sizeof(struct xfs_rmap_key));
65 }
66
67 static inline xfs_rtrmap_ptr_t *
xfs_rtrmap_ptr_addr(struct xfs_btree_block * block,unsigned int index,unsigned int maxrecs)68 xfs_rtrmap_ptr_addr(
69 struct xfs_btree_block *block,
70 unsigned int index,
71 unsigned int maxrecs)
72 {
73 return (xfs_rtrmap_ptr_t *)
74 ((char *)block + XFS_RTRMAP_BLOCK_LEN +
75 maxrecs * 2 * sizeof(struct xfs_rmap_key) +
76 (index - 1) * sizeof(xfs_rtrmap_ptr_t));
77 }
78
79 unsigned int xfs_rtrmapbt_maxlevels_ondisk(void);
80
81 int __init xfs_rtrmapbt_init_cur_cache(void);
82 void xfs_rtrmapbt_destroy_cur_cache(void);
83
84 xfs_filblks_t xfs_rtrmapbt_calc_reserves(struct xfs_mount *mp);
85
86 /* Addresses of key, pointers, and records within an ondisk rtrmapbt block. */
87
88 static inline struct xfs_rmap_rec *
xfs_rtrmap_droot_rec_addr(struct xfs_rtrmap_root * block,unsigned int index)89 xfs_rtrmap_droot_rec_addr(
90 struct xfs_rtrmap_root *block,
91 unsigned int index)
92 {
93 return (struct xfs_rmap_rec *)
94 ((char *)(block + 1) +
95 (index - 1) * sizeof(struct xfs_rmap_rec));
96 }
97
98 static inline struct xfs_rmap_key *
xfs_rtrmap_droot_key_addr(struct xfs_rtrmap_root * block,unsigned int index)99 xfs_rtrmap_droot_key_addr(
100 struct xfs_rtrmap_root *block,
101 unsigned int index)
102 {
103 return (struct xfs_rmap_key *)
104 ((char *)(block + 1) +
105 (index - 1) * 2 * sizeof(struct xfs_rmap_key));
106 }
107
108 static inline xfs_rtrmap_ptr_t *
xfs_rtrmap_droot_ptr_addr(struct xfs_rtrmap_root * block,unsigned int index,unsigned int maxrecs)109 xfs_rtrmap_droot_ptr_addr(
110 struct xfs_rtrmap_root *block,
111 unsigned int index,
112 unsigned int maxrecs)
113 {
114 return (xfs_rtrmap_ptr_t *)
115 ((char *)(block + 1) +
116 maxrecs * 2 * sizeof(struct xfs_rmap_key) +
117 (index - 1) * sizeof(xfs_rtrmap_ptr_t));
118 }
119
120 /*
121 * Address of pointers within the incore btree root.
122 *
123 * These are to be used when we know the size of the block and
124 * we don't have a cursor.
125 */
126 static inline xfs_rtrmap_ptr_t *
xfs_rtrmap_broot_ptr_addr(struct xfs_mount * mp,struct xfs_btree_block * bb,unsigned int index,unsigned int block_size)127 xfs_rtrmap_broot_ptr_addr(
128 struct xfs_mount *mp,
129 struct xfs_btree_block *bb,
130 unsigned int index,
131 unsigned int block_size)
132 {
133 return xfs_rtrmap_ptr_addr(bb, index,
134 xfs_rtrmapbt_maxrecs(mp, block_size, false));
135 }
136
137 /*
138 * Compute the space required for the incore btree root containing the given
139 * number of records.
140 */
141 static inline size_t
xfs_rtrmap_broot_space_calc(struct xfs_mount * mp,unsigned int level,unsigned int nrecs)142 xfs_rtrmap_broot_space_calc(
143 struct xfs_mount *mp,
144 unsigned int level,
145 unsigned int nrecs)
146 {
147 size_t sz = XFS_RTRMAP_BLOCK_LEN;
148
149 if (level > 0)
150 return sz + nrecs * (2 * sizeof(struct xfs_rmap_key) +
151 sizeof(xfs_rtrmap_ptr_t));
152 return sz + nrecs * sizeof(struct xfs_rmap_rec);
153 }
154
155 /*
156 * Compute the space required for the incore btree root given the ondisk
157 * btree root block.
158 */
159 static inline size_t
xfs_rtrmap_broot_space(struct xfs_mount * mp,struct xfs_rtrmap_root * bb)160 xfs_rtrmap_broot_space(struct xfs_mount *mp, struct xfs_rtrmap_root *bb)
161 {
162 return xfs_rtrmap_broot_space_calc(mp, be16_to_cpu(bb->bb_level),
163 be16_to_cpu(bb->bb_numrecs));
164 }
165
166 /* Compute the space required for the ondisk root block. */
167 static inline size_t
xfs_rtrmap_droot_space_calc(unsigned int level,unsigned int nrecs)168 xfs_rtrmap_droot_space_calc(
169 unsigned int level,
170 unsigned int nrecs)
171 {
172 size_t sz = sizeof(struct xfs_rtrmap_root);
173
174 if (level > 0)
175 return sz + nrecs * (2 * sizeof(struct xfs_rmap_key) +
176 sizeof(xfs_rtrmap_ptr_t));
177 return sz + nrecs * sizeof(struct xfs_rmap_rec);
178 }
179
180 /*
181 * Compute the space required for the ondisk root block given an incore root
182 * block.
183 */
184 static inline size_t
xfs_rtrmap_droot_space(struct xfs_btree_block * bb)185 xfs_rtrmap_droot_space(struct xfs_btree_block *bb)
186 {
187 return xfs_rtrmap_droot_space_calc(be16_to_cpu(bb->bb_level),
188 be16_to_cpu(bb->bb_numrecs));
189 }
190
191 int xfs_iformat_rtrmap(struct xfs_inode *ip, struct xfs_dinode *dip);
192 void xfs_rtrmapbt_to_disk(struct xfs_mount *mp, struct xfs_btree_block *rblock,
193 unsigned int rblocklen, struct xfs_rtrmap_root *dblock,
194 unsigned int dblocklen);
195 void xfs_iflush_rtrmap(struct xfs_inode *ip, struct xfs_dinode *dip);
196
197 int xfs_rtrmapbt_create(struct xfs_rtgroup *rtg, struct xfs_inode *ip,
198 struct xfs_trans *tp, bool init);
199 int xfs_rtrmapbt_init_rtsb(struct xfs_mount *mp, struct xfs_rtgroup *rtg,
200 struct xfs_trans *tp);
201
202 unsigned long long xfs_rtrmapbt_calc_size(struct xfs_mount *mp,
203 unsigned long long len);
204
205 struct xfs_btree_cur *xfs_rtrmapbt_mem_cursor(struct xfs_rtgroup *rtg,
206 struct xfs_trans *tp, struct xfbtree *xfbtree);
207 int xfs_rtrmapbt_mem_init(struct xfs_mount *mp, struct xfbtree *xfbtree,
208 struct xfs_buftarg *btp, xfs_rgnumber_t rgno);
209
210 #endif /* __XFS_RTRMAP_BTREE_H__ */
211