diff options
author | Brian Foster <bfoster@redhat.com> | 2018-05-08 03:38:48 +0300 |
---|---|---|
committer | Darrick J. Wong <darrick.wong@oracle.com> | 2018-05-09 20:04:02 +0300 |
commit | 658f8f95117349194af1631ef87970c212c68487 (patch) | |
tree | 41f98f4eb18de5580d78f64cbbf5db8b8b5be863 /fs/xfs/xfs_inode.c | |
parent | 2bc5eba8b6957824631205aeffc75db8dbb5426a (diff) | |
download | linux-658f8f95117349194af1631ef87970c212c68487.tar.xz |
xfs: defer agfl frees from inode inactivation
XFS inode chunks are already freed via deferred operations (which
now also defer AGFL block frees), but inode btree blocks are freed
directly in the associated context. This has been known to lead to
log reservation overruns in particular workloads where an inobt
block free may require several AGFL block frees (and thus several
allocation btree modifications) before the inobt block itself is
actually freed.
To avoid this problem, defer the frees of any AGFL blocks before the
inobt block free takes place. This requires passing the dfops from
xfs_inactive_ifree() down through the inobt ->[alloc|free]_block()
callouts, which essentially only requires to attach the dfops to the
transaction since it is already carried all the way through to the
inobt update and allocation.
Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r-- | fs/xfs/xfs_inode.c | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 3cdd4fa37947..9959b6287bea 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1823,6 +1823,7 @@ xfs_inactive_ifree( xfs_trans_ijoin(tp, ip, 0); xfs_defer_init(&dfops, &first_block); + tp->t_agfl_dfops = &dfops; error = xfs_ifree(tp, ip, &dfops); if (error) { /* |