xfs: add missing defer ijoins for held inodes
Log items that require relogging during deferred operations processing are explicitly joined to the associated dfops via the xfs_defer_*join() helpers. These calls imply that the associated object is "held" by the transaction such that when rolled, the item can be immediately joined to a follow up transaction. For buffers, this means the buffer remains locked and held after each roll. For inodes, this means that the inode remains locked. Failure to join a held item to the dfops structure means the associated object pins the tail of the log while dfops processing completes, because the item never relogs and is not unlocked or released until deferred processing completes. Currently, all buffers that are held in transactions (XFS_BLI_HOLD) with deferred operations are explicitly joined to the dfops. This is not the case for inodes, however, as various contexts defer operations to transactions with held inodes without explicit joins to the associated dfops (and thus not relogging). While this is not a catastrophic problem, it is not ideal. Given that we want to eventually relog such items automatically during dfops processing, start by explicitly adding these missing xfs_defer_ijoin() calls. A call is added everywhere an inode is joined to a transaction without transferring lock ownership and said transaction runs deferred operations. All xfs_defer_ijoin() calls will eventually be replaced by automatic dfops inode relogging. This patch essentially implements the behavior change that would otherwise occur due to automatic inode dfops relogging. Signed-off-by: Brian Foster <bfoster@redhat.com> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
This commit is contained in:
Родитель
1214f1cf66
Коммит
488c919a5b
|
@ -1119,6 +1119,7 @@ xfs_bmap_add_attrfork(
|
|||
xfs_log_sb(tp);
|
||||
}
|
||||
|
||||
xfs_defer_ijoin(tp->t_dfops, ip);
|
||||
error = xfs_trans_commit(tp);
|
||||
xfs_iunlock(ip, XFS_ILOCK_EXCL);
|
||||
return error;
|
||||
|
|
|
@ -979,6 +979,7 @@ xfs_alloc_file_space(
|
|||
/*
|
||||
* Complete the transaction
|
||||
*/
|
||||
xfs_defer_ijoin(tp->t_dfops, ip);
|
||||
error = xfs_trans_commit(tp);
|
||||
xfs_iunlock(ip, XFS_ILOCK_EXCL);
|
||||
if (error)
|
||||
|
|
|
@ -1810,6 +1810,7 @@ xfs_inactive_ifree(
|
|||
* Just ignore errors at this point. There is nothing we can do except
|
||||
* to try to keep going. Make sure it's not a silent error.
|
||||
*/
|
||||
xfs_defer_ijoin(tp->t_dfops, ip);
|
||||
error = xfs_trans_commit(tp);
|
||||
if (error)
|
||||
xfs_notice(mp, "%s: xfs_trans_commit returned error %d",
|
||||
|
|
|
@ -261,6 +261,7 @@ xfs_iomap_write_direct(
|
|||
/*
|
||||
* Complete the transaction
|
||||
*/
|
||||
xfs_defer_ijoin(tp->t_dfops, ip);
|
||||
error = xfs_trans_commit(tp);
|
||||
if (error)
|
||||
goto out_unlock;
|
||||
|
@ -763,6 +764,7 @@ xfs_iomap_write_allocate(
|
|||
if (error)
|
||||
goto trans_cancel;
|
||||
|
||||
xfs_defer_ijoin(tp->t_dfops, ip);
|
||||
error = xfs_trans_commit(tp);
|
||||
if (error)
|
||||
goto error0;
|
||||
|
@ -882,6 +884,7 @@ xfs_iomap_write_unwritten(
|
|||
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
|
||||
}
|
||||
|
||||
xfs_defer_ijoin(tp->t_dfops, ip);
|
||||
error = xfs_trans_commit(tp);
|
||||
xfs_iunlock(ip, XFS_ILOCK_EXCL);
|
||||
if (error)
|
||||
|
|
|
@ -435,6 +435,7 @@ retry:
|
|||
xfs_inode_set_cowblocks_tag(ip);
|
||||
|
||||
/* Finish up. */
|
||||
xfs_defer_ijoin(tp->t_dfops, ip);
|
||||
error = xfs_trans_commit(tp);
|
||||
if (error)
|
||||
return error;
|
||||
|
|
Загрузка…
Ссылка в новой задаче