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 #include "xfs.h" 7 #include "xfs_fs.h" 8 #include "xfs_shared.h" 9 #include "xfs_format.h" 10 #include "xfs_trans_resv.h" 11 #include "xfs_bit.h" 12 #include "xfs_sb.h" 13 #include "xfs_mount.h" 14 #include "xfs_btree.h" 15 #include "xfs_alloc_btree.h" 16 #include "xfs_rmap_btree.h" 17 #include "xfs_alloc.h" 18 #include "xfs_ialloc.h" 19 #include "xfs_rmap.h" 20 #include "xfs_ag.h" 21 #include "xfs_ag_resv.h" 22 #include "xfs_health.h" 23 #include "xfs_error.h" 24 #include "xfs_bmap.h" 25 #include "xfs_defer.h" 26 #include "xfs_log_format.h" 27 #include "xfs_trans.h" 28 #include "xfs_trace.h" 29 #include "xfs_inode.h" 30 #include "xfs_icache.h" 31 #include "xfs_rtgroup.h" 32 #include "xfs_rtbitmap.h" 33 #include "xfs_metafile.h" 34 #include "xfs_metadir.h" 35 36 int 37 xfs_rtgroup_alloc( 38 struct xfs_mount *mp, 39 xfs_rgnumber_t rgno, 40 xfs_rgnumber_t rgcount, 41 xfs_rtbxlen_t rextents) 42 { 43 struct xfs_rtgroup *rtg; 44 int error; 45 46 rtg = kzalloc(sizeof(struct xfs_rtgroup), GFP_KERNEL); 47 if (!rtg) 48 return -ENOMEM; 49 50 error = xfs_group_insert(mp, rtg_group(rtg), rgno, XG_TYPE_RTG); 51 if (error) 52 goto out_free_rtg; 53 return 0; 54 55 out_free_rtg: 56 kfree(rtg); 57 return error; 58 } 59 60 void 61 xfs_rtgroup_free( 62 struct xfs_mount *mp, 63 xfs_rgnumber_t rgno) 64 { 65 xfs_group_free(mp, rgno, XG_TYPE_RTG, NULL); 66 } 67 68 /* Free a range of incore rtgroup objects. */ 69 void 70 xfs_free_rtgroups( 71 struct xfs_mount *mp, 72 xfs_rgnumber_t first_rgno, 73 xfs_rgnumber_t end_rgno) 74 { 75 xfs_rgnumber_t rgno; 76 77 for (rgno = first_rgno; rgno < end_rgno; rgno++) 78 xfs_rtgroup_free(mp, rgno); 79 } 80 81 /* Initialize some range of incore rtgroup objects. */ 82 int 83 xfs_initialize_rtgroups( 84 struct xfs_mount *mp, 85 xfs_rgnumber_t first_rgno, 86 xfs_rgnumber_t end_rgno, 87 xfs_rtbxlen_t rextents) 88 { 89 xfs_rgnumber_t index; 90 int error; 91 92 if (first_rgno >= end_rgno) 93 return 0; 94 95 for (index = first_rgno; index < end_rgno; index++) { 96 error = xfs_rtgroup_alloc(mp, index, end_rgno, rextents); 97 if (error) 98 goto out_unwind_new_rtgs; 99 } 100 101 return 0; 102 103 out_unwind_new_rtgs: 104 xfs_free_rtgroups(mp, first_rgno, index); 105 return error; 106 } 107 108 /* Compute the number of rt extents in this realtime group. */ 109 xfs_rtxnum_t 110 __xfs_rtgroup_extents( 111 struct xfs_mount *mp, 112 xfs_rgnumber_t rgno, 113 xfs_rgnumber_t rgcount, 114 xfs_rtbxlen_t rextents) 115 { 116 ASSERT(rgno < rgcount); 117 if (rgno == rgcount - 1) 118 return rextents - ((xfs_rtxnum_t)rgno * mp->m_sb.sb_rgextents); 119 120 ASSERT(xfs_has_rtgroups(mp)); 121 return mp->m_sb.sb_rgextents; 122 } 123 124 xfs_rtxnum_t 125 xfs_rtgroup_extents( 126 struct xfs_mount *mp, 127 xfs_rgnumber_t rgno) 128 { 129 return __xfs_rtgroup_extents(mp, rgno, mp->m_sb.sb_rgcount, 130 mp->m_sb.sb_rextents); 131 } 132 133 /* 134 * Update the rt extent count of the previous tail rtgroup if it changed during 135 * recovery (i.e. recovery of a growfs). 136 */ 137 int 138 xfs_update_last_rtgroup_size( 139 struct xfs_mount *mp, 140 xfs_rgnumber_t prev_rgcount) 141 { 142 struct xfs_rtgroup *rtg; 143 144 ASSERT(prev_rgcount > 0); 145 146 rtg = xfs_rtgroup_grab(mp, prev_rgcount - 1); 147 if (!rtg) 148 return -EFSCORRUPTED; 149 rtg->rtg_extents = __xfs_rtgroup_extents(mp, prev_rgcount - 1, 150 mp->m_sb.sb_rgcount, mp->m_sb.sb_rextents); 151 xfs_rtgroup_rele(rtg); 152 return 0; 153 } 154 155 /* Lock metadata inodes associated with this rt group. */ 156 void 157 xfs_rtgroup_lock( 158 struct xfs_rtgroup *rtg, 159 unsigned int rtglock_flags) 160 { 161 ASSERT(!(rtglock_flags & ~XFS_RTGLOCK_ALL_FLAGS)); 162 ASSERT(!(rtglock_flags & XFS_RTGLOCK_BITMAP_SHARED) || 163 !(rtglock_flags & XFS_RTGLOCK_BITMAP)); 164 165 if (rtglock_flags & XFS_RTGLOCK_BITMAP) { 166 /* 167 * Lock both realtime free space metadata inodes for a freespace 168 * update. 169 */ 170 xfs_ilock(rtg->rtg_inodes[XFS_RTGI_BITMAP], XFS_ILOCK_EXCL); 171 xfs_ilock(rtg->rtg_inodes[XFS_RTGI_SUMMARY], XFS_ILOCK_EXCL); 172 } else if (rtglock_flags & XFS_RTGLOCK_BITMAP_SHARED) { 173 xfs_ilock(rtg->rtg_inodes[XFS_RTGI_BITMAP], XFS_ILOCK_SHARED); 174 } 175 } 176 177 /* Unlock metadata inodes associated with this rt group. */ 178 void 179 xfs_rtgroup_unlock( 180 struct xfs_rtgroup *rtg, 181 unsigned int rtglock_flags) 182 { 183 ASSERT(!(rtglock_flags & ~XFS_RTGLOCK_ALL_FLAGS)); 184 ASSERT(!(rtglock_flags & XFS_RTGLOCK_BITMAP_SHARED) || 185 !(rtglock_flags & XFS_RTGLOCK_BITMAP)); 186 187 if (rtglock_flags & XFS_RTGLOCK_BITMAP) { 188 xfs_iunlock(rtg->rtg_inodes[XFS_RTGI_SUMMARY], XFS_ILOCK_EXCL); 189 xfs_iunlock(rtg->rtg_inodes[XFS_RTGI_BITMAP], XFS_ILOCK_EXCL); 190 } else if (rtglock_flags & XFS_RTGLOCK_BITMAP_SHARED) { 191 xfs_iunlock(rtg->rtg_inodes[XFS_RTGI_BITMAP], XFS_ILOCK_SHARED); 192 } 193 } 194 195 /* 196 * Join realtime group metadata inodes to the transaction. The ILOCKs will be 197 * released on transaction commit. 198 */ 199 void 200 xfs_rtgroup_trans_join( 201 struct xfs_trans *tp, 202 struct xfs_rtgroup *rtg, 203 unsigned int rtglock_flags) 204 { 205 ASSERT(!(rtglock_flags & ~XFS_RTGLOCK_ALL_FLAGS)); 206 ASSERT(!(rtglock_flags & XFS_RTGLOCK_BITMAP_SHARED)); 207 208 if (rtglock_flags & XFS_RTGLOCK_BITMAP) { 209 xfs_trans_ijoin(tp, rtg->rtg_inodes[XFS_RTGI_BITMAP], 210 XFS_ILOCK_EXCL); 211 xfs_trans_ijoin(tp, rtg->rtg_inodes[XFS_RTGI_SUMMARY], 212 XFS_ILOCK_EXCL); 213 } 214 } 215 216 #ifdef CONFIG_PROVE_LOCKING 217 static struct lock_class_key xfs_rtginode_lock_class; 218 219 static int 220 xfs_rtginode_ilock_cmp_fn( 221 const struct lockdep_map *m1, 222 const struct lockdep_map *m2) 223 { 224 const struct xfs_inode *ip1 = 225 container_of(m1, struct xfs_inode, i_lock.dep_map); 226 const struct xfs_inode *ip2 = 227 container_of(m2, struct xfs_inode, i_lock.dep_map); 228 229 if (ip1->i_projid < ip2->i_projid) 230 return -1; 231 if (ip1->i_projid > ip2->i_projid) 232 return 1; 233 return 0; 234 } 235 236 static inline void 237 xfs_rtginode_ilock_print_fn( 238 const struct lockdep_map *m) 239 { 240 const struct xfs_inode *ip = 241 container_of(m, struct xfs_inode, i_lock.dep_map); 242 243 printk(KERN_CONT " rgno=%u", ip->i_projid); 244 } 245 246 /* 247 * Most of the time each of the RTG inode locks are only taken one at a time. 248 * But when committing deferred ops, more than one of a kind can be taken. 249 * However, deferred rt ops will be committed in rgno order so there is no 250 * potential for deadlocks. The code here is needed to tell lockdep about this 251 * order. 252 */ 253 static inline void 254 xfs_rtginode_lockdep_setup( 255 struct xfs_inode *ip, 256 xfs_rgnumber_t rgno, 257 enum xfs_rtg_inodes type) 258 { 259 lockdep_set_class_and_subclass(&ip->i_lock, &xfs_rtginode_lock_class, 260 type); 261 lock_set_cmp_fn(&ip->i_lock, xfs_rtginode_ilock_cmp_fn, 262 xfs_rtginode_ilock_print_fn); 263 } 264 #else 265 #define xfs_rtginode_lockdep_setup(ip, rgno, type) do { } while (0) 266 #endif /* CONFIG_PROVE_LOCKING */ 267 268 struct xfs_rtginode_ops { 269 const char *name; /* short name */ 270 271 enum xfs_metafile_type metafile_type; 272 273 /* Does the fs have this feature? */ 274 bool (*enabled)(struct xfs_mount *mp); 275 }; 276 277 static const struct xfs_rtginode_ops xfs_rtginode_ops[XFS_RTGI_MAX] = { 278 [XFS_RTGI_BITMAP] = { 279 .name = "bitmap", 280 .metafile_type = XFS_METAFILE_RTBITMAP, 281 }, 282 [XFS_RTGI_SUMMARY] = { 283 .name = "summary", 284 .metafile_type = XFS_METAFILE_RTSUMMARY, 285 }, 286 }; 287 288 /* Return the shortname of this rtgroup inode. */ 289 const char * 290 xfs_rtginode_name( 291 enum xfs_rtg_inodes type) 292 { 293 return xfs_rtginode_ops[type].name; 294 } 295 296 /* Return the metafile type of this rtgroup inode. */ 297 enum xfs_metafile_type 298 xfs_rtginode_metafile_type( 299 enum xfs_rtg_inodes type) 300 { 301 return xfs_rtginode_ops[type].metafile_type; 302 } 303 304 /* Should this rtgroup inode be present? */ 305 bool 306 xfs_rtginode_enabled( 307 struct xfs_rtgroup *rtg, 308 enum xfs_rtg_inodes type) 309 { 310 const struct xfs_rtginode_ops *ops = &xfs_rtginode_ops[type]; 311 312 if (!ops->enabled) 313 return true; 314 return ops->enabled(rtg_mount(rtg)); 315 } 316 317 /* Load and existing rtgroup inode into the rtgroup structure. */ 318 int 319 xfs_rtginode_load( 320 struct xfs_rtgroup *rtg, 321 enum xfs_rtg_inodes type, 322 struct xfs_trans *tp) 323 { 324 struct xfs_mount *mp = tp->t_mountp; 325 struct xfs_inode *ip; 326 const struct xfs_rtginode_ops *ops = &xfs_rtginode_ops[type]; 327 int error; 328 329 if (!xfs_rtginode_enabled(rtg, type)) 330 return 0; 331 332 if (!xfs_has_rtgroups(mp)) { 333 xfs_ino_t ino; 334 335 switch (type) { 336 case XFS_RTGI_BITMAP: 337 ino = mp->m_sb.sb_rbmino; 338 break; 339 case XFS_RTGI_SUMMARY: 340 ino = mp->m_sb.sb_rsumino; 341 break; 342 default: 343 /* None of the other types exist on !rtgroups */ 344 return 0; 345 } 346 347 error = xfs_trans_metafile_iget(tp, ino, ops->metafile_type, 348 &ip); 349 } else { 350 const char *path; 351 352 if (!mp->m_rtdirip) 353 return -EFSCORRUPTED; 354 355 path = xfs_rtginode_path(rtg_rgno(rtg), type); 356 if (!path) 357 return -ENOMEM; 358 error = xfs_metadir_load(tp, mp->m_rtdirip, path, 359 ops->metafile_type, &ip); 360 kfree(path); 361 } 362 363 if (error) 364 return error; 365 366 if (XFS_IS_CORRUPT(mp, ip->i_df.if_format != XFS_DINODE_FMT_EXTENTS && 367 ip->i_df.if_format != XFS_DINODE_FMT_BTREE)) { 368 xfs_irele(ip); 369 return -EFSCORRUPTED; 370 } 371 372 if (XFS_IS_CORRUPT(mp, ip->i_projid != rtg_rgno(rtg))) { 373 xfs_irele(ip); 374 return -EFSCORRUPTED; 375 } 376 377 xfs_rtginode_lockdep_setup(ip, rtg_rgno(rtg), type); 378 rtg->rtg_inodes[type] = ip; 379 return 0; 380 } 381 382 /* Release an rtgroup metadata inode. */ 383 void 384 xfs_rtginode_irele( 385 struct xfs_inode **ipp) 386 { 387 if (*ipp) 388 xfs_irele(*ipp); 389 *ipp = NULL; 390 } 391 392 /* Create the parent directory for all rtgroup inodes and load it. */ 393 int 394 xfs_rtginode_mkdir_parent( 395 struct xfs_mount *mp) 396 { 397 if (!mp->m_metadirip) 398 return -EFSCORRUPTED; 399 400 return xfs_metadir_mkdir(mp->m_metadirip, "rtgroups", &mp->m_rtdirip); 401 } 402 403 /* Load the parent directory of all rtgroup inodes. */ 404 int 405 xfs_rtginode_load_parent( 406 struct xfs_trans *tp) 407 { 408 struct xfs_mount *mp = tp->t_mountp; 409 410 if (!mp->m_metadirip) 411 return -EFSCORRUPTED; 412 413 return xfs_metadir_load(tp, mp->m_metadirip, "rtgroups", 414 XFS_METAFILE_DIR, &mp->m_rtdirip); 415 } 416