Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0 2 : /* 3 : * Copyright (c) 2013 Jie Liu. 4 : * All Rights Reserved. 5 : */ 6 : #include "xfs.h" 7 : #include "xfs_fs.h" 8 : #include "xfs_shared.h" 9 : #include "xfs_format.h" 10 : #include "xfs_log_format.h" 11 : #include "xfs_trans_resv.h" 12 : #include "xfs_mount.h" 13 : #include "xfs_da_format.h" 14 : #include "xfs_trans_space.h" 15 : #include "xfs_da_btree.h" 16 : #include "xfs_bmap_btree.h" 17 : #include "xfs_trace.h" 18 : 19 : /* 20 : * Decide if the filesystem has the parent pointer feature or any feature 21 : * added after that. 22 : */ 23 : static inline bool 24 137452 : xfs_has_parent_or_newer_feature( 25 : struct xfs_mount *mp) 26 : { 27 137452 : if (!xfs_sb_is_v5(&mp->m_sb)) 28 : return false; 29 : 30 136958 : if (xfs_sb_has_compat_feature(&mp->m_sb, ~0)) 31 : return true; 32 : 33 136958 : if (xfs_sb_has_ro_compat_feature(&mp->m_sb, 34 : ~(XFS_SB_FEAT_RO_COMPAT_FINOBT | 35 : XFS_SB_FEAT_RO_COMPAT_RMAPBT | 36 : XFS_SB_FEAT_RO_COMPAT_REFLINK | 37 : XFS_SB_FEAT_RO_COMPAT_INOBTCNT))) 38 : return true; 39 : 40 136936 : if (xfs_sb_has_incompat_feature(&mp->m_sb, 41 : ~(XFS_SB_FEAT_INCOMPAT_FTYPE | 42 : XFS_SB_FEAT_INCOMPAT_SPINODES | 43 : XFS_SB_FEAT_INCOMPAT_META_UUID | 44 : XFS_SB_FEAT_INCOMPAT_BIGTIME | 45 : XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR | 46 : XFS_SB_FEAT_INCOMPAT_NREXT64))) 47 124570 : return true; 48 : 49 : return false; 50 : } 51 : 52 : /* 53 : * Calculate the maximum length in bytes that would be required for a local 54 : * attribute value as large attributes out of line are not logged. 55 : */ 56 : STATIC int 57 68726 : xfs_log_calc_max_attrsetm_res( 58 : struct xfs_mount *mp) 59 : { 60 68726 : int size; 61 68726 : int nblks; 62 : 63 68726 : size = xfs_attr_leaf_entsize_local_max(mp->m_attr_geo->blksize) - 64 : MAXNAMELEN - 1; 65 68726 : nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK); 66 68726 : nblks += XFS_B_TO_FSB(mp, size); 67 : 68 : /* 69 : * Starting with the parent pointer feature, every new fs feature 70 : * corrects a unit conversion error in the xattr transaction 71 : * reservation code that resulted in oversized minimum log size 72 : * computations. 73 : */ 74 68726 : if (xfs_has_parent_or_newer_feature(mp)) 75 62296 : size = XFS_B_TO_FSB(mp, size); 76 : 77 68726 : nblks += XFS_NEXTENTADD_SPACE_RES(mp, size, XFS_ATTR_FORK); 78 : 79 68726 : return M_RES(mp)->tr_attrsetm.tr_logres + 80 68726 : M_RES(mp)->tr_attrsetrt.tr_logres * nblks; 81 : } 82 : 83 : /* 84 : * Compute an alternate set of log reservation sizes for use exclusively with 85 : * minimum log size calculations. 86 : */ 87 : static void 88 68726 : xfs_log_calc_trans_resv_for_minlogblocks( 89 : struct xfs_mount *mp, 90 : struct xfs_trans_resv *resv) 91 : { 92 68726 : unsigned int rmap_maxlevels = mp->m_rmap_maxlevels; 93 : 94 : /* 95 : * Starting with the parent pointer feature, every new fs feature 96 : * drops the oversized minimum log size computation introduced by the 97 : * original reflink code. 98 : */ 99 68726 : if (xfs_has_parent_or_newer_feature(mp)) { 100 62296 : xfs_trans_resv_calc(mp, resv); 101 62296 : return; 102 : } 103 : 104 : /* 105 : * In the early days of rmap+reflink, we always set the rmap maxlevels 106 : * to 9 even if the AG was small enough that it would never grow to 107 : * that height. Transaction reservation sizes influence the minimum 108 : * log size calculation, which influences the size of the log that mkfs 109 : * creates. Use the old value here to ensure that newly formatted 110 : * small filesystems will mount on older kernels. 111 : */ 112 6430 : if (xfs_has_rmapbt(mp) && xfs_has_reflink(mp)) 113 1827 : mp->m_rmap_maxlevels = XFS_OLD_REFLINK_RMAP_MAXLEVELS; 114 : 115 6430 : xfs_trans_resv_calc(mp, resv); 116 : 117 6430 : if (xfs_has_reflink(mp)) { 118 : /* 119 : * In the early days of reflink, typical log operation counts 120 : * were greatly overestimated. 121 : */ 122 1827 : resv->tr_write.tr_logcount = XFS_WRITE_LOG_COUNT_REFLINK; 123 1827 : resv->tr_itruncate.tr_logcount = 124 : XFS_ITRUNCATE_LOG_COUNT_REFLINK; 125 1827 : resv->tr_qm_dqalloc.tr_logcount = XFS_WRITE_LOG_COUNT_REFLINK; 126 4603 : } else if (xfs_has_rmapbt(mp)) { 127 : /* 128 : * In the early days of non-reflink rmap, the impact of rmapbt 129 : * updates on log counts were not taken into account at all. 130 : */ 131 0 : resv->tr_write.tr_logcount = XFS_WRITE_LOG_COUNT; 132 0 : resv->tr_itruncate.tr_logcount = XFS_ITRUNCATE_LOG_COUNT; 133 0 : resv->tr_qm_dqalloc.tr_logcount = XFS_WRITE_LOG_COUNT; 134 : } 135 : 136 : /* 137 : * In the early days of reflink, we did not use deferred refcount 138 : * update log items, so log reservations must be recomputed using the 139 : * old calculations. 140 : */ 141 12860 : resv->tr_write.tr_logres = 142 6430 : xfs_calc_write_reservation_minlogsize(mp); 143 12860 : resv->tr_itruncate.tr_logres = 144 6430 : xfs_calc_itruncate_reservation_minlogsize(mp); 145 12860 : resv->tr_qm_dqalloc.tr_logres = 146 6430 : xfs_calc_qm_dqalloc_reservation_minlogsize(mp); 147 : 148 : /* Put everything back the way it was. This goes at the end. */ 149 6430 : mp->m_rmap_maxlevels = rmap_maxlevels; 150 : } 151 : 152 : /* 153 : * Iterate over the log space reservation table to figure out and return 154 : * the maximum one in terms of the pre-calculated values which were done 155 : * at mount time. 156 : */ 157 : void 158 68726 : xfs_log_get_max_trans_res( 159 : struct xfs_mount *mp, 160 : struct xfs_trans_res *max_resp) 161 : { 162 68726 : struct xfs_trans_resv resv = {}; 163 68726 : struct xfs_trans_res *resp; 164 68726 : struct xfs_trans_res *end_resp; 165 68726 : unsigned int i; 166 68726 : int log_space = 0; 167 68726 : int attr_space; 168 : 169 68726 : attr_space = xfs_log_calc_max_attrsetm_res(mp); 170 : 171 68726 : xfs_log_calc_trans_resv_for_minlogblocks(mp, &resv); 172 : 173 68726 : resp = (struct xfs_trans_res *)&resv; 174 68726 : end_resp = (struct xfs_trans_res *)(&resv + 1); 175 2130506 : for (i = 0; resp < end_resp; i++, resp++) { 176 1993054 : int tmp = resp->tr_logcount > 1 ? 177 1993054 : resp->tr_logres * resp->tr_logcount : 178 687260 : resp->tr_logres; 179 : 180 1993054 : trace_xfs_trans_resv_calc_minlogsize(mp, i, resp); 181 1993054 : if (log_space < tmp) { 182 189475 : log_space = tmp; 183 189475 : *max_resp = *resp; /* struct copy */ 184 : } 185 : } 186 : 187 68726 : if (attr_space > log_space) { 188 4407 : *max_resp = resv.tr_attrsetm; /* struct copy */ 189 4407 : max_resp->tr_logres = attr_space; 190 : } 191 68726 : trace_xfs_log_get_max_trans_res(mp, max_resp); 192 68726 : } 193 : 194 : /* 195 : * Calculate the minimum valid log size for the given superblock configuration. 196 : * Used to calculate the minimum log size at mkfs time, and to determine if 197 : * the log is large enough or not at mount time. Returns the minimum size in 198 : * filesystem block size units. 199 : */ 200 : int 201 68726 : xfs_log_calc_minimum_size( 202 : struct xfs_mount *mp) 203 : { 204 68726 : struct xfs_trans_res tres = {0}; 205 68726 : int max_logres; 206 68726 : int min_logblks = 0; 207 68726 : int lsunit = 0; 208 : 209 68726 : xfs_log_get_max_trans_res(mp, &tres); 210 : 211 68726 : max_logres = xfs_log_calc_unit_res(mp, tres.tr_logres); 212 68726 : if (tres.tr_logcount > 1) 213 68726 : max_logres *= tres.tr_logcount; 214 : 215 68726 : if (xfs_has_logv2(mp) && mp->m_sb.sb_logsunit > 1) 216 41549 : lsunit = BTOBB(mp->m_sb.sb_logsunit); 217 : 218 : /* 219 : * Two factors should be taken into account for calculating the minimum 220 : * log space. 221 : * 1) The fundamental limitation is that no single transaction can be 222 : * larger than half size of the log. 223 : * 224 : * From mkfs.xfs, this is considered by the XFS_MIN_LOG_FACTOR 225 : * define, which is set to 3. That means we can definitely fit 226 : * maximally sized 2 transactions in the log. We'll use this same 227 : * value here. 228 : * 229 : * 2) If the lsunit option is specified, a transaction requires 2 LSU 230 : * for the reservation because there are two log writes that can 231 : * require padding - the transaction data and the commit record which 232 : * are written separately and both can require padding to the LSU. 233 : * Consider that we can have an active CIL reservation holding 2*LSU, 234 : * but the CIL is not over a push threshold, in this case, if we 235 : * don't have enough log space for at one new transaction, which 236 : * includes another 2*LSU in the reservation, we will run into dead 237 : * loop situation in log space grant procedure. i.e. 238 : * xlog_grant_head_wait(). 239 : * 240 : * Hence the log size needs to be able to contain two maximally sized 241 : * and padded transactions, which is (2 * (2 * LSU + maxlres)). 242 : * 243 : * Also, the log size should be a multiple of the log stripe unit, round 244 : * it up to lsunit boundary if lsunit is specified. 245 : */ 246 41549 : if (lsunit) { 247 41549 : min_logblks = roundup_64(BTOBB(max_logres), lsunit) + 248 41549 : 2 * lsunit; 249 : } else 250 27177 : min_logblks = BTOBB(max_logres) + 2 * BBSIZE; 251 68726 : min_logblks *= XFS_MIN_LOG_FACTOR; 252 : 253 68726 : return XFS_BB_TO_FSB(mp, min_logblks); 254 : }