Commit ad99191a authored by Darrick J. Wong's avatar Darrick J. Wong Committed by Jialin Zhang
Browse files

xfs: refactor buffer cancellation table allocation

mainline inclusion
from mainline-v5.19-rc1
commit 27232349
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I4KIAO
CVE: NA

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=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.

Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
Signed-off-by: default avatarDave Chinner <david@fromorbit.com>

Conflicts:
	fs/xfs/libxfs/xfs_log_recover.h
	fs/xfs/xfs_log_priv.h

Signed-off-by: default avataryangerkun <yangerkun@huawei.com>
Reviewed-by: default avatarZhang Yi <yi.zhang@huawei.com>
Signed-off-by: default avatarJialin Zhang <zhangjialin11@huawei.com>
parent f34a931a
Loading
Loading
Loading
Loading
+8 −6
Original line number Diff line number Diff line
@@ -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
@@ -124,5 +118,13 @@ bool xlog_is_buffer_cancelled(struct xlog *log, xfs_daddr_t blkno, uint len);

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__ */
+47 −0
Original line number Diff line number Diff line
@@ -23,6 +23,15 @@
#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.
@@ -993,3 +1002,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;
}
+0 −3
Original line number Diff line number Diff line
@@ -444,9 +444,6 @@ struct xlog {
	uint32_t		l_iclog_roundoff;/* padding roundoff */
};

#define XLOG_BUF_CANCEL_BUCKET(log, blkno) \
	((log)->l_buf_cancel_table + ((uint64_t)blkno % XLOG_BC_TABLE_SIZE))

/*
 * Bits for operational state
 */
+9 −23
Original line number Diff line number Diff line
@@ -3229,7 +3229,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);

@@ -3237,37 +3237,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;
}