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_log_format.h" 11 #include "xfs_shared.h" 12 #include "xfs_trans_resv.h" 13 #include "xfs_bit.h" 14 #include "xfs_sb.h" 15 #include "xfs_mount.h" 16 #include "xfs_defer.h" 17 #include "xfs_inode.h" 18 #include "xfs_btree.h" 19 #include "xfs_rmap.h" 20 #include "xfs_alloc_btree.h" 21 #include "xfs_alloc.h" 22 #include "xfs_ialloc.h" 23 24 /* Find the size of the AG, in blocks. */ 25 xfs_agblock_t 26 xfs_ag_block_count( 27 struct xfs_mount *mp, 28 xfs_agnumber_t agno) 29 { 30 ASSERT(agno < mp->m_sb.sb_agcount); 31 32 if (agno < mp->m_sb.sb_agcount - 1) 33 return mp->m_sb.sb_agblocks; 34 return mp->m_sb.sb_dblocks - (agno * mp->m_sb.sb_agblocks); 35 } 36 37 /* 38 * Verify that an AG block number pointer neither points outside the AG 39 * nor points at static metadata. 40 */ 41 bool 42 xfs_verify_agbno( 43 struct xfs_mount *mp, 44 xfs_agnumber_t agno, 45 xfs_agblock_t agbno) 46 { 47 xfs_agblock_t eoag; 48 49 eoag = xfs_ag_block_count(mp, agno); 50 if (agbno >= eoag) 51 return false; 52 if (agbno <= XFS_AGFL_BLOCK(mp)) 53 return false; 54 return true; 55 } 56 57 /* 58 * Verify that an FS block number pointer neither points outside the 59 * filesystem nor points at static AG metadata. 60 */ 61 bool 62 xfs_verify_fsbno( 63 struct xfs_mount *mp, 64 xfs_fsblock_t fsbno) 65 { 66 xfs_agnumber_t agno = XFS_FSB_TO_AGNO(mp, fsbno); 67 68 if (agno >= mp->m_sb.sb_agcount) 69 return false; 70 return xfs_verify_agbno(mp, agno, XFS_FSB_TO_AGBNO(mp, fsbno)); 71 } 72 73 /* Calculate the first and last possible inode number in an AG. */ 74 void 75 xfs_agino_range( 76 struct xfs_mount *mp, 77 xfs_agnumber_t agno, 78 xfs_agino_t *first, 79 xfs_agino_t *last) 80 { 81 xfs_agblock_t bno; 82 xfs_agblock_t eoag; 83 84 eoag = xfs_ag_block_count(mp, agno); 85 86 /* 87 * Calculate the first inode, which will be in the first 88 * cluster-aligned block after the AGFL. 89 */ 90 bno = round_up(XFS_AGFL_BLOCK(mp) + 1, 91 xfs_ialloc_cluster_alignment(mp)); 92 *first = XFS_OFFBNO_TO_AGINO(mp, bno, 0); 93 94 /* 95 * Calculate the last inode, which will be at the end of the 96 * last (aligned) cluster that can be allocated in the AG. 97 */ 98 bno = round_down(eoag, xfs_ialloc_cluster_alignment(mp)); 99 *last = XFS_OFFBNO_TO_AGINO(mp, bno, 0) - 1; 100 } 101 102 /* 103 * Verify that an AG inode number pointer neither points outside the AG 104 * nor points at static metadata. 105 */ 106 bool 107 xfs_verify_agino( 108 struct xfs_mount *mp, 109 xfs_agnumber_t agno, 110 xfs_agino_t agino) 111 { 112 xfs_agino_t first; 113 xfs_agino_t last; 114 115 xfs_agino_range(mp, agno, &first, &last); 116 return agino >= first && agino <= last; 117 } 118 119 /* 120 * Verify that an FS inode number pointer neither points outside the 121 * filesystem nor points at static AG metadata. 122 */ 123 bool 124 xfs_verify_ino( 125 struct xfs_mount *mp, 126 xfs_ino_t ino) 127 { 128 xfs_agnumber_t agno = XFS_INO_TO_AGNO(mp, ino); 129 xfs_agino_t agino = XFS_INO_TO_AGINO(mp, ino); 130 131 if (agno >= mp->m_sb.sb_agcount) 132 return false; 133 if (XFS_AGINO_TO_INO(mp, agno, agino) != ino) 134 return false; 135 return xfs_verify_agino(mp, agno, agino); 136 } 137 138 /* Is this an internal inode number? */ 139 bool 140 xfs_internal_inum( 141 struct xfs_mount *mp, 142 xfs_ino_t ino) 143 { 144 return ino == mp->m_sb.sb_rbmino || ino == mp->m_sb.sb_rsumino || 145 (xfs_sb_version_hasquota(&mp->m_sb) && 146 xfs_is_quota_inode(&mp->m_sb, ino)); 147 } 148 149 /* 150 * Verify that a directory entry's inode number doesn't point at an internal 151 * inode, empty space, or static AG metadata. 152 */ 153 bool 154 xfs_verify_dir_ino( 155 struct xfs_mount *mp, 156 xfs_ino_t ino) 157 { 158 if (xfs_internal_inum(mp, ino)) 159 return false; 160 return xfs_verify_ino(mp, ino); 161 } 162 163 /* 164 * Verify that an realtime block number pointer doesn't point off the 165 * end of the realtime device. 166 */ 167 bool 168 xfs_verify_rtbno( 169 struct xfs_mount *mp, 170 xfs_rtblock_t rtbno) 171 { 172 return rtbno < mp->m_sb.sb_rblocks; 173 } 174