From: Darrick J. Wong Date: Wed, 24 Jul 2019 19:54:07 +0000 (-0400) Subject: xfs: don't reserve per-AG space for an internal log X-Git-Tag: v5.2.0-rc0~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=247c49990174dccfb60d285c5265d154f2ce7d78;p=thirdparty%2Fxfsprogs-dev.git xfs: don't reserve per-AG space for an internal log Source kernel commit: 5cd213b0fec640a46adc5e6e4dfc7763aa54b3b2 It turns out that the log can consume nearly all the space in an AG, and when this happens this it's possible that there will be less free space in the AG than the reservation would try to hide. On a debug kernel this can trigger an ASSERT in xfs/250: XFS: Assertion failed: xfs_perag_resv(pag, XFS_AG_RESV_METADATA)->ar_reserved + xfs_perag_resv(pag, XFS_AG_RESV_RMAPBT)->ar_reserved <= pag->pagf_freeblks + pag->pagf_flcount, file: fs/xfs/libxfs/xfs_ag_resv.c, line: 319 The log is permanently allocated, so we know we're never going to have to expand the btrees to hold any records associated with the log space. We therefore can treat the space as if it doesn't exist. Signed-off-by: Darrick J. Wong Reviewed-by: Eric Sandeen Signed-off-by: Eric Sandeen --- diff --git a/libxfs/xfs_ialloc_btree.c b/libxfs/xfs_ialloc_btree.c index 599c79da5..ea1f068c8 100644 --- a/libxfs/xfs_ialloc_btree.c +++ b/libxfs/xfs_ialloc_btree.c @@ -548,6 +548,15 @@ xfs_inobt_max_size( if (mp->m_inobt_mxr[0] == 0) return 0; + /* + * The log is permanently allocated, so the space it occupies will + * never be available for the kinds of things that would require btree + * expansion. We therefore can pretend the space isn't there. + */ + if (mp->m_sb.sb_logstart && + XFS_FSB_TO_AGNO(mp, mp->m_sb.sb_logstart) == agno) + agblocks -= mp->m_sb.sb_logblocks; + return xfs_btree_calc_size(mp->m_inobt_mnr, (uint64_t)agblocks * mp->m_sb.sb_inopblock / XFS_INODES_PER_CHUNK); diff --git a/libxfs/xfs_refcount_btree.c b/libxfs/xfs_refcount_btree.c index 65018b12a..0d8d5c223 100644 --- a/libxfs/xfs_refcount_btree.c +++ b/libxfs/xfs_refcount_btree.c @@ -426,6 +426,15 @@ xfs_refcountbt_calc_reserves( tree_len = be32_to_cpu(agf->agf_refcount_blocks); xfs_trans_brelse(tp, agbp); + /* + * The log is permanently allocated, so the space it occupies will + * never be available for the kinds of things that would require btree + * expansion. We therefore can pretend the space isn't there. + */ + if (mp->m_sb.sb_logstart && + XFS_FSB_TO_AGNO(mp, mp->m_sb.sb_logstart) == agno) + agblocks -= mp->m_sb.sb_logblocks; + *ask += xfs_refcountbt_max_size(mp, agblocks); *used += tree_len; diff --git a/libxfs/xfs_rmap_btree.c b/libxfs/xfs_rmap_btree.c index 59abe4136..36860e711 100644 --- a/libxfs/xfs_rmap_btree.c +++ b/libxfs/xfs_rmap_btree.c @@ -576,6 +576,15 @@ xfs_rmapbt_calc_reserves( tree_len = be32_to_cpu(agf->agf_rmap_blocks); xfs_trans_brelse(tp, agbp); + /* + * The log is permanently allocated, so the space it occupies will + * never be available for the kinds of things that would require btree + * expansion. We therefore can pretend the space isn't there. + */ + if (mp->m_sb.sb_logstart && + XFS_FSB_TO_AGNO(mp, mp->m_sb.sb_logstart) == agno) + agblocks -= mp->m_sb.sb_logblocks; + /* 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;