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;
}
/*
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(
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