diff options
author | Emanuele Giuseppe Esposito <eesposit@redhat.com> | 2022-10-25 04:49:46 -0400 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2022-10-27 20:14:11 +0200 |
commit | 3428b100dc65dbce3e3b646df471a8fb2a5df556 (patch) | |
tree | 00989aec1879e28d85b909c8b5af68dc511529c5 | |
parent | e08cc001d502958040565636e19a42c06e1ae8b7 (diff) |
blockjob: implement .change_aio_ctx in child_job
child_job_change_aio_ctx() is very similar to
child_job_can_set_aio_ctx(), but it implements a new transaction
so that if all check pass, the new transaction's .commit()
will take care of changin the BlockJob AioContext.
child_job_set_aio_ctx_commit() is similar to child_job_set_aio_ctx(),
but it doesn't need to invoke the recursion, as this is already
taken care by child_job_change_aio_ctx().
Note: bdrv_child_try_change_aio_context() is not called by
anyone at this point.
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20221025084952.2139888-5-eesposit@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
-rw-r--r-- | blockjob.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/blockjob.c b/blockjob.c index bdf20a0e35..5a783b75c6 100644 --- a/blockjob.c +++ b/blockjob.c @@ -126,6 +126,50 @@ static void child_job_drained_end(BdrvChild *c, int *drained_end_counter) job_resume(&job->job); } +typedef struct BdrvStateChildJobContext { + AioContext *new_ctx; + BlockJob *job; +} BdrvStateChildJobContext; + +static void child_job_set_aio_ctx_commit(void *opaque) +{ + BdrvStateChildJobContext *s = opaque; + BlockJob *job = s->job; + + job_set_aio_context(&job->job, s->new_ctx); +} + +static TransactionActionDrv change_child_job_context = { + .commit = child_job_set_aio_ctx_commit, + .clean = g_free, +}; + +static bool child_job_change_aio_ctx(BdrvChild *c, AioContext *ctx, + GHashTable *visited, Transaction *tran, + Error **errp) +{ + BlockJob *job = c->opaque; + BdrvStateChildJobContext *s; + GSList *l; + + for (l = job->nodes; l; l = l->next) { + BdrvChild *sibling = l->data; + if (!bdrv_child_change_aio_context(sibling, ctx, visited, + tran, errp)) { + return false; + } + } + + s = g_new(BdrvStateChildJobContext, 1); + *s = (BdrvStateChildJobContext) { + .new_ctx = ctx, + .job = job, + }; + + tran_add(tran, &change_child_job_context, s); + return true; +} + static bool child_job_can_set_aio_ctx(BdrvChild *c, AioContext *ctx, GSList **ignore, Error **errp) { @@ -174,6 +218,7 @@ static const BdrvChildClass child_job = { .drained_end = child_job_drained_end, .can_set_aio_ctx = child_job_can_set_aio_ctx, .set_aio_ctx = child_job_set_aio_ctx, + .change_aio_ctx = child_job_change_aio_ctx, .stay_at_node = true, .get_parent_aio_context = child_job_get_parent_aio_context, }; |