* [Qemu-devel] [PATCH 0/8] block: Introduce common read/write function
@ 2016-03-08 12:47 Kevin Wolf
2016-03-08 12:47 ` [Qemu-devel] [PATCH 1/8] block: Use BdrvChild in BlockBackend Kevin Wolf
` (9 more replies)
0 siblings, 10 replies; 11+ messages in thread
From: Kevin Wolf @ 2016-03-08 12:47 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, qemu-devel, stefanha, mreitz
BlockBackends support a few different interfaces for reads and writes. Until
now they used to forward the requests directly to the BDS layer, which
implemented wrappers around one central common read/write function that
contained the actual implementation of features provided by the block layer.
This only works as long as none of the features are actually on the
BlockBackend level. As it happens, we have features (writethrough cache, I/O
throttling) that are currently implemented in the BDS, but must move to the BB.
As a preparation, this series introduces the mapping of the existing APIs to a
single coroutine based preadv/pwritev function (as we already have on the BDS
level) to the BB layer. The BDS version of the emulation can't go away just yet
because there are internal users of them, but the goal is to remove them in the
long term.
Depends on Max's "blockdev: Further BlockBackend work".
Kevin Wolf (8):
block: Use BdrvChild in BlockBackend
block: Use blk_co_preadv() for blk_read()
block: Use blk_co_pwritev() for blk_write()
block: Pull up blk_read_unthrottled() implementation
block: Use blk_co_pwritev() in blk_write_zeroes()
block: Use blk_prw() in blk_pread()/blk_pwrite()
block: Use blk_aio_prwv() for aio_read/write/write_zeroes
block: Use blk_co_pwritev() in blk_co_write_zeroes()
block.c | 47 +++--
block/block-backend.c | 485 +++++++++++++++++++++++++++++++++-------------
block/io.c | 24 +--
include/block/block.h | 2 -
include/block/block_int.h | 12 ++
5 files changed, 401 insertions(+), 169 deletions(-)
--
1.8.3.1
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Qemu-devel] [PATCH 1/8] block: Use BdrvChild in BlockBackend
2016-03-08 12:47 [Qemu-devel] [PATCH 0/8] block: Introduce common read/write function Kevin Wolf
@ 2016-03-08 12:47 ` Kevin Wolf
2016-03-08 12:47 ` [Qemu-devel] [PATCH 2/8] block: Use blk_co_preadv() for blk_read() Kevin Wolf
` (8 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Kevin Wolf @ 2016-03-08 12:47 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, qemu-devel, stefanha, mreitz
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block.c | 47 ++++++---
block/block-backend.c | 254 ++++++++++++++++++++++++++++------------------
include/block/block_int.h | 5 +
3 files changed, 192 insertions(+), 114 deletions(-)
diff --git a/block.c b/block.c
index 11ba73c..57056b5 100644
--- a/block.c
+++ b/block.c
@@ -1195,10 +1195,9 @@ static int bdrv_fill_options(QDict **options, const char *filename,
return 0;
}
-static BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
- BlockDriverState *child_bs,
- const char *child_name,
- const BdrvChildRole *child_role)
+BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
+ const char *child_name,
+ const BdrvChildRole *child_role)
{
BdrvChild *child = g_new(BdrvChild, 1);
*child = (BdrvChild) {
@@ -1207,24 +1206,43 @@ static BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
.role = child_role,
};
- QLIST_INSERT_HEAD(&parent_bs->children, child, next);
QLIST_INSERT_HEAD(&child_bs->parents, child, next_parent);
return child;
}
+static BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
+ BlockDriverState *child_bs,
+ const char *child_name,
+ const BdrvChildRole *child_role)
+{
+ BdrvChild *child = bdrv_root_attach_child(child_bs, child_name, child_role);
+ QLIST_INSERT_HEAD(&parent_bs->children, child, next);
+ return child;
+}
+
static void bdrv_detach_child(BdrvChild *child)
{
- QLIST_REMOVE(child, next);
+ if (child->next.le_prev) {
+ QLIST_REMOVE(child, next);
+ child->next.le_prev = NULL;
+ }
QLIST_REMOVE(child, next_parent);
g_free(child->name);
g_free(child);
}
-void bdrv_unref_child(BlockDriverState *parent, BdrvChild *child)
+void bdrv_root_unref_child(BdrvChild *child)
{
BlockDriverState *child_bs;
+ child_bs = child->bs;
+ bdrv_detach_child(child);
+ bdrv_unref(child_bs);
+}
+
+void bdrv_unref_child(BlockDriverState *parent, BdrvChild *child)
+{
if (child == NULL) {
return;
}
@@ -1233,9 +1251,7 @@ void bdrv_unref_child(BlockDriverState *parent, BdrvChild *child)
child->bs->inherits_from = NULL;
}
- child_bs = child->bs;
- bdrv_detach_child(child);
- bdrv_unref(child_bs);
+ bdrv_root_unref_child(child);
}
/*
@@ -2275,6 +2291,14 @@ static void change_parent_backing_link(BlockDriverState *from,
{
BdrvChild *c, *next;
+ if (from->blk) {
+ /* FIXME We bypass blk_set_bs(), so we need to make these updates
+ * manually. The root problem is not in this change function, but the
+ * existence of BlockDriverState.blk. */
+ to->blk = from->blk;
+ from->blk = NULL;
+ }
+
QLIST_FOREACH_SAFE(c, &from->parents, next_parent, next) {
assert(c->role != &child_backing);
c->bs = to;
@@ -2283,9 +2307,6 @@ static void change_parent_backing_link(BlockDriverState *from,
bdrv_ref(to);
bdrv_unref(from);
}
- if (from->blk) {
- blk_set_bs(from->blk, to);
- }
}
static void swap_feature_fields(BlockDriverState *bs_top,
diff --git a/block/block-backend.c b/block/block-backend.c
index d1621ec..056d79e 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -27,7 +27,7 @@ static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb);
struct BlockBackend {
char *name;
int refcnt;
- BlockDriverState *bs;
+ BdrvChild *root;
DriveInfo *legacy_dinfo; /* null unless created by drive_new() */
QTAILQ_ENTRY(BlockBackend) link; /* for blk_backends */
QTAILQ_ENTRY(BlockBackend) monitor_link; /* for monitor_block_backends */
@@ -78,6 +78,17 @@ static QTAILQ_HEAD(, BlockBackend) blk_backends =
static QTAILQ_HEAD(, BlockBackend) monitor_block_backends =
QTAILQ_HEAD_INITIALIZER(monitor_block_backends);
+static void blk_root_inherit_options(int *child_flags, QDict *child_options,
+ int parent_flags, QDict *parent_options)
+{
+ /* We're not supposed to call this function for root nodes */
+ abort();
+}
+
+static const BdrvChildRole child_root = {
+ .inherit_options = blk_root_inherit_options,
+};
+
/*
* Create a new BlockBackend with @name, with a reference count of one.
* @name must not be null or empty.
@@ -129,7 +140,7 @@ BlockBackend *blk_new_with_bs(const char *name, Error **errp)
}
bs = bdrv_new_root();
- blk->bs = bs;
+ blk->root = bdrv_root_attach_child(bs, "root", &child_root);
bs->blk = blk;
return blk;
}
@@ -159,7 +170,7 @@ BlockBackend *blk_new_open(const char *name, const char *filename,
return NULL;
}
- ret = bdrv_open(&blk->bs, filename, reference, options, flags, errp);
+ ret = bdrv_open(&blk->root->bs, filename, reference, options, flags, errp);
if (ret < 0) {
blk_unref(blk);
return NULL;
@@ -172,7 +183,7 @@ static void blk_delete(BlockBackend *blk)
{
assert(!blk->refcnt);
assert(!blk->dev);
- if (blk->bs) {
+ if (blk->root) {
blk_remove_bs(blk);
}
assert(QLIST_EMPTY(&blk->remove_bs_notifiers.notifiers));
@@ -245,7 +256,7 @@ void blk_remove_all_bs(void)
AioContext *ctx = blk_get_aio_context(blk);
aio_context_acquire(ctx);
- if (blk->bs) {
+ if (blk->root) {
blk_remove_bs(blk);
}
aio_context_release(ctx);
@@ -287,9 +298,9 @@ BlockDriverState *blk_next_root_bs(BlockDriverState *bs)
do {
blk = blk_all_next(blk);
- } while (blk && !blk->bs);
+ } while (blk && !blk->root);
- return blk ? blk->bs : NULL;
+ return blk ? blk->root->bs : NULL;
}
/*
@@ -365,7 +376,7 @@ bool blk_name_taken(const char *name)
*/
BlockDriverState *blk_bs(BlockBackend *blk)
{
- return blk->bs;
+ return blk->root ? blk->root->bs : NULL;
}
/*
@@ -375,13 +386,13 @@ void blk_set_bs(BlockBackend *blk, BlockDriverState *bs)
{
bdrv_ref(bs);
- if (blk->bs) {
- blk->bs->blk = NULL;
- bdrv_unref(blk->bs);
+ if (blk->root) {
+ blk->root->bs->blk = NULL;
+ bdrv_root_unref_child(blk->root);
}
assert(bs->blk == NULL);
- blk->bs = bs;
+ blk->root = bdrv_root_attach_child(bs, "root", &child_root);
bs->blk = blk;
}
@@ -425,15 +436,15 @@ BlockBackend *blk_by_legacy_dinfo(DriveInfo *dinfo)
*/
void blk_remove_bs(BlockBackend *blk)
{
- assert(blk->bs->blk == blk);
+ assert(blk->root->bs->blk == blk);
notifier_list_notify(&blk->remove_bs_notifiers, blk);
blk_update_root_state(blk);
- blk->bs->blk = NULL;
- bdrv_unref(blk->bs);
- blk->bs = NULL;
+ blk->root->bs->blk = NULL;
+ bdrv_root_unref_child(blk->root);
+ blk->root = NULL;
}
/*
@@ -441,9 +452,9 @@ void blk_remove_bs(BlockBackend *blk)
*/
void blk_insert_bs(BlockBackend *blk, BlockDriverState *bs)
{
- assert(!blk->bs && !bs->blk);
+ assert(!blk->root && !bs->blk);
bdrv_ref(bs);
- blk->bs = bs;
+ blk->root = bdrv_root_attach_child(bs, "root", &child_root);
bs->blk = blk;
notifier_list_notify(&blk->insert_bs_notifiers, blk);
@@ -625,9 +636,10 @@ void blk_iostatus_disable(BlockBackend *blk)
void blk_iostatus_reset(BlockBackend *blk)
{
if (blk_iostatus_is_enabled(blk)) {
+ BlockDriverState *bs = blk_bs(blk);
blk->iostatus = BLOCK_DEVICE_IO_STATUS_OK;
- if (blk->bs && blk->bs->job) {
- block_job_iostatus_reset(blk->bs->job);
+ if (bs && bs->job) {
+ block_job_iostatus_reset(bs->job);
}
}
}
@@ -693,7 +705,7 @@ int blk_read(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
return ret;
}
- return bdrv_read(blk->bs, sector_num, buf, nb_sectors);
+ return bdrv_read(blk_bs(blk), sector_num, buf, nb_sectors);
}
int blk_read_unthrottled(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
@@ -704,7 +716,7 @@ int blk_read_unthrottled(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
return ret;
}
- return bdrv_read_unthrottled(blk->bs, sector_num, buf, nb_sectors);
+ return bdrv_read_unthrottled(blk_bs(blk), sector_num, buf, nb_sectors);
}
int blk_write(BlockBackend *blk, int64_t sector_num, const uint8_t *buf,
@@ -715,7 +727,7 @@ int blk_write(BlockBackend *blk, int64_t sector_num, const uint8_t *buf,
return ret;
}
- return bdrv_write(blk->bs, sector_num, buf, nb_sectors);
+ return bdrv_write(blk_bs(blk), sector_num, buf, nb_sectors);
}
int blk_write_zeroes(BlockBackend *blk, int64_t sector_num,
@@ -726,7 +738,7 @@ int blk_write_zeroes(BlockBackend *blk, int64_t sector_num,
return ret;
}
- return bdrv_write_zeroes(blk->bs, sector_num, nb_sectors, flags);
+ return bdrv_write_zeroes(blk_bs(blk), sector_num, nb_sectors, flags);
}
static void error_callback_bh(void *opaque)
@@ -764,7 +776,7 @@ BlockAIOCB *blk_aio_write_zeroes(BlockBackend *blk, int64_t sector_num,
return blk_abort_aio_request(blk, cb, opaque, ret);
}
- return bdrv_aio_write_zeroes(blk->bs, sector_num, nb_sectors, flags,
+ return bdrv_aio_write_zeroes(blk_bs(blk), sector_num, nb_sectors, flags,
cb, opaque);
}
@@ -775,7 +787,7 @@ int blk_pread(BlockBackend *blk, int64_t offset, void *buf, int count)
return ret;
}
- return bdrv_pread(blk->bs, offset, buf, count);
+ return bdrv_pread(blk_bs(blk), offset, buf, count);
}
int blk_pwrite(BlockBackend *blk, int64_t offset, const void *buf, int count)
@@ -785,7 +797,7 @@ int blk_pwrite(BlockBackend *blk, int64_t offset, const void *buf, int count)
return ret;
}
- return bdrv_pwrite(blk->bs, offset, buf, count);
+ return bdrv_pwrite(blk_bs(blk), offset, buf, count);
}
int64_t blk_getlength(BlockBackend *blk)
@@ -794,15 +806,15 @@ int64_t blk_getlength(BlockBackend *blk)
return -ENOMEDIUM;
}
- return bdrv_getlength(blk->bs);
+ return bdrv_getlength(blk_bs(blk));
}
void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr)
{
- if (!blk->bs) {
+ if (!blk_bs(blk)) {
*nb_sectors_ptr = 0;
} else {
- bdrv_get_geometry(blk->bs, nb_sectors_ptr);
+ bdrv_get_geometry(blk_bs(blk), nb_sectors_ptr);
}
}
@@ -812,7 +824,7 @@ int64_t blk_nb_sectors(BlockBackend *blk)
return -ENOMEDIUM;
}
- return bdrv_nb_sectors(blk->bs);
+ return bdrv_nb_sectors(blk_bs(blk));
}
BlockAIOCB *blk_aio_readv(BlockBackend *blk, int64_t sector_num,
@@ -824,7 +836,7 @@ BlockAIOCB *blk_aio_readv(BlockBackend *blk, int64_t sector_num,
return blk_abort_aio_request(blk, cb, opaque, ret);
}
- return bdrv_aio_readv(blk->bs, sector_num, iov, nb_sectors, cb, opaque);
+ return bdrv_aio_readv(blk_bs(blk), sector_num, iov, nb_sectors, cb, opaque);
}
BlockAIOCB *blk_aio_writev(BlockBackend *blk, int64_t sector_num,
@@ -836,7 +848,7 @@ BlockAIOCB *blk_aio_writev(BlockBackend *blk, int64_t sector_num,
return blk_abort_aio_request(blk, cb, opaque, ret);
}
- return bdrv_aio_writev(blk->bs, sector_num, iov, nb_sectors, cb, opaque);
+ return bdrv_aio_writev(blk_bs(blk), sector_num, iov, nb_sectors, cb, opaque);
}
BlockAIOCB *blk_aio_flush(BlockBackend *blk,
@@ -846,7 +858,7 @@ BlockAIOCB *blk_aio_flush(BlockBackend *blk,
return blk_abort_aio_request(blk, cb, opaque, -ENOMEDIUM);
}
- return bdrv_aio_flush(blk->bs, cb, opaque);
+ return bdrv_aio_flush(blk_bs(blk), cb, opaque);
}
BlockAIOCB *blk_aio_discard(BlockBackend *blk,
@@ -858,7 +870,7 @@ BlockAIOCB *blk_aio_discard(BlockBackend *blk,
return blk_abort_aio_request(blk, cb, opaque, ret);
}
- return bdrv_aio_discard(blk->bs, sector_num, nb_sectors, cb, opaque);
+ return bdrv_aio_discard(blk_bs(blk), sector_num, nb_sectors, cb, opaque);
}
void blk_aio_cancel(BlockAIOCB *acb)
@@ -882,7 +894,7 @@ int blk_aio_multiwrite(BlockBackend *blk, BlockRequest *reqs, int num_reqs)
}
}
- return bdrv_aio_multiwrite(blk->bs, reqs, num_reqs);
+ return bdrv_aio_multiwrite(blk_bs(blk), reqs, num_reqs);
}
int blk_ioctl(BlockBackend *blk, unsigned long int req, void *buf)
@@ -891,7 +903,7 @@ int blk_ioctl(BlockBackend *blk, unsigned long int req, void *buf)
return -ENOMEDIUM;
}
- return bdrv_ioctl(blk->bs, req, buf);
+ return bdrv_ioctl(blk_bs(blk), req, buf);
}
BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf,
@@ -901,7 +913,7 @@ BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf,
return blk_abort_aio_request(blk, cb, opaque, -ENOMEDIUM);
}
- return bdrv_aio_ioctl(blk->bs, req, buf, cb, opaque);
+ return bdrv_aio_ioctl(blk_bs(blk), req, buf, cb, opaque);
}
int blk_co_discard(BlockBackend *blk, int64_t sector_num, int nb_sectors)
@@ -911,7 +923,7 @@ int blk_co_discard(BlockBackend *blk, int64_t sector_num, int nb_sectors)
return ret;
}
- return bdrv_co_discard(blk->bs, sector_num, nb_sectors);
+ return bdrv_co_discard(blk_bs(blk), sector_num, nb_sectors);
}
int blk_co_flush(BlockBackend *blk)
@@ -920,7 +932,7 @@ int blk_co_flush(BlockBackend *blk)
return -ENOMEDIUM;
}
- return bdrv_co_flush(blk->bs);
+ return bdrv_co_flush(blk_bs(blk));
}
int blk_flush(BlockBackend *blk)
@@ -929,13 +941,13 @@ int blk_flush(BlockBackend *blk)
return -ENOMEDIUM;
}
- return bdrv_flush(blk->bs);
+ return bdrv_flush(blk_bs(blk));
}
void blk_drain(BlockBackend *blk)
{
- if (blk->bs) {
- bdrv_drain(blk->bs);
+ if (blk_bs(blk)) {
+ bdrv_drain(blk_bs(blk));
}
}
@@ -1023,8 +1035,10 @@ void blk_error_action(BlockBackend *blk, BlockErrorAction action,
int blk_is_read_only(BlockBackend *blk)
{
- if (blk->bs) {
- return bdrv_is_read_only(blk->bs);
+ BlockDriverState *bs = blk_bs(blk);
+
+ if (bs) {
+ return bdrv_is_read_only(bs);
} else {
return blk->root_state.read_only;
}
@@ -1032,17 +1046,21 @@ int blk_is_read_only(BlockBackend *blk)
int blk_is_sg(BlockBackend *blk)
{
- if (!blk->bs) {
+ BlockDriverState *bs = blk_bs(blk);
+
+ if (!bs) {
return 0;
}
- return bdrv_is_sg(blk->bs);
+ return bdrv_is_sg(bs);
}
int blk_enable_write_cache(BlockBackend *blk)
{
- if (blk->bs) {
- return bdrv_enable_write_cache(blk->bs);
+ BlockDriverState *bs = blk_bs(blk);
+
+ if (bs) {
+ return bdrv_enable_write_cache(bs);
} else {
return !!(blk->root_state.open_flags & BDRV_O_CACHE_WB);
}
@@ -1050,8 +1068,10 @@ int blk_enable_write_cache(BlockBackend *blk)
void blk_set_enable_write_cache(BlockBackend *blk, bool wce)
{
- if (blk->bs) {
- bdrv_set_enable_write_cache(blk->bs, wce);
+ BlockDriverState *bs = blk_bs(blk);
+
+ if (bs) {
+ bdrv_set_enable_write_cache(bs, wce);
} else {
if (wce) {
blk->root_state.open_flags |= BDRV_O_CACHE_WB;
@@ -1063,17 +1083,21 @@ void blk_set_enable_write_cache(BlockBackend *blk, bool wce)
void blk_invalidate_cache(BlockBackend *blk, Error **errp)
{
- if (!blk->bs) {
+ BlockDriverState *bs = blk_bs(blk);
+
+ if (!bs) {
error_setg(errp, "Device '%s' has no medium", blk->name);
return;
}
- bdrv_invalidate_cache(blk->bs, errp);
+ bdrv_invalidate_cache(bs, errp);
}
bool blk_is_inserted(BlockBackend *blk)
{
- return blk->bs && bdrv_is_inserted(blk->bs);
+ BlockDriverState *bs = blk_bs(blk);
+
+ return bs && bdrv_is_inserted(bs);
}
bool blk_is_available(BlockBackend *blk)
@@ -1083,22 +1107,28 @@ bool blk_is_available(BlockBackend *blk)
void blk_lock_medium(BlockBackend *blk, bool locked)
{
- if (blk->bs) {
- bdrv_lock_medium(blk->bs, locked);
+ BlockDriverState *bs = blk_bs(blk);
+
+ if (bs) {
+ bdrv_lock_medium(bs, locked);
}
}
void blk_eject(BlockBackend *blk, bool eject_flag)
{
- if (blk->bs) {
- bdrv_eject(blk->bs, eject_flag);
+ BlockDriverState *bs = blk_bs(blk);
+
+ if (bs) {
+ bdrv_eject(bs, eject_flag);
}
}
int blk_get_flags(BlockBackend *blk)
{
- if (blk->bs) {
- return bdrv_get_flags(blk->bs);
+ BlockDriverState *bs = blk_bs(blk);
+
+ if (bs) {
+ return bdrv_get_flags(bs);
} else {
return blk->root_state.open_flags;
}
@@ -1106,8 +1136,10 @@ int blk_get_flags(BlockBackend *blk)
int blk_get_max_transfer_length(BlockBackend *blk)
{
- if (blk->bs) {
- return blk->bs->bl.max_transfer_length;
+ BlockDriverState *bs = blk_bs(blk);
+
+ if (bs) {
+ return bs->bl.max_transfer_length;
} else {
return 0;
}
@@ -1115,7 +1147,7 @@ int blk_get_max_transfer_length(BlockBackend *blk)
int blk_get_max_iov(BlockBackend *blk)
{
- return blk->bs->bl.max_iov;
+ return blk->root->bs->bl.max_iov;
}
void blk_set_guest_block_size(BlockBackend *blk, int align)
@@ -1125,48 +1157,58 @@ void blk_set_guest_block_size(BlockBackend *blk, int align)
void *blk_try_blockalign(BlockBackend *blk, size_t size)
{
- return qemu_try_blockalign(blk ? blk->bs : NULL, size);
+ return qemu_try_blockalign(blk ? blk_bs(blk) : NULL, size);
}
void *blk_blockalign(BlockBackend *blk, size_t size)
{
- return qemu_blockalign(blk ? blk->bs : NULL, size);
+ return qemu_blockalign(blk ? blk_bs(blk) : NULL, size);
}
bool blk_op_is_blocked(BlockBackend *blk, BlockOpType op, Error **errp)
{
- if (!blk->bs) {
+ BlockDriverState *bs = blk_bs(blk);
+
+ if (!bs) {
return false;
}
- return bdrv_op_is_blocked(blk->bs, op, errp);
+ return bdrv_op_is_blocked(bs, op, errp);
}
void blk_op_unblock(BlockBackend *blk, BlockOpType op, Error *reason)
{
- if (blk->bs) {
- bdrv_op_unblock(blk->bs, op, reason);
+ BlockDriverState *bs = blk_bs(blk);
+
+ if (bs) {
+ bdrv_op_unblock(bs, op, reason);
}
}
void blk_op_block_all(BlockBackend *blk, Error *reason)
{
- if (blk->bs) {
- bdrv_op_block_all(blk->bs, reason);
+ BlockDriverState *bs = blk_bs(blk);
+
+ if (bs) {
+ bdrv_op_block_all(bs, reason);
}
}
void blk_op_unblock_all(BlockBackend *blk, Error *reason)
{
- if (blk->bs) {
- bdrv_op_unblock_all(blk->bs, reason);
+ BlockDriverState *bs = blk_bs(blk);
+
+ if (bs) {
+ bdrv_op_unblock_all(bs, reason);
}
}
AioContext *blk_get_aio_context(BlockBackend *blk)
{
- if (blk->bs) {
- return bdrv_get_aio_context(blk->bs);
+ BlockDriverState *bs = blk_bs(blk);
+
+ if (bs) {
+ return bdrv_get_aio_context(bs);
} else {
return qemu_get_aio_context();
}
@@ -1180,8 +1222,10 @@ static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb)
void blk_set_aio_context(BlockBackend *blk, AioContext *new_context)
{
- if (blk->bs) {
- bdrv_set_aio_context(blk->bs, new_context);
+ BlockDriverState *bs = blk_bs(blk);
+
+ if (bs) {
+ bdrv_set_aio_context(bs, new_context);
}
}
@@ -1189,8 +1233,10 @@ void blk_add_aio_context_notifier(BlockBackend *blk,
void (*attached_aio_context)(AioContext *new_context, void *opaque),
void (*detach_aio_context)(void *opaque), void *opaque)
{
- if (blk->bs) {
- bdrv_add_aio_context_notifier(blk->bs, attached_aio_context,
+ BlockDriverState *bs = blk_bs(blk);
+
+ if (bs) {
+ bdrv_add_aio_context_notifier(bs, attached_aio_context,
detach_aio_context, opaque);
}
}
@@ -1201,8 +1247,10 @@ void blk_remove_aio_context_notifier(BlockBackend *blk,
void (*detach_aio_context)(void *),
void *opaque)
{
- if (blk->bs) {
- bdrv_remove_aio_context_notifier(blk->bs, attached_aio_context,
+ BlockDriverState *bs = blk_bs(blk);
+
+ if (bs) {
+ bdrv_remove_aio_context_notifier(bs, attached_aio_context,
detach_aio_context, opaque);
}
}
@@ -1219,15 +1267,19 @@ void blk_add_insert_bs_notifier(BlockBackend *blk, Notifier *notify)
void blk_io_plug(BlockBackend *blk)
{
- if (blk->bs) {
- bdrv_io_plug(blk->bs);
+ BlockDriverState *bs = blk_bs(blk);
+
+ if (bs) {
+ bdrv_io_plug(bs);
}
}
void blk_io_unplug(BlockBackend *blk)
{
- if (blk->bs) {
- bdrv_io_unplug(blk->bs);
+ BlockDriverState *bs = blk_bs(blk);
+
+ if (bs) {
+ bdrv_io_unplug(bs);
}
}
@@ -1250,7 +1302,7 @@ int coroutine_fn blk_co_write_zeroes(BlockBackend *blk, int64_t sector_num,
return ret;
}
- return bdrv_co_write_zeroes(blk->bs, sector_num, nb_sectors, flags);
+ return bdrv_co_write_zeroes(blk_bs(blk), sector_num, nb_sectors, flags);
}
int blk_write_compressed(BlockBackend *blk, int64_t sector_num,
@@ -1261,7 +1313,7 @@ int blk_write_compressed(BlockBackend *blk, int64_t sector_num,
return ret;
}
- return bdrv_write_compressed(blk->bs, sector_num, buf, nb_sectors);
+ return bdrv_write_compressed(blk_bs(blk), sector_num, buf, nb_sectors);
}
int blk_truncate(BlockBackend *blk, int64_t offset)
@@ -1270,7 +1322,7 @@ int blk_truncate(BlockBackend *blk, int64_t offset)
return -ENOMEDIUM;
}
- return bdrv_truncate(blk->bs, offset);
+ return bdrv_truncate(blk_bs(blk), offset);
}
int blk_discard(BlockBackend *blk, int64_t sector_num, int nb_sectors)
@@ -1280,7 +1332,7 @@ int blk_discard(BlockBackend *blk, int64_t sector_num, int nb_sectors)
return ret;
}
- return bdrv_discard(blk->bs, sector_num, nb_sectors);
+ return bdrv_discard(blk_bs(blk), sector_num, nb_sectors);
}
int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
@@ -1290,7 +1342,7 @@ int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
return -ENOMEDIUM;
}
- return bdrv_save_vmstate(blk->bs, buf, pos, size);
+ return bdrv_save_vmstate(blk_bs(blk), buf, pos, size);
}
int blk_load_vmstate(BlockBackend *blk, uint8_t *buf, int64_t pos, int size)
@@ -1299,7 +1351,7 @@ int blk_load_vmstate(BlockBackend *blk, uint8_t *buf, int64_t pos, int size)
return -ENOMEDIUM;
}
- return bdrv_load_vmstate(blk->bs, buf, pos, size);
+ return bdrv_load_vmstate(blk_bs(blk), buf, pos, size);
}
int blk_probe_blocksizes(BlockBackend *blk, BlockSizes *bsz)
@@ -1308,7 +1360,7 @@ int blk_probe_blocksizes(BlockBackend *blk, BlockSizes *bsz)
return -ENOMEDIUM;
}
- return bdrv_probe_blocksizes(blk->bs, bsz);
+ return bdrv_probe_blocksizes(blk_bs(blk), bsz);
}
int blk_probe_geometry(BlockBackend *blk, HDGeometry *geo)
@@ -1317,7 +1369,7 @@ int blk_probe_geometry(BlockBackend *blk, HDGeometry *geo)
return -ENOMEDIUM;
}
- return bdrv_probe_geometry(blk->bs, geo);
+ return bdrv_probe_geometry(blk_bs(blk), geo);
}
/*
@@ -1326,18 +1378,18 @@ int blk_probe_geometry(BlockBackend *blk, HDGeometry *geo)
*/
void blk_update_root_state(BlockBackend *blk)
{
- assert(blk->bs);
+ assert(blk->root);
- blk->root_state.open_flags = blk->bs->open_flags;
- blk->root_state.read_only = blk->bs->read_only;
- blk->root_state.detect_zeroes = blk->bs->detect_zeroes;
+ blk->root_state.open_flags = blk->root->bs->open_flags;
+ blk->root_state.read_only = blk->root->bs->read_only;
+ blk->root_state.detect_zeroes = blk->root->bs->detect_zeroes;
if (blk->root_state.throttle_group) {
g_free(blk->root_state.throttle_group);
throttle_group_unref(blk->root_state.throttle_state);
}
- if (blk->bs->throttle_state) {
- const char *name = throttle_group_get_name(blk->bs);
+ if (blk->root->bs->throttle_state) {
+ const char *name = throttle_group_get_name(blk->root->bs);
blk->root_state.throttle_group = g_strdup(name);
blk->root_state.throttle_state = throttle_group_incref(name);
} else {
@@ -1386,8 +1438,8 @@ int blk_commit_all(void)
AioContext *aio_context = blk_get_aio_context(blk);
aio_context_acquire(aio_context);
- if (blk_is_available(blk) && blk->bs->drv && blk->bs->backing) {
- int ret = bdrv_commit(blk->bs);
+ if (blk_is_available(blk) && blk->root->bs->backing) {
+ int ret = bdrv_commit(blk->root->bs);
if (ret < 0) {
aio_context_release(aio_context);
return ret;
diff --git a/include/block/block_int.h b/include/block/block_int.h
index fdcacab..9d3a2cc 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -690,6 +690,11 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target,
BlockCompletionFunc *cb, void *opaque,
BlockJobTxn *txn, Error **errp);
+BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
+ const char *child_name,
+ const BdrvChildRole *child_role);
+void bdrv_root_unref_child(BdrvChild *child);
+
void blk_set_bs(BlockBackend *blk, BlockDriverState *bs);
void blk_dev_change_media_cb(BlockBackend *blk, bool load);
--
1.8.3.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Qemu-devel] [PATCH 2/8] block: Use blk_co_preadv() for blk_read()
2016-03-08 12:47 [Qemu-devel] [PATCH 0/8] block: Introduce common read/write function Kevin Wolf
2016-03-08 12:47 ` [Qemu-devel] [PATCH 1/8] block: Use BdrvChild in BlockBackend Kevin Wolf
@ 2016-03-08 12:47 ` Kevin Wolf
2016-03-08 12:47 ` [Qemu-devel] [PATCH 3/8] block: Use blk_co_pwritev() for blk_write() Kevin Wolf
` (7 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Kevin Wolf @ 2016-03-08 12:47 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, qemu-devel, stefanha, mreitz
This patch introduces blk_co_preadv() as a central function on the
BlockBackend level that is supposed to handle all read requests from the
BB to its root BDS eventually.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/block-backend.c | 64 ++++++++++++++++++++++++++++++++++++++++++++---
block/io.c | 5 +---
include/block/block_int.h | 4 +++
3 files changed, 65 insertions(+), 8 deletions(-)
diff --git a/block/block-backend.c b/block/block-backend.c
index 056d79e..d97d1ac 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -22,6 +22,8 @@
/* Number of coroutines to reserve per attached device model */
#define COROUTINE_POOL_RESERVATION 64
+#define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */
+
static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb);
struct BlockBackend {
@@ -697,15 +699,69 @@ static int blk_check_request(BlockBackend *blk, int64_t sector_num,
nb_sectors * BDRV_SECTOR_SIZE);
}
-int blk_read(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
- int nb_sectors)
+static int coroutine_fn blk_co_preadv(BlockBackend *blk, int64_t offset,
+ unsigned int bytes, QEMUIOVector *qiov,
+ BdrvRequestFlags flags)
{
- int ret = blk_check_request(blk, sector_num, nb_sectors);
+ int ret = blk_check_byte_request(blk, offset, bytes);
if (ret < 0) {
return ret;
}
- return bdrv_read(blk_bs(blk), sector_num, buf, nb_sectors);
+ return bdrv_co_do_preadv(blk_bs(blk), offset, bytes, qiov, flags);
+}
+
+typedef struct BlkRwCo {
+ BlockBackend *blk;
+ int64_t offset;
+ QEMUIOVector *qiov;
+ int ret;
+ BdrvRequestFlags flags;
+} BlkRwCo;
+
+static void blk_read_entry(void *opaque)
+{
+ BlkRwCo *rwco = opaque;
+
+ rwco->ret = blk_co_preadv(rwco->blk, rwco->offset, rwco->qiov->size,
+ rwco->qiov, rwco->flags);
+}
+
+int blk_read(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
+ int nb_sectors)
+{
+ AioContext *aio_context;
+ QEMUIOVector qiov;
+ struct iovec iov;
+ Coroutine *co;
+ BlkRwCo rwco;
+
+ if (nb_sectors < 0 || nb_sectors > BDRV_REQUEST_MAX_SECTORS) {
+ return -EINVAL;
+ }
+
+ iov = (struct iovec) {
+ .iov_base = buf,
+ .iov_len = nb_sectors * BDRV_SECTOR_SIZE,
+ };
+ qemu_iovec_init_external(&qiov, &iov, 1);
+
+ rwco = (BlkRwCo) {
+ .blk = blk,
+ .offset = sector_num << BDRV_SECTOR_BITS,
+ .qiov = &qiov,
+ .ret = NOT_DONE,
+ };
+
+ co = qemu_coroutine_create(blk_read_entry);
+ qemu_coroutine_enter(co, &rwco);
+
+ aio_context = blk_get_aio_context(blk);
+ while (rwco.ret == NOT_DONE) {
+ aio_poll(aio_context, true);
+ }
+
+ return rwco.ret;
}
int blk_read_unthrottled(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
diff --git a/block/io.c b/block/io.c
index 5f9b6d6..c7084e4 100644
--- a/block/io.c
+++ b/block/io.c
@@ -44,9 +44,6 @@ static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs,
static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs,
int64_t sector_num, int nb_sectors,
QEMUIOVector *iov);
-static int coroutine_fn bdrv_co_do_preadv(BlockDriverState *bs,
- int64_t offset, unsigned int bytes, QEMUIOVector *qiov,
- BdrvRequestFlags flags);
static int coroutine_fn bdrv_co_do_pwritev(BlockDriverState *bs,
int64_t offset, unsigned int bytes, QEMUIOVector *qiov,
BdrvRequestFlags flags);
@@ -939,7 +936,7 @@ out:
/*
* Handle a read request in coroutine context
*/
-static int coroutine_fn bdrv_co_do_preadv(BlockDriverState *bs,
+int coroutine_fn bdrv_co_do_preadv(BlockDriverState *bs,
int64_t offset, unsigned int bytes, QEMUIOVector *qiov,
BdrvRequestFlags flags)
{
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 9d3a2cc..db830f6 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -508,6 +508,10 @@ extern BlockDriver bdrv_qcow2;
*/
void bdrv_setup_io_funcs(BlockDriver *bdrv);
+int coroutine_fn bdrv_co_do_preadv(BlockDriverState *bs,
+ int64_t offset, unsigned int bytes, QEMUIOVector *qiov,
+ BdrvRequestFlags flags);
+
int get_tmp_filename(char *filename, int size);
BlockDriver *bdrv_probe_all(const uint8_t *buf, int buf_size,
const char *filename);
--
1.8.3.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Qemu-devel] [PATCH 3/8] block: Use blk_co_pwritev() for blk_write()
2016-03-08 12:47 [Qemu-devel] [PATCH 0/8] block: Introduce common read/write function Kevin Wolf
2016-03-08 12:47 ` [Qemu-devel] [PATCH 1/8] block: Use BdrvChild in BlockBackend Kevin Wolf
2016-03-08 12:47 ` [Qemu-devel] [PATCH 2/8] block: Use blk_co_preadv() for blk_read() Kevin Wolf
@ 2016-03-08 12:47 ` Kevin Wolf
2016-03-08 12:47 ` [Qemu-devel] [PATCH 4/8] block: Pull up blk_read_unthrottled() implementation Kevin Wolf
` (6 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Kevin Wolf @ 2016-03-08 12:47 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, qemu-devel, stefanha, mreitz
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/block-backend.c | 39 ++++++++++++++++++++++++++++++---------
block/io.c | 5 +----
include/block/block_int.h | 3 +++
3 files changed, 34 insertions(+), 13 deletions(-)
diff --git a/block/block-backend.c b/block/block-backend.c
index d97d1ac..e159647 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -711,6 +711,18 @@ static int coroutine_fn blk_co_preadv(BlockBackend *blk, int64_t offset,
return bdrv_co_do_preadv(blk_bs(blk), offset, bytes, qiov, flags);
}
+static int coroutine_fn blk_co_pwritev(BlockBackend *blk, int64_t offset,
+ unsigned int bytes, QEMUIOVector *qiov,
+ BdrvRequestFlags flags)
+{
+ int ret = blk_check_byte_request(blk, offset, bytes);
+ if (ret < 0) {
+ return ret;
+ }
+
+ return bdrv_co_do_pwritev(blk_bs(blk), offset, bytes, qiov, flags);
+}
+
typedef struct BlkRwCo {
BlockBackend *blk;
int64_t offset;
@@ -727,8 +739,16 @@ static void blk_read_entry(void *opaque)
rwco->qiov, rwco->flags);
}
-int blk_read(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
- int nb_sectors)
+static void blk_write_entry(void *opaque)
+{
+ BlkRwCo *rwco = opaque;
+
+ rwco->ret = blk_co_pwritev(rwco->blk, rwco->offset, rwco->qiov->size,
+ rwco->qiov, rwco->flags);
+}
+
+static int blk_rw(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
+ int nb_sectors, CoroutineEntry co_entry)
{
AioContext *aio_context;
QEMUIOVector qiov;
@@ -753,7 +773,7 @@ int blk_read(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
.ret = NOT_DONE,
};
- co = qemu_coroutine_create(blk_read_entry);
+ co = qemu_coroutine_create(co_entry);
qemu_coroutine_enter(co, &rwco);
aio_context = blk_get_aio_context(blk);
@@ -764,6 +784,12 @@ int blk_read(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
return rwco.ret;
}
+int blk_read(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
+ int nb_sectors)
+{
+ return blk_rw(blk, sector_num, buf, nb_sectors, blk_read_entry);
+}
+
int blk_read_unthrottled(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
int nb_sectors)
{
@@ -778,12 +804,7 @@ int blk_read_unthrottled(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
int blk_write(BlockBackend *blk, int64_t sector_num, const uint8_t *buf,
int nb_sectors)
{
- int ret = blk_check_request(blk, sector_num, nb_sectors);
- if (ret < 0) {
- return ret;
- }
-
- return bdrv_write(blk_bs(blk), sector_num, buf, nb_sectors);
+ return blk_rw(blk, sector_num, (uint8_t*) buf, nb_sectors, blk_write_entry);
}
int blk_write_zeroes(BlockBackend *blk, int64_t sector_num,
diff --git a/block/io.c b/block/io.c
index c7084e4..aa8537c 100644
--- a/block/io.c
+++ b/block/io.c
@@ -44,9 +44,6 @@ static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs,
static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs,
int64_t sector_num, int nb_sectors,
QEMUIOVector *iov);
-static int coroutine_fn bdrv_co_do_pwritev(BlockDriverState *bs,
- int64_t offset, unsigned int bytes, QEMUIOVector *qiov,
- BdrvRequestFlags flags);
static BlockAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
int64_t sector_num,
QEMUIOVector *qiov,
@@ -1281,7 +1278,7 @@ fail:
/*
* Handle a write request in coroutine context
*/
-static int coroutine_fn bdrv_co_do_pwritev(BlockDriverState *bs,
+int coroutine_fn bdrv_co_do_pwritev(BlockDriverState *bs,
int64_t offset, unsigned int bytes, QEMUIOVector *qiov,
BdrvRequestFlags flags)
{
diff --git a/include/block/block_int.h b/include/block/block_int.h
index db830f6..35ba42f 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -511,6 +511,9 @@ void bdrv_setup_io_funcs(BlockDriver *bdrv);
int coroutine_fn bdrv_co_do_preadv(BlockDriverState *bs,
int64_t offset, unsigned int bytes, QEMUIOVector *qiov,
BdrvRequestFlags flags);
+int coroutine_fn bdrv_co_do_pwritev(BlockDriverState *bs,
+ int64_t offset, unsigned int bytes, QEMUIOVector *qiov,
+ BdrvRequestFlags flags);
int get_tmp_filename(char *filename, int size);
BlockDriver *bdrv_probe_all(const uint8_t *buf, int buf_size,
--
1.8.3.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Qemu-devel] [PATCH 4/8] block: Pull up blk_read_unthrottled() implementation
2016-03-08 12:47 [Qemu-devel] [PATCH 0/8] block: Introduce common read/write function Kevin Wolf
` (2 preceding siblings ...)
2016-03-08 12:47 ` [Qemu-devel] [PATCH 3/8] block: Use blk_co_pwritev() for blk_write() Kevin Wolf
@ 2016-03-08 12:47 ` Kevin Wolf
2016-03-08 12:47 ` [Qemu-devel] [PATCH 5/8] block: Use blk_co_pwritev() in blk_write_zeroes() Kevin Wolf
` (5 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Kevin Wolf @ 2016-03-08 12:47 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, qemu-devel, stefanha, mreitz
Use blk_read(), so that it goes through blk_co_preadv() like all read
requests from the BB to the BDS.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/block-backend.c | 12 ++++++++++--
block/io.c | 14 --------------
include/block/block.h | 2 --
3 files changed, 10 insertions(+), 18 deletions(-)
diff --git a/block/block-backend.c b/block/block-backend.c
index e159647..4fd0545 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -793,12 +793,20 @@ int blk_read(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
int blk_read_unthrottled(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
int nb_sectors)
{
- int ret = blk_check_request(blk, sector_num, nb_sectors);
+ BlockDriverState *bs = blk_bs(blk);
+ bool enabled;
+ int ret;
+
+ ret = blk_check_request(blk, sector_num, nb_sectors);
if (ret < 0) {
return ret;
}
- return bdrv_read_unthrottled(blk_bs(blk), sector_num, buf, nb_sectors);
+ enabled = bs->io_limits_enabled;
+ bs->io_limits_enabled = false;
+ ret = blk_read(blk, sector_num, buf, nb_sectors);
+ bs->io_limits_enabled = enabled;
+ return ret;
}
int blk_write(BlockBackend *blk, int64_t sector_num, const uint8_t *buf,
diff --git a/block/io.c b/block/io.c
index aa8537c..41d954ca 100644
--- a/block/io.c
+++ b/block/io.c
@@ -615,20 +615,6 @@ int bdrv_read(BlockDriverState *bs, int64_t sector_num,
return bdrv_rw_co(bs, sector_num, buf, nb_sectors, false, 0);
}
-/* Just like bdrv_read(), but with I/O throttling temporarily disabled */
-int bdrv_read_unthrottled(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
-{
- bool enabled;
- int ret;
-
- enabled = bs->io_limits_enabled;
- bs->io_limits_enabled = false;
- ret = bdrv_read(bs, sector_num, buf, nb_sectors);
- bs->io_limits_enabled = enabled;
- return ret;
-}
-
/* Return < 0 if error. Important errors are:
-EIO generic I/O error (may happen for all errors)
-ENOMEDIUM No media inserted.
diff --git a/include/block/block.h b/include/block/block.h
index d2e1a51..3a78414 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -227,8 +227,6 @@ void bdrv_reopen_commit(BDRVReopenState *reopen_state);
void bdrv_reopen_abort(BDRVReopenState *reopen_state);
int bdrv_read(BlockDriverState *bs, int64_t sector_num,
uint8_t *buf, int nb_sectors);
-int bdrv_read_unthrottled(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors);
int bdrv_write(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors);
int bdrv_write_zeroes(BlockDriverState *bs, int64_t sector_num,
--
1.8.3.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Qemu-devel] [PATCH 5/8] block: Use blk_co_pwritev() in blk_write_zeroes()
2016-03-08 12:47 [Qemu-devel] [PATCH 0/8] block: Introduce common read/write function Kevin Wolf
` (3 preceding siblings ...)
2016-03-08 12:47 ` [Qemu-devel] [PATCH 4/8] block: Pull up blk_read_unthrottled() implementation Kevin Wolf
@ 2016-03-08 12:47 ` Kevin Wolf
2016-03-08 12:47 ` [Qemu-devel] [PATCH 6/8] block: Use blk_prw() in blk_pread()/blk_pwrite() Kevin Wolf
` (4 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Kevin Wolf @ 2016-03-08 12:47 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, qemu-devel, stefanha, mreitz
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/block-backend.c | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/block/block-backend.c b/block/block-backend.c
index 4fd0545..5b9d387 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -748,7 +748,8 @@ static void blk_write_entry(void *opaque)
}
static int blk_rw(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
- int nb_sectors, CoroutineEntry co_entry)
+ int nb_sectors, CoroutineEntry co_entry,
+ BdrvRequestFlags flags)
{
AioContext *aio_context;
QEMUIOVector qiov;
@@ -770,6 +771,7 @@ static int blk_rw(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
.blk = blk,
.offset = sector_num << BDRV_SECTOR_BITS,
.qiov = &qiov,
+ .flags = flags,
.ret = NOT_DONE,
};
@@ -787,7 +789,7 @@ static int blk_rw(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
int blk_read(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
int nb_sectors)
{
- return blk_rw(blk, sector_num, buf, nb_sectors, blk_read_entry);
+ return blk_rw(blk, sector_num, buf, nb_sectors, blk_read_entry, 0);
}
int blk_read_unthrottled(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
@@ -812,18 +814,15 @@ int blk_read_unthrottled(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
int blk_write(BlockBackend *blk, int64_t sector_num, const uint8_t *buf,
int nb_sectors)
{
- return blk_rw(blk, sector_num, (uint8_t*) buf, nb_sectors, blk_write_entry);
+ return blk_rw(blk, sector_num, (uint8_t*) buf, nb_sectors,
+ blk_write_entry, 0);
}
int blk_write_zeroes(BlockBackend *blk, int64_t sector_num,
int nb_sectors, BdrvRequestFlags flags)
{
- int ret = blk_check_request(blk, sector_num, nb_sectors);
- if (ret < 0) {
- return ret;
- }
-
- return bdrv_write_zeroes(blk_bs(blk), sector_num, nb_sectors, flags);
+ return blk_rw(blk, sector_num, NULL, nb_sectors, blk_write_entry,
+ BDRV_REQ_ZERO_WRITE);
}
static void error_callback_bh(void *opaque)
--
1.8.3.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Qemu-devel] [PATCH 6/8] block: Use blk_prw() in blk_pread()/blk_pwrite()
2016-03-08 12:47 [Qemu-devel] [PATCH 0/8] block: Introduce common read/write function Kevin Wolf
` (4 preceding siblings ...)
2016-03-08 12:47 ` [Qemu-devel] [PATCH 5/8] block: Use blk_co_pwritev() in blk_write_zeroes() Kevin Wolf
@ 2016-03-08 12:47 ` Kevin Wolf
2016-03-08 12:47 ` [Qemu-devel] [PATCH 7/8] block: Use blk_aio_prwv() for aio_read/write/write_zeroes Kevin Wolf
` (3 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Kevin Wolf @ 2016-03-08 12:47 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, qemu-devel, stefanha, mreitz
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/block-backend.c | 36 +++++++++++++++++++++---------------
1 file changed, 21 insertions(+), 15 deletions(-)
diff --git a/block/block-backend.c b/block/block-backend.c
index 5b9d387..579cc09 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -747,9 +747,9 @@ static void blk_write_entry(void *opaque)
rwco->qiov, rwco->flags);
}
-static int blk_rw(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
- int nb_sectors, CoroutineEntry co_entry,
- BdrvRequestFlags flags)
+static int blk_prw(BlockBackend *blk, int64_t offset, uint8_t *buf,
+ int64_t bytes, CoroutineEntry co_entry,
+ BdrvRequestFlags flags)
{
AioContext *aio_context;
QEMUIOVector qiov;
@@ -757,19 +757,15 @@ static int blk_rw(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
Coroutine *co;
BlkRwCo rwco;
- if (nb_sectors < 0 || nb_sectors > BDRV_REQUEST_MAX_SECTORS) {
- return -EINVAL;
- }
-
iov = (struct iovec) {
.iov_base = buf,
- .iov_len = nb_sectors * BDRV_SECTOR_SIZE,
+ .iov_len = bytes,
};
qemu_iovec_init_external(&qiov, &iov, 1);
rwco = (BlkRwCo) {
.blk = blk,
- .offset = sector_num << BDRV_SECTOR_BITS,
+ .offset = offset,
.qiov = &qiov,
.flags = flags,
.ret = NOT_DONE,
@@ -786,6 +782,18 @@ static int blk_rw(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
return rwco.ret;
}
+static int blk_rw(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
+ int nb_sectors, CoroutineEntry co_entry,
+ BdrvRequestFlags flags)
+{
+ if (nb_sectors < 0 || nb_sectors > BDRV_REQUEST_MAX_SECTORS) {
+ return -EINVAL;
+ }
+
+ return blk_prw(blk, sector_num << BDRV_SECTOR_BITS, buf,
+ nb_sectors << BDRV_SECTOR_BITS, co_entry, flags);
+}
+
int blk_read(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
int nb_sectors)
{
@@ -866,22 +874,20 @@ BlockAIOCB *blk_aio_write_zeroes(BlockBackend *blk, int64_t sector_num,
int blk_pread(BlockBackend *blk, int64_t offset, void *buf, int count)
{
- int ret = blk_check_byte_request(blk, offset, count);
+ int ret = blk_prw(blk, offset, buf, count, blk_read_entry, 0);
if (ret < 0) {
return ret;
}
-
- return bdrv_pread(blk_bs(blk), offset, buf, count);
+ return count;
}
int blk_pwrite(BlockBackend *blk, int64_t offset, const void *buf, int count)
{
- int ret = blk_check_byte_request(blk, offset, count);
+ int ret = blk_prw(blk, offset, (void*) buf, count, blk_write_entry, 0);
if (ret < 0) {
return ret;
}
-
- return bdrv_pwrite(blk_bs(blk), offset, buf, count);
+ return count;
}
int64_t blk_getlength(BlockBackend *blk)
--
1.8.3.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Qemu-devel] [PATCH 7/8] block: Use blk_aio_prwv() for aio_read/write/write_zeroes
2016-03-08 12:47 [Qemu-devel] [PATCH 0/8] block: Introduce common read/write function Kevin Wolf
` (5 preceding siblings ...)
2016-03-08 12:47 ` [Qemu-devel] [PATCH 6/8] block: Use blk_prw() in blk_pread()/blk_pwrite() Kevin Wolf
@ 2016-03-08 12:47 ` Kevin Wolf
2016-03-08 12:47 ` [Qemu-devel] [PATCH 8/8] block: Use blk_co_pwritev() in blk_co_write_zeroes() Kevin Wolf
` (2 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Kevin Wolf @ 2016-03-08 12:47 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, qemu-devel, stefanha, mreitz
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/block-backend.c | 104 +++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 91 insertions(+), 13 deletions(-)
diff --git a/block/block-backend.c b/block/block-backend.c
index 579cc09..2947e8c 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -859,17 +859,95 @@ BlockAIOCB *blk_abort_aio_request(BlockBackend *blk,
return &acb->common;
}
+typedef struct BlkAioEmAIOCB {
+ BlockAIOCB common;
+ BlkRwCo rwco;
+ bool has_returned;
+ QEMUBH* bh;
+} BlkAioEmAIOCB;
+
+static const AIOCBInfo blk_aio_em_aiocb_info = {
+ .aiocb_size = sizeof(BlkAioEmAIOCB),
+};
+
+static void blk_aio_complete(BlkAioEmAIOCB *acb)
+{
+ if (acb->bh) {
+ assert(acb->has_returned);
+ qemu_bh_delete(acb->bh);
+ }
+ if (acb->has_returned) {
+ acb->common.cb(acb->common.opaque, acb->rwco.ret);
+ qemu_aio_unref(acb);
+ }
+}
+
+static void blk_aio_complete_bh(void *opaque)
+{
+ blk_aio_complete(opaque);
+}
+
+static BlockAIOCB *blk_aio_prwv(BlockBackend *blk, int64_t offset,
+ QEMUIOVector *qiov, CoroutineEntry co_entry,
+ BdrvRequestFlags flags,
+ BlockCompletionFunc *cb, void *opaque)
+{
+ BlkAioEmAIOCB *acb;
+ Coroutine *co;
+
+ acb = blk_aio_get(&blk_aio_em_aiocb_info, blk, cb, opaque);
+ acb->rwco = (BlkRwCo) {
+ .blk = blk,
+ .offset = offset,
+ .qiov = qiov,
+ .flags = flags,
+ .ret = NOT_DONE,
+ };
+ acb->bh = NULL;
+ acb->has_returned = false;
+
+ co = qemu_coroutine_create(co_entry);
+ qemu_coroutine_enter(co, acb);
+
+ acb->has_returned = true;
+ if (acb->rwco.ret != NOT_DONE) {
+ acb->bh = aio_bh_new(blk_get_aio_context(blk), blk_aio_complete_bh, acb);
+ qemu_bh_schedule(acb->bh);
+ }
+
+ return &acb->common;
+}
+
+static void blk_aio_read_entry(void *opaque)
+{
+ BlkAioEmAIOCB *acb = opaque;
+ BlkRwCo *rwco = &acb->rwco;
+
+ rwco->ret = blk_co_preadv(rwco->blk, rwco->offset, rwco->qiov->size,
+ rwco->qiov, rwco->flags);
+ blk_aio_complete(acb);
+}
+
+static void blk_aio_write_entry(void *opaque)
+{
+ BlkAioEmAIOCB *acb = opaque;
+ BlkRwCo *rwco = &acb->rwco;
+
+ rwco->ret = blk_co_pwritev(rwco->blk, rwco->offset, rwco->qiov->size,
+ rwco->qiov, rwco->flags);
+ blk_aio_complete(acb);
+}
+
BlockAIOCB *blk_aio_write_zeroes(BlockBackend *blk, int64_t sector_num,
int nb_sectors, BdrvRequestFlags flags,
BlockCompletionFunc *cb, void *opaque)
{
- int ret = blk_check_request(blk, sector_num, nb_sectors);
- if (ret < 0) {
- return blk_abort_aio_request(blk, cb, opaque, ret);
+ if (nb_sectors < 0 || nb_sectors > BDRV_REQUEST_MAX_SECTORS) {
+ return blk_abort_aio_request(blk, cb, opaque, -EINVAL);
}
- return bdrv_aio_write_zeroes(blk_bs(blk), sector_num, nb_sectors, flags,
- cb, opaque);
+ return blk_aio_prwv(blk, sector_num << BDRV_SECTOR_BITS, NULL,
+ blk_aio_write_entry, BDRV_REQ_ZERO_WRITE, cb, opaque);
}
int blk_pread(BlockBackend *blk, int64_t offset, void *buf, int count)
@@ -921,24 +999,24 @@ BlockAIOCB *blk_aio_readv(BlockBackend *blk, int64_t sector_num,
QEMUIOVector *iov, int nb_sectors,
BlockCompletionFunc *cb, void *opaque)
{
- int ret = blk_check_request(blk, sector_num, nb_sectors);
- if (ret < 0) {
- return blk_abort_aio_request(blk, cb, opaque, ret);
+ if (nb_sectors < 0 || nb_sectors > BDRV_REQUEST_MAX_SECTORS) {
+ return blk_abort_aio_request(blk, cb, opaque, -EINVAL);
}
- return bdrv_aio_readv(blk_bs(blk), sector_num, iov, nb_sectors, cb, opaque);
+ return blk_aio_prwv(blk, sector_num << BDRV_SECTOR_BITS, iov,
+ blk_aio_read_entry, 0, cb, opaque);
}
BlockAIOCB *blk_aio_writev(BlockBackend *blk, int64_t sector_num,
QEMUIOVector *iov, int nb_sectors,
BlockCompletionFunc *cb, void *opaque)
{
- int ret = blk_check_request(blk, sector_num, nb_sectors);
- if (ret < 0) {
- return blk_abort_aio_request(blk, cb, opaque, ret);
+ if (nb_sectors < 0 || nb_sectors > BDRV_REQUEST_MAX_SECTORS) {
+ return blk_abort_aio_request(blk, cb, opaque, -EINVAL);
}
- return bdrv_aio_writev(blk_bs(blk), sector_num, iov, nb_sectors, cb, opaque);
+ return blk_aio_prwv(blk, sector_num << BDRV_SECTOR_BITS, iov,
+ blk_aio_write_entry, 0, cb, opaque);
}
BlockAIOCB *blk_aio_flush(BlockBackend *blk,
--
1.8.3.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Qemu-devel] [PATCH 8/8] block: Use blk_co_pwritev() in blk_co_write_zeroes()
2016-03-08 12:47 [Qemu-devel] [PATCH 0/8] block: Introduce common read/write function Kevin Wolf
` (6 preceding siblings ...)
2016-03-08 12:47 ` [Qemu-devel] [PATCH 7/8] block: Use blk_aio_prwv() for aio_read/write/write_zeroes Kevin Wolf
@ 2016-03-08 12:47 ` Kevin Wolf
2016-03-17 14:08 ` [Qemu-devel] [PATCH 0/8] block: Introduce common read/write function Kevin Wolf
2016-03-17 14:35 ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi
9 siblings, 0 replies; 11+ messages in thread
From: Kevin Wolf @ 2016-03-08 12:47 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, qemu-devel, stefanha, mreitz
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/block-backend.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/block/block-backend.c b/block/block-backend.c
index 2947e8c..1c2ea72 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -1465,12 +1465,13 @@ void *blk_aio_get(const AIOCBInfo *aiocb_info, BlockBackend *blk,
int coroutine_fn blk_co_write_zeroes(BlockBackend *blk, int64_t sector_num,
int nb_sectors, BdrvRequestFlags flags)
{
- int ret = blk_check_request(blk, sector_num, nb_sectors);
- if (ret < 0) {
- return ret;
+ if (nb_sectors < 0 || nb_sectors > BDRV_REQUEST_MAX_SECTORS) {
+ return -EINVAL;
}
- return bdrv_co_write_zeroes(blk_bs(blk), sector_num, nb_sectors, flags);
+ return blk_co_pwritev(blk, sector_num << BDRV_SECTOR_BITS,
+ nb_sectors << BDRV_SECTOR_BITS, NULL,
+ BDRV_REQ_ZERO_WRITE);
}
int blk_write_compressed(BlockBackend *blk, int64_t sector_num,
--
1.8.3.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [Qemu-devel] [PATCH 0/8] block: Introduce common read/write function
2016-03-08 12:47 [Qemu-devel] [PATCH 0/8] block: Introduce common read/write function Kevin Wolf
` (7 preceding siblings ...)
2016-03-08 12:47 ` [Qemu-devel] [PATCH 8/8] block: Use blk_co_pwritev() in blk_co_write_zeroes() Kevin Wolf
@ 2016-03-17 14:08 ` Kevin Wolf
2016-03-17 14:35 ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi
9 siblings, 0 replies; 11+ messages in thread
From: Kevin Wolf @ 2016-03-17 14:08 UTC (permalink / raw)
To: qemu-block; +Cc: qemu-devel, stefanha, mreitz
Am 08.03.2016 um 13:47 hat Kevin Wolf geschrieben:
> BlockBackends support a few different interfaces for reads and writes. Until
> now they used to forward the requests directly to the BDS layer, which
> implemented wrappers around one central common read/write function that
> contained the actual implementation of features provided by the block layer.
>
> This only works as long as none of the features are actually on the
> BlockBackend level. As it happens, we have features (writethrough cache, I/O
> throttling) that are currently implemented in the BDS, but must move to the BB.
>
> As a preparation, this series introduces the mapping of the existing APIs to a
> single coroutine based preadv/pwritev function (as we already have on the BDS
> level) to the BB layer. The BDS version of the emulation can't go away just yet
> because there are internal users of them, but the goal is to remove them in the
> long term.
>
> Depends on Max's "blockdev: Further BlockBackend work".
Applied to the block branch.
Kevin
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Qemu-devel] [Qemu-block] [PATCH 0/8] block: Introduce common read/write function
2016-03-08 12:47 [Qemu-devel] [PATCH 0/8] block: Introduce common read/write function Kevin Wolf
` (8 preceding siblings ...)
2016-03-17 14:08 ` [Qemu-devel] [PATCH 0/8] block: Introduce common read/write function Kevin Wolf
@ 2016-03-17 14:35 ` Stefan Hajnoczi
9 siblings, 0 replies; 11+ messages in thread
From: Stefan Hajnoczi @ 2016-03-17 14:35 UTC (permalink / raw)
To: Kevin Wolf; +Cc: stefanha, qemu-devel, qemu-block, mreitz
[-- Attachment #1: Type: text/plain, Size: 2008 bytes --]
On Tue, Mar 08, 2016 at 01:47:45PM +0100, Kevin Wolf wrote:
> BlockBackends support a few different interfaces for reads and writes. Until
> now they used to forward the requests directly to the BDS layer, which
> implemented wrappers around one central common read/write function that
> contained the actual implementation of features provided by the block layer.
>
> This only works as long as none of the features are actually on the
> BlockBackend level. As it happens, we have features (writethrough cache, I/O
> throttling) that are currently implemented in the BDS, but must move to the BB.
>
> As a preparation, this series introduces the mapping of the existing APIs to a
> single coroutine based preadv/pwritev function (as we already have on the BDS
> level) to the BB layer. The BDS version of the emulation can't go away just yet
> because there are internal users of them, but the goal is to remove them in the
> long term.
>
> Depends on Max's "blockdev: Further BlockBackend work".
>
> Kevin Wolf (8):
> block: Use BdrvChild in BlockBackend
> block: Use blk_co_preadv() for blk_read()
> block: Use blk_co_pwritev() for blk_write()
> block: Pull up blk_read_unthrottled() implementation
> block: Use blk_co_pwritev() in blk_write_zeroes()
> block: Use blk_prw() in blk_pread()/blk_pwrite()
> block: Use blk_aio_prwv() for aio_read/write/write_zeroes
> block: Use blk_co_pwritev() in blk_co_write_zeroes()
>
> block.c | 47 +++--
> block/block-backend.c | 485 +++++++++++++++++++++++++++++++++-------------
> block/io.c | 24 +--
> include/block/block.h | 2 -
> include/block/block_int.h | 12 ++
> 5 files changed, 401 insertions(+), 169 deletions(-)
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
This series conflicts with Paolo's "AioContext fine-grained locking,
part 1 of 3, including bdrv_drain rewrite".
We should merge both of them soon to prevent further conflicts.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2016-03-17 14:36 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-03-08 12:47 [Qemu-devel] [PATCH 0/8] block: Introduce common read/write function Kevin Wolf
2016-03-08 12:47 ` [Qemu-devel] [PATCH 1/8] block: Use BdrvChild in BlockBackend Kevin Wolf
2016-03-08 12:47 ` [Qemu-devel] [PATCH 2/8] block: Use blk_co_preadv() for blk_read() Kevin Wolf
2016-03-08 12:47 ` [Qemu-devel] [PATCH 3/8] block: Use blk_co_pwritev() for blk_write() Kevin Wolf
2016-03-08 12:47 ` [Qemu-devel] [PATCH 4/8] block: Pull up blk_read_unthrottled() implementation Kevin Wolf
2016-03-08 12:47 ` [Qemu-devel] [PATCH 5/8] block: Use blk_co_pwritev() in blk_write_zeroes() Kevin Wolf
2016-03-08 12:47 ` [Qemu-devel] [PATCH 6/8] block: Use blk_prw() in blk_pread()/blk_pwrite() Kevin Wolf
2016-03-08 12:47 ` [Qemu-devel] [PATCH 7/8] block: Use blk_aio_prwv() for aio_read/write/write_zeroes Kevin Wolf
2016-03-08 12:47 ` [Qemu-devel] [PATCH 8/8] block: Use blk_co_pwritev() in blk_co_write_zeroes() Kevin Wolf
2016-03-17 14:08 ` [Qemu-devel] [PATCH 0/8] block: Introduce common read/write function Kevin Wolf
2016-03-17 14:35 ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).