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 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 54 static inline struct xfs_group *rtg_group(struct xfs_rtgroup *rtg) 55 { 56 return &rtg->rtg_group; 57 } 58 59 static inline struct xfs_mount *rtg_mount(const struct xfs_rtgroup *rtg) 60 { 61 return rtg->rtg_group.xg_mount; 62 } 63 64 static inline xfs_rgnumber_t rtg_rgno(const struct xfs_rtgroup *rtg) 65 { 66 return rtg->rtg_group.xg_gno; 67 } 68 69 static inline struct xfs_inode *rtg_bitmap(const struct xfs_rtgroup *rtg) 70 { 71 return rtg->rtg_inodes[XFS_RTGI_BITMAP]; 72 } 73 74 static inline struct xfs_inode *rtg_summary(const struct xfs_rtgroup *rtg) 75 { 76 return rtg->rtg_inodes[XFS_RTGI_SUMMARY]; 77 } 78 79 static inline struct xfs_inode *rtg_rmap(const struct xfs_rtgroup *rtg) 80 { 81 return rtg->rtg_inodes[XFS_RTGI_RMAP]; 82 } 83 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 * 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 * 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 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 * 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 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 * 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 * 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 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 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 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 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 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 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 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 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 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 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 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 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