1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. 4 * Copyright (C) 2010 Red Hat, Inc. 5 * All Rights Reserved. 6 */ 7 #include "xfs.h" 8 #include "xfs_fs.h" 9 #include "xfs_shared.h" 10 #include "xfs_format.h" 11 #include "xfs_log_format.h" 12 #include "xfs_trans_resv.h" 13 #include "xfs_mount.h" 14 #include "xfs_da_format.h" 15 #include "xfs_da_btree.h" 16 #include "xfs_inode.h" 17 #include "xfs_bmap_btree.h" 18 #include "xfs_quota.h" 19 #include "xfs_trans.h" 20 #include "xfs_qm.h" 21 #include "xfs_trans_space.h" 22 23 #define _ALLOC true 24 #define _FREE false 25 26 /* 27 * A buffer has a format structure overhead in the log in addition 28 * to the data, so we need to take this into account when reserving 29 * space in a transaction for a buffer. Round the space required up 30 * to a multiple of 128 bytes so that we don't change the historical 31 * reservation that has been used for this overhead. 32 */ 33 STATIC uint 34 xfs_buf_log_overhead(void) 35 { 36 return round_up(sizeof(struct xlog_op_header) + 37 sizeof(struct xfs_buf_log_format), 128); 38 } 39 40 /* 41 * Calculate out transaction log reservation per item in bytes. 42 * 43 * The nbufs argument is used to indicate the number of items that 44 * will be changed in a transaction. size is used to tell how many 45 * bytes should be reserved per item. 46 */ 47 STATIC uint 48 xfs_calc_buf_res( 49 uint nbufs, 50 uint size) 51 { 52 return nbufs * (size + xfs_buf_log_overhead()); 53 } 54 55 /* 56 * Per-extent log reservation for the btree changes involved in freeing or 57 * allocating an extent. In classic XFS there were two trees that will be 58 * modified (bnobt + cntbt). With rmap enabled, there are three trees 59 * (rmapbt). With reflink, there are four trees (refcountbt). The number of 60 * blocks reserved is based on the formula: 61 * 62 * num trees * ((2 blocks/level * max depth) - 1) 63 * 64 * Keep in mind that max depth is calculated separately for each type of tree. 65 */ 66 uint 67 xfs_allocfree_log_count( 68 struct xfs_mount *mp, 69 uint num_ops) 70 { 71 uint blocks; 72 73 blocks = num_ops * 2 * (2 * mp->m_ag_maxlevels - 1); 74 if (xfs_sb_version_hasrmapbt(&mp->m_sb)) 75 blocks += num_ops * (2 * mp->m_rmap_maxlevels - 1); 76 if (xfs_sb_version_hasreflink(&mp->m_sb)) 77 blocks += num_ops * (2 * mp->m_refc_maxlevels - 1); 78 79 return blocks; 80 } 81 82 /* 83 * Logging inodes is really tricksy. They are logged in memory format, 84 * which means that what we write into the log doesn't directly translate into 85 * the amount of space they use on disk. 86 * 87 * Case in point - btree format forks in memory format use more space than the 88 * on-disk format. In memory, the buffer contains a normal btree block header so 89 * the btree code can treat it as though it is just another generic buffer. 90 * However, when we write it to the inode fork, we don't write all of this 91 * header as it isn't needed. e.g. the root is only ever in the inode, so 92 * there's no need for sibling pointers which would waste 16 bytes of space. 93 * 94 * Hence when we have an inode with a maximally sized btree format fork, then 95 * amount of information we actually log is greater than the size of the inode 96 * on disk. Hence we need an inode reservation function that calculates all this 97 * correctly. So, we log: 98 * 99 * - 4 log op headers for object 100 * - for the ilf, the inode core and 2 forks 101 * - inode log format object 102 * - the inode core 103 * - two inode forks containing bmap btree root blocks. 104 * - the btree data contained by both forks will fit into the inode size, 105 * hence when combined with the inode core above, we have a total of the 106 * actual inode size. 107 * - the BMBT headers need to be accounted separately, as they are 108 * additional to the records and pointers that fit inside the inode 109 * forks. 110 */ 111 STATIC uint 112 xfs_calc_inode_res( 113 struct xfs_mount *mp, 114 uint ninodes) 115 { 116 return ninodes * 117 (4 * sizeof(struct xlog_op_header) + 118 sizeof(struct xfs_inode_log_format) + 119 mp->m_sb.sb_inodesize + 120 2 * XFS_BMBT_BLOCK_LEN(mp)); 121 } 122 123 /* 124 * Inode btree record insertion/removal modifies the inode btree and free space 125 * btrees (since the inobt does not use the agfl). This requires the following 126 * reservation: 127 * 128 * the inode btree: max depth * blocksize 129 * the allocation btrees: 2 trees * (max depth - 1) * block size 130 * 131 * The caller must account for SB and AG header modifications, etc. 132 */ 133 STATIC uint 134 xfs_calc_inobt_res( 135 struct xfs_mount *mp) 136 { 137 return xfs_calc_buf_res(M_IGEO(mp)->inobt_maxlevels, 138 XFS_FSB_TO_B(mp, 1)) + 139 xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), 140 XFS_FSB_TO_B(mp, 1)); 141 } 142 143 /* 144 * The free inode btree is a conditional feature. The behavior differs slightly 145 * from that of the traditional inode btree in that the finobt tracks records 146 * for inode chunks with at least one free inode. A record can be removed from 147 * the tree during individual inode allocation. Therefore the finobt 148 * reservation is unconditional for both the inode chunk allocation and 149 * individual inode allocation (modify) cases. 150 * 151 * Behavior aside, the reservation for finobt modification is equivalent to the 152 * traditional inobt: cover a full finobt shape change plus block allocation. 153 */ 154 STATIC uint 155 xfs_calc_finobt_res( 156 struct xfs_mount *mp) 157 { 158 if (!xfs_sb_version_hasfinobt(&mp->m_sb)) 159 return 0; 160 161 return xfs_calc_inobt_res(mp); 162 } 163 164 /* 165 * Calculate the reservation required to allocate or free an inode chunk. This 166 * includes: 167 * 168 * the allocation btrees: 2 trees * (max depth - 1) * block size 169 * the inode chunk: m_ino_geo.ialloc_blks * N 170 * 171 * The size N of the inode chunk reservation depends on whether it is for 172 * allocation or free and which type of create transaction is in use. An inode 173 * chunk free always invalidates the buffers and only requires reservation for 174 * headers (N == 0). An inode chunk allocation requires a chunk sized 175 * reservation on v4 and older superblocks to initialize the chunk. No chunk 176 * reservation is required for allocation on v5 supers, which use ordered 177 * buffers to initialize. 178 */ 179 STATIC uint 180 xfs_calc_inode_chunk_res( 181 struct xfs_mount *mp, 182 bool alloc) 183 { 184 uint res, size = 0; 185 186 res = xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), 187 XFS_FSB_TO_B(mp, 1)); 188 if (alloc) { 189 /* icreate tx uses ordered buffers */ 190 if (xfs_sb_version_hascrc(&mp->m_sb)) 191 return res; 192 size = XFS_FSB_TO_B(mp, 1); 193 } 194 195 res += xfs_calc_buf_res(M_IGEO(mp)->ialloc_blks, size); 196 return res; 197 } 198 199 /* 200 * Various log reservation values. 201 * 202 * These are based on the size of the file system block because that is what 203 * most transactions manipulate. Each adds in an additional 128 bytes per 204 * item logged to try to account for the overhead of the transaction mechanism. 205 * 206 * Note: Most of the reservations underestimate the number of allocation 207 * groups into which they could free extents in the xfs_defer_finish() call. 208 * This is because the number in the worst case is quite high and quite 209 * unusual. In order to fix this we need to change xfs_defer_finish() to free 210 * extents in only a single AG at a time. This will require changes to the 211 * EFI code as well, however, so that the EFI for the extents not freed is 212 * logged again in each transaction. See SGI PV #261917. 213 * 214 * Reservation functions here avoid a huge stack in xfs_trans_init due to 215 * register overflow from temporaries in the calculations. 216 */ 217 218 219 /* 220 * In a write transaction we can allocate a maximum of 2 221 * extents. This gives: 222 * the inode getting the new extents: inode size 223 * the inode's bmap btree: max depth * block size 224 * the agfs of the ags from which the extents are allocated: 2 * sector 225 * the superblock free block counter: sector size 226 * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size 227 * And the bmap_finish transaction can free bmap blocks in a join: 228 * the agfs of the ags containing the blocks: 2 * sector size 229 * the agfls of the ags containing the blocks: 2 * sector size 230 * the super block free block counter: sector size 231 * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size 232 */ 233 STATIC uint 234 xfs_calc_write_reservation( 235 struct xfs_mount *mp) 236 { 237 return XFS_DQUOT_LOGRES(mp) + 238 max((xfs_calc_inode_res(mp, 1) + 239 xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK), 240 XFS_FSB_TO_B(mp, 1)) + 241 xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) + 242 xfs_calc_buf_res(xfs_allocfree_log_count(mp, 2), 243 XFS_FSB_TO_B(mp, 1))), 244 (xfs_calc_buf_res(5, mp->m_sb.sb_sectsize) + 245 xfs_calc_buf_res(xfs_allocfree_log_count(mp, 2), 246 XFS_FSB_TO_B(mp, 1)))); 247 } 248 249 /* 250 * In truncating a file we free up to two extents at once. We can modify: 251 * the inode being truncated: inode size 252 * the inode's bmap btree: (max depth + 1) * block size 253 * And the bmap_finish transaction can free the blocks and bmap blocks: 254 * the agf for each of the ags: 4 * sector size 255 * the agfl for each of the ags: 4 * sector size 256 * the super block to reflect the freed blocks: sector size 257 * worst case split in allocation btrees per extent assuming 4 extents: 258 * 4 exts * 2 trees * (2 * max depth - 1) * block size 259 */ 260 STATIC uint 261 xfs_calc_itruncate_reservation( 262 struct xfs_mount *mp) 263 { 264 return XFS_DQUOT_LOGRES(mp) + 265 max((xfs_calc_inode_res(mp, 1) + 266 xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + 1, 267 XFS_FSB_TO_B(mp, 1))), 268 (xfs_calc_buf_res(9, mp->m_sb.sb_sectsize) + 269 xfs_calc_buf_res(xfs_allocfree_log_count(mp, 4), 270 XFS_FSB_TO_B(mp, 1)))); 271 } 272 273 /* 274 * In renaming a files we can modify: 275 * the four inodes involved: 4 * inode size 276 * the two directory btrees: 2 * (max depth + v2) * dir block size 277 * the two directory bmap btrees: 2 * max depth * block size 278 * And the bmap_finish transaction can free dir and bmap blocks (two sets 279 * of bmap blocks) giving: 280 * the agf for the ags in which the blocks live: 3 * sector size 281 * the agfl for the ags in which the blocks live: 3 * sector size 282 * the superblock for the free block count: sector size 283 * the allocation btrees: 3 exts * 2 trees * (2 * max depth - 1) * block size 284 */ 285 STATIC uint 286 xfs_calc_rename_reservation( 287 struct xfs_mount *mp) 288 { 289 return XFS_DQUOT_LOGRES(mp) + 290 max((xfs_calc_inode_res(mp, 4) + 291 xfs_calc_buf_res(2 * XFS_DIROP_LOG_COUNT(mp), 292 XFS_FSB_TO_B(mp, 1))), 293 (xfs_calc_buf_res(7, mp->m_sb.sb_sectsize) + 294 xfs_calc_buf_res(xfs_allocfree_log_count(mp, 3), 295 XFS_FSB_TO_B(mp, 1)))); 296 } 297 298 /* 299 * For removing an inode from unlinked list at first, we can modify: 300 * the agi hash list and counters: sector size 301 * the on disk inode before ours in the agi hash list: inode cluster size 302 * the on disk inode in the agi hash list: inode cluster size 303 */ 304 STATIC uint 305 xfs_calc_iunlink_remove_reservation( 306 struct xfs_mount *mp) 307 { 308 return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) + 309 2 * M_IGEO(mp)->inode_cluster_size; 310 } 311 312 /* 313 * For creating a link to an inode: 314 * the parent directory inode: inode size 315 * the linked inode: inode size 316 * the directory btree could split: (max depth + v2) * dir block size 317 * the directory bmap btree could join or split: (max depth + v2) * blocksize 318 * And the bmap_finish transaction can free some bmap blocks giving: 319 * the agf for the ag in which the blocks live: sector size 320 * the agfl for the ag in which the blocks live: sector size 321 * the superblock for the free block count: sector size 322 * the allocation btrees: 2 trees * (2 * max depth - 1) * block size 323 */ 324 STATIC uint 325 xfs_calc_link_reservation( 326 struct xfs_mount *mp) 327 { 328 return XFS_DQUOT_LOGRES(mp) + 329 xfs_calc_iunlink_remove_reservation(mp) + 330 max((xfs_calc_inode_res(mp, 2) + 331 xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), 332 XFS_FSB_TO_B(mp, 1))), 333 (xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) + 334 xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), 335 XFS_FSB_TO_B(mp, 1)))); 336 } 337 338 /* 339 * For adding an inode to unlinked list we can modify: 340 * the agi hash list: sector size 341 * the on disk inode: inode cluster size 342 */ 343 STATIC uint 344 xfs_calc_iunlink_add_reservation(xfs_mount_t *mp) 345 { 346 return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) + 347 M_IGEO(mp)->inode_cluster_size; 348 } 349 350 /* 351 * For removing a directory entry we can modify: 352 * the parent directory inode: inode size 353 * the removed inode: inode size 354 * the directory btree could join: (max depth + v2) * dir block size 355 * the directory bmap btree could join or split: (max depth + v2) * blocksize 356 * And the bmap_finish transaction can free the dir and bmap blocks giving: 357 * the agf for the ag in which the blocks live: 2 * sector size 358 * the agfl for the ag in which the blocks live: 2 * sector size 359 * the superblock for the free block count: sector size 360 * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size 361 */ 362 STATIC uint 363 xfs_calc_remove_reservation( 364 struct xfs_mount *mp) 365 { 366 return XFS_DQUOT_LOGRES(mp) + 367 xfs_calc_iunlink_add_reservation(mp) + 368 max((xfs_calc_inode_res(mp, 1) + 369 xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), 370 XFS_FSB_TO_B(mp, 1))), 371 (xfs_calc_buf_res(4, mp->m_sb.sb_sectsize) + 372 xfs_calc_buf_res(xfs_allocfree_log_count(mp, 2), 373 XFS_FSB_TO_B(mp, 1)))); 374 } 375 376 /* 377 * For create, break it in to the two cases that the transaction 378 * covers. We start with the modify case - allocation done by modification 379 * of the state of existing inodes - and the allocation case. 380 */ 381 382 /* 383 * For create we can modify: 384 * the parent directory inode: inode size 385 * the new inode: inode size 386 * the inode btree entry: block size 387 * the superblock for the nlink flag: sector size 388 * the directory btree: (max depth + v2) * dir block size 389 * the directory inode's bmap btree: (max depth + v2) * block size 390 * the finobt (record modification and allocation btrees) 391 */ 392 STATIC uint 393 xfs_calc_create_resv_modify( 394 struct xfs_mount *mp) 395 { 396 return xfs_calc_inode_res(mp, 2) + 397 xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) + 398 (uint)XFS_FSB_TO_B(mp, 1) + 399 xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), XFS_FSB_TO_B(mp, 1)) + 400 xfs_calc_finobt_res(mp); 401 } 402 403 /* 404 * For icreate we can allocate some inodes giving: 405 * the agi and agf of the ag getting the new inodes: 2 * sectorsize 406 * the superblock for the nlink flag: sector size 407 * the inode chunk (allocation, optional init) 408 * the inobt (record insertion) 409 * the finobt (optional, record insertion) 410 */ 411 STATIC uint 412 xfs_calc_icreate_resv_alloc( 413 struct xfs_mount *mp) 414 { 415 return xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) + 416 mp->m_sb.sb_sectsize + 417 xfs_calc_inode_chunk_res(mp, _ALLOC) + 418 xfs_calc_inobt_res(mp) + 419 xfs_calc_finobt_res(mp); 420 } 421 422 STATIC uint 423 xfs_calc_icreate_reservation(xfs_mount_t *mp) 424 { 425 return XFS_DQUOT_LOGRES(mp) + 426 max(xfs_calc_icreate_resv_alloc(mp), 427 xfs_calc_create_resv_modify(mp)); 428 } 429 430 STATIC uint 431 xfs_calc_create_tmpfile_reservation( 432 struct xfs_mount *mp) 433 { 434 uint res = XFS_DQUOT_LOGRES(mp); 435 436 res += xfs_calc_icreate_resv_alloc(mp); 437 return res + xfs_calc_iunlink_add_reservation(mp); 438 } 439 440 /* 441 * Making a new directory is the same as creating a new file. 442 */ 443 STATIC uint 444 xfs_calc_mkdir_reservation( 445 struct xfs_mount *mp) 446 { 447 return xfs_calc_icreate_reservation(mp); 448 } 449 450 451 /* 452 * Making a new symplink is the same as creating a new file, but 453 * with the added blocks for remote symlink data which can be up to 1kB in 454 * length (XFS_SYMLINK_MAXLEN). 455 */ 456 STATIC uint 457 xfs_calc_symlink_reservation( 458 struct xfs_mount *mp) 459 { 460 return xfs_calc_icreate_reservation(mp) + 461 xfs_calc_buf_res(1, XFS_SYMLINK_MAXLEN); 462 } 463 464 /* 465 * In freeing an inode we can modify: 466 * the inode being freed: inode size 467 * the super block free inode counter, AGF and AGFL: sector size 468 * the on disk inode (agi unlinked list removal) 469 * the inode chunk (invalidated, headers only) 470 * the inode btree 471 * the finobt (record insertion, removal or modification) 472 * 473 * Note that the inode chunk res. includes an allocfree res. for freeing of the 474 * inode chunk. This is technically extraneous because the inode chunk free is 475 * deferred (it occurs after a transaction roll). Include the extra reservation 476 * anyways since we've had reports of ifree transaction overruns due to too many 477 * agfl fixups during inode chunk frees. 478 */ 479 STATIC uint 480 xfs_calc_ifree_reservation( 481 struct xfs_mount *mp) 482 { 483 return XFS_DQUOT_LOGRES(mp) + 484 xfs_calc_inode_res(mp, 1) + 485 xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) + 486 xfs_calc_iunlink_remove_reservation(mp) + 487 xfs_calc_inode_chunk_res(mp, _FREE) + 488 xfs_calc_inobt_res(mp) + 489 xfs_calc_finobt_res(mp); 490 } 491 492 /* 493 * When only changing the inode we log the inode and possibly the superblock 494 * We also add a bit of slop for the transaction stuff. 495 */ 496 STATIC uint 497 xfs_calc_ichange_reservation( 498 struct xfs_mount *mp) 499 { 500 return XFS_DQUOT_LOGRES(mp) + 501 xfs_calc_inode_res(mp, 1) + 502 xfs_calc_buf_res(1, mp->m_sb.sb_sectsize); 503 504 } 505 506 /* 507 * Growing the data section of the filesystem. 508 * superblock 509 * agi and agf 510 * allocation btrees 511 */ 512 STATIC uint 513 xfs_calc_growdata_reservation( 514 struct xfs_mount *mp) 515 { 516 return xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) + 517 xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), 518 XFS_FSB_TO_B(mp, 1)); 519 } 520 521 /* 522 * Growing the rt section of the filesystem. 523 * In the first set of transactions (ALLOC) we allocate space to the 524 * bitmap or summary files. 525 * superblock: sector size 526 * agf of the ag from which the extent is allocated: sector size 527 * bmap btree for bitmap/summary inode: max depth * blocksize 528 * bitmap/summary inode: inode size 529 * allocation btrees for 1 block alloc: 2 * (2 * maxdepth - 1) * blocksize 530 */ 531 STATIC uint 532 xfs_calc_growrtalloc_reservation( 533 struct xfs_mount *mp) 534 { 535 return xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) + 536 xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK), 537 XFS_FSB_TO_B(mp, 1)) + 538 xfs_calc_inode_res(mp, 1) + 539 xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), 540 XFS_FSB_TO_B(mp, 1)); 541 } 542 543 /* 544 * Growing the rt section of the filesystem. 545 * In the second set of transactions (ZERO) we zero the new metadata blocks. 546 * one bitmap/summary block: blocksize 547 */ 548 STATIC uint 549 xfs_calc_growrtzero_reservation( 550 struct xfs_mount *mp) 551 { 552 return xfs_calc_buf_res(1, mp->m_sb.sb_blocksize); 553 } 554 555 /* 556 * Growing the rt section of the filesystem. 557 * In the third set of transactions (FREE) we update metadata without 558 * allocating any new blocks. 559 * superblock: sector size 560 * bitmap inode: inode size 561 * summary inode: inode size 562 * one bitmap block: blocksize 563 * summary blocks: new summary size 564 */ 565 STATIC uint 566 xfs_calc_growrtfree_reservation( 567 struct xfs_mount *mp) 568 { 569 return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) + 570 xfs_calc_inode_res(mp, 2) + 571 xfs_calc_buf_res(1, mp->m_sb.sb_blocksize) + 572 xfs_calc_buf_res(1, mp->m_rsumsize); 573 } 574 575 /* 576 * Logging the inode modification timestamp on a synchronous write. 577 * inode 578 */ 579 STATIC uint 580 xfs_calc_swrite_reservation( 581 struct xfs_mount *mp) 582 { 583 return xfs_calc_inode_res(mp, 1); 584 } 585 586 /* 587 * Logging the inode mode bits when writing a setuid/setgid file 588 * inode 589 */ 590 STATIC uint 591 xfs_calc_writeid_reservation( 592 struct xfs_mount *mp) 593 { 594 return xfs_calc_inode_res(mp, 1); 595 } 596 597 /* 598 * Converting the inode from non-attributed to attributed. 599 * the inode being converted: inode size 600 * agf block and superblock (for block allocation) 601 * the new block (directory sized) 602 * bmap blocks for the new directory block 603 * allocation btrees 604 */ 605 STATIC uint 606 xfs_calc_addafork_reservation( 607 struct xfs_mount *mp) 608 { 609 return XFS_DQUOT_LOGRES(mp) + 610 xfs_calc_inode_res(mp, 1) + 611 xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) + 612 xfs_calc_buf_res(1, mp->m_dir_geo->blksize) + 613 xfs_calc_buf_res(XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1, 614 XFS_FSB_TO_B(mp, 1)) + 615 xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), 616 XFS_FSB_TO_B(mp, 1)); 617 } 618 619 /* 620 * Removing the attribute fork of a file 621 * the inode being truncated: inode size 622 * the inode's bmap btree: max depth * block size 623 * And the bmap_finish transaction can free the blocks and bmap blocks: 624 * the agf for each of the ags: 4 * sector size 625 * the agfl for each of the ags: 4 * sector size 626 * the super block to reflect the freed blocks: sector size 627 * worst case split in allocation btrees per extent assuming 4 extents: 628 * 4 exts * 2 trees * (2 * max depth - 1) * block size 629 */ 630 STATIC uint 631 xfs_calc_attrinval_reservation( 632 struct xfs_mount *mp) 633 { 634 return max((xfs_calc_inode_res(mp, 1) + 635 xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK), 636 XFS_FSB_TO_B(mp, 1))), 637 (xfs_calc_buf_res(9, mp->m_sb.sb_sectsize) + 638 xfs_calc_buf_res(xfs_allocfree_log_count(mp, 4), 639 XFS_FSB_TO_B(mp, 1)))); 640 } 641 642 /* 643 * Setting an attribute at mount time. 644 * the inode getting the attribute 645 * the superblock for allocations 646 * the agfs extents are allocated from 647 * the attribute btree * max depth 648 * the inode allocation btree 649 * Since attribute transaction space is dependent on the size of the attribute, 650 * the calculation is done partially at mount time and partially at runtime(see 651 * below). 652 */ 653 STATIC uint 654 xfs_calc_attrsetm_reservation( 655 struct xfs_mount *mp) 656 { 657 return XFS_DQUOT_LOGRES(mp) + 658 xfs_calc_inode_res(mp, 1) + 659 xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) + 660 xfs_calc_buf_res(XFS_DA_NODE_MAXDEPTH, XFS_FSB_TO_B(mp, 1)); 661 } 662 663 /* 664 * Setting an attribute at runtime, transaction space unit per block. 665 * the superblock for allocations: sector size 666 * the inode bmap btree could join or split: max depth * block size 667 * Since the runtime attribute transaction space is dependent on the total 668 * blocks needed for the 1st bmap, here we calculate out the space unit for 669 * one block so that the caller could figure out the total space according 670 * to the attibute extent length in blocks by: 671 * ext * M_RES(mp)->tr_attrsetrt.tr_logres 672 */ 673 STATIC uint 674 xfs_calc_attrsetrt_reservation( 675 struct xfs_mount *mp) 676 { 677 return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) + 678 xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK), 679 XFS_FSB_TO_B(mp, 1)); 680 } 681 682 /* 683 * Removing an attribute. 684 * the inode: inode size 685 * the attribute btree could join: max depth * block size 686 * the inode bmap btree could join or split: max depth * block size 687 * And the bmap_finish transaction can free the attr blocks freed giving: 688 * the agf for the ag in which the blocks live: 2 * sector size 689 * the agfl for the ag in which the blocks live: 2 * sector size 690 * the superblock for the free block count: sector size 691 * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size 692 */ 693 STATIC uint 694 xfs_calc_attrrm_reservation( 695 struct xfs_mount *mp) 696 { 697 return XFS_DQUOT_LOGRES(mp) + 698 max((xfs_calc_inode_res(mp, 1) + 699 xfs_calc_buf_res(XFS_DA_NODE_MAXDEPTH, 700 XFS_FSB_TO_B(mp, 1)) + 701 (uint)XFS_FSB_TO_B(mp, 702 XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) + 703 xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK), 0)), 704 (xfs_calc_buf_res(5, mp->m_sb.sb_sectsize) + 705 xfs_calc_buf_res(xfs_allocfree_log_count(mp, 2), 706 XFS_FSB_TO_B(mp, 1)))); 707 } 708 709 /* 710 * Clearing a bad agino number in an agi hash bucket. 711 */ 712 STATIC uint 713 xfs_calc_clear_agi_bucket_reservation( 714 struct xfs_mount *mp) 715 { 716 return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize); 717 } 718 719 /* 720 * Adjusting quota limits. 721 * the xfs_disk_dquot_t: sizeof(struct xfs_disk_dquot) 722 */ 723 STATIC uint 724 xfs_calc_qm_setqlim_reservation(void) 725 { 726 return xfs_calc_buf_res(1, sizeof(struct xfs_disk_dquot)); 727 } 728 729 /* 730 * Allocating quota on disk if needed. 731 * the write transaction log space for quota file extent allocation 732 * the unit of quota allocation: one system block size 733 */ 734 STATIC uint 735 xfs_calc_qm_dqalloc_reservation( 736 struct xfs_mount *mp) 737 { 738 return xfs_calc_write_reservation(mp) + 739 xfs_calc_buf_res(1, 740 XFS_FSB_TO_B(mp, XFS_DQUOT_CLUSTER_SIZE_FSB) - 1); 741 } 742 743 /* 744 * Turning off quotas. 745 * the xfs_qoff_logitem_t: sizeof(struct xfs_qoff_logitem) * 2 746 * the superblock for the quota flags: sector size 747 */ 748 STATIC uint 749 xfs_calc_qm_quotaoff_reservation( 750 struct xfs_mount *mp) 751 { 752 return sizeof(struct xfs_qoff_logitem) * 2 + 753 xfs_calc_buf_res(1, mp->m_sb.sb_sectsize); 754 } 755 756 /* 757 * End of turning off quotas. 758 * the xfs_qoff_logitem_t: sizeof(struct xfs_qoff_logitem) * 2 759 */ 760 STATIC uint 761 xfs_calc_qm_quotaoff_end_reservation(void) 762 { 763 return sizeof(struct xfs_qoff_logitem) * 2; 764 } 765 766 /* 767 * Syncing the incore super block changes to disk. 768 * the super block to reflect the changes: sector size 769 */ 770 STATIC uint 771 xfs_calc_sb_reservation( 772 struct xfs_mount *mp) 773 { 774 return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize); 775 } 776 777 void 778 xfs_trans_resv_calc( 779 struct xfs_mount *mp, 780 struct xfs_trans_resv *resp) 781 { 782 /* 783 * The following transactions are logged in physical format and 784 * require a permanent reservation on space. 785 */ 786 resp->tr_write.tr_logres = xfs_calc_write_reservation(mp); 787 if (xfs_sb_version_hasreflink(&mp->m_sb)) 788 resp->tr_write.tr_logcount = XFS_WRITE_LOG_COUNT_REFLINK; 789 else 790 resp->tr_write.tr_logcount = XFS_WRITE_LOG_COUNT; 791 resp->tr_write.tr_logflags |= XFS_TRANS_PERM_LOG_RES; 792 793 resp->tr_itruncate.tr_logres = xfs_calc_itruncate_reservation(mp); 794 if (xfs_sb_version_hasreflink(&mp->m_sb)) 795 resp->tr_itruncate.tr_logcount = 796 XFS_ITRUNCATE_LOG_COUNT_REFLINK; 797 else 798 resp->tr_itruncate.tr_logcount = XFS_ITRUNCATE_LOG_COUNT; 799 resp->tr_itruncate.tr_logflags |= XFS_TRANS_PERM_LOG_RES; 800 801 resp->tr_rename.tr_logres = xfs_calc_rename_reservation(mp); 802 resp->tr_rename.tr_logcount = XFS_RENAME_LOG_COUNT; 803 resp->tr_rename.tr_logflags |= XFS_TRANS_PERM_LOG_RES; 804 805 resp->tr_link.tr_logres = xfs_calc_link_reservation(mp); 806 resp->tr_link.tr_logcount = XFS_LINK_LOG_COUNT; 807 resp->tr_link.tr_logflags |= XFS_TRANS_PERM_LOG_RES; 808 809 resp->tr_remove.tr_logres = xfs_calc_remove_reservation(mp); 810 resp->tr_remove.tr_logcount = XFS_REMOVE_LOG_COUNT; 811 resp->tr_remove.tr_logflags |= XFS_TRANS_PERM_LOG_RES; 812 813 resp->tr_symlink.tr_logres = xfs_calc_symlink_reservation(mp); 814 resp->tr_symlink.tr_logcount = XFS_SYMLINK_LOG_COUNT; 815 resp->tr_symlink.tr_logflags |= XFS_TRANS_PERM_LOG_RES; 816 817 resp->tr_create.tr_logres = xfs_calc_icreate_reservation(mp); 818 resp->tr_create.tr_logcount = XFS_CREATE_LOG_COUNT; 819 resp->tr_create.tr_logflags |= XFS_TRANS_PERM_LOG_RES; 820 821 resp->tr_create_tmpfile.tr_logres = 822 xfs_calc_create_tmpfile_reservation(mp); 823 resp->tr_create_tmpfile.tr_logcount = XFS_CREATE_TMPFILE_LOG_COUNT; 824 resp->tr_create_tmpfile.tr_logflags |= XFS_TRANS_PERM_LOG_RES; 825 826 resp->tr_mkdir.tr_logres = xfs_calc_mkdir_reservation(mp); 827 resp->tr_mkdir.tr_logcount = XFS_MKDIR_LOG_COUNT; 828 resp->tr_mkdir.tr_logflags |= XFS_TRANS_PERM_LOG_RES; 829 830 resp->tr_ifree.tr_logres = xfs_calc_ifree_reservation(mp); 831 resp->tr_ifree.tr_logcount = XFS_INACTIVE_LOG_COUNT; 832 resp->tr_ifree.tr_logflags |= XFS_TRANS_PERM_LOG_RES; 833 834 resp->tr_addafork.tr_logres = xfs_calc_addafork_reservation(mp); 835 resp->tr_addafork.tr_logcount = XFS_ADDAFORK_LOG_COUNT; 836 resp->tr_addafork.tr_logflags |= XFS_TRANS_PERM_LOG_RES; 837 838 resp->tr_attrinval.tr_logres = xfs_calc_attrinval_reservation(mp); 839 resp->tr_attrinval.tr_logcount = XFS_ATTRINVAL_LOG_COUNT; 840 resp->tr_attrinval.tr_logflags |= XFS_TRANS_PERM_LOG_RES; 841 842 resp->tr_attrsetm.tr_logres = xfs_calc_attrsetm_reservation(mp); 843 resp->tr_attrsetm.tr_logcount = XFS_ATTRSET_LOG_COUNT; 844 resp->tr_attrsetm.tr_logflags |= XFS_TRANS_PERM_LOG_RES; 845 846 resp->tr_attrrm.tr_logres = xfs_calc_attrrm_reservation(mp); 847 resp->tr_attrrm.tr_logcount = XFS_ATTRRM_LOG_COUNT; 848 resp->tr_attrrm.tr_logflags |= XFS_TRANS_PERM_LOG_RES; 849 850 resp->tr_growrtalloc.tr_logres = xfs_calc_growrtalloc_reservation(mp); 851 resp->tr_growrtalloc.tr_logcount = XFS_DEFAULT_PERM_LOG_COUNT; 852 resp->tr_growrtalloc.tr_logflags |= XFS_TRANS_PERM_LOG_RES; 853 854 resp->tr_qm_dqalloc.tr_logres = xfs_calc_qm_dqalloc_reservation(mp); 855 if (xfs_sb_version_hasreflink(&mp->m_sb)) 856 resp->tr_qm_dqalloc.tr_logcount = XFS_WRITE_LOG_COUNT_REFLINK; 857 else 858 resp->tr_qm_dqalloc.tr_logcount = XFS_WRITE_LOG_COUNT; 859 resp->tr_qm_dqalloc.tr_logflags |= XFS_TRANS_PERM_LOG_RES; 860 861 /* 862 * The following transactions are logged in logical format with 863 * a default log count. 864 */ 865 resp->tr_qm_setqlim.tr_logres = xfs_calc_qm_setqlim_reservation(); 866 resp->tr_qm_setqlim.tr_logcount = XFS_DEFAULT_LOG_COUNT; 867 868 resp->tr_qm_quotaoff.tr_logres = xfs_calc_qm_quotaoff_reservation(mp); 869 resp->tr_qm_quotaoff.tr_logcount = XFS_DEFAULT_LOG_COUNT; 870 871 resp->tr_qm_equotaoff.tr_logres = 872 xfs_calc_qm_quotaoff_end_reservation(); 873 resp->tr_qm_equotaoff.tr_logcount = XFS_DEFAULT_LOG_COUNT; 874 875 resp->tr_sb.tr_logres = xfs_calc_sb_reservation(mp); 876 resp->tr_sb.tr_logcount = XFS_DEFAULT_LOG_COUNT; 877 878 /* growdata requires permanent res; it can free space to the last AG */ 879 resp->tr_growdata.tr_logres = xfs_calc_growdata_reservation(mp); 880 resp->tr_growdata.tr_logcount = XFS_DEFAULT_PERM_LOG_COUNT; 881 resp->tr_growdata.tr_logflags |= XFS_TRANS_PERM_LOG_RES; 882 883 /* The following transaction are logged in logical format */ 884 resp->tr_ichange.tr_logres = xfs_calc_ichange_reservation(mp); 885 resp->tr_fsyncts.tr_logres = xfs_calc_swrite_reservation(mp); 886 resp->tr_writeid.tr_logres = xfs_calc_writeid_reservation(mp); 887 resp->tr_attrsetrt.tr_logres = xfs_calc_attrsetrt_reservation(mp); 888 resp->tr_clearagi.tr_logres = xfs_calc_clear_agi_bucket_reservation(mp); 889 resp->tr_growrtzero.tr_logres = xfs_calc_growrtzero_reservation(mp); 890 resp->tr_growrtfree.tr_logres = xfs_calc_growrtfree_reservation(mp); 891 } 892