]> www.infradead.org Git - users/willy/linux.git/commitdiff
xfs: add missing defer ijoins for held inodes
authorBrian Foster <bfoster@redhat.com>
Wed, 1 Aug 2018 14:20:31 +0000 (07:20 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Fri, 3 Aug 2018 06:05:13 +0000 (23:05 -0700)
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>
fs/xfs/libxfs/xfs_bmap.c
fs/xfs/xfs_bmap_util.c
fs/xfs/xfs_inode.c
fs/xfs/xfs_iomap.c
fs/xfs/xfs_reflink.c

index 8edf7522aaff5fa6a7b7b3c95c751cd34f57fe05..71687d805f79d8d4b15fe365bde0392ad2649c2f 100644 (file)
@@ -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;
index 412dc58ae54dc129e558e8a7b7b031ee726152ff..0c58a66b39e5929cdbf41e797b83f30bb91b1b49 100644 (file)
@@ -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)
index 5fc1815c2b626e140f6957dc425fb3c0ddba44f3..441c8593cfd74cd65494bc7d8199deb4ad3882c3 100644 (file)
@@ -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",
index 3282575e2df49340c662c2e6c267a1ff2e3b70f9..8093a01fcf9e846bcedafa050c7185f7d342016a 100644 (file)
@@ -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)
index 9a0a565262667e41a848f39c9f6d9cb9c13440b1..e986fcf928e5011647068cd96fdd8bc33b07182e 100644 (file)
@@ -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;