Commit 27232349 authored by Darrick J. Wong's avatar Darrick J. Wong Committed by Dave Chinner
Browse files

xfs: refactor buffer cancellation table allocation



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>
parent ab6a8d3f
Loading
Loading
Loading
Loading
+8 −6
Original line number Diff line number Diff line
@@ -110,12 +110,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
@@ -128,5 +122,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__ */
+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
@@ -428,9 +428,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
 */
+9 −23
Original line number Diff line number Diff line
@@ -3223,7 +3223,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);

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