mirror of https://github.com/xemu-project/xemu.git
Block layer patches
- Lock the graph, part 2 (BlockDriver callbacks) - virtio-scsi: fix SCSIDevice hot unplug with IOThread - rbd: Add support for layered encryption -----BEGIN PGP SIGNATURE----- iQJFBAABCAAvFiEE3D3rFZqa+V09dFb+fwmycsiPL9YFAmP3tUURHGt3b2xmQHJl ZGhhdC5jb20ACgkQfwmycsiPL9ZQkA/9HFBrcsfSyzU5sHXcpqrcVPsvFwwzhsXN V6zMvBXQVEMYo6oDBSyNrniOJSYjiFLm1c+bMAaAFbo8dvVqqlkecBuZgQkFjnCy vXyaYeWnBSG5A91Vs30qzLObBsrX7P1Gh+bvtRvBPThC1zd8lrxMbVzlsxnTfDFo DsPkgiXL0SZ6YLBN5s61GBCfjvF8i0/8TPAvvwhHEo15sBgcBSTFYSftzEe9TXmH NHAuHnRshrd9DNnf20tVPuHCanSTsIpbx5cLYBoy81vSbjqJG4agULZLltKP3fiM kadpqmhJwjq+KhioLmcIjevPnUuqOMEzubaxZUm9o8jjsFPa8Isv4sIaAxyUP6e6 aze1Xh9vUXn/JEf2/hApUY+2rz5dREL/TqpFwyzZjdqJb8PVCuy1JA1m2zLkvRPd Bl9pS7kabhcZOHrITnJS7Lvyy4IWeiw78trtaer0nCbKbPdQB62eswSXKYh5g+Ke kVJbkRSNi6lnljK5egIR3VxxM5kbGZsY4aGuyZk3Lc5yeAuPOil9swHlSO+5LFxP lRZOyumHbfKU6J7JbGFErrqR2fZiqKUN/6i0HZAIcjpZq1QxXlmHBbmrkXao+j5Y 0WcHdduH65dHT8fnBMgDZCXUfV7iBufspkCmY1v50YNJRPNmDzb4Os/Jh9qLHHMQ M1ae+58T0Fo= =gOli -----END PGP SIGNATURE----- Merge tag 'for-upstream' of https://repo.or.cz/qemu/kevin into staging Block layer patches - Lock the graph, part 2 (BlockDriver callbacks) - virtio-scsi: fix SCSIDevice hot unplug with IOThread - rbd: Add support for layered encryption # -----BEGIN PGP SIGNATURE----- # # iQJFBAABCAAvFiEE3D3rFZqa+V09dFb+fwmycsiPL9YFAmP3tUURHGt3b2xmQHJl # ZGhhdC5jb20ACgkQfwmycsiPL9ZQkA/9HFBrcsfSyzU5sHXcpqrcVPsvFwwzhsXN # V6zMvBXQVEMYo6oDBSyNrniOJSYjiFLm1c+bMAaAFbo8dvVqqlkecBuZgQkFjnCy # vXyaYeWnBSG5A91Vs30qzLObBsrX7P1Gh+bvtRvBPThC1zd8lrxMbVzlsxnTfDFo # DsPkgiXL0SZ6YLBN5s61GBCfjvF8i0/8TPAvvwhHEo15sBgcBSTFYSftzEe9TXmH # NHAuHnRshrd9DNnf20tVPuHCanSTsIpbx5cLYBoy81vSbjqJG4agULZLltKP3fiM # kadpqmhJwjq+KhioLmcIjevPnUuqOMEzubaxZUm9o8jjsFPa8Isv4sIaAxyUP6e6 # aze1Xh9vUXn/JEf2/hApUY+2rz5dREL/TqpFwyzZjdqJb8PVCuy1JA1m2zLkvRPd # Bl9pS7kabhcZOHrITnJS7Lvyy4IWeiw78trtaer0nCbKbPdQB62eswSXKYh5g+Ke # kVJbkRSNi6lnljK5egIR3VxxM5kbGZsY4aGuyZk3Lc5yeAuPOil9swHlSO+5LFxP # lRZOyumHbfKU6J7JbGFErrqR2fZiqKUN/6i0HZAIcjpZq1QxXlmHBbmrkXao+j5Y # 0WcHdduH65dHT8fnBMgDZCXUfV7iBufspkCmY1v50YNJRPNmDzb4Os/Jh9qLHHMQ # M1ae+58T0Fo= # =gOli # -----END PGP SIGNATURE----- # gpg: Signature made Thu 23 Feb 2023 18:49:41 GMT # gpg: using RSA key DC3DEB159A9AF95D3D7456FE7F09B272C88F2FD6 # gpg: issuer "kwolf@redhat.com" # gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" [full] # Primary key fingerprint: DC3D EB15 9A9A F95D 3D74 56FE 7F09 B272 C88F 2FD6 * tag 'for-upstream' of https://repo.or.cz/qemu/kevin: (29 commits) block/rbd: Add support for layered encryption block/rbd: Add luks-any encryption opening option block/rbd: Remove redundant stack variable passphrase_len virtio-scsi: reset SCSI devices from main loop thread dma-helpers: prevent dma_blk_cb() vs dma_aio_cancel() race scsi: protect req->aiocb with AioContext lock block: Mark bdrv_co_refresh_total_sectors() and callers GRAPH_RDLOCK block: Mark bdrv_*_dirty_bitmap() and callers GRAPH_RDLOCK block: Mark bdrv_co_delete_file() and callers GRAPH_RDLOCK block: Mark bdrv_(un)register_buf() GRAPH_RDLOCK block: Mark bdrv_co_eject/lock_medium() and callers GRAPH_RDLOCK block: Mark bdrv_co_is_inserted() and callers GRAPH_RDLOCK block: Mark bdrv_co_io_(un)plug() and callers GRAPH_RDLOCK block: Mark bdrv_co_create() and callers GRAPH_RDLOCK block: Mark preadv_snapshot/snapshot_block_status GRAPH_RDLOCK block: Mark bdrv_co_copy_range() GRAPH_RDLOCK block: Mark bdrv_co_do_pwrite_zeroes() GRAPH_RDLOCK block: Mark bdrv_co_pwrite_sync() and callers GRAPH_RDLOCK block: Mark public read/write functions GRAPH_RDLOCK block: Mark read/write in block/io.c GRAPH_RDLOCK ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
1270a3f57c
10
block.c
10
block.c
|
@ -277,7 +277,7 @@ bool bdrv_is_read_only(BlockDriverState *bs)
|
||||||
return !(bs->open_flags & BDRV_O_RDWR);
|
return !(bs->open_flags & BDRV_O_RDWR);
|
||||||
}
|
}
|
||||||
|
|
||||||
int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
|
static int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
|
||||||
bool ignore_allow_rdw, Error **errp)
|
bool ignore_allow_rdw, Error **errp)
|
||||||
{
|
{
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
@ -533,6 +533,7 @@ int coroutine_fn bdrv_co_create(BlockDriver *drv, const char *filename,
|
||||||
int ret;
|
int ret;
|
||||||
GLOBAL_STATE_CODE();
|
GLOBAL_STATE_CODE();
|
||||||
ERRP_GUARD();
|
ERRP_GUARD();
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
|
|
||||||
if (!drv->bdrv_co_create_opts) {
|
if (!drv->bdrv_co_create_opts) {
|
||||||
error_setg(errp, "Driver '%s' does not support image creation",
|
error_setg(errp, "Driver '%s' does not support image creation",
|
||||||
|
@ -739,6 +740,7 @@ int coroutine_fn bdrv_co_delete_file(BlockDriverState *bs, Error **errp)
|
||||||
|
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
assert(bs != NULL);
|
assert(bs != NULL);
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
|
|
||||||
if (!bs->drv) {
|
if (!bs->drv) {
|
||||||
error_setg(errp, "Block node '%s' is not opened", bs->filename);
|
error_setg(errp, "Block node '%s' is not opened", bs->filename);
|
||||||
|
@ -1040,6 +1042,7 @@ int coroutine_fn bdrv_co_refresh_total_sectors(BlockDriverState *bs,
|
||||||
{
|
{
|
||||||
BlockDriver *drv = bs->drv;
|
BlockDriver *drv = bs->drv;
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
|
|
||||||
if (!drv) {
|
if (!drv) {
|
||||||
return -ENOMEDIUM;
|
return -ENOMEDIUM;
|
||||||
|
@ -5841,6 +5844,7 @@ int64_t coroutine_fn bdrv_co_nb_sectors(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
BlockDriver *drv = bs->drv;
|
BlockDriver *drv = bs->drv;
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
|
|
||||||
if (!drv)
|
if (!drv)
|
||||||
return -ENOMEDIUM;
|
return -ENOMEDIUM;
|
||||||
|
@ -5862,6 +5866,7 @@ int64_t coroutine_fn bdrv_co_getlength(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
int64_t ret;
|
int64_t ret;
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
|
|
||||||
ret = bdrv_co_nb_sectors(bs);
|
ret = bdrv_co_nb_sectors(bs);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -6825,6 +6830,7 @@ bool coroutine_fn bdrv_co_is_inserted(BlockDriverState *bs)
|
||||||
BlockDriver *drv = bs->drv;
|
BlockDriver *drv = bs->drv;
|
||||||
BdrvChild *child;
|
BdrvChild *child;
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
|
|
||||||
if (!drv) {
|
if (!drv) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -6847,6 +6853,7 @@ void coroutine_fn bdrv_co_eject(BlockDriverState *bs, bool eject_flag)
|
||||||
{
|
{
|
||||||
BlockDriver *drv = bs->drv;
|
BlockDriver *drv = bs->drv;
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
|
|
||||||
if (drv && drv->bdrv_co_eject) {
|
if (drv && drv->bdrv_co_eject) {
|
||||||
drv->bdrv_co_eject(bs, eject_flag);
|
drv->bdrv_co_eject(bs, eject_flag);
|
||||||
|
@ -6861,6 +6868,7 @@ void coroutine_fn bdrv_co_lock_medium(BlockDriverState *bs, bool locked)
|
||||||
{
|
{
|
||||||
BlockDriver *drv = bs->drv;
|
BlockDriver *drv = bs->drv;
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
trace_bdrv_lock_medium(bs, locked);
|
trace_bdrv_lock_medium(bs, locked);
|
||||||
|
|
||||||
if (drv && drv->bdrv_co_lock_medium) {
|
if (drv && drv->bdrv_co_lock_medium) {
|
||||||
|
|
|
@ -269,7 +269,10 @@ static int coroutine_fn backup_run(Job *job, Error **errp)
|
||||||
return -ECANCELED;
|
return -ECANCELED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* rdlock protects the subsequent call to bdrv_is_allocated() */
|
||||||
|
bdrv_graph_co_rdlock();
|
||||||
ret = block_copy_reset_unallocated(s->bcs, offset, &count);
|
ret = block_copy_reset_unallocated(s->bcs, offset, &count);
|
||||||
|
bdrv_graph_co_rdunlock();
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -626,7 +626,7 @@ static int rule_check(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
|
||||||
return -error;
|
return -error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
blkdebug_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
blkdebug_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
|
@ -647,7 +647,7 @@ blkdebug_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
|
return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
blkdebug_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
blkdebug_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
|
@ -668,7 +668,7 @@ blkdebug_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
|
return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn blkdebug_co_flush(BlockDriverState *bs)
|
static int GRAPH_RDLOCK coroutine_fn blkdebug_co_flush(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
int err = rule_check(bs, 0, 0, BLKDEBUG_IO_TYPE_FLUSH);
|
int err = rule_check(bs, 0, 0, BLKDEBUG_IO_TYPE_FLUSH);
|
||||||
|
|
||||||
|
@ -679,8 +679,8 @@ static int coroutine_fn blkdebug_co_flush(BlockDriverState *bs)
|
||||||
return bdrv_co_flush(bs->file->bs);
|
return bdrv_co_flush(bs->file->bs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn blkdebug_co_pwrite_zeroes(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes,
|
blkdebug_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
BdrvRequestFlags flags)
|
BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
uint32_t align = MAX(bs->bl.request_alignment,
|
uint32_t align = MAX(bs->bl.request_alignment,
|
||||||
|
@ -712,8 +712,8 @@ static int coroutine_fn blkdebug_co_pwrite_zeroes(BlockDriverState *bs,
|
||||||
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
|
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn blkdebug_co_pdiscard(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes)
|
blkdebug_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
|
||||||
{
|
{
|
||||||
uint32_t align = bs->bl.pdiscard_alignment;
|
uint32_t align = bs->bl.pdiscard_alignment;
|
||||||
int err;
|
int err;
|
||||||
|
@ -967,7 +967,8 @@ static bool blkdebug_debug_is_suspended(BlockDriverState *bs, const char *tag)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int64_t coroutine_fn blkdebug_co_getlength(BlockDriverState *bs)
|
static int64_t coroutine_fn GRAPH_RDLOCK
|
||||||
|
blkdebug_co_getlength(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
return bdrv_co_getlength(bs->file->bs);
|
return bdrv_co_getlength(bs->file->bs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -267,7 +267,8 @@ static void blk_log_writes_close(BlockDriverState *bs)
|
||||||
s->log_file = NULL;
|
s->log_file = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int64_t coroutine_fn blk_log_writes_co_getlength(BlockDriverState *bs)
|
static int64_t coroutine_fn GRAPH_RDLOCK
|
||||||
|
blk_log_writes_co_getlength(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
return bdrv_co_getlength(bs->file->bs);
|
return bdrv_co_getlength(bs->file->bs);
|
||||||
}
|
}
|
||||||
|
@ -294,7 +295,7 @@ static void blk_log_writes_refresh_limits(BlockDriverState *bs, Error **errp)
|
||||||
bs->bl.request_alignment = s->sectorsize;
|
bs->bl.request_alignment = s->sectorsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
blk_log_writes_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
blk_log_writes_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
|
@ -307,7 +308,7 @@ typedef struct BlkLogWritesFileReq {
|
||||||
uint64_t bytes;
|
uint64_t bytes;
|
||||||
int file_flags;
|
int file_flags;
|
||||||
QEMUIOVector *qiov;
|
QEMUIOVector *qiov;
|
||||||
int (*func)(struct BlkLogWritesFileReq *r);
|
int GRAPH_RDLOCK_PTR (*func)(struct BlkLogWritesFileReq *r);
|
||||||
int file_ret;
|
int file_ret;
|
||||||
} BlkLogWritesFileReq;
|
} BlkLogWritesFileReq;
|
||||||
|
|
||||||
|
@ -319,7 +320,8 @@ typedef struct {
|
||||||
int log_ret;
|
int log_ret;
|
||||||
} BlkLogWritesLogReq;
|
} BlkLogWritesLogReq;
|
||||||
|
|
||||||
static void coroutine_fn blk_log_writes_co_do_log(BlkLogWritesLogReq *lr)
|
static void coroutine_fn GRAPH_RDLOCK
|
||||||
|
blk_log_writes_co_do_log(BlkLogWritesLogReq *lr)
|
||||||
{
|
{
|
||||||
BDRVBlkLogWritesState *s = lr->bs->opaque;
|
BDRVBlkLogWritesState *s = lr->bs->opaque;
|
||||||
uint64_t cur_log_offset = s->cur_log_sector << s->sectorbits;
|
uint64_t cur_log_offset = s->cur_log_sector << s->sectorbits;
|
||||||
|
@ -368,15 +370,16 @@ static void coroutine_fn blk_log_writes_co_do_log(BlkLogWritesLogReq *lr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void coroutine_fn blk_log_writes_co_do_file(BlkLogWritesFileReq *fr)
|
static void coroutine_fn GRAPH_RDLOCK
|
||||||
|
blk_log_writes_co_do_file(BlkLogWritesFileReq *fr)
|
||||||
{
|
{
|
||||||
fr->file_ret = fr->func(fr);
|
fr->file_ret = fr->func(fr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
blk_log_writes_co_log(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
|
blk_log_writes_co_log(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
|
||||||
QEMUIOVector *qiov, int flags,
|
QEMUIOVector *qiov, int flags,
|
||||||
int (*file_func)(BlkLogWritesFileReq *r),
|
int /*GRAPH_RDLOCK*/ (*file_func)(BlkLogWritesFileReq *r),
|
||||||
uint64_t entry_flags, bool is_zero_write)
|
uint64_t entry_flags, bool is_zero_write)
|
||||||
{
|
{
|
||||||
QEMUIOVector log_qiov;
|
QEMUIOVector log_qiov;
|
||||||
|
@ -428,32 +431,33 @@ blk_log_writes_co_log(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
|
||||||
return fr.file_ret;
|
return fr.file_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
blk_log_writes_co_do_file_pwritev(BlkLogWritesFileReq *fr)
|
blk_log_writes_co_do_file_pwritev(BlkLogWritesFileReq *fr)
|
||||||
{
|
{
|
||||||
return bdrv_co_pwritev(fr->bs->file, fr->offset, fr->bytes,
|
return bdrv_co_pwritev(fr->bs->file, fr->offset, fr->bytes,
|
||||||
fr->qiov, fr->file_flags);
|
fr->qiov, fr->file_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
blk_log_writes_co_do_file_pwrite_zeroes(BlkLogWritesFileReq *fr)
|
blk_log_writes_co_do_file_pwrite_zeroes(BlkLogWritesFileReq *fr)
|
||||||
{
|
{
|
||||||
return bdrv_co_pwrite_zeroes(fr->bs->file, fr->offset, fr->bytes,
|
return bdrv_co_pwrite_zeroes(fr->bs->file, fr->offset, fr->bytes,
|
||||||
fr->file_flags);
|
fr->file_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn blk_log_writes_co_do_file_flush(BlkLogWritesFileReq *fr)
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
|
blk_log_writes_co_do_file_flush(BlkLogWritesFileReq *fr)
|
||||||
{
|
{
|
||||||
return bdrv_co_flush(fr->bs->file->bs);
|
return bdrv_co_flush(fr->bs->file->bs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
blk_log_writes_co_do_file_pdiscard(BlkLogWritesFileReq *fr)
|
blk_log_writes_co_do_file_pdiscard(BlkLogWritesFileReq *fr)
|
||||||
{
|
{
|
||||||
return bdrv_co_pdiscard(fr->bs->file, fr->offset, fr->bytes);
|
return bdrv_co_pdiscard(fr->bs->file, fr->offset, fr->bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
blk_log_writes_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
blk_log_writes_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
|
@ -461,7 +465,7 @@ blk_log_writes_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
blk_log_writes_co_do_file_pwritev, 0, false);
|
blk_log_writes_co_do_file_pwritev, 0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
blk_log_writes_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
|
blk_log_writes_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
|
||||||
int64_t bytes, BdrvRequestFlags flags)
|
int64_t bytes, BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
|
@ -470,14 +474,15 @@ blk_log_writes_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn blk_log_writes_co_flush_to_disk(BlockDriverState *bs)
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
|
blk_log_writes_co_flush_to_disk(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
return blk_log_writes_co_log(bs, 0, 0, NULL, 0,
|
return blk_log_writes_co_log(bs, 0, 0, NULL, 0,
|
||||||
blk_log_writes_co_do_file_flush,
|
blk_log_writes_co_do_file_flush,
|
||||||
LOG_FLUSH_FLAG, false);
|
LOG_FLUSH_FLAG, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
blk_log_writes_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
|
blk_log_writes_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
|
||||||
{
|
{
|
||||||
return blk_log_writes_co_log(bs, offset, bytes, NULL, 0,
|
return blk_log_writes_co_log(bs, offset, bytes, NULL, 0,
|
||||||
|
|
|
@ -40,7 +40,8 @@ fail:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int64_t coroutine_fn blkreplay_co_getlength(BlockDriverState *bs)
|
static int64_t coroutine_fn GRAPH_RDLOCK
|
||||||
|
blkreplay_co_getlength(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
return bdrv_co_getlength(bs->file->bs);
|
return bdrv_co_getlength(bs->file->bs);
|
||||||
}
|
}
|
||||||
|
@ -69,8 +70,9 @@ static void block_request_create(uint64_t reqid, BlockDriverState *bs,
|
||||||
replay_block_event(req->bh, reqid);
|
replay_block_event(req->bh, reqid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn blkreplay_co_preadv(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes, QEMUIOVector *qiov, BdrvRequestFlags flags)
|
blkreplay_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
|
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
uint64_t reqid = blkreplay_next_id();
|
uint64_t reqid = blkreplay_next_id();
|
||||||
int ret = bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
|
int ret = bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
|
||||||
|
@ -80,8 +82,9 @@ static int coroutine_fn blkreplay_co_preadv(BlockDriverState *bs,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn blkreplay_co_pwritev(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes, QEMUIOVector *qiov, BdrvRequestFlags flags)
|
blkreplay_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
|
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
uint64_t reqid = blkreplay_next_id();
|
uint64_t reqid = blkreplay_next_id();
|
||||||
int ret = bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
|
int ret = bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
|
||||||
|
@ -91,8 +94,9 @@ static int coroutine_fn blkreplay_co_pwritev(BlockDriverState *bs,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn blkreplay_co_pwrite_zeroes(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes, BdrvRequestFlags flags)
|
blkreplay_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
|
BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
uint64_t reqid = blkreplay_next_id();
|
uint64_t reqid = blkreplay_next_id();
|
||||||
int ret = bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
|
int ret = bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
|
||||||
|
@ -102,8 +106,8 @@ static int coroutine_fn blkreplay_co_pwrite_zeroes(BlockDriverState *bs,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn blkreplay_co_pdiscard(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes)
|
blkreplay_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
|
||||||
{
|
{
|
||||||
uint64_t reqid = blkreplay_next_id();
|
uint64_t reqid = blkreplay_next_id();
|
||||||
int ret = bdrv_co_pdiscard(bs->file, offset, bytes);
|
int ret = bdrv_co_pdiscard(bs->file, offset, bytes);
|
||||||
|
@ -113,7 +117,7 @@ static int coroutine_fn blkreplay_co_pdiscard(BlockDriverState *bs,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn blkreplay_co_flush(BlockDriverState *bs)
|
static int coroutine_fn GRAPH_RDLOCK blkreplay_co_flush(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
uint64_t reqid = blkreplay_next_id();
|
uint64_t reqid = blkreplay_next_id();
|
||||||
int ret = bdrv_co_flush(bs->file->bs);
|
int ret = bdrv_co_flush(bs->file->bs);
|
||||||
|
|
|
@ -155,7 +155,8 @@ static void blkverify_close(BlockDriverState *bs)
|
||||||
s->test_file = NULL;
|
s->test_file = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int64_t coroutine_fn blkverify_co_getlength(BlockDriverState *bs)
|
static int64_t coroutine_fn GRAPH_RDLOCK
|
||||||
|
blkverify_co_getlength(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
BDRVBlkverifyState *s = bs->opaque;
|
BDRVBlkverifyState *s = bs->opaque;
|
||||||
|
|
||||||
|
@ -256,7 +257,7 @@ blkverify_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
return blkverify_co_prwv(bs, &r, offset, bytes, qiov, qiov, flags, true);
|
return blkverify_co_prwv(bs, &r, offset, bytes, qiov, qiov, flags, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn blkverify_co_flush(BlockDriverState *bs)
|
static int coroutine_fn GRAPH_RDLOCK blkverify_co_flush(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
BDRVBlkverifyState *s = bs->opaque;
|
BDRVBlkverifyState *s = bs->opaque;
|
||||||
|
|
||||||
|
|
|
@ -1235,8 +1235,8 @@ void blk_set_disable_request_queuing(BlockBackend *blk, bool disable)
|
||||||
blk->disable_request_queuing = disable;
|
blk->disable_request_queuing = disable;
|
||||||
}
|
}
|
||||||
|
|
||||||
static coroutine_fn int blk_check_byte_request(BlockBackend *blk,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes)
|
blk_check_byte_request(BlockBackend *blk, int64_t offset, int64_t bytes)
|
||||||
{
|
{
|
||||||
int64_t len;
|
int64_t len;
|
||||||
|
|
||||||
|
@ -1244,7 +1244,7 @@ static coroutine_fn int blk_check_byte_request(BlockBackend *blk,
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!blk_is_available(blk)) {
|
if (!blk_co_is_available(blk)) {
|
||||||
return -ENOMEDIUM;
|
return -ENOMEDIUM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1289,6 +1289,7 @@ blk_co_do_preadv_part(BlockBackend *blk, int64_t offset, int64_t bytes,
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
|
||||||
blk_wait_while_drained(blk);
|
blk_wait_while_drained(blk);
|
||||||
|
GRAPH_RDLOCK_GUARD();
|
||||||
|
|
||||||
/* Call blk_bs() only after waiting, the graph may have changed */
|
/* Call blk_bs() only after waiting, the graph may have changed */
|
||||||
bs = blk_bs(blk);
|
bs = blk_bs(blk);
|
||||||
|
@ -1363,6 +1364,7 @@ blk_co_do_pwritev_part(BlockBackend *blk, int64_t offset, int64_t bytes,
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
|
||||||
blk_wait_while_drained(blk);
|
blk_wait_while_drained(blk);
|
||||||
|
GRAPH_RDLOCK_GUARD();
|
||||||
|
|
||||||
/* Call blk_bs() only after waiting, the graph may have changed */
|
/* Call blk_bs() only after waiting, the graph may have changed */
|
||||||
bs = blk_bs(blk);
|
bs = blk_bs(blk);
|
||||||
|
@ -1431,6 +1433,7 @@ int coroutine_fn blk_co_block_status_above(BlockBackend *blk,
|
||||||
BlockDriverState **file)
|
BlockDriverState **file)
|
||||||
{
|
{
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
GRAPH_RDLOCK_GUARD();
|
||||||
return bdrv_co_block_status_above(blk_bs(blk), base, offset, bytes, pnum,
|
return bdrv_co_block_status_above(blk_bs(blk), base, offset, bytes, pnum,
|
||||||
map, file);
|
map, file);
|
||||||
}
|
}
|
||||||
|
@ -1441,6 +1444,7 @@ int coroutine_fn blk_co_is_allocated_above(BlockBackend *blk,
|
||||||
int64_t bytes, int64_t *pnum)
|
int64_t bytes, int64_t *pnum)
|
||||||
{
|
{
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
GRAPH_RDLOCK_GUARD();
|
||||||
return bdrv_co_is_allocated_above(blk_bs(blk), base, include_base, offset,
|
return bdrv_co_is_allocated_above(blk_bs(blk), base, include_base, offset,
|
||||||
bytes, pnum);
|
bytes, pnum);
|
||||||
}
|
}
|
||||||
|
@ -1602,8 +1606,9 @@ BlockAIOCB *blk_aio_pwrite_zeroes(BlockBackend *blk, int64_t offset,
|
||||||
int64_t coroutine_fn blk_co_getlength(BlockBackend *blk)
|
int64_t coroutine_fn blk_co_getlength(BlockBackend *blk)
|
||||||
{
|
{
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
GRAPH_RDLOCK_GUARD();
|
||||||
|
|
||||||
if (!blk_is_available(blk)) {
|
if (!blk_co_is_available(blk)) {
|
||||||
return -ENOMEDIUM;
|
return -ENOMEDIUM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1623,8 +1628,9 @@ void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr)
|
||||||
int64_t coroutine_fn blk_co_nb_sectors(BlockBackend *blk)
|
int64_t coroutine_fn blk_co_nb_sectors(BlockBackend *blk)
|
||||||
{
|
{
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
GRAPH_RDLOCK_GUARD();
|
||||||
|
|
||||||
if (!blk_is_available(blk)) {
|
if (!blk_co_is_available(blk)) {
|
||||||
return -ENOMEDIUM;
|
return -ENOMEDIUM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1670,8 +1676,9 @@ blk_co_do_ioctl(BlockBackend *blk, unsigned long int req, void *buf)
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
|
||||||
blk_wait_while_drained(blk);
|
blk_wait_while_drained(blk);
|
||||||
|
GRAPH_RDLOCK_GUARD();
|
||||||
|
|
||||||
if (!blk_is_available(blk)) {
|
if (!blk_co_is_available(blk)) {
|
||||||
return -ENOMEDIUM;
|
return -ENOMEDIUM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1716,6 +1723,7 @@ blk_co_do_pdiscard(BlockBackend *blk, int64_t offset, int64_t bytes)
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
|
||||||
blk_wait_while_drained(blk);
|
blk_wait_while_drained(blk);
|
||||||
|
GRAPH_RDLOCK_GUARD();
|
||||||
|
|
||||||
ret = blk_check_byte_request(blk, offset, bytes);
|
ret = blk_check_byte_request(blk, offset, bytes);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -1759,10 +1767,11 @@ int coroutine_fn blk_co_pdiscard(BlockBackend *blk, int64_t offset,
|
||||||
/* To be called between exactly one pair of blk_inc/dec_in_flight() */
|
/* To be called between exactly one pair of blk_inc/dec_in_flight() */
|
||||||
static int coroutine_fn blk_co_do_flush(BlockBackend *blk)
|
static int coroutine_fn blk_co_do_flush(BlockBackend *blk)
|
||||||
{
|
{
|
||||||
blk_wait_while_drained(blk);
|
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
blk_wait_while_drained(blk);
|
||||||
|
GRAPH_RDLOCK_GUARD();
|
||||||
|
|
||||||
if (!blk_is_available(blk)) {
|
if (!blk_co_is_available(blk)) {
|
||||||
return -ENOMEDIUM;
|
return -ENOMEDIUM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1989,20 +1998,22 @@ bool coroutine_fn blk_co_is_inserted(BlockBackend *blk)
|
||||||
{
|
{
|
||||||
BlockDriverState *bs = blk_bs(blk);
|
BlockDriverState *bs = blk_bs(blk);
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
|
|
||||||
return bs && bdrv_co_is_inserted(bs);
|
return bs && bdrv_co_is_inserted(bs);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool blk_is_available(BlockBackend *blk)
|
bool coroutine_fn blk_co_is_available(BlockBackend *blk)
|
||||||
{
|
{
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
return blk_is_inserted(blk) && !blk_dev_is_tray_open(blk);
|
return blk_co_is_inserted(blk) && !blk_dev_is_tray_open(blk);
|
||||||
}
|
}
|
||||||
|
|
||||||
void coroutine_fn blk_co_lock_medium(BlockBackend *blk, bool locked)
|
void coroutine_fn blk_co_lock_medium(BlockBackend *blk, bool locked)
|
||||||
{
|
{
|
||||||
BlockDriverState *bs = blk_bs(blk);
|
BlockDriverState *bs = blk_bs(blk);
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
GRAPH_RDLOCK_GUARD();
|
||||||
|
|
||||||
if (bs) {
|
if (bs) {
|
||||||
bdrv_co_lock_medium(bs, locked);
|
bdrv_co_lock_medium(bs, locked);
|
||||||
|
@ -2014,6 +2025,7 @@ void coroutine_fn blk_co_eject(BlockBackend *blk, bool eject_flag)
|
||||||
BlockDriverState *bs = blk_bs(blk);
|
BlockDriverState *bs = blk_bs(blk);
|
||||||
char *id;
|
char *id;
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
GRAPH_RDLOCK_GUARD();
|
||||||
|
|
||||||
if (bs) {
|
if (bs) {
|
||||||
bdrv_co_eject(bs, eject_flag);
|
bdrv_co_eject(bs, eject_flag);
|
||||||
|
@ -2321,6 +2333,7 @@ void coroutine_fn blk_co_io_plug(BlockBackend *blk)
|
||||||
{
|
{
|
||||||
BlockDriverState *bs = blk_bs(blk);
|
BlockDriverState *bs = blk_bs(blk);
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
GRAPH_RDLOCK_GUARD();
|
||||||
|
|
||||||
if (bs) {
|
if (bs) {
|
||||||
bdrv_co_io_plug(bs);
|
bdrv_co_io_plug(bs);
|
||||||
|
@ -2331,6 +2344,7 @@ void coroutine_fn blk_co_io_unplug(BlockBackend *blk)
|
||||||
{
|
{
|
||||||
BlockDriverState *bs = blk_bs(blk);
|
BlockDriverState *bs = blk_bs(blk);
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
GRAPH_RDLOCK_GUARD();
|
||||||
|
|
||||||
if (bs) {
|
if (bs) {
|
||||||
bdrv_co_io_unplug(bs);
|
bdrv_co_io_unplug(bs);
|
||||||
|
@ -2372,7 +2386,8 @@ int coroutine_fn blk_co_truncate(BlockBackend *blk, int64_t offset, bool exact,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
IO_OR_GS_CODE();
|
IO_OR_GS_CODE();
|
||||||
if (!blk_is_available(blk)) {
|
GRAPH_RDLOCK_GUARD();
|
||||||
|
if (!blk_co_is_available(blk)) {
|
||||||
error_setg(errp, "No medium inserted");
|
error_setg(errp, "No medium inserted");
|
||||||
return -ENOMEDIUM;
|
return -ENOMEDIUM;
|
||||||
}
|
}
|
||||||
|
@ -2627,6 +2642,7 @@ int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in,
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
GRAPH_RDLOCK_GUARD();
|
||||||
|
|
||||||
r = blk_check_byte_request(blk_in, off_in, bytes);
|
r = blk_check_byte_request(blk_in, off_in, bytes);
|
||||||
if (r) {
|
if (r) {
|
||||||
|
@ -2636,6 +2652,7 @@ int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in,
|
||||||
if (r) {
|
if (r) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
return bdrv_co_copy_range(blk_in->root, off_in,
|
return bdrv_co_copy_range(blk_in->root, off_in,
|
||||||
blk_out->root, off_out,
|
blk_out->root, off_out,
|
||||||
bytes, read_flags, write_flags);
|
bytes, read_flags, write_flags);
|
||||||
|
|
|
@ -469,10 +469,9 @@ static coroutine_fn int block_copy_task_run(AioTaskPool *pool,
|
||||||
* value of @method should be used for subsequent tasks.
|
* value of @method should be used for subsequent tasks.
|
||||||
* Returns 0 on success.
|
* Returns 0 on success.
|
||||||
*/
|
*/
|
||||||
static int coroutine_fn block_copy_do_copy(BlockCopyState *s,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes,
|
block_copy_do_copy(BlockCopyState *s, int64_t offset, int64_t bytes,
|
||||||
BlockCopyMethod *method,
|
BlockCopyMethod *method, bool *error_is_read)
|
||||||
bool *error_is_read)
|
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
int64_t nbytes = MIN(offset + bytes, s->len) - offset;
|
int64_t nbytes = MIN(offset + bytes, s->len) - offset;
|
||||||
|
@ -558,8 +557,10 @@ static coroutine_fn int block_copy_task_entry(AioTask *task)
|
||||||
BlockCopyMethod method = t->method;
|
BlockCopyMethod method = t->method;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
WITH_GRAPH_RDLOCK_GUARD() {
|
||||||
ret = block_copy_do_copy(s, t->req.offset, t->req.bytes, &method,
|
ret = block_copy_do_copy(s, t->req.offset, t->req.bytes, &method,
|
||||||
&error_is_read);
|
&error_is_read);
|
||||||
|
}
|
||||||
|
|
||||||
WITH_QEMU_LOCK_GUARD(&s->lock) {
|
WITH_QEMU_LOCK_GUARD(&s->lock) {
|
||||||
if (s->method == t->method) {
|
if (s->method == t->method) {
|
||||||
|
@ -581,9 +582,9 @@ static coroutine_fn int block_copy_task_entry(AioTask *task)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static coroutine_fn int block_copy_block_status(BlockCopyState *s,
|
static coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset,
|
int block_copy_block_status(BlockCopyState *s, int64_t offset, int64_t bytes,
|
||||||
int64_t bytes, int64_t *pnum)
|
int64_t *pnum)
|
||||||
{
|
{
|
||||||
int64_t num;
|
int64_t num;
|
||||||
BlockDriverState *base;
|
BlockDriverState *base;
|
||||||
|
@ -618,8 +619,8 @@ static coroutine_fn int block_copy_block_status(BlockCopyState *s,
|
||||||
* Check if the cluster starting at offset is allocated or not.
|
* Check if the cluster starting at offset is allocated or not.
|
||||||
* return via pnum the number of contiguous clusters sharing this allocation.
|
* return via pnum the number of contiguous clusters sharing this allocation.
|
||||||
*/
|
*/
|
||||||
static int coroutine_fn block_copy_is_cluster_allocated(BlockCopyState *s,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset,
|
block_copy_is_cluster_allocated(BlockCopyState *s, int64_t offset,
|
||||||
int64_t *pnum)
|
int64_t *pnum)
|
||||||
{
|
{
|
||||||
BlockDriverState *bs = s->source->bs;
|
BlockDriverState *bs = s->source->bs;
|
||||||
|
@ -630,6 +631,7 @@ static int coroutine_fn block_copy_is_cluster_allocated(BlockCopyState *s,
|
||||||
assert(QEMU_IS_ALIGNED(offset, s->cluster_size));
|
assert(QEMU_IS_ALIGNED(offset, s->cluster_size));
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
/* protected in backup_run() */
|
||||||
ret = bdrv_co_is_allocated(bs, offset, bytes, &count);
|
ret = bdrv_co_is_allocated(bs, offset, bytes, &count);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -704,7 +706,7 @@ int64_t coroutine_fn block_copy_reset_unallocated(BlockCopyState *s,
|
||||||
* Returns 1 if dirty clusters found and successfully copied, 0 if no dirty
|
* Returns 1 if dirty clusters found and successfully copied, 0 if no dirty
|
||||||
* clusters found and -errno on failure.
|
* clusters found and -errno on failure.
|
||||||
*/
|
*/
|
||||||
static int coroutine_fn
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
block_copy_dirty_clusters(BlockCopyCallState *call_state)
|
block_copy_dirty_clusters(BlockCopyCallState *call_state)
|
||||||
{
|
{
|
||||||
BlockCopyState *s = call_state->s;
|
BlockCopyState *s = call_state->s;
|
||||||
|
@ -827,7 +829,8 @@ void block_copy_kick(BlockCopyCallState *call_state)
|
||||||
* it means that some I/O operation failed in context of _this_ block_copy call,
|
* it means that some I/O operation failed in context of _this_ block_copy call,
|
||||||
* not some parallel operation.
|
* not some parallel operation.
|
||||||
*/
|
*/
|
||||||
static int coroutine_fn block_copy_common(BlockCopyCallState *call_state)
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
|
block_copy_common(BlockCopyCallState *call_state)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
BlockCopyState *s = call_state->s;
|
BlockCopyState *s = call_state->s;
|
||||||
|
@ -892,6 +895,7 @@ static int coroutine_fn block_copy_common(BlockCopyCallState *call_state)
|
||||||
|
|
||||||
static void coroutine_fn block_copy_async_co_entry(void *opaque)
|
static void coroutine_fn block_copy_async_co_entry(void *opaque)
|
||||||
{
|
{
|
||||||
|
GRAPH_RDLOCK_GUARD();
|
||||||
block_copy_common(opaque);
|
block_copy_common(opaque);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -237,7 +237,7 @@ static int64_t seek_to_sector(BlockDriverState *bs, int64_t sector_num)
|
||||||
return bitmap_offset + (512 * (s->bitmap_blocks + extent_offset));
|
return bitmap_offset + (512 * (s->bitmap_blocks + extent_offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
bochs_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
bochs_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
|
|
|
@ -206,8 +206,9 @@ static const BlockJobDriver commit_job_driver = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int coroutine_fn bdrv_commit_top_preadv(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes, QEMUIOVector *qiov, BdrvRequestFlags flags)
|
bdrv_commit_top_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
|
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
return bdrv_co_preadv(bs->backing, offset, bytes, qiov, flags);
|
return bdrv_co_preadv(bs->backing, offset, bytes, qiov, flags);
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,8 +78,8 @@ typedef struct BDRVCopyBeforeWriteState {
|
||||||
int snapshot_error;
|
int snapshot_error;
|
||||||
} BDRVCopyBeforeWriteState;
|
} BDRVCopyBeforeWriteState;
|
||||||
|
|
||||||
static coroutine_fn int cbw_co_preadv(
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
BlockDriverState *bs, int64_t offset, int64_t bytes,
|
cbw_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
|
return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
|
||||||
|
@ -149,8 +149,8 @@ static coroutine_fn int cbw_do_copy_before_write(BlockDriverState *bs,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn cbw_co_pdiscard(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes)
|
cbw_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
|
||||||
{
|
{
|
||||||
int ret = cbw_do_copy_before_write(bs, offset, bytes, 0);
|
int ret = cbw_do_copy_before_write(bs, offset, bytes, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -160,8 +160,9 @@ static int coroutine_fn cbw_co_pdiscard(BlockDriverState *bs,
|
||||||
return bdrv_co_pdiscard(bs->file, offset, bytes);
|
return bdrv_co_pdiscard(bs->file, offset, bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn cbw_co_pwrite_zeroes(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes, BdrvRequestFlags flags)
|
cbw_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
|
BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
int ret = cbw_do_copy_before_write(bs, offset, bytes, flags);
|
int ret = cbw_do_copy_before_write(bs, offset, bytes, flags);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -171,11 +172,9 @@ static int coroutine_fn cbw_co_pwrite_zeroes(BlockDriverState *bs,
|
||||||
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
|
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static coroutine_fn int cbw_co_pwritev(BlockDriverState *bs,
|
static coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset,
|
int cbw_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
int64_t bytes,
|
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
||||||
QEMUIOVector *qiov,
|
|
||||||
BdrvRequestFlags flags)
|
|
||||||
{
|
{
|
||||||
int ret = cbw_do_copy_before_write(bs, offset, bytes, flags);
|
int ret = cbw_do_copy_before_write(bs, offset, bytes, flags);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -185,7 +184,7 @@ static coroutine_fn int cbw_co_pwritev(BlockDriverState *bs,
|
||||||
return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
|
return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn cbw_co_flush(BlockDriverState *bs)
|
static int coroutine_fn GRAPH_RDLOCK cbw_co_flush(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
if (!bs->file) {
|
if (!bs->file) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -257,7 +256,7 @@ cbw_snapshot_read_unlock(BlockDriverState *bs, BlockReq *req)
|
||||||
g_free(req);
|
g_free(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
static coroutine_fn int
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
cbw_co_preadv_snapshot(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
cbw_co_preadv_snapshot(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
QEMUIOVector *qiov, size_t qiov_offset)
|
QEMUIOVector *qiov, size_t qiov_offset)
|
||||||
{
|
{
|
||||||
|
@ -289,7 +288,7 @@ cbw_co_preadv_snapshot(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
cbw_co_snapshot_block_status(BlockDriverState *bs,
|
cbw_co_snapshot_block_status(BlockDriverState *bs,
|
||||||
bool want_zero, int64_t offset, int64_t bytes,
|
bool want_zero, int64_t offset, int64_t bytes,
|
||||||
int64_t *pnum, int64_t *map,
|
int64_t *pnum, int64_t *map,
|
||||||
|
@ -322,8 +321,8 @@ cbw_co_snapshot_block_status(BlockDriverState *bs,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn cbw_co_pdiscard_snapshot(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes)
|
cbw_co_pdiscard_snapshot(BlockDriverState *bs, int64_t offset, int64_t bytes)
|
||||||
{
|
{
|
||||||
BDRVCopyBeforeWriteState *s = bs->opaque;
|
BDRVCopyBeforeWriteState *s = bs->opaque;
|
||||||
|
|
||||||
|
|
|
@ -121,16 +121,15 @@ static void cor_child_perm(BlockDriverState *bs, BdrvChild *c,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int64_t coroutine_fn cor_co_getlength(BlockDriverState *bs)
|
static int64_t coroutine_fn GRAPH_RDLOCK cor_co_getlength(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
return bdrv_co_getlength(bs->file->bs);
|
return bdrv_co_getlength(bs->file->bs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int coroutine_fn cor_co_preadv_part(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes,
|
cor_co_preadv_part(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
QEMUIOVector *qiov,
|
QEMUIOVector *qiov, size_t qiov_offset,
|
||||||
size_t qiov_offset,
|
|
||||||
BdrvRequestFlags flags)
|
BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
int64_t n;
|
int64_t n;
|
||||||
|
@ -180,11 +179,9 @@ static int coroutine_fn cor_co_preadv_part(BlockDriverState *bs,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int coroutine_fn cor_co_pwritev_part(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset,
|
cor_co_pwritev_part(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
int64_t bytes,
|
QEMUIOVector *qiov, size_t qiov_offset,
|
||||||
QEMUIOVector *qiov,
|
|
||||||
size_t qiov_offset,
|
|
||||||
BdrvRequestFlags flags)
|
BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
return bdrv_co_pwritev_part(bs->file, offset, bytes, qiov, qiov_offset,
|
return bdrv_co_pwritev_part(bs->file, offset, bytes, qiov, qiov_offset,
|
||||||
|
@ -192,24 +189,23 @@ static int coroutine_fn cor_co_pwritev_part(BlockDriverState *bs,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int coroutine_fn cor_co_pwrite_zeroes(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes,
|
cor_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
BdrvRequestFlags flags)
|
BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
|
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int coroutine_fn cor_co_pdiscard(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes)
|
cor_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
|
||||||
{
|
{
|
||||||
return bdrv_co_pdiscard(bs->file, offset, bytes);
|
return bdrv_co_pdiscard(bs->file, offset, bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int coroutine_fn cor_co_pwritev_compressed(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset,
|
cor_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
int64_t bytes,
|
|
||||||
QEMUIOVector *qiov)
|
QEMUIOVector *qiov)
|
||||||
{
|
{
|
||||||
return bdrv_co_pwritev(bs->file, offset, bytes, qiov,
|
return bdrv_co_pwritev(bs->file, offset, bytes, qiov,
|
||||||
|
@ -217,13 +213,15 @@ static int coroutine_fn cor_co_pwritev_compressed(BlockDriverState *bs,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void coroutine_fn cor_co_eject(BlockDriverState *bs, bool eject_flag)
|
static void coroutine_fn GRAPH_RDLOCK
|
||||||
|
cor_co_eject(BlockDriverState *bs, bool eject_flag)
|
||||||
{
|
{
|
||||||
bdrv_co_eject(bs->file->bs, eject_flag);
|
bdrv_co_eject(bs->file->bs, eject_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void coroutine_fn cor_co_lock_medium(BlockDriverState *bs, bool locked)
|
static void coroutine_fn GRAPH_RDLOCK
|
||||||
|
cor_co_lock_medium(BlockDriverState *bs, bool locked)
|
||||||
{
|
{
|
||||||
bdrv_co_lock_medium(bs->file->bs, locked);
|
bdrv_co_lock_medium(bs->file->bs, locked);
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ bdrv_co_check(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix);
|
||||||
int coroutine_fn GRAPH_RDLOCK
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
bdrv_co_invalidate_cache(BlockDriverState *bs, Error **errp);
|
bdrv_co_invalidate_cache(BlockDriverState *bs, Error **errp);
|
||||||
|
|
||||||
int coroutine_fn
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
bdrv_co_common_block_status_above(BlockDriverState *bs,
|
bdrv_co_common_block_status_above(BlockDriverState *bs,
|
||||||
BlockDriverState *base,
|
BlockDriverState *base,
|
||||||
bool include_base,
|
bool include_base,
|
||||||
|
|
|
@ -43,6 +43,7 @@ static int coroutine_fn blockdev_create_run(Job *job, Error **errp)
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
GLOBAL_STATE_CODE();
|
GLOBAL_STATE_CODE();
|
||||||
|
GRAPH_RDLOCK_GUARD();
|
||||||
|
|
||||||
job_progress_set_remaining(&s->common, 1);
|
job_progress_set_remaining(&s->common, 1);
|
||||||
ret = s->drv->bdrv_co_create(s->opts, errp);
|
ret = s->drv->bdrv_co_create(s->opts, errp);
|
||||||
|
@ -59,6 +60,12 @@ static const JobDriver blockdev_create_job_driver = {
|
||||||
.run = blockdev_create_run,
|
.run = blockdev_create_run,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Checking whether the function is present doesn't require the graph lock */
|
||||||
|
static inline bool TSA_NO_TSA has_bdrv_co_create(BlockDriver *drv)
|
||||||
|
{
|
||||||
|
return drv->bdrv_co_create;
|
||||||
|
}
|
||||||
|
|
||||||
void qmp_blockdev_create(const char *job_id, BlockdevCreateOptions *options,
|
void qmp_blockdev_create(const char *job_id, BlockdevCreateOptions *options,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
|
@ -79,7 +86,7 @@ void qmp_blockdev_create(const char *job_id, BlockdevCreateOptions *options,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Error out if the driver doesn't support .bdrv_co_create */
|
/* Error out if the driver doesn't support .bdrv_co_create */
|
||||||
if (!drv->bdrv_co_create) {
|
if (!has_bdrv_co_create(drv)) {
|
||||||
error_setg(errp, "Driver does not support blockdev-create");
|
error_setg(errp, "Driver does not support blockdev-create");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -359,7 +359,7 @@ block_crypto_co_create_generic(BlockDriverState *bs, int64_t size,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
block_crypto_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
|
block_crypto_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
|
||||||
PreallocMode prealloc, BdrvRequestFlags flags,
|
PreallocMode prealloc, BdrvRequestFlags flags,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
|
@ -397,7 +397,7 @@ static int block_crypto_reopen_prepare(BDRVReopenState *state,
|
||||||
*/
|
*/
|
||||||
#define BLOCK_CRYPTO_MAX_IO_SIZE (1024 * 1024)
|
#define BLOCK_CRYPTO_MAX_IO_SIZE (1024 * 1024)
|
||||||
|
|
||||||
static coroutine_fn int
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
block_crypto_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
block_crypto_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
|
@ -459,7 +459,7 @@ block_crypto_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static coroutine_fn int
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
block_crypto_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
block_crypto_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
|
@ -530,7 +530,8 @@ static void block_crypto_refresh_limits(BlockDriverState *bs, Error **errp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int64_t coroutine_fn block_crypto_co_getlength(BlockDriverState *bs)
|
static int64_t coroutine_fn GRAPH_RDLOCK
|
||||||
|
block_crypto_co_getlength(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
BlockCrypto *crypto = bs->opaque;
|
BlockCrypto *crypto = bs->opaque;
|
||||||
int64_t len = bdrv_co_getlength(bs->file->bs);
|
int64_t len = bdrv_co_getlength(bs->file->bs);
|
||||||
|
@ -664,10 +665,9 @@ fail:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn block_crypto_co_create_opts_luks(BlockDriver *drv,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
const char *filename,
|
block_crypto_co_create_opts_luks(BlockDriver *drv, const char *filename,
|
||||||
QemuOpts *opts,
|
QemuOpts *opts, Error **errp)
|
||||||
Error **errp)
|
|
||||||
{
|
{
|
||||||
QCryptoBlockCreateOptions *create_opts = NULL;
|
QCryptoBlockCreateOptions *create_opts = NULL;
|
||||||
BlockDriverState *bs = NULL;
|
BlockDriverState *bs = NULL;
|
||||||
|
|
|
@ -394,6 +394,7 @@ int coroutine_fn
|
||||||
bdrv_co_remove_persistent_dirty_bitmap(BlockDriverState *bs, const char *name,
|
bdrv_co_remove_persistent_dirty_bitmap(BlockDriverState *bs, const char *name,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
if (bs->drv && bs->drv->bdrv_co_remove_persistent_dirty_bitmap) {
|
if (bs->drv && bs->drv->bdrv_co_remove_persistent_dirty_bitmap) {
|
||||||
return bs->drv->bdrv_co_remove_persistent_dirty_bitmap(bs, name, errp);
|
return bs->drv->bdrv_co_remove_persistent_dirty_bitmap(bs, name, errp);
|
||||||
}
|
}
|
||||||
|
@ -415,6 +416,7 @@ bdrv_co_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name,
|
||||||
uint32_t granularity, Error **errp)
|
uint32_t granularity, Error **errp)
|
||||||
{
|
{
|
||||||
BlockDriver *drv = bs->drv;
|
BlockDriver *drv = bs->drv;
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
|
|
||||||
if (!drv) {
|
if (!drv) {
|
||||||
error_setg_errno(errp, ENOMEDIUM,
|
error_setg_errno(errp, ENOMEDIUM,
|
||||||
|
|
|
@ -2607,10 +2607,9 @@ out:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn raw_co_create_opts(BlockDriver *drv,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
const char *filename,
|
raw_co_create_opts(BlockDriver *drv, const char *filename,
|
||||||
QemuOpts *opts,
|
QemuOpts *opts, Error **errp)
|
||||||
Error **errp)
|
|
||||||
{
|
{
|
||||||
BlockdevCreateOptions options;
|
BlockdevCreateOptions options;
|
||||||
int64_t total_size = 0;
|
int64_t total_size = 0;
|
||||||
|
@ -2920,8 +2919,8 @@ static void coroutine_fn check_cache_dropped(BlockDriverState *bs, Error **errp)
|
||||||
}
|
}
|
||||||
#endif /* __linux__ */
|
#endif /* __linux__ */
|
||||||
|
|
||||||
static void coroutine_fn raw_co_invalidate_cache(BlockDriverState *bs,
|
static void coroutine_fn GRAPH_RDLOCK
|
||||||
Error **errp)
|
raw_co_invalidate_cache(BlockDriverState *bs, Error **errp)
|
||||||
{
|
{
|
||||||
BDRVRawState *s = bs->opaque;
|
BDRVRawState *s = bs->opaque;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -3272,7 +3271,7 @@ static void raw_abort_perm_update(BlockDriverState *bs)
|
||||||
raw_handle_perm_lock(bs, RAW_PL_ABORT, 0, 0, NULL);
|
raw_handle_perm_lock(bs, RAW_PL_ABORT, 0, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn raw_co_copy_range_from(
|
static int coroutine_fn GRAPH_RDLOCK raw_co_copy_range_from(
|
||||||
BlockDriverState *bs, BdrvChild *src, int64_t src_offset,
|
BlockDriverState *bs, BdrvChild *src, int64_t src_offset,
|
||||||
BdrvChild *dst, int64_t dst_offset, int64_t bytes,
|
BdrvChild *dst, int64_t dst_offset, int64_t bytes,
|
||||||
BdrvRequestFlags read_flags, BdrvRequestFlags write_flags)
|
BdrvRequestFlags read_flags, BdrvRequestFlags write_flags)
|
||||||
|
@ -3281,13 +3280,11 @@ static int coroutine_fn raw_co_copy_range_from(
|
||||||
read_flags, write_flags);
|
read_flags, write_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn raw_co_copy_range_to(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
BdrvChild *src,
|
raw_co_copy_range_to(BlockDriverState *bs,
|
||||||
int64_t src_offset,
|
BdrvChild *src, int64_t src_offset,
|
||||||
BdrvChild *dst,
|
BdrvChild *dst, int64_t dst_offset,
|
||||||
int64_t dst_offset,
|
int64_t bytes, BdrvRequestFlags read_flags,
|
||||||
int64_t bytes,
|
|
||||||
BdrvRequestFlags read_flags,
|
|
||||||
BdrvRequestFlags write_flags)
|
BdrvRequestFlags write_flags)
|
||||||
{
|
{
|
||||||
RawPosixAIOData acb;
|
RawPosixAIOData acb;
|
||||||
|
|
|
@ -613,10 +613,9 @@ static int raw_co_create(BlockdevCreateOptions *options, Error **errp)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn raw_co_create_opts(BlockDriver *drv,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
const char *filename,
|
raw_co_create_opts(BlockDriver *drv, const char *filename,
|
||||||
QemuOpts *opts,
|
QemuOpts *opts, Error **errp)
|
||||||
Error **errp)
|
|
||||||
{
|
{
|
||||||
BlockdevCreateOptions options;
|
BlockdevCreateOptions options;
|
||||||
int64_t total_size = 0;
|
int64_t total_size = 0;
|
||||||
|
|
|
@ -55,16 +55,16 @@ static int compress_open(BlockDriverState *bs, QDict *options, int flags,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int64_t coroutine_fn compress_co_getlength(BlockDriverState *bs)
|
static int64_t coroutine_fn GRAPH_RDLOCK
|
||||||
|
compress_co_getlength(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
return bdrv_co_getlength(bs->file->bs);
|
return bdrv_co_getlength(bs->file->bs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int coroutine_fn compress_co_preadv_part(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes,
|
compress_co_preadv_part(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
QEMUIOVector *qiov,
|
QEMUIOVector *qiov, size_t qiov_offset,
|
||||||
size_t qiov_offset,
|
|
||||||
BdrvRequestFlags flags)
|
BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
return bdrv_co_preadv_part(bs->file, offset, bytes, qiov, qiov_offset,
|
return bdrv_co_preadv_part(bs->file, offset, bytes, qiov, qiov_offset,
|
||||||
|
@ -72,11 +72,9 @@ static int coroutine_fn compress_co_preadv_part(BlockDriverState *bs,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int coroutine_fn compress_co_pwritev_part(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset,
|
compress_co_pwritev_part(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
int64_t bytes,
|
QEMUIOVector *qiov, size_t qiov_offset,
|
||||||
QEMUIOVector *qiov,
|
|
||||||
size_t qiov_offset,
|
|
||||||
BdrvRequestFlags flags)
|
BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
return bdrv_co_pwritev_part(bs->file, offset, bytes, qiov, qiov_offset,
|
return bdrv_co_pwritev_part(bs->file, offset, bytes, qiov, qiov_offset,
|
||||||
|
@ -84,16 +82,16 @@ static int coroutine_fn compress_co_pwritev_part(BlockDriverState *bs,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int coroutine_fn compress_co_pwrite_zeroes(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes,
|
compress_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
BdrvRequestFlags flags)
|
BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
|
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int coroutine_fn compress_co_pdiscard(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes)
|
compress_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
|
||||||
{
|
{
|
||||||
return bdrv_co_pdiscard(bs->file, offset, bytes);
|
return bdrv_co_pdiscard(bs->file, offset, bytes);
|
||||||
}
|
}
|
||||||
|
@ -117,14 +115,14 @@ static void compress_refresh_limits(BlockDriverState *bs, Error **errp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void coroutine_fn
|
static void coroutine_fn GRAPH_RDLOCK
|
||||||
compress_co_eject(BlockDriverState *bs, bool eject_flag)
|
compress_co_eject(BlockDriverState *bs, bool eject_flag)
|
||||||
{
|
{
|
||||||
bdrv_co_eject(bs->file->bs, eject_flag);
|
bdrv_co_eject(bs->file->bs, eject_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void coroutine_fn
|
static void coroutine_fn GRAPH_RDLOCK
|
||||||
compress_co_lock_medium(BlockDriverState *bs, bool locked)
|
compress_co_lock_medium(BlockDriverState *bs, bool locked)
|
||||||
{
|
{
|
||||||
bdrv_co_lock_medium(bs->file->bs, locked);
|
bdrv_co_lock_medium(bs->file->bs, locked);
|
||||||
|
|
100
block/io.c
100
block/io.c
|
@ -160,6 +160,7 @@ void bdrv_refresh_limits(BlockDriverState *bs, Transaction *tran, Error **errp)
|
||||||
bool have_limits;
|
bool have_limits;
|
||||||
|
|
||||||
GLOBAL_STATE_CODE();
|
GLOBAL_STATE_CODE();
|
||||||
|
assume_graph_lock(); /* FIXME */
|
||||||
|
|
||||||
if (tran) {
|
if (tran) {
|
||||||
BdrvRefreshLimitsState *s = g_new(BdrvRefreshLimitsState, 1);
|
BdrvRefreshLimitsState *s = g_new(BdrvRefreshLimitsState, 1);
|
||||||
|
@ -932,6 +933,7 @@ int coroutine_fn bdrv_co_pwrite_sync(BdrvChild *child, int64_t offset,
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
|
|
||||||
ret = bdrv_co_pwrite(child, offset, bytes, buf, flags);
|
ret = bdrv_co_pwrite(child, offset, bytes, buf, flags);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -959,16 +961,16 @@ static void bdrv_co_io_em_complete(void *opaque, int ret)
|
||||||
aio_co_wake(co->coroutine);
|
aio_co_wake(co->coroutine);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn bdrv_driver_preadv(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes,
|
bdrv_driver_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
QEMUIOVector *qiov,
|
QEMUIOVector *qiov, size_t qiov_offset, int flags)
|
||||||
size_t qiov_offset, int flags)
|
|
||||||
{
|
{
|
||||||
BlockDriver *drv = bs->drv;
|
BlockDriver *drv = bs->drv;
|
||||||
int64_t sector_num;
|
int64_t sector_num;
|
||||||
unsigned int nb_sectors;
|
unsigned int nb_sectors;
|
||||||
QEMUIOVector local_qiov;
|
QEMUIOVector local_qiov;
|
||||||
int ret;
|
int ret;
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
|
|
||||||
bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort);
|
bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort);
|
||||||
assert(!(flags & ~bs->supported_read_flags));
|
assert(!(flags & ~bs->supported_read_flags));
|
||||||
|
@ -1028,10 +1030,9 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn bdrv_driver_pwritev(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes,
|
bdrv_driver_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
QEMUIOVector *qiov,
|
QEMUIOVector *qiov, size_t qiov_offset,
|
||||||
size_t qiov_offset,
|
|
||||||
BdrvRequestFlags flags)
|
BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
BlockDriver *drv = bs->drv;
|
BlockDriver *drv = bs->drv;
|
||||||
|
@ -1040,6 +1041,7 @@ static int coroutine_fn bdrv_driver_pwritev(BlockDriverState *bs,
|
||||||
unsigned int nb_sectors;
|
unsigned int nb_sectors;
|
||||||
QEMUIOVector local_qiov;
|
QEMUIOVector local_qiov;
|
||||||
int ret;
|
int ret;
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
|
|
||||||
bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort);
|
bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort);
|
||||||
|
|
||||||
|
@ -1110,7 +1112,7 @@ emulate_flags:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
bdrv_driver_pwritev_compressed(BlockDriverState *bs, int64_t offset,
|
bdrv_driver_pwritev_compressed(BlockDriverState *bs, int64_t offset,
|
||||||
int64_t bytes, QEMUIOVector *qiov,
|
int64_t bytes, QEMUIOVector *qiov,
|
||||||
size_t qiov_offset)
|
size_t qiov_offset)
|
||||||
|
@ -1118,6 +1120,7 @@ bdrv_driver_pwritev_compressed(BlockDriverState *bs, int64_t offset,
|
||||||
BlockDriver *drv = bs->drv;
|
BlockDriver *drv = bs->drv;
|
||||||
QEMUIOVector local_qiov;
|
QEMUIOVector local_qiov;
|
||||||
int ret;
|
int ret;
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
|
|
||||||
bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort);
|
bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort);
|
||||||
|
|
||||||
|
@ -1145,9 +1148,9 @@ bdrv_driver_pwritev_compressed(BlockDriverState *bs, int64_t offset,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes, QEMUIOVector *qiov,
|
bdrv_co_do_copy_on_readv(BdrvChild *child, int64_t offset, int64_t bytes,
|
||||||
size_t qiov_offset, int flags)
|
QEMUIOVector *qiov, size_t qiov_offset, int flags)
|
||||||
{
|
{
|
||||||
BlockDriverState *bs = child->bs;
|
BlockDriverState *bs = child->bs;
|
||||||
|
|
||||||
|
@ -1309,9 +1312,10 @@ err:
|
||||||
* handles copy on read, zeroing after EOF, and fragmentation of large
|
* handles copy on read, zeroing after EOF, and fragmentation of large
|
||||||
* reads; any other features must be implemented by the caller.
|
* reads; any other features must be implemented by the caller.
|
||||||
*/
|
*/
|
||||||
static int coroutine_fn bdrv_aligned_preadv(BdrvChild *child,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
BdrvTrackedRequest *req, int64_t offset, int64_t bytes,
|
bdrv_aligned_preadv(BdrvChild *child, BdrvTrackedRequest *req,
|
||||||
int64_t align, QEMUIOVector *qiov, size_t qiov_offset, int flags)
|
int64_t offset, int64_t bytes, int64_t align,
|
||||||
|
QEMUIOVector *qiov, size_t qiov_offset, int flags)
|
||||||
{
|
{
|
||||||
BlockDriverState *bs = child->bs;
|
BlockDriverState *bs = child->bs;
|
||||||
int64_t total_bytes, max_bytes;
|
int64_t total_bytes, max_bytes;
|
||||||
|
@ -1478,10 +1482,9 @@ static bool bdrv_init_padding(BlockDriverState *bs,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static coroutine_fn int bdrv_padding_rmw_read(BdrvChild *child,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
BdrvTrackedRequest *req,
|
bdrv_padding_rmw_read(BdrvChild *child, BdrvTrackedRequest *req,
|
||||||
BdrvRequestPadding *pad,
|
BdrvRequestPadding *pad, bool zero_middle)
|
||||||
bool zero_middle)
|
|
||||||
{
|
{
|
||||||
QEMUIOVector local_qiov;
|
QEMUIOVector local_qiov;
|
||||||
BlockDriverState *bs = child->bs;
|
BlockDriverState *bs = child->bs;
|
||||||
|
@ -1669,8 +1672,9 @@ fail:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes, BdrvRequestFlags flags)
|
bdrv_co_do_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
|
BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
BlockDriver *drv = bs->drv;
|
BlockDriver *drv = bs->drv;
|
||||||
QEMUIOVector qiov;
|
QEMUIOVector qiov;
|
||||||
|
@ -1686,6 +1690,7 @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
|
||||||
bs->bl.request_alignment);
|
bs->bl.request_alignment);
|
||||||
int max_transfer = MIN_NON_ZERO(bs->bl.max_transfer, MAX_BOUNCE_BUFFER);
|
int max_transfer = MIN_NON_ZERO(bs->bl.max_transfer, MAX_BOUNCE_BUFFER);
|
||||||
|
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
bdrv_check_request(offset, bytes, &error_abort);
|
bdrv_check_request(offset, bytes, &error_abort);
|
||||||
|
|
||||||
if (!drv) {
|
if (!drv) {
|
||||||
|
@ -1889,9 +1894,10 @@ bdrv_co_write_req_finish(BdrvChild *child, int64_t offset, int64_t bytes,
|
||||||
* Forwards an already correctly aligned write request to the BlockDriver,
|
* Forwards an already correctly aligned write request to the BlockDriver,
|
||||||
* after possibly fragmenting it.
|
* after possibly fragmenting it.
|
||||||
*/
|
*/
|
||||||
static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
BdrvTrackedRequest *req, int64_t offset, int64_t bytes,
|
bdrv_aligned_pwritev(BdrvChild *child, BdrvTrackedRequest *req,
|
||||||
int64_t align, QEMUIOVector *qiov, size_t qiov_offset,
|
int64_t offset, int64_t bytes, int64_t align,
|
||||||
|
QEMUIOVector *qiov, size_t qiov_offset,
|
||||||
BdrvRequestFlags flags)
|
BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
BlockDriverState *bs = child->bs;
|
BlockDriverState *bs = child->bs;
|
||||||
|
@ -1976,11 +1982,9 @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn bdrv_co_do_zero_pwritev(BdrvChild *child,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset,
|
bdrv_co_do_zero_pwritev(BdrvChild *child, int64_t offset, int64_t bytes,
|
||||||
int64_t bytes,
|
BdrvRequestFlags flags, BdrvTrackedRequest *req)
|
||||||
BdrvRequestFlags flags,
|
|
||||||
BdrvTrackedRequest *req)
|
|
||||||
{
|
{
|
||||||
BlockDriverState *bs = child->bs;
|
BlockDriverState *bs = child->bs;
|
||||||
QEMUIOVector local_qiov;
|
QEMUIOVector local_qiov;
|
||||||
|
@ -2153,6 +2157,7 @@ int coroutine_fn bdrv_co_pwrite_zeroes(BdrvChild *child, int64_t offset,
|
||||||
{
|
{
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
trace_bdrv_co_pwrite_zeroes(child->bs, offset, bytes, flags);
|
trace_bdrv_co_pwrite_zeroes(child->bs, offset, bytes, flags);
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
|
|
||||||
if (!(child->bs->open_flags & BDRV_O_UNMAP)) {
|
if (!(child->bs->open_flags & BDRV_O_UNMAP)) {
|
||||||
flags &= ~BDRV_REQ_MAY_UNMAP;
|
flags &= ~BDRV_REQ_MAY_UNMAP;
|
||||||
|
@ -2224,11 +2229,10 @@ int bdrv_flush_all(void)
|
||||||
* BDRV_BLOCK_OFFSET_VALID bit is set, 'map' and 'file' (if non-NULL) are
|
* BDRV_BLOCK_OFFSET_VALID bit is set, 'map' and 'file' (if non-NULL) are
|
||||||
* set to the host mapping and BDS corresponding to the guest offset.
|
* set to the host mapping and BDS corresponding to the guest offset.
|
||||||
*/
|
*/
|
||||||
static int coroutine_fn bdrv_co_block_status(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
bool want_zero,
|
bdrv_co_block_status(BlockDriverState *bs, bool want_zero,
|
||||||
int64_t offset, int64_t bytes,
|
int64_t offset, int64_t bytes,
|
||||||
int64_t *pnum, int64_t *map,
|
int64_t *pnum, int64_t *map, BlockDriverState **file)
|
||||||
BlockDriverState **file)
|
|
||||||
{
|
{
|
||||||
int64_t total_size;
|
int64_t total_size;
|
||||||
int64_t n; /* bytes */
|
int64_t n; /* bytes */
|
||||||
|
@ -2240,6 +2244,7 @@ static int coroutine_fn bdrv_co_block_status(BlockDriverState *bs,
|
||||||
bool has_filtered_child;
|
bool has_filtered_child;
|
||||||
|
|
||||||
assert(pnum);
|
assert(pnum);
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
*pnum = 0;
|
*pnum = 0;
|
||||||
total_size = bdrv_getlength(bs);
|
total_size = bdrv_getlength(bs);
|
||||||
if (total_size < 0) {
|
if (total_size < 0) {
|
||||||
|
@ -2470,6 +2475,7 @@ bdrv_co_common_block_status_above(BlockDriverState *bs,
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
|
||||||
assert(!include_base || base); /* Can't include NULL base */
|
assert(!include_base || base); /* Can't include NULL base */
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
|
|
||||||
if (!depth) {
|
if (!depth) {
|
||||||
depth = &dummy;
|
depth = &dummy;
|
||||||
|
@ -2836,6 +2842,7 @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
bdrv_inc_in_flight(bs);
|
bdrv_inc_in_flight(bs);
|
||||||
|
|
||||||
if (!bdrv_co_is_inserted(bs) || bdrv_is_read_only(bs) ||
|
if (!bdrv_co_is_inserted(bs) || bdrv_is_read_only(bs) ||
|
||||||
|
@ -2961,6 +2968,7 @@ int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset,
|
||||||
int head, tail, align;
|
int head, tail, align;
|
||||||
BlockDriverState *bs = child->bs;
|
BlockDriverState *bs = child->bs;
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
|
|
||||||
if (!bs || !bs->drv || !bdrv_co_is_inserted(bs)) {
|
if (!bs || !bs->drv || !bdrv_co_is_inserted(bs)) {
|
||||||
return -ENOMEDIUM;
|
return -ENOMEDIUM;
|
||||||
|
@ -3080,6 +3088,7 @@ int coroutine_fn bdrv_co_ioctl(BlockDriverState *bs, int req, void *buf)
|
||||||
};
|
};
|
||||||
BlockAIOCB *acb;
|
BlockAIOCB *acb;
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
|
|
||||||
bdrv_inc_in_flight(bs);
|
bdrv_inc_in_flight(bs);
|
||||||
if (!drv || (!drv->bdrv_aio_ioctl && !drv->bdrv_co_ioctl)) {
|
if (!drv || (!drv->bdrv_aio_ioctl && !drv->bdrv_co_ioctl)) {
|
||||||
|
@ -3144,6 +3153,7 @@ void coroutine_fn bdrv_co_io_plug(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
BdrvChild *child;
|
BdrvChild *child;
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
|
|
||||||
QLIST_FOREACH(child, &bs->children, next) {
|
QLIST_FOREACH(child, &bs->children, next) {
|
||||||
bdrv_co_io_plug(child->bs);
|
bdrv_co_io_plug(child->bs);
|
||||||
|
@ -3161,6 +3171,7 @@ void coroutine_fn bdrv_co_io_unplug(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
BdrvChild *child;
|
BdrvChild *child;
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
|
|
||||||
assert(bs->io_plugged);
|
assert(bs->io_plugged);
|
||||||
if (qatomic_fetch_dec(&bs->io_plugged) == 1) {
|
if (qatomic_fetch_dec(&bs->io_plugged) == 1) {
|
||||||
|
@ -3176,13 +3187,15 @@ void coroutine_fn bdrv_co_io_unplug(BlockDriverState *bs)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Helper that undoes bdrv_register_buf() when it fails partway through */
|
/* Helper that undoes bdrv_register_buf() when it fails partway through */
|
||||||
static void bdrv_register_buf_rollback(BlockDriverState *bs,
|
static void GRAPH_RDLOCK
|
||||||
void *host,
|
bdrv_register_buf_rollback(BlockDriverState *bs, void *host, size_t size,
|
||||||
size_t size,
|
|
||||||
BdrvChild *final_child)
|
BdrvChild *final_child)
|
||||||
{
|
{
|
||||||
BdrvChild *child;
|
BdrvChild *child;
|
||||||
|
|
||||||
|
GLOBAL_STATE_CODE();
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
|
|
||||||
QLIST_FOREACH(child, &bs->children, next) {
|
QLIST_FOREACH(child, &bs->children, next) {
|
||||||
if (child == final_child) {
|
if (child == final_child) {
|
||||||
break;
|
break;
|
||||||
|
@ -3202,6 +3215,8 @@ bool bdrv_register_buf(BlockDriverState *bs, void *host, size_t size,
|
||||||
BdrvChild *child;
|
BdrvChild *child;
|
||||||
|
|
||||||
GLOBAL_STATE_CODE();
|
GLOBAL_STATE_CODE();
|
||||||
|
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||||
|
|
||||||
if (bs->drv && bs->drv->bdrv_register_buf) {
|
if (bs->drv && bs->drv->bdrv_register_buf) {
|
||||||
if (!bs->drv->bdrv_register_buf(bs, host, size, errp)) {
|
if (!bs->drv->bdrv_register_buf(bs, host, size, errp)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -3221,6 +3236,8 @@ void bdrv_unregister_buf(BlockDriverState *bs, void *host, size_t size)
|
||||||
BdrvChild *child;
|
BdrvChild *child;
|
||||||
|
|
||||||
GLOBAL_STATE_CODE();
|
GLOBAL_STATE_CODE();
|
||||||
|
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||||
|
|
||||||
if (bs->drv && bs->drv->bdrv_unregister_buf) {
|
if (bs->drv && bs->drv->bdrv_unregister_buf) {
|
||||||
bs->drv->bdrv_unregister_buf(bs, host, size);
|
bs->drv->bdrv_unregister_buf(bs, host, size);
|
||||||
}
|
}
|
||||||
|
@ -3229,7 +3246,7 @@ void bdrv_unregister_buf(BlockDriverState *bs, void *host, size_t size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn bdrv_co_copy_range_internal(
|
static int coroutine_fn GRAPH_RDLOCK bdrv_co_copy_range_internal(
|
||||||
BdrvChild *src, int64_t src_offset, BdrvChild *dst,
|
BdrvChild *src, int64_t src_offset, BdrvChild *dst,
|
||||||
int64_t dst_offset, int64_t bytes,
|
int64_t dst_offset, int64_t bytes,
|
||||||
BdrvRequestFlags read_flags, BdrvRequestFlags write_flags,
|
BdrvRequestFlags read_flags, BdrvRequestFlags write_flags,
|
||||||
|
@ -3237,6 +3254,7 @@ static int coroutine_fn bdrv_co_copy_range_internal(
|
||||||
{
|
{
|
||||||
BdrvTrackedRequest req;
|
BdrvTrackedRequest req;
|
||||||
int ret;
|
int ret;
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
|
|
||||||
/* TODO We can support BDRV_REQ_NO_FALLBACK here */
|
/* TODO We can support BDRV_REQ_NO_FALLBACK here */
|
||||||
assert(!(read_flags & BDRV_REQ_NO_FALLBACK));
|
assert(!(read_flags & BDRV_REQ_NO_FALLBACK));
|
||||||
|
@ -3318,6 +3336,7 @@ int coroutine_fn bdrv_co_copy_range_from(BdrvChild *src, int64_t src_offset,
|
||||||
BdrvRequestFlags write_flags)
|
BdrvRequestFlags write_flags)
|
||||||
{
|
{
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
trace_bdrv_co_copy_range_from(src, src_offset, dst, dst_offset, bytes,
|
trace_bdrv_co_copy_range_from(src, src_offset, dst, dst_offset, bytes,
|
||||||
read_flags, write_flags);
|
read_flags, write_flags);
|
||||||
return bdrv_co_copy_range_internal(src, src_offset, dst, dst_offset,
|
return bdrv_co_copy_range_internal(src, src_offset, dst, dst_offset,
|
||||||
|
@ -3335,6 +3354,7 @@ int coroutine_fn bdrv_co_copy_range_to(BdrvChild *src, int64_t src_offset,
|
||||||
BdrvRequestFlags write_flags)
|
BdrvRequestFlags write_flags)
|
||||||
{
|
{
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
trace_bdrv_co_copy_range_to(src, src_offset, dst, dst_offset, bytes,
|
trace_bdrv_co_copy_range_to(src, src_offset, dst, dst_offset, bytes,
|
||||||
read_flags, write_flags);
|
read_flags, write_flags);
|
||||||
return bdrv_co_copy_range_internal(src, src_offset, dst, dst_offset,
|
return bdrv_co_copy_range_internal(src, src_offset, dst, dst_offset,
|
||||||
|
@ -3347,6 +3367,8 @@ int coroutine_fn bdrv_co_copy_range(BdrvChild *src, int64_t src_offset,
|
||||||
BdrvRequestFlags write_flags)
|
BdrvRequestFlags write_flags)
|
||||||
{
|
{
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
|
|
||||||
return bdrv_co_copy_range_from(src, src_offset,
|
return bdrv_co_copy_range_from(src, src_offset,
|
||||||
dst, dst_offset,
|
dst, dst_offset,
|
||||||
bytes, read_flags, write_flags);
|
bytes, read_flags, write_flags);
|
||||||
|
@ -3380,6 +3402,7 @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
|
||||||
int64_t old_size, new_bytes;
|
int64_t old_size, new_bytes;
|
||||||
int ret;
|
int ret;
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
|
|
||||||
/* if bs->drv == NULL, bs is closed, so there's nothing to do here */
|
/* if bs->drv == NULL, bs is closed, so there's nothing to do here */
|
||||||
if (!drv) {
|
if (!drv) {
|
||||||
|
@ -3517,6 +3540,7 @@ bdrv_co_preadv_snapshot(BdrvChild *child, int64_t offset, int64_t bytes,
|
||||||
BlockDriver *drv = bs->drv;
|
BlockDriver *drv = bs->drv;
|
||||||
int ret;
|
int ret;
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
|
|
||||||
if (!drv) {
|
if (!drv) {
|
||||||
return -ENOMEDIUM;
|
return -ENOMEDIUM;
|
||||||
|
@ -3542,6 +3566,7 @@ bdrv_co_snapshot_block_status(BlockDriverState *bs,
|
||||||
BlockDriver *drv = bs->drv;
|
BlockDriver *drv = bs->drv;
|
||||||
int ret;
|
int ret;
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
|
|
||||||
if (!drv) {
|
if (!drv) {
|
||||||
return -ENOMEDIUM;
|
return -ENOMEDIUM;
|
||||||
|
@ -3565,6 +3590,7 @@ bdrv_co_pdiscard_snapshot(BlockDriverState *bs, int64_t offset, int64_t bytes)
|
||||||
BlockDriver *drv = bs->drv;
|
BlockDriver *drv = bs->drv;
|
||||||
int ret;
|
int ret;
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
|
|
||||||
if (!drv) {
|
if (!drv) {
|
||||||
return -ENOMEDIUM;
|
return -ENOMEDIUM;
|
||||||
|
|
|
@ -2190,13 +2190,11 @@ static void coroutine_fn iscsi_co_invalidate_cache(BlockDriverState *bs,
|
||||||
iscsi_allocmap_invalidate(iscsilun);
|
iscsi_allocmap_invalidate(iscsilun);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn iscsi_co_copy_range_from(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
BdrvChild *src,
|
iscsi_co_copy_range_from(BlockDriverState *bs,
|
||||||
int64_t src_offset,
|
BdrvChild *src, int64_t src_offset,
|
||||||
BdrvChild *dst,
|
BdrvChild *dst, int64_t dst_offset,
|
||||||
int64_t dst_offset,
|
int64_t bytes, BdrvRequestFlags read_flags,
|
||||||
int64_t bytes,
|
|
||||||
BdrvRequestFlags read_flags,
|
|
||||||
BdrvRequestFlags write_flags)
|
BdrvRequestFlags write_flags)
|
||||||
{
|
{
|
||||||
return bdrv_co_copy_range_to(src, src_offset, dst, dst_offset, bytes,
|
return bdrv_co_copy_range_to(src, src_offset, dst, dst_offset, bytes,
|
||||||
|
@ -2331,13 +2329,11 @@ static void iscsi_xcopy_data(struct iscsi_data *data,
|
||||||
src_lba, dst_lba);
|
src_lba, dst_lba);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn iscsi_co_copy_range_to(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
BdrvChild *src,
|
iscsi_co_copy_range_to(BlockDriverState *bs,
|
||||||
int64_t src_offset,
|
BdrvChild *src, int64_t src_offset,
|
||||||
BdrvChild *dst,
|
BdrvChild *dst, int64_t dst_offset,
|
||||||
int64_t dst_offset,
|
int64_t bytes, BdrvRequestFlags read_flags,
|
||||||
int64_t bytes,
|
|
||||||
BdrvRequestFlags read_flags,
|
|
||||||
BdrvRequestFlags write_flags)
|
BdrvRequestFlags write_flags)
|
||||||
{
|
{
|
||||||
IscsiLun *dst_lun = dst->bs->opaque;
|
IscsiLun *dst_lun = dst->bs->opaque;
|
||||||
|
|
|
@ -389,8 +389,10 @@ static void coroutine_fn mirror_co_read(void *opaque)
|
||||||
op->is_in_flight = true;
|
op->is_in_flight = true;
|
||||||
trace_mirror_one_iteration(s, op->offset, op->bytes);
|
trace_mirror_one_iteration(s, op->offset, op->bytes);
|
||||||
|
|
||||||
|
WITH_GRAPH_RDLOCK_GUARD() {
|
||||||
ret = bdrv_co_preadv(s->mirror_top_bs->backing, op->offset, op->bytes,
|
ret = bdrv_co_preadv(s->mirror_top_bs->backing, op->offset, op->bytes,
|
||||||
&op->qiov, 0);
|
&op->qiov, 0);
|
||||||
|
}
|
||||||
mirror_read_complete(op, ret);
|
mirror_read_complete(op, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,9 +559,11 @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
|
||||||
MirrorMethod mirror_method = MIRROR_METHOD_COPY;
|
MirrorMethod mirror_method = MIRROR_METHOD_COPY;
|
||||||
|
|
||||||
assert(!(offset % s->granularity));
|
assert(!(offset % s->granularity));
|
||||||
|
WITH_GRAPH_RDLOCK_GUARD() {
|
||||||
ret = bdrv_block_status_above(source, NULL, offset,
|
ret = bdrv_block_status_above(source, NULL, offset,
|
||||||
nb_chunks * s->granularity,
|
nb_chunks * s->granularity,
|
||||||
&io_bytes, NULL, NULL);
|
&io_bytes, NULL, NULL);
|
||||||
|
}
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
io_bytes = MIN(nb_chunks * s->granularity, max_io_bytes);
|
io_bytes = MIN(nb_chunks * s->granularity, max_io_bytes);
|
||||||
} else if (ret & BDRV_BLOCK_DATA) {
|
} else if (ret & BDRV_BLOCK_DATA) {
|
||||||
|
@ -862,8 +866,10 @@ static int coroutine_fn mirror_dirty_init(MirrorBlockJob *s)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = bdrv_is_allocated_above(bs, s->base_overlay, true, offset, bytes,
|
WITH_GRAPH_RDLOCK_GUARD() {
|
||||||
&count);
|
ret = bdrv_is_allocated_above(bs, s->base_overlay, true, offset,
|
||||||
|
bytes, &count);
|
||||||
|
}
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -895,6 +901,7 @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
|
||||||
{
|
{
|
||||||
MirrorBlockJob *s = container_of(job, MirrorBlockJob, common.job);
|
MirrorBlockJob *s = container_of(job, MirrorBlockJob, common.job);
|
||||||
BlockDriverState *bs = s->mirror_top_bs->backing->bs;
|
BlockDriverState *bs = s->mirror_top_bs->backing->bs;
|
||||||
|
MirrorBDSOpaque *mirror_top_opaque = s->mirror_top_bs->opaque;
|
||||||
BlockDriverState *target_bs = blk_bs(s->target);
|
BlockDriverState *target_bs = blk_bs(s->target);
|
||||||
bool need_drain = true;
|
bool need_drain = true;
|
||||||
BlockDeviceIoStatus iostatus;
|
BlockDeviceIoStatus iostatus;
|
||||||
|
@ -909,7 +916,10 @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
|
||||||
goto immediate_exit;
|
goto immediate_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bdrv_graph_co_rdlock();
|
||||||
s->bdev_length = bdrv_co_getlength(bs);
|
s->bdev_length = bdrv_co_getlength(bs);
|
||||||
|
bdrv_graph_co_rdunlock();
|
||||||
|
|
||||||
if (s->bdev_length < 0) {
|
if (s->bdev_length < 0) {
|
||||||
ret = s->bdev_length;
|
ret = s->bdev_length;
|
||||||
goto immediate_exit;
|
goto immediate_exit;
|
||||||
|
@ -984,6 +994,12 @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Only now the job is fully initialised and mirror_top_bs should start
|
||||||
|
* accessing it.
|
||||||
|
*/
|
||||||
|
mirror_top_opaque->job = s;
|
||||||
|
|
||||||
assert(!s->dbi);
|
assert(!s->dbi);
|
||||||
s->dbi = bdrv_dirty_iter_new(s->dirty_bitmap);
|
s->dbi = bdrv_dirty_iter_new(s->dirty_bitmap);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
@ -1425,14 +1441,16 @@ static void coroutine_fn active_write_settle(MirrorOp *op)
|
||||||
g_free(op);
|
g_free(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn bdrv_mirror_top_preadv(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes, QEMUIOVector *qiov, BdrvRequestFlags flags)
|
bdrv_mirror_top_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
|
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
return bdrv_co_preadv(bs->backing, offset, bytes, qiov, flags);
|
return bdrv_co_preadv(bs->backing, offset, bytes, qiov, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn bdrv_mirror_top_do_write(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
MirrorMethod method, uint64_t offset, uint64_t bytes, QEMUIOVector *qiov,
|
bdrv_mirror_top_do_write(BlockDriverState *bs, MirrorMethod method,
|
||||||
|
uint64_t offset, uint64_t bytes, QEMUIOVector *qiov,
|
||||||
int flags)
|
int flags)
|
||||||
{
|
{
|
||||||
MirrorOp *op = NULL;
|
MirrorOp *op = NULL;
|
||||||
|
@ -1482,8 +1500,9 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn bdrv_mirror_top_pwritev(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes, QEMUIOVector *qiov, BdrvRequestFlags flags)
|
bdrv_mirror_top_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
|
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
MirrorBDSOpaque *s = bs->opaque;
|
MirrorBDSOpaque *s = bs->opaque;
|
||||||
QEMUIOVector bounce_qiov;
|
QEMUIOVector bounce_qiov;
|
||||||
|
@ -1523,7 +1542,7 @@ static int coroutine_fn bdrv_mirror_top_pwritev(BlockDriverState *bs,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn bdrv_mirror_top_flush(BlockDriverState *bs)
|
static int coroutine_fn GRAPH_RDLOCK bdrv_mirror_top_flush(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
if (bs->backing == NULL) {
|
if (bs->backing == NULL) {
|
||||||
/* we can be here after failed bdrv_append in mirror_start_job */
|
/* we can be here after failed bdrv_append in mirror_start_job */
|
||||||
|
@ -1532,15 +1551,16 @@ static int coroutine_fn bdrv_mirror_top_flush(BlockDriverState *bs)
|
||||||
return bdrv_co_flush(bs->backing->bs);
|
return bdrv_co_flush(bs->backing->bs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn bdrv_mirror_top_pwrite_zeroes(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes, BdrvRequestFlags flags)
|
bdrv_mirror_top_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
|
||||||
|
int64_t bytes, BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
return bdrv_mirror_top_do_write(bs, MIRROR_METHOD_ZERO, offset, bytes, NULL,
|
return bdrv_mirror_top_do_write(bs, MIRROR_METHOD_ZERO, offset, bytes, NULL,
|
||||||
flags);
|
flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn bdrv_mirror_top_pdiscard(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes)
|
bdrv_mirror_top_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
|
||||||
{
|
{
|
||||||
return bdrv_mirror_top_do_write(bs, MIRROR_METHOD_DISCARD, offset, bytes,
|
return bdrv_mirror_top_do_write(bs, MIRROR_METHOD_DISCARD, offset, bytes,
|
||||||
NULL, 0);
|
NULL, 0);
|
||||||
|
@ -1703,7 +1723,6 @@ static BlockJob *mirror_start_job(
|
||||||
if (!s) {
|
if (!s) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
bs_opaque->job = s;
|
|
||||||
|
|
||||||
/* The block job now has a reference to this node */
|
/* The block job now has a reference to this node */
|
||||||
bdrv_unref(mirror_top_bs);
|
bdrv_unref(mirror_top_bs);
|
||||||
|
|
|
@ -165,8 +165,8 @@ static int64_t block_status(BDRVParallelsState *s, int64_t sector_num,
|
||||||
return start_off;
|
return start_off;
|
||||||
}
|
}
|
||||||
|
|
||||||
static coroutine_fn int64_t allocate_clusters(BlockDriverState *bs,
|
static int64_t coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t sector_num,
|
allocate_clusters(BlockDriverState *bs, int64_t sector_num,
|
||||||
int nb_sectors, int *pnum)
|
int nb_sectors, int *pnum)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
@ -261,7 +261,8 @@ static coroutine_fn int64_t allocate_clusters(BlockDriverState *bs,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static coroutine_fn int parallels_co_flush_to_os(BlockDriverState *bs)
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
|
parallels_co_flush_to_os(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
BDRVParallelsState *s = bs->opaque;
|
BDRVParallelsState *s = bs->opaque;
|
||||||
unsigned long size = DIV_ROUND_UP(s->header_size, s->bat_dirty_block);
|
unsigned long size = DIV_ROUND_UP(s->header_size, s->bat_dirty_block);
|
||||||
|
@ -320,8 +321,8 @@ static int coroutine_fn parallels_co_block_status(BlockDriverState *bs,
|
||||||
return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID;
|
return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
static coroutine_fn int parallels_co_writev(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t sector_num, int nb_sectors,
|
parallels_co_writev(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
|
||||||
QEMUIOVector *qiov, int flags)
|
QEMUIOVector *qiov, int flags)
|
||||||
{
|
{
|
||||||
BDRVParallelsState *s = bs->opaque;
|
BDRVParallelsState *s = bs->opaque;
|
||||||
|
@ -363,8 +364,9 @@ static coroutine_fn int parallels_co_writev(BlockDriverState *bs,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static coroutine_fn int parallels_co_readv(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
|
parallels_co_readv(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
|
||||||
|
QEMUIOVector *qiov)
|
||||||
{
|
{
|
||||||
BDRVParallelsState *s = bs->opaque;
|
BDRVParallelsState *s = bs->opaque;
|
||||||
uint64_t bytes_done = 0;
|
uint64_t bytes_done = 0;
|
||||||
|
@ -414,8 +416,8 @@ static coroutine_fn int parallels_co_readv(BlockDriverState *bs,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int coroutine_fn parallels_co_check(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
BdrvCheckResult *res,
|
parallels_co_check(BlockDriverState *bs, BdrvCheckResult *res,
|
||||||
BdrvCheckMode fix)
|
BdrvCheckMode fix)
|
||||||
{
|
{
|
||||||
BDRVParallelsState *s = bs->opaque;
|
BDRVParallelsState *s = bs->opaque;
|
||||||
|
@ -620,10 +622,9 @@ exit:
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn parallels_co_create_opts(BlockDriver *drv,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
const char *filename,
|
parallels_co_create_opts(BlockDriver *drv, const char *filename,
|
||||||
QemuOpts *opts,
|
QemuOpts *opts, Error **errp)
|
||||||
Error **errp)
|
|
||||||
{
|
{
|
||||||
BlockdevCreateOptions *create_options = NULL;
|
BlockdevCreateOptions *create_options = NULL;
|
||||||
BlockDriverState *bs = NULL;
|
BlockDriverState *bs = NULL;
|
||||||
|
|
|
@ -226,16 +226,17 @@ static void preallocate_reopen_abort(BDRVReopenState *state)
|
||||||
state->opaque = NULL;
|
state->opaque = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static coroutine_fn int preallocate_co_preadv_part(
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
BlockDriverState *bs, int64_t offset, int64_t bytes,
|
preallocate_co_preadv_part(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
QEMUIOVector *qiov, size_t qiov_offset, BdrvRequestFlags flags)
|
QEMUIOVector *qiov, size_t qiov_offset,
|
||||||
|
BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
return bdrv_co_preadv_part(bs->file, offset, bytes, qiov, qiov_offset,
|
return bdrv_co_preadv_part(bs->file, offset, bytes, qiov, qiov_offset,
|
||||||
flags);
|
flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn preallocate_co_pdiscard(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes)
|
preallocate_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
|
||||||
{
|
{
|
||||||
return bdrv_co_pdiscard(bs->file, offset, bytes);
|
return bdrv_co_pdiscard(bs->file, offset, bytes);
|
||||||
}
|
}
|
||||||
|
@ -269,8 +270,9 @@ static bool has_prealloc_perms(BlockDriverState *bs)
|
||||||
* want_merge_zero is used to merge write-zero request with preallocation in
|
* want_merge_zero is used to merge write-zero request with preallocation in
|
||||||
* one bdrv_co_pwrite_zeroes() call.
|
* one bdrv_co_pwrite_zeroes() call.
|
||||||
*/
|
*/
|
||||||
static bool coroutine_fn handle_write(BlockDriverState *bs, int64_t offset,
|
static bool coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t bytes, bool want_merge_zero)
|
handle_write(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
|
bool want_merge_zero)
|
||||||
{
|
{
|
||||||
BDRVPreallocateState *s = bs->opaque;
|
BDRVPreallocateState *s = bs->opaque;
|
||||||
int64_t end = offset + bytes;
|
int64_t end = offset + bytes;
|
||||||
|
@ -345,8 +347,9 @@ static bool coroutine_fn handle_write(BlockDriverState *bs, int64_t offset,
|
||||||
return want_merge_zero;
|
return want_merge_zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn preallocate_co_pwrite_zeroes(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes, BdrvRequestFlags flags)
|
preallocate_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
|
||||||
|
int64_t bytes, BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
bool want_merge_zero =
|
bool want_merge_zero =
|
||||||
!(flags & ~(BDRV_REQ_ZERO_WRITE | BDRV_REQ_NO_FALLBACK));
|
!(flags & ~(BDRV_REQ_ZERO_WRITE | BDRV_REQ_NO_FALLBACK));
|
||||||
|
@ -357,11 +360,9 @@ static int coroutine_fn preallocate_co_pwrite_zeroes(BlockDriverState *bs,
|
||||||
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
|
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static coroutine_fn int preallocate_co_pwritev_part(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset,
|
preallocate_co_pwritev_part(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
int64_t bytes,
|
QEMUIOVector *qiov, size_t qiov_offset,
|
||||||
QEMUIOVector *qiov,
|
|
||||||
size_t qiov_offset,
|
|
||||||
BdrvRequestFlags flags)
|
BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
handle_write(bs, offset, bytes, false);
|
handle_write(bs, offset, bytes, false);
|
||||||
|
@ -370,7 +371,7 @@ static coroutine_fn int preallocate_co_pwritev_part(BlockDriverState *bs,
|
||||||
flags);
|
flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
preallocate_co_truncate(BlockDriverState *bs, int64_t offset,
|
preallocate_co_truncate(BlockDriverState *bs, int64_t offset,
|
||||||
bool exact, PreallocMode prealloc,
|
bool exact, PreallocMode prealloc,
|
||||||
BdrvRequestFlags flags, Error **errp)
|
BdrvRequestFlags flags, Error **errp)
|
||||||
|
@ -437,12 +438,13 @@ preallocate_co_truncate(BlockDriverState *bs, int64_t offset,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn preallocate_co_flush(BlockDriverState *bs)
|
static int coroutine_fn GRAPH_RDLOCK preallocate_co_flush(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
return bdrv_co_flush(bs->file->bs);
|
return bdrv_co_flush(bs->file->bs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int64_t coroutine_fn preallocate_co_getlength(BlockDriverState *bs)
|
static int64_t coroutine_fn GRAPH_RDLOCK
|
||||||
|
preallocate_co_getlength(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
int64_t ret;
|
int64_t ret;
|
||||||
BDRVPreallocateState *s = bs->opaque;
|
BDRVPreallocateState *s = bs->opaque;
|
||||||
|
|
42
block/qcow.c
42
block/qcow.c
|
@ -92,8 +92,8 @@ typedef struct BDRVQcowState {
|
||||||
|
|
||||||
static QemuOptsList qcow_create_opts;
|
static QemuOptsList qcow_create_opts;
|
||||||
|
|
||||||
static int coroutine_fn decompress_cluster(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
uint64_t cluster_offset);
|
decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset);
|
||||||
|
|
||||||
static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename)
|
static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename)
|
||||||
{
|
{
|
||||||
|
@ -350,10 +350,9 @@ static int qcow_reopen_prepare(BDRVReopenState *state,
|
||||||
* return 0 if not allocated, 1 if *result is assigned, and negative
|
* return 0 if not allocated, 1 if *result is assigned, and negative
|
||||||
* errno on failure.
|
* errno on failure.
|
||||||
*/
|
*/
|
||||||
static int coroutine_fn get_cluster_offset(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
uint64_t offset, int allocate,
|
get_cluster_offset(BlockDriverState *bs, uint64_t offset, int allocate,
|
||||||
int compressed_size,
|
int compressed_size, int n_start, int n_end,
|
||||||
int n_start, int n_end,
|
|
||||||
uint64_t *result)
|
uint64_t *result)
|
||||||
{
|
{
|
||||||
BDRVQcowState *s = bs->opaque;
|
BDRVQcowState *s = bs->opaque;
|
||||||
|
@ -525,11 +524,10 @@ static int coroutine_fn get_cluster_offset(BlockDriverState *bs,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn qcow_co_block_status(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
bool want_zero,
|
qcow_co_block_status(BlockDriverState *bs, bool want_zero,
|
||||||
int64_t offset, int64_t bytes,
|
int64_t offset, int64_t bytes, int64_t *pnum,
|
||||||
int64_t *pnum, int64_t *map,
|
int64_t *map, BlockDriverState **file)
|
||||||
BlockDriverState **file)
|
|
||||||
{
|
{
|
||||||
BDRVQcowState *s = bs->opaque;
|
BDRVQcowState *s = bs->opaque;
|
||||||
int index_in_cluster, ret;
|
int index_in_cluster, ret;
|
||||||
|
@ -586,8 +584,8 @@ static int decompress_buffer(uint8_t *out_buf, int out_buf_size,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn decompress_cluster(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
uint64_t cluster_offset)
|
decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset)
|
||||||
{
|
{
|
||||||
BDRVQcowState *s = bs->opaque;
|
BDRVQcowState *s = bs->opaque;
|
||||||
int ret, csize;
|
int ret, csize;
|
||||||
|
@ -619,9 +617,9 @@ static void qcow_refresh_limits(BlockDriverState *bs, Error **errp)
|
||||||
bs->bl.request_alignment = BDRV_SECTOR_SIZE;
|
bs->bl.request_alignment = BDRV_SECTOR_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static coroutine_fn int qcow_co_preadv(BlockDriverState *bs, int64_t offset,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t bytes, QEMUIOVector *qiov,
|
qcow_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
BdrvRequestFlags flags)
|
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
BDRVQcowState *s = bs->opaque;
|
BDRVQcowState *s = bs->opaque;
|
||||||
int offset_in_cluster;
|
int offset_in_cluster;
|
||||||
|
@ -715,9 +713,9 @@ static coroutine_fn int qcow_co_preadv(BlockDriverState *bs, int64_t offset,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static coroutine_fn int qcow_co_pwritev(BlockDriverState *bs, int64_t offset,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t bytes, QEMUIOVector *qiov,
|
qcow_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
BdrvRequestFlags flags)
|
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
BDRVQcowState *s = bs->opaque;
|
BDRVQcowState *s = bs->opaque;
|
||||||
int offset_in_cluster;
|
int offset_in_cluster;
|
||||||
|
@ -923,8 +921,8 @@ exit:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn qcow_co_create_opts(BlockDriver *drv,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
const char *filename,
|
qcow_co_create_opts(BlockDriver *drv, const char *filename,
|
||||||
QemuOpts *opts, Error **errp)
|
QemuOpts *opts, Error **errp)
|
||||||
{
|
{
|
||||||
BlockdevCreateOptions *create_options = NULL;
|
BlockdevCreateOptions *create_options = NULL;
|
||||||
|
@ -1046,7 +1044,7 @@ static int qcow_make_empty(BlockDriverState *bs)
|
||||||
|
|
||||||
/* XXX: put compressed sectors first, then all the cluster aligned
|
/* XXX: put compressed sectors first, then all the cluster aligned
|
||||||
tables to avoid losing bytes in alignment */
|
tables to avoid losing bytes in alignment */
|
||||||
static coroutine_fn int
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
qcow_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
qcow_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
QEMUIOVector *qiov)
|
QEMUIOVector *qiov)
|
||||||
{
|
{
|
||||||
|
|
|
@ -491,10 +491,9 @@ static int count_contiguous_subclusters(BlockDriverState *bs, int nb_clusters,
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn do_perform_cow_read(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
uint64_t src_cluster_offset,
|
do_perform_cow_read(BlockDriverState *bs, uint64_t src_cluster_offset,
|
||||||
unsigned offset_in_cluster,
|
unsigned offset_in_cluster, QEMUIOVector *qiov)
|
||||||
QEMUIOVector *qiov)
|
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -535,10 +534,9 @@ static int coroutine_fn do_perform_cow_read(BlockDriverState *bs,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn do_perform_cow_write(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
uint64_t cluster_offset,
|
do_perform_cow_write(BlockDriverState *bs, uint64_t cluster_offset,
|
||||||
unsigned offset_in_cluster,
|
unsigned offset_in_cluster, QEMUIOVector *qiov)
|
||||||
QEMUIOVector *qiov)
|
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -886,7 +884,8 @@ int coroutine_fn qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn perform_cow(BlockDriverState *bs, QCowL2Meta *m)
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
|
perform_cow(BlockDriverState *bs, QCowL2Meta *m)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
Qcow2COWRegion *start = &m->cow_start;
|
Qcow2COWRegion *start = &m->cow_start;
|
||||||
|
|
128
block/qcow2.c
128
block/qcow2.c
|
@ -601,8 +601,8 @@ static void qcow2_add_check_result(BdrvCheckResult *out,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn qcow2_co_check_locked(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
BdrvCheckResult *result,
|
qcow2_co_check_locked(BlockDriverState *bs, BdrvCheckResult *result,
|
||||||
BdrvCheckMode fix)
|
BdrvCheckMode fix)
|
||||||
{
|
{
|
||||||
BdrvCheckResult snapshot_res = {};
|
BdrvCheckResult snapshot_res = {};
|
||||||
|
@ -640,8 +640,8 @@ static int coroutine_fn qcow2_co_check_locked(BlockDriverState *bs,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn qcow2_co_check(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
BdrvCheckResult *result,
|
qcow2_co_check(BlockDriverState *bs, BdrvCheckResult *result,
|
||||||
BdrvCheckMode fix)
|
BdrvCheckMode fix)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
|
@ -1294,9 +1294,9 @@ static int validate_compression_type(BDRVQcow2State *s, Error **errp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called with s->lock held. */
|
/* Called with s->lock held. */
|
||||||
static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int flags, bool open_data_file,
|
qcow2_do_open(BlockDriverState *bs, QDict *options, int flags,
|
||||||
Error **errp)
|
bool open_data_file, Error **errp)
|
||||||
{
|
{
|
||||||
ERRP_GUARD();
|
ERRP_GUARD();
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
|
@ -1890,6 +1890,8 @@ static void coroutine_fn qcow2_open_entry(void *opaque)
|
||||||
QCow2OpenCo *qoc = opaque;
|
QCow2OpenCo *qoc = opaque;
|
||||||
BDRVQcow2State *s = qoc->bs->opaque;
|
BDRVQcow2State *s = qoc->bs->opaque;
|
||||||
|
|
||||||
|
assume_graph_lock(); /* FIXME */
|
||||||
|
|
||||||
qemu_co_mutex_lock(&s->lock);
|
qemu_co_mutex_lock(&s->lock);
|
||||||
qoc->ret = qcow2_do_open(qoc->bs, qoc->options, qoc->flags, true,
|
qoc->ret = qcow2_do_open(qoc->bs, qoc->options, qoc->flags, true,
|
||||||
qoc->errp);
|
qoc->errp);
|
||||||
|
@ -2137,9 +2139,8 @@ static int coroutine_fn qcow2_co_block_status(BlockDriverState *bs,
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static coroutine_fn int qcow2_handle_l2meta(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
QCowL2Meta **pl2meta,
|
qcow2_handle_l2meta(BlockDriverState *bs, QCowL2Meta **pl2meta, bool link_l2)
|
||||||
bool link_l2)
|
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
QCowL2Meta *l2meta = *pl2meta;
|
QCowL2Meta *l2meta = *pl2meta;
|
||||||
|
@ -2170,7 +2171,7 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static coroutine_fn int
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
qcow2_co_preadv_encrypted(BlockDriverState *bs,
|
qcow2_co_preadv_encrypted(BlockDriverState *bs,
|
||||||
uint64_t host_offset,
|
uint64_t host_offset,
|
||||||
uint64_t offset,
|
uint64_t offset,
|
||||||
|
@ -2271,12 +2272,10 @@ static coroutine_fn int qcow2_add_task(BlockDriverState *bs,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static coroutine_fn int qcow2_co_preadv_task(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
QCow2SubclusterType subc_type,
|
qcow2_co_preadv_task(BlockDriverState *bs, QCow2SubclusterType subc_type,
|
||||||
uint64_t host_offset,
|
uint64_t host_offset, uint64_t offset, uint64_t bytes,
|
||||||
uint64_t offset, uint64_t bytes,
|
QEMUIOVector *qiov, size_t qiov_offset)
|
||||||
QEMUIOVector *qiov,
|
|
||||||
size_t qiov_offset)
|
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
|
|
||||||
|
@ -2315,7 +2314,11 @@ static coroutine_fn int qcow2_co_preadv_task(BlockDriverState *bs,
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
static coroutine_fn int qcow2_co_preadv_task_entry(AioTask *task)
|
/*
|
||||||
|
* This function can count as GRAPH_RDLOCK because qcow2_co_preadv_part() holds
|
||||||
|
* the graph lock and keeps it until this coroutine has terminated.
|
||||||
|
*/
|
||||||
|
static int coroutine_fn GRAPH_RDLOCK qcow2_co_preadv_task_entry(AioTask *task)
|
||||||
{
|
{
|
||||||
Qcow2AioTask *t = container_of(task, Qcow2AioTask, task);
|
Qcow2AioTask *t = container_of(task, Qcow2AioTask, task);
|
||||||
|
|
||||||
|
@ -2326,10 +2329,9 @@ static coroutine_fn int qcow2_co_preadv_task_entry(AioTask *task)
|
||||||
t->qiov, t->qiov_offset);
|
t->qiov, t->qiov_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
static coroutine_fn int qcow2_co_preadv_part(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes,
|
qcow2_co_preadv_part(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
QEMUIOVector *qiov,
|
QEMUIOVector *qiov, size_t qiov_offset,
|
||||||
size_t qiov_offset,
|
|
||||||
BdrvRequestFlags flags)
|
BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
|
@ -2450,7 +2452,8 @@ static bool merge_cow(uint64_t offset, unsigned bytes,
|
||||||
* Return 1 if the COW regions read as zeroes, 0 if not, < 0 on error.
|
* Return 1 if the COW regions read as zeroes, 0 if not, < 0 on error.
|
||||||
* Note that returning 0 does not guarantee non-zero data.
|
* Note that returning 0 does not guarantee non-zero data.
|
||||||
*/
|
*/
|
||||||
static int coroutine_fn is_zero_cow(BlockDriverState *bs, QCowL2Meta *m)
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
|
is_zero_cow(BlockDriverState *bs, QCowL2Meta *m)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* This check is designed for optimization shortcut so it must be
|
* This check is designed for optimization shortcut so it must be
|
||||||
|
@ -2468,8 +2471,8 @@ static int coroutine_fn is_zero_cow(BlockDriverState *bs, QCowL2Meta *m)
|
||||||
m->cow_end.nb_bytes);
|
m->cow_end.nb_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn handle_alloc_space(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
QCowL2Meta *l2meta)
|
handle_alloc_space(BlockDriverState *bs, QCowL2Meta *l2meta)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
QCowL2Meta *m;
|
QCowL2Meta *m;
|
||||||
|
@ -2532,12 +2535,10 @@ static int coroutine_fn handle_alloc_space(BlockDriverState *bs,
|
||||||
* l2meta - if not NULL, qcow2_co_pwritev_task() will consume it. Caller must
|
* l2meta - if not NULL, qcow2_co_pwritev_task() will consume it. Caller must
|
||||||
* not use it somehow after qcow2_co_pwritev_task() call
|
* not use it somehow after qcow2_co_pwritev_task() call
|
||||||
*/
|
*/
|
||||||
static coroutine_fn int qcow2_co_pwritev_task(BlockDriverState *bs,
|
static coroutine_fn GRAPH_RDLOCK
|
||||||
uint64_t host_offset,
|
int qcow2_co_pwritev_task(BlockDriverState *bs, uint64_t host_offset,
|
||||||
uint64_t offset, uint64_t bytes,
|
uint64_t offset, uint64_t bytes, QEMUIOVector *qiov,
|
||||||
QEMUIOVector *qiov,
|
uint64_t qiov_offset, QCowL2Meta *l2meta)
|
||||||
uint64_t qiov_offset,
|
|
||||||
QCowL2Meta *l2meta)
|
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
|
@ -2603,7 +2604,11 @@ out_locked:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static coroutine_fn int qcow2_co_pwritev_task_entry(AioTask *task)
|
/*
|
||||||
|
* This function can count as GRAPH_RDLOCK because qcow2_co_pwritev_part() holds
|
||||||
|
* the graph lock and keeps it until this coroutine has terminated.
|
||||||
|
*/
|
||||||
|
static coroutine_fn GRAPH_RDLOCK int qcow2_co_pwritev_task_entry(AioTask *task)
|
||||||
{
|
{
|
||||||
Qcow2AioTask *t = container_of(task, Qcow2AioTask, task);
|
Qcow2AioTask *t = container_of(task, Qcow2AioTask, task);
|
||||||
|
|
||||||
|
@ -2614,9 +2619,10 @@ static coroutine_fn int qcow2_co_pwritev_task_entry(AioTask *task)
|
||||||
t->l2meta);
|
t->l2meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
static coroutine_fn int qcow2_co_pwritev_part(
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
BlockDriverState *bs, int64_t offset, int64_t bytes,
|
qcow2_co_pwritev_part(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
QEMUIOVector *qiov, size_t qiov_offset, BdrvRequestFlags flags)
|
QEMUIOVector *qiov, size_t qiov_offset,
|
||||||
|
BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
int offset_in_cluster;
|
int offset_in_cluster;
|
||||||
|
@ -2771,8 +2777,8 @@ static void qcow2_close(BlockDriverState *bs)
|
||||||
qcow2_do_close(bs, true);
|
qcow2_do_close(bs, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void coroutine_fn qcow2_co_invalidate_cache(BlockDriverState *bs,
|
static void coroutine_fn GRAPH_RDLOCK
|
||||||
Error **errp)
|
qcow2_co_invalidate_cache(BlockDriverState *bs, Error **errp)
|
||||||
{
|
{
|
||||||
ERRP_GUARD();
|
ERRP_GUARD();
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
|
@ -3183,9 +3189,9 @@ static int qcow2_set_up_encryption(BlockDriverState *bs,
|
||||||
*
|
*
|
||||||
* Returns: 0 on success, -errno on failure.
|
* Returns: 0 on success, -errno on failure.
|
||||||
*/
|
*/
|
||||||
static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
uint64_t new_length, PreallocMode mode,
|
preallocate_co(BlockDriverState *bs, uint64_t offset, uint64_t new_length,
|
||||||
Error **errp)
|
PreallocMode mode, Error **errp)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
uint64_t bytes;
|
uint64_t bytes;
|
||||||
|
@ -3810,9 +3816,8 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn qcow2_co_create_opts(BlockDriver *drv,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
const char *filename,
|
qcow2_co_create_opts(BlockDriver *drv, const char *filename, QemuOpts *opts,
|
||||||
QemuOpts *opts,
|
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
BlockdevCreateOptions *create_options = NULL;
|
BlockdevCreateOptions *create_options = NULL;
|
||||||
|
@ -3974,8 +3979,9 @@ static bool is_zero(BlockDriverState *bs, int64_t offset, int64_t bytes)
|
||||||
return res >= 0 && (res & BDRV_BLOCK_ZERO) && bytes == 0;
|
return res >= 0 && (res & BDRV_BLOCK_ZERO) && bytes == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static coroutine_fn int qcow2_co_pwrite_zeroes(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes, BdrvRequestFlags flags)
|
qcow2_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
|
BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
|
@ -4058,7 +4064,7 @@ static coroutine_fn int qcow2_co_pdiscard(BlockDriverState *bs,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
qcow2_co_copy_range_from(BlockDriverState *bs,
|
qcow2_co_copy_range_from(BlockDriverState *bs,
|
||||||
BdrvChild *src, int64_t src_offset,
|
BdrvChild *src, int64_t src_offset,
|
||||||
BdrvChild *dst, int64_t dst_offset,
|
BdrvChild *dst, int64_t dst_offset,
|
||||||
|
@ -4141,7 +4147,7 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
qcow2_co_copy_range_to(BlockDriverState *bs,
|
qcow2_co_copy_range_to(BlockDriverState *bs,
|
||||||
BdrvChild *src, int64_t src_offset,
|
BdrvChild *src, int64_t src_offset,
|
||||||
BdrvChild *dst, int64_t dst_offset,
|
BdrvChild *dst, int64_t dst_offset,
|
||||||
|
@ -4209,9 +4215,9 @@ fail:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
bool exact, PreallocMode prealloc,
|
qcow2_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
|
||||||
BdrvRequestFlags flags, Error **errp)
|
PreallocMode prealloc, BdrvRequestFlags flags, Error **errp)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
uint64_t old_length;
|
uint64_t old_length;
|
||||||
|
@ -4585,7 +4591,7 @@ fail:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static coroutine_fn int
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
qcow2_co_pwritev_compressed_task(BlockDriverState *bs,
|
qcow2_co_pwritev_compressed_task(BlockDriverState *bs,
|
||||||
uint64_t offset, uint64_t bytes,
|
uint64_t offset, uint64_t bytes,
|
||||||
QEMUIOVector *qiov, size_t qiov_offset)
|
QEMUIOVector *qiov, size_t qiov_offset)
|
||||||
|
@ -4649,7 +4655,13 @@ fail:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static coroutine_fn int qcow2_co_pwritev_compressed_task_entry(AioTask *task)
|
/*
|
||||||
|
* This function can count as GRAPH_RDLOCK because
|
||||||
|
* qcow2_co_pwritev_compressed_part() holds the graph lock and keeps it until
|
||||||
|
* this coroutine has terminated.
|
||||||
|
*/
|
||||||
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
|
qcow2_co_pwritev_compressed_task_entry(AioTask *task)
|
||||||
{
|
{
|
||||||
Qcow2AioTask *t = container_of(task, Qcow2AioTask, task);
|
Qcow2AioTask *t = container_of(task, Qcow2AioTask, task);
|
||||||
|
|
||||||
|
@ -4663,7 +4675,7 @@ static coroutine_fn int qcow2_co_pwritev_compressed_task_entry(AioTask *task)
|
||||||
* XXX: put compressed sectors first, then all the cluster aligned
|
* XXX: put compressed sectors first, then all the cluster aligned
|
||||||
* tables to avoid losing bytes in alignment
|
* tables to avoid losing bytes in alignment
|
||||||
*/
|
*/
|
||||||
static coroutine_fn int
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
qcow2_co_pwritev_compressed_part(BlockDriverState *bs,
|
qcow2_co_pwritev_compressed_part(BlockDriverState *bs,
|
||||||
int64_t offset, int64_t bytes,
|
int64_t offset, int64_t bytes,
|
||||||
QEMUIOVector *qiov, size_t qiov_offset)
|
QEMUIOVector *qiov, size_t qiov_offset)
|
||||||
|
@ -4726,7 +4738,7 @@ qcow2_co_pwritev_compressed_part(BlockDriverState *bs,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
qcow2_co_preadv_compressed(BlockDriverState *bs,
|
qcow2_co_preadv_compressed(BlockDriverState *bs,
|
||||||
uint64_t l2_entry,
|
uint64_t l2_entry,
|
||||||
uint64_t offset,
|
uint64_t offset,
|
||||||
|
@ -5288,8 +5300,8 @@ static int64_t qcow2_check_vmstate_request(BlockDriverState *bs,
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
static coroutine_fn int qcow2_co_save_vmstate(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
QEMUIOVector *qiov, int64_t pos)
|
qcow2_co_save_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos)
|
||||||
{
|
{
|
||||||
int64_t offset = qcow2_check_vmstate_request(bs, qiov, pos);
|
int64_t offset = qcow2_check_vmstate_request(bs, qiov, pos);
|
||||||
if (offset < 0) {
|
if (offset < 0) {
|
||||||
|
@ -5300,8 +5312,8 @@ static coroutine_fn int qcow2_co_save_vmstate(BlockDriverState *bs,
|
||||||
return bs->drv->bdrv_co_pwritev_part(bs, offset, qiov->size, qiov, 0, 0);
|
return bs->drv->bdrv_co_pwritev_part(bs, offset, qiov->size, qiov, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static coroutine_fn int qcow2_co_load_vmstate(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
QEMUIOVector *qiov, int64_t pos)
|
qcow2_co_load_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos)
|
||||||
{
|
{
|
||||||
int64_t offset = qcow2_check_vmstate_request(bs, qiov, pos);
|
int64_t offset = qcow2_check_vmstate_request(bs, qiov, pos);
|
||||||
if (offset < 0) {
|
if (offset < 0) {
|
||||||
|
|
|
@ -846,7 +846,7 @@ int qcow2_validate_table(BlockDriverState *bs, uint64_t offset,
|
||||||
Error **errp);
|
Error **errp);
|
||||||
|
|
||||||
/* qcow2-refcount.c functions */
|
/* qcow2-refcount.c functions */
|
||||||
int coroutine_fn qcow2_refcount_init(BlockDriverState *bs);
|
int coroutine_fn GRAPH_RDLOCK qcow2_refcount_init(BlockDriverState *bs);
|
||||||
void qcow2_refcount_close(BlockDriverState *bs);
|
void qcow2_refcount_close(BlockDriverState *bs);
|
||||||
|
|
||||||
int qcow2_get_refcount(BlockDriverState *bs, int64_t cluster_index,
|
int qcow2_get_refcount(BlockDriverState *bs, int64_t cluster_index,
|
||||||
|
@ -893,14 +893,17 @@ int qcow2_inc_refcounts_imrt(BlockDriverState *bs, BdrvCheckResult *res,
|
||||||
int qcow2_change_refcount_order(BlockDriverState *bs, int refcount_order,
|
int qcow2_change_refcount_order(BlockDriverState *bs, int refcount_order,
|
||||||
BlockDriverAmendStatusCB *status_cb,
|
BlockDriverAmendStatusCB *status_cb,
|
||||||
void *cb_opaque, Error **errp);
|
void *cb_opaque, Error **errp);
|
||||||
int coroutine_fn qcow2_shrink_reftable(BlockDriverState *bs);
|
int coroutine_fn GRAPH_RDLOCK qcow2_shrink_reftable(BlockDriverState *bs);
|
||||||
int64_t qcow2_get_last_cluster(BlockDriverState *bs, int64_t size);
|
int64_t qcow2_get_last_cluster(BlockDriverState *bs, int64_t size);
|
||||||
int coroutine_fn qcow2_detect_metadata_preallocation(BlockDriverState *bs);
|
int coroutine_fn qcow2_detect_metadata_preallocation(BlockDriverState *bs);
|
||||||
|
|
||||||
/* qcow2-cluster.c functions */
|
/* qcow2-cluster.c functions */
|
||||||
int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
|
int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
|
||||||
bool exact_size);
|
bool exact_size);
|
||||||
int coroutine_fn qcow2_shrink_l1_table(BlockDriverState *bs, uint64_t max_size);
|
|
||||||
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
|
qcow2_shrink_l1_table(BlockDriverState *bs, uint64_t max_size);
|
||||||
|
|
||||||
int qcow2_write_l1_entry(BlockDriverState *bs, int l1_index);
|
int qcow2_write_l1_entry(BlockDriverState *bs, int l1_index);
|
||||||
int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num,
|
int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num,
|
||||||
uint8_t *buf, int nb_sectors, bool enc, Error **errp);
|
uint8_t *buf, int nb_sectors, bool enc, Error **errp);
|
||||||
|
@ -918,14 +921,17 @@ int coroutine_fn qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
|
||||||
void qcow2_parse_compressed_l2_entry(BlockDriverState *bs, uint64_t l2_entry,
|
void qcow2_parse_compressed_l2_entry(BlockDriverState *bs, uint64_t l2_entry,
|
||||||
uint64_t *coffset, int *csize);
|
uint64_t *coffset, int *csize);
|
||||||
|
|
||||||
int coroutine_fn qcow2_alloc_cluster_link_l2(BlockDriverState *bs,
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
QCowL2Meta *m);
|
qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m);
|
||||||
|
|
||||||
void qcow2_alloc_cluster_abort(BlockDriverState *bs, QCowL2Meta *m);
|
void qcow2_alloc_cluster_abort(BlockDriverState *bs, QCowL2Meta *m);
|
||||||
int qcow2_cluster_discard(BlockDriverState *bs, uint64_t offset,
|
int qcow2_cluster_discard(BlockDriverState *bs, uint64_t offset,
|
||||||
uint64_t bytes, enum qcow2_discard_type type,
|
uint64_t bytes, enum qcow2_discard_type type,
|
||||||
bool full_discard);
|
bool full_discard);
|
||||||
int coroutine_fn qcow2_subcluster_zeroize(BlockDriverState *bs, uint64_t offset,
|
|
||||||
uint64_t bytes, int flags);
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
|
qcow2_subcluster_zeroize(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
|
||||||
|
int flags);
|
||||||
|
|
||||||
int qcow2_expand_zero_clusters(BlockDriverState *bs,
|
int qcow2_expand_zero_clusters(BlockDriverState *bs,
|
||||||
BlockDriverAmendStatusCB *status_cb,
|
BlockDriverAmendStatusCB *status_cb,
|
||||||
|
@ -948,9 +954,10 @@ void qcow2_free_snapshots(BlockDriverState *bs);
|
||||||
int qcow2_read_snapshots(BlockDriverState *bs, Error **errp);
|
int qcow2_read_snapshots(BlockDriverState *bs, Error **errp);
|
||||||
int qcow2_write_snapshots(BlockDriverState *bs);
|
int qcow2_write_snapshots(BlockDriverState *bs);
|
||||||
|
|
||||||
int coroutine_fn qcow2_check_read_snapshot_table(BlockDriverState *bs,
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
BdrvCheckResult *result,
|
qcow2_check_read_snapshot_table(BlockDriverState *bs, BdrvCheckResult *result,
|
||||||
BdrvCheckMode fix);
|
BdrvCheckMode fix);
|
||||||
|
|
||||||
int coroutine_fn qcow2_check_fix_snapshot_table(BlockDriverState *bs,
|
int coroutine_fn qcow2_check_fix_snapshot_table(BlockDriverState *bs,
|
||||||
BdrvCheckResult *result,
|
BdrvCheckResult *result,
|
||||||
BdrvCheckMode fix);
|
BdrvCheckMode fix);
|
||||||
|
|
|
@ -107,7 +107,8 @@ static unsigned int qed_check_l2_table(QEDCheck *check, QEDTable *table)
|
||||||
/**
|
/**
|
||||||
* Descend tables and check each cluster is referenced once only
|
* Descend tables and check each cluster is referenced once only
|
||||||
*/
|
*/
|
||||||
static int coroutine_fn qed_check_l1_table(QEDCheck *check, QEDTable *table)
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
|
qed_check_l1_table(QEDCheck *check, QEDTable *table)
|
||||||
{
|
{
|
||||||
BDRVQEDState *s = check->s;
|
BDRVQEDState *s = check->s;
|
||||||
unsigned int i, num_invalid_l1 = 0;
|
unsigned int i, num_invalid_l1 = 0;
|
||||||
|
|
|
@ -21,8 +21,8 @@
|
||||||
#include "qemu/memalign.h"
|
#include "qemu/memalign.h"
|
||||||
|
|
||||||
/* Called with table_lock held. */
|
/* Called with table_lock held. */
|
||||||
static int coroutine_fn qed_read_table(BDRVQEDState *s, uint64_t offset,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
QEDTable *table)
|
qed_read_table(BDRVQEDState *s, uint64_t offset, QEDTable *table)
|
||||||
{
|
{
|
||||||
unsigned int bytes = s->header.cluster_size * s->header.table_size;
|
unsigned int bytes = s->header.cluster_size * s->header.table_size;
|
||||||
|
|
||||||
|
@ -63,9 +63,9 @@ out:
|
||||||
*
|
*
|
||||||
* Called with table_lock held.
|
* Called with table_lock held.
|
||||||
*/
|
*/
|
||||||
static int coroutine_fn qed_write_table(BDRVQEDState *s, uint64_t offset,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
QEDTable *table, unsigned int index,
|
qed_write_table(BDRVQEDState *s, uint64_t offset, QEDTable *table,
|
||||||
unsigned int n, bool flush)
|
unsigned int index, unsigned int n, bool flush)
|
||||||
{
|
{
|
||||||
unsigned int sector_mask = BDRV_SECTOR_SIZE / sizeof(uint64_t) - 1;
|
unsigned int sector_mask = BDRV_SECTOR_SIZE / sizeof(uint64_t) - 1;
|
||||||
unsigned int start, end, i;
|
unsigned int start, end, i;
|
||||||
|
|
89
block/qed.c
89
block/qed.c
|
@ -100,7 +100,7 @@ int qed_write_header_sync(BDRVQEDState *s)
|
||||||
*
|
*
|
||||||
* No new allocating reqs can start while this function runs.
|
* No new allocating reqs can start while this function runs.
|
||||||
*/
|
*/
|
||||||
static int coroutine_fn qed_write_header(BDRVQEDState *s)
|
static int coroutine_fn GRAPH_RDLOCK qed_write_header(BDRVQEDState *s)
|
||||||
{
|
{
|
||||||
/* We must write full sectors for O_DIRECT but cannot necessarily generate
|
/* We must write full sectors for O_DIRECT but cannot necessarily generate
|
||||||
* the data following the header if an unrecognized compat feature is
|
* the data following the header if an unrecognized compat feature is
|
||||||
|
@ -282,11 +282,12 @@ static void coroutine_fn qed_unplug_allocating_write_reqs(BDRVQEDState *s)
|
||||||
qemu_co_mutex_unlock(&s->table_lock);
|
qemu_co_mutex_unlock(&s->table_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void coroutine_fn qed_need_check_timer(BDRVQEDState *s)
|
static void coroutine_fn GRAPH_RDLOCK qed_need_check_timer(BDRVQEDState *s)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
trace_qed_need_check_timer_cb(s);
|
trace_qed_need_check_timer_cb(s);
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
|
|
||||||
if (!qed_plug_allocating_write_reqs(s)) {
|
if (!qed_plug_allocating_write_reqs(s)) {
|
||||||
return;
|
return;
|
||||||
|
@ -312,6 +313,7 @@ static void coroutine_fn qed_need_check_timer(BDRVQEDState *s)
|
||||||
static void coroutine_fn qed_need_check_timer_entry(void *opaque)
|
static void coroutine_fn qed_need_check_timer_entry(void *opaque)
|
||||||
{
|
{
|
||||||
BDRVQEDState *s = opaque;
|
BDRVQEDState *s = opaque;
|
||||||
|
GRAPH_RDLOCK_GUARD();
|
||||||
|
|
||||||
qed_need_check_timer(opaque);
|
qed_need_check_timer(opaque);
|
||||||
bdrv_dec_in_flight(s->bs);
|
bdrv_dec_in_flight(s->bs);
|
||||||
|
@ -393,8 +395,8 @@ static void bdrv_qed_init_state(BlockDriverState *bs)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called with table_lock held. */
|
/* Called with table_lock held. */
|
||||||
static int coroutine_fn bdrv_qed_do_open(BlockDriverState *bs, QDict *options,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int flags, Error **errp)
|
bdrv_qed_do_open(BlockDriverState *bs, QDict *options, int flags, Error **errp)
|
||||||
{
|
{
|
||||||
BDRVQEDState *s = bs->opaque;
|
BDRVQEDState *s = bs->opaque;
|
||||||
QEDHeader le_header;
|
QEDHeader le_header;
|
||||||
|
@ -555,7 +557,7 @@ typedef struct QEDOpenCo {
|
||||||
int ret;
|
int ret;
|
||||||
} QEDOpenCo;
|
} QEDOpenCo;
|
||||||
|
|
||||||
static void coroutine_fn bdrv_qed_open_entry(void *opaque)
|
static void coroutine_fn GRAPH_RDLOCK bdrv_qed_open_entry(void *opaque)
|
||||||
{
|
{
|
||||||
QEDOpenCo *qoc = opaque;
|
QEDOpenCo *qoc = opaque;
|
||||||
BDRVQEDState *s = qoc->bs->opaque;
|
BDRVQEDState *s = qoc->bs->opaque;
|
||||||
|
@ -577,6 +579,8 @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
|
||||||
};
|
};
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
assume_graph_lock(); /* FIXME */
|
||||||
|
|
||||||
ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
|
ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -750,10 +754,9 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn bdrv_qed_co_create_opts(BlockDriver *drv,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
const char *filename,
|
bdrv_qed_co_create_opts(BlockDriver *drv, const char *filename,
|
||||||
QemuOpts *opts,
|
QemuOpts *opts, Error **errp)
|
||||||
Error **errp)
|
|
||||||
{
|
{
|
||||||
BlockdevCreateOptions *create_options = NULL;
|
BlockdevCreateOptions *create_options = NULL;
|
||||||
QDict *qdict;
|
QDict *qdict;
|
||||||
|
@ -822,10 +825,9 @@ fail:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn bdrv_qed_co_block_status(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
bool want_zero,
|
bdrv_qed_co_block_status(BlockDriverState *bs, bool want_zero, int64_t pos,
|
||||||
int64_t pos, int64_t bytes,
|
int64_t bytes, int64_t *pnum, int64_t *map,
|
||||||
int64_t *pnum, int64_t *map,
|
|
||||||
BlockDriverState **file)
|
BlockDriverState **file)
|
||||||
{
|
{
|
||||||
BDRVQEDState *s = bs->opaque;
|
BDRVQEDState *s = bs->opaque;
|
||||||
|
@ -879,8 +881,8 @@ static BDRVQEDState *acb_to_s(QEDAIOCB *acb)
|
||||||
* This function reads qiov->size bytes starting at pos from the backing file.
|
* This function reads qiov->size bytes starting at pos from the backing file.
|
||||||
* If there is no backing file then zeroes are read.
|
* If there is no backing file then zeroes are read.
|
||||||
*/
|
*/
|
||||||
static int coroutine_fn qed_read_backing_file(BDRVQEDState *s, uint64_t pos,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
QEMUIOVector *qiov)
|
qed_read_backing_file(BDRVQEDState *s, uint64_t pos, QEMUIOVector *qiov)
|
||||||
{
|
{
|
||||||
if (s->bs->backing) {
|
if (s->bs->backing) {
|
||||||
BLKDBG_EVENT(s->bs->file, BLKDBG_READ_BACKING_AIO);
|
BLKDBG_EVENT(s->bs->file, BLKDBG_READ_BACKING_AIO);
|
||||||
|
@ -898,8 +900,8 @@ static int coroutine_fn qed_read_backing_file(BDRVQEDState *s, uint64_t pos,
|
||||||
* @len: Number of bytes
|
* @len: Number of bytes
|
||||||
* @offset: Byte offset in image file
|
* @offset: Byte offset in image file
|
||||||
*/
|
*/
|
||||||
static int coroutine_fn qed_copy_from_backing_file(BDRVQEDState *s,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
uint64_t pos, uint64_t len,
|
qed_copy_from_backing_file(BDRVQEDState *s, uint64_t pos, uint64_t len,
|
||||||
uint64_t offset)
|
uint64_t offset)
|
||||||
{
|
{
|
||||||
QEMUIOVector qiov;
|
QEMUIOVector qiov;
|
||||||
|
@ -993,7 +995,7 @@ static void coroutine_fn qed_aio_complete(QEDAIOCB *acb)
|
||||||
*
|
*
|
||||||
* Called with table_lock held.
|
* Called with table_lock held.
|
||||||
*/
|
*/
|
||||||
static int coroutine_fn qed_aio_write_l1_update(QEDAIOCB *acb)
|
static int coroutine_fn GRAPH_RDLOCK qed_aio_write_l1_update(QEDAIOCB *acb)
|
||||||
{
|
{
|
||||||
BDRVQEDState *s = acb_to_s(acb);
|
BDRVQEDState *s = acb_to_s(acb);
|
||||||
CachedL2Table *l2_table = acb->request.l2_table;
|
CachedL2Table *l2_table = acb->request.l2_table;
|
||||||
|
@ -1023,7 +1025,8 @@ static int coroutine_fn qed_aio_write_l1_update(QEDAIOCB *acb)
|
||||||
*
|
*
|
||||||
* Called with table_lock held.
|
* Called with table_lock held.
|
||||||
*/
|
*/
|
||||||
static int coroutine_fn qed_aio_write_l2_update(QEDAIOCB *acb, uint64_t offset)
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
|
qed_aio_write_l2_update(QEDAIOCB *acb, uint64_t offset)
|
||||||
{
|
{
|
||||||
BDRVQEDState *s = acb_to_s(acb);
|
BDRVQEDState *s = acb_to_s(acb);
|
||||||
bool need_alloc = acb->find_cluster_ret == QED_CLUSTER_L1;
|
bool need_alloc = acb->find_cluster_ret == QED_CLUSTER_L1;
|
||||||
|
@ -1061,7 +1064,7 @@ static int coroutine_fn qed_aio_write_l2_update(QEDAIOCB *acb, uint64_t offset)
|
||||||
*
|
*
|
||||||
* Called with table_lock *not* held.
|
* Called with table_lock *not* held.
|
||||||
*/
|
*/
|
||||||
static int coroutine_fn qed_aio_write_main(QEDAIOCB *acb)
|
static int coroutine_fn GRAPH_RDLOCK qed_aio_write_main(QEDAIOCB *acb)
|
||||||
{
|
{
|
||||||
BDRVQEDState *s = acb_to_s(acb);
|
BDRVQEDState *s = acb_to_s(acb);
|
||||||
uint64_t offset = acb->cur_cluster +
|
uint64_t offset = acb->cur_cluster +
|
||||||
|
@ -1079,7 +1082,7 @@ static int coroutine_fn qed_aio_write_main(QEDAIOCB *acb)
|
||||||
*
|
*
|
||||||
* Called with table_lock held.
|
* Called with table_lock held.
|
||||||
*/
|
*/
|
||||||
static int coroutine_fn qed_aio_write_cow(QEDAIOCB *acb)
|
static int coroutine_fn GRAPH_RDLOCK qed_aio_write_cow(QEDAIOCB *acb)
|
||||||
{
|
{
|
||||||
BDRVQEDState *s = acb_to_s(acb);
|
BDRVQEDState *s = acb_to_s(acb);
|
||||||
uint64_t start, len, offset;
|
uint64_t start, len, offset;
|
||||||
|
@ -1157,7 +1160,8 @@ static bool qed_should_set_need_check(BDRVQEDState *s)
|
||||||
*
|
*
|
||||||
* Called with table_lock held.
|
* Called with table_lock held.
|
||||||
*/
|
*/
|
||||||
static int coroutine_fn qed_aio_write_alloc(QEDAIOCB *acb, size_t len)
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
|
qed_aio_write_alloc(QEDAIOCB *acb, size_t len)
|
||||||
{
|
{
|
||||||
BDRVQEDState *s = acb_to_s(acb);
|
BDRVQEDState *s = acb_to_s(acb);
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -1220,8 +1224,8 @@ static int coroutine_fn qed_aio_write_alloc(QEDAIOCB *acb, size_t len)
|
||||||
*
|
*
|
||||||
* Called with table_lock held.
|
* Called with table_lock held.
|
||||||
*/
|
*/
|
||||||
static int coroutine_fn qed_aio_write_inplace(QEDAIOCB *acb, uint64_t offset,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
size_t len)
|
qed_aio_write_inplace(QEDAIOCB *acb, uint64_t offset, size_t len)
|
||||||
{
|
{
|
||||||
BDRVQEDState *s = acb_to_s(acb);
|
BDRVQEDState *s = acb_to_s(acb);
|
||||||
int r;
|
int r;
|
||||||
|
@ -1263,8 +1267,8 @@ out:
|
||||||
*
|
*
|
||||||
* Called with table_lock held.
|
* Called with table_lock held.
|
||||||
*/
|
*/
|
||||||
static int coroutine_fn qed_aio_write_data(void *opaque, int ret,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
uint64_t offset, size_t len)
|
qed_aio_write_data(void *opaque, int ret, uint64_t offset, size_t len)
|
||||||
{
|
{
|
||||||
QEDAIOCB *acb = opaque;
|
QEDAIOCB *acb = opaque;
|
||||||
|
|
||||||
|
@ -1296,8 +1300,8 @@ static int coroutine_fn qed_aio_write_data(void *opaque, int ret,
|
||||||
*
|
*
|
||||||
* Called with table_lock held.
|
* Called with table_lock held.
|
||||||
*/
|
*/
|
||||||
static int coroutine_fn qed_aio_read_data(void *opaque, int ret,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
uint64_t offset, size_t len)
|
qed_aio_read_data(void *opaque, int ret, uint64_t offset, size_t len)
|
||||||
{
|
{
|
||||||
QEDAIOCB *acb = opaque;
|
QEDAIOCB *acb = opaque;
|
||||||
BDRVQEDState *s = acb_to_s(acb);
|
BDRVQEDState *s = acb_to_s(acb);
|
||||||
|
@ -1334,7 +1338,7 @@ static int coroutine_fn qed_aio_read_data(void *opaque, int ret,
|
||||||
/**
|
/**
|
||||||
* Begin next I/O or complete the request
|
* Begin next I/O or complete the request
|
||||||
*/
|
*/
|
||||||
static int coroutine_fn qed_aio_next_io(QEDAIOCB *acb)
|
static int coroutine_fn GRAPH_RDLOCK qed_aio_next_io(QEDAIOCB *acb)
|
||||||
{
|
{
|
||||||
BDRVQEDState *s = acb_to_s(acb);
|
BDRVQEDState *s = acb_to_s(acb);
|
||||||
uint64_t offset;
|
uint64_t offset;
|
||||||
|
@ -1379,9 +1383,9 @@ static int coroutine_fn qed_aio_next_io(QEDAIOCB *acb)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn qed_co_request(BlockDriverState *bs, int64_t sector_num,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
QEMUIOVector *qiov, int nb_sectors,
|
qed_co_request(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov,
|
||||||
int flags)
|
int nb_sectors, int flags)
|
||||||
{
|
{
|
||||||
QEDAIOCB acb = {
|
QEDAIOCB acb = {
|
||||||
.bs = bs,
|
.bs = bs,
|
||||||
|
@ -1398,23 +1402,22 @@ static int coroutine_fn qed_co_request(BlockDriverState *bs, int64_t sector_num,
|
||||||
return qed_aio_next_io(&acb);
|
return qed_aio_next_io(&acb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn bdrv_qed_co_readv(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t sector_num, int nb_sectors,
|
bdrv_qed_co_readv(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
|
||||||
QEMUIOVector *qiov)
|
QEMUIOVector *qiov)
|
||||||
{
|
{
|
||||||
return qed_co_request(bs, sector_num, qiov, nb_sectors, 0);
|
return qed_co_request(bs, sector_num, qiov, nb_sectors, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn bdrv_qed_co_writev(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t sector_num, int nb_sectors,
|
bdrv_qed_co_writev(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
|
||||||
QEMUIOVector *qiov, int flags)
|
QEMUIOVector *qiov, int flags)
|
||||||
{
|
{
|
||||||
return qed_co_request(bs, sector_num, qiov, nb_sectors, QED_AIOCB_WRITE);
|
return qed_co_request(bs, sector_num, qiov, nb_sectors, QED_AIOCB_WRITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn bdrv_qed_co_pwrite_zeroes(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset,
|
bdrv_qed_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
int64_t bytes,
|
|
||||||
BdrvRequestFlags flags)
|
BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
BDRVQEDState *s = bs->opaque;
|
BDRVQEDState *s = bs->opaque;
|
||||||
|
@ -1569,8 +1572,8 @@ static int bdrv_qed_change_backing_file(BlockDriverState *bs,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void coroutine_fn bdrv_qed_co_invalidate_cache(BlockDriverState *bs,
|
static void coroutine_fn GRAPH_RDLOCK
|
||||||
Error **errp)
|
bdrv_qed_co_invalidate_cache(BlockDriverState *bs, Error **errp)
|
||||||
{
|
{
|
||||||
BDRVQEDState *s = bs->opaque;
|
BDRVQEDState *s = bs->opaque;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -1586,8 +1589,8 @@ static void coroutine_fn bdrv_qed_co_invalidate_cache(BlockDriverState *bs,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn bdrv_qed_co_check(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
BdrvCheckResult *result,
|
bdrv_qed_co_check(BlockDriverState *bs, BdrvCheckResult *result,
|
||||||
BdrvCheckMode fix)
|
BdrvCheckMode fix)
|
||||||
{
|
{
|
||||||
BDRVQEDState *s = bs->opaque;
|
BDRVQEDState *s = bs->opaque;
|
||||||
|
|
45
block/qed.h
45
block/qed.h
|
@ -200,33 +200,40 @@ void qed_commit_l2_cache_entry(L2TableCache *l2_cache, CachedL2Table *l2_table);
|
||||||
/**
|
/**
|
||||||
* Table I/O functions
|
* Table I/O functions
|
||||||
*/
|
*/
|
||||||
int coroutine_fn qed_read_l1_table_sync(BDRVQEDState *s);
|
int coroutine_fn GRAPH_RDLOCK qed_read_l1_table_sync(BDRVQEDState *s);
|
||||||
int coroutine_fn qed_write_l1_table(BDRVQEDState *s, unsigned int index,
|
|
||||||
unsigned int n);
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
int coroutine_fn qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index,
|
qed_write_l1_table(BDRVQEDState *s, unsigned int index, unsigned int n);
|
||||||
unsigned int n);
|
|
||||||
int coroutine_fn qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
uint64_t offset);
|
qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index, unsigned int n);
|
||||||
int coroutine_fn qed_read_l2_table(BDRVQEDState *s, QEDRequest *request,
|
|
||||||
uint64_t offset);
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
int coroutine_fn qed_write_l2_table(BDRVQEDState *s, QEDRequest *request,
|
qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request, uint64_t offset);
|
||||||
unsigned int index, unsigned int n,
|
|
||||||
bool flush);
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
int coroutine_fn qed_write_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
|
qed_read_l2_table(BDRVQEDState *s, QEDRequest *request, uint64_t offset);
|
||||||
unsigned int index, unsigned int n,
|
|
||||||
bool flush);
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
|
qed_write_l2_table(BDRVQEDState *s, QEDRequest *request, unsigned int index,
|
||||||
|
unsigned int n, bool flush);
|
||||||
|
|
||||||
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
|
qed_write_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
|
||||||
|
unsigned int index, unsigned int n, bool flush);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cluster functions
|
* Cluster functions
|
||||||
*/
|
*/
|
||||||
int coroutine_fn qed_find_cluster(BDRVQEDState *s, QEDRequest *request,
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
uint64_t pos, size_t *len,
|
qed_find_cluster(BDRVQEDState *s, QEDRequest *request, uint64_t pos,
|
||||||
uint64_t *img_offset);
|
size_t *len, uint64_t *img_offset);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Consistency check
|
* Consistency check
|
||||||
*/
|
*/
|
||||||
int coroutine_fn qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix);
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
|
qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix);
|
||||||
|
|
||||||
QEDTable *qed_alloc_table(BDRVQEDState *s);
|
QEDTable *qed_alloc_table(BDRVQEDState *s);
|
||||||
|
|
||||||
|
|
|
@ -270,7 +270,11 @@ static void quorum_report_bad_versions(BDRVQuorumState *s,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void coroutine_fn quorum_rewrite_entry(void *opaque)
|
/*
|
||||||
|
* This function can count as GRAPH_RDLOCK because read_quorum_children() holds
|
||||||
|
* the graph lock and keeps it until this coroutine has terminated.
|
||||||
|
*/
|
||||||
|
static void coroutine_fn GRAPH_RDLOCK quorum_rewrite_entry(void *opaque)
|
||||||
{
|
{
|
||||||
QuorumCo *co = opaque;
|
QuorumCo *co = opaque;
|
||||||
QuorumAIOCB *acb = co->acb;
|
QuorumAIOCB *acb = co->acb;
|
||||||
|
@ -290,8 +294,8 @@ static void coroutine_fn quorum_rewrite_entry(void *opaque)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool quorum_rewrite_bad_versions(QuorumAIOCB *acb,
|
static bool coroutine_fn GRAPH_RDLOCK
|
||||||
QuorumVoteValue *value)
|
quorum_rewrite_bad_versions(QuorumAIOCB *acb, QuorumVoteValue *value)
|
||||||
{
|
{
|
||||||
QuorumVoteVersion *version;
|
QuorumVoteVersion *version;
|
||||||
QuorumVoteItem *item;
|
QuorumVoteItem *item;
|
||||||
|
@ -491,7 +495,7 @@ static int quorum_vote_error(QuorumAIOCB *acb)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void quorum_vote(QuorumAIOCB *acb)
|
static void coroutine_fn GRAPH_RDLOCK quorum_vote(QuorumAIOCB *acb)
|
||||||
{
|
{
|
||||||
bool quorum = true;
|
bool quorum = true;
|
||||||
int i, j, ret;
|
int i, j, ret;
|
||||||
|
@ -571,7 +575,11 @@ free_exit:
|
||||||
quorum_free_vote_list(&acb->votes);
|
quorum_free_vote_list(&acb->votes);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void coroutine_fn read_quorum_children_entry(void *opaque)
|
/*
|
||||||
|
* This function can count as GRAPH_RDLOCK because read_quorum_children() holds
|
||||||
|
* the graph lock and keeps it until this coroutine has terminated.
|
||||||
|
*/
|
||||||
|
static void coroutine_fn GRAPH_RDLOCK read_quorum_children_entry(void *opaque)
|
||||||
{
|
{
|
||||||
QuorumCo *co = opaque;
|
QuorumCo *co = opaque;
|
||||||
QuorumAIOCB *acb = co->acb;
|
QuorumAIOCB *acb = co->acb;
|
||||||
|
@ -599,7 +607,7 @@ static void coroutine_fn read_quorum_children_entry(void *opaque)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn read_quorum_children(QuorumAIOCB *acb)
|
static int coroutine_fn GRAPH_RDLOCK read_quorum_children(QuorumAIOCB *acb)
|
||||||
{
|
{
|
||||||
BDRVQuorumState *s = acb->bs->opaque;
|
BDRVQuorumState *s = acb->bs->opaque;
|
||||||
int i;
|
int i;
|
||||||
|
@ -640,7 +648,7 @@ static int coroutine_fn read_quorum_children(QuorumAIOCB *acb)
|
||||||
return acb->vote_ret;
|
return acb->vote_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn read_fifo_child(QuorumAIOCB *acb)
|
static int coroutine_fn GRAPH_RDLOCK read_fifo_child(QuorumAIOCB *acb)
|
||||||
{
|
{
|
||||||
BDRVQuorumState *s = acb->bs->opaque;
|
BDRVQuorumState *s = acb->bs->opaque;
|
||||||
int n, ret;
|
int n, ret;
|
||||||
|
@ -661,10 +669,9 @@ static int coroutine_fn read_fifo_child(QuorumAIOCB *acb)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn quorum_co_preadv(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes,
|
quorum_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
QEMUIOVector *qiov,
|
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
||||||
BdrvRequestFlags flags)
|
|
||||||
{
|
{
|
||||||
BDRVQuorumState *s = bs->opaque;
|
BDRVQuorumState *s = bs->opaque;
|
||||||
QuorumAIOCB *acb = quorum_aio_get(bs, qiov, offset, bytes, flags);
|
QuorumAIOCB *acb = quorum_aio_get(bs, qiov, offset, bytes, flags);
|
||||||
|
@ -683,7 +690,11 @@ static int coroutine_fn quorum_co_preadv(BlockDriverState *bs,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void coroutine_fn write_quorum_entry(void *opaque)
|
/*
|
||||||
|
* This function can count as GRAPH_RDLOCK because quorum_co_pwritev() holds the
|
||||||
|
* graph lock and keeps it until this coroutine has terminated.
|
||||||
|
*/
|
||||||
|
static void coroutine_fn GRAPH_RDLOCK write_quorum_entry(void *opaque)
|
||||||
{
|
{
|
||||||
QuorumCo *co = opaque;
|
QuorumCo *co = opaque;
|
||||||
QuorumAIOCB *acb = co->acb;
|
QuorumAIOCB *acb = co->acb;
|
||||||
|
@ -714,9 +725,9 @@ static void coroutine_fn write_quorum_entry(void *opaque)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn quorum_co_pwritev(BlockDriverState *bs, int64_t offset,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t bytes, QEMUIOVector *qiov,
|
quorum_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
BdrvRequestFlags flags)
|
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
BDRVQuorumState *s = bs->opaque;
|
BDRVQuorumState *s = bs->opaque;
|
||||||
QuorumAIOCB *acb = quorum_aio_get(bs, qiov, offset, bytes, flags);
|
QuorumAIOCB *acb = quorum_aio_get(bs, qiov, offset, bytes, flags);
|
||||||
|
@ -745,16 +756,16 @@ static int coroutine_fn quorum_co_pwritev(BlockDriverState *bs, int64_t offset,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn quorum_co_pwrite_zeroes(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes,
|
quorum_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
BdrvRequestFlags flags)
|
BdrvRequestFlags flags)
|
||||||
|
|
||||||
{
|
{
|
||||||
return quorum_co_pwritev(bs, offset, bytes, NULL,
|
return quorum_co_pwritev(bs, offset, bytes, NULL,
|
||||||
flags | BDRV_REQ_ZERO_WRITE);
|
flags | BDRV_REQ_ZERO_WRITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int64_t coroutine_fn quorum_co_getlength(BlockDriverState *bs)
|
static int64_t coroutine_fn GRAPH_RDLOCK
|
||||||
|
quorum_co_getlength(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
BDRVQuorumState *s = bs->opaque;
|
BDRVQuorumState *s = bs->opaque;
|
||||||
int64_t result;
|
int64_t result;
|
||||||
|
@ -778,7 +789,7 @@ static int64_t coroutine_fn quorum_co_getlength(BlockDriverState *bs)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static coroutine_fn int quorum_co_flush(BlockDriverState *bs)
|
static coroutine_fn GRAPH_RDLOCK int quorum_co_flush(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
BDRVQuorumState *s = bs->opaque;
|
BDRVQuorumState *s = bs->opaque;
|
||||||
QuorumVoteVersion *winner = NULL;
|
QuorumVoteVersion *winner = NULL;
|
||||||
|
@ -1217,11 +1228,10 @@ static void quorum_child_perm(BlockDriverState *bs, BdrvChild *c,
|
||||||
* return BDRV_BLOCK_ZERO if *all* children agree that a certain
|
* return BDRV_BLOCK_ZERO if *all* children agree that a certain
|
||||||
* region contains zeroes, and BDRV_BLOCK_DATA otherwise.
|
* region contains zeroes, and BDRV_BLOCK_DATA otherwise.
|
||||||
*/
|
*/
|
||||||
static int coroutine_fn quorum_co_block_status(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
bool want_zero,
|
quorum_co_block_status(BlockDriverState *bs, bool want_zero,
|
||||||
int64_t offset, int64_t count,
|
int64_t offset, int64_t count,
|
||||||
int64_t *pnum, int64_t *map,
|
int64_t *pnum, int64_t *map, BlockDriverState **file)
|
||||||
BlockDriverState **file)
|
|
||||||
{
|
{
|
||||||
BDRVQuorumState *s = bs->opaque;
|
BDRVQuorumState *s = bs->opaque;
|
||||||
int i, ret;
|
int i, ret;
|
||||||
|
|
|
@ -203,9 +203,9 @@ static inline int raw_adjust_offset(BlockDriverState *bs, int64_t *offset,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn raw_co_preadv(BlockDriverState *bs, int64_t offset,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t bytes, QEMUIOVector *qiov,
|
raw_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
BdrvRequestFlags flags)
|
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -218,9 +218,9 @@ static int coroutine_fn raw_co_preadv(BlockDriverState *bs, int64_t offset,
|
||||||
return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
|
return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn raw_co_pwritev(BlockDriverState *bs, int64_t offset,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t bytes, QEMUIOVector *qiov,
|
raw_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
BdrvRequestFlags flags)
|
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
void *buf = NULL;
|
void *buf = NULL;
|
||||||
BlockDriver *drv;
|
BlockDriver *drv;
|
||||||
|
@ -292,8 +292,8 @@ static int coroutine_fn raw_co_block_status(BlockDriverState *bs,
|
||||||
return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID;
|
return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn raw_co_pwrite_zeroes(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes,
|
raw_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
BdrvRequestFlags flags)
|
BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -305,8 +305,8 @@ static int coroutine_fn raw_co_pwrite_zeroes(BlockDriverState *bs,
|
||||||
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
|
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn raw_co_pdiscard(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes)
|
raw_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -317,7 +317,8 @@ static int coroutine_fn raw_co_pdiscard(BlockDriverState *bs,
|
||||||
return bdrv_co_pdiscard(bs->file, offset, bytes);
|
return bdrv_co_pdiscard(bs->file, offset, bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int64_t coroutine_fn raw_co_getlength(BlockDriverState *bs)
|
static int64_t coroutine_fn GRAPH_RDLOCK
|
||||||
|
raw_co_getlength(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
int64_t len;
|
int64_t len;
|
||||||
BDRVRawState *s = bs->opaque;
|
BDRVRawState *s = bs->opaque;
|
||||||
|
@ -384,9 +385,9 @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
bool exact, PreallocMode prealloc,
|
raw_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
|
||||||
BdrvRequestFlags flags, Error **errp)
|
PreallocMode prealloc, BdrvRequestFlags flags, Error **errp)
|
||||||
{
|
{
|
||||||
BDRVRawState *s = bs->opaque;
|
BDRVRawState *s = bs->opaque;
|
||||||
|
|
||||||
|
@ -405,18 +406,20 @@ static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
|
||||||
return bdrv_co_truncate(bs->file, offset, exact, prealloc, flags, errp);
|
return bdrv_co_truncate(bs->file, offset, exact, prealloc, flags, errp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void coroutine_fn raw_co_eject(BlockDriverState *bs, bool eject_flag)
|
static void coroutine_fn GRAPH_RDLOCK
|
||||||
|
raw_co_eject(BlockDriverState *bs, bool eject_flag)
|
||||||
{
|
{
|
||||||
bdrv_co_eject(bs->file->bs, eject_flag);
|
bdrv_co_eject(bs->file->bs, eject_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void coroutine_fn raw_co_lock_medium(BlockDriverState *bs, bool locked)
|
static void coroutine_fn GRAPH_RDLOCK
|
||||||
|
raw_co_lock_medium(BlockDriverState *bs, bool locked)
|
||||||
{
|
{
|
||||||
bdrv_co_lock_medium(bs->file->bs, locked);
|
bdrv_co_lock_medium(bs->file->bs, locked);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn raw_co_ioctl(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
unsigned long int req, void *buf)
|
raw_co_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
|
||||||
{
|
{
|
||||||
BDRVRawState *s = bs->opaque;
|
BDRVRawState *s = bs->opaque;
|
||||||
if (s->offset || s->has_size) {
|
if (s->offset || s->has_size) {
|
||||||
|
@ -430,10 +433,9 @@ static int raw_has_zero_init(BlockDriverState *bs)
|
||||||
return bdrv_has_zero_init(bs->file->bs);
|
return bdrv_has_zero_init(bs->file->bs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn raw_co_create_opts(BlockDriver *drv,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
const char *filename,
|
raw_co_create_opts(BlockDriver *drv, const char *filename,
|
||||||
QemuOpts *opts,
|
QemuOpts *opts, Error **errp)
|
||||||
Error **errp)
|
|
||||||
{
|
{
|
||||||
return bdrv_co_create_file(filename, opts, errp);
|
return bdrv_co_create_file(filename, opts, errp);
|
||||||
}
|
}
|
||||||
|
@ -536,13 +538,11 @@ static int raw_probe_geometry(BlockDriverState *bs, HDGeometry *geo)
|
||||||
return bdrv_probe_geometry(bs->file->bs, geo);
|
return bdrv_probe_geometry(bs->file->bs, geo);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn raw_co_copy_range_from(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
BdrvChild *src,
|
raw_co_copy_range_from(BlockDriverState *bs,
|
||||||
int64_t src_offset,
|
BdrvChild *src, int64_t src_offset,
|
||||||
BdrvChild *dst,
|
BdrvChild *dst, int64_t dst_offset,
|
||||||
int64_t dst_offset,
|
int64_t bytes, BdrvRequestFlags read_flags,
|
||||||
int64_t bytes,
|
|
||||||
BdrvRequestFlags read_flags,
|
|
||||||
BdrvRequestFlags write_flags)
|
BdrvRequestFlags write_flags)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -555,13 +555,11 @@ static int coroutine_fn raw_co_copy_range_from(BlockDriverState *bs,
|
||||||
bytes, read_flags, write_flags);
|
bytes, read_flags, write_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn raw_co_copy_range_to(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
BdrvChild *src,
|
raw_co_copy_range_to(BlockDriverState *bs,
|
||||||
int64_t src_offset,
|
BdrvChild *src, int64_t src_offset,
|
||||||
BdrvChild *dst,
|
BdrvChild *dst, int64_t dst_offset,
|
||||||
int64_t dst_offset,
|
int64_t bytes, BdrvRequestFlags read_flags,
|
||||||
int64_t bytes,
|
|
||||||
BdrvRequestFlags read_flags,
|
|
||||||
BdrvRequestFlags write_flags)
|
BdrvRequestFlags write_flags)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
186
block/rbd.c
186
block/rbd.c
|
@ -72,6 +72,16 @@ static const char rbd_luks2_header_verification[
|
||||||
'L', 'U', 'K', 'S', 0xBA, 0xBE, 0, 2
|
'L', 'U', 'K', 'S', 0xBA, 0xBE, 0, 2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char rbd_layered_luks_header_verification[
|
||||||
|
RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN] = {
|
||||||
|
'R', 'B', 'D', 'L', 0xBA, 0xBE, 0, 1
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char rbd_layered_luks2_header_verification[
|
||||||
|
RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN] = {
|
||||||
|
'R', 'B', 'D', 'L', 0xBA, 0xBE, 0, 2
|
||||||
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
RBD_AIO_READ,
|
RBD_AIO_READ,
|
||||||
RBD_AIO_WRITE,
|
RBD_AIO_WRITE,
|
||||||
|
@ -386,7 +396,6 @@ static int qemu_rbd_encryption_format(rbd_image_t image,
|
||||||
{
|
{
|
||||||
int r = 0;
|
int r = 0;
|
||||||
g_autofree char *passphrase = NULL;
|
g_autofree char *passphrase = NULL;
|
||||||
size_t passphrase_len;
|
|
||||||
rbd_encryption_format_t format;
|
rbd_encryption_format_t format;
|
||||||
rbd_encryption_options_t opts;
|
rbd_encryption_options_t opts;
|
||||||
rbd_encryption_luks1_format_options_t luks_opts;
|
rbd_encryption_luks1_format_options_t luks_opts;
|
||||||
|
@ -408,12 +417,12 @@ static int qemu_rbd_encryption_format(rbd_image_t image,
|
||||||
opts_size = sizeof(luks_opts);
|
opts_size = sizeof(luks_opts);
|
||||||
r = qemu_rbd_convert_luks_create_options(
|
r = qemu_rbd_convert_luks_create_options(
|
||||||
qapi_RbdEncryptionCreateOptionsLUKS_base(&encrypt->u.luks),
|
qapi_RbdEncryptionCreateOptionsLUKS_base(&encrypt->u.luks),
|
||||||
&luks_opts.alg, &passphrase, &passphrase_len, errp);
|
&luks_opts.alg, &passphrase, &luks_opts.passphrase_size,
|
||||||
|
errp);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
luks_opts.passphrase = passphrase;
|
luks_opts.passphrase = passphrase;
|
||||||
luks_opts.passphrase_size = passphrase_len;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2: {
|
case RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2: {
|
||||||
|
@ -424,12 +433,12 @@ static int qemu_rbd_encryption_format(rbd_image_t image,
|
||||||
r = qemu_rbd_convert_luks_create_options(
|
r = qemu_rbd_convert_luks_create_options(
|
||||||
qapi_RbdEncryptionCreateOptionsLUKS2_base(
|
qapi_RbdEncryptionCreateOptionsLUKS2_base(
|
||||||
&encrypt->u.luks2),
|
&encrypt->u.luks2),
|
||||||
&luks2_opts.alg, &passphrase, &passphrase_len, errp);
|
&luks2_opts.alg, &passphrase, &luks2_opts.passphrase_size,
|
||||||
|
errp);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
luks2_opts.passphrase = passphrase;
|
luks2_opts.passphrase = passphrase;
|
||||||
luks2_opts.passphrase_size = passphrase_len;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
|
@ -468,9 +477,11 @@ static int qemu_rbd_encryption_load(rbd_image_t image,
|
||||||
{
|
{
|
||||||
int r = 0;
|
int r = 0;
|
||||||
g_autofree char *passphrase = NULL;
|
g_autofree char *passphrase = NULL;
|
||||||
size_t passphrase_len;
|
|
||||||
rbd_encryption_luks1_format_options_t luks_opts;
|
rbd_encryption_luks1_format_options_t luks_opts;
|
||||||
rbd_encryption_luks2_format_options_t luks2_opts;
|
rbd_encryption_luks2_format_options_t luks2_opts;
|
||||||
|
#ifdef LIBRBD_SUPPORTS_ENCRYPTION_LOAD2
|
||||||
|
rbd_encryption_luks_format_options_t luks_any_opts;
|
||||||
|
#endif
|
||||||
rbd_encryption_format_t format;
|
rbd_encryption_format_t format;
|
||||||
rbd_encryption_options_t opts;
|
rbd_encryption_options_t opts;
|
||||||
size_t opts_size;
|
size_t opts_size;
|
||||||
|
@ -483,12 +494,11 @@ static int qemu_rbd_encryption_load(rbd_image_t image,
|
||||||
opts_size = sizeof(luks_opts);
|
opts_size = sizeof(luks_opts);
|
||||||
r = qemu_rbd_convert_luks_options(
|
r = qemu_rbd_convert_luks_options(
|
||||||
qapi_RbdEncryptionOptionsLUKS_base(&encrypt->u.luks),
|
qapi_RbdEncryptionOptionsLUKS_base(&encrypt->u.luks),
|
||||||
&passphrase, &passphrase_len, errp);
|
&passphrase, &luks_opts.passphrase_size, errp);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
luks_opts.passphrase = passphrase;
|
luks_opts.passphrase = passphrase;
|
||||||
luks_opts.passphrase_size = passphrase_len;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2: {
|
case RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2: {
|
||||||
|
@ -498,14 +508,29 @@ static int qemu_rbd_encryption_load(rbd_image_t image,
|
||||||
opts_size = sizeof(luks2_opts);
|
opts_size = sizeof(luks2_opts);
|
||||||
r = qemu_rbd_convert_luks_options(
|
r = qemu_rbd_convert_luks_options(
|
||||||
qapi_RbdEncryptionOptionsLUKS2_base(&encrypt->u.luks2),
|
qapi_RbdEncryptionOptionsLUKS2_base(&encrypt->u.luks2),
|
||||||
&passphrase, &passphrase_len, errp);
|
&passphrase, &luks2_opts.passphrase_size, errp);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
luks2_opts.passphrase = passphrase;
|
luks2_opts.passphrase = passphrase;
|
||||||
luks2_opts.passphrase_size = passphrase_len;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#ifdef LIBRBD_SUPPORTS_ENCRYPTION_LOAD2
|
||||||
|
case RBD_IMAGE_ENCRYPTION_FORMAT_LUKS_ANY: {
|
||||||
|
memset(&luks_any_opts, 0, sizeof(luks_any_opts));
|
||||||
|
format = RBD_ENCRYPTION_FORMAT_LUKS;
|
||||||
|
opts = &luks_any_opts;
|
||||||
|
opts_size = sizeof(luks_any_opts);
|
||||||
|
r = qemu_rbd_convert_luks_options(
|
||||||
|
qapi_RbdEncryptionOptionsLUKSAny_base(&encrypt->u.luks_any),
|
||||||
|
&passphrase, &luks_any_opts.passphrase_size, errp);
|
||||||
|
if (r < 0) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
luks_any_opts.passphrase = passphrase;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
default: {
|
default: {
|
||||||
r = -ENOTSUP;
|
r = -ENOTSUP;
|
||||||
error_setg_errno(
|
error_setg_errno(
|
||||||
|
@ -523,6 +548,128 @@ static int qemu_rbd_encryption_load(rbd_image_t image,
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef LIBRBD_SUPPORTS_ENCRYPTION_LOAD2
|
||||||
|
static int qemu_rbd_encryption_load2(rbd_image_t image,
|
||||||
|
RbdEncryptionOptions *encrypt,
|
||||||
|
Error **errp)
|
||||||
|
{
|
||||||
|
int r = 0;
|
||||||
|
int encrypt_count = 1;
|
||||||
|
int i;
|
||||||
|
RbdEncryptionOptions *curr_encrypt;
|
||||||
|
rbd_encryption_spec_t *specs;
|
||||||
|
rbd_encryption_luks1_format_options_t *luks_opts;
|
||||||
|
rbd_encryption_luks2_format_options_t *luks2_opts;
|
||||||
|
rbd_encryption_luks_format_options_t *luks_any_opts;
|
||||||
|
|
||||||
|
/* count encryption options */
|
||||||
|
for (curr_encrypt = encrypt->parent; curr_encrypt;
|
||||||
|
curr_encrypt = curr_encrypt->parent) {
|
||||||
|
++encrypt_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
specs = g_new0(rbd_encryption_spec_t, encrypt_count);
|
||||||
|
|
||||||
|
curr_encrypt = encrypt;
|
||||||
|
for (i = 0; i < encrypt_count; ++i) {
|
||||||
|
switch (curr_encrypt->format) {
|
||||||
|
case RBD_IMAGE_ENCRYPTION_FORMAT_LUKS: {
|
||||||
|
specs[i].format = RBD_ENCRYPTION_FORMAT_LUKS1;
|
||||||
|
|
||||||
|
luks_opts = g_new0(rbd_encryption_luks1_format_options_t, 1);
|
||||||
|
specs[i].opts = luks_opts;
|
||||||
|
specs[i].opts_size = sizeof(*luks_opts);
|
||||||
|
|
||||||
|
r = qemu_rbd_convert_luks_options(
|
||||||
|
qapi_RbdEncryptionOptionsLUKS_base(
|
||||||
|
&curr_encrypt->u.luks),
|
||||||
|
(char **)&luks_opts->passphrase,
|
||||||
|
&luks_opts->passphrase_size,
|
||||||
|
errp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2: {
|
||||||
|
specs[i].format = RBD_ENCRYPTION_FORMAT_LUKS2;
|
||||||
|
|
||||||
|
luks2_opts = g_new0(rbd_encryption_luks2_format_options_t, 1);
|
||||||
|
specs[i].opts = luks2_opts;
|
||||||
|
specs[i].opts_size = sizeof(*luks2_opts);
|
||||||
|
|
||||||
|
r = qemu_rbd_convert_luks_options(
|
||||||
|
qapi_RbdEncryptionOptionsLUKS2_base(
|
||||||
|
&curr_encrypt->u.luks2),
|
||||||
|
(char **)&luks2_opts->passphrase,
|
||||||
|
&luks2_opts->passphrase_size,
|
||||||
|
errp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case RBD_IMAGE_ENCRYPTION_FORMAT_LUKS_ANY: {
|
||||||
|
specs[i].format = RBD_ENCRYPTION_FORMAT_LUKS;
|
||||||
|
|
||||||
|
luks_any_opts = g_new0(rbd_encryption_luks_format_options_t, 1);
|
||||||
|
specs[i].opts = luks_any_opts;
|
||||||
|
specs[i].opts_size = sizeof(*luks_any_opts);
|
||||||
|
|
||||||
|
r = qemu_rbd_convert_luks_options(
|
||||||
|
qapi_RbdEncryptionOptionsLUKSAny_base(
|
||||||
|
&curr_encrypt->u.luks_any),
|
||||||
|
(char **)&luks_any_opts->passphrase,
|
||||||
|
&luks_any_opts->passphrase_size,
|
||||||
|
errp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
r = -ENOTSUP;
|
||||||
|
error_setg_errno(
|
||||||
|
errp, -r, "unknown image encryption format: %u",
|
||||||
|
curr_encrypt->format);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r < 0) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
curr_encrypt = curr_encrypt->parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = rbd_encryption_load2(image, specs, encrypt_count);
|
||||||
|
if (r < 0) {
|
||||||
|
error_setg_errno(errp, -r, "layered encryption load fail");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
for (i = 0; i < encrypt_count; ++i) {
|
||||||
|
if (!specs[i].opts) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (specs[i].format) {
|
||||||
|
case RBD_ENCRYPTION_FORMAT_LUKS1: {
|
||||||
|
luks_opts = specs[i].opts;
|
||||||
|
g_free((void *)luks_opts->passphrase);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case RBD_ENCRYPTION_FORMAT_LUKS2: {
|
||||||
|
luks2_opts = specs[i].opts;
|
||||||
|
g_free((void *)luks2_opts->passphrase);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case RBD_ENCRYPTION_FORMAT_LUKS: {
|
||||||
|
luks_any_opts = specs[i].opts;
|
||||||
|
g_free((void *)luks_any_opts->passphrase);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free(specs[i].opts);
|
||||||
|
}
|
||||||
|
g_free(specs);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* FIXME Deprecate and remove keypairs or make it available in QMP. */
|
/* FIXME Deprecate and remove keypairs or make it available in QMP. */
|
||||||
|
@ -989,7 +1136,16 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
|
||||||
|
|
||||||
if (opts->encrypt) {
|
if (opts->encrypt) {
|
||||||
#ifdef LIBRBD_SUPPORTS_ENCRYPTION
|
#ifdef LIBRBD_SUPPORTS_ENCRYPTION
|
||||||
|
if (opts->encrypt->parent) {
|
||||||
|
#ifdef LIBRBD_SUPPORTS_ENCRYPTION_LOAD2
|
||||||
|
r = qemu_rbd_encryption_load2(s->image, opts->encrypt, errp);
|
||||||
|
#else
|
||||||
|
r = -ENOTSUP;
|
||||||
|
error_setg(errp, "RBD library does not support layered encryption");
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
r = qemu_rbd_encryption_load(s->image, opts->encrypt, errp);
|
r = qemu_rbd_encryption_load(s->image, opts->encrypt, errp);
|
||||||
|
}
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
goto failed_post_open;
|
goto failed_post_open;
|
||||||
}
|
}
|
||||||
|
@ -1281,6 +1437,16 @@ static ImageInfoSpecific *qemu_rbd_get_specific_info(BlockDriverState *bs,
|
||||||
spec_info->u.rbd.data->encryption_format =
|
spec_info->u.rbd.data->encryption_format =
|
||||||
RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2;
|
RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2;
|
||||||
spec_info->u.rbd.data->has_encryption_format = true;
|
spec_info->u.rbd.data->has_encryption_format = true;
|
||||||
|
} else if (memcmp(buf, rbd_layered_luks_header_verification,
|
||||||
|
RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN) == 0) {
|
||||||
|
spec_info->u.rbd.data->encryption_format =
|
||||||
|
RBD_IMAGE_ENCRYPTION_FORMAT_LUKS;
|
||||||
|
spec_info->u.rbd.data->has_encryption_format = true;
|
||||||
|
} else if (memcmp(buf, rbd_layered_luks2_header_verification,
|
||||||
|
RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN) == 0) {
|
||||||
|
spec_info->u.rbd.data->encryption_format =
|
||||||
|
RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2;
|
||||||
|
spec_info->u.rbd.data->has_encryption_format = true;
|
||||||
} else {
|
} else {
|
||||||
spec_info->u.rbd.data->has_encryption_format = false;
|
spec_info->u.rbd.data->has_encryption_format = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,7 +179,8 @@ static void replication_child_perm(BlockDriverState *bs, BdrvChild *c,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int64_t coroutine_fn replication_co_getlength(BlockDriverState *bs)
|
static int64_t coroutine_fn GRAPH_RDLOCK
|
||||||
|
replication_co_getlength(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
return bdrv_co_getlength(bs->file->bs);
|
return bdrv_co_getlength(bs->file->bs);
|
||||||
}
|
}
|
||||||
|
@ -220,10 +221,9 @@ static int replication_return_value(BDRVReplicationState *s, int ret)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static coroutine_fn int replication_co_readv(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t sector_num,
|
replication_co_readv(BlockDriverState *bs, int64_t sector_num,
|
||||||
int remaining_sectors,
|
int remaining_sectors, QEMUIOVector *qiov)
|
||||||
QEMUIOVector *qiov)
|
|
||||||
{
|
{
|
||||||
BDRVReplicationState *s = bs->opaque;
|
BDRVReplicationState *s = bs->opaque;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -244,11 +244,9 @@ static coroutine_fn int replication_co_readv(BlockDriverState *bs,
|
||||||
return replication_return_value(s, ret);
|
return replication_return_value(s, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static coroutine_fn int replication_co_writev(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t sector_num,
|
replication_co_writev(BlockDriverState *bs, int64_t sector_num,
|
||||||
int remaining_sectors,
|
int remaining_sectors, QEMUIOVector *qiov, int flags)
|
||||||
QEMUIOVector *qiov,
|
|
||||||
int flags)
|
|
||||||
{
|
{
|
||||||
BDRVReplicationState *s = bs->opaque;
|
BDRVReplicationState *s = bs->opaque;
|
||||||
QEMUIOVector hd_qiov;
|
QEMUIOVector hd_qiov;
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
#include "qemu/cutils.h"
|
#include "qemu/cutils.h"
|
||||||
#include "block/block_int.h"
|
#include "block/block_int.h"
|
||||||
|
|
||||||
static coroutine_fn int
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
snapshot_access_co_preadv_part(BlockDriverState *bs,
|
snapshot_access_co_preadv_part(BlockDriverState *bs,
|
||||||
int64_t offset, int64_t bytes,
|
int64_t offset, int64_t bytes,
|
||||||
QEMUIOVector *qiov, size_t qiov_offset,
|
QEMUIOVector *qiov, size_t qiov_offset,
|
||||||
|
@ -39,7 +39,7 @@ snapshot_access_co_preadv_part(BlockDriverState *bs,
|
||||||
return bdrv_co_preadv_snapshot(bs->file, offset, bytes, qiov, qiov_offset);
|
return bdrv_co_preadv_snapshot(bs->file, offset, bytes, qiov, qiov_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
snapshot_access_co_block_status(BlockDriverState *bs,
|
snapshot_access_co_block_status(BlockDriverState *bs,
|
||||||
bool want_zero, int64_t offset,
|
bool want_zero, int64_t offset,
|
||||||
int64_t bytes, int64_t *pnum,
|
int64_t bytes, int64_t *pnum,
|
||||||
|
@ -49,8 +49,8 @@ snapshot_access_co_block_status(BlockDriverState *bs,
|
||||||
bytes, pnum, map, file);
|
bytes, pnum, map, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn snapshot_access_co_pdiscard(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes)
|
snapshot_access_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
|
||||||
{
|
{
|
||||||
return bdrv_co_pdiscard_snapshot(bs->file->bs, offset, bytes);
|
return bdrv_co_pdiscard_snapshot(bs->file->bs, offset, bytes);
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,10 +140,12 @@ static int coroutine_fn stream_run(Job *job, Error **errp)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = bdrv_getlength(s->target_bs);
|
WITH_GRAPH_RDLOCK_GUARD() {
|
||||||
|
len = bdrv_co_getlength(s->target_bs);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
job_progress_set_remaining(&s->common.job, len);
|
job_progress_set_remaining(&s->common.job, len);
|
||||||
|
|
||||||
for ( ; offset < len; offset += n) {
|
for ( ; offset < len; offset += n) {
|
||||||
|
@ -160,12 +162,15 @@ static int coroutine_fn stream_run(Job *job, Error **errp)
|
||||||
|
|
||||||
copy = false;
|
copy = false;
|
||||||
|
|
||||||
|
WITH_GRAPH_RDLOCK_GUARD() {
|
||||||
ret = bdrv_is_allocated(unfiltered_bs, offset, STREAM_CHUNK, &n);
|
ret = bdrv_is_allocated(unfiltered_bs, offset, STREAM_CHUNK, &n);
|
||||||
if (ret == 1) {
|
if (ret == 1) {
|
||||||
/* Allocated in the top, no need to copy. */
|
/* Allocated in the top, no need to copy. */
|
||||||
} else if (ret >= 0) {
|
} else if (ret >= 0) {
|
||||||
/* Copy if allocated in the intermediate images. Limit to the
|
/*
|
||||||
* known-unallocated area [offset, offset+n*BDRV_SECTOR_SIZE). */
|
* Copy if allocated in the intermediate images. Limit to the
|
||||||
|
* known-unallocated area [offset, offset+n*BDRV_SECTOR_SIZE).
|
||||||
|
*/
|
||||||
ret = bdrv_is_allocated_above(bdrv_cow_bs(unfiltered_bs),
|
ret = bdrv_is_allocated_above(bdrv_cow_bs(unfiltered_bs),
|
||||||
s->base_overlay, true,
|
s->base_overlay, true,
|
||||||
offset, n, &n);
|
offset, n, &n);
|
||||||
|
@ -176,6 +181,7 @@ static int coroutine_fn stream_run(Job *job, Error **errp)
|
||||||
|
|
||||||
copy = (ret > 0);
|
copy = (ret > 0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
trace_stream_one_iteration(s, offset, n, ret);
|
trace_stream_one_iteration(s, offset, n, ret);
|
||||||
if (copy) {
|
if (copy) {
|
||||||
ret = stream_populate(s->blk, offset, n);
|
ret = stream_populate(s->blk, offset, n);
|
||||||
|
|
|
@ -106,15 +106,15 @@ static void throttle_close(BlockDriverState *bs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int64_t coroutine_fn throttle_co_getlength(BlockDriverState *bs)
|
static int64_t coroutine_fn GRAPH_RDLOCK
|
||||||
|
throttle_co_getlength(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
return bdrv_co_getlength(bs->file->bs);
|
return bdrv_co_getlength(bs->file->bs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn throttle_co_preadv(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes,
|
throttle_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
QEMUIOVector *qiov,
|
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
||||||
BdrvRequestFlags flags)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
ThrottleGroupMember *tgm = bs->opaque;
|
ThrottleGroupMember *tgm = bs->opaque;
|
||||||
|
@ -123,10 +123,9 @@ static int coroutine_fn throttle_co_preadv(BlockDriverState *bs,
|
||||||
return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
|
return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn throttle_co_pwritev(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes,
|
throttle_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
QEMUIOVector *qiov,
|
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
||||||
BdrvRequestFlags flags)
|
|
||||||
{
|
{
|
||||||
ThrottleGroupMember *tgm = bs->opaque;
|
ThrottleGroupMember *tgm = bs->opaque;
|
||||||
throttle_group_co_io_limits_intercept(tgm, bytes, true);
|
throttle_group_co_io_limits_intercept(tgm, bytes, true);
|
||||||
|
@ -134,8 +133,8 @@ static int coroutine_fn throttle_co_pwritev(BlockDriverState *bs,
|
||||||
return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
|
return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn throttle_co_pwrite_zeroes(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes,
|
throttle_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
BdrvRequestFlags flags)
|
BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
ThrottleGroupMember *tgm = bs->opaque;
|
ThrottleGroupMember *tgm = bs->opaque;
|
||||||
|
@ -144,8 +143,8 @@ static int coroutine_fn throttle_co_pwrite_zeroes(BlockDriverState *bs,
|
||||||
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
|
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn throttle_co_pdiscard(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes)
|
throttle_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
|
||||||
{
|
{
|
||||||
ThrottleGroupMember *tgm = bs->opaque;
|
ThrottleGroupMember *tgm = bs->opaque;
|
||||||
throttle_group_co_io_limits_intercept(tgm, bytes, true);
|
throttle_group_co_io_limits_intercept(tgm, bytes, true);
|
||||||
|
@ -153,16 +152,15 @@ static int coroutine_fn throttle_co_pdiscard(BlockDriverState *bs,
|
||||||
return bdrv_co_pdiscard(bs->file, offset, bytes);
|
return bdrv_co_pdiscard(bs->file, offset, bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn throttle_co_pwritev_compressed(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset,
|
throttle_co_pwritev_compressed(BlockDriverState *bs, int64_t offset,
|
||||||
int64_t bytes,
|
int64_t bytes, QEMUIOVector *qiov)
|
||||||
QEMUIOVector *qiov)
|
|
||||||
{
|
{
|
||||||
return throttle_co_pwritev(bs, offset, bytes, qiov,
|
return throttle_co_pwritev(bs, offset, bytes, qiov,
|
||||||
BDRV_REQ_WRITE_COMPRESSED);
|
BDRV_REQ_WRITE_COMPRESSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn throttle_co_flush(BlockDriverState *bs)
|
static int coroutine_fn GRAPH_RDLOCK throttle_co_flush(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
return bdrv_co_flush(bs->file->bs);
|
return bdrv_co_flush(bs->file->bs);
|
||||||
}
|
}
|
||||||
|
|
11
block/vdi.c
11
block/vdi.c
|
@ -544,7 +544,7 @@ static int coroutine_fn vdi_co_block_status(BlockDriverState *bs,
|
||||||
(s->header.image_type == VDI_TYPE_STATIC ? BDRV_BLOCK_RECURSE : 0);
|
(s->header.image_type == VDI_TYPE_STATIC ? BDRV_BLOCK_RECURSE : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
vdi_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
vdi_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
|
@ -600,7 +600,7 @@ vdi_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
vdi_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
vdi_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
|
@ -898,10 +898,9 @@ static int coroutine_fn vdi_co_create(BlockdevCreateOptions *create_options,
|
||||||
return vdi_co_do_create(create_options, DEFAULT_CLUSTER_SIZE, errp);
|
return vdi_co_do_create(create_options, DEFAULT_CLUSTER_SIZE, errp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn vdi_co_create_opts(BlockDriver *drv,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
const char *filename,
|
vdi_co_create_opts(BlockDriver *drv, const char *filename,
|
||||||
QemuOpts *opts,
|
QemuOpts *opts, Error **errp)
|
||||||
Error **errp)
|
|
||||||
{
|
{
|
||||||
QDict *qdict = NULL;
|
QDict *qdict = NULL;
|
||||||
BlockdevCreateOptions *create_options = NULL;
|
BlockdevCreateOptions *create_options = NULL;
|
||||||
|
|
18
block/vhdx.c
18
block/vhdx.c
|
@ -1172,8 +1172,9 @@ vhdx_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static coroutine_fn int vhdx_co_readv(BlockDriverState *bs, int64_t sector_num,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int nb_sectors, QEMUIOVector *qiov)
|
vhdx_co_readv(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
|
||||||
|
QEMUIOVector *qiov)
|
||||||
{
|
{
|
||||||
BDRVVHDXState *s = bs->opaque;
|
BDRVVHDXState *s = bs->opaque;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
@ -1324,9 +1325,9 @@ int vhdx_user_visible_write(BlockDriverState *bs, BDRVVHDXState *s)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static coroutine_fn int vhdx_co_writev(BlockDriverState *bs, int64_t sector_num,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int nb_sectors, QEMUIOVector *qiov,
|
vhdx_co_writev(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
|
||||||
int flags)
|
QEMUIOVector *qiov, int flags)
|
||||||
{
|
{
|
||||||
int ret = -ENOTSUP;
|
int ret = -ENOTSUP;
|
||||||
BDRVVHDXState *s = bs->opaque;
|
BDRVVHDXState *s = bs->opaque;
|
||||||
|
@ -2058,10 +2059,9 @@ delete_and_exit:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn vhdx_co_create_opts(BlockDriver *drv,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
const char *filename,
|
vhdx_co_create_opts(BlockDriver *drv, const char *filename,
|
||||||
QemuOpts *opts,
|
QemuOpts *opts, Error **errp)
|
||||||
Error **errp)
|
|
||||||
{
|
{
|
||||||
BlockdevCreateOptions *create_options = NULL;
|
BlockdevCreateOptions *create_options = NULL;
|
||||||
QDict *qdict;
|
QDict *qdict;
|
||||||
|
|
100
block/vmdk.c
100
block/vmdk.c
|
@ -1403,12 +1403,10 @@ static void vmdk_refresh_limits(BlockDriverState *bs, Error **errp)
|
||||||
* [@skip_start_sector, @skip_end_sector) is not copied or written, and leave
|
* [@skip_start_sector, @skip_end_sector) is not copied or written, and leave
|
||||||
* it for call to write user data in the request.
|
* it for call to write user data in the request.
|
||||||
*/
|
*/
|
||||||
static int coroutine_fn get_whole_cluster(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
VmdkExtent *extent,
|
get_whole_cluster(BlockDriverState *bs, VmdkExtent *extent,
|
||||||
uint64_t cluster_offset,
|
uint64_t cluster_offset, uint64_t offset,
|
||||||
uint64_t offset,
|
uint64_t skip_start_bytes, uint64_t skip_end_bytes,
|
||||||
uint64_t skip_start_bytes,
|
|
||||||
uint64_t skip_end_bytes,
|
|
||||||
bool zeroed)
|
bool zeroed)
|
||||||
{
|
{
|
||||||
int ret = VMDK_OK;
|
int ret = VMDK_OK;
|
||||||
|
@ -1484,8 +1482,8 @@ exit:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
uint32_t offset)
|
vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data, uint32_t offset)
|
||||||
{
|
{
|
||||||
offset = cpu_to_le32(offset);
|
offset = cpu_to_le32(offset);
|
||||||
/* update L2 table */
|
/* update L2 table */
|
||||||
|
@ -1536,13 +1534,10 @@ static int coroutine_fn vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data,
|
||||||
* VMDK_UNALLOC if cluster is not mapped and @allocate is false.
|
* VMDK_UNALLOC if cluster is not mapped and @allocate is false.
|
||||||
* VMDK_ERROR if failed.
|
* VMDK_ERROR if failed.
|
||||||
*/
|
*/
|
||||||
static int coroutine_fn get_cluster_offset(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
VmdkExtent *extent,
|
get_cluster_offset(BlockDriverState *bs, VmdkExtent *extent,
|
||||||
VmdkMetaData *m_data,
|
VmdkMetaData *m_data, uint64_t offset, bool allocate,
|
||||||
uint64_t offset,
|
uint64_t *cluster_offset, uint64_t skip_start_bytes,
|
||||||
bool allocate,
|
|
||||||
uint64_t *cluster_offset,
|
|
||||||
uint64_t skip_start_bytes,
|
|
||||||
uint64_t skip_end_bytes)
|
uint64_t skip_end_bytes)
|
||||||
{
|
{
|
||||||
unsigned int l1_index, l2_offset, l2_index;
|
unsigned int l1_index, l2_offset, l2_index;
|
||||||
|
@ -1736,11 +1731,10 @@ static inline uint64_t vmdk_find_offset_in_cluster(VmdkExtent *extent,
|
||||||
return extent_relative_offset % cluster_size;
|
return extent_relative_offset % cluster_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn vmdk_co_block_status(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
bool want_zero,
|
vmdk_co_block_status(BlockDriverState *bs, bool want_zero,
|
||||||
int64_t offset, int64_t bytes,
|
int64_t offset, int64_t bytes, int64_t *pnum,
|
||||||
int64_t *pnum, int64_t *map,
|
int64_t *map, BlockDriverState **file)
|
||||||
BlockDriverState **file)
|
|
||||||
{
|
{
|
||||||
BDRVVmdkState *s = bs->opaque;
|
BDRVVmdkState *s = bs->opaque;
|
||||||
int64_t index_in_cluster, n, ret;
|
int64_t index_in_cluster, n, ret;
|
||||||
|
@ -1785,7 +1779,7 @@ static int coroutine_fn vmdk_co_block_status(BlockDriverState *bs,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset,
|
vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset,
|
||||||
int64_t offset_in_cluster, QEMUIOVector *qiov,
|
int64_t offset_in_cluster, QEMUIOVector *qiov,
|
||||||
uint64_t qiov_offset, uint64_t n_bytes,
|
uint64_t qiov_offset, uint64_t n_bytes,
|
||||||
|
@ -1867,10 +1861,9 @@ vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset,
|
vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset,
|
||||||
int64_t offset_in_cluster, QEMUIOVector *qiov,
|
int64_t offset_in_cluster, QEMUIOVector *qiov, int bytes)
|
||||||
int bytes)
|
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
int cluster_bytes, buf_bytes;
|
int cluster_bytes, buf_bytes;
|
||||||
|
@ -1934,7 +1927,7 @@ vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
vmdk_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
vmdk_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
|
@ -2016,9 +2009,9 @@ fail:
|
||||||
*
|
*
|
||||||
* Returns: error code with 0 for success.
|
* Returns: error code with 0 for success.
|
||||||
*/
|
*/
|
||||||
static int coroutine_fn vmdk_pwritev(BlockDriverState *bs, uint64_t offset,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
uint64_t bytes, QEMUIOVector *qiov,
|
vmdk_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
|
||||||
bool zeroed, bool zero_dry_run)
|
QEMUIOVector *qiov, bool zeroed, bool zero_dry_run)
|
||||||
{
|
{
|
||||||
BDRVVmdkState *s = bs->opaque;
|
BDRVVmdkState *s = bs->opaque;
|
||||||
VmdkExtent *extent = NULL;
|
VmdkExtent *extent = NULL;
|
||||||
|
@ -2114,7 +2107,7 @@ static int coroutine_fn vmdk_pwritev(BlockDriverState *bs, uint64_t offset,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
vmdk_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
vmdk_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
|
@ -2126,7 +2119,7 @@ vmdk_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
vmdk_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
vmdk_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
QEMUIOVector *qiov)
|
QEMUIOVector *qiov)
|
||||||
{
|
{
|
||||||
|
@ -2154,9 +2147,8 @@ vmdk_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
return vmdk_co_pwritev(bs, offset, bytes, qiov, 0);
|
return vmdk_co_pwritev(bs, offset, bytes, qiov, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn vmdk_co_pwrite_zeroes(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset,
|
vmdk_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
int64_t bytes,
|
|
||||||
BdrvRequestFlags flags)
|
BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -2285,10 +2277,9 @@ exit:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn vmdk_create_extent(const char *filename,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t filesize, bool flat,
|
vmdk_create_extent(const char *filename, int64_t filesize, bool flat,
|
||||||
bool compress, bool zeroed_grain,
|
bool compress, bool zeroed_grain, BlockBackend **pbb,
|
||||||
BlockBackend **pbb,
|
|
||||||
QemuOpts *opts, Error **errp)
|
QemuOpts *opts, Error **errp)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -2367,13 +2358,9 @@ static int filename_decompose(const char *filename, char *path, char *prefix,
|
||||||
* non-split format.
|
* non-split format.
|
||||||
* idx >= 1: get the n-th extent if in a split subformat
|
* idx >= 1: get the n-th extent if in a split subformat
|
||||||
*/
|
*/
|
||||||
typedef BlockBackend * coroutine_fn (*vmdk_create_extent_fn)(int64_t size,
|
typedef BlockBackend * coroutine_fn /* GRAPH_RDLOCK */
|
||||||
int idx,
|
(*vmdk_create_extent_fn)(int64_t size, int idx, bool flat, bool split,
|
||||||
bool flat,
|
bool compress, bool zeroed_grain, void *opaque,
|
||||||
bool split,
|
|
||||||
bool compress,
|
|
||||||
bool zeroed_grain,
|
|
||||||
void *opaque,
|
|
||||||
Error **errp);
|
Error **errp);
|
||||||
|
|
||||||
static void vmdk_desc_add_extent(GString *desc,
|
static void vmdk_desc_add_extent(GString *desc,
|
||||||
|
@ -2387,7 +2374,8 @@ static void vmdk_desc_add_extent(GString *desc,
|
||||||
g_free(basename);
|
g_free(basename);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn vmdk_co_do_create(int64_t size,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
|
vmdk_co_do_create(int64_t size,
|
||||||
BlockdevVmdkSubformat subformat,
|
BlockdevVmdkSubformat subformat,
|
||||||
BlockdevVmdkAdapterType adapter_type,
|
BlockdevVmdkAdapterType adapter_type,
|
||||||
const char *backing_file,
|
const char *backing_file,
|
||||||
|
@ -2617,9 +2605,9 @@ typedef struct {
|
||||||
QemuOpts *opts;
|
QemuOpts *opts;
|
||||||
} VMDKCreateOptsData;
|
} VMDKCreateOptsData;
|
||||||
|
|
||||||
static BlockBackend * coroutine_fn vmdk_co_create_opts_cb(int64_t size, int idx,
|
static BlockBackend * coroutine_fn GRAPH_RDLOCK
|
||||||
bool flat, bool split, bool compress,
|
vmdk_co_create_opts_cb(int64_t size, int idx, bool flat, bool split,
|
||||||
bool zeroed_grain, void *opaque,
|
bool compress, bool zeroed_grain, void *opaque,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
BlockBackend *blk = NULL;
|
BlockBackend *blk = NULL;
|
||||||
|
@ -2659,10 +2647,9 @@ exit:
|
||||||
return blk;
|
return blk;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn vmdk_co_create_opts(BlockDriver *drv,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
const char *filename,
|
vmdk_co_create_opts(BlockDriver *drv, const char *filename,
|
||||||
QemuOpts *opts,
|
QemuOpts *opts, Error **errp)
|
||||||
Error **errp)
|
|
||||||
{
|
{
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
char *desc = NULL;
|
char *desc = NULL;
|
||||||
|
@ -2822,8 +2809,8 @@ static BlockBackend * coroutine_fn vmdk_co_create_cb(int64_t size, int idx,
|
||||||
return blk;
|
return blk;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn vmdk_co_create(BlockdevCreateOptions *create_options,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
Error **errp)
|
vmdk_co_create(BlockdevCreateOptions *create_options, Error **errp)
|
||||||
{
|
{
|
||||||
BlockdevCreateOptionsVmdk *opts;
|
BlockdevCreateOptionsVmdk *opts;
|
||||||
|
|
||||||
|
@ -2918,9 +2905,8 @@ static VmdkExtentInfo *vmdk_get_extent_info(VmdkExtent *extent)
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn vmdk_co_check(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
BdrvCheckResult *result,
|
vmdk_co_check(BlockDriverState *bs, BdrvCheckResult *result, BdrvCheckMode fix)
|
||||||
BdrvCheckMode fix)
|
|
||||||
{
|
{
|
||||||
BDRVVmdkState *s = bs->opaque;
|
BDRVVmdkState *s = bs->opaque;
|
||||||
VmdkExtent *extent = NULL;
|
VmdkExtent *extent = NULL;
|
||||||
|
|
11
block/vpc.c
11
block/vpc.c
|
@ -610,7 +610,7 @@ vpc_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
vpc_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
vpc_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
|
@ -660,7 +660,7 @@ fail:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
vpc_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
vpc_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
|
@ -1087,10 +1087,9 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn vpc_co_create_opts(BlockDriver *drv,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
const char *filename,
|
vpc_co_create_opts(BlockDriver *drv, const char *filename,
|
||||||
QemuOpts *opts,
|
QemuOpts *opts, Error **errp)
|
||||||
Error **errp)
|
|
||||||
{
|
{
|
||||||
BlockdevCreateOptions *create_options = NULL;
|
BlockdevCreateOptions *create_options = NULL;
|
||||||
QDict *qdict;
|
QDict *qdict;
|
||||||
|
|
|
@ -273,9 +273,11 @@ static void scsi_aio_complete(void *opaque, int ret)
|
||||||
SCSIDiskReq *r = (SCSIDiskReq *)opaque;
|
SCSIDiskReq *r = (SCSIDiskReq *)opaque;
|
||||||
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
|
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
|
||||||
|
|
||||||
|
aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
|
||||||
|
|
||||||
assert(r->req.aiocb != NULL);
|
assert(r->req.aiocb != NULL);
|
||||||
r->req.aiocb = NULL;
|
r->req.aiocb = NULL;
|
||||||
aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
|
|
||||||
if (scsi_disk_req_check_error(r, ret, true)) {
|
if (scsi_disk_req_check_error(r, ret, true)) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
@ -352,6 +354,7 @@ done:
|
||||||
scsi_req_unref(&r->req);
|
scsi_req_unref(&r->req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Called with AioContext lock held */
|
||||||
static void scsi_dma_complete(void *opaque, int ret)
|
static void scsi_dma_complete(void *opaque, int ret)
|
||||||
{
|
{
|
||||||
SCSIDiskReq *r = (SCSIDiskReq *)opaque;
|
SCSIDiskReq *r = (SCSIDiskReq *)opaque;
|
||||||
|
@ -360,14 +363,12 @@ static void scsi_dma_complete(void *opaque, int ret)
|
||||||
assert(r->req.aiocb != NULL);
|
assert(r->req.aiocb != NULL);
|
||||||
r->req.aiocb = NULL;
|
r->req.aiocb = NULL;
|
||||||
|
|
||||||
aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct);
|
block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct);
|
||||||
} else {
|
} else {
|
||||||
block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct);
|
block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct);
|
||||||
}
|
}
|
||||||
scsi_dma_complete_noio(r, ret);
|
scsi_dma_complete_noio(r, ret);
|
||||||
aio_context_release(blk_get_aio_context(s->qdev.conf.blk));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void scsi_read_complete_noio(SCSIDiskReq *r, int ret)
|
static void scsi_read_complete_noio(SCSIDiskReq *r, int ret)
|
||||||
|
@ -393,10 +394,11 @@ static void scsi_read_complete(void *opaque, int ret)
|
||||||
SCSIDiskReq *r = (SCSIDiskReq *)opaque;
|
SCSIDiskReq *r = (SCSIDiskReq *)opaque;
|
||||||
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
|
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
|
||||||
|
|
||||||
|
aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
|
||||||
|
|
||||||
assert(r->req.aiocb != NULL);
|
assert(r->req.aiocb != NULL);
|
||||||
r->req.aiocb = NULL;
|
r->req.aiocb = NULL;
|
||||||
|
|
||||||
aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct);
|
block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct);
|
||||||
} else {
|
} else {
|
||||||
|
@ -446,10 +448,11 @@ static void scsi_do_read_cb(void *opaque, int ret)
|
||||||
SCSIDiskReq *r = (SCSIDiskReq *)opaque;
|
SCSIDiskReq *r = (SCSIDiskReq *)opaque;
|
||||||
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
|
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
|
||||||
|
|
||||||
|
aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
|
||||||
|
|
||||||
assert (r->req.aiocb != NULL);
|
assert (r->req.aiocb != NULL);
|
||||||
r->req.aiocb = NULL;
|
r->req.aiocb = NULL;
|
||||||
|
|
||||||
aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct);
|
block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct);
|
||||||
} else {
|
} else {
|
||||||
|
@ -530,10 +533,11 @@ static void scsi_write_complete(void * opaque, int ret)
|
||||||
SCSIDiskReq *r = (SCSIDiskReq *)opaque;
|
SCSIDiskReq *r = (SCSIDiskReq *)opaque;
|
||||||
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
|
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
|
||||||
|
|
||||||
|
aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
|
||||||
|
|
||||||
assert (r->req.aiocb != NULL);
|
assert (r->req.aiocb != NULL);
|
||||||
r->req.aiocb = NULL;
|
r->req.aiocb = NULL;
|
||||||
|
|
||||||
aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct);
|
block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1737,10 +1741,11 @@ static void scsi_unmap_complete(void *opaque, int ret)
|
||||||
SCSIDiskReq *r = data->r;
|
SCSIDiskReq *r = data->r;
|
||||||
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
|
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
|
||||||
|
|
||||||
|
aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
|
||||||
|
|
||||||
assert(r->req.aiocb != NULL);
|
assert(r->req.aiocb != NULL);
|
||||||
r->req.aiocb = NULL;
|
r->req.aiocb = NULL;
|
||||||
|
|
||||||
aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
|
|
||||||
if (scsi_disk_req_check_error(r, ret, true)) {
|
if (scsi_disk_req_check_error(r, ret, true)) {
|
||||||
scsi_req_unref(&r->req);
|
scsi_req_unref(&r->req);
|
||||||
g_free(data);
|
g_free(data);
|
||||||
|
@ -1816,9 +1821,11 @@ static void scsi_write_same_complete(void *opaque, int ret)
|
||||||
SCSIDiskReq *r = data->r;
|
SCSIDiskReq *r = data->r;
|
||||||
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
|
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
|
||||||
|
|
||||||
|
aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
|
||||||
|
|
||||||
assert(r->req.aiocb != NULL);
|
assert(r->req.aiocb != NULL);
|
||||||
r->req.aiocb = NULL;
|
r->req.aiocb = NULL;
|
||||||
aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
|
|
||||||
if (scsi_disk_req_check_error(r, ret, true)) {
|
if (scsi_disk_req_check_error(r, ret, true)) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,10 +111,11 @@ static void scsi_command_complete(void *opaque, int ret)
|
||||||
SCSIGenericReq *r = (SCSIGenericReq *)opaque;
|
SCSIGenericReq *r = (SCSIGenericReq *)opaque;
|
||||||
SCSIDevice *s = r->req.dev;
|
SCSIDevice *s = r->req.dev;
|
||||||
|
|
||||||
|
aio_context_acquire(blk_get_aio_context(s->conf.blk));
|
||||||
|
|
||||||
assert(r->req.aiocb != NULL);
|
assert(r->req.aiocb != NULL);
|
||||||
r->req.aiocb = NULL;
|
r->req.aiocb = NULL;
|
||||||
|
|
||||||
aio_context_acquire(blk_get_aio_context(s->conf.blk));
|
|
||||||
scsi_command_complete_noio(r, ret);
|
scsi_command_complete_noio(r, ret);
|
||||||
aio_context_release(blk_get_aio_context(s->conf.blk));
|
aio_context_release(blk_get_aio_context(s->conf.blk));
|
||||||
}
|
}
|
||||||
|
@ -269,11 +270,11 @@ static void scsi_read_complete(void * opaque, int ret)
|
||||||
SCSIDevice *s = r->req.dev;
|
SCSIDevice *s = r->req.dev;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
|
aio_context_acquire(blk_get_aio_context(s->conf.blk));
|
||||||
|
|
||||||
assert(r->req.aiocb != NULL);
|
assert(r->req.aiocb != NULL);
|
||||||
r->req.aiocb = NULL;
|
r->req.aiocb = NULL;
|
||||||
|
|
||||||
aio_context_acquire(blk_get_aio_context(s->conf.blk));
|
|
||||||
|
|
||||||
if (ret || r->req.io_canceled) {
|
if (ret || r->req.io_canceled) {
|
||||||
scsi_command_complete_noio(r, ret);
|
scsi_command_complete_noio(r, ret);
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -386,11 +387,11 @@ static void scsi_write_complete(void * opaque, int ret)
|
||||||
|
|
||||||
trace_scsi_generic_write_complete(ret);
|
trace_scsi_generic_write_complete(ret);
|
||||||
|
|
||||||
|
aio_context_acquire(blk_get_aio_context(s->conf.blk));
|
||||||
|
|
||||||
assert(r->req.aiocb != NULL);
|
assert(r->req.aiocb != NULL);
|
||||||
r->req.aiocb = NULL;
|
r->req.aiocb = NULL;
|
||||||
|
|
||||||
aio_context_acquire(blk_get_aio_context(s->conf.blk));
|
|
||||||
|
|
||||||
if (ret || r->req.io_canceled) {
|
if (ret || r->req.io_canceled) {
|
||||||
scsi_command_complete_noio(r, ret);
|
scsi_command_complete_noio(r, ret);
|
||||||
goto done;
|
goto done;
|
||||||
|
|
|
@ -43,13 +43,11 @@ typedef struct VirtIOSCSIReq {
|
||||||
QEMUSGList qsgl;
|
QEMUSGList qsgl;
|
||||||
QEMUIOVector resp_iov;
|
QEMUIOVector resp_iov;
|
||||||
|
|
||||||
union {
|
/* Used for two-stage request submission and TMFs deferred to BH */
|
||||||
/* Used for two-stage request submission */
|
|
||||||
QTAILQ_ENTRY(VirtIOSCSIReq) next;
|
QTAILQ_ENTRY(VirtIOSCSIReq) next;
|
||||||
|
|
||||||
/* Used for cancellation of request during TMFs */
|
/* Used for cancellation of request during TMFs */
|
||||||
int remaining;
|
int remaining;
|
||||||
};
|
|
||||||
|
|
||||||
SCSIRequest *sreq;
|
SCSIRequest *sreq;
|
||||||
size_t resp_size;
|
size_t resp_size;
|
||||||
|
@ -294,6 +292,122 @@ static inline void virtio_scsi_ctx_check(VirtIOSCSI *s, SCSIDevice *d)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void virtio_scsi_do_one_tmf_bh(VirtIOSCSIReq *req)
|
||||||
|
{
|
||||||
|
VirtIOSCSI *s = req->dev;
|
||||||
|
SCSIDevice *d = virtio_scsi_device_get(s, req->req.tmf.lun);
|
||||||
|
BusChild *kid;
|
||||||
|
int target;
|
||||||
|
|
||||||
|
switch (req->req.tmf.subtype) {
|
||||||
|
case VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET:
|
||||||
|
if (!d) {
|
||||||
|
req->resp.tmf.response = VIRTIO_SCSI_S_BAD_TARGET;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (d->lun != virtio_scsi_get_lun(req->req.tmf.lun)) {
|
||||||
|
req->resp.tmf.response = VIRTIO_SCSI_S_INCORRECT_LUN;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
qatomic_inc(&s->resetting);
|
||||||
|
device_cold_reset(&d->qdev);
|
||||||
|
qatomic_dec(&s->resetting);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET:
|
||||||
|
target = req->req.tmf.lun[1];
|
||||||
|
qatomic_inc(&s->resetting);
|
||||||
|
|
||||||
|
rcu_read_lock();
|
||||||
|
QTAILQ_FOREACH_RCU(kid, &s->bus.qbus.children, sibling) {
|
||||||
|
SCSIDevice *d1 = SCSI_DEVICE(kid->child);
|
||||||
|
if (d1->channel == 0 && d1->id == target) {
|
||||||
|
device_cold_reset(&d1->qdev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rcu_read_unlock();
|
||||||
|
|
||||||
|
qatomic_dec(&s->resetting);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_assert_not_reached();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
object_unref(OBJECT(d));
|
||||||
|
|
||||||
|
virtio_scsi_acquire(s);
|
||||||
|
virtio_scsi_complete_req(req);
|
||||||
|
virtio_scsi_release(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Some TMFs must be processed from the main loop thread */
|
||||||
|
static void virtio_scsi_do_tmf_bh(void *opaque)
|
||||||
|
{
|
||||||
|
VirtIOSCSI *s = opaque;
|
||||||
|
QTAILQ_HEAD(, VirtIOSCSIReq) reqs = QTAILQ_HEAD_INITIALIZER(reqs);
|
||||||
|
VirtIOSCSIReq *req;
|
||||||
|
VirtIOSCSIReq *tmp;
|
||||||
|
|
||||||
|
GLOBAL_STATE_CODE();
|
||||||
|
|
||||||
|
virtio_scsi_acquire(s);
|
||||||
|
|
||||||
|
QTAILQ_FOREACH_SAFE(req, &s->tmf_bh_list, next, tmp) {
|
||||||
|
QTAILQ_REMOVE(&s->tmf_bh_list, req, next);
|
||||||
|
QTAILQ_INSERT_TAIL(&reqs, req, next);
|
||||||
|
}
|
||||||
|
|
||||||
|
qemu_bh_delete(s->tmf_bh);
|
||||||
|
s->tmf_bh = NULL;
|
||||||
|
|
||||||
|
virtio_scsi_release(s);
|
||||||
|
|
||||||
|
QTAILQ_FOREACH_SAFE(req, &reqs, next, tmp) {
|
||||||
|
QTAILQ_REMOVE(&reqs, req, next);
|
||||||
|
virtio_scsi_do_one_tmf_bh(req);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void virtio_scsi_reset_tmf_bh(VirtIOSCSI *s)
|
||||||
|
{
|
||||||
|
VirtIOSCSIReq *req;
|
||||||
|
VirtIOSCSIReq *tmp;
|
||||||
|
|
||||||
|
GLOBAL_STATE_CODE();
|
||||||
|
|
||||||
|
virtio_scsi_acquire(s);
|
||||||
|
|
||||||
|
if (s->tmf_bh) {
|
||||||
|
qemu_bh_delete(s->tmf_bh);
|
||||||
|
s->tmf_bh = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTAILQ_FOREACH_SAFE(req, &s->tmf_bh_list, next, tmp) {
|
||||||
|
QTAILQ_REMOVE(&s->tmf_bh_list, req, next);
|
||||||
|
|
||||||
|
/* SAM-6 6.3.2 Hard reset */
|
||||||
|
req->resp.tmf.response = VIRTIO_SCSI_S_TARGET_FAILURE;
|
||||||
|
virtio_scsi_complete_req(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtio_scsi_release(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void virtio_scsi_defer_tmf_to_bh(VirtIOSCSIReq *req)
|
||||||
|
{
|
||||||
|
VirtIOSCSI *s = req->dev;
|
||||||
|
|
||||||
|
QTAILQ_INSERT_TAIL(&s->tmf_bh_list, req, next);
|
||||||
|
|
||||||
|
if (!s->tmf_bh) {
|
||||||
|
s->tmf_bh = qemu_bh_new(virtio_scsi_do_tmf_bh, s);
|
||||||
|
qemu_bh_schedule(s->tmf_bh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Return 0 if the request is ready to be completed and return to guest;
|
/* Return 0 if the request is ready to be completed and return to guest;
|
||||||
* -EINPROGRESS if the request is submitted and will be completed later, in the
|
* -EINPROGRESS if the request is submitted and will be completed later, in the
|
||||||
* case of async cancellation. */
|
* case of async cancellation. */
|
||||||
|
@ -301,8 +415,6 @@ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req)
|
||||||
{
|
{
|
||||||
SCSIDevice *d = virtio_scsi_device_get(s, req->req.tmf.lun);
|
SCSIDevice *d = virtio_scsi_device_get(s, req->req.tmf.lun);
|
||||||
SCSIRequest *r, *next;
|
SCSIRequest *r, *next;
|
||||||
BusChild *kid;
|
|
||||||
int target;
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
virtio_scsi_ctx_check(s, d);
|
virtio_scsi_ctx_check(s, d);
|
||||||
|
@ -359,15 +471,9 @@ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET:
|
case VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET:
|
||||||
if (!d) {
|
case VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET:
|
||||||
goto fail;
|
virtio_scsi_defer_tmf_to_bh(req);
|
||||||
}
|
ret = -EINPROGRESS;
|
||||||
if (d->lun != virtio_scsi_get_lun(req->req.tmf.lun)) {
|
|
||||||
goto incorrect_lun;
|
|
||||||
}
|
|
||||||
s->resetting++;
|
|
||||||
device_cold_reset(&d->qdev);
|
|
||||||
s->resetting--;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIRTIO_SCSI_T_TMF_ABORT_TASK_SET:
|
case VIRTIO_SCSI_T_TMF_ABORT_TASK_SET:
|
||||||
|
@ -410,22 +516,6 @@ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET:
|
|
||||||
target = req->req.tmf.lun[1];
|
|
||||||
s->resetting++;
|
|
||||||
|
|
||||||
rcu_read_lock();
|
|
||||||
QTAILQ_FOREACH_RCU(kid, &s->bus.qbus.children, sibling) {
|
|
||||||
SCSIDevice *d1 = SCSI_DEVICE(kid->child);
|
|
||||||
if (d1->channel == 0 && d1->id == target) {
|
|
||||||
device_cold_reset(&d1->qdev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rcu_read_unlock();
|
|
||||||
|
|
||||||
s->resetting--;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VIRTIO_SCSI_T_TMF_CLEAR_ACA:
|
case VIRTIO_SCSI_T_TMF_CLEAR_ACA:
|
||||||
default:
|
default:
|
||||||
req->resp.tmf.response = VIRTIO_SCSI_S_FUNCTION_REJECTED;
|
req->resp.tmf.response = VIRTIO_SCSI_S_FUNCTION_REJECTED;
|
||||||
|
@ -655,7 +745,7 @@ static void virtio_scsi_request_cancelled(SCSIRequest *r)
|
||||||
if (!req) {
|
if (!req) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (req->dev->resetting) {
|
if (qatomic_read(&req->dev->resetting)) {
|
||||||
req->resp.cmd.response = VIRTIO_SCSI_S_RESET;
|
req->resp.cmd.response = VIRTIO_SCSI_S_RESET;
|
||||||
} else {
|
} else {
|
||||||
req->resp.cmd.response = VIRTIO_SCSI_S_ABORTED;
|
req->resp.cmd.response = VIRTIO_SCSI_S_ABORTED;
|
||||||
|
@ -831,9 +921,12 @@ static void virtio_scsi_reset(VirtIODevice *vdev)
|
||||||
VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev);
|
VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev);
|
||||||
|
|
||||||
assert(!s->dataplane_started);
|
assert(!s->dataplane_started);
|
||||||
s->resetting++;
|
|
||||||
|
virtio_scsi_reset_tmf_bh(s);
|
||||||
|
|
||||||
|
qatomic_inc(&s->resetting);
|
||||||
bus_cold_reset(BUS(&s->bus));
|
bus_cold_reset(BUS(&s->bus));
|
||||||
s->resetting--;
|
qatomic_dec(&s->resetting);
|
||||||
|
|
||||||
vs->sense_size = VIRTIO_SCSI_SENSE_DEFAULT_SIZE;
|
vs->sense_size = VIRTIO_SCSI_SENSE_DEFAULT_SIZE;
|
||||||
vs->cdb_size = VIRTIO_SCSI_CDB_DEFAULT_SIZE;
|
vs->cdb_size = VIRTIO_SCSI_CDB_DEFAULT_SIZE;
|
||||||
|
@ -1053,6 +1146,8 @@ static void virtio_scsi_device_realize(DeviceState *dev, Error **errp)
|
||||||
VirtIOSCSI *s = VIRTIO_SCSI(dev);
|
VirtIOSCSI *s = VIRTIO_SCSI(dev);
|
||||||
Error *err = NULL;
|
Error *err = NULL;
|
||||||
|
|
||||||
|
QTAILQ_INIT(&s->tmf_bh_list);
|
||||||
|
|
||||||
virtio_scsi_common_realize(dev,
|
virtio_scsi_common_realize(dev,
|
||||||
virtio_scsi_handle_ctrl,
|
virtio_scsi_handle_ctrl,
|
||||||
virtio_scsi_handle_event,
|
virtio_scsi_handle_event,
|
||||||
|
@ -1090,6 +1185,8 @@ static void virtio_scsi_device_unrealize(DeviceState *dev)
|
||||||
{
|
{
|
||||||
VirtIOSCSI *s = VIRTIO_SCSI(dev);
|
VirtIOSCSI *s = VIRTIO_SCSI(dev);
|
||||||
|
|
||||||
|
virtio_scsi_reset_tmf_bh(s);
|
||||||
|
|
||||||
qbus_set_hotplug_handler(BUS(&s->bus), NULL);
|
qbus_set_hotplug_handler(BUS(&s->bus), NULL);
|
||||||
virtio_scsi_common_unrealize(dev);
|
virtio_scsi_common_unrealize(dev);
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,9 +36,9 @@ void block_copy_set_progress_meter(BlockCopyState *s, ProgressMeter *pm);
|
||||||
void block_copy_state_free(BlockCopyState *s);
|
void block_copy_state_free(BlockCopyState *s);
|
||||||
|
|
||||||
void block_copy_reset(BlockCopyState *s, int64_t offset, int64_t bytes);
|
void block_copy_reset(BlockCopyState *s, int64_t offset, int64_t bytes);
|
||||||
int64_t coroutine_fn block_copy_reset_unallocated(BlockCopyState *s,
|
|
||||||
int64_t offset,
|
int64_t coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t *count);
|
block_copy_reset_unallocated(BlockCopyState *s, int64_t offset, int64_t *count);
|
||||||
|
|
||||||
int coroutine_fn block_copy(BlockCopyState *s, int64_t offset, int64_t bytes,
|
int coroutine_fn block_copy(BlockCopyState *s, int64_t offset, int64_t bytes,
|
||||||
bool ignore_ratelimit, uint64_t timeout_ns,
|
bool ignore_ratelimit, uint64_t timeout_ns,
|
||||||
|
|
|
@ -58,13 +58,15 @@ BlockDriver *bdrv_find_protocol(const char *filename,
|
||||||
Error **errp);
|
Error **errp);
|
||||||
BlockDriver *bdrv_find_format(const char *format_name);
|
BlockDriver *bdrv_find_format(const char *format_name);
|
||||||
|
|
||||||
int coroutine_fn bdrv_co_create(BlockDriver *drv, const char *filename,
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
QemuOpts *opts, Error **errp);
|
bdrv_co_create(BlockDriver *drv, const char *filename, QemuOpts *opts,
|
||||||
int co_wrapper bdrv_create(BlockDriver *drv, const char *filename,
|
Error **errp);
|
||||||
|
|
||||||
|
int co_wrapper_bdrv_rdlock bdrv_create(BlockDriver *drv, const char *filename,
|
||||||
QemuOpts *opts, Error **errp);
|
QemuOpts *opts, Error **errp);
|
||||||
|
|
||||||
int coroutine_fn bdrv_co_create_file(const char *filename, QemuOpts *opts,
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
Error **errp);
|
bdrv_co_create_file(const char *filename, QemuOpts *opts, Error **errp);
|
||||||
|
|
||||||
BlockDriverState *bdrv_new(void);
|
BlockDriverState *bdrv_new(void);
|
||||||
int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top,
|
int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top,
|
||||||
|
|
|
@ -60,27 +60,29 @@ int co_wrapper_mixed_bdrv_rdlock
|
||||||
bdrv_pwrite_sync(BdrvChild *child, int64_t offset, int64_t bytes,
|
bdrv_pwrite_sync(BdrvChild *child, int64_t offset, int64_t bytes,
|
||||||
const void *buf, BdrvRequestFlags flags);
|
const void *buf, BdrvRequestFlags flags);
|
||||||
|
|
||||||
int coroutine_fn bdrv_co_pwrite_sync(BdrvChild *child, int64_t offset,
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t bytes, const void *buf,
|
bdrv_co_pwrite_sync(BdrvChild *child, int64_t offset, int64_t bytes,
|
||||||
BdrvRequestFlags flags);
|
const void *buf, BdrvRequestFlags flags);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Efficiently zero a region of the disk image. Note that this is a regular
|
* Efficiently zero a region of the disk image. Note that this is a regular
|
||||||
* I/O request like read or write and should have a reasonable size. This
|
* I/O request like read or write and should have a reasonable size. This
|
||||||
* 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(BdrvChild *child, int64_t offset,
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t bytes, BdrvRequestFlags flags);
|
bdrv_co_pwrite_zeroes(BdrvChild *child, int64_t offset, int64_t bytes,
|
||||||
|
BdrvRequestFlags flags);
|
||||||
|
|
||||||
int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
PreallocMode prealloc, BdrvRequestFlags flags,
|
bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
|
||||||
Error **errp);
|
PreallocMode prealloc, BdrvRequestFlags flags, Error **errp);
|
||||||
|
|
||||||
int64_t coroutine_fn bdrv_co_nb_sectors(BlockDriverState *bs);
|
int64_t coroutine_fn GRAPH_RDLOCK bdrv_co_nb_sectors(BlockDriverState *bs);
|
||||||
int64_t co_wrapper_mixed bdrv_nb_sectors(BlockDriverState *bs);
|
int64_t co_wrapper_mixed_bdrv_rdlock bdrv_nb_sectors(BlockDriverState *bs);
|
||||||
|
|
||||||
int64_t coroutine_fn bdrv_co_getlength(BlockDriverState *bs);
|
int64_t coroutine_fn GRAPH_RDLOCK bdrv_co_getlength(BlockDriverState *bs);
|
||||||
int64_t co_wrapper_mixed bdrv_getlength(BlockDriverState *bs);
|
int64_t co_wrapper_mixed_bdrv_rdlock bdrv_getlength(BlockDriverState *bs);
|
||||||
|
|
||||||
int64_t coroutine_fn bdrv_co_get_allocated_file_size(BlockDriverState *bs);
|
int64_t coroutine_fn bdrv_co_get_allocated_file_size(BlockDriverState *bs);
|
||||||
int64_t co_wrapper bdrv_get_allocated_file_size(BlockDriverState *bs);
|
int64_t co_wrapper bdrv_get_allocated_file_size(BlockDriverState *bs);
|
||||||
|
@ -88,8 +90,12 @@ int64_t co_wrapper bdrv_get_allocated_file_size(BlockDriverState *bs);
|
||||||
BlockMeasureInfo *bdrv_measure(BlockDriver *drv, QemuOpts *opts,
|
BlockMeasureInfo *bdrv_measure(BlockDriver *drv, QemuOpts *opts,
|
||||||
BlockDriverState *in_bs, Error **errp);
|
BlockDriverState *in_bs, Error **errp);
|
||||||
void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr);
|
void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr);
|
||||||
int coroutine_fn bdrv_co_delete_file(BlockDriverState *bs, Error **errp);
|
|
||||||
void coroutine_fn bdrv_co_delete_file_noerr(BlockDriverState *bs);
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
|
bdrv_co_delete_file(BlockDriverState *bs, Error **errp);
|
||||||
|
|
||||||
|
void coroutine_fn GRAPH_RDLOCK
|
||||||
|
bdrv_co_delete_file_noerr(BlockDriverState *bs);
|
||||||
|
|
||||||
|
|
||||||
/* async block I/O */
|
/* async block I/O */
|
||||||
|
@ -97,45 +103,45 @@ void bdrv_aio_cancel(BlockAIOCB *acb);
|
||||||
void bdrv_aio_cancel_async(BlockAIOCB *acb);
|
void bdrv_aio_cancel_async(BlockAIOCB *acb);
|
||||||
|
|
||||||
/* sg packet commands */
|
/* sg packet commands */
|
||||||
int coroutine_fn bdrv_co_ioctl(BlockDriverState *bs, int req, void *buf);
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
|
bdrv_co_ioctl(BlockDriverState *bs, int req, void *buf);
|
||||||
|
|
||||||
/* Ensure contents are flushed to disk. */
|
/* Ensure contents are flushed to disk. */
|
||||||
int coroutine_fn bdrv_co_flush(BlockDriverState *bs);
|
int coroutine_fn GRAPH_RDLOCK bdrv_co_flush(BlockDriverState *bs);
|
||||||
|
|
||||||
int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset,
|
int coroutine_fn GRAPH_RDLOCK bdrv_co_pdiscard(BdrvChild *child, int64_t offset,
|
||||||
int64_t bytes);
|
int64_t bytes);
|
||||||
|
|
||||||
bool bdrv_can_write_zeroes_with_unmap(BlockDriverState *bs);
|
bool bdrv_can_write_zeroes_with_unmap(BlockDriverState *bs);
|
||||||
int bdrv_block_status(BlockDriverState *bs, int64_t offset,
|
int bdrv_block_status(BlockDriverState *bs, int64_t offset,
|
||||||
int64_t bytes, int64_t *pnum, int64_t *map,
|
int64_t bytes, int64_t *pnum, int64_t *map,
|
||||||
BlockDriverState **file);
|
BlockDriverState **file);
|
||||||
|
|
||||||
int coroutine_fn bdrv_co_block_status_above(BlockDriverState *bs,
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
BlockDriverState *base,
|
bdrv_co_block_status_above(BlockDriverState *bs, BlockDriverState *base,
|
||||||
int64_t offset, int64_t bytes,
|
int64_t offset, int64_t bytes, int64_t *pnum,
|
||||||
int64_t *pnum, int64_t *map,
|
int64_t *map, BlockDriverState **file);
|
||||||
BlockDriverState **file);
|
|
||||||
int bdrv_block_status_above(BlockDriverState *bs, BlockDriverState *base,
|
int bdrv_block_status_above(BlockDriverState *bs, BlockDriverState *base,
|
||||||
int64_t offset, int64_t bytes, int64_t *pnum,
|
int64_t offset, int64_t bytes, int64_t *pnum,
|
||||||
int64_t *map, BlockDriverState **file);
|
int64_t *map, BlockDriverState **file);
|
||||||
|
|
||||||
int coroutine_fn bdrv_co_is_allocated(BlockDriverState *bs, int64_t offset,
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t bytes, int64_t *pnum);
|
bdrv_co_is_allocated(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
|
int64_t *pnum);
|
||||||
int bdrv_is_allocated(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
int bdrv_is_allocated(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
int64_t *pnum);
|
int64_t *pnum);
|
||||||
|
|
||||||
int coroutine_fn bdrv_co_is_allocated_above(BlockDriverState *top,
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
BlockDriverState *base,
|
bdrv_co_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
|
||||||
bool include_base, int64_t offset,
|
bool include_base, int64_t offset, int64_t bytes,
|
||||||
int64_t bytes, int64_t *pnum);
|
int64_t *pnum);
|
||||||
int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
|
int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
|
||||||
bool include_base, int64_t offset, int64_t bytes,
|
bool include_base, int64_t offset, int64_t bytes,
|
||||||
int64_t *pnum);
|
int64_t *pnum);
|
||||||
|
|
||||||
int coroutine_fn bdrv_co_is_zero_fast(BlockDriverState *bs, int64_t offset,
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t bytes);
|
bdrv_co_is_zero_fast(BlockDriverState *bs, int64_t offset, int64_t bytes);
|
||||||
|
|
||||||
int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
|
|
||||||
bool ignore_allow_rdw, Error **errp);
|
|
||||||
int bdrv_apply_auto_read_only(BlockDriverState *bs, const char *errmsg,
|
int bdrv_apply_auto_read_only(BlockDriverState *bs, const char *errmsg,
|
||||||
Error **errp);
|
Error **errp);
|
||||||
bool bdrv_is_read_only(BlockDriverState *bs);
|
bool bdrv_is_read_only(BlockDriverState *bs);
|
||||||
|
@ -143,11 +149,14 @@ bool bdrv_is_writable(BlockDriverState *bs);
|
||||||
bool bdrv_is_sg(BlockDriverState *bs);
|
bool bdrv_is_sg(BlockDriverState *bs);
|
||||||
int bdrv_get_flags(BlockDriverState *bs);
|
int bdrv_get_flags(BlockDriverState *bs);
|
||||||
|
|
||||||
bool coroutine_fn bdrv_co_is_inserted(BlockDriverState *bs);
|
bool coroutine_fn GRAPH_RDLOCK bdrv_co_is_inserted(BlockDriverState *bs);
|
||||||
bool co_wrapper bdrv_is_inserted(BlockDriverState *bs);
|
bool co_wrapper_bdrv_rdlock bdrv_is_inserted(BlockDriverState *bs);
|
||||||
|
|
||||||
void coroutine_fn bdrv_co_lock_medium(BlockDriverState *bs, bool locked);
|
void coroutine_fn GRAPH_RDLOCK
|
||||||
void coroutine_fn bdrv_co_eject(BlockDriverState *bs, bool eject_flag);
|
bdrv_co_lock_medium(BlockDriverState *bs, bool locked);
|
||||||
|
|
||||||
|
void coroutine_fn GRAPH_RDLOCK
|
||||||
|
bdrv_co_eject(BlockDriverState *bs, bool eject_flag);
|
||||||
|
|
||||||
const char *bdrv_get_format_name(BlockDriverState *bs);
|
const char *bdrv_get_format_name(BlockDriverState *bs);
|
||||||
|
|
||||||
|
@ -231,17 +240,15 @@ void coroutine_fn bdrv_co_leave(BlockDriverState *bs, AioContext *old_ctx);
|
||||||
|
|
||||||
AioContext *child_of_bds_get_parent_aio_context(BdrvChild *c);
|
AioContext *child_of_bds_get_parent_aio_context(BdrvChild *c);
|
||||||
|
|
||||||
void coroutine_fn bdrv_co_io_plug(BlockDriverState *bs);
|
void coroutine_fn GRAPH_RDLOCK bdrv_co_io_plug(BlockDriverState *bs);
|
||||||
void coroutine_fn bdrv_co_io_unplug(BlockDriverState *bs);
|
void coroutine_fn GRAPH_RDLOCK bdrv_co_io_unplug(BlockDriverState *bs);
|
||||||
|
|
||||||
bool coroutine_fn bdrv_co_can_store_new_dirty_bitmap(BlockDriverState *bs,
|
bool coroutine_fn GRAPH_RDLOCK
|
||||||
const char *name,
|
bdrv_co_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name,
|
||||||
uint32_t granularity,
|
uint32_t granularity, Error **errp);
|
||||||
Error **errp);
|
bool co_wrapper_bdrv_rdlock
|
||||||
bool co_wrapper bdrv_can_store_new_dirty_bitmap(BlockDriverState *bs,
|
bdrv_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name,
|
||||||
const char *name,
|
uint32_t granularity, Error **errp);
|
||||||
uint32_t granularity,
|
|
||||||
Error **errp);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -272,7 +279,8 @@ bool co_wrapper bdrv_can_store_new_dirty_bitmap(BlockDriverState *bs,
|
||||||
*
|
*
|
||||||
* Returns: 0 if succeeded; negative error code if failed.
|
* Returns: 0 if succeeded; negative error code if failed.
|
||||||
**/
|
**/
|
||||||
int coroutine_fn bdrv_co_copy_range(BdrvChild *src, int64_t src_offset,
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
|
bdrv_co_copy_range(BdrvChild *src, int64_t src_offset,
|
||||||
BdrvChild *dst, int64_t dst_offset,
|
BdrvChild *dst, int64_t dst_offset,
|
||||||
int64_t bytes, BdrvRequestFlags read_flags,
|
int64_t bytes, BdrvRequestFlags read_flags,
|
||||||
BdrvRequestFlags write_flags);
|
BdrvRequestFlags write_flags);
|
||||||
|
|
|
@ -246,12 +246,11 @@ struct BlockDriver {
|
||||||
Error **errp);
|
Error **errp);
|
||||||
void (*bdrv_close)(BlockDriverState *bs);
|
void (*bdrv_close)(BlockDriverState *bs);
|
||||||
|
|
||||||
int coroutine_fn (*bdrv_co_create)(BlockdevCreateOptions *opts,
|
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_create)(
|
||||||
Error **errp);
|
BlockdevCreateOptions *opts, Error **errp);
|
||||||
int coroutine_fn (*bdrv_co_create_opts)(BlockDriver *drv,
|
|
||||||
const char *filename,
|
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_create_opts)(
|
||||||
QemuOpts *opts,
|
BlockDriver *drv, const char *filename, QemuOpts *opts, Error **errp);
|
||||||
Error **errp);
|
|
||||||
|
|
||||||
int (*bdrv_amend_options)(BlockDriverState *bs,
|
int (*bdrv_amend_options)(BlockDriverState *bs,
|
||||||
QemuOpts *opts,
|
QemuOpts *opts,
|
||||||
|
@ -446,9 +445,10 @@ struct BlockDriver {
|
||||||
*
|
*
|
||||||
* Returns: true on success, false on failure
|
* Returns: true on success, false on failure
|
||||||
*/
|
*/
|
||||||
bool (*bdrv_register_buf)(BlockDriverState *bs, void *host, size_t size,
|
bool GRAPH_RDLOCK_PTR (*bdrv_register_buf)(
|
||||||
Error **errp);
|
BlockDriverState *bs, void *host, size_t size, Error **errp);
|
||||||
void (*bdrv_unregister_buf)(BlockDriverState *bs, void *host, size_t size);
|
void GRAPH_RDLOCK_PTR (*bdrv_unregister_buf)(
|
||||||
|
BlockDriverState *bs, void *host, size_t size);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This field is modified only under the BQL, and is part of
|
* This field is modified only under the BQL, and is part of
|
||||||
|
@ -471,19 +471,22 @@ struct BlockDriver {
|
||||||
Error **errp);
|
Error **errp);
|
||||||
|
|
||||||
/* aio */
|
/* aio */
|
||||||
BlockAIOCB *(*bdrv_aio_preadv)(BlockDriverState *bs,
|
BlockAIOCB * GRAPH_RDLOCK_PTR (*bdrv_aio_preadv)(BlockDriverState *bs,
|
||||||
int64_t offset, int64_t bytes, QEMUIOVector *qiov,
|
int64_t offset, int64_t bytes, QEMUIOVector *qiov,
|
||||||
BdrvRequestFlags flags, BlockCompletionFunc *cb, void *opaque);
|
BdrvRequestFlags flags, BlockCompletionFunc *cb, void *opaque);
|
||||||
BlockAIOCB *(*bdrv_aio_pwritev)(BlockDriverState *bs,
|
|
||||||
|
BlockAIOCB * GRAPH_RDLOCK_PTR (*bdrv_aio_pwritev)(BlockDriverState *bs,
|
||||||
int64_t offset, int64_t bytes, QEMUIOVector *qiov,
|
int64_t offset, int64_t bytes, QEMUIOVector *qiov,
|
||||||
BdrvRequestFlags flags, BlockCompletionFunc *cb, void *opaque);
|
BdrvRequestFlags flags, BlockCompletionFunc *cb, void *opaque);
|
||||||
BlockAIOCB *(*bdrv_aio_flush)(BlockDriverState *bs,
|
|
||||||
BlockCompletionFunc *cb, void *opaque);
|
BlockAIOCB * GRAPH_RDLOCK_PTR (*bdrv_aio_flush)(
|
||||||
BlockAIOCB *(*bdrv_aio_pdiscard)(BlockDriverState *bs,
|
BlockDriverState *bs, BlockCompletionFunc *cb, void *opaque);
|
||||||
int64_t offset, int bytes,
|
|
||||||
|
BlockAIOCB * GRAPH_RDLOCK_PTR (*bdrv_aio_pdiscard)(
|
||||||
|
BlockDriverState *bs, int64_t offset, int bytes,
|
||||||
BlockCompletionFunc *cb, void *opaque);
|
BlockCompletionFunc *cb, void *opaque);
|
||||||
|
|
||||||
int coroutine_fn (*bdrv_co_readv)(BlockDriverState *bs,
|
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_readv)(BlockDriverState *bs,
|
||||||
int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
|
int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -501,16 +504,16 @@ struct BlockDriver {
|
||||||
*
|
*
|
||||||
* The buffer in @qiov may point directly to guest memory.
|
* The buffer in @qiov may point directly to guest memory.
|
||||||
*/
|
*/
|
||||||
int coroutine_fn (*bdrv_co_preadv)(BlockDriverState *bs,
|
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_preadv)(BlockDriverState *bs,
|
||||||
int64_t offset, int64_t bytes, QEMUIOVector *qiov,
|
int64_t offset, int64_t bytes, QEMUIOVector *qiov,
|
||||||
BdrvRequestFlags flags);
|
BdrvRequestFlags flags);
|
||||||
|
|
||||||
int coroutine_fn (*bdrv_co_preadv_part)(BlockDriverState *bs,
|
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_preadv_part)(
|
||||||
int64_t offset, int64_t bytes,
|
BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
QEMUIOVector *qiov, size_t qiov_offset,
|
QEMUIOVector *qiov, size_t qiov_offset,
|
||||||
BdrvRequestFlags flags);
|
BdrvRequestFlags flags);
|
||||||
|
|
||||||
int coroutine_fn (*bdrv_co_writev)(BlockDriverState *bs,
|
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_writev)(BlockDriverState *bs,
|
||||||
int64_t sector_num, int nb_sectors, QEMUIOVector *qiov,
|
int64_t sector_num, int nb_sectors, QEMUIOVector *qiov,
|
||||||
int flags);
|
int flags);
|
||||||
/**
|
/**
|
||||||
|
@ -528,12 +531,12 @@ struct BlockDriver {
|
||||||
*
|
*
|
||||||
* The buffer in @qiov may point directly to guest memory.
|
* The buffer in @qiov may point directly to guest memory.
|
||||||
*/
|
*/
|
||||||
int coroutine_fn (*bdrv_co_pwritev)(BlockDriverState *bs,
|
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_pwritev)(
|
||||||
int64_t offset, int64_t bytes, QEMUIOVector *qiov,
|
BlockDriverState *bs, int64_t offset, int64_t bytes, QEMUIOVector *qiov,
|
||||||
BdrvRequestFlags flags);
|
|
||||||
int coroutine_fn (*bdrv_co_pwritev_part)(BlockDriverState *bs,
|
|
||||||
int64_t offset, int64_t bytes, QEMUIOVector *qiov, size_t qiov_offset,
|
|
||||||
BdrvRequestFlags flags);
|
BdrvRequestFlags flags);
|
||||||
|
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_pwritev_part)(
|
||||||
|
BlockDriverState *bs, int64_t offset, int64_t bytes, QEMUIOVector *qiov,
|
||||||
|
size_t qiov_offset, BdrvRequestFlags flags);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Efficiently zero a region of the disk image. Typically an image format
|
* Efficiently zero a region of the disk image. Typically an image format
|
||||||
|
@ -541,10 +544,12 @@ struct BlockDriver {
|
||||||
* function pointer may be NULL or return -ENOSUP and .bdrv_co_writev()
|
* function pointer may be NULL or return -ENOSUP and .bdrv_co_writev()
|
||||||
* will be called instead.
|
* will be called instead.
|
||||||
*/
|
*/
|
||||||
int coroutine_fn (*bdrv_co_pwrite_zeroes)(BlockDriverState *bs,
|
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_pwrite_zeroes)(
|
||||||
int64_t offset, int64_t bytes, BdrvRequestFlags flags);
|
BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
int coroutine_fn (*bdrv_co_pdiscard)(BlockDriverState *bs,
|
BdrvRequestFlags flags);
|
||||||
int64_t offset, int64_t bytes);
|
|
||||||
|
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_pdiscard)(
|
||||||
|
BlockDriverState *bs, int64_t offset, int64_t bytes);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Map [offset, offset + nbytes) range onto a child of @bs to copy from,
|
* Map [offset, offset + nbytes) range onto a child of @bs to copy from,
|
||||||
|
@ -554,14 +559,10 @@ struct BlockDriver {
|
||||||
* See the comment of bdrv_co_copy_range for the parameter and return value
|
* See the comment of bdrv_co_copy_range for the parameter and return value
|
||||||
* semantics.
|
* semantics.
|
||||||
*/
|
*/
|
||||||
int coroutine_fn (*bdrv_co_copy_range_from)(BlockDriverState *bs,
|
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_copy_range_from)(
|
||||||
BdrvChild *src,
|
BlockDriverState *bs, BdrvChild *src, int64_t offset,
|
||||||
int64_t offset,
|
BdrvChild *dst, int64_t dst_offset, int64_t bytes,
|
||||||
BdrvChild *dst,
|
BdrvRequestFlags read_flags, BdrvRequestFlags write_flags);
|
||||||
int64_t dst_offset,
|
|
||||||
int64_t bytes,
|
|
||||||
BdrvRequestFlags read_flags,
|
|
||||||
BdrvRequestFlags write_flags);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Map [offset, offset + nbytes) range onto a child of bs to copy data to,
|
* Map [offset, offset + nbytes) range onto a child of bs to copy data to,
|
||||||
|
@ -572,14 +573,10 @@ struct BlockDriver {
|
||||||
* See the comment of bdrv_co_copy_range for the parameter and return value
|
* See the comment of bdrv_co_copy_range for the parameter and return value
|
||||||
* semantics.
|
* semantics.
|
||||||
*/
|
*/
|
||||||
int coroutine_fn (*bdrv_co_copy_range_to)(BlockDriverState *bs,
|
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_copy_range_to)(
|
||||||
BdrvChild *src,
|
BlockDriverState *bs, BdrvChild *src, int64_t src_offset,
|
||||||
int64_t src_offset,
|
BdrvChild *dst, int64_t dst_offset, int64_t bytes,
|
||||||
BdrvChild *dst,
|
BdrvRequestFlags read_flags, BdrvRequestFlags write_flags);
|
||||||
int64_t dst_offset,
|
|
||||||
int64_t bytes,
|
|
||||||
BdrvRequestFlags read_flags,
|
|
||||||
BdrvRequestFlags write_flags);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Building block for bdrv_block_status[_above] and
|
* Building block for bdrv_block_status[_above] and
|
||||||
|
@ -606,7 +603,8 @@ struct BlockDriver {
|
||||||
* *pnum value for the block-status cache on protocol nodes, prior
|
* *pnum value for the block-status cache on protocol nodes, prior
|
||||||
* to clamping *pnum for return to its caller.
|
* to clamping *pnum for return to its caller.
|
||||||
*/
|
*/
|
||||||
int coroutine_fn (*bdrv_co_block_status)(BlockDriverState *bs,
|
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_block_status)(
|
||||||
|
BlockDriverState *bs,
|
||||||
bool want_zero, int64_t offset, int64_t bytes, int64_t *pnum,
|
bool want_zero, int64_t offset, int64_t bytes, int64_t *pnum,
|
||||||
int64_t *map, BlockDriverState **file);
|
int64_t *map, BlockDriverState **file);
|
||||||
|
|
||||||
|
@ -626,13 +624,16 @@ struct BlockDriver {
|
||||||
* - receive the snapshot's actual length (which may differ from bs's
|
* - receive the snapshot's actual length (which may differ from bs's
|
||||||
* length)
|
* length)
|
||||||
*/
|
*/
|
||||||
int coroutine_fn (*bdrv_co_preadv_snapshot)(BlockDriverState *bs,
|
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_preadv_snapshot)(
|
||||||
int64_t offset, int64_t bytes, QEMUIOVector *qiov, size_t qiov_offset);
|
BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
int coroutine_fn (*bdrv_co_snapshot_block_status)(BlockDriverState *bs,
|
QEMUIOVector *qiov, size_t qiov_offset);
|
||||||
bool want_zero, int64_t offset, int64_t bytes, int64_t *pnum,
|
|
||||||
int64_t *map, BlockDriverState **file);
|
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_snapshot_block_status)(
|
||||||
int coroutine_fn (*bdrv_co_pdiscard_snapshot)(BlockDriverState *bs,
|
BlockDriverState *bs, bool want_zero, int64_t offset, int64_t bytes,
|
||||||
int64_t offset, int64_t bytes);
|
int64_t *pnum, int64_t *map, BlockDriverState **file);
|
||||||
|
|
||||||
|
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_pdiscard_snapshot)(
|
||||||
|
BlockDriverState *bs, int64_t offset, int64_t bytes);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Invalidate any cached meta-data.
|
* Invalidate any cached meta-data.
|
||||||
|
@ -645,24 +646,26 @@ struct BlockDriver {
|
||||||
* layers, if needed. This function is needed for deterministic
|
* layers, if needed. This function is needed for deterministic
|
||||||
* synchronization of the flush finishing callback.
|
* synchronization of the flush finishing callback.
|
||||||
*/
|
*/
|
||||||
int coroutine_fn (*bdrv_co_flush)(BlockDriverState *bs);
|
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_flush)(BlockDriverState *bs);
|
||||||
|
|
||||||
/* Delete a created file. */
|
/* Delete a created file. */
|
||||||
int coroutine_fn (*bdrv_co_delete_file)(BlockDriverState *bs,
|
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_delete_file)(
|
||||||
Error **errp);
|
BlockDriverState *bs, Error **errp);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Flushes all data that was already written to the OS all the way down to
|
* Flushes all data that was already written to the OS all the way down to
|
||||||
* the disk (for example file-posix.c calls fsync()).
|
* the disk (for example file-posix.c calls fsync()).
|
||||||
*/
|
*/
|
||||||
int coroutine_fn (*bdrv_co_flush_to_disk)(BlockDriverState *bs);
|
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_flush_to_disk)(
|
||||||
|
BlockDriverState *bs);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Flushes all internal caches to the OS. The data may still sit in a
|
* Flushes all internal caches to the OS. The data may still sit in a
|
||||||
* writeback cache of the host OS, but it will survive a crash of the qemu
|
* writeback cache of the host OS, but it will survive a crash of the qemu
|
||||||
* process.
|
* process.
|
||||||
*/
|
*/
|
||||||
int coroutine_fn (*bdrv_co_flush_to_os)(BlockDriverState *bs);
|
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_flush_to_os)(
|
||||||
|
BlockDriverState *bs);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Truncate @bs to @offset bytes using the given @prealloc mode
|
* Truncate @bs to @offset bytes using the given @prealloc mode
|
||||||
|
@ -677,21 +680,26 @@ struct BlockDriver {
|
||||||
* If @exact is true and this function fails but would succeed
|
* If @exact is true and this function fails but would succeed
|
||||||
* with @exact = false, it should return -ENOTSUP.
|
* with @exact = false, it should return -ENOTSUP.
|
||||||
*/
|
*/
|
||||||
int coroutine_fn (*bdrv_co_truncate)(BlockDriverState *bs, int64_t offset,
|
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_truncate)(
|
||||||
bool exact, PreallocMode prealloc,
|
BlockDriverState *bs, int64_t offset, bool exact,
|
||||||
BdrvRequestFlags flags, Error **errp);
|
PreallocMode prealloc, BdrvRequestFlags flags, Error **errp);
|
||||||
int64_t coroutine_fn (*bdrv_co_getlength)(BlockDriverState *bs);
|
|
||||||
|
int64_t coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_getlength)(
|
||||||
|
BlockDriverState *bs);
|
||||||
|
|
||||||
int64_t coroutine_fn (*bdrv_co_get_allocated_file_size)(
|
int64_t coroutine_fn (*bdrv_co_get_allocated_file_size)(
|
||||||
BlockDriverState *bs);
|
BlockDriverState *bs);
|
||||||
|
|
||||||
BlockMeasureInfo *(*bdrv_measure)(QemuOpts *opts, BlockDriverState *in_bs,
|
BlockMeasureInfo *(*bdrv_measure)(QemuOpts *opts, BlockDriverState *in_bs,
|
||||||
Error **errp);
|
Error **errp);
|
||||||
|
|
||||||
int coroutine_fn (*bdrv_co_pwritev_compressed)(BlockDriverState *bs,
|
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_pwritev_compressed)(
|
||||||
int64_t offset, int64_t bytes, QEMUIOVector *qiov);
|
BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
int coroutine_fn (*bdrv_co_pwritev_compressed_part)(BlockDriverState *bs,
|
QEMUIOVector *qiov);
|
||||||
int64_t offset, int64_t bytes, QEMUIOVector *qiov,
|
|
||||||
size_t qiov_offset);
|
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_pwritev_compressed_part)(
|
||||||
|
BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
|
QEMUIOVector *qiov, size_t qiov_offset);
|
||||||
|
|
||||||
int coroutine_fn (*bdrv_co_get_info)(BlockDriverState *bs,
|
int coroutine_fn (*bdrv_co_get_info)(BlockDriverState *bs,
|
||||||
BlockDriverInfo *bdi);
|
BlockDriverInfo *bdi);
|
||||||
|
@ -707,16 +715,20 @@ struct BlockDriver {
|
||||||
BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos);
|
BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos);
|
||||||
|
|
||||||
/* removable device specific */
|
/* removable device specific */
|
||||||
bool coroutine_fn (*bdrv_co_is_inserted)(BlockDriverState *bs);
|
bool coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_is_inserted)(
|
||||||
void coroutine_fn (*bdrv_co_eject)(BlockDriverState *bs, bool eject_flag);
|
BlockDriverState *bs);
|
||||||
void coroutine_fn (*bdrv_co_lock_medium)(BlockDriverState *bs, bool locked);
|
void coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_eject)(
|
||||||
|
BlockDriverState *bs, bool eject_flag);
|
||||||
|
void coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_lock_medium)(
|
||||||
|
BlockDriverState *bs, bool locked);
|
||||||
|
|
||||||
/* to control generic scsi devices */
|
/* to control generic scsi devices */
|
||||||
BlockAIOCB *(*bdrv_aio_ioctl)(BlockDriverState *bs,
|
BlockAIOCB *coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_aio_ioctl)(
|
||||||
unsigned long int req, void *buf,
|
BlockDriverState *bs, unsigned long int req, void *buf,
|
||||||
BlockCompletionFunc *cb, void *opaque);
|
BlockCompletionFunc *cb, void *opaque);
|
||||||
int coroutine_fn (*bdrv_co_ioctl)(BlockDriverState *bs,
|
|
||||||
unsigned long int req, void *buf);
|
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_ioctl)(
|
||||||
|
BlockDriverState *bs, unsigned long int req, void *buf);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns 0 for completed check, -errno for internal errors.
|
* Returns 0 for completed check, -errno for internal errors.
|
||||||
|
@ -729,8 +741,9 @@ struct BlockDriver {
|
||||||
BlkdebugEvent event);
|
BlkdebugEvent event);
|
||||||
|
|
||||||
/* io queue for linux-aio */
|
/* io queue for linux-aio */
|
||||||
void coroutine_fn (*bdrv_co_io_plug)(BlockDriverState *bs);
|
void coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_io_plug)(BlockDriverState *bs);
|
||||||
void coroutine_fn (*bdrv_co_io_unplug)(BlockDriverState *bs);
|
void coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_io_unplug)(
|
||||||
|
BlockDriverState *bs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bdrv_drain_begin is called if implemented in the beginning of a
|
* bdrv_drain_begin is called if implemented in the beginning of a
|
||||||
|
@ -748,14 +761,16 @@ struct BlockDriver {
|
||||||
void (*bdrv_drain_end)(BlockDriverState *bs);
|
void (*bdrv_drain_end)(BlockDriverState *bs);
|
||||||
|
|
||||||
bool (*bdrv_supports_persistent_dirty_bitmap)(BlockDriverState *bs);
|
bool (*bdrv_supports_persistent_dirty_bitmap)(BlockDriverState *bs);
|
||||||
bool coroutine_fn (*bdrv_co_can_store_new_dirty_bitmap)(
|
|
||||||
|
bool coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_can_store_new_dirty_bitmap)(
|
||||||
BlockDriverState *bs, const char *name, uint32_t granularity,
|
BlockDriverState *bs, const char *name, uint32_t granularity,
|
||||||
Error **errp);
|
Error **errp);
|
||||||
int coroutine_fn (*bdrv_co_remove_persistent_dirty_bitmap)(
|
|
||||||
|
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_remove_persistent_dirty_bitmap)(
|
||||||
BlockDriverState *bs, const char *name, Error **errp);
|
BlockDriverState *bs, const char *name, Error **errp);
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline bool block_driver_can_compress(BlockDriver *drv)
|
static inline bool TSA_NO_TSA block_driver_can_compress(BlockDriver *drv)
|
||||||
{
|
{
|
||||||
return drv->bdrv_co_pwritev_compressed ||
|
return drv->bdrv_co_pwritev_compressed ||
|
||||||
drv->bdrv_co_pwritev_compressed_part;
|
drv->bdrv_co_pwritev_compressed_part;
|
||||||
|
|
|
@ -35,42 +35,44 @@
|
||||||
* the I/O API.
|
* the I/O API.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int coroutine_fn bdrv_co_preadv_snapshot(BdrvChild *child,
|
int coroutine_fn GRAPH_RDLOCK bdrv_co_preadv_snapshot(BdrvChild *child,
|
||||||
int64_t offset, int64_t bytes, QEMUIOVector *qiov, size_t qiov_offset);
|
int64_t offset, int64_t bytes, QEMUIOVector *qiov, size_t qiov_offset);
|
||||||
int coroutine_fn bdrv_co_snapshot_block_status(BlockDriverState *bs,
|
int coroutine_fn GRAPH_RDLOCK bdrv_co_snapshot_block_status(
|
||||||
bool want_zero, int64_t offset, int64_t bytes, int64_t *pnum,
|
BlockDriverState *bs, bool want_zero, int64_t offset, int64_t bytes,
|
||||||
int64_t *map, BlockDriverState **file);
|
int64_t *pnum, int64_t *map, BlockDriverState **file);
|
||||||
int coroutine_fn bdrv_co_pdiscard_snapshot(BlockDriverState *bs,
|
int coroutine_fn GRAPH_RDLOCK bdrv_co_pdiscard_snapshot(BlockDriverState *bs,
|
||||||
int64_t offset, int64_t bytes);
|
int64_t offset, int64_t bytes);
|
||||||
|
|
||||||
|
|
||||||
int coroutine_fn bdrv_co_preadv(BdrvChild *child,
|
int coroutine_fn GRAPH_RDLOCK bdrv_co_preadv(BdrvChild *child,
|
||||||
int64_t offset, int64_t bytes, QEMUIOVector *qiov,
|
int64_t offset, int64_t bytes, QEMUIOVector *qiov,
|
||||||
BdrvRequestFlags flags);
|
BdrvRequestFlags flags);
|
||||||
int coroutine_fn bdrv_co_preadv_part(BdrvChild *child,
|
int coroutine_fn GRAPH_RDLOCK bdrv_co_preadv_part(BdrvChild *child,
|
||||||
int64_t offset, int64_t bytes,
|
int64_t offset, int64_t bytes,
|
||||||
QEMUIOVector *qiov, size_t qiov_offset, BdrvRequestFlags flags);
|
QEMUIOVector *qiov, size_t qiov_offset, BdrvRequestFlags flags);
|
||||||
int coroutine_fn bdrv_co_pwritev(BdrvChild *child,
|
int coroutine_fn GRAPH_RDLOCK bdrv_co_pwritev(BdrvChild *child,
|
||||||
int64_t offset, int64_t bytes, QEMUIOVector *qiov,
|
int64_t offset, int64_t bytes, QEMUIOVector *qiov,
|
||||||
BdrvRequestFlags flags);
|
BdrvRequestFlags flags);
|
||||||
int coroutine_fn bdrv_co_pwritev_part(BdrvChild *child,
|
int coroutine_fn GRAPH_RDLOCK bdrv_co_pwritev_part(BdrvChild *child,
|
||||||
int64_t offset, int64_t bytes,
|
int64_t offset, int64_t bytes,
|
||||||
QEMUIOVector *qiov, size_t qiov_offset, BdrvRequestFlags flags);
|
QEMUIOVector *qiov, size_t qiov_offset, BdrvRequestFlags flags);
|
||||||
|
|
||||||
static inline int coroutine_fn bdrv_co_pread(BdrvChild *child,
|
static inline int coroutine_fn GRAPH_RDLOCK bdrv_co_pread(BdrvChild *child,
|
||||||
int64_t offset, int64_t bytes, void *buf, BdrvRequestFlags flags)
|
int64_t offset, int64_t bytes, void *buf, BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
|
QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
|
|
||||||
return bdrv_co_preadv(child, offset, bytes, &qiov, flags);
|
return bdrv_co_preadv(child, offset, bytes, &qiov, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int coroutine_fn bdrv_co_pwrite(BdrvChild *child,
|
static inline int coroutine_fn GRAPH_RDLOCK bdrv_co_pwrite(BdrvChild *child,
|
||||||
int64_t offset, int64_t bytes, const void *buf, BdrvRequestFlags flags)
|
int64_t offset, int64_t bytes, const void *buf, BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
|
QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
|
||||||
IO_CODE();
|
IO_CODE();
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
|
|
||||||
return bdrv_co_pwritev(child, offset, bytes, &qiov, flags);
|
return bdrv_co_pwritev(child, offset, bytes, &qiov, flags);
|
||||||
}
|
}
|
||||||
|
@ -111,20 +113,21 @@ void bdrv_dirty_bitmap_merge_internal(BdrvDirtyBitmap *dest,
|
||||||
void bdrv_inc_in_flight(BlockDriverState *bs);
|
void bdrv_inc_in_flight(BlockDriverState *bs);
|
||||||
void bdrv_dec_in_flight(BlockDriverState *bs);
|
void bdrv_dec_in_flight(BlockDriverState *bs);
|
||||||
|
|
||||||
int coroutine_fn bdrv_co_copy_range_from(BdrvChild *src, int64_t src_offset,
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
|
bdrv_co_copy_range_from(BdrvChild *src, int64_t src_offset,
|
||||||
BdrvChild *dst, int64_t dst_offset,
|
BdrvChild *dst, int64_t dst_offset,
|
||||||
int64_t bytes,
|
int64_t bytes, BdrvRequestFlags read_flags,
|
||||||
BdrvRequestFlags read_flags,
|
|
||||||
BdrvRequestFlags write_flags);
|
BdrvRequestFlags write_flags);
|
||||||
int coroutine_fn bdrv_co_copy_range_to(BdrvChild *src, int64_t src_offset,
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
|
bdrv_co_copy_range_to(BdrvChild *src, int64_t src_offset,
|
||||||
BdrvChild *dst, int64_t dst_offset,
|
BdrvChild *dst, int64_t dst_offset,
|
||||||
int64_t bytes,
|
int64_t bytes, BdrvRequestFlags read_flags,
|
||||||
BdrvRequestFlags read_flags,
|
|
||||||
BdrvRequestFlags write_flags);
|
BdrvRequestFlags write_flags);
|
||||||
|
|
||||||
int coroutine_fn bdrv_co_refresh_total_sectors(BlockDriverState *bs,
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t hint);
|
bdrv_co_refresh_total_sectors(BlockDriverState *bs, int64_t hint);
|
||||||
int co_wrapper_mixed
|
|
||||||
|
int co_wrapper_mixed_bdrv_rdlock
|
||||||
bdrv_refresh_total_sectors(BlockDriverState *bs, int64_t hint);
|
bdrv_refresh_total_sectors(BlockDriverState *bs, int64_t hint);
|
||||||
|
|
||||||
BdrvChild *bdrv_cow_child(BlockDriverState *bs);
|
BdrvChild *bdrv_cow_child(BlockDriverState *bs);
|
||||||
|
|
|
@ -36,11 +36,11 @@ int bdrv_dirty_bitmap_check(const BdrvDirtyBitmap *bitmap, uint32_t flags,
|
||||||
void bdrv_release_dirty_bitmap(BdrvDirtyBitmap *bitmap);
|
void bdrv_release_dirty_bitmap(BdrvDirtyBitmap *bitmap);
|
||||||
void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs);
|
void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs);
|
||||||
|
|
||||||
int coroutine_fn bdrv_co_remove_persistent_dirty_bitmap(BlockDriverState *bs,
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
const char *name,
|
bdrv_co_remove_persistent_dirty_bitmap(BlockDriverState *bs, const char *name,
|
||||||
Error **errp);
|
Error **errp);
|
||||||
int co_wrapper bdrv_remove_persistent_dirty_bitmap(BlockDriverState *bs,
|
int co_wrapper_bdrv_rdlock
|
||||||
const char *name,
|
bdrv_remove_persistent_dirty_bitmap(BlockDriverState *bs, const char *name,
|
||||||
Error **errp);
|
Error **errp);
|
||||||
|
|
||||||
void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap *bitmap);
|
void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap *bitmap);
|
||||||
|
|
|
@ -74,13 +74,22 @@ struct VirtIOSCSICommon {
|
||||||
VirtQueue **cmd_vqs;
|
VirtQueue **cmd_vqs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct VirtIOSCSIReq;
|
||||||
|
|
||||||
struct VirtIOSCSI {
|
struct VirtIOSCSI {
|
||||||
VirtIOSCSICommon parent_obj;
|
VirtIOSCSICommon parent_obj;
|
||||||
|
|
||||||
SCSIBus bus;
|
SCSIBus bus;
|
||||||
int resetting;
|
int resetting; /* written from main loop thread, read from any thread */
|
||||||
bool events_dropped;
|
bool events_dropped;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TMFs deferred to main loop BH. These fields are protected by
|
||||||
|
* virtio_scsi_acquire().
|
||||||
|
*/
|
||||||
|
QEMUBH *tmf_bh;
|
||||||
|
QTAILQ_HEAD(, VirtIOSCSIReq) tmf_bh_list;
|
||||||
|
|
||||||
/* Fields for dataplane below */
|
/* Fields for dataplane below */
|
||||||
AioContext *ctx; /* one iothread per virtio-scsi-pci for now */
|
AioContext *ctx; /* one iothread per virtio-scsi-pci for now */
|
||||||
|
|
||||||
|
|
|
@ -55,10 +55,11 @@ BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf,
|
||||||
void blk_inc_in_flight(BlockBackend *blk);
|
void blk_inc_in_flight(BlockBackend *blk);
|
||||||
void blk_dec_in_flight(BlockBackend *blk);
|
void blk_dec_in_flight(BlockBackend *blk);
|
||||||
|
|
||||||
bool coroutine_fn blk_co_is_inserted(BlockBackend *blk);
|
bool coroutine_fn GRAPH_RDLOCK blk_co_is_inserted(BlockBackend *blk);
|
||||||
bool co_wrapper_mixed blk_is_inserted(BlockBackend *blk);
|
bool co_wrapper_mixed_bdrv_rdlock blk_is_inserted(BlockBackend *blk);
|
||||||
|
|
||||||
bool blk_is_available(BlockBackend *blk);
|
bool coroutine_fn GRAPH_RDLOCK blk_co_is_available(BlockBackend *blk);
|
||||||
|
bool co_wrapper_mixed_bdrv_rdlock blk_is_available(BlockBackend *blk);
|
||||||
|
|
||||||
void coroutine_fn blk_co_lock_medium(BlockBackend *blk, bool locked);
|
void coroutine_fn blk_co_lock_medium(BlockBackend *blk, bool locked);
|
||||||
void co_wrapper blk_lock_medium(BlockBackend *blk, bool locked);
|
void co_wrapper blk_lock_medium(BlockBackend *blk, bool locked);
|
||||||
|
|
|
@ -3922,10 +3922,12 @@
|
||||||
##
|
##
|
||||||
# @RbdImageEncryptionFormat:
|
# @RbdImageEncryptionFormat:
|
||||||
#
|
#
|
||||||
|
# @luks-any: Used for opening either luks or luks2 (Since 8.0)
|
||||||
|
#
|
||||||
# Since: 6.1
|
# Since: 6.1
|
||||||
##
|
##
|
||||||
{ 'enum': 'RbdImageEncryptionFormat',
|
{ 'enum': 'RbdImageEncryptionFormat',
|
||||||
'data': [ 'luks', 'luks2' ] }
|
'data': [ 'luks', 'luks2', 'luks-any' ] }
|
||||||
|
|
||||||
##
|
##
|
||||||
# @RbdEncryptionOptionsLUKSBase:
|
# @RbdEncryptionOptionsLUKSBase:
|
||||||
|
@ -3967,6 +3969,15 @@
|
||||||
'base': 'RbdEncryptionOptionsLUKSBase',
|
'base': 'RbdEncryptionOptionsLUKSBase',
|
||||||
'data': { } }
|
'data': { } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @RbdEncryptionOptionsLUKSAny:
|
||||||
|
#
|
||||||
|
# Since: 8.0
|
||||||
|
##
|
||||||
|
{ 'struct': 'RbdEncryptionOptionsLUKSAny',
|
||||||
|
'base': 'RbdEncryptionOptionsLUKSBase',
|
||||||
|
'data': { } }
|
||||||
|
|
||||||
##
|
##
|
||||||
# @RbdEncryptionCreateOptionsLUKS:
|
# @RbdEncryptionCreateOptionsLUKS:
|
||||||
#
|
#
|
||||||
|
@ -3988,13 +3999,23 @@
|
||||||
##
|
##
|
||||||
# @RbdEncryptionOptions:
|
# @RbdEncryptionOptions:
|
||||||
#
|
#
|
||||||
|
# @format: Encryption format.
|
||||||
|
#
|
||||||
|
# @parent: Parent image encryption options (for cloned images).
|
||||||
|
# Can be left unspecified if this cloned image is encrypted
|
||||||
|
# using the same format and secret as its parent image (i.e.
|
||||||
|
# not explicitly formatted) or if its parent image is not
|
||||||
|
# encrypted. (Since 8.0)
|
||||||
|
#
|
||||||
# Since: 6.1
|
# Since: 6.1
|
||||||
##
|
##
|
||||||
{ 'union': 'RbdEncryptionOptions',
|
{ 'union': 'RbdEncryptionOptions',
|
||||||
'base': { 'format': 'RbdImageEncryptionFormat' },
|
'base': { 'format': 'RbdImageEncryptionFormat',
|
||||||
|
'*parent': 'RbdEncryptionOptions' },
|
||||||
'discriminator': 'format',
|
'discriminator': 'format',
|
||||||
'data': { 'luks': 'RbdEncryptionOptionsLUKS',
|
'data': { 'luks': 'RbdEncryptionOptionsLUKS',
|
||||||
'luks2': 'RbdEncryptionOptionsLUKS2' } }
|
'luks2': 'RbdEncryptionOptionsLUKS2',
|
||||||
|
'luks-any': 'RbdEncryptionOptionsLUKSAny'} }
|
||||||
|
|
||||||
##
|
##
|
||||||
# @RbdEncryptionCreateOptions:
|
# @RbdEncryptionCreateOptions:
|
||||||
|
|
|
@ -1991,7 +1991,9 @@ static void coroutine_fn convert_co_do_copy(void *opaque)
|
||||||
qemu_co_mutex_unlock(&s->lock);
|
qemu_co_mutex_unlock(&s->lock);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
WITH_GRAPH_RDLOCK_GUARD() {
|
||||||
n = convert_iteration_sectors(s, s->sector_num);
|
n = convert_iteration_sectors(s, s->sector_num);
|
||||||
|
}
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
qemu_co_mutex_unlock(&s->lock);
|
qemu_co_mutex_unlock(&s->lock);
|
||||||
s->ret = n;
|
s->ret = n;
|
||||||
|
@ -2039,7 +2041,9 @@ retry:
|
||||||
|
|
||||||
if (s->ret == -EINPROGRESS) {
|
if (s->ret == -EINPROGRESS) {
|
||||||
if (copy_range) {
|
if (copy_range) {
|
||||||
|
WITH_GRAPH_RDLOCK_GUARD() {
|
||||||
ret = convert_co_copy_range(s, sector_num, n);
|
ret = convert_co_copy_range(s, sector_num, n);
|
||||||
|
}
|
||||||
if (ret) {
|
if (ret) {
|
||||||
s->copy_range = false;
|
s->copy_range = false;
|
||||||
goto retry;
|
goto retry;
|
||||||
|
|
|
@ -113,17 +113,19 @@ static void dma_complete(DMAAIOCB *dbs, int ret)
|
||||||
static void dma_blk_cb(void *opaque, int ret)
|
static void dma_blk_cb(void *opaque, int ret)
|
||||||
{
|
{
|
||||||
DMAAIOCB *dbs = (DMAAIOCB *)opaque;
|
DMAAIOCB *dbs = (DMAAIOCB *)opaque;
|
||||||
|
AioContext *ctx = dbs->ctx;
|
||||||
dma_addr_t cur_addr, cur_len;
|
dma_addr_t cur_addr, cur_len;
|
||||||
void *mem;
|
void *mem;
|
||||||
|
|
||||||
trace_dma_blk_cb(dbs, ret);
|
trace_dma_blk_cb(dbs, ret);
|
||||||
|
|
||||||
|
aio_context_acquire(ctx);
|
||||||
dbs->acb = NULL;
|
dbs->acb = NULL;
|
||||||
dbs->offset += dbs->iov.size;
|
dbs->offset += dbs->iov.size;
|
||||||
|
|
||||||
if (dbs->sg_cur_index == dbs->sg->nsg || ret < 0) {
|
if (dbs->sg_cur_index == dbs->sg->nsg || ret < 0) {
|
||||||
dma_complete(dbs, ret);
|
dma_complete(dbs, ret);
|
||||||
return;
|
goto out;
|
||||||
}
|
}
|
||||||
dma_blk_unmap(dbs);
|
dma_blk_unmap(dbs);
|
||||||
|
|
||||||
|
@ -164,9 +166,9 @@ static void dma_blk_cb(void *opaque, int ret)
|
||||||
|
|
||||||
if (dbs->iov.size == 0) {
|
if (dbs->iov.size == 0) {
|
||||||
trace_dma_map_wait(dbs);
|
trace_dma_map_wait(dbs);
|
||||||
dbs->bh = aio_bh_new(dbs->ctx, reschedule_dma, dbs);
|
dbs->bh = aio_bh_new(ctx, reschedule_dma, dbs);
|
||||||
cpu_register_map_client(dbs->bh);
|
cpu_register_map_client(dbs->bh);
|
||||||
return;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!QEMU_IS_ALIGNED(dbs->iov.size, dbs->align)) {
|
if (!QEMU_IS_ALIGNED(dbs->iov.size, dbs->align)) {
|
||||||
|
@ -174,11 +176,11 @@ static void dma_blk_cb(void *opaque, int ret)
|
||||||
QEMU_ALIGN_DOWN(dbs->iov.size, dbs->align));
|
QEMU_ALIGN_DOWN(dbs->iov.size, dbs->align));
|
||||||
}
|
}
|
||||||
|
|
||||||
aio_context_acquire(dbs->ctx);
|
|
||||||
dbs->acb = dbs->io_func(dbs->offset, &dbs->iov,
|
dbs->acb = dbs->io_func(dbs->offset, &dbs->iov,
|
||||||
dma_blk_cb, dbs, dbs->io_func_opaque);
|
dma_blk_cb, dbs, dbs->io_func_opaque);
|
||||||
aio_context_release(dbs->ctx);
|
|
||||||
assert(dbs->acb);
|
assert(dbs->acb);
|
||||||
|
out:
|
||||||
|
aio_context_release(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dma_aio_cancel(BlockAIOCB *acb)
|
static void dma_aio_cancel(BlockAIOCB *acb)
|
||||||
|
|
|
@ -933,10 +933,9 @@ static void bdrv_test_top_close(BlockDriverState *bs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn bdrv_test_top_co_preadv(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes,
|
bdrv_test_top_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
QEMUIOVector *qiov,
|
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
||||||
BdrvRequestFlags flags)
|
|
||||||
{
|
{
|
||||||
BDRVTestTopState *tts = bs->opaque;
|
BDRVTestTopState *tts = bs->opaque;
|
||||||
return bdrv_co_preadv(tts->wait_child, offset, bytes, qiov, flags);
|
return bdrv_co_preadv(tts->wait_child, offset, bytes, qiov, flags);
|
||||||
|
@ -967,6 +966,8 @@ static void coroutine_fn test_co_delete_by_drain(void *opaque)
|
||||||
void *buffer = g_malloc(65536);
|
void *buffer = g_malloc(65536);
|
||||||
QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buffer, 65536);
|
QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buffer, 65536);
|
||||||
|
|
||||||
|
GRAPH_RDLOCK_GUARD();
|
||||||
|
|
||||||
/* Pretend some internal write operation from parent to child.
|
/* Pretend some internal write operation from parent to child.
|
||||||
* Important: We have to read from the child, not from the parent!
|
* Important: We have to read from the child, not from the parent!
|
||||||
* Draining works by first propagating it all up the tree to the
|
* Draining works by first propagating it all up the tree to the
|
||||||
|
@ -1698,11 +1699,9 @@ static void bdrv_replace_test_close(BlockDriverState *bs)
|
||||||
* Otherwise:
|
* Otherwise:
|
||||||
* Set .has_read to true and return success.
|
* Set .has_read to true and return success.
|
||||||
*/
|
*/
|
||||||
static int coroutine_fn bdrv_replace_test_co_preadv(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset,
|
bdrv_replace_test_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||||
int64_t bytes,
|
QEMUIOVector *qiov, BdrvRequestFlags flags)
|
||||||
QEMUIOVector *qiov,
|
|
||||||
BdrvRequestFlags flags)
|
|
||||||
{
|
{
|
||||||
BDRVReplaceTestState *s = bs->opaque;
|
BDRVReplaceTestState *s = bs->opaque;
|
||||||
|
|
||||||
|
@ -1778,7 +1777,10 @@ static void coroutine_fn bdrv_replace_test_read_entry(void *opaque)
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Queue a read request post-drain */
|
/* Queue a read request post-drain */
|
||||||
|
bdrv_graph_co_rdlock();
|
||||||
ret = bdrv_replace_test_co_preadv(bs, 0, 1, &qiov, 0);
|
ret = bdrv_replace_test_co_preadv(bs, 0, 1, &qiov, 0);
|
||||||
|
bdrv_graph_co_rdunlock();
|
||||||
|
|
||||||
g_assert(ret >= 0);
|
g_assert(ret >= 0);
|
||||||
bdrv_dec_in_flight(bs);
|
bdrv_dec_in_flight(bs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -312,7 +312,8 @@ static void test_sync_op_blk_truncate(BlockBackend *blk)
|
||||||
g_assert_cmpint(ret, ==, -EINVAL);
|
g_assert_cmpint(ret, ==, -EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_sync_op_block_status(BdrvChild *c)
|
/* Disable TSA to make bdrv_test.bdrv_co_block_status writable */
|
||||||
|
static void TSA_NO_TSA test_sync_op_block_status(BdrvChild *c)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
int64_t n;
|
int64_t n;
|
||||||
|
|
Loading…
Reference in New Issue