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