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 /* 65 * Verify that a data device extent is fully contained inside the filesystem, 66 * does not cross an AG boundary, and does not point at static metadata. 67 */ 68 bool 69 xfs_verify_fsbext( 70 struct xfs_mount *mp, 71 xfs_fsblock_t fsbno, 72 xfs_fsblock_t len) 73 { 74 if (fsbno + len <= fsbno) 75 return false; 76 77 if (!xfs_verify_fsbno(mp, fsbno)) 78 return false; 79 80 if (!xfs_verify_fsbno(mp, fsbno + len - 1)) 81 return false; 82 83 return XFS_FSB_TO_AGNO(mp, fsbno) == 84 XFS_FSB_TO_AGNO(mp, fsbno + len - 1); 85 } 86 87 /* Calculate the first and last possible inode number in an AG. */ 88 void 89 xfs_agino_range( 90 struct xfs_mount *mp, 91 xfs_agnumber_t agno, 92 xfs_agino_t *first, 93 xfs_agino_t *last) 94 { 95 xfs_agblock_t bno; 96 xfs_agblock_t eoag; 97 98 eoag = xfs_ag_block_count(mp, agno); 99 100 /* 101 * Calculate the first inode, which will be in the first 102 * cluster-aligned block after the AGFL. 103 */ 104 bno = round_up(XFS_AGFL_BLOCK(mp) + 1, M_IGEO(mp)->cluster_align); 105 *first = XFS_AGB_TO_AGINO(mp, bno); 106 107 /* 108 * Calculate the last inode, which will be at the end of the 109 * last (aligned) cluster that can be allocated in the AG. 110 */ 111 bno = round_down(eoag, M_IGEO(mp)->cluster_align); 112 *last = XFS_AGB_TO_AGINO(mp, bno) - 1; 113 } 114 115 /* 116 * Verify that an AG inode number pointer neither points outside the AG 117 * nor points at static metadata. 118 */ 119 bool 120 xfs_verify_agino( 121 struct xfs_mount *mp, 122 xfs_agnumber_t agno, 123 xfs_agino_t agino) 124 { 125 xfs_agino_t first; 126 xfs_agino_t last; 127 128 xfs_agino_range(mp, agno, &first, &last); 129 return agino >= first && agino <= last; 130 } 131 132 /* 133 * Verify that an AG inode number pointer neither points outside the AG 134 * nor points at static metadata, or is NULLAGINO. 135 */ 136 bool 137 xfs_verify_agino_or_null( 138 struct xfs_mount *mp, 139 xfs_agnumber_t agno, 140 xfs_agino_t agino) 141 { 142 return agino == NULLAGINO || xfs_verify_agino(mp, agno, agino); 143 } 144 145 /* 146 * Verify that an FS inode number pointer neither points outside the 147 * filesystem nor points at static AG metadata. 148 */ 149 bool 150 xfs_verify_ino( 151 struct xfs_mount *mp, 152 xfs_ino_t ino) 153 { 154 xfs_agnumber_t agno = XFS_INO_TO_AGNO(mp, ino); 155 xfs_agino_t agino = XFS_INO_TO_AGINO(mp, ino); 156 157 if (agno >= mp->m_sb.sb_agcount) 158 return false; 159 if (XFS_AGINO_TO_INO(mp, agno, agino) != ino) 160 return false; 161 return xfs_verify_agino(mp, agno, agino); 162 } 163 164 /* Is this an internal inode number? */ 165 bool 166 xfs_internal_inum( 167 struct xfs_mount *mp, 168 xfs_ino_t ino) 169 { 170 return ino == mp->m_sb.sb_rbmino || ino == mp->m_sb.sb_rsumino || 171 (xfs_sb_version_hasquota(&mp->m_sb) && 172 xfs_is_quota_inode(&mp->m_sb, ino)); 173 } 174 175 /* 176 * Verify that a directory entry's inode number doesn't point at an internal 177 * inode, empty space, or static AG metadata. 178 */ 179 bool 180 xfs_verify_dir_ino( 181 struct xfs_mount *mp, 182 xfs_ino_t ino) 183 { 184 if (xfs_internal_inum(mp, ino)) 185 return false; 186 return xfs_verify_ino(mp, ino); 187 } 188 189 /* 190 * Verify that an realtime block number pointer doesn't point off the 191 * end of the realtime device. 192 */ 193 bool 194 xfs_verify_rtbno( 195 struct xfs_mount *mp, 196 xfs_rtblock_t rtbno) 197 { 198 return rtbno < mp->m_sb.sb_rblocks; 199 } 200 201 /* Verify that a realtime device extent is fully contained inside the volume. */ 202 bool 203 xfs_verify_rtext( 204 struct xfs_mount *mp, 205 xfs_rtblock_t rtbno, 206 xfs_rtblock_t len) 207 { 208 if (rtbno + len <= rtbno) 209 return false; 210 211 if (!xfs_verify_rtbno(mp, rtbno)) 212 return false; 213 214 return xfs_verify_rtbno(mp, rtbno + len - 1); 215 } 216 217 /* Calculate the range of valid icount values. */ 218 void 219 xfs_icount_range( 220 struct xfs_mount *mp, 221 unsigned long long *min, 222 unsigned long long *max) 223 { 224 unsigned long long nr_inos = 0; 225 xfs_agnumber_t agno; 226 227 /* root, rtbitmap, rtsum all live in the first chunk */ 228 *min = XFS_INODES_PER_CHUNK; 229 230 for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) { 231 xfs_agino_t first, last; 232 233 xfs_agino_range(mp, agno, &first, &last); 234 nr_inos += last - first + 1; 235 } 236 *max = nr_inos; 237 } 238 239 /* Sanity-checking of inode counts. */ 240 bool 241 xfs_verify_icount( 242 struct xfs_mount *mp, 243 unsigned long long icount) 244 { 245 unsigned long long min, max; 246 247 xfs_icount_range(mp, &min, &max); 248 return icount >= min && icount <= max; 249 } 250 251 /* Sanity-checking of dir/attr block offsets. */ 252 bool 253 xfs_verify_dablk( 254 struct xfs_mount *mp, 255 xfs_fileoff_t dabno) 256 { 257 xfs_dablk_t max_dablk = -1U; 258 259 return dabno <= max_dablk; 260 } 261 262 /* Check that a file block offset does not exceed the maximum. */ 263 bool 264 xfs_verify_fileoff( 265 struct xfs_mount *mp, 266 xfs_fileoff_t off) 267 { 268 return off <= XFS_MAX_FILEOFF; 269 } 270 271 /* Check that a range of file block offsets do not exceed the maximum. */ 272 bool 273 xfs_verify_fileext( 274 struct xfs_mount *mp, 275 xfs_fileoff_t off, 276 xfs_fileoff_t len) 277 { 278 if (off + len <= off) 279 return false; 280 281 if (!xfs_verify_fileoff(mp, off)) 282 return false; 283 284 return xfs_verify_fileoff(mp, off + len - 1); 285 } 286