]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: reset dfops to initial state after finish
authorBrian Foster <bfoster@redhat.com>
Fri, 5 Oct 2018 02:36:10 +0000 (21:36 -0500)
committerEric Sandeen <sandeen@redhat.com>
Fri, 5 Oct 2018 02:36:10 +0000 (21:36 -0500)
Source kernel commit: 509308b413c9e4e3140b4bc524522255d126787e

xfs_defer_init() is currently used in two particular situations. The
first and most obvious case is raw initialization of an
xfs_defer_ops struct. The other case is partial reinit of
xfs_defer_ops on reuse due to iteration.

Most instances of the first case will be replaced by a single init
of a dfops embedded in the transaction. Init calls are still
technically required for the second case because the dfops may have
low space mode enabled or have joined items that need to be reset
before the dfops should be reused.

Since the current dfops usage expects either a final transaction
be reused, we can shift some of the init logic into
xfs_defer_finish() such that the latter returns with a reinitialized
dfops. This eliminates the second dependency noted above such that a
dfops is immediately ready for reuse after an xfs_defer_finish()
without the need to change any calling code.

Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Bill O'Donnell <billodo@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
libxfs/xfs_defer.c

index ba73b89013ecf6f71195abc19c5d4b2f0aab6402..17ee0e0af11c368c37ac4acd29bf142793d18206 100644 (file)
@@ -319,6 +319,19 @@ xfs_defer_bjoin(
        return -EFSCORRUPTED;
 }
 
+/*
+ * Reset an already used dfops after finish.
+ */
+static void
+xfs_defer_reset(
+       struct xfs_defer_ops    *dop)
+{
+       ASSERT(!xfs_defer_has_unfinished_work(dop));
+       dop->dop_low = false;
+       memset(dop->dop_inodes, 0, sizeof(dop->dop_inodes));
+       memset(dop->dop_bufs, 0, sizeof(dop->dop_bufs));
+}
+
 /*
  * Finish all the pending work.  This involves logging intent items for
  * any work items that wandered in since the last transaction roll (if
@@ -427,10 +440,13 @@ xfs_defer_finish(
                dop = (*tp)->t_dfops;
        }
 out:
-       if (error)
+       if (error) {
                trace_xfs_defer_finish_error((*tp)->t_mountp, dop, error);
-       else
+       } else {
                trace_xfs_defer_finish_done((*tp)->t_mountp, dop, _RET_IP_);
+               xfs_defer_reset(dop);
+       }
+
        return error;
 }