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