aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2019-02-13 14:46:16 -0500
committerDarrick J. Wong <darrick.wong@oracle.com>2019-02-15 01:42:57 -0500
commit15a268d9f263ed3a0601a1296568241a5a3da7aa (patch)
tree551546fb5270bde61302991d5e4db717dbb456f0
parente1f6ca11381588e3ef138c10de60eeb34cb8466a (diff)
xfs: reserve blocks for ifree transaction during log recovery
Log recovery frees all the inodes stored in the unlinked list, which can cause expansion of the free inode btree. The ifree code skips block reservations if it thinks there's a per-AG space reservation, but we don't set up the reservation until after log recovery, which means that a finobt expansion blows up in xfs_trans_mod_sb when we exceed the transaction's block reservation. To fix this, we set the "no finobt reservation" flag to true when we create the xfs_mount and only set it to false if we confirm that every AG had enough free space to put aside for the finobt. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Dave Chinner <dchinner@redhat.com>
-rw-r--r--fs/xfs/xfs_fsops.c1
-rw-r--r--fs/xfs/xfs_super.c7
2 files changed, 8 insertions, 0 deletions
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index f3ef70c542e1..584648582ba7 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -533,6 +533,7 @@ xfs_fs_reserve_ag_blocks(
533 int error = 0; 533 int error = 0;
534 int err2; 534 int err2;
535 535
536 mp->m_finobt_nores = false;
536 for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) { 537 for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
537 pag = xfs_perag_get(mp, agno); 538 pag = xfs_perag_get(mp, agno);
538 err2 = xfs_ag_resv_init(pag, NULL); 539 err2 = xfs_ag_resv_init(pag, NULL);
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index c9097cb0b955..08033ac040d6 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -1594,6 +1594,13 @@ xfs_mount_alloc(
1594 INIT_DELAYED_WORK(&mp->m_eofblocks_work, xfs_eofblocks_worker); 1594 INIT_DELAYED_WORK(&mp->m_eofblocks_work, xfs_eofblocks_worker);
1595 INIT_DELAYED_WORK(&mp->m_cowblocks_work, xfs_cowblocks_worker); 1595 INIT_DELAYED_WORK(&mp->m_cowblocks_work, xfs_cowblocks_worker);
1596 mp->m_kobj.kobject.kset = xfs_kset; 1596 mp->m_kobj.kobject.kset = xfs_kset;
1597 /*
1598 * We don't create the finobt per-ag space reservation until after log
1599 * recovery, so we must set this to true so that an ifree transaction
1600 * started during log recovery will not depend on space reservations
1601 * for finobt expansion.
1602 */
1603 mp->m_finobt_nores = true;
1597 return mp; 1604 return mp;
1598} 1605}
1599 1606