forked from Minki/linux
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
|
||||
* 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(
|
||||
@ -904,39 +949,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)
|
||||
|
Loading…
Reference in New Issue
Block a user