1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 * Copyright (c) 2022-2024 Oracle. All Rights Reserved.
4 * Author: Darrick J. Wong <djwong@kernel.org>
6 #ifndef __LIBXFS_RTGROUP_H
7 #define __LIBXFS_RTGROUP_H 1
15 XFS_RTGI_BITMAP
, /* allocation bitmap */
16 XFS_RTGI_SUMMARY
, /* allocation summary */
21 #ifdef MAX_LOCKDEP_SUBCLASSES
22 static_assert(XFS_RTGI_MAX
<= MAX_LOCKDEP_SUBCLASSES
);
26 * Realtime group incore structure, similar to the per-AG structure.
29 struct xfs_group rtg_group
;
31 /* per-rtgroup metadata inodes */
32 struct xfs_inode
*rtg_inodes
[XFS_RTGI_MAX
];
34 /* Number of blocks in this group */
35 xfs_rtxnum_t rtg_extents
;
38 * Cache of rt summary level per bitmap block with the invariant that
39 * rtg_rsum_cache[bbno] > the maximum i for which rsum[i][bbno] != 0,
40 * or 0 if rsum[i][bbno] == 0 for all i.
42 * Reads and writes are serialized by the rsumip inode lock.
44 uint8_t *rtg_rsum_cache
;
47 static inline struct xfs_rtgroup
*to_rtg(struct xfs_group
*xg
)
49 return container_of(xg
, struct xfs_rtgroup
, rtg_group
);
52 static inline struct xfs_group
*rtg_group(struct xfs_rtgroup
*rtg
)
54 return &rtg
->rtg_group
;
57 static inline struct xfs_mount
*rtg_mount(const struct xfs_rtgroup
*rtg
)
59 return rtg
->rtg_group
.xg_mount
;
62 static inline xfs_rgnumber_t
rtg_rgno(const struct xfs_rtgroup
*rtg
)
64 return rtg
->rtg_group
.xg_gno
;
67 /* Passive rtgroup references */
68 static inline struct xfs_rtgroup
*
73 return to_rtg(xfs_group_get(mp
, rgno
, XG_TYPE_RTG
));
76 static inline struct xfs_rtgroup
*
78 struct xfs_rtgroup
*rtg
)
80 return to_rtg(xfs_group_hold(rtg_group(rtg
)));
85 struct xfs_rtgroup
*rtg
)
87 xfs_group_put(rtg_group(rtg
));
90 /* Active rtgroup references */
91 static inline struct xfs_rtgroup
*
96 return to_rtg(xfs_group_grab(mp
, rgno
, XG_TYPE_RTG
));
101 struct xfs_rtgroup
*rtg
)
103 xfs_group_rele(rtg_group(rtg
));
106 static inline struct xfs_rtgroup
*
107 xfs_rtgroup_next_range(
108 struct xfs_mount
*mp
,
109 struct xfs_rtgroup
*rtg
,
110 xfs_rgnumber_t start_rgno
,
111 xfs_rgnumber_t end_rgno
)
113 return to_rtg(xfs_group_next_range(mp
, rtg
? rtg_group(rtg
) : NULL
,
114 start_rgno
, end_rgno
, XG_TYPE_RTG
));
117 static inline struct xfs_rtgroup
*
119 struct xfs_mount
*mp
,
120 struct xfs_rtgroup
*rtg
)
122 return xfs_rtgroup_next_range(mp
, rtg
, 0, mp
->m_sb
.sb_rgcount
- 1);
125 static inline xfs_rtblock_t
127 struct xfs_rtgroup
*rtg
,
130 return xfs_gbno_to_fsb(rtg_group(rtg
), rgbno
);
133 static inline xfs_rgnumber_t
135 struct xfs_mount
*mp
,
138 return xfs_fsb_to_gno(mp
, rtbno
, XG_TYPE_RTG
);
141 static inline xfs_rgblock_t
143 struct xfs_mount
*mp
,
146 return xfs_fsb_to_gbno(mp
, rtbno
, XG_TYPE_RTG
);
149 /* Is rtbno the start of a RT group? */
151 xfs_rtbno_is_group_start(
152 struct xfs_mount
*mp
,
155 return (rtbno
& mp
->m_groups
[XG_TYPE_RTG
].blkmask
) == 0;
158 /* Convert an rtgroups rt extent number into an rgbno. */
159 static inline xfs_rgblock_t
161 struct xfs_rtgroup
*rtg
,
164 struct xfs_mount
*mp
= rtg_mount(rtg
);
166 if (likely(mp
->m_rtxblklog
>= 0))
167 return rtx
<< mp
->m_rtxblklog
;
168 return rtx
* mp
->m_sb
.sb_rextsize
;
171 static inline xfs_daddr_t
173 struct xfs_mount
*mp
,
176 struct xfs_groups
*g
= &mp
->m_groups
[XG_TYPE_RTG
];
177 xfs_rgnumber_t rgno
= xfs_rtb_to_rgno(mp
, rtbno
);
178 uint64_t start_bno
= (xfs_rtblock_t
)rgno
* g
->blocks
;
180 return XFS_FSB_TO_BB(mp
, start_bno
+ (rtbno
& g
->blkmask
));
183 static inline xfs_rtblock_t
185 struct xfs_mount
*mp
,
188 xfs_rfsblock_t bno
= XFS_BB_TO_FSBT(mp
, daddr
);
190 if (xfs_has_rtgroups(mp
)) {
191 struct xfs_groups
*g
= &mp
->m_groups
[XG_TYPE_RTG
];
195 rgno
= div_u64_rem(bno
, g
->blocks
, &rgbno
);
196 return ((xfs_rtblock_t
)rgno
<< g
->blklog
) + rgbno
;
203 int xfs_rtgroup_alloc(struct xfs_mount
*mp
, xfs_rgnumber_t rgno
,
204 xfs_rgnumber_t rgcount
, xfs_rtbxlen_t rextents
);
205 void xfs_rtgroup_free(struct xfs_mount
*mp
, xfs_rgnumber_t rgno
);
207 void xfs_free_rtgroups(struct xfs_mount
*mp
, xfs_rgnumber_t first_rgno
,
208 xfs_rgnumber_t end_rgno
);
209 int xfs_initialize_rtgroups(struct xfs_mount
*mp
, xfs_rgnumber_t first_rgno
,
210 xfs_rgnumber_t end_rgno
, xfs_rtbxlen_t rextents
);
212 xfs_rtxnum_t
__xfs_rtgroup_extents(struct xfs_mount
*mp
, xfs_rgnumber_t rgno
,
213 xfs_rgnumber_t rgcount
, xfs_rtbxlen_t rextents
);
214 xfs_rtxnum_t
xfs_rtgroup_extents(struct xfs_mount
*mp
, xfs_rgnumber_t rgno
);
215 void xfs_rtgroup_calc_geometry(struct xfs_mount
*mp
, struct xfs_rtgroup
*rtg
,
216 xfs_rgnumber_t rgno
, xfs_rgnumber_t rgcount
,
217 xfs_rtbxlen_t rextents
);
219 int xfs_update_last_rtgroup_size(struct xfs_mount
*mp
,
220 xfs_rgnumber_t prev_rgcount
);
222 /* Lock the rt bitmap inode in exclusive mode */
223 #define XFS_RTGLOCK_BITMAP (1U << 0)
224 /* Lock the rt bitmap inode in shared mode */
225 #define XFS_RTGLOCK_BITMAP_SHARED (1U << 1)
227 #define XFS_RTGLOCK_ALL_FLAGS (XFS_RTGLOCK_BITMAP | \
228 XFS_RTGLOCK_BITMAP_SHARED)
230 void xfs_rtgroup_lock(struct xfs_rtgroup
*rtg
, unsigned int rtglock_flags
);
231 void xfs_rtgroup_unlock(struct xfs_rtgroup
*rtg
, unsigned int rtglock_flags
);
232 void xfs_rtgroup_trans_join(struct xfs_trans
*tp
, struct xfs_rtgroup
*rtg
,
233 unsigned int rtglock_flags
);
235 int xfs_rtgroup_get_geometry(struct xfs_rtgroup
*rtg
,
236 struct xfs_rtgroup_geometry
*rgeo
);
238 int xfs_rtginode_mkdir_parent(struct xfs_mount
*mp
);
239 int xfs_rtginode_load_parent(struct xfs_trans
*tp
);
241 const char *xfs_rtginode_name(enum xfs_rtg_inodes type
);
242 enum xfs_metafile_type
xfs_rtginode_metafile_type(enum xfs_rtg_inodes type
);
243 bool xfs_rtginode_enabled(struct xfs_rtgroup
*rtg
, enum xfs_rtg_inodes type
);
244 void xfs_rtginode_mark_sick(struct xfs_rtgroup
*rtg
, enum xfs_rtg_inodes type
);
245 int xfs_rtginode_load(struct xfs_rtgroup
*rtg
, enum xfs_rtg_inodes type
,
246 struct xfs_trans
*tp
);
247 int xfs_rtginode_create(struct xfs_rtgroup
*rtg
, enum xfs_rtg_inodes type
,
249 void xfs_rtginode_irele(struct xfs_inode
**ipp
);
251 static inline const char *xfs_rtginode_path(xfs_rgnumber_t rgno
,
252 enum xfs_rtg_inodes type
)
254 return kasprintf(GFP_KERNEL
, "%u.%s", rgno
, xfs_rtginode_name(type
));
257 void xfs_update_rtsb(struct xfs_buf
*rtsb_bp
,
258 const struct xfs_buf
*sb_bp
);
259 struct xfs_buf
*xfs_log_rtsb(struct xfs_trans
*tp
,
260 const struct xfs_buf
*sb_bp
);
262 static inline void xfs_free_rtgroups(struct xfs_mount
*mp
,
263 xfs_rgnumber_t first_rgno
, xfs_rgnumber_t end_rgno
)
267 static inline int xfs_initialize_rtgroups(struct xfs_mount
*mp
,
268 xfs_rgnumber_t first_rgno
, xfs_rgnumber_t end_rgno
,
269 xfs_rtbxlen_t rextents
)
274 # define xfs_rtgroup_extents(mp, rgno) (0)
275 # define xfs_update_last_rtgroup_size(mp, rgno) (-EOPNOTSUPP)
276 # define xfs_rtgroup_lock(rtg, gf) ((void)0)
277 # define xfs_rtgroup_unlock(rtg, gf) ((void)0)
278 # define xfs_rtgroup_trans_join(tp, rtg, gf) ((void)0)
279 # define xfs_update_rtsb(bp, sb_bp) ((void)0)
280 # define xfs_log_rtsb(tp, sb_bp) (NULL)
281 # define xfs_rtgroup_get_geometry(rtg, rgeo) (-EOPNOTSUPP)
282 #endif /* CONFIG_XFS_RT */
284 #endif /* __LIBXFS_RTGROUP_H */