root/fs/xfs/libxfs/xfs_types.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. xfs_ag_block_count
  2. xfs_verify_agbno
  3. xfs_verify_fsbno
  4. xfs_agino_range
  5. xfs_verify_agino
  6. xfs_verify_agino_or_null
  7. xfs_verify_ino
  8. xfs_internal_inum
  9. xfs_verify_dir_ino
  10. xfs_verify_rtbno
  11. xfs_icount_range
  12. xfs_verify_icount
  13. xfs_verify_dablk

   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 }

/* [<][>][^][v][top][bottom][index][help] */