1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3 * Copyright (c) 2022-2024 Oracle. All Rights Reserved.
4 * Author: Darrick J. Wong <djwong@kernel.org>
5 */
6 #ifndef __LIBXFS_RTGROUP_H
7 #define __LIBXFS_RTGROUP_H 1
8
9 #include "xfs_group.h"
10
11 struct xfs_mount;
12 struct xfs_trans;
13
14 enum xfs_rtg_inodes {
15 XFS_RTGI_BITMAP, /* allocation bitmap */
16 XFS_RTGI_SUMMARY, /* allocation summary */
17 XFS_RTGI_RMAP, /* rmap btree inode */
18 XFS_RTGI_REFCOUNT, /* refcount btree inode */
19
20 XFS_RTGI_MAX,
21 };
22
23 #ifdef MAX_LOCKDEP_SUBCLASSES
24 static_assert(XFS_RTGI_MAX <= MAX_LOCKDEP_SUBCLASSES);
25 #endif
26
27 /*
28 * Realtime group incore structure, similar to the per-AG structure.
29 */
30 struct xfs_rtgroup {
31 struct xfs_group rtg_group;
32
33 /* per-rtgroup metadata inodes */
34 struct xfs_inode *rtg_inodes[XFS_RTGI_MAX];
35
36 /* Number of blocks in this group */
37 xfs_rtxnum_t rtg_extents;
38
39 /*
40 * For bitmap based RT devices this points to a cache of rt summary
41 * level per bitmap block with the invariant that rtg_rsum_cache[bbno]
42 * > the maximum i for which rsum[i][bbno] != 0, or 0 if
43 * rsum[i][bbno] == 0 for all i.
44 * Reads and writes are serialized by the rsumip inode lock.
45 *
46 * For zoned RT devices this points to the open zone structure for
47 * a group that is open for writers, or is NULL.
48 */
49 union {
50 uint8_t *rtg_rsum_cache;
51 struct xfs_open_zone *rtg_open_zone;
52 };
53 };
54
55 /*
56 * For zoned RT devices this is set on groups that have no written blocks
57 * and can be picked by the allocator for opening.
58 */
59 #define XFS_RTG_FREE XA_MARK_0
60
61 /*
62 * For zoned RT devices this is set on groups that are fully written and that
63 * have unused blocks. Used by the garbage collection to pick targets.
64 */
65 #define XFS_RTG_RECLAIMABLE XA_MARK_1
66
to_rtg(struct xfs_group * xg)67 static inline struct xfs_rtgroup *to_rtg(struct xfs_group *xg)
68 {
69 return container_of(xg, struct xfs_rtgroup, rtg_group);
70 }
71
rtg_group(struct xfs_rtgroup * rtg)72 static inline struct xfs_group *rtg_group(struct xfs_rtgroup *rtg)
73 {
74 return &rtg->rtg_group;
75 }
76
rtg_mount(const struct xfs_rtgroup * rtg)77 static inline struct xfs_mount *rtg_mount(const struct xfs_rtgroup *rtg)
78 {
79 return rtg->rtg_group.xg_mount;
80 }
81
rtg_rgno(const struct xfs_rtgroup * rtg)82 static inline xfs_rgnumber_t rtg_rgno(const struct xfs_rtgroup *rtg)
83 {
84 return rtg->rtg_group.xg_gno;
85 }
86
rtg_blocks(const struct xfs_rtgroup * rtg)87 static inline xfs_rgblock_t rtg_blocks(const struct xfs_rtgroup *rtg)
88 {
89 return rtg->rtg_group.xg_block_count;
90 }
91
rtg_bitmap(const struct xfs_rtgroup * rtg)92 static inline struct xfs_inode *rtg_bitmap(const struct xfs_rtgroup *rtg)
93 {
94 return rtg->rtg_inodes[XFS_RTGI_BITMAP];
95 }
96
rtg_summary(const struct xfs_rtgroup * rtg)97 static inline struct xfs_inode *rtg_summary(const struct xfs_rtgroup *rtg)
98 {
99 return rtg->rtg_inodes[XFS_RTGI_SUMMARY];
100 }
101
rtg_rmap(const struct xfs_rtgroup * rtg)102 static inline struct xfs_inode *rtg_rmap(const struct xfs_rtgroup *rtg)
103 {
104 return rtg->rtg_inodes[XFS_RTGI_RMAP];
105 }
106
rtg_refcount(const struct xfs_rtgroup * rtg)107 static inline struct xfs_inode *rtg_refcount(const struct xfs_rtgroup *rtg)
108 {
109 return rtg->rtg_inodes[XFS_RTGI_REFCOUNT];
110 }
111
112 /* Passive rtgroup references */
113 static inline struct xfs_rtgroup *
xfs_rtgroup_get(struct xfs_mount * mp,xfs_rgnumber_t rgno)114 xfs_rtgroup_get(
115 struct xfs_mount *mp,
116 xfs_rgnumber_t rgno)
117 {
118 return to_rtg(xfs_group_get(mp, rgno, XG_TYPE_RTG));
119 }
120
121 static inline struct xfs_rtgroup *
xfs_rtgroup_hold(struct xfs_rtgroup * rtg)122 xfs_rtgroup_hold(
123 struct xfs_rtgroup *rtg)
124 {
125 return to_rtg(xfs_group_hold(rtg_group(rtg)));
126 }
127
128 static inline void
xfs_rtgroup_put(struct xfs_rtgroup * rtg)129 xfs_rtgroup_put(
130 struct xfs_rtgroup *rtg)
131 {
132 xfs_group_put(rtg_group(rtg));
133 }
134
135 /* Active rtgroup references */
136 static inline struct xfs_rtgroup *
xfs_rtgroup_grab(struct xfs_mount * mp,xfs_rgnumber_t rgno)137 xfs_rtgroup_grab(
138 struct xfs_mount *mp,
139 xfs_rgnumber_t rgno)
140 {
141 return to_rtg(xfs_group_grab(mp, rgno, XG_TYPE_RTG));
142 }
143
144 static inline void
xfs_rtgroup_rele(struct xfs_rtgroup * rtg)145 xfs_rtgroup_rele(
146 struct xfs_rtgroup *rtg)
147 {
148 xfs_group_rele(rtg_group(rtg));
149 }
150
151 static inline struct xfs_rtgroup *
xfs_rtgroup_next_range(struct xfs_mount * mp,struct xfs_rtgroup * rtg,xfs_rgnumber_t start_rgno,xfs_rgnumber_t end_rgno)152 xfs_rtgroup_next_range(
153 struct xfs_mount *mp,
154 struct xfs_rtgroup *rtg,
155 xfs_rgnumber_t start_rgno,
156 xfs_rgnumber_t end_rgno)
157 {
158 return to_rtg(xfs_group_next_range(mp, rtg ? rtg_group(rtg) : NULL,
159 start_rgno, end_rgno, XG_TYPE_RTG));
160 }
161
162 static inline struct xfs_rtgroup *
xfs_rtgroup_next(struct xfs_mount * mp,struct xfs_rtgroup * rtg)163 xfs_rtgroup_next(
164 struct xfs_mount *mp,
165 struct xfs_rtgroup *rtg)
166 {
167 return xfs_rtgroup_next_range(mp, rtg, 0, mp->m_sb.sb_rgcount - 1);
168 }
169
170 static inline bool
xfs_verify_rgbno(struct xfs_rtgroup * rtg,xfs_rgblock_t rgbno)171 xfs_verify_rgbno(
172 struct xfs_rtgroup *rtg,
173 xfs_rgblock_t rgbno)
174 {
175 ASSERT(xfs_has_rtgroups(rtg_mount(rtg)));
176
177 return xfs_verify_gbno(rtg_group(rtg), rgbno);
178 }
179
180 /*
181 * Check that [@rgbno,@len] is a valid extent range in @rtg.
182 *
183 * Must only be used for RTG-enabled file systems.
184 */
185 static inline bool
xfs_verify_rgbext(struct xfs_rtgroup * rtg,xfs_rgblock_t rgbno,xfs_extlen_t len)186 xfs_verify_rgbext(
187 struct xfs_rtgroup *rtg,
188 xfs_rgblock_t rgbno,
189 xfs_extlen_t len)
190 {
191 ASSERT(xfs_has_rtgroups(rtg_mount(rtg)));
192
193 return xfs_verify_gbext(rtg_group(rtg), rgbno, len);
194 }
195
196 static inline xfs_rtblock_t
xfs_rgbno_to_rtb(struct xfs_rtgroup * rtg,xfs_rgblock_t rgbno)197 xfs_rgbno_to_rtb(
198 struct xfs_rtgroup *rtg,
199 xfs_rgblock_t rgbno)
200 {
201 return xfs_gbno_to_fsb(rtg_group(rtg), rgbno);
202 }
203
204 static inline xfs_rgnumber_t
xfs_rtb_to_rgno(struct xfs_mount * mp,xfs_rtblock_t rtbno)205 xfs_rtb_to_rgno(
206 struct xfs_mount *mp,
207 xfs_rtblock_t rtbno)
208 {
209 return xfs_fsb_to_gno(mp, rtbno, XG_TYPE_RTG);
210 }
211
212 static inline xfs_rgblock_t
xfs_rtb_to_rgbno(struct xfs_mount * mp,xfs_rtblock_t rtbno)213 xfs_rtb_to_rgbno(
214 struct xfs_mount *mp,
215 xfs_rtblock_t rtbno)
216 {
217 return xfs_fsb_to_gbno(mp, rtbno, XG_TYPE_RTG);
218 }
219
220 /* Is rtbno the start of a RT group? */
221 static inline bool
xfs_rtbno_is_group_start(struct xfs_mount * mp,xfs_rtblock_t rtbno)222 xfs_rtbno_is_group_start(
223 struct xfs_mount *mp,
224 xfs_rtblock_t rtbno)
225 {
226 return (rtbno & mp->m_groups[XG_TYPE_RTG].blkmask) == 0;
227 }
228
229 /* Convert an rtgroups rt extent number into an rgbno. */
230 static inline xfs_rgblock_t
xfs_rtx_to_rgbno(struct xfs_rtgroup * rtg,xfs_rtxnum_t rtx)231 xfs_rtx_to_rgbno(
232 struct xfs_rtgroup *rtg,
233 xfs_rtxnum_t rtx)
234 {
235 struct xfs_mount *mp = rtg_mount(rtg);
236
237 if (likely(mp->m_rtxblklog >= 0))
238 return rtx << mp->m_rtxblklog;
239 return rtx * mp->m_sb.sb_rextsize;
240 }
241
242 static inline xfs_daddr_t
xfs_rtb_to_daddr(struct xfs_mount * mp,xfs_rtblock_t rtbno)243 xfs_rtb_to_daddr(
244 struct xfs_mount *mp,
245 xfs_rtblock_t rtbno)
246 {
247 struct xfs_groups *g = &mp->m_groups[XG_TYPE_RTG];
248
249 if (xfs_has_rtgroups(mp) && !g->has_daddr_gaps) {
250 xfs_rgnumber_t rgno = xfs_rtb_to_rgno(mp, rtbno);
251
252 rtbno = (xfs_rtblock_t)rgno * g->blocks + (rtbno & g->blkmask);
253 }
254
255 return XFS_FSB_TO_BB(mp, g->start_fsb + rtbno);
256 }
257
258 static inline xfs_rtblock_t
xfs_daddr_to_rtb(struct xfs_mount * mp,xfs_daddr_t daddr)259 xfs_daddr_to_rtb(
260 struct xfs_mount *mp,
261 xfs_daddr_t daddr)
262 {
263 struct xfs_groups *g = &mp->m_groups[XG_TYPE_RTG];
264 xfs_rfsblock_t bno;
265
266 bno = XFS_BB_TO_FSBT(mp, daddr) - g->start_fsb;
267 if (xfs_has_rtgroups(mp) && !g->has_daddr_gaps) {
268 xfs_rgnumber_t rgno;
269 uint32_t rgbno;
270
271 rgno = div_u64_rem(bno, g->blocks, &rgbno);
272 return ((xfs_rtblock_t)rgno << g->blklog) + rgbno;
273 }
274
275 return bno;
276 }
277
278 #ifdef CONFIG_XFS_RT
279 int xfs_rtgroup_alloc(struct xfs_mount *mp, xfs_rgnumber_t rgno,
280 xfs_rgnumber_t rgcount, xfs_rtbxlen_t rextents);
281 void xfs_rtgroup_free(struct xfs_mount *mp, xfs_rgnumber_t rgno);
282
283 void xfs_free_rtgroups(struct xfs_mount *mp, xfs_rgnumber_t first_rgno,
284 xfs_rgnumber_t end_rgno);
285 int xfs_initialize_rtgroups(struct xfs_mount *mp, xfs_rgnumber_t first_rgno,
286 xfs_rgnumber_t end_rgno, xfs_rtbxlen_t rextents);
287
288 xfs_rtxnum_t __xfs_rtgroup_extents(struct xfs_mount *mp, xfs_rgnumber_t rgno,
289 xfs_rgnumber_t rgcount, xfs_rtbxlen_t rextents);
290 xfs_rtxnum_t xfs_rtgroup_extents(struct xfs_mount *mp, xfs_rgnumber_t rgno);
291 void xfs_rtgroup_calc_geometry(struct xfs_mount *mp, struct xfs_rtgroup *rtg,
292 xfs_rgnumber_t rgno, xfs_rgnumber_t rgcount,
293 xfs_rtbxlen_t rextents);
294
295 int xfs_update_last_rtgroup_size(struct xfs_mount *mp,
296 xfs_rgnumber_t prev_rgcount);
297
298 /* Lock the rt bitmap inode in exclusive mode */
299 #define XFS_RTGLOCK_BITMAP (1U << 0)
300 /* Lock the rt bitmap inode in shared mode */
301 #define XFS_RTGLOCK_BITMAP_SHARED (1U << 1)
302 /* Lock the rt rmap inode in exclusive mode */
303 #define XFS_RTGLOCK_RMAP (1U << 2)
304 /* Lock the rt refcount inode in exclusive mode */
305 #define XFS_RTGLOCK_REFCOUNT (1U << 3)
306
307 #define XFS_RTGLOCK_ALL_FLAGS (XFS_RTGLOCK_BITMAP | \
308 XFS_RTGLOCK_BITMAP_SHARED | \
309 XFS_RTGLOCK_RMAP | \
310 XFS_RTGLOCK_REFCOUNT)
311
312 void xfs_rtgroup_lock(struct xfs_rtgroup *rtg, unsigned int rtglock_flags);
313 void xfs_rtgroup_unlock(struct xfs_rtgroup *rtg, unsigned int rtglock_flags);
314 void xfs_rtgroup_trans_join(struct xfs_trans *tp, struct xfs_rtgroup *rtg,
315 unsigned int rtglock_flags);
316
317 int xfs_rtgroup_get_geometry(struct xfs_rtgroup *rtg,
318 struct xfs_rtgroup_geometry *rgeo);
319
320 int xfs_rtginode_mkdir_parent(struct xfs_mount *mp);
321 int xfs_rtginode_load_parent(struct xfs_trans *tp);
322
323 const char *xfs_rtginode_name(enum xfs_rtg_inodes type);
324 enum xfs_metafile_type xfs_rtginode_metafile_type(enum xfs_rtg_inodes type);
325 bool xfs_rtginode_enabled(struct xfs_rtgroup *rtg, enum xfs_rtg_inodes type);
326 void xfs_rtginode_mark_sick(struct xfs_rtgroup *rtg, enum xfs_rtg_inodes type);
327 int xfs_rtginode_load(struct xfs_rtgroup *rtg, enum xfs_rtg_inodes type,
328 struct xfs_trans *tp);
329 int xfs_rtginode_create(struct xfs_rtgroup *rtg, enum xfs_rtg_inodes type,
330 bool init);
331 void xfs_rtginode_irele(struct xfs_inode **ipp);
332
333 void xfs_rtginode_irele(struct xfs_inode **ipp);
334
xfs_rtginode_path(xfs_rgnumber_t rgno,enum xfs_rtg_inodes type)335 static inline const char *xfs_rtginode_path(xfs_rgnumber_t rgno,
336 enum xfs_rtg_inodes type)
337 {
338 return kasprintf(GFP_KERNEL, "%u.%s", rgno, xfs_rtginode_name(type));
339 }
340
341 void xfs_update_rtsb(struct xfs_buf *rtsb_bp,
342 const struct xfs_buf *sb_bp);
343 struct xfs_buf *xfs_log_rtsb(struct xfs_trans *tp,
344 const struct xfs_buf *sb_bp);
345 #else
xfs_free_rtgroups(struct xfs_mount * mp,xfs_rgnumber_t first_rgno,xfs_rgnumber_t end_rgno)346 static inline void xfs_free_rtgroups(struct xfs_mount *mp,
347 xfs_rgnumber_t first_rgno, xfs_rgnumber_t end_rgno)
348 {
349 }
350
xfs_initialize_rtgroups(struct xfs_mount * mp,xfs_rgnumber_t first_rgno,xfs_rgnumber_t end_rgno,xfs_rtbxlen_t rextents)351 static inline int xfs_initialize_rtgroups(struct xfs_mount *mp,
352 xfs_rgnumber_t first_rgno, xfs_rgnumber_t end_rgno,
353 xfs_rtbxlen_t rextents)
354 {
355 return 0;
356 }
357
358 # define xfs_rtgroup_extents(mp, rgno) (0)
359 # define xfs_update_last_rtgroup_size(mp, rgno) (0)
360 # define xfs_rtgroup_lock(rtg, gf) ((void)0)
361 # define xfs_rtgroup_unlock(rtg, gf) ((void)0)
362 # define xfs_rtgroup_trans_join(tp, rtg, gf) ((void)0)
363 # define xfs_update_rtsb(bp, sb_bp) ((void)0)
364 # define xfs_log_rtsb(tp, sb_bp) (NULL)
365 # define xfs_rtgroup_get_geometry(rtg, rgeo) (-EOPNOTSUPP)
366 #endif /* CONFIG_XFS_RT */
367
368 #endif /* __LIBXFS_RTGROUP_H */
369