Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

xfs: use the actual AG length when reserving blocks



We need to use the actual AG length when making per-AG reservations,
since we could otherwise end up reserving more blocks out of the last
AG than there are actual blocks.

Complained-about-by: default avatarBrian Foster <bfoster@redhat.com>
Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
parent 7a21272b
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -256,6 +256,9 @@ xfs_ag_resv_init(
			goto out;
	}

	ASSERT(xfs_perag_resv(pag, XFS_AG_RESV_METADATA)->ar_reserved +
	       xfs_perag_resv(pag, XFS_AG_RESV_AGFL)->ar_reserved <=
	       pag->pagf_freeblks + pag->pagf_flcount);
out:
	return error;
}
+6 −3
Original line number Diff line number Diff line
@@ -409,13 +409,14 @@ xfs_refcountbt_calc_size(
 */
xfs_extlen_t
xfs_refcountbt_max_size(
	struct xfs_mount	*mp)
	struct xfs_mount	*mp,
	xfs_agblock_t		agblocks)
{
	/* Bail out if we're uninitialized, which can happen in mkfs. */
	if (mp->m_refc_mxr[0] == 0)
		return 0;

	return xfs_refcountbt_calc_size(mp, mp->m_sb.sb_agblocks);
	return xfs_refcountbt_calc_size(mp, agblocks);
}

/*
@@ -430,22 +431,24 @@ xfs_refcountbt_calc_reserves(
{
	struct xfs_buf		*agbp;
	struct xfs_agf		*agf;
	xfs_agblock_t		agblocks;
	xfs_extlen_t		tree_len;
	int			error;

	if (!xfs_sb_version_hasreflink(&mp->m_sb))
		return 0;

	*ask += xfs_refcountbt_max_size(mp);

	error = xfs_alloc_read_agf(mp, NULL, agno, 0, &agbp);
	if (error)
		return error;

	agf = XFS_BUF_TO_AGF(agbp);
	agblocks = be32_to_cpu(agf->agf_length);
	tree_len = be32_to_cpu(agf->agf_refcount_blocks);
	xfs_buf_relse(agbp);

	*ask += xfs_refcountbt_max_size(mp, agblocks);
	*used += tree_len;

	return error;
+2 −1
Original line number Diff line number Diff line
@@ -66,7 +66,8 @@ extern void xfs_refcountbt_compute_maxlevels(struct xfs_mount *mp);

extern xfs_extlen_t xfs_refcountbt_calc_size(struct xfs_mount *mp,
		unsigned long long len);
extern xfs_extlen_t xfs_refcountbt_max_size(struct xfs_mount *mp);
extern xfs_extlen_t xfs_refcountbt_max_size(struct xfs_mount *mp,
		xfs_agblock_t agblocks);

extern int xfs_refcountbt_calc_reserves(struct xfs_mount *mp,
		xfs_agnumber_t agno, xfs_extlen_t *ask, xfs_extlen_t *used);
+7 −7
Original line number Diff line number Diff line
@@ -550,13 +550,14 @@ xfs_rmapbt_calc_size(
 */
xfs_extlen_t
xfs_rmapbt_max_size(
	struct xfs_mount	*mp)
	struct xfs_mount	*mp,
	xfs_agblock_t		agblocks)
{
	/* Bail out if we're uninitialized, which can happen in mkfs. */
	if (mp->m_rmap_mxr[0] == 0)
		return 0;

	return xfs_rmapbt_calc_size(mp, mp->m_sb.sb_agblocks);
	return xfs_rmapbt_calc_size(mp, agblocks);
}

/*
@@ -571,25 +572,24 @@ xfs_rmapbt_calc_reserves(
{
	struct xfs_buf		*agbp;
	struct xfs_agf		*agf;
	xfs_extlen_t		pool_len;
	xfs_agblock_t		agblocks;
	xfs_extlen_t		tree_len;
	int			error;

	if (!xfs_sb_version_hasrmapbt(&mp->m_sb))
		return 0;

	/* Reserve 1% of the AG or enough for 1 block per record. */
	pool_len = max(mp->m_sb.sb_agblocks / 100, xfs_rmapbt_max_size(mp));
	*ask += pool_len;

	error = xfs_alloc_read_agf(mp, NULL, agno, 0, &agbp);
	if (error)
		return error;

	agf = XFS_BUF_TO_AGF(agbp);
	agblocks = be32_to_cpu(agf->agf_length);
	tree_len = be32_to_cpu(agf->agf_rmap_blocks);
	xfs_buf_relse(agbp);

	/* Reserve 1% of the AG or enough for 1 block per record. */
	*ask += max(agblocks / 100, xfs_rmapbt_max_size(mp, agblocks));
	*used += tree_len;

	return error;
+2 −1
Original line number Diff line number Diff line
@@ -60,7 +60,8 @@ extern void xfs_rmapbt_compute_maxlevels(struct xfs_mount *mp);

extern xfs_extlen_t xfs_rmapbt_calc_size(struct xfs_mount *mp,
		unsigned long long len);
extern xfs_extlen_t xfs_rmapbt_max_size(struct xfs_mount *mp);
extern xfs_extlen_t xfs_rmapbt_max_size(struct xfs_mount *mp,
		xfs_agblock_t agblocks);

extern int xfs_rmapbt_calc_reserves(struct xfs_mount *mp,
		xfs_agnumber_t agno, xfs_extlen_t *ask, xfs_extlen_t *used);
Loading