1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. 4 * Copyright (C) 2017 Oracle. 5 * All Rights Reserved. 6 */ 7 #include "xfs.h" 8 #include "xfs_fs.h" 9 #include "xfs_format.h" 10 #include "xfs_shared.h" 11 #include "xfs_trans_resv.h" 12 #include "xfs_bit.h" 13 #include "xfs_mount.h" 14 15 /* Find the size of the AG, in blocks. */ 16 xfs_agblock_t 17 xfs_ag_block_count( 18 struct xfs_mount *mp, 19 xfs_agnumber_t agno) 20 { 21 ASSERT(agno < mp->m_sb.sb_agcount); 22 23 if (agno < mp->m_sb.sb_agcount - 1) 24 return mp->m_sb.sb_agblocks; 25 return mp->m_sb.sb_dblocks - (agno * mp->m_sb.sb_agblocks); 26 } 27 28 /* 29 * Verify that an AG block number pointer neither points outside the AG 30 * nor points at static metadata. 31 */ 32 bool 33 xfs_verify_agbno( 34 struct xfs_mount *mp, 35 xfs_agnumber_t agno, 36 xfs_agblock_t agbno) 37 { 38 xfs_agblock_t eoag; 39 40 eoag = xfs_ag_block_count(mp, agno); 41 if (agbno >= eoag) 42 return false; 43 if (agbno <= XFS_AGFL_BLOCK(mp)) 44 return false; 45 return true; 46 } 47 48 /* 49 * Verify that an FS block number pointer neither points outside the 50 * filesystem nor points at static AG metadata. 51 */ 52 bool 53 xfs_verify_fsbno( 54 struct xfs_mount *mp, 55 xfs_fsblock_t fsbno) 56 { 57 xfs_agnumber_t agno = XFS_FSB_TO_AGNO(mp, fsbno); 58 59 if (agno >= mp->m_sb.sb_agcount) 60 return false; 61 return xfs_verify_agbno(mp, agno, XFS_FSB_TO_AGBNO(mp, fsbno)); 62 } 63 64 /* Calculate the first and last possible inode number in an AG. */ 65 void 66 xfs_agino_range( 67 struct xfs_mount *mp, 68 xfs_agnumber_t agno, 69 xfs_agino_t *first, 70 xfs_agino_t *last) 71 { 72 xfs_agblock_t bno; 73 xfs_agblock_t eoag; 74 75 eoag = xfs_ag_block_count(mp, agno); 76 77 /* 78 * Calculate the first inode, which will be in the first 79 * cluster-aligned block after the AGFL. 80 */ 81 bno = round_up(XFS_AGFL_BLOCK(mp) + 1, M_IGEO(mp)->cluster_align); 82 *first = XFS_AGB_TO_AGINO(mp, bno); 83 84 /* 85 * Calculate the last inode, which will be at the end of the 86 * last (aligned) cluster that can be allocated in the AG. 87 */ 88 bno = round_down(eoag, M_IGEO(mp)->cluster_align); 89 *last = XFS_AGB_TO_AGINO(mp, bno) - 1; 90 } 91 92 /* 93 * Verify that an AG inode number pointer neither points outside the AG 94 * nor points at static metadata. 95 */ 96 bool 97 xfs_verify_agino( 98 struct xfs_mount *mp, 99 xfs_agnumber_t agno, 100 xfs_agino_t agino) 101 { 102 xfs_agino_t first; 103 xfs_agino_t last; 104 105 xfs_agino_range(mp, agno, &first, &last); 106 return agino >= first && agino <= last; 107 } 108 109 /* 110 * Verify that an AG inode number pointer neither points outside the AG 111 * nor points at static metadata, or is NULLAGINO. 112 */ 113 bool 114 xfs_verify_agino_or_null( 115 struct xfs_mount *mp, 116 xfs_agnumber_t agno, 117 xfs_agino_t agino) 118 { 119 return agino == NULLAGINO || xfs_verify_agino(mp, agno, agino); 120 } 121 122 /* 123 * Verify that an FS inode number pointer neither points outside the 124 * filesystem nor points at static AG metadata. 125 */ 126 bool 127 xfs_verify_ino( 128 struct xfs_mount *mp, 129 xfs_ino_t ino) 130 { 131 xfs_agnumber_t agno = XFS_INO_TO_AGNO(mp, ino); 132 xfs_agino_t agino = XFS_INO_TO_AGINO(mp, ino); 133 134 if (agno >= mp->m_sb.sb_agcount) 135 return false; 136 if (XFS_AGINO_TO_INO(mp, agno, agino) != ino) 137 return false; 138 return xfs_verify_agino(mp, agno, agino); 139 } 140 141 /* Is this an internal inode number? */ 142 bool 143 xfs_internal_inum( 144 struct xfs_mount *mp, 145 xfs_ino_t ino) 146 { 147 return ino == mp->m_sb.sb_rbmino || ino == mp->m_sb.sb_rsumino || 148 (xfs_sb_version_hasquota(&mp->m_sb) && 149 xfs_is_quota_inode(&mp->m_sb, ino)); 150 } 151 152 /* 153 * Verify that a directory entry's inode number doesn't point at an internal 154 * inode, empty space, or static AG metadata. 155 */ 156 bool 157 xfs_verify_dir_ino( 158 struct xfs_mount *mp, 159 xfs_ino_t ino) 160 { 161 if (xfs_internal_inum(mp, ino)) 162 return false; 163 return xfs_verify_ino(mp, ino); 164 } 165 166 /* 167 * Verify that an realtime block number pointer doesn't point off the 168 * end of the realtime device. 169 */ 170 bool 171 xfs_verify_rtbno( 172 struct xfs_mount *mp, 173 xfs_rtblock_t rtbno) 174 { 175 return rtbno < mp->m_sb.sb_rblocks; 176 } 177 178 /* Calculate the range of valid icount values. */ 179 void 180 xfs_icount_range( 181 struct xfs_mount *mp, 182 unsigned long long *min, 183 unsigned long long *max) 184 { 185 unsigned long long nr_inos = 0; 186 xfs_agnumber_t agno; 187 188 /* root, rtbitmap, rtsum all live in the first chunk */ 189 *min = XFS_INODES_PER_CHUNK; 190 191 for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) { 192 xfs_agino_t first, last; 193 194 xfs_agino_range(mp, agno, &first, &last); 195 nr_inos += last - first + 1; 196 } 197 *max = nr_inos; 198 } 199 200 /* Sanity-checking of inode counts. */ 201 bool 202 xfs_verify_icount( 203 struct xfs_mount *mp, 204 unsigned long long icount) 205 { 206 unsigned long long min, max; 207 208 xfs_icount_range(mp, &min, &max); 209 return icount >= min && icount <= max; 210 } 211 212 /* Sanity-checking of dir/attr block offsets. */ 213 bool 214 xfs_verify_dablk( 215 struct xfs_mount *mp, 216 xfs_fileoff_t dabno) 217 { 218 xfs_dablk_t max_dablk = -1U; 219 220 return dabno <= max_dablk; 221 } 222