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 18 XFS_RTGI_MAX, 19 }; 20 21 #ifdef MAX_LOCKDEP_SUBCLASSES 22 static_assert(XFS_RTGI_MAX <= MAX_LOCKDEP_SUBCLASSES); 23 #endif 24 25 /* 26 * Realtime group incore structure, similar to the per-AG structure. 27 */ 28 struct xfs_rtgroup { 29 struct xfs_group rtg_group; 30 31 /* per-rtgroup metadata inodes */ 32 struct xfs_inode *rtg_inodes[XFS_RTGI_MAX]; 33 34 /* Number of blocks in this group */ 35 xfs_rtxnum_t rtg_extents; 36 37 /* 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. 41 * 42 * Reads and writes are serialized by the rsumip inode lock. 43 */ 44 uint8_t *rtg_rsum_cache; 45 }; 46 47 static inline struct xfs_rtgroup *to_rtg(struct xfs_group *xg) 48 { 49 return container_of(xg, struct xfs_rtgroup, rtg_group); 50 } 51 52 static inline struct xfs_group *rtg_group(struct xfs_rtgroup *rtg) 53 { 54 return &rtg->rtg_group; 55 } 56 57 static inline struct xfs_mount *rtg_mount(const struct xfs_rtgroup *rtg) 58 { 59 return rtg->rtg_group.xg_mount; 60 } 61 62 static inline xfs_rgnumber_t rtg_rgno(const struct xfs_rtgroup *rtg) 63 { 64 return rtg->rtg_group.xg_gno; 65 } 66 67 /* Passive rtgroup references */ 68 static inline struct xfs_rtgroup * 69 xfs_rtgroup_get( 70 struct xfs_mount *mp, 71 xfs_rgnumber_t rgno) 72 { 73 return to_rtg(xfs_group_get(mp, rgno, XG_TYPE_RTG)); 74 } 75 76 static inline struct xfs_rtgroup * 77 xfs_rtgroup_hold( 78 struct xfs_rtgroup *rtg) 79 { 80 return to_rtg(xfs_group_hold(rtg_group(rtg))); 81 } 82 83 static inline void 84 xfs_rtgroup_put( 85 struct xfs_rtgroup *rtg) 86 { 87 xfs_group_put(rtg_group(rtg)); 88 } 89 90 /* Active rtgroup references */ 91 static inline struct xfs_rtgroup * 92 xfs_rtgroup_grab( 93 struct xfs_mount *mp, 94 xfs_rgnumber_t rgno) 95 { 96 return to_rtg(xfs_group_grab(mp, rgno, XG_TYPE_RTG)); 97 } 98 99 static inline void 100 xfs_rtgroup_rele( 101 struct xfs_rtgroup *rtg) 102 { 103 xfs_group_rele(rtg_group(rtg)); 104 } 105 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) 112 { 113 return to_rtg(xfs_group_next_range(mp, rtg ? rtg_group(rtg) : NULL, 114 start_rgno, end_rgno, XG_TYPE_RTG)); 115 } 116 117 static inline struct xfs_rtgroup * 118 xfs_rtgroup_next( 119 struct xfs_mount *mp, 120 struct xfs_rtgroup *rtg) 121 { 122 return xfs_rtgroup_next_range(mp, rtg, 0, mp->m_sb.sb_rgcount - 1); 123 } 124 125 static inline xfs_rtblock_t 126 xfs_rgbno_to_rtb( 127 struct xfs_rtgroup *rtg, 128 xfs_rgblock_t rgbno) 129 { 130 return xfs_gbno_to_fsb(rtg_group(rtg), rgbno); 131 } 132 133 static inline xfs_rgnumber_t 134 xfs_rtb_to_rgno( 135 struct xfs_mount *mp, 136 xfs_rtblock_t rtbno) 137 { 138 return xfs_fsb_to_gno(mp, rtbno, XG_TYPE_RTG); 139 } 140 141 static inline xfs_rgblock_t 142 xfs_rtb_to_rgbno( 143 struct xfs_mount *mp, 144 xfs_rtblock_t rtbno) 145 { 146 return xfs_fsb_to_gbno(mp, rtbno, XG_TYPE_RTG); 147 } 148 149 /* Is rtbno the start of a RT group? */ 150 static inline bool 151 xfs_rtbno_is_group_start( 152 struct xfs_mount *mp, 153 xfs_rtblock_t rtbno) 154 { 155 return (rtbno & mp->m_groups[XG_TYPE_RTG].blkmask) == 0; 156 } 157 158 /* Convert an rtgroups rt extent number into an rgbno. */ 159 static inline xfs_rgblock_t 160 xfs_rtx_to_rgbno( 161 struct xfs_rtgroup *rtg, 162 xfs_rtxnum_t rtx) 163 { 164 struct xfs_mount *mp = rtg_mount(rtg); 165 166 if (likely(mp->m_rtxblklog >= 0)) 167 return rtx << mp->m_rtxblklog; 168 return rtx * mp->m_sb.sb_rextsize; 169 } 170 171 static inline xfs_daddr_t 172 xfs_rtb_to_daddr( 173 struct xfs_mount *mp, 174 xfs_rtblock_t rtbno) 175 { 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; 179 180 return XFS_FSB_TO_BB(mp, start_bno + (rtbno & g->blkmask)); 181 } 182 183 static inline xfs_rtblock_t 184 xfs_daddr_to_rtb( 185 struct xfs_mount *mp, 186 xfs_daddr_t daddr) 187 { 188 xfs_rfsblock_t bno = XFS_BB_TO_FSBT(mp, daddr); 189 190 if (xfs_has_rtgroups(mp)) { 191 struct xfs_groups *g = &mp->m_groups[XG_TYPE_RTG]; 192 xfs_rgnumber_t rgno; 193 uint32_t rgbno; 194 195 rgno = div_u64_rem(bno, g->blocks, &rgbno); 196 return ((xfs_rtblock_t)rgno << g->blklog) + rgbno; 197 } 198 199 return bno; 200 } 201 202 #ifdef CONFIG_XFS_RT 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); 206 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); 211 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); 218 219 int xfs_update_last_rtgroup_size(struct xfs_mount *mp, 220 xfs_rgnumber_t prev_rgcount); 221 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) 226 227 #define XFS_RTGLOCK_ALL_FLAGS (XFS_RTGLOCK_BITMAP | \ 228 XFS_RTGLOCK_BITMAP_SHARED) 229 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); 234 235 int xfs_rtgroup_get_geometry(struct xfs_rtgroup *rtg, 236 struct xfs_rtgroup_geometry *rgeo); 237 238 int xfs_rtginode_mkdir_parent(struct xfs_mount *mp); 239 int xfs_rtginode_load_parent(struct xfs_trans *tp); 240 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, 248 bool init); 249 void xfs_rtginode_irele(struct xfs_inode **ipp); 250 251 static inline const char *xfs_rtginode_path(xfs_rgnumber_t rgno, 252 enum xfs_rtg_inodes type) 253 { 254 return kasprintf(GFP_KERNEL, "%u.%s", rgno, xfs_rtginode_name(type)); 255 } 256 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); 261 #else 262 static inline void xfs_free_rtgroups(struct xfs_mount *mp, 263 xfs_rgnumber_t first_rgno, xfs_rgnumber_t end_rgno) 264 { 265 } 266 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) 270 { 271 return 0; 272 } 273 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 */ 283 284 #endif /* __LIBXFS_RTGROUP_H */ 285