提交 fcf905e9 编写于 作者: D Dave Chinner 提交者: Zheng Zengkai

xfs: factor out log write ordering from xlog_cil_push_work()

mainline-inclusion
from mainline-v5.14-rc4
commit bf034bc8
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I4V7IK
CVE: NA

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=bf034bc827807ac15affa051e6a94b03f93b1a03

-------------------------------------------------

So we can use it for start record ordering as well as commit record
ordering in future.
Signed-off-by: NDave Chinner <dchinner@redhat.com>
Reviewed-by: NDarrick J. Wong <djwong@kernel.org>
Reviewed-by: NChristoph Hellwig <hch@lst.de>
Signed-off-by: NDarrick J. Wong <djwong@kernel.org>
Signed-off-by: NLihong Kou <koulihong@huawei.com>
Reviewed-by: Nguoxuenan <guoxuenan@huawei.com>
Reviewed-by: NZhang Yi <yi.zhang@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 2eede308
......@@ -684,9 +684,54 @@ xlog_cil_set_ctx_write_state(
/*
* Write out the commit record of a checkpoint transaction associated with the
* given ticket to close off a running log write. Return the lsn of the commit
* record.
* Ensure that the order of log writes follows checkpoint sequence order. This
* relies on the context LSN being zero until the log write has guaranteed the
* LSN that the log write will start at via xlog_state_get_iclog_space().
*/
static int
xlog_cil_order_write(
struct xfs_cil *cil,
xfs_csn_t sequence)
{
struct xfs_cil_ctx *ctx;
restart:
spin_lock(&cil->xc_push_lock);
list_for_each_entry(ctx, &cil->xc_committing, committing) {
/*
* Avoid getting stuck in this loop because we were woken by the
* shutdown, but then went back to sleep once already in the
* shutdown state.
*/
if (xlog_is_shutdown(cil->xc_log)) {
spin_unlock(&cil->xc_push_lock);
return -EIO;
}
/*
* Higher sequences will wait for this one so skip them.
* Don't wait for our own sequence, either.
*/
if (ctx->sequence >= sequence)
continue;
if (!ctx->commit_lsn) {
/*
* It is still being pushed! Wait for the push to
* complete, then start again from the beginning.
*/
xlog_wait(&cil->xc_commit_wait, &cil->xc_push_lock);
goto restart;
}
}
spin_unlock(&cil->xc_push_lock);
return 0;
}
/*
* Write out the commit record of a checkpoint transaction to close off a
* running log write. These commit records are strictly ordered in ascending CIL
* sequence order so that log recovery will always replay the checkpoints in the
* correct order.
*/
static int
xlog_cil_write_commit_record(
......@@ -922,39 +967,9 @@ xlog_cil_push_work(
if (error)
goto out_abort_free_ticket;
/*
* now that we've written the checkpoint into the log, strictly
* order the commit records so replay will get them in the right order.
*/
restart:
spin_lock(&cil->xc_push_lock);
list_for_each_entry(new_ctx, &cil->xc_committing, committing) {
/*
* Avoid getting stuck in this loop because we were woken by the
* shutdown, but then went back to sleep once already in the
* shutdown state.
*/
if (xlog_is_shutdown(log)) {
spin_unlock(&cil->xc_push_lock);
goto out_abort_free_ticket;
}
/*
* Higher sequences will wait for this one so skip them.
* Don't wait for our own sequence, either.
*/
if (new_ctx->sequence >= ctx->sequence)
continue;
if (!new_ctx->commit_lsn) {
/*
* It is still being pushed! Wait for the push to
* complete, then start again from the beginning.
*/
xlog_wait(&cil->xc_commit_wait, &cil->xc_push_lock);
goto restart;
}
}
spin_unlock(&cil->xc_push_lock);
error = xlog_cil_order_write(ctx->cil, ctx->sequence);
if (error)
goto out_abort_free_ticket;
error = xlog_cil_write_commit_record(ctx, &commit_iclog);
if (error)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册