@@ -124,6 +124,50 @@ static void child_job_drained_end(BdrvChild *c, int *drained_end_counter)
}
}
+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,
+ GSList **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_tail(tran, &change_child_job_context, s);
+ return true;
+}
+
static bool child_job_can_set_aio_ctx(BdrvChild *c, AioContext *ctx,
GSList **ignore, Error **errp)
{
@@ -172,6 +216,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,
};
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> --- blockjob.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+)