]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
xfs: refactor buffer cancellation table allocation
authorDarrick J. Wong <djwong@kernel.org>
Thu, 16 Nov 2023 02:28:17 +0000 (18:28 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 28 Nov 2023 16:56:25 +0000 (16:56 +0000)
[ Upstream commit 2723234923b3294dbcf6019c288c87465e927ed4 ]

Move the code that allocates and frees the buffer cancellation tables
used by log recovery into the file that actually uses the tables.  This
is a precursor to some cleanups and a memory leak fix.

( backport: dependency of 8db074bd84df5ccc88bff3f8f900f66f4b8349fa )

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Leah Rumancik <leah.rumancik@gmail.com>
Acked-by: Chandan Babu R <chandanbabu@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/xfs/libxfs/xfs_log_recover.h
fs/xfs/xfs_buf_item_recover.c
fs/xfs/xfs_log_priv.h
fs/xfs/xfs_log_recover.c

index ff69a00008176e640708bd08b9cab27e098630c2..b8b65a6e9b1ec4a38f81884fdad02b7d9be21fdd 100644 (file)
@@ -108,12 +108,6 @@ struct xlog_recover {
 
 #define ITEM_TYPE(i)   (*(unsigned short *)(i)->ri_buf[0].i_addr)
 
-/*
- * This is the number of entries in the l_buf_cancel_table used during
- * recovery.
- */
-#define        XLOG_BC_TABLE_SIZE      64
-
 #define        XLOG_RECOVER_CRCPASS    0
 #define        XLOG_RECOVER_PASS1      1
 #define        XLOG_RECOVER_PASS2      2
@@ -126,5 +120,13 @@ int xlog_recover_iget(struct xfs_mount *mp, xfs_ino_t ino,
                struct xfs_inode **ipp);
 void xlog_recover_release_intent(struct xlog *log, unsigned short intent_type,
                uint64_t intent_id);
+void xlog_alloc_buf_cancel_table(struct xlog *log);
+void xlog_free_buf_cancel_table(struct xlog *log);
+
+#ifdef DEBUG
+void xlog_check_buf_cancel_table(struct xlog *log);
+#else
+#define xlog_check_buf_cancel_table(log) do { } while (0)
+#endif
 
 #endif /* __XFS_LOG_RECOVER_H__ */
index e04e44ef14c6df058ea4600b0dab6296d888648f..dc099b2f4984c18343fe848c50d9dbd1e06d2b27 100644 (file)
 #include "xfs_dir2.h"
 #include "xfs_quota.h"
 
+/*
+ * This is the number of entries in the l_buf_cancel_table used during
+ * recovery.
+ */
+#define        XLOG_BC_TABLE_SIZE      64
+
+#define XLOG_BUF_CANCEL_BUCKET(log, blkno) \
+       ((log)->l_buf_cancel_table + ((uint64_t)blkno % XLOG_BC_TABLE_SIZE))
+
 /*
  * This structure is used during recovery to record the buf log items which
  * have been canceled and should not be replayed.
@@ -1003,3 +1012,41 @@ const struct xlog_recover_item_ops xlog_buf_item_ops = {
        .commit_pass1           = xlog_recover_buf_commit_pass1,
        .commit_pass2           = xlog_recover_buf_commit_pass2,
 };
+
+#ifdef DEBUG
+void
+xlog_check_buf_cancel_table(
+       struct xlog     *log)
+{
+       int             i;
+
+       for (i = 0; i < XLOG_BC_TABLE_SIZE; i++)
+               ASSERT(list_empty(&log->l_buf_cancel_table[i]));
+}
+#endif
+
+void
+xlog_alloc_buf_cancel_table(
+       struct xlog     *log)
+{
+       int             i;
+
+       ASSERT(log->l_buf_cancel_table == NULL);
+
+       log->l_buf_cancel_table = kmem_zalloc(XLOG_BC_TABLE_SIZE *
+                                                sizeof(struct list_head),
+                                                0);
+       for (i = 0; i < XLOG_BC_TABLE_SIZE; i++)
+               INIT_LIST_HEAD(&log->l_buf_cancel_table[i]);
+}
+
+void
+xlog_free_buf_cancel_table(
+       struct xlog     *log)
+{
+       if (!log->l_buf_cancel_table)
+               return;
+
+       kmem_free(log->l_buf_cancel_table);
+       log->l_buf_cancel_table = NULL;
+}
index f3d68ca39f45c91de529a121aa636af607f5bcf3..03393595676f4ce931ce4aa5c4110c80d69265d5 100644 (file)
@@ -454,9 +454,6 @@ struct xlog {
        struct rw_semaphore     l_incompat_users;
 };
 
-#define XLOG_BUF_CANCEL_BUCKET(log, blkno) \
-       ((log)->l_buf_cancel_table + ((uint64_t)blkno % XLOG_BC_TABLE_SIZE))
-
 /*
  * Bits for operational state
  */
index 581aeb288b32b60908a14060409cc46f062df194..18d8eebc2d4455ddda494da250c6fe5e35b5e670 100644 (file)
@@ -3248,7 +3248,7 @@ xlog_do_log_recovery(
        xfs_daddr_t     head_blk,
        xfs_daddr_t     tail_blk)
 {
-       int             error, i;
+       int             error;
 
        ASSERT(head_blk != tail_blk);
 
@@ -3256,37 +3256,23 @@ xlog_do_log_recovery(
         * First do a pass to find all of the cancelled buf log items.
         * Store them in the buf_cancel_table for use in the second pass.
         */
-       log->l_buf_cancel_table = kmem_zalloc(XLOG_BC_TABLE_SIZE *
-                                                sizeof(struct list_head),
-                                                0);
-       for (i = 0; i < XLOG_BC_TABLE_SIZE; i++)
-               INIT_LIST_HEAD(&log->l_buf_cancel_table[i]);
+       xlog_alloc_buf_cancel_table(log);
 
        error = xlog_do_recovery_pass(log, head_blk, tail_blk,
                                      XLOG_RECOVER_PASS1, NULL);
-       if (error != 0) {
-               kmem_free(log->l_buf_cancel_table);
-               log->l_buf_cancel_table = NULL;
-               return error;
-       }
+       if (error != 0)
+               goto out_cancel;
+
        /*
         * Then do a second pass to actually recover the items in the log.
         * When it is complete free the table of buf cancel items.
         */
        error = xlog_do_recovery_pass(log, head_blk, tail_blk,
                                      XLOG_RECOVER_PASS2, NULL);
-#ifdef DEBUG
-       if (!error) {
-               int     i;
-
-               for (i = 0; i < XLOG_BC_TABLE_SIZE; i++)
-                       ASSERT(list_empty(&log->l_buf_cancel_table[i]));
-       }
-#endif /* DEBUG */
-
-       kmem_free(log->l_buf_cancel_table);
-       log->l_buf_cancel_table = NULL;
-
+       if (!error)
+               xlog_check_buf_cancel_table(log);
+out_cancel:
+       xlog_free_buf_cancel_table(log);
        return error;
 }