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 /* Create this rtgroup metadata inode and initialize it. */ 277 int (*create)(struct xfs_rtgroup *rtg, 278 struct xfs_inode *ip, 279 struct xfs_trans *tp, 280 bool init); 281 }; 282 283 static const struct xfs_rtginode_ops xfs_rtginode_ops[XFS_RTGI_MAX] = { 284 [XFS_RTGI_BITMAP] = { 285 .name = "bitmap", 286 .metafile_type = XFS_METAFILE_RTBITMAP, 287 .create = xfs_rtbitmap_create, 288 }, 289 [XFS_RTGI_SUMMARY] = { 290 .name = "summary", 291 .metafile_type = XFS_METAFILE_RTSUMMARY, 292 .create = xfs_rtsummary_create, 293 }, 294 }; 295 296 /* Return the shortname of this rtgroup inode. */ 297 const char * 298 xfs_rtginode_name( 299 enum xfs_rtg_inodes type) 300 { 301 return xfs_rtginode_ops[type].name; 302 } 303 304 /* Return the metafile type of this rtgroup inode. */ 305 enum xfs_metafile_type 306 xfs_rtginode_metafile_type( 307 enum xfs_rtg_inodes type) 308 { 309 return xfs_rtginode_ops[type].metafile_type; 310 } 311 312 /* Should this rtgroup inode be present? */ 313 bool 314 xfs_rtginode_enabled( 315 struct xfs_rtgroup *rtg, 316 enum xfs_rtg_inodes type) 317 { 318 const struct xfs_rtginode_ops *ops = &xfs_rtginode_ops[type]; 319 320 if (!ops->enabled) 321 return true; 322 return ops->enabled(rtg_mount(rtg)); 323 } 324 325 /* Load and existing rtgroup inode into the rtgroup structure. */ 326 int 327 xfs_rtginode_load( 328 struct xfs_rtgroup *rtg, 329 enum xfs_rtg_inodes type, 330 struct xfs_trans *tp) 331 { 332 struct xfs_mount *mp = tp->t_mountp; 333 struct xfs_inode *ip; 334 const struct xfs_rtginode_ops *ops = &xfs_rtginode_ops[type]; 335 int error; 336 337 if (!xfs_rtginode_enabled(rtg, type)) 338 return 0; 339 340 if (!xfs_has_rtgroups(mp)) { 341 xfs_ino_t ino; 342 343 switch (type) { 344 case XFS_RTGI_BITMAP: 345 ino = mp->m_sb.sb_rbmino; 346 break; 347 case XFS_RTGI_SUMMARY: 348 ino = mp->m_sb.sb_rsumino; 349 break; 350 default: 351 /* None of the other types exist on !rtgroups */ 352 return 0; 353 } 354 355 error = xfs_trans_metafile_iget(tp, ino, ops->metafile_type, 356 &ip); 357 } else { 358 const char *path; 359 360 if (!mp->m_rtdirip) 361 return -EFSCORRUPTED; 362 363 path = xfs_rtginode_path(rtg_rgno(rtg), type); 364 if (!path) 365 return -ENOMEM; 366 error = xfs_metadir_load(tp, mp->m_rtdirip, path, 367 ops->metafile_type, &ip); 368 kfree(path); 369 } 370 371 if (error) 372 return error; 373 374 if (XFS_IS_CORRUPT(mp, ip->i_df.if_format != XFS_DINODE_FMT_EXTENTS && 375 ip->i_df.if_format != XFS_DINODE_FMT_BTREE)) { 376 xfs_irele(ip); 377 return -EFSCORRUPTED; 378 } 379 380 if (XFS_IS_CORRUPT(mp, ip->i_projid != rtg_rgno(rtg))) { 381 xfs_irele(ip); 382 return -EFSCORRUPTED; 383 } 384 385 xfs_rtginode_lockdep_setup(ip, rtg_rgno(rtg), type); 386 rtg->rtg_inodes[type] = ip; 387 return 0; 388 } 389 390 /* Release an rtgroup metadata inode. */ 391 void 392 xfs_rtginode_irele( 393 struct xfs_inode **ipp) 394 { 395 if (*ipp) 396 xfs_irele(*ipp); 397 *ipp = NULL; 398 } 399 400 /* Add a metadata inode for a realtime rmap btree. */ 401 int 402 xfs_rtginode_create( 403 struct xfs_rtgroup *rtg, 404 enum xfs_rtg_inodes type, 405 bool init) 406 { 407 const struct xfs_rtginode_ops *ops = &xfs_rtginode_ops[type]; 408 struct xfs_mount *mp = rtg_mount(rtg); 409 struct xfs_metadir_update upd = { 410 .dp = mp->m_rtdirip, 411 .metafile_type = ops->metafile_type, 412 }; 413 int error; 414 415 if (!xfs_rtginode_enabled(rtg, type)) 416 return 0; 417 418 if (!mp->m_rtdirip) 419 return -EFSCORRUPTED; 420 421 upd.path = xfs_rtginode_path(rtg_rgno(rtg), type); 422 if (!upd.path) 423 return -ENOMEM; 424 425 error = xfs_metadir_start_create(&upd); 426 if (error) 427 goto out_path; 428 429 error = xfs_metadir_create(&upd, S_IFREG); 430 if (error) 431 return error; 432 433 xfs_rtginode_lockdep_setup(upd.ip, rtg_rgno(rtg), type); 434 435 upd.ip->i_projid = rtg_rgno(rtg); 436 error = ops->create(rtg, upd.ip, upd.tp, init); 437 if (error) 438 goto out_cancel; 439 440 error = xfs_metadir_commit(&upd); 441 if (error) 442 goto out_path; 443 444 kfree(upd.path); 445 xfs_finish_inode_setup(upd.ip); 446 rtg->rtg_inodes[type] = upd.ip; 447 return 0; 448 449 out_cancel: 450 xfs_metadir_cancel(&upd, error); 451 /* Have to finish setting up the inode to ensure it's deleted. */ 452 if (upd.ip) { 453 xfs_finish_inode_setup(upd.ip); 454 xfs_irele(upd.ip); 455 } 456 out_path: 457 kfree(upd.path); 458 return error; 459 } 460 461 /* Create the parent directory for all rtgroup inodes and load it. */ 462 int 463 xfs_rtginode_mkdir_parent( 464 struct xfs_mount *mp) 465 { 466 if (!mp->m_metadirip) 467 return -EFSCORRUPTED; 468 469 return xfs_metadir_mkdir(mp->m_metadirip, "rtgroups", &mp->m_rtdirip); 470 } 471 472 /* Load the parent directory of all rtgroup inodes. */ 473 int 474 xfs_rtginode_load_parent( 475 struct xfs_trans *tp) 476 { 477 struct xfs_mount *mp = tp->t_mountp; 478 479 if (!mp->m_metadirip) 480 return -EFSCORRUPTED; 481 482 return xfs_metadir_load(tp, mp->m_metadirip, "rtgroups", 483 XFS_METAFILE_DIR, &mp->m_rtdirip); 484 } 485