]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: move the min and max group block numbers to xfs_group
authorDarrick J. Wong <djwong@kernel.org>
Mon, 25 Nov 2024 21:14:26 +0000 (13:14 -0800)
committerDarrick J. Wong <djwong@kernel.org>
Tue, 24 Dec 2024 02:01:31 +0000 (18:01 -0800)
Source kernel commit: e0b5b97dde8e4737d06cb5888abd88373abc22df

Move the min and max agblock numbers to the generic xfs_group structure
so that we can start building validators for extents within an rtgroup.
While we're at it, use check_add_overflow for the extent length
computation because that has much better overflow checking.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
libxfs/init.c
libxfs/xfs_ag.c
libxfs/xfs_ag.h
libxfs/xfs_group.h
libxfs/xfs_ialloc_btree.c
libxfs/xfs_rtgroup.c
libxfs/xfs_rtgroup.h

index a037012b77e5f6211bf92448dd4003ebf135b527..6642cd50c00b5fdf7f9957ba90724f281cc18faa 100644 (file)
@@ -668,7 +668,6 @@ libxfs_mount(
 {
        struct xfs_buf          *bp;
        struct xfs_sb           *sbp;
-       struct xfs_rtgroup      *rtg = NULL;
        xfs_daddr_t             d;
        int                     i;
        int                     error;
@@ -831,9 +830,6 @@ libxfs_mount(
                exit(1);
        }
 
-       while ((rtg = xfs_rtgroup_next(mp, rtg)))
-               rtg->rtg_extents = xfs_rtgroup_extents(mp, rtg_rgno(rtg));
-
        xfs_set_rtgroup_data_loaded(mp);
 
        return mp;
index 181e929132d855acaa6c5c1203a6f3dfc54a4133..095b581a116180d209fc045044d9bf0618a5296a 100644 (file)
@@ -203,9 +203,10 @@ xfs_update_last_ag_size(
 
        if (!pag)
                return -EFSCORRUPTED;
-       pag->block_count = __xfs_ag_block_count(mp, prev_agcount - 1,
-                       mp->m_sb.sb_agcount, mp->m_sb.sb_dblocks);
-       __xfs_agino_range(mp, pag->block_count, &pag->agino_min,
+       pag_group(pag)->xg_block_count = __xfs_ag_block_count(mp,
+                       prev_agcount - 1, mp->m_sb.sb_agcount,
+                       mp->m_sb.sb_dblocks);
+       __xfs_agino_range(mp, pag_group(pag)->xg_block_count, &pag->agino_min,
                        &pag->agino_max);
        xfs_perag_rele(pag);
        return 0;
@@ -239,9 +240,10 @@ xfs_perag_alloc(
        /*
         * Pre-calculated geometry
         */
-       pag->block_count = __xfs_ag_block_count(mp, index, agcount, dblocks);
-       pag->min_block = XFS_AGFL_BLOCK(mp) + 1;
-       __xfs_agino_range(mp, pag->block_count, &pag->agino_min,
+       pag_group(pag)->xg_block_count = __xfs_ag_block_count(mp, index, agcount,
+                               dblocks);
+       pag_group(pag)->xg_min_gbno = XFS_AGFL_BLOCK(mp) + 1;
+       __xfs_agino_range(mp, pag_group(pag)->xg_block_count, &pag->agino_min,
                        &pag->agino_max);
 
        error = xfs_group_insert(mp, pag_group(pag), index, XG_TYPE_AG);
@@ -850,8 +852,8 @@ xfs_ag_shrink_space(
        }
 
        /* Update perag geometry */
-       pag->block_count -= delta;
-       __xfs_agino_range(mp, pag->block_count, &pag->agino_min,
+       pag_group(pag)->xg_block_count -= delta;
+       __xfs_agino_range(mp, pag_group(pag)->xg_block_count, &pag->agino_min,
                        &pag->agino_max);
 
        xfs_ialloc_log_agi(*tpp, agibp, XFS_AGI_LENGTH);
@@ -922,8 +924,8 @@ xfs_ag_extend_space(
                return error;
 
        /* Update perag geometry */
-       pag->block_count = be32_to_cpu(agf->agf_length);
-       __xfs_agino_range(mp, pag->block_count, &pag->agino_min,
+       pag_group(pag)->xg_block_count = be32_to_cpu(agf->agf_length);
+       __xfs_agino_range(mp, pag_group(pag)->xg_block_count, &pag->agino_min,
                        &pag->agino_max);
        return 0;
 }
index 9c22a76d58cfc2f730340734facf045cce0e85ed..1f24cfa273217245ae0ff08f053c90586d6489a4 100644 (file)
@@ -61,8 +61,6 @@ struct xfs_perag {
        struct xfs_ag_resv      pag_rmapbt_resv;
 
        /* Precalculated geometry info */
-       xfs_agblock_t           block_count;
-       xfs_agblock_t           min_block;
        xfs_agino_t             agino_min;
        xfs_agino_t             agino_max;
 
@@ -220,11 +218,7 @@ void xfs_agino_range(struct xfs_mount *mp, xfs_agnumber_t agno,
 static inline bool
 xfs_verify_agbno(struct xfs_perag *pag, xfs_agblock_t agbno)
 {
-       if (agbno >= pag->block_count)
-               return false;
-       if (agbno < pag->min_block)
-               return false;
-       return true;
+       return xfs_verify_gbno(pag_group(pag), agbno);
 }
 
 static inline bool
@@ -233,13 +227,7 @@ xfs_verify_agbext(
        xfs_agblock_t           agbno,
        xfs_agblock_t           len)
 {
-       if (agbno + len <= agbno)
-               return false;
-
-       if (!xfs_verify_agbno(pag, agbno))
-               return false;
-
-       return xfs_verify_agbno(pag, agbno + len - 1);
+       return xfs_verify_gbext(pag_group(pag), agbno, len);
 }
 
 /*
index 5b7362277c3f7ab6b3cc1e65cc7022031bca31fc..242b05627c7a6ea862c8dc0b30fc4a93281d0682 100644 (file)
@@ -12,6 +12,10 @@ struct xfs_group {
        atomic_t                xg_ref;         /* passive reference count */
        atomic_t                xg_active_ref;  /* active reference count */
 
+       /* Precalculated geometry info */
+       uint32_t                xg_block_count; /* max usable gbno */
+       uint32_t                xg_min_gbno;    /* min usable gbno */
+
 #ifdef __KERNEL__
        /* -- kernel only structures below this line -- */
 
@@ -128,4 +132,33 @@ xfs_fsb_to_gbno(
        return fsbno & mp->m_groups[type].blkmask;
 }
 
+static inline bool
+xfs_verify_gbno(
+       struct xfs_group        *xg,
+       uint32_t                gbno)
+{
+       if (gbno >= xg->xg_block_count)
+               return false;
+       if (gbno < xg->xg_min_gbno)
+               return false;
+       return true;
+}
+
+static inline bool
+xfs_verify_gbext(
+       struct xfs_group        *xg,
+       uint32_t                gbno,
+       uint32_t                glen)
+{
+       uint32_t                end;
+
+       if (!xfs_verify_gbno(xg, gbno))
+               return false;
+       if (glen == 0 || check_add_overflow(gbno, glen - 1, &end))
+               return false;
+       if (!xfs_verify_gbno(xg, end))
+               return false;
+       return true;
+}
+
 #endif /* __LIBXFS_GROUP_H */
index 4eeea240b0bd8977ba028d1433288de20426c162..19fca9fad62b1d0ce265dd9a140be6b2c52ea83d 100644 (file)
@@ -716,7 +716,7 @@ xfs_inobt_max_size(
        struct xfs_perag        *pag)
 {
        struct xfs_mount        *mp = pag_mount(pag);
-       xfs_agblock_t           agblocks = pag->block_count;
+       xfs_agblock_t           agblocks = pag_group(pag)->xg_block_count;
 
        /* Bail out if we're uninitialized, which can happen in mkfs. */
        if (M_IGEO(mp)->inobt_mxr[0] == 0)
index 50cfb038f03b79415a6829c4a1530536916e2b69..8189b83d0f184a01092757982efa8b8124990d6c 100644 (file)
 #include "xfs_metafile.h"
 #include "xfs_metadir.h"
 
+/* Find the first usable fsblock in this rtgroup. */
+static inline uint32_t
+xfs_rtgroup_min_block(
+       struct xfs_mount        *mp,
+       xfs_rgnumber_t          rgno)
+{
+       if (xfs_has_rtsb(mp) && rgno == 0)
+               return mp->m_sb.sb_rextsize;
+
+       return 0;
+}
+
+/* Precompute this group's geometry */
+void
+xfs_rtgroup_calc_geometry(
+       struct xfs_mount        *mp,
+       struct xfs_rtgroup      *rtg,
+       xfs_rgnumber_t          rgno,
+       xfs_rgnumber_t          rgcount,
+       xfs_rtbxlen_t           rextents)
+{
+       rtg->rtg_extents = __xfs_rtgroup_extents(mp, rgno, rgcount, rextents);
+       rtg_group(rtg)->xg_block_count = rtg->rtg_extents * mp->m_sb.sb_rextsize;
+       rtg_group(rtg)->xg_min_gbno = xfs_rtgroup_min_block(mp, rgno);
+}
+
 int
 xfs_rtgroup_alloc(
        struct xfs_mount        *mp,
@@ -45,6 +71,8 @@ xfs_rtgroup_alloc(
        if (!rtg)
                return -ENOMEM;
 
+       xfs_rtgroup_calc_geometry(mp, rtg, rgno, rgcount, rextents);
+
        error = xfs_group_insert(mp, rtg_group(rtg), rgno, XG_TYPE_RTG);
        if (error)
                goto out_free_rtg;
@@ -146,6 +174,7 @@ xfs_update_last_rtgroup_size(
                return -EFSCORRUPTED;
        rtg->rtg_extents = __xfs_rtgroup_extents(mp, prev_rgcount - 1,
                        mp->m_sb.sb_rgcount, mp->m_sb.sb_rextents);
+       rtg_group(rtg)->xg_block_count = rtg->rtg_extents * mp->m_sb.sb_rextsize;
        xfs_rtgroup_rele(rtg);
        return 0;
 }
@@ -220,7 +249,7 @@ xfs_rtgroup_get_geometry(
        /* Fill out form. */
        memset(rgeo, 0, sizeof(*rgeo));
        rgeo->rg_number = rtg_rgno(rtg);
-       rgeo->rg_length = rtg->rtg_extents * rtg_mount(rtg)->m_sb.sb_rextsize;
+       rgeo->rg_length = rtg_group(rtg)->xg_block_count;
        xfs_rtgroup_geom_health(rtg, rgeo);
        return 0;
 }
index c15b232e1f8e772462e5ae1aa863260e7889de92..1e51dc62d1143ec82b0107382c95a49cdd903dfc 100644 (file)
@@ -199,6 +199,9 @@ int xfs_initialize_rtgroups(struct xfs_mount *mp, xfs_rgnumber_t first_rgno,
 xfs_rtxnum_t __xfs_rtgroup_extents(struct xfs_mount *mp, xfs_rgnumber_t rgno,
                xfs_rgnumber_t rgcount, xfs_rtbxlen_t rextents);
 xfs_rtxnum_t xfs_rtgroup_extents(struct xfs_mount *mp, xfs_rgnumber_t rgno);
+void xfs_rtgroup_calc_geometry(struct xfs_mount *mp, struct xfs_rtgroup *rtg,
+               xfs_rgnumber_t rgno, xfs_rgnumber_t rgcount,
+               xfs_rtbxlen_t rextents);
 
 int xfs_update_last_rtgroup_size(struct xfs_mount *mp,
                xfs_rgnumber_t prev_rgcount);