block: Add blk_new_open()
blk_new_with_bs() creates a BlockBackend with an empty BlockDriverState attached to it. Empty BDSs are not nice, therefore add an alternative function which combines blk_new_with_bs() with bdrv_open(). Note: In contrast to bdrv_open() which takes a BlockDriver parameter, blk_new_open() does not take such a parameter. This is because bdrv_open() opens a BlockDriverState, therefore it is natural to be able to set the BlockDriver for that BDS. The fact that bdrv_open() can open more than a single BDS is merely some form of a byproduct. blk_new_open() on the other hand is intended to be used to create a whole tree of BlockDriverStates. Therefore, setting a single BlockDriver does not make much sense. Instead, the drivers to be used for each of the nodes must be configured through the "options" QDict; including the driver of the root BDS. Signed-off-by: Max Reitz <mreitz@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Message-id: 1423162705-32065-3-git-send-email-mreitz@redhat.com Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
parent
1ef01253eb
commit
ca49a4fdb3
@ -91,6 +91,40 @@ BlockBackend *blk_new_with_bs(const char *name, Error **errp)
|
|||||||
return blk;
|
return blk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calls blk_new_with_bs() and then calls bdrv_open() on the BlockDriverState.
|
||||||
|
*
|
||||||
|
* Just as with bdrv_open(), after having called this function the reference to
|
||||||
|
* @options belongs to the block layer (even on failure).
|
||||||
|
*
|
||||||
|
* TODO: Remove @filename and @flags; it should be possible to specify a whole
|
||||||
|
* BDS tree just by specifying the @options QDict (or @reference,
|
||||||
|
* alternatively). At the time of adding this function, this is not possible,
|
||||||
|
* though, so callers of this function have to be able to specify @filename and
|
||||||
|
* @flags.
|
||||||
|
*/
|
||||||
|
BlockBackend *blk_new_open(const char *name, const char *filename,
|
||||||
|
const char *reference, QDict *options, int flags,
|
||||||
|
Error **errp)
|
||||||
|
{
|
||||||
|
BlockBackend *blk;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
blk = blk_new_with_bs(name, errp);
|
||||||
|
if (!blk) {
|
||||||
|
QDECREF(options);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = bdrv_open(&blk->bs, filename, reference, options, flags, NULL, errp);
|
||||||
|
if (ret < 0) {
|
||||||
|
blk_unref(blk);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return blk;
|
||||||
|
}
|
||||||
|
|
||||||
static void blk_delete(BlockBackend *blk)
|
static void blk_delete(BlockBackend *blk)
|
||||||
{
|
{
|
||||||
assert(!blk->refcnt);
|
assert(!blk->refcnt);
|
||||||
|
@ -62,6 +62,9 @@ typedef struct BlockDevOps {
|
|||||||
|
|
||||||
BlockBackend *blk_new(const char *name, Error **errp);
|
BlockBackend *blk_new(const char *name, Error **errp);
|
||||||
BlockBackend *blk_new_with_bs(const char *name, Error **errp);
|
BlockBackend *blk_new_with_bs(const char *name, Error **errp);
|
||||||
|
BlockBackend *blk_new_open(const char *name, const char *filename,
|
||||||
|
const char *reference, QDict *options, int flags,
|
||||||
|
Error **errp);
|
||||||
void blk_ref(BlockBackend *blk);
|
void blk_ref(BlockBackend *blk);
|
||||||
void blk_unref(BlockBackend *blk);
|
void blk_unref(BlockBackend *blk);
|
||||||
const char *blk_name(BlockBackend *blk);
|
const char *blk_name(BlockBackend *blk);
|
||||||
|
Loading…
Reference in New Issue
Block a user