xfs: mark log recovery buffers for completion
authorDave Chinner <dchinner@redhat.com>
Mon, 29 Jun 2020 21:48:47 +0000 (14:48 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Mon, 6 Jul 2020 17:46:58 +0000 (10:46 -0700)
Log recovery has it's own buffer write completion handler for
buffers that it directly recovers. Convert these to direct calls by
flagging these buffers as being log recovery buffers. The flag will
get cleared by the log recovery IO completion routine, so it will
never leak out of log recovery.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-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>
fs/xfs/xfs_buf.c
fs/xfs/xfs_buf.h
fs/xfs/xfs_buf_item_recover.c
fs/xfs/xfs_dquot_item_recover.c
fs/xfs/xfs_inode_item_recover.c
fs/xfs/xfs_log_recover.c

index 5179326..6a2c942 100644 (file)
@@ -14,6 +14,7 @@
 #include "xfs_mount.h"
 #include "xfs_trace.h"
 #include "xfs_log.h"
+#include "xfs_log_recover.h"
 #include "xfs_trans.h"
 #include "xfs_buf_item.h"
 #include "xfs_errortag.h"
@@ -1207,6 +1208,15 @@ xfs_buf_ioend(
        if (read)
                goto out_finish;
 
+       /*
+        * If this is a log recovery buffer, we aren't doing transactional IO
+        * yet so we need to let it handle IO completions.
+        */
+       if (bp->b_flags & _XBF_LOGRECOVERY) {
+               xlog_recover_iodone(bp);
+               return;
+       }
+
        if (bp->b_flags & _XBF_INODES) {
                xfs_buf_inode_iodone(bp);
                return;
index c1d0843..30dabc5 100644 (file)
@@ -33,6 +33,7 @@
 /* buffer type flags for write callbacks */
 #define _XBF_INODES     (1 << 16)/* inode buffer */
 #define _XBF_DQUOTS     (1 << 17)/* dquot buffer */
+#define _XBF_LOGRECOVERY        (1 << 18)/* log recovery buffer */
 
 /* flags used only internally */
 #define _XBF_PAGES      (1 << 20)/* backed by refcounted pages */
@@ -56,6 +57,7 @@ typedef unsigned int xfs_buf_flags_t;
        { XBF_WRITE_FAIL,       "WRITE_FAIL" }, \
        { _XBF_INODES,          "INODES" }, \
        { _XBF_DQUOTS,          "DQUOTS" }, \
+       { _XBF_LOGRECOVERY,             "LOG_RECOVERY" }, \
        { _XBF_PAGES,           "PAGES" }, \
        { _XBF_KMEM,            "KMEM" }, \
        { _XBF_DELWRI_Q,        "DELWRI_Q" }, \
index 04faa73..74c851f 100644 (file)
@@ -419,8 +419,7 @@ xlog_recover_validate_buf_type(
        if (bp->b_ops) {
                struct xfs_buf_log_item *bip;
 
-               ASSERT(!bp->b_iodone || bp->b_iodone == xlog_recover_iodone);
-               bp->b_iodone = xlog_recover_iodone;
+               bp->b_flags |= _XBF_LOGRECOVERY;
                xfs_buf_item_init(bp, mp);
                bip = bp->b_log_item;
                bip->bli_item.li_lsn = current_lsn;
@@ -963,7 +962,7 @@ xlog_recover_buf_commit_pass2(
                error = xfs_bwrite(bp);
        } else {
                ASSERT(bp->b_mount == mp);
-               bp->b_iodone = xlog_recover_iodone;
+               bp->b_flags |= _XBF_LOGRECOVERY;
                xfs_buf_delwri_queue(bp, buffer_list);
        }
 
index 3400be4..f9ea9f5 100644 (file)
@@ -153,7 +153,7 @@ xlog_recover_dquot_commit_pass2(
 
        ASSERT(dq_f->qlf_size == 2);
        ASSERT(bp->b_mount == mp);
-       bp->b_iodone = xlog_recover_iodone;
+       bp->b_flags |= _XBF_LOGRECOVERY;
        xfs_buf_delwri_queue(bp, buffer_list);
 
 out_release:
index dc3e26f..5e0d291 100644 (file)
@@ -376,7 +376,7 @@ out_owner_change:
        xfs_dinode_calc_crc(log->l_mp, dip);
 
        ASSERT(bp->b_mount == mp);
-       bp->b_iodone = xlog_recover_iodone;
+       bp->b_flags |= _XBF_LOGRECOVERY;
        xfs_buf_delwri_queue(bp, buffer_list);
 
 out_release:
index ec015df..52a65a7 100644 (file)
@@ -287,9 +287,8 @@ xlog_recover_iodone(
        if (bp->b_log_item)
                xfs_buf_item_relse(bp);
        ASSERT(bp->b_log_item == NULL);
-
-       bp->b_iodone = NULL;
-       xfs_buf_ioend(bp);
+       bp->b_flags &= ~_XBF_LOGRECOVERY;
+       xfs_buf_ioend_finish(bp);
 }
 
 /*