aboutsummaryrefslogtreecommitdiff
path: root/blockjob.c
diff options
context:
space:
mode:
authorKevin Wolf <kwolf@redhat.com>2017-01-17 11:56:42 +0100
committerKevin Wolf <kwolf@redhat.com>2017-02-28 20:40:37 +0100
commit76d554e20bd0a965ac22d6155a129be12fac2667 (patch)
treedd9e34a6339d8cebb1c60a51782cb6ae84490dcd /blockjob.c
parent26de9438c1b6013532fb95de0720e2696588332f (diff)
blockjob: Add permissions to block_job_add_bdrv()
Block jobs don't actually do I/O through the the reference they create with block_job_add_bdrv(), but they might want to use the permisssion system to express what the block job does to intermediate nodes. This adds permissions to block_job_add_bdrv() to provide the means to request permissions. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Acked-by: Fam Zheng <famz@redhat.com>
Diffstat (limited to 'blockjob.c')
-rw-r--r--blockjob.c36
1 files changed, 30 insertions, 6 deletions
diff --git a/blockjob.c b/blockjob.c
index 27833c7c0d..4216cdeebf 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -55,6 +55,19 @@ struct BlockJobTxn {
static QLIST_HEAD(, BlockJob) block_jobs = QLIST_HEAD_INITIALIZER(block_jobs);
+static char *child_job_get_parent_desc(BdrvChild *c)
+{
+ BlockJob *job = c->opaque;
+ return g_strdup_printf("%s job '%s'",
+ BlockJobType_lookup[job->driver->job_type],
+ job->id);
+}
+
+static const BdrvChildRole child_job = {
+ .get_parent_desc = child_job_get_parent_desc,
+ .stay_at_node = true,
+};
+
BlockJob *block_job_next(BlockJob *job)
{
if (!job) {
@@ -115,11 +128,22 @@ static void block_job_detach_aio_context(void *opaque)
block_job_unref(job);
}
-void block_job_add_bdrv(BlockJob *job, BlockDriverState *bs)
+int block_job_add_bdrv(BlockJob *job, const char *name, BlockDriverState *bs,
+ uint64_t perm, uint64_t shared_perm, Error **errp)
{
- job->nodes = g_slist_prepend(job->nodes, bs);
+ BdrvChild *c;
+
+ c = bdrv_root_attach_child(bs, name, &child_job, perm, shared_perm,
+ job, errp);
+ if (c == NULL) {
+ return -EPERM;
+ }
+
+ job->nodes = g_slist_prepend(job->nodes, c);
bdrv_ref(bs);
bdrv_op_block_all(bs, job->blocker);
+
+ return 0;
}
void *block_job_create(const char *job_id, const BlockJobDriver *driver,
@@ -171,7 +195,7 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
job = g_malloc0(driver->instance_size);
error_setg(&job->blocker, "block device is in use by block job: %s",
BlockJobType_lookup[driver->job_type]);
- block_job_add_bdrv(job, bs);
+ block_job_add_bdrv(job, "main node", bs, 0, BLK_PERM_ALL, &error_abort);
bdrv_op_unblock(bs, BLOCK_OP_TYPE_DATAPLANE, job->blocker);
job->driver = driver;
@@ -238,9 +262,9 @@ void block_job_unref(BlockJob *job)
BlockDriverState *bs = blk_bs(job->blk);
bs->job = NULL;
for (l = job->nodes; l; l = l->next) {
- bs = l->data;
- bdrv_op_unblock_all(bs, job->blocker);
- bdrv_unref(bs);
+ BdrvChild *c = l->data;
+ bdrv_op_unblock_all(c->bs, job->blocker);
+ bdrv_root_unref_child(c);
}
g_slist_free(job->nodes);
blk_remove_aio_context_notifier(job->blk,