blockjob: drop BlockJob.blk field
It's unused now (except for permission handling)[*]. The only reasonable user of it was block-stream job, recently updated to use own blk. And other block jobs prefer to use own source node related objects. So, the arguments of dropping the field are: - block jobs prefer not to use it - block jobs usually has more then one node to operate on, and better to operate symmetrically (for example has both source and target blk's in specific block-job state structure) *: BlockJob.blk is used to keep some permissions. We simply move permissions to block-job child created in block_job_create() together with blk. In mirror, we just should not care anymore about restoring state of blk. Most probably this code could be dropped long ago, after dropping bs->job pointer. Now it finally goes away together with BlockJob.blk itself. iotest 141 output is updated, as "bdrv_has_blk(bs)" check in qmp_blockdev_del() doesn't fail (we don't have blk now). Still, new error message looks even better. In iotest 283 we need to add a job id, otherwise "Invalid job ID" happens now earlier than permission check (as permissions moved from blk to block-job node). Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Reviewed-by: Nikita Lapshin <nikita.lapshin@virtuozzo.com>
This commit is contained in:
parent
1b177bbea0
commit
985cac8f20
@ -771,13 +771,6 @@ static int mirror_exit_common(Job *job)
|
|||||||
block_job_remove_all_bdrv(bjob);
|
block_job_remove_all_bdrv(bjob);
|
||||||
bdrv_replace_node(mirror_top_bs, mirror_top_bs->backing->bs, &error_abort);
|
bdrv_replace_node(mirror_top_bs, mirror_top_bs->backing->bs, &error_abort);
|
||||||
|
|
||||||
/* We just changed the BDS the job BB refers to (with either or both of the
|
|
||||||
* bdrv_replace_node() calls), so switch the BB back so the cleanup does
|
|
||||||
* the right thing. We don't need any permissions any more now. */
|
|
||||||
blk_remove_bs(bjob->blk);
|
|
||||||
blk_set_perm(bjob->blk, 0, BLK_PERM_ALL, &error_abort);
|
|
||||||
blk_insert_bs(bjob->blk, mirror_top_bs, &error_abort);
|
|
||||||
|
|
||||||
bs_opaque->job = NULL;
|
bs_opaque->job = NULL;
|
||||||
|
|
||||||
bdrv_drained_end(src);
|
bdrv_drained_end(src);
|
||||||
|
31
blockjob.c
31
blockjob.c
@ -86,7 +86,6 @@ void block_job_free(Job *job)
|
|||||||
BlockJob *bjob = container_of(job, BlockJob, job);
|
BlockJob *bjob = container_of(job, BlockJob, job);
|
||||||
|
|
||||||
block_job_remove_all_bdrv(bjob);
|
block_job_remove_all_bdrv(bjob);
|
||||||
blk_unref(bjob->blk);
|
|
||||||
ratelimit_destroy(&bjob->limit);
|
ratelimit_destroy(&bjob->limit);
|
||||||
error_free(bjob->blocker);
|
error_free(bjob->blocker);
|
||||||
}
|
}
|
||||||
@ -433,22 +432,16 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
|
|||||||
uint64_t shared_perm, int64_t speed, int flags,
|
uint64_t shared_perm, int64_t speed, int flags,
|
||||||
BlockCompletionFunc *cb, void *opaque, Error **errp)
|
BlockCompletionFunc *cb, void *opaque, Error **errp)
|
||||||
{
|
{
|
||||||
BlockBackend *blk;
|
|
||||||
BlockJob *job;
|
BlockJob *job;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (job_id == NULL && !(flags & JOB_INTERNAL)) {
|
if (job_id == NULL && !(flags & JOB_INTERNAL)) {
|
||||||
job_id = bdrv_get_device_name(bs);
|
job_id = bdrv_get_device_name(bs);
|
||||||
}
|
}
|
||||||
|
|
||||||
blk = blk_new_with_bs(bs, perm, shared_perm, errp);
|
job = job_create(job_id, &driver->job_driver, txn, bdrv_get_aio_context(bs),
|
||||||
if (!blk) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
job = job_create(job_id, &driver->job_driver, txn, blk_get_aio_context(blk),
|
|
||||||
flags, cb, opaque, errp);
|
flags, cb, opaque, errp);
|
||||||
if (job == NULL) {
|
if (job == NULL) {
|
||||||
blk_unref(blk);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -458,8 +451,6 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
|
|||||||
|
|
||||||
ratelimit_init(&job->limit);
|
ratelimit_init(&job->limit);
|
||||||
|
|
||||||
job->blk = blk;
|
|
||||||
|
|
||||||
job->finalize_cancelled_notifier.notify = block_job_event_cancelled;
|
job->finalize_cancelled_notifier.notify = block_job_event_cancelled;
|
||||||
job->finalize_completed_notifier.notify = block_job_event_completed;
|
job->finalize_completed_notifier.notify = block_job_event_completed;
|
||||||
job->pending_notifier.notify = block_job_event_pending;
|
job->pending_notifier.notify = block_job_event_pending;
|
||||||
@ -476,21 +467,23 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
|
|||||||
|
|
||||||
error_setg(&job->blocker, "block device is in use by block job: %s",
|
error_setg(&job->blocker, "block device is in use by block job: %s",
|
||||||
job_type_str(&job->job));
|
job_type_str(&job->job));
|
||||||
block_job_add_bdrv(job, "main node", bs, 0, BLK_PERM_ALL, &error_abort);
|
|
||||||
|
ret = block_job_add_bdrv(job, "main node", bs, perm, shared_perm, errp);
|
||||||
|
if (ret < 0) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
bdrv_op_unblock(bs, BLOCK_OP_TYPE_DATAPLANE, job->blocker);
|
bdrv_op_unblock(bs, BLOCK_OP_TYPE_DATAPLANE, job->blocker);
|
||||||
|
|
||||||
/* Disable request queuing in the BlockBackend to avoid deadlocks on drain:
|
|
||||||
* The job reports that it's busy until it reaches a pause point. */
|
|
||||||
blk_set_disable_request_queuing(blk, true);
|
|
||||||
blk_set_allow_aio_context_change(blk, true);
|
|
||||||
|
|
||||||
if (!block_job_set_speed(job, speed, errp)) {
|
if (!block_job_set_speed(job, speed, errp)) {
|
||||||
job_early_fail(&job->job);
|
goto fail;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return job;
|
return job;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
job_early_fail(&job->job);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void block_job_iostatus_reset(BlockJob *job)
|
void block_job_iostatus_reset(BlockJob *job)
|
||||||
|
@ -43,9 +43,6 @@ typedef struct BlockJob {
|
|||||||
/** Data belonging to the generic Job infrastructure */
|
/** Data belonging to the generic Job infrastructure */
|
||||||
Job job;
|
Job job;
|
||||||
|
|
||||||
/** The block device on which the job is operating. */
|
|
||||||
BlockBackend *blk;
|
|
||||||
|
|
||||||
/** Status that is published by the query-block-jobs QMP API */
|
/** Status that is published by the query-block-jobs QMP API */
|
||||||
BlockDeviceIoStatus iostatus;
|
BlockDeviceIoStatus iostatus;
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ wrote 1048576/1048576 bytes at offset 0
|
|||||||
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
|
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
|
||||||
{'execute': 'blockdev-del',
|
{'execute': 'blockdev-del',
|
||||||
'arguments': {'node-name': 'drv0'}}
|
'arguments': {'node-name': 'drv0'}}
|
||||||
{"error": {"class": "GenericError", "desc": "Node drv0 is in use"}}
|
{"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block device is in use by block job: commit"}}
|
||||||
{'execute': 'block-job-cancel',
|
{'execute': 'block-job-cancel',
|
||||||
'arguments': {'device': 'job0'}}
|
'arguments': {'device': 'job0'}}
|
||||||
{"return": {}}
|
{"return": {}}
|
||||||
|
@ -93,7 +93,8 @@ vm.qmp_log('blockdev-add', **{
|
|||||||
'take-child-perms': ['write']
|
'take-child-perms': ['write']
|
||||||
})
|
})
|
||||||
|
|
||||||
vm.qmp_log('blockdev-backup', sync='full', device='source', target='target')
|
vm.qmp_log('blockdev-backup', sync='full', device='source', target='target',
|
||||||
|
job_id="backup0")
|
||||||
|
|
||||||
vm.shutdown()
|
vm.shutdown()
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
{"return": {}}
|
{"return": {}}
|
||||||
{"execute": "blockdev-add", "arguments": {"driver": "blkdebug", "image": "base", "node-name": "other", "take-child-perms": ["write"]}}
|
{"execute": "blockdev-add", "arguments": {"driver": "blkdebug", "image": "base", "node-name": "other", "take-child-perms": ["write"]}}
|
||||||
{"return": {}}
|
{"return": {}}
|
||||||
{"execute": "blockdev-backup", "arguments": {"device": "source", "sync": "full", "target": "target"}}
|
{"execute": "blockdev-backup", "arguments": {"device": "source", "job-id": "backup0", "sync": "full", "target": "target"}}
|
||||||
{"error": {"class": "GenericError", "desc": "Permission conflict on node 'base': permissions 'write' are both required by node 'other' (uses node 'base' as 'image' child) and unshared by node 'source' (uses node 'base' as 'image' child)."}}
|
{"error": {"class": "GenericError", "desc": "Permission conflict on node 'base': permissions 'write' are both required by node 'other' (uses node 'base' as 'image' child) and unshared by node 'source' (uses node 'base' as 'image' child)."}}
|
||||||
|
|
||||||
=== copy-before-write filter should be gone after job-finalize ===
|
=== copy-before-write filter should be gone after job-finalize ===
|
||||||
|
Loading…
Reference in New Issue
Block a user