summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2026-06-09 10:52:45 +0300
committerCarlos Maiolino <cem@kernel.org>2026-06-10 13:21:52 +0300
commitdfac6ba84819bd12535943c4090766bbc6c5ea7e (patch)
treede489ea8f08c8b8cf6510cb869f9ba3a15f3b6a9
parent4cb6e89a3d901d4da515977e55f9a9a779238660 (diff)
downloadlinux-dfac6ba84819bd12535943c4090766bbc6c5ea7e.tar.xz
xfs: cleanup xfs_growfs_compute_deltas
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>
-rw-r--r--fs/xfs/libxfs/xfs_ag.c44
-rw-r--r--fs/xfs/libxfs/xfs_ag.h5
-rw-r--r--fs/xfs/xfs_fsops.c4
3 files changed, 26 insertions, 27 deletions
diff --git a/fs/xfs/libxfs/xfs_ag.c b/fs/xfs/libxfs/xfs_ag.c
index 0c5f0548021f..6cab66781d66 100644
--- a/fs/xfs/libxfs/xfs_ag.c
+++ b/fs/xfs/libxfs/xfs_ag.c
@@ -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;
}
/*
diff --git a/fs/xfs/libxfs/xfs_ag.h b/fs/xfs/libxfs/xfs_ag.h
index 8aa4266c5571..fd22fe598931 100644
--- a/fs/xfs/libxfs/xfs_ag.h
+++ b/fs/xfs/libxfs/xfs_ag.h
@@ -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(
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index 436857356a0a..67624a804a7f 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -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