block: Convert bdrv_co_preadv/pwritev to BdrvChild

This is the final patch for converting the common I/O path to take
a BdrvChild parameter instead of BlockDriverState.

The completion of this conversion means that all users that perform I/O
on an image need to actually hold a reference (in the form of BdrvChild,
possible as part of a BlockBackend) to that image. This also protects
against inconsistent use of BlockBackend vs. BlockDriverState functions
because direct use of a BlockDriverState isn't possible any more and
blk->root is private for block-backends.c.

In addition, we can now distinguish different users in the I/O path,
and the future op blockers work is going to add assertions based on
permissions stored in BdrvChild.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Kevin Wolf 2016-06-20 21:31:46 +02:00
parent e293b7a3df
commit a03ef88f77
12 changed files with 38 additions and 37 deletions

View File

@ -85,7 +85,7 @@ static int coroutine_fn blkreplay_co_preadv(BlockDriverState *bs,
uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags) uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags)
{ {
uint64_t reqid = request_id++; uint64_t reqid = request_id++;
int ret = bdrv_co_preadv(bs->file->bs, offset, bytes, qiov, flags); int ret = bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
block_request_create(reqid, bs, qemu_coroutine_self()); block_request_create(reqid, bs, qemu_coroutine_self());
qemu_coroutine_yield(); qemu_coroutine_yield();
@ -96,7 +96,7 @@ static int coroutine_fn blkreplay_co_pwritev(BlockDriverState *bs,
uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags) uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags)
{ {
uint64_t reqid = request_id++; uint64_t reqid = request_id++;
int ret = bdrv_co_pwritev(bs->file->bs, offset, bytes, qiov, flags); int ret = bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
block_request_create(reqid, bs, qemu_coroutine_self()); block_request_create(reqid, bs, qemu_coroutine_self());
qemu_coroutine_yield(); qemu_coroutine_yield();
@ -107,7 +107,7 @@ static int coroutine_fn blkreplay_co_pwrite_zeroes(BlockDriverState *bs,
int64_t offset, int count, BdrvRequestFlags flags) int64_t offset, int count, BdrvRequestFlags flags)
{ {
uint64_t reqid = request_id++; uint64_t reqid = request_id++;
int ret = bdrv_co_pwrite_zeroes(bs->file->bs, offset, count, flags); int ret = bdrv_co_pwrite_zeroes(bs->file, offset, count, flags);
block_request_create(reqid, bs, qemu_coroutine_self()); block_request_create(reqid, bs, qemu_coroutine_self());
qemu_coroutine_yield(); qemu_coroutine_yield();

View File

@ -760,7 +760,7 @@ int coroutine_fn blk_co_preadv(BlockBackend *blk, int64_t offset,
throttle_group_co_io_limits_intercept(blk, bytes, false); throttle_group_co_io_limits_intercept(blk, bytes, false);
} }
return bdrv_co_preadv(blk_bs(blk), offset, bytes, qiov, flags); return bdrv_co_preadv(blk->root, offset, bytes, qiov, flags);
} }
int coroutine_fn blk_co_pwritev(BlockBackend *blk, int64_t offset, int coroutine_fn blk_co_pwritev(BlockBackend *blk, int64_t offset,
@ -785,7 +785,7 @@ int coroutine_fn blk_co_pwritev(BlockBackend *blk, int64_t offset,
flags |= BDRV_REQ_FUA; flags |= BDRV_REQ_FUA;
} }
return bdrv_co_pwritev(blk_bs(blk), offset, bytes, qiov, flags); return bdrv_co_pwritev(blk->root, offset, bytes, qiov, flags);
} }
typedef struct BlkRwCo { typedef struct BlkRwCo {

View File

@ -255,7 +255,7 @@ bochs_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
qemu_iovec_concat(&local_qiov, qiov, bytes_done, 512); qemu_iovec_concat(&local_qiov, qiov, bytes_done, 512);
if (block_offset > 0) { if (block_offset > 0) {
ret = bdrv_co_preadv(bs->file->bs, block_offset, 512, ret = bdrv_co_preadv(bs->file, block_offset, 512,
&local_qiov, 0); &local_qiov, 0);
if (ret < 0) { if (ret < 0) {
goto fail; goto fail;

View File

@ -566,11 +566,11 @@ static void coroutine_fn bdrv_rw_co_entry(void *opaque)
RwCo *rwco = opaque; RwCo *rwco = opaque;
if (!rwco->is_write) { if (!rwco->is_write) {
rwco->ret = bdrv_co_preadv(rwco->child->bs, rwco->offset, rwco->ret = bdrv_co_preadv(rwco->child, rwco->offset,
rwco->qiov->size, rwco->qiov, rwco->qiov->size, rwco->qiov,
rwco->flags); rwco->flags);
} else { } else {
rwco->ret = bdrv_co_pwritev(rwco->child->bs, rwco->offset, rwco->ret = bdrv_co_pwritev(rwco->child, rwco->offset,
rwco->qiov->size, rwco->qiov, rwco->qiov->size, rwco->qiov,
rwco->flags); rwco->flags);
} }
@ -1061,10 +1061,11 @@ out:
/* /*
* Handle a read request in coroutine context * Handle a read request in coroutine context
*/ */
int coroutine_fn bdrv_co_preadv(BlockDriverState *bs, int coroutine_fn bdrv_co_preadv(BdrvChild *child,
int64_t offset, unsigned int bytes, QEMUIOVector *qiov, int64_t offset, unsigned int bytes, QEMUIOVector *qiov,
BdrvRequestFlags flags) BdrvRequestFlags flags)
{ {
BlockDriverState *bs = child->bs;
BlockDriver *drv = bs->drv; BlockDriver *drv = bs->drv;
BdrvTrackedRequest req; BdrvTrackedRequest req;
@ -1137,7 +1138,7 @@ static int coroutine_fn bdrv_co_do_readv(BdrvChild *child,
return -EINVAL; return -EINVAL;
} }
return bdrv_co_preadv(child->bs, sector_num << BDRV_SECTOR_BITS, return bdrv_co_preadv(child, sector_num << BDRV_SECTOR_BITS,
nb_sectors << BDRV_SECTOR_BITS, qiov, flags); nb_sectors << BDRV_SECTOR_BITS, qiov, flags);
} }
@ -1406,10 +1407,11 @@ fail:
/* /*
* Handle a write request in coroutine context * Handle a write request in coroutine context
*/ */
int coroutine_fn bdrv_co_pwritev(BlockDriverState *bs, int coroutine_fn bdrv_co_pwritev(BdrvChild *child,
int64_t offset, unsigned int bytes, QEMUIOVector *qiov, int64_t offset, unsigned int bytes, QEMUIOVector *qiov,
BdrvRequestFlags flags) BdrvRequestFlags flags)
{ {
BlockDriverState *bs = child->bs;
BdrvTrackedRequest req; BdrvTrackedRequest req;
uint64_t align = bs->bl.request_alignment; uint64_t align = bs->bl.request_alignment;
uint8_t *head_buf = NULL; uint8_t *head_buf = NULL;
@ -1543,7 +1545,7 @@ static int coroutine_fn bdrv_co_do_writev(BdrvChild *child,
return -EINVAL; return -EINVAL;
} }
return bdrv_co_pwritev(child->bs, sector_num << BDRV_SECTOR_BITS, return bdrv_co_pwritev(child, sector_num << BDRV_SECTOR_BITS,
nb_sectors << BDRV_SECTOR_BITS, qiov, flags); nb_sectors << BDRV_SECTOR_BITS, qiov, flags);
} }
@ -1555,17 +1557,16 @@ int coroutine_fn bdrv_co_writev(BdrvChild *child, int64_t sector_num,
return bdrv_co_do_writev(child, sector_num, nb_sectors, qiov, 0); return bdrv_co_do_writev(child, sector_num, nb_sectors, qiov, 0);
} }
int coroutine_fn bdrv_co_pwrite_zeroes(BlockDriverState *bs, int coroutine_fn bdrv_co_pwrite_zeroes(BdrvChild *child, int64_t offset,
int64_t offset, int count, int count, BdrvRequestFlags flags)
BdrvRequestFlags flags)
{ {
trace_bdrv_co_pwrite_zeroes(bs, offset, count, flags); trace_bdrv_co_pwrite_zeroes(child->bs, offset, count, flags);
if (!(bs->open_flags & BDRV_O_UNMAP)) { if (!(child->bs->open_flags & BDRV_O_UNMAP)) {
flags &= ~BDRV_REQ_MAY_UNMAP; flags &= ~BDRV_REQ_MAY_UNMAP;
} }
return bdrv_co_pwritev(bs, offset, count, NULL, return bdrv_co_pwritev(child, offset, count, NULL,
BDRV_REQ_ZERO_WRITE | flags); BDRV_REQ_ZERO_WRITE | flags);
} }

View File

@ -446,7 +446,7 @@ static int coroutine_fn do_perform_cow(BlockDriverState *bs,
} }
BLKDBG_EVENT(bs->file, BLKDBG_COW_WRITE); BLKDBG_EVENT(bs->file, BLKDBG_COW_WRITE);
ret = bdrv_co_pwritev(bs->file->bs, cluster_offset + offset_in_cluster, ret = bdrv_co_pwritev(bs->file, cluster_offset + offset_in_cluster,
bytes, &qiov, 0); bytes, &qiov, 0);
if (ret < 0) { if (ret < 0) {
goto out; goto out;

View File

@ -1443,7 +1443,7 @@ static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t offset,
BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO); BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
qemu_co_mutex_unlock(&s->lock); qemu_co_mutex_unlock(&s->lock);
ret = bdrv_co_preadv(bs->backing->bs, offset, n1, ret = bdrv_co_preadv(bs->backing, offset, n1,
&local_qiov, 0); &local_qiov, 0);
qemu_co_mutex_lock(&s->lock); qemu_co_mutex_lock(&s->lock);
@ -1506,7 +1506,7 @@ static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t offset,
BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO); BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
qemu_co_mutex_unlock(&s->lock); qemu_co_mutex_unlock(&s->lock);
ret = bdrv_co_preadv(bs->file->bs, ret = bdrv_co_preadv(bs->file,
cluster_offset + offset_in_cluster, cluster_offset + offset_in_cluster,
cur_bytes, &hd_qiov, 0); cur_bytes, &hd_qiov, 0);
qemu_co_mutex_lock(&s->lock); qemu_co_mutex_lock(&s->lock);
@ -1637,7 +1637,7 @@ static coroutine_fn int qcow2_co_pwritev(BlockDriverState *bs, uint64_t offset,
BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO); BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
trace_qcow2_writev_data(qemu_coroutine_self(), trace_qcow2_writev_data(qemu_coroutine_self(),
cluster_offset + offset_in_cluster); cluster_offset + offset_in_cluster);
ret = bdrv_co_pwritev(bs->file->bs, ret = bdrv_co_pwritev(bs->file,
cluster_offset + offset_in_cluster, cluster_offset + offset_in_cluster,
cur_bytes, &hd_qiov, 0); cur_bytes, &hd_qiov, 0);
qemu_co_mutex_lock(&s->lock); qemu_co_mutex_lock(&s->lock);

View File

@ -105,7 +105,7 @@ raw_co_writev_flags(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
} }
BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO); BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
ret = bdrv_co_pwritev(bs->file->bs, sector_num * BDRV_SECTOR_SIZE, ret = bdrv_co_pwritev(bs->file, sector_num * BDRV_SECTOR_SIZE,
nb_sectors * BDRV_SECTOR_SIZE, qiov, flags); nb_sectors * BDRV_SECTOR_SIZE, qiov, flags);
fail: fail:
@ -131,7 +131,7 @@ static int coroutine_fn raw_co_pwrite_zeroes(BlockDriverState *bs,
int64_t offset, int count, int64_t offset, int count,
BdrvRequestFlags flags) BdrvRequestFlags flags)
{ {
return bdrv_co_pwrite_zeroes(bs->file->bs, offset, count, flags); return bdrv_co_pwrite_zeroes(bs->file, offset, count, flags);
} }
static int coroutine_fn raw_co_discard(BlockDriverState *bs, static int coroutine_fn raw_co_discard(BlockDriverState *bs,

View File

@ -597,7 +597,7 @@ vdi_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
qemu_iovec_reset(&local_qiov); qemu_iovec_reset(&local_qiov);
qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes); qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes);
ret = bdrv_co_preadv(bs->file->bs, data_offset, n_bytes, ret = bdrv_co_preadv(bs->file, data_offset, n_bytes,
&local_qiov, 0); &local_qiov, 0);
} }
logout("%u bytes read\n", n_bytes); logout("%u bytes read\n", n_bytes);
@ -690,7 +690,7 @@ vdi_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
qemu_iovec_reset(&local_qiov); qemu_iovec_reset(&local_qiov);
qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes); qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes);
ret = bdrv_co_pwritev(bs->file->bs, data_offset, n_bytes, ret = bdrv_co_pwritev(bs->file, data_offset, n_bytes,
&local_qiov, 0); &local_qiov, 0);
} }

