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 #include "xfs_ag.h" 15 16 17 /* 18 * Verify that an AG block number pointer neither points outside the AG 19 * nor points at static metadata. 20 */ 21 static inline bool 22 xfs_verify_agno_agbno( 23 struct xfs_mount *mp, 24 xfs_agnumber_t agno, 25 xfs_agblock_t agbno) 26 { 27 xfs_agblock_t eoag; 28 29 eoag = xfs_ag_block_count(mp, agno); 30 if (agbno >= eoag) 31 return false; 32 if (agbno <= XFS_AGFL_BLOCK(mp)) 33 return false; 34 return true; 35 } 36 37 /* 38 * Verify that an FS block number pointer neither points outside the 39 * filesystem nor points at static AG metadata. 40 */ 41 inline bool 42 xfs_verify_fsbno( 43 struct xfs_mount *mp, 44 xfs_fsblock_t fsbno) 45 { 46 xfs_agnumber_t agno = XFS_FSB_TO_AGNO(mp, fsbno); 47 48 if (agno >= mp->m_sb.sb_agcount) 49 return false; 50 return xfs_verify_agno_agbno(mp, agno, XFS_FSB_TO_AGBNO(mp, fsbno)); 51 } 52 53 /* 54 * Verify that a data device extent is fully contained inside the filesystem, 55 * does not cross an AG boundary, and does not point at static metadata. 56 */ 57 bool 58 xfs_verify_fsbext( 59 struct xfs_mount *mp, 60 xfs_fsblock_t fsbno, 61 xfs_fsblock_t len) 62 { 63 if (fsbno + len <= fsbno) 64 return false; 65 66 if (!xfs_verify_fsbno(mp, fsbno)) 67 return false; 68 69 if (!xfs_verify_fsbno(mp, fsbno + len - 1)) 70 return false; 71 72 return XFS_FSB_TO_AGNO(mp, fsbno) == 73 XFS_FSB_TO_AGNO(mp, fsbno + len - 1); 74 } 75 76 /* 77 * Verify that an AG inode number pointer neither points outside the AG 78 * nor points at static metadata. 79 */ 80 static inline bool 81 xfs_verify_agno_agino( 82 struct xfs_mount *mp, 83 xfs_agnumber_t agno, 84 xfs_agino_t agino) 85 { 86 xfs_agino_t first; 87 xfs_agino_t last; 88 89 xfs_agino_range(mp, agno, &first, &last); 90 return agino >= first && agino <= last; 91 } 92 93 /* 94 * Verify that an FS inode number pointer neither points outside the 95 * filesystem nor points at static AG metadata. 96 */ 97 inline bool 98 xfs_verify_ino( 99 struct xfs_mount *mp, 100 xfs_ino_t ino) 101 { 102 xfs_agnumber_t agno = XFS_INO_TO_AGNO(mp, ino); 103 xfs_agino_t agino = XFS_INO_TO_AGINO(mp, ino); 104 105 if (agno >= mp->m_sb.sb_agcount) 106 return false; 107 if (XFS_AGINO_TO_INO(mp, agno, agino) != ino) 108 return false; 109 return xfs_verify_agno_agino(mp, agno, agino); 110 } 111 112 /* Is this an internal inode number? */ 113 inline bool 114 xfs_internal_inum( 115 struct xfs_mount *mp, 116 xfs_ino_t ino) 117 { 118 return ino == mp->m_sb.sb_rbmino || ino == mp->m_sb.sb_rsumino || 119 (xfs_has_quota(mp) && 120 xfs_is_quota_inode(&mp->m_sb, ino)); 121 } 122 123 /* 124 * Verify that a directory entry's inode number doesn't point at an internal 125 * inode, empty space, or static AG metadata. 126 */ 127 bool 128 xfs_verify_dir_ino( 129 struct xfs_mount *mp, 130 xfs_ino_t ino) 131 { 132 if (xfs_internal_inum(mp, ino)) 133 return false; 134 return xfs_verify_ino(mp, ino); 135 } 136 137 /* 138 * Verify that an realtime block number pointer doesn't point off the 139 * end of the realtime device. 140 */ 141 inline bool 142 xfs_verify_rtbno( 143 struct xfs_mount *mp, 144 xfs_rtblock_t rtbno) 145 { 146 return rtbno < mp->m_sb.sb_rblocks; 147 } 148 149 /* Verify that a realtime device extent is fully contained inside the volume. */ 150 bool 151 xfs_verify_rtext( 152 struct xfs_mount *mp, 153 xfs_rtblock_t rtbno, 154 xfs_rtblock_t len) 155 { 156 if (rtbno + len <= rtbno) 157 return false; 158 159 if (!xfs_verify_rtbno(mp, rtbno)) 160 return false; 161 162 return xfs_verify_rtbno(mp, rtbno + len - 1); 163 } 164 165 /* Calculate the range of valid icount values. */ 166 inline void 167 xfs_icount_range( 168 struct xfs_mount *mp, 169 unsigned long long *min, 170 unsigned long long *max) 171 { 172 unsigned long long nr_inos = 0; 173 struct xfs_perag *pag; 174 xfs_agnumber_t agno; 175 176 /* root, rtbitmap, rtsum all live in the first chunk */ 177 *min = XFS_INODES_PER_CHUNK; 178 179 for_each_perag(mp, agno, pag) 180 nr_inos += pag->agino_max - pag->agino_min + 1; 181 *max = nr_inos; 182 } 183 184 /* Sanity-checking of inode counts. */ 185 bool 186 xfs_verify_icount( 187 struct xfs_mount *mp, 188 unsigned long long icount) 189 { 190 unsigned long long min, max; 191 192 xfs_icount_range(mp, &min, &max); 193 return icount >= min && icount <= max; 194 } 195 196 /* Sanity-checking of dir/attr block offsets. */ 197 bool 198 xfs_verify_dablk( 199 struct xfs_mount *mp, 200 xfs_fileoff_t dabno) 201 { 202 xfs_dablk_t max_dablk = -1U; 203 204 return dabno <= max_dablk; 205 } 206 207 /* Check that a file block offset does not exceed the maximum. */ 208 bool 209 xfs_verify_fileoff( 210 struct xfs_mount *mp, 211 xfs_fileoff_t off) 212 { 213 return off <= XFS_MAX_FILEOFF; 214 } 215 216 /* Check that a range of file block offsets do not exceed the maximum. */ 217 bool 218 xfs_verify_fileext( 219 struct xfs_mount *mp, 220 xfs_fileoff_t off, 221 xfs_fileoff_t len) 222 { 223 if (off + len <= off) 224 return false; 225 226 if (!xfs_verify_fileoff(mp, off)) 227 return false; 228 229 return xfs_verify_fileoff(mp, off + len - 1); 230 } 231