Skip to content

Commit

Permalink
xfs: add missing defer ijoins for held inodes
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Darrick J. Wong <[email protected]>
Reviewed-by: Christoph Hellwig <[email protected]>
Signed-off-by: Darrick J. Wong <[email protected]>
  • Loading branch information
Brian Foster authored and djwong committed Aug 3, 2018
1 parent 1214f1c commit 488c919
Show file tree
Hide file tree
Showing 5 changed files with 7 additions and 0 deletions.
1 change: 1 addition & 0 deletions fs/xfs/libxfs/xfs_bmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions fs/xfs/xfs_bmap_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions fs/xfs/xfs_inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
3 changes: 3 additions & 0 deletions fs/xfs/xfs_iomap.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions fs/xfs/xfs_reflink.c
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,7 @@ xfs_reflink_allocate_cow(
xfs_inode_set_cowblocks_tag(ip);

/* Finish up. */
xfs_defer_ijoin(tp->t_dfops, ip);
error = xfs_trans_commit(tp);
if (error)
return error;
Expand Down

0 comments on commit 488c919

Please sign in to comment.