Misc block job patches
cover Misc block job patches
Hi,
here's a few patches from my block-stream series that I think are ready to be merged now.
I don't think there's anything controversial here:
- Patches 1 and 2 simply use block_job_next() in places where bdrv_next() was being used to look for block jobs.
- Patch 3 is a fix that was already proposed in the list.
- Patch 4 is quite simple and it deals with the failure of block_job_create() in commit_start().
Regards,
Berto
Alberto Garcia (4):
block: use the block job list in bdrv_drain_all()
block: use the block job list in qmp_query_block_jobs()
block: Prevent sleeping jobs from resuming if they have been paused
block: Create the commit block job before reopening any image
block/commit.c | 11 ++++++----- block/io.c | 24 ++++++++++++++++++------ blockdev.c | 20 ++++++++------------ blockjob.c | 6 ++++-- 4 files changed, 36 insertions(+), 25 deletions(-)
Signature · 1 line
2.8.1
PATCH 1/4 block: use the block job list in bdrv_drain_all()
bdrv_drain_all() pauses all block jobs by using bdrv_next() to iterate over all top-level BlockDriverStates. Therefore the code is unable to find block jobs in other nodes.
This patch uses block_job_next() to iterate over all block jobs.
--- block/io.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-)
block/io.c +18 -6
@@ -289,15 +289,21 @@ void bdrv_drain_all(void)bool busy = true;BlockDriverState *bs;BdrvNextIterator it; +BlockJob *job =NULL ;GSList *aio_ctxs =NULL , *ctx; +while ((job =block_job_next (job))) { +AioContext *aio_context =blk_get_aio_context (job->blk); + +aio_context_acquire (aio_context); +block_job_pause (job); +aio_context_release (aio_context); + } +for (bs =bdrv_first (&it); bs; bs =bdrv_next (&it)) {AioContext *aio_context =bdrv_get_aio_context (bs);aio_context_acquire (aio_context); -if (bs->job) { -block_job_pause (bs->job); - }bdrv_parent_drained_begin (bs);bdrv_io_unplugged_begin (bs);bdrv_drain_recurse (bs);
@@ -340,12 +346,18 @@ void bdrv_drain_all(void)aio_context_acquire (aio_context);bdrv_io_unplugged_end (bs);bdrv_parent_drained_end (bs); -if (bs->job) { -block_job_resume (bs->job); - }aio_context_release (aio_context); }g_slist_free (aio_ctxs); + + job =NULL ; +while ((job =block_job_next (job))) { +AioContext *aio_context =blk_get_aio_context (job->blk); + +aio_context_acquire (aio_context); +block_job_resume (job); +aio_context_release (aio_context); + } }/**
Signature · 1 line
2.8.1
Re: [Qemu-devel] [PATCH 1/4] block: use the block job list in bdrv_drain_all()
Quoted 10 lines · Alberto Garcia
bdrv_drain_all()pauses all block jobs by usingbdrv_next()to iterate over all top-level BlockDriverStates. Therefore the code is unable to find block jobs in other nodes.This patch uses
block_job_next()to iterate over all block jobs.Signed-off-by Alberto Garcia <[email protected]>--- block/io.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-)
PATCH 2/4 block: use the block job list in qmp_query_block_jobs()
In reply to Alberto Garciaqmp_query_block_jobs() uses bdrv_next() to look for block jobs, but this function can only find those in top-level BlockDriverStates.
This patch uses block_job_next() instead.
--- blockdev.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-)
blockdev.c +8 -12
@@ -4141,22 +4141,18 @@ void qmp_x_blockdev_change(const char *parent, bool has_child,BlockJobInfoList *qmp_query_block_jobs (Error **errp) {BlockJobInfoList *head =NULL , **p_next = &head; -BlockDriverState *bs; -BdrvNextIterator it; +BlockJob *job; -for (bs =bdrv_first (&it); bs; bs =bdrv_next (&it)) { -AioContext *aio_context =bdrv_get_aio_context (bs); +for (job =block_job_next (NULL ); job; job =block_job_next (job)) { +BlockJobInfoList *elem =g_new0 (BlockJobInfoList,1 ); +AioContext *aio_context =blk_get_aio_context (job->blk);aio_context_acquire (aio_context); - -if (bs->job) { -BlockJobInfoList *elem =g_new0 (BlockJobInfoList,1 ); - elem->value =block_job_query (bs->job); - *p_next = elem; - p_next = &elem->next; - } - + elem->value =block_job_query (job);aio_context_release (aio_context); + + *p_next = elem; + p_next = &elem->next; }return head;
Signature · 1 line
2.8.1
Re: [Qemu-devel] [PATCH 2/4] block: use the block job list in qmp_query_block_jobs()
Quoted 9 lines · Alberto Garcia
qmp_query_block_jobs()usesbdrv_next()to look for block jobs, but this function can only find those in top-level BlockDriverStates.This patch uses
block_job_next()instead.Signed-off-by Alberto Garcia <[email protected]>--- blockdev.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-)
PATCH 3/4 block: Prevent sleeping jobs from resuming if they have been paused
In reply to Alberto GarciaIf we pause a block job and drain its BlockDriverState we want that the job remains inactive until we call block_job_resume() again.
However if we pause the job while it is sleeping then it will resume when the sleep timer fires.
This patch prevents that from happening by checking if the job has been paused after it comes back from sleeping.
--- blockjob.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
blockjob.c +4 -2
@@ -361,10 +361,12 @@ void block_job_sleep_ns(BlockJob *job, QEMUClockType type, int64_t ns) } job->busy = false; +if (!block_job_is_paused (job)) { +co_aio_sleep_ns (blk_get_aio_context (job->blk), type, ns); + } +/* The job can be paused while sleeping, so check this again */ if (block_job_is_paused (job)) {qemu_coroutine_yield (); - }else { -co_aio_sleep_ns (blk_get_aio_context (job->blk), type, ns); } job->busy = true; }
Signature · 1 line
2.8.1
Re: [Qemu-devel] [PATCH 3/4] block: Prevent sleeping jobs from resuming if they have been paused
Quoted 6 lines · Alberto Garcia
If we pause a block job and drain its BlockDriverState we want that the job remains inactive until we call
block_job_resume()again.However if we pause the job while it is sleeping then it will resume when the sleep timer fires.
Quoted 8 lines
This patch prevents that from happening by checking if the job has been paused after it comes back from sleeping.
Signed-off-by Alberto Garcia <[email protected]>Suggested-by Kevin Wolf <[email protected]>--- blockjob.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
PATCH 4/4 block: Create the commit block job before reopening any image
In reply to Alberto GarciaIf the base or overlay images need to be reopened in read-write mode but the block_job_create() call fails then no one will put those images back in read-only mode.
We can solve this problem easily by calling block_job_create() first.
--- block/commit.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
block/commit.c +6 -5
@@ -236,6 +236,11 @@ void commit_start(BlockDriverState *bs, BlockDriverState *base,return ; } + s =block_job_create (&commit_job_driver, bs, speed, cb, opaque, errp); +if (!s) { +return ; + } + orig_base_flags =bdrv_get_flags (base); orig_overlay_flags =bdrv_get_flags (overlay_bs);
@@ -252,16 +257,12 @@ void commit_start(BlockDriverState *bs, BlockDriverState *base,bdrv_reopen_multiple (reopen_queue, &local_err);if (local_err !=NULL ) {error_propagate (errp, local_err); +block_job_unref (&s->common);return ; } } - s =block_job_create (&commit_job_driver, bs, speed, cb, opaque, errp); -if (!s) { -return ; - } - s->base =blk_new ();blk_insert_bs (s->base, base);
Signature · 1 line
2.8.1
Re: [Qemu-devel] [PATCH 4/4] block: Create the commit block job before reopening any image
Quoted 10 lines · Alberto Garcia
If the base or overlay images need to be reopened in read-write mode but the
block_job_create()call fails then no one will put those images back in read-only mode.We can solve this problem easily by calling
block_job_create()first.Signed-off-by Alberto Garcia <[email protected]>--- block/commit.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
Quoted 25 lines · Alberto Garcia
Hi,
here's a few patches from my block-stream series that I think are ready to be merged now.
I don't think there's anything controversial here:
- Patches 1 and 2 simply use
block_job_next()in places wherebdrv_next()was being used to look for block jobs.- Patch 3 is a fix that was already proposed in the list.
- Patch 4 is quite simple and it deals with the failure of
block_job_create()incommit_start().Regards,
Berto
Alberto Garcia (4):
block: use the block job list inbdrv_drain_all()
block: use the block job list inqmp_query_block_jobs()
block: Prevent sleeping jobs from resuming if they have been paused
block: Create the commit block job before reopening any image
Quoted 5 lines
block/commit.c | 11 ++++++----- block/io.c | 24 ++++++++++++++++++------ blockdev.c | 20 ++++++++------------ blockjob.c | 6 ++++-- 4 files changed, 36 insertions(+), 25 deletions(-)
Thanks Berto, I've applied the series to my block branch:
https://github.com/XanClic/qemu/commits/block
Max