Commit e0b5b97d authored by Darrick J. Wong's avatar Darrick J. Wong
Browse files

xfs: move the min and max group block numbers to xfs_group



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: default avatarDarrick J. Wong <djwong@kernel.org>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
parent ceaa0bd7
Loading
Loading
Loading
Loading
+12 −10
Original line number Diff line number Diff line
@@ -205,9 +205,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;
@@ -241,9 +242,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);
@@ -852,8 +854,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);
@@ -924,8 +926,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;
}
+2 −14
Original line number Diff line number Diff line
@@ -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);
}

/*
+33 −0
Original line number Diff line number Diff line
@@ -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 */
+1 −1
Original line number Diff line number Diff line
@@ -717,7 +717,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)
+30 −1
Original line number Diff line number Diff line
@@ -34,6 +34,32 @@
#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,
@@ -48,6 +74,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;
@@ -149,6 +177,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;
}
@@ -223,7 +252,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;
}
Loading