1 /* 2 * Copyright (c) 2013 Jie Liu. 3 * All Rights Reserved. 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it would be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write the Free Software Foundation, 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 #include "xfs.h" 19 #include "xfs_fs.h" 20 #include "xfs_shared.h" 21 #include "xfs_format.h" 22 #include "xfs_log_format.h" 23 #include "xfs_trans_resv.h" 24 #include "xfs_ag.h" 25 #include "xfs_sb.h" 26 #include "xfs_mount.h" 27 #include "xfs_da_format.h" 28 #include "xfs_trans_space.h" 29 #include "xfs_inode.h" 30 #include "xfs_da_btree.h" 31 #include "xfs_attr_leaf.h" 32 #include "xfs_bmap_btree.h" 33 34 /* 35 * Calculate the maximum length in bytes that would be required for a local 36 * attribute value as large attributes out of line are not logged. 37 */ 38 STATIC int 39 xfs_log_calc_max_attrsetm_res( 40 struct xfs_mount *mp) 41 { 42 int size; 43 int nblks; 44 45 size = xfs_attr_leaf_entsize_local_max(mp->m_attr_geo->blksize) - 46 MAXNAMELEN - 1; 47 nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK); 48 nblks += XFS_B_TO_FSB(mp, size); 49 nblks += XFS_NEXTENTADD_SPACE_RES(mp, size, XFS_ATTR_FORK); 50 51 return M_RES(mp)->tr_attrsetm.tr_logres + 52 M_RES(mp)->tr_attrsetrt.tr_logres * nblks; 53 } 54 55 /* 56 * Iterate over the log space reservation table to figure out and return 57 * the maximum one in terms of the pre-calculated values which were done 58 * at mount time. 59 */ 60 STATIC void 61 xfs_log_get_max_trans_res( 62 struct xfs_mount *mp, 63 struct xfs_trans_res *max_resp) 64 { 65 struct xfs_trans_res *resp; 66 struct xfs_trans_res *end_resp; 67 int log_space = 0; 68 int attr_space; 69 70 attr_space = xfs_log_calc_max_attrsetm_res(mp); 71 72 resp = (struct xfs_trans_res *)M_RES(mp); 73 end_resp = (struct xfs_trans_res *)(M_RES(mp) + 1); 74 for (; resp < end_resp; resp++) { 75 int tmp = resp->tr_logcount > 1 ? 76 resp->tr_logres * resp->tr_logcount : 77 resp->tr_logres; 78 if (log_space < tmp) { 79 log_space = tmp; 80 *max_resp = *resp; /* struct copy */ 81 } 82 } 83 84 if (attr_space > log_space) { 85 *max_resp = M_RES(mp)->tr_attrsetm; /* struct copy */ 86 max_resp->tr_logres = attr_space; 87 } 88 } 89 90 /* 91 * Calculate the minimum valid log size for the given superblock configuration. 92 * Used to calculate the minimum log size at mkfs time, and to determine if 93 * the log is large enough or not at mount time. Returns the minimum size in 94 * filesystem block size units. 95 */ 96 int 97 xfs_log_calc_minimum_size( 98 struct xfs_mount *mp) 99 { 100 struct xfs_trans_res tres = {0}; 101 int max_logres; 102 int min_logblks = 0; 103 int lsunit = 0; 104 105 xfs_log_get_max_trans_res(mp, &tres); 106 107 max_logres = xfs_log_calc_unit_res(mp, tres.tr_logres); 108 if (tres.tr_logcount > 1) 109 max_logres *= tres.tr_logcount; 110 111 if (xfs_sb_version_haslogv2(&mp->m_sb) && mp->m_sb.sb_logsunit > 1) 112 lsunit = BTOBB(mp->m_sb.sb_logsunit); 113 114 /* 115 * Two factors should be taken into account for calculating the minimum 116 * log space. 117 * 1) The fundamental limitation is that no single transaction can be 118 * larger than half size of the log. 119 * 120 * From mkfs.xfs, this is considered by the XFS_MIN_LOG_FACTOR 121 * define, which is set to 3. That means we can definitely fit 122 * maximally sized 2 transactions in the log. We'll use this same 123 * value here. 124 * 125 * 2) If the lsunit option is specified, a transaction requires 2 LSU 126 * for the reservation because there are two log writes that can 127 * require padding - the transaction data and the commit record which 128 * are written separately and both can require padding to the LSU. 129 * Consider that we can have an active CIL reservation holding 2*LSU, 130 * but the CIL is not over a push threshold, in this case, if we 131 * don't have enough log space for at one new transaction, which 132 * includes another 2*LSU in the reservation, we will run into dead 133 * loop situation in log space grant procedure. i.e. 134 * xlog_grant_head_wait(). 135 * 136 * Hence the log size needs to be able to contain two maximally sized 137 * and padded transactions, which is (2 * (2 * LSU + maxlres)). 138 * 139 * Also, the log size should be a multiple of the log stripe unit, round 140 * it up to lsunit boundary if lsunit is specified. 141 */ 142 if (lsunit) { 143 min_logblks = roundup_64(BTOBB(max_logres), lsunit) + 144 2 * lsunit; 145 } else 146 min_logblks = BTOBB(max_logres) + 2 * BBSIZE; 147 min_logblks *= XFS_MIN_LOG_FACTOR; 148 149 return XFS_BB_TO_FSB(mp, min_logblks); 150 } 151