Defer AGFL frees during inode btree ([f]inobt) block allocations and frees that occur when removing inode chunks. The inode btrees do not use the AGFL and instead make allocator calls directly from the context of the tree update. This can chew up log reservation in the transaction if multiple AGFL block frees are required. Update the inobt cursor initialization function to receive an optional dfops pointer and carry it to ->[alloc|free]_block() context. From there, pass the dfops along to the allocator appropriately. Update xfs_difree_inobt() to pass dfops from the context where an inode chunk is freed and associated record removed from the inobt. All other inobt cursor users pass a NULL dfops and thus do not change behavior. Signed-off-by: Brian Foster <bfoster@xxxxxxxxxx> --- fs/xfs/libxfs/xfs_ialloc.c | 16 ++++++++-------- fs/xfs/libxfs/xfs_ialloc_btree.c | 11 +++++++---- fs/xfs/libxfs/xfs_ialloc_btree.h | 4 ++-- fs/xfs/scrub/common.c | 8 ++++---- fs/xfs/xfs_itable.c | 4 ++-- 5 files changed, 23 insertions(+), 20 deletions(-) diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index de3f04a98656..4345ba9b691a 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -183,7 +183,7 @@ xfs_inobt_insert( int i; int error; - cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, btnum); + cur = xfs_inobt_init_cursor(mp, tp, NULL, agbp, agno, btnum); for (thisino = newino; thisino < newino + newlen; @@ -532,7 +532,7 @@ xfs_inobt_insert_sprec( int i; struct xfs_inobt_rec_incore rec; - cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, btnum); + cur = xfs_inobt_init_cursor(mp, tp, NULL, agbp, agno, btnum); /* the new record is pre-aligned so we know where to look */ error = xfs_inobt_lookup(cur, nrec->ir_startino, XFS_LOOKUP_EQ, &i); @@ -1141,7 +1141,7 @@ xfs_dialloc_ag_inobt( ASSERT(pag->pagi_freecount > 0); restart_pagno: - cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_INO); + cur = xfs_inobt_init_cursor(mp, tp, NULL, agbp, agno, XFS_BTNUM_INO); /* * If pagino is 0 (this is the root inode allocation) use newino. * This must work because we've just allocated some. @@ -1570,7 +1570,7 @@ xfs_dialloc_ag( if (!pagino) pagino = be32_to_cpu(agi->agi_newino); - cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_FINO); + cur = xfs_inobt_init_cursor(mp, tp, NULL, agbp, agno, XFS_BTNUM_FINO); error = xfs_check_agi_freecount(cur, agi); if (error) @@ -1613,7 +1613,7 @@ xfs_dialloc_ag( * the original freecount. If all is well, make the equivalent update to * the inobt using the finobt record and offset information. */ - icur = xfs_inobt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_INO); + icur = xfs_inobt_init_cursor(mp, tp, NULL, agbp, agno, XFS_BTNUM_INO); error = xfs_check_agi_freecount(icur, agi); if (error) @@ -1921,7 +1921,7 @@ xfs_difree_inobt( /* * Initialize the cursor. */ - cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_INO); + cur = xfs_inobt_init_cursor(mp, tp, dfops, agbp, agno, XFS_BTNUM_INO); error = xfs_check_agi_freecount(cur, agi); if (error) @@ -2042,7 +2042,7 @@ xfs_difree_finobt( int error; int i; - cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_FINO); + cur = xfs_inobt_init_cursor(mp, tp, NULL, agbp, agno, XFS_BTNUM_FINO); error = xfs_inobt_lookup(cur, ibtrec->ir_startino, XFS_LOOKUP_EQ, &i); if (error) @@ -2235,7 +2235,7 @@ xfs_imap_lookup( * we have a record, we need to ensure it contains the inode number * we are looking up. */ - cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_INO); + cur = xfs_inobt_init_cursor(mp, tp, NULL, agbp, agno, XFS_BTNUM_INO); error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &i); if (!error) { if (i) diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c index b899f02e5c5e..4c996521b031 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.c +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c @@ -48,8 +48,8 @@ xfs_inobt_dup_cursor( struct xfs_btree_cur *cur) { return xfs_inobt_init_cursor(cur->bc_mp, cur->bc_tp, - cur->bc_private.a.agbp, cur->bc_private.a.agno, - cur->bc_btnum); + cur->bc_private.a.dfops, cur->bc_private.a.agbp, + cur->bc_private.a.agno, cur->bc_btnum); } STATIC void @@ -105,6 +105,7 @@ __xfs_inobt_alloc_block( args.prod = 1; args.type = XFS_ALLOCTYPE_NEAR_BNO; args.resv = resv; + args.dfops = cur->bc_private.a.dfops; error = xfs_alloc_vextent(&args); if (error) { @@ -155,7 +156,7 @@ xfs_inobt_free_block( xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_INOBT); return xfs_free_extent(cur->bc_tp, XFS_DADDR_TO_FSB(cur->bc_mp, XFS_BUF_ADDR(bp)), 1, - &oinfo, XFS_AG_RESV_NONE, NULL); + &oinfo, XFS_AG_RESV_NONE, cur->bc_private.a.dfops); } STATIC int @@ -393,6 +394,7 @@ struct xfs_btree_cur * /* new inode btree cursor */ xfs_inobt_init_cursor( struct xfs_mount *mp, /* file system mount point */ struct xfs_trans *tp, /* transaction pointer */ + struct xfs_defer_ops *dfops, /* deferred ops */ struct xfs_buf *agbp, /* buffer for agi structure */ xfs_agnumber_t agno, /* allocation group number */ xfs_btnum_t btnum) /* ialloc or free ino btree */ @@ -420,6 +422,7 @@ xfs_inobt_init_cursor( if (xfs_sb_version_hascrc(&mp->m_sb)) cur->bc_flags |= XFS_BTREE_CRC_BLOCKS; + cur->bc_private.a.dfops = dfops; cur->bc_private.a.agbp = agbp; cur->bc_private.a.agno = agno; @@ -552,7 +555,7 @@ xfs_inobt_count_blocks( if (error) return error; - cur = xfs_inobt_init_cursor(mp, NULL, agbp, agno, btnum); + cur = xfs_inobt_init_cursor(mp, NULL, NULL, agbp, agno, btnum); error = xfs_btree_count_blocks(cur, tree_blocks); xfs_btree_del_cursor(cur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); xfs_buf_relse(agbp); diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.h b/fs/xfs/libxfs/xfs_ialloc_btree.h index aa81e2e63f3f..0194351c09c8 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.h +++ b/fs/xfs/libxfs/xfs_ialloc_btree.h @@ -58,8 +58,8 @@ struct xfs_mount; ((index) - 1) * sizeof(xfs_inobt_ptr_t))) extern struct xfs_btree_cur *xfs_inobt_init_cursor(struct xfs_mount *, - struct xfs_trans *, struct xfs_buf *, xfs_agnumber_t, - xfs_btnum_t); + struct xfs_trans *, struct xfs_defer_ops *, struct xfs_buf *, + xfs_agnumber_t, xfs_btnum_t); extern int xfs_inobt_maxrecs(struct xfs_mount *, int, int); /* ir_holemask to inode allocation bitmap conversion */ diff --git a/fs/xfs/scrub/common.c b/fs/xfs/scrub/common.c index ac95fe911d96..44f96c835836 100644 --- a/fs/xfs/scrub/common.c +++ b/fs/xfs/scrub/common.c @@ -358,16 +358,16 @@ xfs_scrub_ag_btcur_init( /* Set up a inobt cursor for cross-referencing. */ if (sa->agi_bp) { - sa->ino_cur = xfs_inobt_init_cursor(mp, sc->tp, sa->agi_bp, - agno, XFS_BTNUM_INO); + sa->ino_cur = xfs_inobt_init_cursor(mp, sc->tp, NULL, + sa->agi_bp, agno, XFS_BTNUM_INO); if (!sa->ino_cur) goto err; } /* Set up a finobt cursor for cross-referencing. */ if (sa->agi_bp && xfs_sb_version_hasfinobt(&mp->m_sb)) { - sa->fino_cur = xfs_inobt_init_cursor(mp, sc->tp, sa->agi_bp, - agno, XFS_BTNUM_FINO); + sa->fino_cur = xfs_inobt_init_cursor(mp, sc->tp, NULL, + sa->agi_bp, agno, XFS_BTNUM_FINO); if (!sa->fino_cur) goto err; } diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index d58310514423..39b16eb84e51 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c @@ -398,7 +398,7 @@ xfs_bulkstat( /* * Allocate and initialize a btree cursor for ialloc btree. */ - cur = xfs_inobt_init_cursor(mp, NULL, agbp, agno, + cur = xfs_inobt_init_cursor(mp, NULL, NULL, agbp, agno, XFS_BTNUM_INO); if (agino > 0) { /* @@ -582,7 +582,7 @@ xfs_inumbers( if (error) break; - cur = xfs_inobt_init_cursor(mp, NULL, agbp, agno, + cur = xfs_inobt_init_cursor(mp, NULL, NULL, agbp, agno, XFS_BTNUM_INO); error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_GE, &stat); -- 2.13.6 -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html