summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2019-05-20 14:25:39 -0400
committerDarrick J. Wong <darrick.wong@oracle.com>2019-05-20 14:25:39 -0400
commit5cd213b0fec640a46adc5e6e4dfc7763aa54b3b2 (patch)
tree9cf65e1f526111727adfc3fdfd5ce16f278587a5 /fs
parenta188339ca5a396acc588e5851ed7e19f66b0ebd9 (diff)
xfs: don't reserve per-AG space for an internal log
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 <darrick.wong@oracle.com> Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/libxfs/xfs_ialloc_btree.c9
-rw-r--r--fs/xfs/libxfs/xfs_refcount_btree.c9
-rw-r--r--fs/xfs/libxfs/xfs_rmap_btree.c9
3 files changed, 27 insertions, 0 deletions
diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c
index 1080381ff243..bc2dfacd2f4a 100644
--- a/fs/xfs/libxfs/xfs_ialloc_btree.c
+++ b/fs/xfs/libxfs/xfs_ialloc_btree.c
@@ -549,6 +549,15 @@ xfs_inobt_max_size(
549 if (mp->m_inobt_mxr[0] == 0) 549 if (mp->m_inobt_mxr[0] == 0)
550 return 0; 550 return 0;
551 551
552 /*
553 * The log is permanently allocated, so the space it occupies will
554 * never be available for the kinds of things that would require btree
555 * expansion. We therefore can pretend the space isn't there.
556 */
557 if (mp->m_sb.sb_logstart &&
558 XFS_FSB_TO_AGNO(mp, mp->m_sb.sb_logstart) == agno)
559 agblocks -= mp->m_sb.sb_logblocks;
560
552 return xfs_btree_calc_size(mp->m_inobt_mnr, 561 return xfs_btree_calc_size(mp->m_inobt_mnr,
553 (uint64_t)agblocks * mp->m_sb.sb_inopblock / 562 (uint64_t)agblocks * mp->m_sb.sb_inopblock /
554 XFS_INODES_PER_CHUNK); 563 XFS_INODES_PER_CHUNK);
diff --git a/fs/xfs/libxfs/xfs_refcount_btree.c b/fs/xfs/libxfs/xfs_refcount_btree.c
index 6f47ab876d90..5d9de9b21726 100644
--- a/fs/xfs/libxfs/xfs_refcount_btree.c
+++ b/fs/xfs/libxfs/xfs_refcount_btree.c
@@ -427,6 +427,15 @@ xfs_refcountbt_calc_reserves(
427 tree_len = be32_to_cpu(agf->agf_refcount_blocks); 427 tree_len = be32_to_cpu(agf->agf_refcount_blocks);
428 xfs_trans_brelse(tp, agbp); 428 xfs_trans_brelse(tp, agbp);
429 429
430 /*
431 * The log is permanently allocated, so the space it occupies will
432 * never be available for the kinds of things that would require btree
433 * expansion. We therefore can pretend the space isn't there.
434 */
435 if (mp->m_sb.sb_logstart &&
436 XFS_FSB_TO_AGNO(mp, mp->m_sb.sb_logstart) == agno)
437 agblocks -= mp->m_sb.sb_logblocks;
438
430 *ask += xfs_refcountbt_max_size(mp, agblocks); 439 *ask += xfs_refcountbt_max_size(mp, agblocks);
431 *used += tree_len; 440 *used += tree_len;
432 441
diff --git a/fs/xfs/libxfs/xfs_rmap_btree.c b/fs/xfs/libxfs/xfs_rmap_btree.c
index 5738e11055e6..5d1f8884c888 100644
--- a/fs/xfs/libxfs/xfs_rmap_btree.c
+++ b/fs/xfs/libxfs/xfs_rmap_btree.c
@@ -578,6 +578,15 @@ xfs_rmapbt_calc_reserves(
578 tree_len = be32_to_cpu(agf->agf_rmap_blocks); 578 tree_len = be32_to_cpu(agf->agf_rmap_blocks);
579 xfs_trans_brelse(tp, agbp); 579 xfs_trans_brelse(tp, agbp);
580 580
581 /*
582 * The log is permanently allocated, so the space it occupies will
583 * never be available for the kinds of things that would require btree
584 * expansion. We therefore can pretend the space isn't there.
585 */
586 if (mp->m_sb.sb_logstart &&
587 XFS_FSB_TO_AGNO(mp, mp->m_sb.sb_logstart) == agno)
588 agblocks -= mp->m_sb.sb_logblocks;
589
581 /* Reserve 1% of the AG or enough for 1 block per record. */ 590 /* Reserve 1% of the AG or enough for 1 block per record. */
582 *ask += max(agblocks / 100, xfs_rmapbt_max_size(mp, agblocks)); 591 *ask += max(agblocks / 100, xfs_rmapbt_max_size(mp, agblocks));
583 *used += tree_len; 592 *used += tree_len;