xfs: factor out log write ordering from xlog_cil_push_work()
So we can use it for start record ordering as well as commit record ordering in future. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Darrick J. Wong <djwong@kernel.org>
This commit is contained in:
parent
c45aba40cf
commit
bf034bc827
@ -656,9 +656,54 @@ xlog_cil_set_ctx_write_state(
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write out the commit record of a checkpoint transaction associated with the
|
* Ensure that the order of log writes follows checkpoint sequence order. This
|
||||||
* given ticket to close off a running log write. Return the lsn of the commit
|
* relies on the context LSN being zero until the log write has guaranteed the
|
||||||
* record.
|
* 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
|
static int
|
||||||
xlog_cil_write_commit_record(
|
xlog_cil_write_commit_record(
|
||||||
@ -904,39 +949,9 @@ xlog_cil_push_work(
|
|||||||
if (error)
|
if (error)
|
||||||
goto out_abort_free_ticket;
|
goto out_abort_free_ticket;
|
||||||
|
|
||||||
/*
|
error = xlog_cil_order_write(ctx->cil, ctx->sequence);
|
||||||
* now that we've written the checkpoint into the log, strictly
|
if (error)
|
||||||
* order the commit records so replay will get them in the right order.
|
goto out_abort_free_ticket;
|
||||||
*/
|
|
||||||
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_write_commit_record(ctx, &commit_iclog);
|
error = xlog_cil_write_commit_record(ctx, &commit_iclog);
|
||||||
if (error)
|
if (error)
|
||||||
|
Loading…
Reference in New Issue
Block a user