On Tue, Apr 24, 2012 at 7:35 PM, Luiz Capitulino <lcapitul...@redhat.com> wrote: > On Tue, 24 Apr 2012 14:53:55 +0100 > Stefan Hajnoczi <stefa...@linux.vnet.ibm.com> wrote: > >> The block job API uses -errno return values internally and we convert >> these to Error in the QMP functions. This is ugly because the Error >> should be created at the point where we still have all the relevant >> information. More importantly, it is hard to add new error cases to >> this case since we quickly run out of -errno values without losing >> information. >> >> Go ahead an use Error directly and don't convert later. >> >> Signed-off-by: Stefan Hajnoczi <stefa...@linux.vnet.ibm.com> >> --- >> block.c | 4 +++- >> block/stream.c | 11 +++++------ >> block_int.h | 11 +++++++---- >> blockdev.c | 16 +++++----------- >> 4 files changed, 20 insertions(+), 22 deletions(-) >> >> diff --git a/block.c b/block.c >> index fe74ddd..2b72a0f 100644 >> --- a/block.c >> +++ b/block.c >> @@ -4083,11 +4083,13 @@ out: >> } >> >> void *block_job_create(const BlockJobType *job_type, BlockDriverState *bs, >> - BlockDriverCompletionFunc *cb, void *opaque) >> + BlockDriverCompletionFunc *cb, void *opaque, >> + Error **errp) >> { >> BlockJob *job; >> >> if (bs->job || bdrv_in_use(bs)) { >> + error_set(errp, QERR_DEVICE_IN_USE, bdrv_get_device_name(bs)); >> return NULL; >> } >> bdrv_set_in_use(bs, 1); >> diff --git a/block/stream.c b/block/stream.c >> index 0efe1ad..7002dc8 100644 >> --- a/block/stream.c >> +++ b/block/stream.c >> @@ -280,16 +280,16 @@ static BlockJobType stream_job_type = { >> .set_speed = stream_set_speed, >> }; >> >> -int stream_start(BlockDriverState *bs, BlockDriverState *base, >> - const char *base_id, BlockDriverCompletionFunc *cb, >> - void *opaque) >> +void stream_start(BlockDriverState *bs, BlockDriverState *base, >> + const char *base_id, BlockDriverCompletionFunc *cb, >> + void *opaque, Error **errp) >> { >> StreamBlockJob *s; >> Coroutine *co; >> >> - s = block_job_create(&stream_job_type, bs, cb, opaque); >> + s = block_job_create(&stream_job_type, bs, cb, opaque, errp); >> if (!s) { >> - return -EBUSY; /* bs must already be in use */ >> + return; >> } >> >> s->base = base; >> @@ -300,5 +300,4 @@ int stream_start(BlockDriverState *bs, BlockDriverState >> *base, >> co = qemu_coroutine_create(stream_run); >> trace_stream_start(bs, base, s, co, opaque); >> qemu_coroutine_enter(co, s); >> - return 0; >> } >> diff --git a/block_int.h b/block_int.h >> index 0acb49f..8cf6ce9 100644 >> --- a/block_int.h >> +++ b/block_int.h >> @@ -346,6 +346,7 @@ int is_windows_drive(const char *filename); >> * @bs: The block >> * @cb: Completion function for the job. >> * @opaque: Opaque pointer value passed to @cb. >> + * @errp: A location to return DeviceInUse. > > Quite minor, but this is not a good description. I'd say just "Error object".
I followed the style of the glib documentation for GError** arguments. I'm happy to change to just "Error object". > >> * >> * Create a new long-running block device job and return it. The job >> * will call @cb asynchronously when the job completes. Note that >> @@ -357,7 +358,8 @@ int is_windows_drive(const char *filename); >> * called from a wrapper that is specific to the job type. >> */ >> void *block_job_create(const BlockJobType *job_type, BlockDriverState *bs, >> - BlockDriverCompletionFunc *cb, void *opaque); >> + BlockDriverCompletionFunc *cb, void *opaque, >> + Error **errp); >> >> /** >> * block_job_complete: >> @@ -417,6 +419,7 @@ void block_job_cancel_sync(BlockJob *job); >> * backing file if the job completes. Ignored if @base is %NULL. >> * @cb: Completion function for the job. >> * @opaque: Opaque pointer value passed to @cb. >> + * @errp: A location to return DeviceInUse. >> * >> * Start a streaming operation on @bs. Clusters that are unallocated >> * in @bs, but allocated in any image between @base and @bs (both >> @@ -424,8 +427,8 @@ void block_job_cancel_sync(BlockJob *job); >> * streaming job, the backing file of @bs will be changed to >> * @base_id in the written image and to @base in the live BlockDriverState. >> */ >> -int stream_start(BlockDriverState *bs, BlockDriverState *base, >> - const char *base_id, BlockDriverCompletionFunc *cb, >> - void *opaque); >> +void stream_start(BlockDriverState *bs, BlockDriverState *base, >> + const char *base_id, BlockDriverCompletionFunc *cb, >> + void *opaque, Error **errp); >> >> #endif /* BLOCK_INT_H */ >> diff --git a/blockdev.c b/blockdev.c >> index 0c2440e..a411477 100644 >> --- a/blockdev.c >> +++ b/blockdev.c >> @@ -1095,7 +1095,7 @@ void qmp_block_stream(const char *device, bool >> has_base, >> { >> BlockDriverState *bs; >> BlockDriverState *base_bs = NULL; >> - int ret; >> + Error *local_err = NULL; >> >> bs = bdrv_find(device); >> if (!bs) { >> @@ -1111,16 +1111,10 @@ void qmp_block_stream(const char *device, bool >> has_base, >> } >> } >> >> - ret = stream_start(bs, base_bs, base, block_stream_cb, bs); >> - if (ret < 0) { >> - switch (ret) { >> - case -EBUSY: >> - error_set(errp, QERR_DEVICE_IN_USE, device); >> - return; >> - default: >> - error_set(errp, QERR_NOT_SUPPORTED); >> - return; >> - } > > Just to be sureI got this right, the default clause is not actually possible > before this patch? I checked, you are right. It was not used. By removing the -errno -> Error conversion layer we ensure this kind of inconsistency cannot happen. Stefan