xref: /linux/fs/xfs/libxfs/xfs_rtgroup.h (revision 9db0d7c5a5be25e56c3eacc1f03d296b7b0b960f)
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 	 * Count of outstanding GC operations for zoned XFS.  Any RTG with a
56 	 * non-zero rtg_gccount will not be picked as new GC victim.
57 	 */
58 	atomic_t		rtg_gccount;
59 };
60 
61 /*
62  * For zoned RT devices this is set on groups that have no written blocks
63  * and can be picked by the allocator for opening.
64  */
65 #define XFS_RTG_FREE			XA_MARK_0
66 
67 /*
68  * For zoned RT devices this is set on groups that are fully written and that
69  * have unused blocks.  Used by the garbage collection to pick targets.
70  */
71 #define XFS_RTG_RECLAIMABLE		XA_MARK_1
72 
to_rtg(struct xfs_group * xg)73 static inline struct xfs_rtgroup *to_rtg(struct xfs_group *xg)
74 {
75 	return container_of(xg, struct xfs_rtgroup, rtg_group);
76 }
77 
rtg_group(struct xfs_rtgroup * rtg)78 static inline struct xfs_group *rtg_group(struct xfs_rtgroup *rtg)
79 {
80 	return &rtg->rtg_group;
81 }
82 
rtg_mount(const struct xfs_rtgroup * rtg)83 static inline struct xfs_mount *rtg_mount(const struct xfs_rtgroup *rtg)
84 {
85 	return rtg->rtg_group.xg_mount;
86 }
87 
rtg_rgno(const struct xfs_rtgroup * rtg)88 static inline xfs_rgnumber_t rtg_rgno(const struct xfs_rtgroup *rtg)
89 {
90 	return rtg->rtg_group.xg_gno;
91 }
92 
rtg_blocks(const struct xfs_rtgroup * rtg)93 static inline xfs_rgblock_t rtg_blocks(const struct xfs_rtgroup *rtg)
94 {
95 	return rtg->rtg_group.xg_block_count;
96 }
97 
rtg_bitmap(const struct xfs_rtgroup * rtg)98 static inline struct xfs_inode *rtg_bitmap(const struct xfs_rtgroup *rtg)
99 {
100 	return rtg->rtg_inodes[XFS_RTGI_BITMAP];
101 }
102 
rtg_summary(const struct xfs_rtgroup * rtg)103 static inline struct xfs_inode *rtg_summary(const struct xfs_rtgroup *rtg)
104 {
105 	return rtg->rtg_inodes[XFS_RTGI_SUMMARY];
106 }
107 
rtg_rmap(const struct xfs_rtgroup * rtg)108 static inline struct xfs_inode *rtg_rmap(const struct xfs_rtgroup *rtg)
109 {
110 	return rtg->rtg_inodes[XFS_RTGI_RMAP];
111 }
112 
rtg_refcount(const struct xfs_rtgroup * rtg)113 static inline struct xfs_inode *rtg_refcount(const struct xfs_rtgroup *rtg)
114 {
115 	return rtg->rtg_inodes[XFS_RTGI_REFCOUNT];
116 }
117 
118 /* Passive rtgroup references */
119 static inline struct xfs_rtgroup *
xfs_rtgroup_get(struct xfs_mount * mp,xfs_rgnumber_t rgno)120 xfs_rtgroup_get(
121 	struct xfs_mount	*mp,
122 	xfs_rgnumber_t		rgno)
123 {
124 	return to_rtg(xfs_group_get(mp, rgno, XG_TYPE_RTG));
125 }
126 
127 static inline struct xfs_rtgroup *
xfs_rtgroup_hold(struct xfs_rtgroup * rtg)128 xfs_rtgroup_hold(
129 	struct xfs_rtgroup	*rtg)
130 {
131 	return to_rtg(xfs_group_hold(rtg_group(rtg)));
132 }
133 
134 static inline void
xfs_rtgroup_put(struct xfs_rtgroup * rtg)135 xfs_rtgroup_put(
136 	struct xfs_rtgroup	*rtg)
137 {
138 	xfs_group_put(rtg_group(rtg));
139 }
140 
141 /* Active rtgroup references */
142 static inline struct xfs_rtgroup *
xfs_rtgroup_grab(struct xfs_mount * mp,xfs_rgnumber_t rgno)143 xfs_rtgroup_grab(
144 	struct xfs_mount	*mp,
145 	xfs_rgnumber_t		rgno)
146 {
147 	return to_rtg(xfs_group_grab(mp, rgno, XG_TYPE_RTG));
148 }
149 
150 static inline void
xfs_rtgroup_rele(struct xfs_rtgroup * rtg)151 xfs_rtgroup_rele(
152 	struct xfs_rtgroup	*rtg)
153 {
154 	xfs_group_rele(rtg_group(rtg));
155 }
156 
157 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)158 xfs_rtgroup_next_range(
159 	struct xfs_mount	*mp,
160 	struct xfs_rtgroup	*rtg,
161 	xfs_rgnumber_t		start_rgno,
162 	xfs_rgnumber_t		end_rgno)
163 {
164 	return to_rtg(xfs_group_next_range(mp, rtg ? rtg_group(rtg) : NULL,
165 			start_rgno, end_rgno, XG_TYPE_RTG));
166 }
167 
168 static inline struct xfs_rtgroup *
xfs_rtgroup_next(struct xfs_mount * mp,struct xfs_rtgroup * rtg)169 xfs_rtgroup_next(
170 	struct xfs_mount	*mp,
171 	struct xfs_rtgroup	*rtg)
172 {
173 	return xfs_rtgroup_next_range(mp, rtg, 0, mp->m_sb.sb_rgcount - 1);
174 }
175 
176 static inline bool
xfs_verify_rgbno(struct xfs_rtgroup * rtg,xfs_rgblock_t rgbno)177 xfs_verify_rgbno(
178 	struct xfs_rtgroup	*rtg,
179 	xfs_rgblock_t		rgbno)
180 {
181 	ASSERT(xfs_has_rtgroups(rtg_mount(rtg)));
182 
183 	return xfs_verify_gbno(rtg_group(rtg), rgbno);
184 }
185 
186 /*
187  * Check that [@rgbno,@len] is a valid extent range in @rtg.
188  *
189  * Must only be used for RTG-enabled file systems.
190  */
191 static inline bool
xfs_verify_rgbext(struct xfs_rtgroup * rtg,xfs_rgblock_t rgbno,xfs_extlen_t len)192 xfs_verify_rgbext(
193 	struct xfs_rtgroup	*rtg,
194 	xfs_rgblock_t		rgbno,
195 	xfs_extlen_t		len)
196 {
197 	ASSERT(xfs_has_rtgroups(rtg_mount(rtg)));
198 
199 	return xfs_verify_gbext(rtg_group(rtg), rgbno, len);
200 }
201 
202 static inline xfs_rtblock_t
xfs_rgbno_to_rtb(struct xfs_rtgroup * rtg,xfs_rgblock_t rgbno)203 xfs_rgbno_to_rtb(
204 	struct xfs_rtgroup	*rtg,
205 	xfs_rgblock_t		rgbno)
206 {
207 	return xfs_gbno_to_fsb(rtg_group(rtg), rgbno);
208 }
209 
210 static inline xfs_rgnumber_t
xfs_rtb_to_rgno(struct xfs_mount * mp,xfs_rtblock_t rtbno)211 xfs_rtb_to_rgno(
212 	struct xfs_mount	*mp,
213 	xfs_rtblock_t		rtbno)
214 {
215 	return xfs_fsb_to_gno(mp, rtbno, XG_TYPE_RTG);
216 }
217 
218 static inline xfs_rgblock_t
xfs_rtb_to_rgbno(struct xfs_mount * mp,xfs_rtblock_t rtbno)219 xfs_rtb_to_rgbno(
220 	struct xfs_mount	*mp,
221 	xfs_rtblock_t		rtbno)
222 {
223 	return xfs_fsb_to_gbno(mp, rtbno, XG_TYPE_RTG);
224 }
225 
226 /* Is rtbno the start of a RT group? */
227 static inline bool
xfs_rtbno_is_group_start(struct xfs_mount * mp,xfs_rtblock_t rtbno)228 xfs_rtbno_is_group_start(
229 	struct xfs_mount	*mp,
230 	xfs_rtblock_t		rtbno)
231 {
232 	return (rtbno & mp->m_groups[XG_TYPE_RTG].blkmask) == 0;
233 }
234 
235 /* Convert an rtgroups rt extent number into an rgbno. */
236 static inline xfs_rgblock_t
xfs_rtx_to_rgbno(struct xfs_rtgroup * rtg,xfs_rtxnum_t rtx)237 xfs_rtx_to_rgbno(
238 	struct xfs_rtgroup	*rtg,
239 	xfs_rtxnum_t		rtx)
240 {
241 	struct xfs_mount	*mp = rtg_mount(rtg);
242 
243 	if (likely(mp->m_rtxblklog >= 0))
244 		return rtx << mp->m_rtxblklog;
245 	return rtx * mp->m_sb.sb_rextsize;
246 }
247 
248 static inline xfs_daddr_t
xfs_rtb_to_daddr(struct xfs_mount * mp,xfs_rtblock_t rtbno)249 xfs_rtb_to_daddr(
250 	struct xfs_mount	*mp,
251 	xfs_rtblock_t		rtbno)
252 {
253 	struct xfs_groups	*g = &mp->m_groups[XG_TYPE_RTG];
254 
255 	if (xfs_has_rtgroups(mp) && !g->has_daddr_gaps) {
256 		xfs_rgnumber_t	rgno = xfs_rtb_to_rgno(mp, rtbno);
257 
258 		rtbno = (xfs_rtblock_t)rgno * g->blocks + (rtbno & g->blkmask);
259 	}
260 
261 	return XFS_FSB_TO_BB(mp, g->start_fsb + rtbno);
262 }
263 
264 static inline xfs_rtblock_t
xfs_daddr_to_rtb(struct xfs_mount * mp,xfs_daddr_t daddr)265 xfs_daddr_to_rtb(
266 	struct xfs_mount	*mp,
267 	xfs_daddr_t		daddr)
268 {
269 	struct xfs_groups	*g = &mp->m_groups[XG_TYPE_RTG];
270 	xfs_rfsblock_t		bno;
271 
272 	bno = XFS_BB_TO_FSBT(mp, daddr) - g->start_fsb;
273 	if (xfs_has_rtgroups(mp) && !g->has_daddr_gaps) {
274 		xfs_rgnumber_t	rgno;
275 		uint32_t	rgbno;
276 
277 		rgno = div_u64_rem(bno, g->blocks, &rgbno);
278 		return ((xfs_rtblock_t)rgno << g->blklog) + rgbno;
279 	}
280 
281 	return bno;
282 }
283 
284 #ifdef CONFIG_XFS_RT
285 int xfs_rtgroup_alloc(struct xfs_mount *mp, xfs_rgnumber_t rgno,
286 		xfs_rgnumber_t rgcount, xfs_rtbxlen_t rextents);
287 void xfs_rtgroup_free(struct xfs_mount *mp, xfs_rgnumber_t rgno);
288 
289 void xfs_free_rtgroups(struct xfs_mount *mp, xfs_rgnumber_t first_rgno,
290 		xfs_rgnumber_t end_rgno);
291 int xfs_initialize_rtgroups(struct xfs_mount *mp, xfs_rgnumber_t first_rgno,
292 		xfs_rgnumber_t end_rgno, xfs_rtbxlen_t rextents);
293 
294 xfs_rtxnum_t __xfs_rtgroup_extents(struct xfs_mount *mp, xfs_rgnumber_t rgno,
295 		xfs_rgnumber_t rgcount, xfs_rtbxlen_t rextents);
296 xfs_rtxnum_t xfs_rtgroup_extents(struct xfs_mount *mp, xfs_rgnumber_t rgno);
297 void xfs_rtgroup_calc_geometry(struct xfs_mount *mp, struct xfs_rtgroup *rtg,
298 		xfs_rgnumber_t rgno, xfs_rgnumber_t rgcount,
299 		xfs_rtbxlen_t rextents);
300 
301 int xfs_update_last_rtgroup_size(struct xfs_mount *mp,
302 		xfs_rgnumber_t prev_rgcount);
303 
304 /* Lock the rt bitmap inode in exclusive mode */
305 #define XFS_RTGLOCK_BITMAP		(1U << 0)
306 /* Lock the rt bitmap inode in shared mode */
307 #define XFS_RTGLOCK_BITMAP_SHARED	(1U << 1)
308 /* Lock the rt rmap inode in exclusive mode */
309 #define XFS_RTGLOCK_RMAP		(1U << 2)
310 /* Lock the rt refcount inode in exclusive mode */
311 #define XFS_RTGLOCK_REFCOUNT		(1U << 3)
312 
313 #define XFS_RTGLOCK_ALL_FLAGS	(XFS_RTGLOCK_BITMAP | \
314 				 XFS_RTGLOCK_BITMAP_SHARED | \
315 				 XFS_RTGLOCK_RMAP | \
316 				 XFS_RTGLOCK_REFCOUNT)
317 
318 void xfs_rtgroup_lock(struct xfs_rtgroup *rtg, unsigned int rtglock_flags);
319 void xfs_rtgroup_unlock(struct xfs_rtgroup *rtg, unsigned int rtglock_flags);
320 void xfs_rtgroup_trans_join(struct xfs_trans *tp, struct xfs_rtgroup *rtg,
321 		unsigned int rtglock_flags);
322 
323 int xfs_rtgroup_get_geometry(struct xfs_rtgroup *rtg,
324 		struct xfs_rtgroup_geometry *rgeo);
325 
326 int xfs_rtginode_mkdir_parent(struct xfs_mount *mp);
327 int xfs_rtginode_load_parent(struct xfs_trans *tp);
328 
329 const char *xfs_rtginode_name(enum xfs_rtg_inodes type);
330 enum xfs_metafile_type xfs_rtginode_metafile_type(enum xfs_rtg_inodes type);
331 bool xfs_rtginode_enabled(struct xfs_rtgroup *rtg, enum xfs_rtg_inodes type);
332 void xfs_rtginode_mark_sick(struct xfs_rtgroup *rtg, enum xfs_rtg_inodes type);
333 int xfs_rtginode_load(struct xfs_rtgroup *rtg, enum xfs_rtg_inodes type,
334 		struct xfs_trans *tp);
335 int xfs_rtginode_create(struct xfs_rtgroup *rtg, enum xfs_rtg_inodes type,
336 		bool init);
337 void xfs_rtginode_irele(struct xfs_inode **ipp);
338 
339 void xfs_rtginode_irele(struct xfs_inode **ipp);
340 
xfs_rtginode_path(xfs_rgnumber_t rgno,enum xfs_rtg_inodes type)341 static inline const char *xfs_rtginode_path(xfs_rgnumber_t rgno,
342 		enum xfs_rtg_inodes type)
343 {
344 	return kasprintf(GFP_KERNEL, "%u.%s", rgno, xfs_rtginode_name(type));
345 }
346 
347 void xfs_update_rtsb(struct xfs_buf *rtsb_bp,
348 		const struct xfs_buf *sb_bp);
349 struct xfs_buf *xfs_log_rtsb(struct xfs_trans *tp,
350 		const struct xfs_buf *sb_bp);
351 #else
xfs_free_rtgroups(struct xfs_mount * mp,xfs_rgnumber_t first_rgno,xfs_rgnumber_t end_rgno)352 static inline void xfs_free_rtgroups(struct xfs_mount *mp,
353 		xfs_rgnumber_t first_rgno, xfs_rgnumber_t end_rgno)
354 {
355 }
356 
xfs_initialize_rtgroups(struct xfs_mount * mp,xfs_rgnumber_t first_rgno,xfs_rgnumber_t end_rgno,xfs_rtbxlen_t rextents)357 static inline int xfs_initialize_rtgroups(struct xfs_mount *mp,
358 		xfs_rgnumber_t first_rgno, xfs_rgnumber_t end_rgno,
359 		xfs_rtbxlen_t rextents)
360 {
361 	return 0;
362 }
363 
364 # define xfs_rtgroup_extents(mp, rgno)		(0)
365 # define xfs_update_last_rtgroup_size(mp, rgno)	(0)
366 # define xfs_rtgroup_lock(rtg, gf)		((void)0)
367 # define xfs_rtgroup_unlock(rtg, gf)		((void)0)
368 # define xfs_rtgroup_trans_join(tp, rtg, gf)	((void)0)
369 # define xfs_update_rtsb(bp, sb_bp)	((void)0)
370 # define xfs_log_rtsb(tp, sb_bp)	(NULL)
371 # define xfs_rtgroup_get_geometry(rtg, rgeo)	(-EOPNOTSUPP)
372 #endif /* CONFIG_XFS_RT */
373 
374 #endif /* __LIBXFS_RTGROUP_H */
375