]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
xfs: cleanup xfs_growfs_compute_deltas
authorChristoph Hellwig <hch@lst.de>
Tue, 9 Jun 2026 07:52:45 +0000 (09:52 +0200)
committerCarlos Maiolino <cem@kernel.org>
Wed, 10 Jun 2026 10:21:52 +0000 (12:21 +0200)
xfs_growfs_compute_deltas has an odd calling conventions, and looks
very convoluted due to the use of do_div and strangely named and typed
variables.

Rename it, make it return the agcount and let the caller calculate the
delta.  The internally use the better div_u64_rem helper and descriptive
variable names and types.  Also add a comment describing what the
function is used for.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
fs/xfs/libxfs/xfs_ag.c
fs/xfs/libxfs/xfs_ag.h
fs/xfs/xfs_fsops.c

index 0c5f0548021f49a6838600355037aa0d830150ab..6cab66781d6673ccedc340c9608669459a31f91e 100644 (file)
@@ -863,32 +863,30 @@ resv_err:
        return err2;
 }
 
-void
-xfs_growfs_compute_deltas(
+/*
+ * Return the agcount for the new file system size passed in *nb and adjust *nb
+ * when it has to be reduced because of maximum AG count or because it would
+ * create a below minimum size AG.
+ */
+xfs_agnumber_t
+xfs_growfs_compute_agcount(
        struct xfs_mount        *mp,
-       xfs_rfsblock_t          *nb,
-       int64_t                 *deltap,
-       xfs_agnumber_t          *nagcountp)
+       xfs_rfsblock_t          *nb)
 {
-       xfs_rfsblock_t  nb_div, nb_mod;
-       int64_t         delta;
-       xfs_agnumber_t  nagcount;
-
-       nb_div = *nb;
-       nb_mod = do_div(nb_div, mp->m_sb.sb_agblocks);
-       if (nb_mod && nb_mod >= XFS_MIN_AG_BLOCKS)
-               nb_div++;
-       else if (nb_mod)
-               *nb = nb_div * mp->m_sb.sb_agblocks;
-
-       if (nb_div > XFS_MAX_AGNUMBER + 1) {
-               nb_div = XFS_MAX_AGNUMBER + 1;
-               *nb = nb_div * mp->m_sb.sb_agblocks;
+       uint64_t                agcount; /* 64-bits wide to catch overflows */
+       xfs_extlen_t            remainder;
+
+       agcount = div_u64_rem(*nb, mp->m_sb.sb_agblocks, &remainder);
+       if (agcount >= XFS_MAX_AGNUMBER + 1) {
+               agcount = XFS_MAX_AGNUMBER + 1;
+               remainder = 0;
+       }
+       *nb = (xfs_rfsblock_t)agcount * mp->m_sb.sb_agblocks;
+       if (remainder >= XFS_MIN_AG_BLOCKS) {
+               *nb += remainder;
+               agcount++;
        }
-       nagcount = nb_div;
-       delta = *nb - mp->m_sb.sb_dblocks;
-       *deltap = delta;
-       *nagcountp = nagcount;
+       return agcount;
 }
 
 /*
index 8aa4266c55714d8aa2108a4a33c146184db183e4..fd22fe59893176abddd8eb70b65cc6dff4fe0b29 100644 (file)
@@ -329,12 +329,11 @@ struct aghdr_init_data {
 int xfs_ag_init_headers(struct xfs_mount *mp, struct aghdr_init_data *id);
 int xfs_ag_shrink_space(struct xfs_perag *pag, struct xfs_trans **tpp,
                        xfs_extlen_t delta);
-void
-xfs_growfs_compute_deltas(struct xfs_mount *mp, xfs_rfsblock_t *nb,
-                       int64_t *deltap, xfs_agnumber_t *nagcountp);
 int xfs_ag_extend_space(struct xfs_perag *pag, struct xfs_trans *tp,
                        xfs_extlen_t len);
 int xfs_ag_get_geometry(struct xfs_perag *pag, struct xfs_ag_geometry *ageo);
+xfs_agnumber_t xfs_growfs_compute_agcount(struct xfs_mount *mp,
+               xfs_rfsblock_t *nb);
 
 static inline xfs_fsblock_t
 xfs_agbno_to_fsb(
index 436857356a0a12fd3bb626b3ac1062f00066bb5b..67624a804a7fa888b747f6087df91f1c74457767 100644 (file)
@@ -124,7 +124,9 @@ xfs_growfs_data_private(
                        mp->m_sb.sb_rextsize);
        if (error)
                return error;
-       xfs_growfs_compute_deltas(mp, &nb, &delta, &nagcount);
+
+       nagcount = xfs_growfs_compute_agcount(mp, &nb);
+       delta = nb - mp->m_sb.sb_dblocks;
 
        /*
         * Reject filesystems with a single AG because they are not