diff options
Diffstat (limited to 'blockjob.c')
-rw-r--r-- | blockjob.c | 21 |
1 files changed, 16 insertions, 5 deletions
@@ -51,7 +51,7 @@ bool BlockJobSTT[BLOCK_JOB_STATUS__MAX][BLOCK_JOB_STATUS__MAX] = { /* P: */ [BLOCK_JOB_STATUS_PAUSED] = {0, 0, 1, 0, 0, 0, 0, 0, 0}, /* Y: */ [BLOCK_JOB_STATUS_READY] = {0, 0, 0, 0, 0, 1, 1, 1, 0}, /* S: */ [BLOCK_JOB_STATUS_STANDBY] = {0, 0, 0, 0, 1, 0, 0, 0, 0}, - /* X: */ [BLOCK_JOB_STATUS_ABORTING] = {0, 0, 0, 0, 0, 0, 0, 1, 0}, + /* X: */ [BLOCK_JOB_STATUS_ABORTING] = {0, 0, 0, 0, 0, 0, 1, 1, 0}, /* E: */ [BLOCK_JOB_STATUS_CONCLUDED] = {0, 0, 0, 0, 0, 0, 0, 0, 1}, /* N: */ [BLOCK_JOB_STATUS_NULL] = {0, 0, 0, 0, 0, 0, 0, 0, 0}, }; @@ -405,13 +405,22 @@ static void block_job_conclude(BlockJob *job) } } +static void block_job_update_rc(BlockJob *job) +{ + if (!job->ret && block_job_is_cancelled(job)) { + job->ret = -ECANCELED; + } + if (job->ret) { + block_job_state_transition(job, BLOCK_JOB_STATUS_ABORTING); + } +} + static void block_job_completed_single(BlockJob *job) { assert(job->completed); - if (job->ret || block_job_is_cancelled(job)) { - block_job_state_transition(job, BLOCK_JOB_STATUS_ABORTING); - } + /* Ensure abort is called for late-transactional failures */ + block_job_update_rc(job); if (!job->ret) { if (job->driver->commit) { @@ -896,7 +905,9 @@ void block_job_completed(BlockJob *job, int ret) assert(blk_bs(job->blk)->job == job); job->completed = true; job->ret = ret; - if (ret < 0 || block_job_is_cancelled(job)) { + block_job_update_rc(job); + trace_block_job_completed(job, ret, job->ret); + if (job->ret) { block_job_completed_txn_abort(job); } else { block_job_completed_txn_success(job); |