Unverified Commit 743a8749 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!3397 xfs: fix some growfs problems

Merge Pull Request from: @ci-robot 
 
PR sync from: Long Li <leo.lilong@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/6SIYYUAGOQU4KIKHESNH2EHNDI5HSZQP/ 
This patch set fix some growfs problems:

Long Li (1):
  xfs: fix dir3 block read verify fail during log recover

Wu Guanghao (1):
  xfs: fix the problem of mount failure caused by not refreshing
    mp->m_sb

yangerkun (2):
  xfs: fix mounting failed caused by sequencing problem in the log
    records
  xfs: keep growfs sb log item active until ail flush success


-- 
2.31.1
 
https://gitee.com/openeuler/kernel/issues/I8LHTR 
 
Link:https://gitee.com/openeuler/kernel/pulls/3397

 

Reviewed-by: default avatarzhangyi (F) <yi.zhang@huawei.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parents 4eb5a1ca 2688cc6e
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ enum xlog_recover_reorder {
	XLOG_REORDER_ITEM_LIST,
	XLOG_REORDER_INODE_BUFFER_LIST,
	XLOG_REORDER_CANCEL_LIST,
	XLOG_REORDER_SB_BUFFER_LIST,
};

struct xlog_recover_item_ops {
+1 −1
Original line number Diff line number Diff line
@@ -796,7 +796,7 @@ xfs_buf_item_committed(

	trace_xfs_buf_item_committed(bip);

	if ((bip->bli_flags & XFS_BLI_INODE_ALLOC_BUF) && lip->li_lsn != 0)
	if ((bip->bli_flags & XFS_BLI_KEEP_LSN) && lip->li_lsn != 0)
		return lip->li_lsn;
	return lsn;
}
+7 −1
Original line number Diff line number Diff line
@@ -20,6 +20,11 @@ struct xfs_mount;
#define XFS_BLI_STALE_INODE	(1u << 5)
#define	XFS_BLI_INODE_BUF	(1u << 6)
#define	XFS_BLI_ORDERED		(1u << 7)
#define	XFS_BLI_GROW_SB_BUF	(1u << 8)

#define XFS_BLI_KEEP_LSN	\
	(XFS_BLI_INODE_ALLOC_BUF | \
	 XFS_BLI_GROW_SB_BUF)

#define XFS_BLI_FLAGS \
	{ XFS_BLI_HOLD,		"HOLD" }, \
@@ -29,7 +34,8 @@ struct xfs_mount;
	{ XFS_BLI_INODE_ALLOC_BUF, "INODE_ALLOC" }, \
	{ XFS_BLI_STALE_INODE,	"STALE_INODE" }, \
	{ XFS_BLI_INODE_BUF,	"INODE_BUF" }, \
	{ XFS_BLI_ORDERED,	"ORDERED" }
	{ XFS_BLI_ORDERED,	"ORDERED" }, \
	{ XFS_BLI_GROW_SB_BUF,  "GROW_SB" }

/*
 * This is the in core log item structure used to track information
+30 −6
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@
#include "xfs_inode.h"
#include "xfs_dir2.h"
#include "xfs_quota.h"
#include "xfs_sb.h"
#include "xfs_ag.h"

/*
 * This is the number of entries in the l_buf_cancel_table used during
@@ -160,6 +162,8 @@ xlog_recover_buf_reorder(
		return XLOG_REORDER_CANCEL_LIST;
	if (buf_f->blf_flags & XFS_BLF_INODE_BUF)
		return XLOG_REORDER_INODE_BUFFER_LIST;
	if (buf_f->blf_blkno == XFS_SB_DADDR)
		return XLOG_REORDER_SB_BUFFER_LIST;
	return XLOG_REORDER_BUFFER_LIST;
}

@@ -946,13 +950,10 @@ xlog_recover_buf_commit_pass2(

		/*
		 * We're skipping replay of this buffer log item due to the log
		 * item LSN being behind the ondisk buffer.  Verify the buffer
		 * contents since we aren't going to run the write verifier.
		 * item LSN being behind the ondisk buffer.  clear XBF_DONE flag
		 * of the buffer to prevent buffer from being used without verify.
		 */
		if (bp->b_ops) {
			bp->b_ops->verify_read(bp);
			error = bp->b_error;
		}
		bp->b_flags &= ~XBF_DONE;
		goto out_release;
	}

@@ -969,6 +970,29 @@ xlog_recover_buf_commit_pass2(
			goto out_release;
	} else {
		xlog_recover_do_reg_buffer(mp, item, bp, buf_f, current_lsn);
		/*
		 * If the superblock buffer is modified, we also need to modify the
		 * content of the mp.
		 */
		if (bp->b_maps[0].bm_bn == XFS_SB_DADDR && bp->b_ops) {
			struct xfs_dsb *sb = bp->b_addr;

			bp->b_ops->verify_write(bp);
			error = bp->b_error;
			if (error)
				goto out_release;

			if (be32_to_cpu(sb->sb_agcount) > mp->m_sb.sb_agcount) {
				error = xfs_initialize_perag(mp,
						be32_to_cpu(sb->sb_agcount),
						be64_to_cpu(sb->sb_dblocks),
						&mp->m_maxagi);
				if (error)
					goto out_release;
			}

			xfs_sb_from_disk(&mp->m_sb, sb);
		}
	}

	/*
+23 −3
Original line number Diff line number Diff line
@@ -1900,6 +1900,9 @@ xlog_recover_reorder_trans(
		case XLOG_REORDER_BUFFER_LIST:
			list_move_tail(&item->ri_list, &buffer_list);
			break;
		case XLOG_REORDER_SB_BUFFER_LIST:
			list_move(&item->ri_list, &buffer_list);
			break;
		case XLOG_REORDER_CANCEL_LIST:
			trace_xfs_log_recover_item_reorder_head(log,
					trans, item, pass);
@@ -1963,6 +1966,25 @@ xlog_recover_items_pass2(
	return error;
}

#define XLOG_RECOVER_COMMIT_QUEUE_MAX 100
static inline bool
xlog_recover_should_pass2(
	struct xlog_recover_item	*item,
	int				items_queued)
{
	struct xfs_buf_log_format	*buf_f;

	if (items_queued >= XLOG_RECOVER_COMMIT_QUEUE_MAX)
		return true;
	if (ITEM_TYPE(item) == XFS_LI_BUF) {
		buf_f = item->ri_buf[0].i_addr;
		if (buf_f->blf_blkno == XFS_SB_DADDR)
			return true;
	}

	return false;
}

/*
 * Perform the transaction.
 *
@@ -1983,8 +2005,6 @@ xlog_recover_commit_trans(
	LIST_HEAD			(ra_list);
	LIST_HEAD			(done_list);

	#define XLOG_RECOVER_COMMIT_QUEUE_MAX 100

	hlist_del_init(&trans->r_list);

	error = xlog_recover_reorder_trans(log, trans, pass);
@@ -2004,7 +2024,7 @@ xlog_recover_commit_trans(
				item->ri_ops->ra_pass2(log, item);
			list_move_tail(&item->ri_list, &ra_list);
			items_queued++;
			if (items_queued >= XLOG_RECOVER_COMMIT_QUEUE_MAX) {
			if (xlog_recover_should_pass2(item, items_queued)) {
				error = xlog_recover_items_pass2(log, trans,
						buffer_list, &ra_list);
				list_splice_tail_init(&ra_list, &done_list);
Loading