qemu-ppc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v6 31/33] include/qemu/job.h: introduce job->pre_run() and use it


From: Emanuele Giuseppe Esposito
Subject: [PATCH v6 31/33] include/qemu/job.h: introduce job->pre_run() and use it in amend
Date: Fri, 21 Jan 2022 12:05:42 -0500

Introduce .pre_run() job callback. This cb will run in job_start,
before the coroutine is created and runs run() in the job aiocontext.

Therefore, .pre_run() always runs in the main loop.
We can use this function together with clean() cb to replace
bdrv_child_refresh_perms in block_crypto_amend_options_generic_luks(),
since that function can also be called from an iothread via
.bdrv_co_amend().

In addition, doing so we check for permissions in all bdrv
in amend, not only crypto.

.pre_run() and .clean() take care of calling bdrv_amend_pre_run()
and bdrv_amend_clean() respectively, to set up driver-specific flags
and allow the crypto driver to temporarly provide the WRITE
perm to qcrypto_block_amend_options().

.pre_run() is not yet invoked by job_start, but .clean() is.
This is not a problem, since it will just be a redundant check
and crypto will have the update->keys flag == false anyways.

Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
---
 block/amend.c      | 33 +++++++++++++++++++++++++++++++++
 include/qemu/job.h |  9 +++++++++
 2 files changed, 42 insertions(+)

diff --git a/block/amend.c b/block/amend.c
index 392df9ef83..1618fd05a6 100644
--- a/block/amend.c
+++ b/block/amend.c
@@ -53,10 +53,43 @@ static int coroutine_fn blockdev_amend_run(Job *job, Error 
**errp)
     return ret;
 }
 
+static int blockdev_amend_refresh_perms(Job *job, Error **errp)
+{
+    BlockdevAmendJob *s = container_of(job, BlockdevAmendJob, common);
+    return bdrv_child_refresh_perms(s->bs, s->bs->file, errp);
+}
+
+static int blockdev_amend_pre_run(Job *job, Error **errp)
+{
+    BlockdevAmendJob *s = container_of(job, BlockdevAmendJob, common);
+
+    if (s->bs->drv->bdrv_amend_pre_run) {
+        s->bs->drv->bdrv_amend_pre_run(s->bs);
+    }
+    return blockdev_amend_refresh_perms(job, errp);
+}
+
+static void blockdev_amend_clean(Job *job)
+{
+    BlockdevAmendJob *s = container_of(job, BlockdevAmendJob, common);
+    Error *errp = NULL;
+
+    if (s->bs->drv->bdrv_amend_clean) {
+        s->bs->drv->bdrv_amend_clean(s->bs);
+    }
+
+    blockdev_amend_refresh_perms(job, &errp);
+    if (errp) {
+        error_report_err(errp);
+    }
+}
+
 static const JobDriver blockdev_amend_job_driver = {
     .instance_size = sizeof(BlockdevAmendJob),
     .job_type      = JOB_TYPE_AMEND,
     .run           = blockdev_amend_run,
+    .pre_run       = blockdev_amend_pre_run,
+    .clean         = blockdev_amend_clean,
 };
 
 void qmp_x_blockdev_amend(const char *job_id,
diff --git a/include/qemu/job.h b/include/qemu/job.h
index 4ea7a4a0cd..915ceff425 100644
--- a/include/qemu/job.h
+++ b/include/qemu/job.h
@@ -223,6 +223,15 @@ struct JobDriver {
      * the GS API.
      */
 
+    /**
+     * Called in the Main Loop context, before the job coroutine
+     * is started in the job aiocontext. Useful to perform operations
+     * that needs to be done under BQL (like permissions setup).
+     * On success, it returns 0. Otherwise the job failed to initialize
+     * and won't start.
+     */
+    int (*pre_run)(Job *job, Error **errp);
+
     /**
      * Called when the job is resumed by the user (i.e. user_paused becomes
      * false). .user_resume is called before .resume.
-- 
2.31.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]