View File

@ -1369,7 +1369,7 @@ static int vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset,
} }
write_offset = cluster_offset + offset_in_cluster, write_offset = cluster_offset + offset_in_cluster,
ret = bdrv_co_pwritev(extent->file->bs, write_offset, n_bytes, ret = bdrv_co_pwritev(extent->file, write_offset, n_bytes,
&local_qiov, 0); &local_qiov, 0);
write_end_sector = DIV_ROUND_UP(write_offset + n_bytes, BDRV_SECTOR_SIZE); write_end_sector = DIV_ROUND_UP(write_offset + n_bytes, BDRV_SECTOR_SIZE);
@ -1407,7 +1407,7 @@ static int vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset,
if (!extent->compressed) { if (!extent->compressed) {
ret = bdrv_co_preadv(extent->file->bs, ret = bdrv_co_preadv(extent->file,
cluster_offset + offset_in_cluster, bytes, cluster_offset + offset_in_cluster, bytes,
qiov, 0); qiov, 0);
if (ret < 0) { if (ret < 0) {
@ -1497,7 +1497,7 @@ vmdk_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
qemu_iovec_reset(&local_qiov); qemu_iovec_reset(&local_qiov);
qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes); qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes);
ret = bdrv_co_preadv(bs->backing->bs, offset, n_bytes, ret = bdrv_co_preadv(bs->backing, offset, n_bytes,
&local_qiov, 0); &local_qiov, 0);
if (ret < 0) { if (ret < 0) {
goto fail; goto fail;

View File

@ -591,7 +591,7 @@ vpc_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
QEMUIOVector local_qiov; QEMUIOVector local_qiov;
if (be32_to_cpu(footer->type) == VHD_FIXED) { if (be32_to_cpu(footer->type) == VHD_FIXED) {
return bdrv_co_preadv(bs->file->bs, offset, bytes, qiov, 0); return bdrv_co_preadv(bs->file, offset, bytes, qiov, 0);
} }
qemu_co_mutex_lock(&s->lock); qemu_co_mutex_lock(&s->lock);
@ -607,7 +607,7 @@ vpc_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
qemu_iovec_reset(&local_qiov); qemu_iovec_reset(&local_qiov);
qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes); qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes);
ret = bdrv_co_preadv(bs->file->bs, image_offset, n_bytes, ret = bdrv_co_preadv(bs->file, image_offset, n_bytes,
&local_qiov, 0); &local_qiov, 0);
if (ret < 0) { if (ret < 0) {
goto fail; goto fail;
@ -640,7 +640,7 @@ vpc_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
QEMUIOVector local_qiov; QEMUIOVector local_qiov;
if (be32_to_cpu(footer->type) == VHD_FIXED) { if (be32_to_cpu(footer->type) == VHD_FIXED) {
return bdrv_co_pwritev(bs->file->bs, offset, bytes, qiov, 0); return bdrv_co_pwritev(bs->file, offset, bytes, qiov, 0);
} }
qemu_co_mutex_lock(&s->lock); qemu_co_mutex_lock(&s->lock);
@ -661,7 +661,7 @@ vpc_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
qemu_iovec_reset(&local_qiov); qemu_iovec_reset(&local_qiov);
qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes); qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes);
ret = bdrv_co_pwritev(bs->file->bs, image_offset, n_bytes, ret = bdrv_co_pwritev(bs->file, image_offset, n_bytes,
&local_qiov, 0); &local_qiov, 0);
if (ret < 0) { if (ret < 0) {
goto fail; goto fail;

View File

@ -249,8 +249,8 @@ int coroutine_fn bdrv_co_writev(BdrvChild *child, int64_t sector_num,
* function is not suitable for zeroing the entire image in a single request * function is not suitable for zeroing the entire image in a single request
* because it may allocate memory for the entire region. * because it may allocate memory for the entire region.
*/ */
int coroutine_fn bdrv_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int coroutine_fn bdrv_co_pwrite_zeroes(BdrvChild *child, int64_t offset,
int count, BdrvRequestFlags flags); int count, BdrvRequestFlags flags);
BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs, BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
const char *backing_file); const char *backing_file);
int bdrv_get_backing_file_depth(BlockDriverState *bs); int bdrv_get_backing_file_depth(BlockDriverState *bs);

View File

@ -563,10 +563,10 @@ extern BlockDriver bdrv_qcow2;
*/ */
void bdrv_setup_io_funcs(BlockDriver *bdrv); void bdrv_setup_io_funcs(BlockDriver *bdrv);
int coroutine_fn bdrv_co_preadv(BlockDriverState *bs, int coroutine_fn bdrv_co_preadv(BdrvChild *child,
int64_t offset, unsigned int bytes, QEMUIOVector *qiov, int64_t offset, unsigned int bytes, QEMUIOVector *qiov,
BdrvRequestFlags flags); BdrvRequestFlags flags);
int coroutine_fn bdrv_co_pwritev(BlockDriverState *bs, int coroutine_fn bdrv_co_pwritev(BdrvChild *child,
int64_t offset, unsigned int bytes, QEMUIOVector *qiov, int64_t offset, unsigned int bytes, QEMUIOVector *qiov,
BdrvRequestFlags flags); BdrvRequestFlags flags);