18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. 48c2ecf20Sopenharmony_ci * Copyright (C) 2010 Red Hat, Inc. 58c2ecf20Sopenharmony_ci * All Rights Reserved. 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci#include "xfs.h" 88c2ecf20Sopenharmony_ci#include "xfs_fs.h" 98c2ecf20Sopenharmony_ci#include "xfs_shared.h" 108c2ecf20Sopenharmony_ci#include "xfs_format.h" 118c2ecf20Sopenharmony_ci#include "xfs_log_format.h" 128c2ecf20Sopenharmony_ci#include "xfs_trans_resv.h" 138c2ecf20Sopenharmony_ci#include "xfs_mount.h" 148c2ecf20Sopenharmony_ci#include "xfs_da_format.h" 158c2ecf20Sopenharmony_ci#include "xfs_da_btree.h" 168c2ecf20Sopenharmony_ci#include "xfs_inode.h" 178c2ecf20Sopenharmony_ci#include "xfs_bmap_btree.h" 188c2ecf20Sopenharmony_ci#include "xfs_quota.h" 198c2ecf20Sopenharmony_ci#include "xfs_trans.h" 208c2ecf20Sopenharmony_ci#include "xfs_qm.h" 218c2ecf20Sopenharmony_ci#include "xfs_trans_space.h" 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci#define _ALLOC true 248c2ecf20Sopenharmony_ci#define _FREE false 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci/* 278c2ecf20Sopenharmony_ci * A buffer has a format structure overhead in the log in addition 288c2ecf20Sopenharmony_ci * to the data, so we need to take this into account when reserving 298c2ecf20Sopenharmony_ci * space in a transaction for a buffer. Round the space required up 308c2ecf20Sopenharmony_ci * to a multiple of 128 bytes so that we don't change the historical 318c2ecf20Sopenharmony_ci * reservation that has been used for this overhead. 328c2ecf20Sopenharmony_ci */ 338c2ecf20Sopenharmony_ciSTATIC uint 348c2ecf20Sopenharmony_cixfs_buf_log_overhead(void) 358c2ecf20Sopenharmony_ci{ 368c2ecf20Sopenharmony_ci return round_up(sizeof(struct xlog_op_header) + 378c2ecf20Sopenharmony_ci sizeof(struct xfs_buf_log_format), 128); 388c2ecf20Sopenharmony_ci} 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci/* 418c2ecf20Sopenharmony_ci * Calculate out transaction log reservation per item in bytes. 428c2ecf20Sopenharmony_ci * 438c2ecf20Sopenharmony_ci * The nbufs argument is used to indicate the number of items that 448c2ecf20Sopenharmony_ci * will be changed in a transaction. size is used to tell how many 458c2ecf20Sopenharmony_ci * bytes should be reserved per item. 468c2ecf20Sopenharmony_ci */ 478c2ecf20Sopenharmony_ciSTATIC uint 488c2ecf20Sopenharmony_cixfs_calc_buf_res( 498c2ecf20Sopenharmony_ci uint nbufs, 508c2ecf20Sopenharmony_ci uint size) 518c2ecf20Sopenharmony_ci{ 528c2ecf20Sopenharmony_ci return nbufs * (size + xfs_buf_log_overhead()); 538c2ecf20Sopenharmony_ci} 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci/* 568c2ecf20Sopenharmony_ci * Per-extent log reservation for the btree changes involved in freeing or 578c2ecf20Sopenharmony_ci * allocating an extent. In classic XFS there were two trees that will be 588c2ecf20Sopenharmony_ci * modified (bnobt + cntbt). With rmap enabled, there are three trees 598c2ecf20Sopenharmony_ci * (rmapbt). With reflink, there are four trees (refcountbt). The number of 608c2ecf20Sopenharmony_ci * blocks reserved is based on the formula: 618c2ecf20Sopenharmony_ci * 628c2ecf20Sopenharmony_ci * num trees * ((2 blocks/level * max depth) - 1) 638c2ecf20Sopenharmony_ci * 648c2ecf20Sopenharmony_ci * Keep in mind that max depth is calculated separately for each type of tree. 658c2ecf20Sopenharmony_ci */ 668c2ecf20Sopenharmony_ciuint 678c2ecf20Sopenharmony_cixfs_allocfree_log_count( 688c2ecf20Sopenharmony_ci struct xfs_mount *mp, 698c2ecf20Sopenharmony_ci uint num_ops) 708c2ecf20Sopenharmony_ci{ 718c2ecf20Sopenharmony_ci uint blocks; 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci blocks = num_ops * 2 * (2 * mp->m_ag_maxlevels - 1); 748c2ecf20Sopenharmony_ci if (xfs_sb_version_hasrmapbt(&mp->m_sb)) 758c2ecf20Sopenharmony_ci blocks += num_ops * (2 * mp->m_rmap_maxlevels - 1); 768c2ecf20Sopenharmony_ci if (xfs_sb_version_hasreflink(&mp->m_sb)) 778c2ecf20Sopenharmony_ci blocks += num_ops * (2 * mp->m_refc_maxlevels - 1); 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci return blocks; 808c2ecf20Sopenharmony_ci} 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci/* 838c2ecf20Sopenharmony_ci * Logging inodes is really tricksy. They are logged in memory format, 848c2ecf20Sopenharmony_ci * which means that what we write into the log doesn't directly translate into 858c2ecf20Sopenharmony_ci * the amount of space they use on disk. 868c2ecf20Sopenharmony_ci * 878c2ecf20Sopenharmony_ci * Case in point - btree format forks in memory format use more space than the 888c2ecf20Sopenharmony_ci * on-disk format. In memory, the buffer contains a normal btree block header so 898c2ecf20Sopenharmony_ci * the btree code can treat it as though it is just another generic buffer. 908c2ecf20Sopenharmony_ci * However, when we write it to the inode fork, we don't write all of this 918c2ecf20Sopenharmony_ci * header as it isn't needed. e.g. the root is only ever in the inode, so 928c2ecf20Sopenharmony_ci * there's no need for sibling pointers which would waste 16 bytes of space. 938c2ecf20Sopenharmony_ci * 948c2ecf20Sopenharmony_ci * Hence when we have an inode with a maximally sized btree format fork, then 958c2ecf20Sopenharmony_ci * amount of information we actually log is greater than the size of the inode 968c2ecf20Sopenharmony_ci * on disk. Hence we need an inode reservation function that calculates all this 978c2ecf20Sopenharmony_ci * correctly. So, we log: 988c2ecf20Sopenharmony_ci * 998c2ecf20Sopenharmony_ci * - 4 log op headers for object 1008c2ecf20Sopenharmony_ci * - for the ilf, the inode core and 2 forks 1018c2ecf20Sopenharmony_ci * - inode log format object 1028c2ecf20Sopenharmony_ci * - the inode core 1038c2ecf20Sopenharmony_ci * - two inode forks containing bmap btree root blocks. 1048c2ecf20Sopenharmony_ci * - the btree data contained by both forks will fit into the inode size, 1058c2ecf20Sopenharmony_ci * hence when combined with the inode core above, we have a total of the 1068c2ecf20Sopenharmony_ci * actual inode size. 1078c2ecf20Sopenharmony_ci * - the BMBT headers need to be accounted separately, as they are 1088c2ecf20Sopenharmony_ci * additional to the records and pointers that fit inside the inode 1098c2ecf20Sopenharmony_ci * forks. 1108c2ecf20Sopenharmony_ci */ 1118c2ecf20Sopenharmony_ciSTATIC uint 1128c2ecf20Sopenharmony_cixfs_calc_inode_res( 1138c2ecf20Sopenharmony_ci struct xfs_mount *mp, 1148c2ecf20Sopenharmony_ci uint ninodes) 1158c2ecf20Sopenharmony_ci{ 1168c2ecf20Sopenharmony_ci return ninodes * 1178c2ecf20Sopenharmony_ci (4 * sizeof(struct xlog_op_header) + 1188c2ecf20Sopenharmony_ci sizeof(struct xfs_inode_log_format) + 1198c2ecf20Sopenharmony_ci mp->m_sb.sb_inodesize + 1208c2ecf20Sopenharmony_ci 2 * XFS_BMBT_BLOCK_LEN(mp)); 1218c2ecf20Sopenharmony_ci} 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci/* 1248c2ecf20Sopenharmony_ci * Inode btree record insertion/removal modifies the inode btree and free space 1258c2ecf20Sopenharmony_ci * btrees (since the inobt does not use the agfl). This requires the following 1268c2ecf20Sopenharmony_ci * reservation: 1278c2ecf20Sopenharmony_ci * 1288c2ecf20Sopenharmony_ci * the inode btree: max depth * blocksize 1298c2ecf20Sopenharmony_ci * the allocation btrees: 2 trees * (max depth - 1) * block size 1308c2ecf20Sopenharmony_ci * 1318c2ecf20Sopenharmony_ci * The caller must account for SB and AG header modifications, etc. 1328c2ecf20Sopenharmony_ci */ 1338c2ecf20Sopenharmony_ciSTATIC uint 1348c2ecf20Sopenharmony_cixfs_calc_inobt_res( 1358c2ecf20Sopenharmony_ci struct xfs_mount *mp) 1368c2ecf20Sopenharmony_ci{ 1378c2ecf20Sopenharmony_ci return xfs_calc_buf_res(M_IGEO(mp)->inobt_maxlevels, 1388c2ecf20Sopenharmony_ci XFS_FSB_TO_B(mp, 1)) + 1398c2ecf20Sopenharmony_ci xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), 1408c2ecf20Sopenharmony_ci XFS_FSB_TO_B(mp, 1)); 1418c2ecf20Sopenharmony_ci} 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci/* 1448c2ecf20Sopenharmony_ci * The free inode btree is a conditional feature. The behavior differs slightly 1458c2ecf20Sopenharmony_ci * from that of the traditional inode btree in that the finobt tracks records 1468c2ecf20Sopenharmony_ci * for inode chunks with at least one free inode. A record can be removed from 1478c2ecf20Sopenharmony_ci * the tree during individual inode allocation. Therefore the finobt 1488c2ecf20Sopenharmony_ci * reservation is unconditional for both the inode chunk allocation and 1498c2ecf20Sopenharmony_ci * individual inode allocation (modify) cases. 1508c2ecf20Sopenharmony_ci * 1518c2ecf20Sopenharmony_ci * Behavior aside, the reservation for finobt modification is equivalent to the 1528c2ecf20Sopenharmony_ci * traditional inobt: cover a full finobt shape change plus block allocation. 1538c2ecf20Sopenharmony_ci */ 1548c2ecf20Sopenharmony_ciSTATIC uint 1558c2ecf20Sopenharmony_cixfs_calc_finobt_res( 1568c2ecf20Sopenharmony_ci struct xfs_mount *mp) 1578c2ecf20Sopenharmony_ci{ 1588c2ecf20Sopenharmony_ci if (!xfs_sb_version_hasfinobt(&mp->m_sb)) 1598c2ecf20Sopenharmony_ci return 0; 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci return xfs_calc_inobt_res(mp); 1628c2ecf20Sopenharmony_ci} 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_ci/* 1658c2ecf20Sopenharmony_ci * Calculate the reservation required to allocate or free an inode chunk. This 1668c2ecf20Sopenharmony_ci * includes: 1678c2ecf20Sopenharmony_ci * 1688c2ecf20Sopenharmony_ci * the allocation btrees: 2 trees * (max depth - 1) * block size 1698c2ecf20Sopenharmony_ci * the inode chunk: m_ino_geo.ialloc_blks * N 1708c2ecf20Sopenharmony_ci * 1718c2ecf20Sopenharmony_ci * The size N of the inode chunk reservation depends on whether it is for 1728c2ecf20Sopenharmony_ci * allocation or free and which type of create transaction is in use. An inode 1738c2ecf20Sopenharmony_ci * chunk free always invalidates the buffers and only requires reservation for 1748c2ecf20Sopenharmony_ci * headers (N == 0). An inode chunk allocation requires a chunk sized 1758c2ecf20Sopenharmony_ci * reservation on v4 and older superblocks to initialize the chunk. No chunk 1768c2ecf20Sopenharmony_ci * reservation is required for allocation on v5 supers, which use ordered 1778c2ecf20Sopenharmony_ci * buffers to initialize. 1788c2ecf20Sopenharmony_ci */ 1798c2ecf20Sopenharmony_ciSTATIC uint 1808c2ecf20Sopenharmony_cixfs_calc_inode_chunk_res( 1818c2ecf20Sopenharmony_ci struct xfs_mount *mp, 1828c2ecf20Sopenharmony_ci bool alloc) 1838c2ecf20Sopenharmony_ci{ 1848c2ecf20Sopenharmony_ci uint res, size = 0; 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_ci res = xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), 1878c2ecf20Sopenharmony_ci XFS_FSB_TO_B(mp, 1)); 1888c2ecf20Sopenharmony_ci if (alloc) { 1898c2ecf20Sopenharmony_ci /* icreate tx uses ordered buffers */ 1908c2ecf20Sopenharmony_ci if (xfs_sb_version_has_v3inode(&mp->m_sb)) 1918c2ecf20Sopenharmony_ci return res; 1928c2ecf20Sopenharmony_ci size = XFS_FSB_TO_B(mp, 1); 1938c2ecf20Sopenharmony_ci } 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_ci res += xfs_calc_buf_res(M_IGEO(mp)->ialloc_blks, size); 1968c2ecf20Sopenharmony_ci return res; 1978c2ecf20Sopenharmony_ci} 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_ci/* 2008c2ecf20Sopenharmony_ci * Per-extent log reservation for the btree changes involved in freeing or 2018c2ecf20Sopenharmony_ci * allocating a realtime extent. We have to be able to log as many rtbitmap 2028c2ecf20Sopenharmony_ci * blocks as needed to mark inuse MAXEXTLEN blocks' worth of realtime extents, 2038c2ecf20Sopenharmony_ci * as well as the realtime summary block. 2048c2ecf20Sopenharmony_ci */ 2058c2ecf20Sopenharmony_cistatic unsigned int 2068c2ecf20Sopenharmony_cixfs_rtalloc_log_count( 2078c2ecf20Sopenharmony_ci struct xfs_mount *mp, 2088c2ecf20Sopenharmony_ci unsigned int num_ops) 2098c2ecf20Sopenharmony_ci{ 2108c2ecf20Sopenharmony_ci unsigned int blksz = XFS_FSB_TO_B(mp, 1); 2118c2ecf20Sopenharmony_ci unsigned int rtbmp_bytes; 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_ci rtbmp_bytes = (MAXEXTLEN / mp->m_sb.sb_rextsize) / NBBY; 2148c2ecf20Sopenharmony_ci return (howmany(rtbmp_bytes, blksz) + 1) * num_ops; 2158c2ecf20Sopenharmony_ci} 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci/* 2188c2ecf20Sopenharmony_ci * Various log reservation values. 2198c2ecf20Sopenharmony_ci * 2208c2ecf20Sopenharmony_ci * These are based on the size of the file system block because that is what 2218c2ecf20Sopenharmony_ci * most transactions manipulate. Each adds in an additional 128 bytes per 2228c2ecf20Sopenharmony_ci * item logged to try to account for the overhead of the transaction mechanism. 2238c2ecf20Sopenharmony_ci * 2248c2ecf20Sopenharmony_ci * Note: Most of the reservations underestimate the number of allocation 2258c2ecf20Sopenharmony_ci * groups into which they could free extents in the xfs_defer_finish() call. 2268c2ecf20Sopenharmony_ci * This is because the number in the worst case is quite high and quite 2278c2ecf20Sopenharmony_ci * unusual. In order to fix this we need to change xfs_defer_finish() to free 2288c2ecf20Sopenharmony_ci * extents in only a single AG at a time. This will require changes to the 2298c2ecf20Sopenharmony_ci * EFI code as well, however, so that the EFI for the extents not freed is 2308c2ecf20Sopenharmony_ci * logged again in each transaction. See SGI PV #261917. 2318c2ecf20Sopenharmony_ci * 2328c2ecf20Sopenharmony_ci * Reservation functions here avoid a huge stack in xfs_trans_init due to 2338c2ecf20Sopenharmony_ci * register overflow from temporaries in the calculations. 2348c2ecf20Sopenharmony_ci */ 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_ci/* 2388c2ecf20Sopenharmony_ci * In a write transaction we can allocate a maximum of 2 2398c2ecf20Sopenharmony_ci * extents. This gives (t1): 2408c2ecf20Sopenharmony_ci * the inode getting the new extents: inode size 2418c2ecf20Sopenharmony_ci * the inode's bmap btree: max depth * block size 2428c2ecf20Sopenharmony_ci * the agfs of the ags from which the extents are allocated: 2 * sector 2438c2ecf20Sopenharmony_ci * the superblock free block counter: sector size 2448c2ecf20Sopenharmony_ci * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size 2458c2ecf20Sopenharmony_ci * Or, if we're writing to a realtime file (t2): 2468c2ecf20Sopenharmony_ci * the inode getting the new extents: inode size 2478c2ecf20Sopenharmony_ci * the inode's bmap btree: max depth * block size 2488c2ecf20Sopenharmony_ci * the agfs of the ags from which the extents are allocated: 2 * sector 2498c2ecf20Sopenharmony_ci * the superblock free block counter: sector size 2508c2ecf20Sopenharmony_ci * the realtime bitmap: ((MAXEXTLEN / rtextsize) / NBBY) bytes 2518c2ecf20Sopenharmony_ci * the realtime summary: 1 block 2528c2ecf20Sopenharmony_ci * the allocation btrees: 2 trees * (2 * max depth - 1) * block size 2538c2ecf20Sopenharmony_ci * And the bmap_finish transaction can free bmap blocks in a join (t3): 2548c2ecf20Sopenharmony_ci * the agfs of the ags containing the blocks: 2 * sector size 2558c2ecf20Sopenharmony_ci * the agfls of the ags containing the blocks: 2 * sector size 2568c2ecf20Sopenharmony_ci * the super block free block counter: sector size 2578c2ecf20Sopenharmony_ci * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size 2588c2ecf20Sopenharmony_ci */ 2598c2ecf20Sopenharmony_ciSTATIC uint 2608c2ecf20Sopenharmony_cixfs_calc_write_reservation( 2618c2ecf20Sopenharmony_ci struct xfs_mount *mp) 2628c2ecf20Sopenharmony_ci{ 2638c2ecf20Sopenharmony_ci unsigned int t1, t2, t3; 2648c2ecf20Sopenharmony_ci unsigned int blksz = XFS_FSB_TO_B(mp, 1); 2658c2ecf20Sopenharmony_ci 2668c2ecf20Sopenharmony_ci t1 = xfs_calc_inode_res(mp, 1) + 2678c2ecf20Sopenharmony_ci xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK), blksz) + 2688c2ecf20Sopenharmony_ci xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) + 2698c2ecf20Sopenharmony_ci xfs_calc_buf_res(xfs_allocfree_log_count(mp, 2), blksz); 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_ci if (xfs_sb_version_hasrealtime(&mp->m_sb)) { 2728c2ecf20Sopenharmony_ci t2 = xfs_calc_inode_res(mp, 1) + 2738c2ecf20Sopenharmony_ci xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK), 2748c2ecf20Sopenharmony_ci blksz) + 2758c2ecf20Sopenharmony_ci xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) + 2768c2ecf20Sopenharmony_ci xfs_calc_buf_res(xfs_rtalloc_log_count(mp, 1), blksz) + 2778c2ecf20Sopenharmony_ci xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), blksz); 2788c2ecf20Sopenharmony_ci } else { 2798c2ecf20Sopenharmony_ci t2 = 0; 2808c2ecf20Sopenharmony_ci } 2818c2ecf20Sopenharmony_ci 2828c2ecf20Sopenharmony_ci t3 = xfs_calc_buf_res(5, mp->m_sb.sb_sectsize) + 2838c2ecf20Sopenharmony_ci xfs_calc_buf_res(xfs_allocfree_log_count(mp, 2), blksz); 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_ci return XFS_DQUOT_LOGRES(mp) + max3(t1, t2, t3); 2868c2ecf20Sopenharmony_ci} 2878c2ecf20Sopenharmony_ci 2888c2ecf20Sopenharmony_ci/* 2898c2ecf20Sopenharmony_ci * In truncating a file we free up to two extents at once. We can modify (t1): 2908c2ecf20Sopenharmony_ci * the inode being truncated: inode size 2918c2ecf20Sopenharmony_ci * the inode's bmap btree: (max depth + 1) * block size 2928c2ecf20Sopenharmony_ci * And the bmap_finish transaction can free the blocks and bmap blocks (t2): 2938c2ecf20Sopenharmony_ci * the agf for each of the ags: 4 * sector size 2948c2ecf20Sopenharmony_ci * the agfl for each of the ags: 4 * sector size 2958c2ecf20Sopenharmony_ci * the super block to reflect the freed blocks: sector size 2968c2ecf20Sopenharmony_ci * worst case split in allocation btrees per extent assuming 4 extents: 2978c2ecf20Sopenharmony_ci * 4 exts * 2 trees * (2 * max depth - 1) * block size 2988c2ecf20Sopenharmony_ci * Or, if it's a realtime file (t3): 2998c2ecf20Sopenharmony_ci * the agf for each of the ags: 2 * sector size 3008c2ecf20Sopenharmony_ci * the agfl for each of the ags: 2 * sector size 3018c2ecf20Sopenharmony_ci * the super block to reflect the freed blocks: sector size 3028c2ecf20Sopenharmony_ci * the realtime bitmap: 2 exts * ((MAXEXTLEN / rtextsize) / NBBY) bytes 3038c2ecf20Sopenharmony_ci * the realtime summary: 2 exts * 1 block 3048c2ecf20Sopenharmony_ci * worst case split in allocation btrees per extent assuming 2 extents: 3058c2ecf20Sopenharmony_ci * 2 exts * 2 trees * (2 * max depth - 1) * block size 3068c2ecf20Sopenharmony_ci */ 3078c2ecf20Sopenharmony_ciSTATIC uint 3088c2ecf20Sopenharmony_cixfs_calc_itruncate_reservation( 3098c2ecf20Sopenharmony_ci struct xfs_mount *mp) 3108c2ecf20Sopenharmony_ci{ 3118c2ecf20Sopenharmony_ci unsigned int t1, t2, t3; 3128c2ecf20Sopenharmony_ci unsigned int blksz = XFS_FSB_TO_B(mp, 1); 3138c2ecf20Sopenharmony_ci 3148c2ecf20Sopenharmony_ci t1 = xfs_calc_inode_res(mp, 1) + 3158c2ecf20Sopenharmony_ci xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + 1, blksz); 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_ci t2 = xfs_calc_buf_res(9, mp->m_sb.sb_sectsize) + 3188c2ecf20Sopenharmony_ci xfs_calc_buf_res(xfs_allocfree_log_count(mp, 4), blksz); 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ci if (xfs_sb_version_hasrealtime(&mp->m_sb)) { 3218c2ecf20Sopenharmony_ci t3 = xfs_calc_buf_res(5, mp->m_sb.sb_sectsize) + 3228c2ecf20Sopenharmony_ci xfs_calc_buf_res(xfs_rtalloc_log_count(mp, 2), blksz) + 3238c2ecf20Sopenharmony_ci xfs_calc_buf_res(xfs_allocfree_log_count(mp, 2), blksz); 3248c2ecf20Sopenharmony_ci } else { 3258c2ecf20Sopenharmony_ci t3 = 0; 3268c2ecf20Sopenharmony_ci } 3278c2ecf20Sopenharmony_ci 3288c2ecf20Sopenharmony_ci return XFS_DQUOT_LOGRES(mp) + max3(t1, t2, t3); 3298c2ecf20Sopenharmony_ci} 3308c2ecf20Sopenharmony_ci 3318c2ecf20Sopenharmony_ci/* 3328c2ecf20Sopenharmony_ci * In renaming a files we can modify: 3338c2ecf20Sopenharmony_ci * the four inodes involved: 4 * inode size 3348c2ecf20Sopenharmony_ci * the two directory btrees: 2 * (max depth + v2) * dir block size 3358c2ecf20Sopenharmony_ci * the two directory bmap btrees: 2 * max depth * block size 3368c2ecf20Sopenharmony_ci * And the bmap_finish transaction can free dir and bmap blocks (two sets 3378c2ecf20Sopenharmony_ci * of bmap blocks) giving: 3388c2ecf20Sopenharmony_ci * the agf for the ags in which the blocks live: 3 * sector size 3398c2ecf20Sopenharmony_ci * the agfl for the ags in which the blocks live: 3 * sector size 3408c2ecf20Sopenharmony_ci * the superblock for the free block count: sector size 3418c2ecf20Sopenharmony_ci * the allocation btrees: 3 exts * 2 trees * (2 * max depth - 1) * block size 3428c2ecf20Sopenharmony_ci */ 3438c2ecf20Sopenharmony_ciSTATIC uint 3448c2ecf20Sopenharmony_cixfs_calc_rename_reservation( 3458c2ecf20Sopenharmony_ci struct xfs_mount *mp) 3468c2ecf20Sopenharmony_ci{ 3478c2ecf20Sopenharmony_ci return XFS_DQUOT_LOGRES(mp) + 3488c2ecf20Sopenharmony_ci max((xfs_calc_inode_res(mp, 4) + 3498c2ecf20Sopenharmony_ci xfs_calc_buf_res(2 * XFS_DIROP_LOG_COUNT(mp), 3508c2ecf20Sopenharmony_ci XFS_FSB_TO_B(mp, 1))), 3518c2ecf20Sopenharmony_ci (xfs_calc_buf_res(7, mp->m_sb.sb_sectsize) + 3528c2ecf20Sopenharmony_ci xfs_calc_buf_res(xfs_allocfree_log_count(mp, 3), 3538c2ecf20Sopenharmony_ci XFS_FSB_TO_B(mp, 1)))); 3548c2ecf20Sopenharmony_ci} 3558c2ecf20Sopenharmony_ci 3568c2ecf20Sopenharmony_ci/* 3578c2ecf20Sopenharmony_ci * For removing an inode from unlinked list at first, we can modify: 3588c2ecf20Sopenharmony_ci * the agi hash list and counters: sector size 3598c2ecf20Sopenharmony_ci * the on disk inode before ours in the agi hash list: inode cluster size 3608c2ecf20Sopenharmony_ci * the on disk inode in the agi hash list: inode cluster size 3618c2ecf20Sopenharmony_ci */ 3628c2ecf20Sopenharmony_ciSTATIC uint 3638c2ecf20Sopenharmony_cixfs_calc_iunlink_remove_reservation( 3648c2ecf20Sopenharmony_ci struct xfs_mount *mp) 3658c2ecf20Sopenharmony_ci{ 3668c2ecf20Sopenharmony_ci return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) + 3678c2ecf20Sopenharmony_ci 2 * M_IGEO(mp)->inode_cluster_size; 3688c2ecf20Sopenharmony_ci} 3698c2ecf20Sopenharmony_ci 3708c2ecf20Sopenharmony_ci/* 3718c2ecf20Sopenharmony_ci * For creating a link to an inode: 3728c2ecf20Sopenharmony_ci * the parent directory inode: inode size 3738c2ecf20Sopenharmony_ci * the linked inode: inode size 3748c2ecf20Sopenharmony_ci * the directory btree could split: (max depth + v2) * dir block size 3758c2ecf20Sopenharmony_ci * the directory bmap btree could join or split: (max depth + v2) * blocksize 3768c2ecf20Sopenharmony_ci * And the bmap_finish transaction can free some bmap blocks giving: 3778c2ecf20Sopenharmony_ci * the agf for the ag in which the blocks live: sector size 3788c2ecf20Sopenharmony_ci * the agfl for the ag in which the blocks live: sector size 3798c2ecf20Sopenharmony_ci * the superblock for the free block count: sector size 3808c2ecf20Sopenharmony_ci * the allocation btrees: 2 trees * (2 * max depth - 1) * block size 3818c2ecf20Sopenharmony_ci */ 3828c2ecf20Sopenharmony_ciSTATIC uint 3838c2ecf20Sopenharmony_cixfs_calc_link_reservation( 3848c2ecf20Sopenharmony_ci struct xfs_mount *mp) 3858c2ecf20Sopenharmony_ci{ 3868c2ecf20Sopenharmony_ci return XFS_DQUOT_LOGRES(mp) + 3878c2ecf20Sopenharmony_ci xfs_calc_iunlink_remove_reservation(mp) + 3888c2ecf20Sopenharmony_ci max((xfs_calc_inode_res(mp, 2) + 3898c2ecf20Sopenharmony_ci xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), 3908c2ecf20Sopenharmony_ci XFS_FSB_TO_B(mp, 1))), 3918c2ecf20Sopenharmony_ci (xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) + 3928c2ecf20Sopenharmony_ci xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), 3938c2ecf20Sopenharmony_ci XFS_FSB_TO_B(mp, 1)))); 3948c2ecf20Sopenharmony_ci} 3958c2ecf20Sopenharmony_ci 3968c2ecf20Sopenharmony_ci/* 3978c2ecf20Sopenharmony_ci * For adding an inode to unlinked list we can modify: 3988c2ecf20Sopenharmony_ci * the agi hash list: sector size 3998c2ecf20Sopenharmony_ci * the on disk inode: inode cluster size 4008c2ecf20Sopenharmony_ci */ 4018c2ecf20Sopenharmony_ciSTATIC uint 4028c2ecf20Sopenharmony_cixfs_calc_iunlink_add_reservation(xfs_mount_t *mp) 4038c2ecf20Sopenharmony_ci{ 4048c2ecf20Sopenharmony_ci return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) + 4058c2ecf20Sopenharmony_ci M_IGEO(mp)->inode_cluster_size; 4068c2ecf20Sopenharmony_ci} 4078c2ecf20Sopenharmony_ci 4088c2ecf20Sopenharmony_ci/* 4098c2ecf20Sopenharmony_ci * For removing a directory entry we can modify: 4108c2ecf20Sopenharmony_ci * the parent directory inode: inode size 4118c2ecf20Sopenharmony_ci * the removed inode: inode size 4128c2ecf20Sopenharmony_ci * the directory btree could join: (max depth + v2) * dir block size 4138c2ecf20Sopenharmony_ci * the directory bmap btree could join or split: (max depth + v2) * blocksize 4148c2ecf20Sopenharmony_ci * And the bmap_finish transaction can free the dir and bmap blocks giving: 4158c2ecf20Sopenharmony_ci * the agf for the ag in which the blocks live: 2 * sector size 4168c2ecf20Sopenharmony_ci * the agfl for the ag in which the blocks live: 2 * sector size 4178c2ecf20Sopenharmony_ci * the superblock for the free block count: sector size 4188c2ecf20Sopenharmony_ci * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size 4198c2ecf20Sopenharmony_ci */ 4208c2ecf20Sopenharmony_ciSTATIC uint 4218c2ecf20Sopenharmony_cixfs_calc_remove_reservation( 4228c2ecf20Sopenharmony_ci struct xfs_mount *mp) 4238c2ecf20Sopenharmony_ci{ 4248c2ecf20Sopenharmony_ci return XFS_DQUOT_LOGRES(mp) + 4258c2ecf20Sopenharmony_ci xfs_calc_iunlink_add_reservation(mp) + 4268c2ecf20Sopenharmony_ci max((xfs_calc_inode_res(mp, 1) + 4278c2ecf20Sopenharmony_ci xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), 4288c2ecf20Sopenharmony_ci XFS_FSB_TO_B(mp, 1))), 4298c2ecf20Sopenharmony_ci (xfs_calc_buf_res(4, mp->m_sb.sb_sectsize) + 4308c2ecf20Sopenharmony_ci xfs_calc_buf_res(xfs_allocfree_log_count(mp, 2), 4318c2ecf20Sopenharmony_ci XFS_FSB_TO_B(mp, 1)))); 4328c2ecf20Sopenharmony_ci} 4338c2ecf20Sopenharmony_ci 4348c2ecf20Sopenharmony_ci/* 4358c2ecf20Sopenharmony_ci * For create, break it in to the two cases that the transaction 4368c2ecf20Sopenharmony_ci * covers. We start with the modify case - allocation done by modification 4378c2ecf20Sopenharmony_ci * of the state of existing inodes - and the allocation case. 4388c2ecf20Sopenharmony_ci */ 4398c2ecf20Sopenharmony_ci 4408c2ecf20Sopenharmony_ci/* 4418c2ecf20Sopenharmony_ci * For create we can modify: 4428c2ecf20Sopenharmony_ci * the parent directory inode: inode size 4438c2ecf20Sopenharmony_ci * the new inode: inode size 4448c2ecf20Sopenharmony_ci * the inode btree entry: block size 4458c2ecf20Sopenharmony_ci * the superblock for the nlink flag: sector size 4468c2ecf20Sopenharmony_ci * the directory btree: (max depth + v2) * dir block size 4478c2ecf20Sopenharmony_ci * the directory inode's bmap btree: (max depth + v2) * block size 4488c2ecf20Sopenharmony_ci * the finobt (record modification and allocation btrees) 4498c2ecf20Sopenharmony_ci */ 4508c2ecf20Sopenharmony_ciSTATIC uint 4518c2ecf20Sopenharmony_cixfs_calc_create_resv_modify( 4528c2ecf20Sopenharmony_ci struct xfs_mount *mp) 4538c2ecf20Sopenharmony_ci{ 4548c2ecf20Sopenharmony_ci return xfs_calc_inode_res(mp, 2) + 4558c2ecf20Sopenharmony_ci xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) + 4568c2ecf20Sopenharmony_ci (uint)XFS_FSB_TO_B(mp, 1) + 4578c2ecf20Sopenharmony_ci xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), XFS_FSB_TO_B(mp, 1)) + 4588c2ecf20Sopenharmony_ci xfs_calc_finobt_res(mp); 4598c2ecf20Sopenharmony_ci} 4608c2ecf20Sopenharmony_ci 4618c2ecf20Sopenharmony_ci/* 4628c2ecf20Sopenharmony_ci * For icreate we can allocate some inodes giving: 4638c2ecf20Sopenharmony_ci * the agi and agf of the ag getting the new inodes: 2 * sectorsize 4648c2ecf20Sopenharmony_ci * the superblock for the nlink flag: sector size 4658c2ecf20Sopenharmony_ci * the inode chunk (allocation, optional init) 4668c2ecf20Sopenharmony_ci * the inobt (record insertion) 4678c2ecf20Sopenharmony_ci * the finobt (optional, record insertion) 4688c2ecf20Sopenharmony_ci */ 4698c2ecf20Sopenharmony_ciSTATIC uint 4708c2ecf20Sopenharmony_cixfs_calc_icreate_resv_alloc( 4718c2ecf20Sopenharmony_ci struct xfs_mount *mp) 4728c2ecf20Sopenharmony_ci{ 4738c2ecf20Sopenharmony_ci return xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) + 4748c2ecf20Sopenharmony_ci mp->m_sb.sb_sectsize + 4758c2ecf20Sopenharmony_ci xfs_calc_inode_chunk_res(mp, _ALLOC) + 4768c2ecf20Sopenharmony_ci xfs_calc_inobt_res(mp) + 4778c2ecf20Sopenharmony_ci xfs_calc_finobt_res(mp); 4788c2ecf20Sopenharmony_ci} 4798c2ecf20Sopenharmony_ci 4808c2ecf20Sopenharmony_ciSTATIC uint 4818c2ecf20Sopenharmony_cixfs_calc_icreate_reservation(xfs_mount_t *mp) 4828c2ecf20Sopenharmony_ci{ 4838c2ecf20Sopenharmony_ci return XFS_DQUOT_LOGRES(mp) + 4848c2ecf20Sopenharmony_ci max(xfs_calc_icreate_resv_alloc(mp), 4858c2ecf20Sopenharmony_ci xfs_calc_create_resv_modify(mp)); 4868c2ecf20Sopenharmony_ci} 4878c2ecf20Sopenharmony_ci 4888c2ecf20Sopenharmony_ciSTATIC uint 4898c2ecf20Sopenharmony_cixfs_calc_create_tmpfile_reservation( 4908c2ecf20Sopenharmony_ci struct xfs_mount *mp) 4918c2ecf20Sopenharmony_ci{ 4928c2ecf20Sopenharmony_ci uint res = XFS_DQUOT_LOGRES(mp); 4938c2ecf20Sopenharmony_ci 4948c2ecf20Sopenharmony_ci res += xfs_calc_icreate_resv_alloc(mp); 4958c2ecf20Sopenharmony_ci return res + xfs_calc_iunlink_add_reservation(mp); 4968c2ecf20Sopenharmony_ci} 4978c2ecf20Sopenharmony_ci 4988c2ecf20Sopenharmony_ci/* 4998c2ecf20Sopenharmony_ci * Making a new directory is the same as creating a new file. 5008c2ecf20Sopenharmony_ci */ 5018c2ecf20Sopenharmony_ciSTATIC uint 5028c2ecf20Sopenharmony_cixfs_calc_mkdir_reservation( 5038c2ecf20Sopenharmony_ci struct xfs_mount *mp) 5048c2ecf20Sopenharmony_ci{ 5058c2ecf20Sopenharmony_ci return xfs_calc_icreate_reservation(mp); 5068c2ecf20Sopenharmony_ci} 5078c2ecf20Sopenharmony_ci 5088c2ecf20Sopenharmony_ci 5098c2ecf20Sopenharmony_ci/* 5108c2ecf20Sopenharmony_ci * Making a new symplink is the same as creating a new file, but 5118c2ecf20Sopenharmony_ci * with the added blocks for remote symlink data which can be up to 1kB in 5128c2ecf20Sopenharmony_ci * length (XFS_SYMLINK_MAXLEN). 5138c2ecf20Sopenharmony_ci */ 5148c2ecf20Sopenharmony_ciSTATIC uint 5158c2ecf20Sopenharmony_cixfs_calc_symlink_reservation( 5168c2ecf20Sopenharmony_ci struct xfs_mount *mp) 5178c2ecf20Sopenharmony_ci{ 5188c2ecf20Sopenharmony_ci return xfs_calc_icreate_reservation(mp) + 5198c2ecf20Sopenharmony_ci xfs_calc_buf_res(1, XFS_SYMLINK_MAXLEN); 5208c2ecf20Sopenharmony_ci} 5218c2ecf20Sopenharmony_ci 5228c2ecf20Sopenharmony_ci/* 5238c2ecf20Sopenharmony_ci * In freeing an inode we can modify: 5248c2ecf20Sopenharmony_ci * the inode being freed: inode size 5258c2ecf20Sopenharmony_ci * the super block free inode counter, AGF and AGFL: sector size 5268c2ecf20Sopenharmony_ci * the on disk inode (agi unlinked list removal) 5278c2ecf20Sopenharmony_ci * the inode chunk (invalidated, headers only) 5288c2ecf20Sopenharmony_ci * the inode btree 5298c2ecf20Sopenharmony_ci * the finobt (record insertion, removal or modification) 5308c2ecf20Sopenharmony_ci * 5318c2ecf20Sopenharmony_ci * Note that the inode chunk res. includes an allocfree res. for freeing of the 5328c2ecf20Sopenharmony_ci * inode chunk. This is technically extraneous because the inode chunk free is 5338c2ecf20Sopenharmony_ci * deferred (it occurs after a transaction roll). Include the extra reservation 5348c2ecf20Sopenharmony_ci * anyways since we've had reports of ifree transaction overruns due to too many 5358c2ecf20Sopenharmony_ci * agfl fixups during inode chunk frees. 5368c2ecf20Sopenharmony_ci */ 5378c2ecf20Sopenharmony_ciSTATIC uint 5388c2ecf20Sopenharmony_cixfs_calc_ifree_reservation( 5398c2ecf20Sopenharmony_ci struct xfs_mount *mp) 5408c2ecf20Sopenharmony_ci{ 5418c2ecf20Sopenharmony_ci return XFS_DQUOT_LOGRES(mp) + 5428c2ecf20Sopenharmony_ci xfs_calc_inode_res(mp, 1) + 5438c2ecf20Sopenharmony_ci xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) + 5448c2ecf20Sopenharmony_ci xfs_calc_iunlink_remove_reservation(mp) + 5458c2ecf20Sopenharmony_ci xfs_calc_inode_chunk_res(mp, _FREE) + 5468c2ecf20Sopenharmony_ci xfs_calc_inobt_res(mp) + 5478c2ecf20Sopenharmony_ci xfs_calc_finobt_res(mp); 5488c2ecf20Sopenharmony_ci} 5498c2ecf20Sopenharmony_ci 5508c2ecf20Sopenharmony_ci/* 5518c2ecf20Sopenharmony_ci * When only changing the inode we log the inode and possibly the superblock 5528c2ecf20Sopenharmony_ci * We also add a bit of slop for the transaction stuff. 5538c2ecf20Sopenharmony_ci */ 5548c2ecf20Sopenharmony_ciSTATIC uint 5558c2ecf20Sopenharmony_cixfs_calc_ichange_reservation( 5568c2ecf20Sopenharmony_ci struct xfs_mount *mp) 5578c2ecf20Sopenharmony_ci{ 5588c2ecf20Sopenharmony_ci return XFS_DQUOT_LOGRES(mp) + 5598c2ecf20Sopenharmony_ci xfs_calc_inode_res(mp, 1) + 5608c2ecf20Sopenharmony_ci xfs_calc_buf_res(1, mp->m_sb.sb_sectsize); 5618c2ecf20Sopenharmony_ci 5628c2ecf20Sopenharmony_ci} 5638c2ecf20Sopenharmony_ci 5648c2ecf20Sopenharmony_ci/* 5658c2ecf20Sopenharmony_ci * Growing the data section of the filesystem. 5668c2ecf20Sopenharmony_ci * superblock 5678c2ecf20Sopenharmony_ci * agi and agf 5688c2ecf20Sopenharmony_ci * allocation btrees 5698c2ecf20Sopenharmony_ci */ 5708c2ecf20Sopenharmony_ciSTATIC uint 5718c2ecf20Sopenharmony_cixfs_calc_growdata_reservation( 5728c2ecf20Sopenharmony_ci struct xfs_mount *mp) 5738c2ecf20Sopenharmony_ci{ 5748c2ecf20Sopenharmony_ci return xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) + 5758c2ecf20Sopenharmony_ci xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), 5768c2ecf20Sopenharmony_ci XFS_FSB_TO_B(mp, 1)); 5778c2ecf20Sopenharmony_ci} 5788c2ecf20Sopenharmony_ci 5798c2ecf20Sopenharmony_ci/* 5808c2ecf20Sopenharmony_ci * Growing the rt section of the filesystem. 5818c2ecf20Sopenharmony_ci * In the first set of transactions (ALLOC) we allocate space to the 5828c2ecf20Sopenharmony_ci * bitmap or summary files. 5838c2ecf20Sopenharmony_ci * superblock: sector size 5848c2ecf20Sopenharmony_ci * agf of the ag from which the extent is allocated: sector size 5858c2ecf20Sopenharmony_ci * bmap btree for bitmap/summary inode: max depth * blocksize 5868c2ecf20Sopenharmony_ci * bitmap/summary inode: inode size 5878c2ecf20Sopenharmony_ci * allocation btrees for 1 block alloc: 2 * (2 * maxdepth - 1) * blocksize 5888c2ecf20Sopenharmony_ci */ 5898c2ecf20Sopenharmony_ciSTATIC uint 5908c2ecf20Sopenharmony_cixfs_calc_growrtalloc_reservation( 5918c2ecf20Sopenharmony_ci struct xfs_mount *mp) 5928c2ecf20Sopenharmony_ci{ 5938c2ecf20Sopenharmony_ci return xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) + 5948c2ecf20Sopenharmony_ci xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK), 5958c2ecf20Sopenharmony_ci XFS_FSB_TO_B(mp, 1)) + 5968c2ecf20Sopenharmony_ci xfs_calc_inode_res(mp, 1) + 5978c2ecf20Sopenharmony_ci xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), 5988c2ecf20Sopenharmony_ci XFS_FSB_TO_B(mp, 1)); 5998c2ecf20Sopenharmony_ci} 6008c2ecf20Sopenharmony_ci 6018c2ecf20Sopenharmony_ci/* 6028c2ecf20Sopenharmony_ci * Growing the rt section of the filesystem. 6038c2ecf20Sopenharmony_ci * In the second set of transactions (ZERO) we zero the new metadata blocks. 6048c2ecf20Sopenharmony_ci * one bitmap/summary block: blocksize 6058c2ecf20Sopenharmony_ci */ 6068c2ecf20Sopenharmony_ciSTATIC uint 6078c2ecf20Sopenharmony_cixfs_calc_growrtzero_reservation( 6088c2ecf20Sopenharmony_ci struct xfs_mount *mp) 6098c2ecf20Sopenharmony_ci{ 6108c2ecf20Sopenharmony_ci return xfs_calc_buf_res(1, mp->m_sb.sb_blocksize); 6118c2ecf20Sopenharmony_ci} 6128c2ecf20Sopenharmony_ci 6138c2ecf20Sopenharmony_ci/* 6148c2ecf20Sopenharmony_ci * Growing the rt section of the filesystem. 6158c2ecf20Sopenharmony_ci * In the third set of transactions (FREE) we update metadata without 6168c2ecf20Sopenharmony_ci * allocating any new blocks. 6178c2ecf20Sopenharmony_ci * superblock: sector size 6188c2ecf20Sopenharmony_ci * bitmap inode: inode size 6198c2ecf20Sopenharmony_ci * summary inode: inode size 6208c2ecf20Sopenharmony_ci * one bitmap block: blocksize 6218c2ecf20Sopenharmony_ci * summary blocks: new summary size 6228c2ecf20Sopenharmony_ci */ 6238c2ecf20Sopenharmony_ciSTATIC uint 6248c2ecf20Sopenharmony_cixfs_calc_growrtfree_reservation( 6258c2ecf20Sopenharmony_ci struct xfs_mount *mp) 6268c2ecf20Sopenharmony_ci{ 6278c2ecf20Sopenharmony_ci return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) + 6288c2ecf20Sopenharmony_ci xfs_calc_inode_res(mp, 2) + 6298c2ecf20Sopenharmony_ci xfs_calc_buf_res(1, mp->m_sb.sb_blocksize) + 6308c2ecf20Sopenharmony_ci xfs_calc_buf_res(1, mp->m_rsumsize); 6318c2ecf20Sopenharmony_ci} 6328c2ecf20Sopenharmony_ci 6338c2ecf20Sopenharmony_ci/* 6348c2ecf20Sopenharmony_ci * Logging the inode modification timestamp on a synchronous write. 6358c2ecf20Sopenharmony_ci * inode 6368c2ecf20Sopenharmony_ci */ 6378c2ecf20Sopenharmony_ciSTATIC uint 6388c2ecf20Sopenharmony_cixfs_calc_swrite_reservation( 6398c2ecf20Sopenharmony_ci struct xfs_mount *mp) 6408c2ecf20Sopenharmony_ci{ 6418c2ecf20Sopenharmony_ci return xfs_calc_inode_res(mp, 1); 6428c2ecf20Sopenharmony_ci} 6438c2ecf20Sopenharmony_ci 6448c2ecf20Sopenharmony_ci/* 6458c2ecf20Sopenharmony_ci * Logging the inode mode bits when writing a setuid/setgid file 6468c2ecf20Sopenharmony_ci * inode 6478c2ecf20Sopenharmony_ci */ 6488c2ecf20Sopenharmony_ciSTATIC uint 6498c2ecf20Sopenharmony_cixfs_calc_writeid_reservation( 6508c2ecf20Sopenharmony_ci struct xfs_mount *mp) 6518c2ecf20Sopenharmony_ci{ 6528c2ecf20Sopenharmony_ci return xfs_calc_inode_res(mp, 1); 6538c2ecf20Sopenharmony_ci} 6548c2ecf20Sopenharmony_ci 6558c2ecf20Sopenharmony_ci/* 6568c2ecf20Sopenharmony_ci * Converting the inode from non-attributed to attributed. 6578c2ecf20Sopenharmony_ci * the inode being converted: inode size 6588c2ecf20Sopenharmony_ci * agf block and superblock (for block allocation) 6598c2ecf20Sopenharmony_ci * the new block (directory sized) 6608c2ecf20Sopenharmony_ci * bmap blocks for the new directory block 6618c2ecf20Sopenharmony_ci * allocation btrees 6628c2ecf20Sopenharmony_ci */ 6638c2ecf20Sopenharmony_ciSTATIC uint 6648c2ecf20Sopenharmony_cixfs_calc_addafork_reservation( 6658c2ecf20Sopenharmony_ci struct xfs_mount *mp) 6668c2ecf20Sopenharmony_ci{ 6678c2ecf20Sopenharmony_ci return XFS_DQUOT_LOGRES(mp) + 6688c2ecf20Sopenharmony_ci xfs_calc_inode_res(mp, 1) + 6698c2ecf20Sopenharmony_ci xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) + 6708c2ecf20Sopenharmony_ci xfs_calc_buf_res(1, mp->m_dir_geo->blksize) + 6718c2ecf20Sopenharmony_ci xfs_calc_buf_res(XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1, 6728c2ecf20Sopenharmony_ci XFS_FSB_TO_B(mp, 1)) + 6738c2ecf20Sopenharmony_ci xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), 6748c2ecf20Sopenharmony_ci XFS_FSB_TO_B(mp, 1)); 6758c2ecf20Sopenharmony_ci} 6768c2ecf20Sopenharmony_ci 6778c2ecf20Sopenharmony_ci/* 6788c2ecf20Sopenharmony_ci * Removing the attribute fork of a file 6798c2ecf20Sopenharmony_ci * the inode being truncated: inode size 6808c2ecf20Sopenharmony_ci * the inode's bmap btree: max depth * block size 6818c2ecf20Sopenharmony_ci * And the bmap_finish transaction can free the blocks and bmap blocks: 6828c2ecf20Sopenharmony_ci * the agf for each of the ags: 4 * sector size 6838c2ecf20Sopenharmony_ci * the agfl for each of the ags: 4 * sector size 6848c2ecf20Sopenharmony_ci * the super block to reflect the freed blocks: sector size 6858c2ecf20Sopenharmony_ci * worst case split in allocation btrees per extent assuming 4 extents: 6868c2ecf20Sopenharmony_ci * 4 exts * 2 trees * (2 * max depth - 1) * block size 6878c2ecf20Sopenharmony_ci */ 6888c2ecf20Sopenharmony_ciSTATIC uint 6898c2ecf20Sopenharmony_cixfs_calc_attrinval_reservation( 6908c2ecf20Sopenharmony_ci struct xfs_mount *mp) 6918c2ecf20Sopenharmony_ci{ 6928c2ecf20Sopenharmony_ci return max((xfs_calc_inode_res(mp, 1) + 6938c2ecf20Sopenharmony_ci xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK), 6948c2ecf20Sopenharmony_ci XFS_FSB_TO_B(mp, 1))), 6958c2ecf20Sopenharmony_ci (xfs_calc_buf_res(9, mp->m_sb.sb_sectsize) + 6968c2ecf20Sopenharmony_ci xfs_calc_buf_res(xfs_allocfree_log_count(mp, 4), 6978c2ecf20Sopenharmony_ci XFS_FSB_TO_B(mp, 1)))); 6988c2ecf20Sopenharmony_ci} 6998c2ecf20Sopenharmony_ci 7008c2ecf20Sopenharmony_ci/* 7018c2ecf20Sopenharmony_ci * Setting an attribute at mount time. 7028c2ecf20Sopenharmony_ci * the inode getting the attribute 7038c2ecf20Sopenharmony_ci * the superblock for allocations 7048c2ecf20Sopenharmony_ci * the agfs extents are allocated from 7058c2ecf20Sopenharmony_ci * the attribute btree * max depth 7068c2ecf20Sopenharmony_ci * the inode allocation btree 7078c2ecf20Sopenharmony_ci * Since attribute transaction space is dependent on the size of the attribute, 7088c2ecf20Sopenharmony_ci * the calculation is done partially at mount time and partially at runtime(see 7098c2ecf20Sopenharmony_ci * below). 7108c2ecf20Sopenharmony_ci */ 7118c2ecf20Sopenharmony_ciSTATIC uint 7128c2ecf20Sopenharmony_cixfs_calc_attrsetm_reservation( 7138c2ecf20Sopenharmony_ci struct xfs_mount *mp) 7148c2ecf20Sopenharmony_ci{ 7158c2ecf20Sopenharmony_ci return XFS_DQUOT_LOGRES(mp) + 7168c2ecf20Sopenharmony_ci xfs_calc_inode_res(mp, 1) + 7178c2ecf20Sopenharmony_ci xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) + 7188c2ecf20Sopenharmony_ci xfs_calc_buf_res(XFS_DA_NODE_MAXDEPTH, XFS_FSB_TO_B(mp, 1)); 7198c2ecf20Sopenharmony_ci} 7208c2ecf20Sopenharmony_ci 7218c2ecf20Sopenharmony_ci/* 7228c2ecf20Sopenharmony_ci * Setting an attribute at runtime, transaction space unit per block. 7238c2ecf20Sopenharmony_ci * the superblock for allocations: sector size 7248c2ecf20Sopenharmony_ci * the inode bmap btree could join or split: max depth * block size 7258c2ecf20Sopenharmony_ci * Since the runtime attribute transaction space is dependent on the total 7268c2ecf20Sopenharmony_ci * blocks needed for the 1st bmap, here we calculate out the space unit for 7278c2ecf20Sopenharmony_ci * one block so that the caller could figure out the total space according 7288c2ecf20Sopenharmony_ci * to the attibute extent length in blocks by: 7298c2ecf20Sopenharmony_ci * ext * M_RES(mp)->tr_attrsetrt.tr_logres 7308c2ecf20Sopenharmony_ci */ 7318c2ecf20Sopenharmony_ciSTATIC uint 7328c2ecf20Sopenharmony_cixfs_calc_attrsetrt_reservation( 7338c2ecf20Sopenharmony_ci struct xfs_mount *mp) 7348c2ecf20Sopenharmony_ci{ 7358c2ecf20Sopenharmony_ci return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) + 7368c2ecf20Sopenharmony_ci xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK), 7378c2ecf20Sopenharmony_ci XFS_FSB_TO_B(mp, 1)); 7388c2ecf20Sopenharmony_ci} 7398c2ecf20Sopenharmony_ci 7408c2ecf20Sopenharmony_ci/* 7418c2ecf20Sopenharmony_ci * Removing an attribute. 7428c2ecf20Sopenharmony_ci * the inode: inode size 7438c2ecf20Sopenharmony_ci * the attribute btree could join: max depth * block size 7448c2ecf20Sopenharmony_ci * the inode bmap btree could join or split: max depth * block size 7458c2ecf20Sopenharmony_ci * And the bmap_finish transaction can free the attr blocks freed giving: 7468c2ecf20Sopenharmony_ci * the agf for the ag in which the blocks live: 2 * sector size 7478c2ecf20Sopenharmony_ci * the agfl for the ag in which the blocks live: 2 * sector size 7488c2ecf20Sopenharmony_ci * the superblock for the free block count: sector size 7498c2ecf20Sopenharmony_ci * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size 7508c2ecf20Sopenharmony_ci */ 7518c2ecf20Sopenharmony_ciSTATIC uint 7528c2ecf20Sopenharmony_cixfs_calc_attrrm_reservation( 7538c2ecf20Sopenharmony_ci struct xfs_mount *mp) 7548c2ecf20Sopenharmony_ci{ 7558c2ecf20Sopenharmony_ci return XFS_DQUOT_LOGRES(mp) + 7568c2ecf20Sopenharmony_ci max((xfs_calc_inode_res(mp, 1) + 7578c2ecf20Sopenharmony_ci xfs_calc_buf_res(XFS_DA_NODE_MAXDEPTH, 7588c2ecf20Sopenharmony_ci XFS_FSB_TO_B(mp, 1)) + 7598c2ecf20Sopenharmony_ci (uint)XFS_FSB_TO_B(mp, 7608c2ecf20Sopenharmony_ci XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) + 7618c2ecf20Sopenharmony_ci xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK), 0)), 7628c2ecf20Sopenharmony_ci (xfs_calc_buf_res(5, mp->m_sb.sb_sectsize) + 7638c2ecf20Sopenharmony_ci xfs_calc_buf_res(xfs_allocfree_log_count(mp, 2), 7648c2ecf20Sopenharmony_ci XFS_FSB_TO_B(mp, 1)))); 7658c2ecf20Sopenharmony_ci} 7668c2ecf20Sopenharmony_ci 7678c2ecf20Sopenharmony_ci/* 7688c2ecf20Sopenharmony_ci * Clearing a bad agino number in an agi hash bucket. 7698c2ecf20Sopenharmony_ci */ 7708c2ecf20Sopenharmony_ciSTATIC uint 7718c2ecf20Sopenharmony_cixfs_calc_clear_agi_bucket_reservation( 7728c2ecf20Sopenharmony_ci struct xfs_mount *mp) 7738c2ecf20Sopenharmony_ci{ 7748c2ecf20Sopenharmony_ci return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize); 7758c2ecf20Sopenharmony_ci} 7768c2ecf20Sopenharmony_ci 7778c2ecf20Sopenharmony_ci/* 7788c2ecf20Sopenharmony_ci * Adjusting quota limits. 7798c2ecf20Sopenharmony_ci * the disk quota buffer: sizeof(struct xfs_disk_dquot) 7808c2ecf20Sopenharmony_ci */ 7818c2ecf20Sopenharmony_ciSTATIC uint 7828c2ecf20Sopenharmony_cixfs_calc_qm_setqlim_reservation(void) 7838c2ecf20Sopenharmony_ci{ 7848c2ecf20Sopenharmony_ci return xfs_calc_buf_res(1, sizeof(struct xfs_disk_dquot)); 7858c2ecf20Sopenharmony_ci} 7868c2ecf20Sopenharmony_ci 7878c2ecf20Sopenharmony_ci/* 7888c2ecf20Sopenharmony_ci * Allocating quota on disk if needed. 7898c2ecf20Sopenharmony_ci * the write transaction log space for quota file extent allocation 7908c2ecf20Sopenharmony_ci * the unit of quota allocation: one system block size 7918c2ecf20Sopenharmony_ci */ 7928c2ecf20Sopenharmony_ciSTATIC uint 7938c2ecf20Sopenharmony_cixfs_calc_qm_dqalloc_reservation( 7948c2ecf20Sopenharmony_ci struct xfs_mount *mp) 7958c2ecf20Sopenharmony_ci{ 7968c2ecf20Sopenharmony_ci return xfs_calc_write_reservation(mp) + 7978c2ecf20Sopenharmony_ci xfs_calc_buf_res(1, 7988c2ecf20Sopenharmony_ci XFS_FSB_TO_B(mp, XFS_DQUOT_CLUSTER_SIZE_FSB) - 1); 7998c2ecf20Sopenharmony_ci} 8008c2ecf20Sopenharmony_ci 8018c2ecf20Sopenharmony_ci/* 8028c2ecf20Sopenharmony_ci * Turning off quotas. 8038c2ecf20Sopenharmony_ci * the quota off logitems: sizeof(struct xfs_qoff_logitem) * 2 8048c2ecf20Sopenharmony_ci * the superblock for the quota flags: sector size 8058c2ecf20Sopenharmony_ci */ 8068c2ecf20Sopenharmony_ciSTATIC uint 8078c2ecf20Sopenharmony_cixfs_calc_qm_quotaoff_reservation( 8088c2ecf20Sopenharmony_ci struct xfs_mount *mp) 8098c2ecf20Sopenharmony_ci{ 8108c2ecf20Sopenharmony_ci return sizeof(struct xfs_qoff_logitem) * 2 + 8118c2ecf20Sopenharmony_ci xfs_calc_buf_res(1, mp->m_sb.sb_sectsize); 8128c2ecf20Sopenharmony_ci} 8138c2ecf20Sopenharmony_ci 8148c2ecf20Sopenharmony_ci/* 8158c2ecf20Sopenharmony_ci * End of turning off quotas. 8168c2ecf20Sopenharmony_ci * the quota off logitems: sizeof(struct xfs_qoff_logitem) * 2 8178c2ecf20Sopenharmony_ci */ 8188c2ecf20Sopenharmony_ciSTATIC uint 8198c2ecf20Sopenharmony_cixfs_calc_qm_quotaoff_end_reservation(void) 8208c2ecf20Sopenharmony_ci{ 8218c2ecf20Sopenharmony_ci return sizeof(struct xfs_qoff_logitem) * 2; 8228c2ecf20Sopenharmony_ci} 8238c2ecf20Sopenharmony_ci 8248c2ecf20Sopenharmony_ci/* 8258c2ecf20Sopenharmony_ci * Syncing the incore super block changes to disk. 8268c2ecf20Sopenharmony_ci * the super block to reflect the changes: sector size 8278c2ecf20Sopenharmony_ci */ 8288c2ecf20Sopenharmony_ciSTATIC uint 8298c2ecf20Sopenharmony_cixfs_calc_sb_reservation( 8308c2ecf20Sopenharmony_ci struct xfs_mount *mp) 8318c2ecf20Sopenharmony_ci{ 8328c2ecf20Sopenharmony_ci return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize); 8338c2ecf20Sopenharmony_ci} 8348c2ecf20Sopenharmony_ci 8358c2ecf20Sopenharmony_civoid 8368c2ecf20Sopenharmony_cixfs_trans_resv_calc( 8378c2ecf20Sopenharmony_ci struct xfs_mount *mp, 8388c2ecf20Sopenharmony_ci struct xfs_trans_resv *resp) 8398c2ecf20Sopenharmony_ci{ 8408c2ecf20Sopenharmony_ci /* 8418c2ecf20Sopenharmony_ci * The following transactions are logged in physical format and 8428c2ecf20Sopenharmony_ci * require a permanent reservation on space. 8438c2ecf20Sopenharmony_ci */ 8448c2ecf20Sopenharmony_ci resp->tr_write.tr_logres = xfs_calc_write_reservation(mp); 8458c2ecf20Sopenharmony_ci if (xfs_sb_version_hasreflink(&mp->m_sb)) 8468c2ecf20Sopenharmony_ci resp->tr_write.tr_logcount = XFS_WRITE_LOG_COUNT_REFLINK; 8478c2ecf20Sopenharmony_ci else 8488c2ecf20Sopenharmony_ci resp->tr_write.tr_logcount = XFS_WRITE_LOG_COUNT; 8498c2ecf20Sopenharmony_ci resp->tr_write.tr_logflags |= XFS_TRANS_PERM_LOG_RES; 8508c2ecf20Sopenharmony_ci 8518c2ecf20Sopenharmony_ci resp->tr_itruncate.tr_logres = xfs_calc_itruncate_reservation(mp); 8528c2ecf20Sopenharmony_ci if (xfs_sb_version_hasreflink(&mp->m_sb)) 8538c2ecf20Sopenharmony_ci resp->tr_itruncate.tr_logcount = 8548c2ecf20Sopenharmony_ci XFS_ITRUNCATE_LOG_COUNT_REFLINK; 8558c2ecf20Sopenharmony_ci else 8568c2ecf20Sopenharmony_ci resp->tr_itruncate.tr_logcount = XFS_ITRUNCATE_LOG_COUNT; 8578c2ecf20Sopenharmony_ci resp->tr_itruncate.tr_logflags |= XFS_TRANS_PERM_LOG_RES; 8588c2ecf20Sopenharmony_ci 8598c2ecf20Sopenharmony_ci resp->tr_rename.tr_logres = xfs_calc_rename_reservation(mp); 8608c2ecf20Sopenharmony_ci resp->tr_rename.tr_logcount = XFS_RENAME_LOG_COUNT; 8618c2ecf20Sopenharmony_ci resp->tr_rename.tr_logflags |= XFS_TRANS_PERM_LOG_RES; 8628c2ecf20Sopenharmony_ci 8638c2ecf20Sopenharmony_ci resp->tr_link.tr_logres = xfs_calc_link_reservation(mp); 8648c2ecf20Sopenharmony_ci resp->tr_link.tr_logcount = XFS_LINK_LOG_COUNT; 8658c2ecf20Sopenharmony_ci resp->tr_link.tr_logflags |= XFS_TRANS_PERM_LOG_RES; 8668c2ecf20Sopenharmony_ci 8678c2ecf20Sopenharmony_ci resp->tr_remove.tr_logres = xfs_calc_remove_reservation(mp); 8688c2ecf20Sopenharmony_ci resp->tr_remove.tr_logcount = XFS_REMOVE_LOG_COUNT; 8698c2ecf20Sopenharmony_ci resp->tr_remove.tr_logflags |= XFS_TRANS_PERM_LOG_RES; 8708c2ecf20Sopenharmony_ci 8718c2ecf20Sopenharmony_ci resp->tr_symlink.tr_logres = xfs_calc_symlink_reservation(mp); 8728c2ecf20Sopenharmony_ci resp->tr_symlink.tr_logcount = XFS_SYMLINK_LOG_COUNT; 8738c2ecf20Sopenharmony_ci resp->tr_symlink.tr_logflags |= XFS_TRANS_PERM_LOG_RES; 8748c2ecf20Sopenharmony_ci 8758c2ecf20Sopenharmony_ci resp->tr_create.tr_logres = xfs_calc_icreate_reservation(mp); 8768c2ecf20Sopenharmony_ci resp->tr_create.tr_logcount = XFS_CREATE_LOG_COUNT; 8778c2ecf20Sopenharmony_ci resp->tr_create.tr_logflags |= XFS_TRANS_PERM_LOG_RES; 8788c2ecf20Sopenharmony_ci 8798c2ecf20Sopenharmony_ci resp->tr_create_tmpfile.tr_logres = 8808c2ecf20Sopenharmony_ci xfs_calc_create_tmpfile_reservation(mp); 8818c2ecf20Sopenharmony_ci resp->tr_create_tmpfile.tr_logcount = XFS_CREATE_TMPFILE_LOG_COUNT; 8828c2ecf20Sopenharmony_ci resp->tr_create_tmpfile.tr_logflags |= XFS_TRANS_PERM_LOG_RES; 8838c2ecf20Sopenharmony_ci 8848c2ecf20Sopenharmony_ci resp->tr_mkdir.tr_logres = xfs_calc_mkdir_reservation(mp); 8858c2ecf20Sopenharmony_ci resp->tr_mkdir.tr_logcount = XFS_MKDIR_LOG_COUNT; 8868c2ecf20Sopenharmony_ci resp->tr_mkdir.tr_logflags |= XFS_TRANS_PERM_LOG_RES; 8878c2ecf20Sopenharmony_ci 8888c2ecf20Sopenharmony_ci resp->tr_ifree.tr_logres = xfs_calc_ifree_reservation(mp); 8898c2ecf20Sopenharmony_ci resp->tr_ifree.tr_logcount = XFS_INACTIVE_LOG_COUNT; 8908c2ecf20Sopenharmony_ci resp->tr_ifree.tr_logflags |= XFS_TRANS_PERM_LOG_RES; 8918c2ecf20Sopenharmony_ci 8928c2ecf20Sopenharmony_ci resp->tr_addafork.tr_logres = xfs_calc_addafork_reservation(mp); 8938c2ecf20Sopenharmony_ci resp->tr_addafork.tr_logcount = XFS_ADDAFORK_LOG_COUNT; 8948c2ecf20Sopenharmony_ci resp->tr_addafork.tr_logflags |= XFS_TRANS_PERM_LOG_RES; 8958c2ecf20Sopenharmony_ci 8968c2ecf20Sopenharmony_ci resp->tr_attrinval.tr_logres = xfs_calc_attrinval_reservation(mp); 8978c2ecf20Sopenharmony_ci resp->tr_attrinval.tr_logcount = XFS_ATTRINVAL_LOG_COUNT; 8988c2ecf20Sopenharmony_ci resp->tr_attrinval.tr_logflags |= XFS_TRANS_PERM_LOG_RES; 8998c2ecf20Sopenharmony_ci 9008c2ecf20Sopenharmony_ci resp->tr_attrsetm.tr_logres = xfs_calc_attrsetm_reservation(mp); 9018c2ecf20Sopenharmony_ci resp->tr_attrsetm.tr_logcount = XFS_ATTRSET_LOG_COUNT; 9028c2ecf20Sopenharmony_ci resp->tr_attrsetm.tr_logflags |= XFS_TRANS_PERM_LOG_RES; 9038c2ecf20Sopenharmony_ci 9048c2ecf20Sopenharmony_ci resp->tr_attrrm.tr_logres = xfs_calc_attrrm_reservation(mp); 9058c2ecf20Sopenharmony_ci resp->tr_attrrm.tr_logcount = XFS_ATTRRM_LOG_COUNT; 9068c2ecf20Sopenharmony_ci resp->tr_attrrm.tr_logflags |= XFS_TRANS_PERM_LOG_RES; 9078c2ecf20Sopenharmony_ci 9088c2ecf20Sopenharmony_ci resp->tr_growrtalloc.tr_logres = xfs_calc_growrtalloc_reservation(mp); 9098c2ecf20Sopenharmony_ci resp->tr_growrtalloc.tr_logcount = XFS_DEFAULT_PERM_LOG_COUNT; 9108c2ecf20Sopenharmony_ci resp->tr_growrtalloc.tr_logflags |= XFS_TRANS_PERM_LOG_RES; 9118c2ecf20Sopenharmony_ci 9128c2ecf20Sopenharmony_ci resp->tr_qm_dqalloc.tr_logres = xfs_calc_qm_dqalloc_reservation(mp); 9138c2ecf20Sopenharmony_ci if (xfs_sb_version_hasreflink(&mp->m_sb)) 9148c2ecf20Sopenharmony_ci resp->tr_qm_dqalloc.tr_logcount = XFS_WRITE_LOG_COUNT_REFLINK; 9158c2ecf20Sopenharmony_ci else 9168c2ecf20Sopenharmony_ci resp->tr_qm_dqalloc.tr_logcount = XFS_WRITE_LOG_COUNT; 9178c2ecf20Sopenharmony_ci resp->tr_qm_dqalloc.tr_logflags |= XFS_TRANS_PERM_LOG_RES; 9188c2ecf20Sopenharmony_ci 9198c2ecf20Sopenharmony_ci /* 9208c2ecf20Sopenharmony_ci * The following transactions are logged in logical format with 9218c2ecf20Sopenharmony_ci * a default log count. 9228c2ecf20Sopenharmony_ci */ 9238c2ecf20Sopenharmony_ci resp->tr_qm_setqlim.tr_logres = xfs_calc_qm_setqlim_reservation(); 9248c2ecf20Sopenharmony_ci resp->tr_qm_setqlim.tr_logcount = XFS_DEFAULT_LOG_COUNT; 9258c2ecf20Sopenharmony_ci 9268c2ecf20Sopenharmony_ci resp->tr_qm_quotaoff.tr_logres = xfs_calc_qm_quotaoff_reservation(mp); 9278c2ecf20Sopenharmony_ci resp->tr_qm_quotaoff.tr_logcount = XFS_DEFAULT_LOG_COUNT; 9288c2ecf20Sopenharmony_ci 9298c2ecf20Sopenharmony_ci resp->tr_qm_equotaoff.tr_logres = 9308c2ecf20Sopenharmony_ci xfs_calc_qm_quotaoff_end_reservation(); 9318c2ecf20Sopenharmony_ci resp->tr_qm_equotaoff.tr_logcount = XFS_DEFAULT_LOG_COUNT; 9328c2ecf20Sopenharmony_ci 9338c2ecf20Sopenharmony_ci resp->tr_sb.tr_logres = xfs_calc_sb_reservation(mp); 9348c2ecf20Sopenharmony_ci resp->tr_sb.tr_logcount = XFS_DEFAULT_LOG_COUNT; 9358c2ecf20Sopenharmony_ci 9368c2ecf20Sopenharmony_ci /* growdata requires permanent res; it can free space to the last AG */ 9378c2ecf20Sopenharmony_ci resp->tr_growdata.tr_logres = xfs_calc_growdata_reservation(mp); 9388c2ecf20Sopenharmony_ci resp->tr_growdata.tr_logcount = XFS_DEFAULT_PERM_LOG_COUNT; 9398c2ecf20Sopenharmony_ci resp->tr_growdata.tr_logflags |= XFS_TRANS_PERM_LOG_RES; 9408c2ecf20Sopenharmony_ci 9418c2ecf20Sopenharmony_ci /* The following transaction are logged in logical format */ 9428c2ecf20Sopenharmony_ci resp->tr_ichange.tr_logres = xfs_calc_ichange_reservation(mp); 9438c2ecf20Sopenharmony_ci resp->tr_fsyncts.tr_logres = xfs_calc_swrite_reservation(mp); 9448c2ecf20Sopenharmony_ci resp->tr_writeid.tr_logres = xfs_calc_writeid_reservation(mp); 9458c2ecf20Sopenharmony_ci resp->tr_attrsetrt.tr_logres = xfs_calc_attrsetrt_reservation(mp); 9468c2ecf20Sopenharmony_ci resp->tr_clearagi.tr_logres = xfs_calc_clear_agi_bucket_reservation(mp); 9478c2ecf20Sopenharmony_ci resp->tr_growrtzero.tr_logres = xfs_calc_growrtzero_reservation(mp); 9488c2ecf20Sopenharmony_ci resp->tr_growrtfree.tr_logres = xfs_calc_growrtfree_reservation(mp); 9498c2ecf20Sopenharmony_ci} 950