Merge remote-tracking branch 'remotes/kwolf-gitlab/tags/for-upstream' into staging

Block layer patches

- qemu-storage-daemon: Add --daemonize
- Fix x-blockdev-amend and block node activation code which incorrectly
  executed code in the iothread that must run in the main thread.
- Add macros for coroutine-safe TLS variables (required for correctness
  with LTO)
- Fix crashes with concurrent I/O and bdrv_refresh_limits()
- Split block APIs in global state and I/O
- iotests: Don't refuse to run at all without GNU sed, just skip tests
  that need it

# gpg: Signature made Fri 04 Mar 2022 17:18:31 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

* remotes/kwolf-gitlab/tags/for-upstream: (50 commits)
  block/amend: Keep strong reference to BDS
  block/amend: Always call .bdrv_amend_clean()
  tests/qemu-iotests: Rework the checks and spots using GNU sed
  iotests/graph-changes-while-io: New test
  iotests: Allow using QMP with the QSD
  block: Make bdrv_refresh_limits() non-recursive
  job.h: assertions in the callers of JobDriver function pointers
  job.h: split function pointers in JobDriver
  block-backend-common.h: split function pointers in BlockDevOps
  block_int-common.h: assertions in the callers of BdrvChildClass function pointers
  block_int-common.h: split function pointers in BdrvChildClass
  block_int-common.h: assertions in the callers of BlockDriver function pointers
  block_int-common.h: split function pointers in BlockDriver
  block/coroutines: I/O and "I/O or GS" API
  block/copy-before-write.h: global state API + assertions
  include/block/snapshot: global state API + assertions
  assertions for blockdev.h global state API
  include/sysemu/blockdev.h: global state API
  assertions for blockjob.h global state API
  include/block/blockjob.h: global state API
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell
2022-03-05 10:59:04 +00:00
75 changed files with 4864 additions and 2827 deletions
+304 -17
View File
File diff suppressed because it is too large Load Diff
+28
View File
@@ -53,10 +53,31 @@ static int coroutine_fn blockdev_amend_run(Job *job, Error **errp)
return ret; return ret;
} }
static int blockdev_amend_pre_run(BlockdevAmendJob *s, Error **errp)
{
if (s->bs->drv->bdrv_amend_pre_run) {
return s->bs->drv->bdrv_amend_pre_run(s->bs, errp);
}
return 0;
}
static void blockdev_amend_free(Job *job)
{
BlockdevAmendJob *s = container_of(job, BlockdevAmendJob, common);
if (s->bs->drv->bdrv_amend_clean) {
s->bs->drv->bdrv_amend_clean(s->bs);
}
bdrv_unref(s->bs);
}
static const JobDriver blockdev_amend_job_driver = { static const JobDriver blockdev_amend_job_driver = {
.instance_size = sizeof(BlockdevAmendJob), .instance_size = sizeof(BlockdevAmendJob),
.job_type = JOB_TYPE_AMEND, .job_type = JOB_TYPE_AMEND,
.run = blockdev_amend_run, .run = blockdev_amend_run,
.free = blockdev_amend_free,
}; };
void qmp_x_blockdev_amend(const char *job_id, void qmp_x_blockdev_amend(const char *job_id,
@@ -110,8 +131,15 @@ void qmp_x_blockdev_amend(const char *job_id,
return; return;
} }
bdrv_ref(bs);
s->bs = bs, s->bs = bs,
s->opts = QAPI_CLONE(BlockdevAmendOptions, options), s->opts = QAPI_CLONE(BlockdevAmendOptions, options),
s->force = has_force ? force : false; s->force = has_force ? force : false;
if (blockdev_amend_pre_run(s, errp)) {
job_early_fail(&s->common);
return;
}
job_start(&s->common); job_start(&s->common);
} }
+1
View File
@@ -372,6 +372,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
assert(bs); assert(bs);
assert(target); assert(target);
GLOBAL_STATE_CODE();
/* QMP interface protects us from these cases */ /* QMP interface protects us from these cases */
assert(sync_mode != MIRROR_SYNC_MODE_INCREMENTAL); assert(sync_mode != MIRROR_SYNC_MODE_INCREMENTAL);
+161 -5
View File
File diff suppressed because it is too large Load Diff
+4
View File
@@ -253,6 +253,8 @@ void commit_start(const char *job_id, BlockDriverState *bs,
uint64_t base_perms, iter_shared_perms; uint64_t base_perms, iter_shared_perms;
int ret; int ret;
GLOBAL_STATE_CODE();
assert(top != bs); assert(top != bs);
if (bdrv_skip_filters(top) == bdrv_skip_filters(base)) { if (bdrv_skip_filters(top) == bdrv_skip_filters(base)) {
error_setg(errp, "Invalid files for merge: top and base are the same"); error_setg(errp, "Invalid files for merge: top and base are the same");
@@ -432,6 +434,8 @@ int bdrv_commit(BlockDriverState *bs)
QEMU_AUTO_VFREE uint8_t *buf = NULL; QEMU_AUTO_VFREE uint8_t *buf = NULL;
Error *local_err = NULL; Error *local_err = NULL;
GLOBAL_STATE_CODE();
if (!drv) if (!drv)
return -ENOMEDIUM; return -ENOMEDIUM;
+2
View File
@@ -223,6 +223,7 @@ BlockDriverState *bdrv_cbw_append(BlockDriverState *source,
QDict *opts; QDict *opts;
assert(source->total_sectors == target->total_sectors); assert(source->total_sectors == target->total_sectors);
GLOBAL_STATE_CODE();
opts = qdict_new(); opts = qdict_new();
qdict_put_str(opts, "driver", "copy-before-write"); qdict_put_str(opts, "driver", "copy-before-write");
@@ -245,6 +246,7 @@ BlockDriverState *bdrv_cbw_append(BlockDriverState *source,
void bdrv_cbw_drop(BlockDriverState *bs) void bdrv_cbw_drop(BlockDriverState *bs)
{ {
GLOBAL_STATE_CODE();
bdrv_drop_filter(bs, &error_abort); bdrv_drop_filter(bs, &error_abort);
bdrv_unref(bs); bdrv_unref(bs);
} }
+7
View File
@@ -29,6 +29,13 @@
#include "block/block_int.h" #include "block/block_int.h"
#include "block/block-copy.h" #include "block/block-copy.h"
/*
* Global state (GS) API. These functions run under the BQL.
*
* See include/block/block-global-state.h for more information about
* the GS API.
*/
BlockDriverState *bdrv_cbw_append(BlockDriverState *source, BlockDriverState *bdrv_cbw_append(BlockDriverState *source,
BlockDriverState *target, BlockDriverState *target,
const char *filter_node_name, const char *filter_node_name,
+52 -29
View File
@@ -30,17 +30,17 @@
/* For blk_bs() in generated block/block-gen.c */ /* For blk_bs() in generated block/block-gen.c */
#include "sysemu/block-backend.h" #include "sysemu/block-backend.h"
/*
* I/O API functions. These functions are thread-safe.
*
* See include/block/block-io.h for more information about
* the I/O API.
*/
int coroutine_fn bdrv_co_check(BlockDriverState *bs, int coroutine_fn bdrv_co_check(BlockDriverState *bs,
BdrvCheckResult *res, BdrvCheckMode fix); BdrvCheckResult *res, BdrvCheckMode fix);
int coroutine_fn bdrv_co_invalidate_cache(BlockDriverState *bs, Error **errp); int coroutine_fn bdrv_co_invalidate_cache(BlockDriverState *bs, Error **errp);
int generated_co_wrapper
bdrv_preadv(BdrvChild *child, int64_t offset, unsigned int bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags);
int generated_co_wrapper
bdrv_pwritev(BdrvChild *child, int64_t offset, unsigned int bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags);
int coroutine_fn int coroutine_fn
bdrv_co_common_block_status_above(BlockDriverState *bs, bdrv_co_common_block_status_above(BlockDriverState *bs,
BlockDriverState *base, BlockDriverState *base,
@@ -52,6 +52,51 @@ bdrv_co_common_block_status_above(BlockDriverState *bs,
int64_t *map, int64_t *map,
BlockDriverState **file, BlockDriverState **file,
int *depth); int *depth);
int coroutine_fn bdrv_co_readv_vmstate(BlockDriverState *bs,
QEMUIOVector *qiov, int64_t pos);
int coroutine_fn bdrv_co_writev_vmstate(BlockDriverState *bs,
QEMUIOVector *qiov, int64_t pos);
int coroutine_fn
nbd_co_do_establish_connection(BlockDriverState *bs, Error **errp);
int coroutine_fn
blk_co_do_preadv(BlockBackend *blk, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags);
int coroutine_fn
blk_co_do_pwritev_part(BlockBackend *blk, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, size_t qiov_offset,
BdrvRequestFlags flags);
int coroutine_fn
blk_co_do_ioctl(BlockBackend *blk, unsigned long int req, void *buf);
int coroutine_fn
blk_co_do_pdiscard(BlockBackend *blk, int64_t offset, int64_t bytes);
int coroutine_fn blk_co_do_flush(BlockBackend *blk);
/*
* "I/O or GS" API functions. These functions can run without
* the BQL, but only in one specific iothread/main loop.
*
* See include/block/block-io.h for more information about
* the "I/O or GS" API.
*/
int generated_co_wrapper
bdrv_preadv(BdrvChild *child, int64_t offset, unsigned int bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags);
int generated_co_wrapper
bdrv_pwritev(BdrvChild *child, int64_t offset, unsigned int bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags);
int generated_co_wrapper int generated_co_wrapper
bdrv_common_block_status_above(BlockDriverState *bs, bdrv_common_block_status_above(BlockDriverState *bs,
BlockDriverState *base, BlockDriverState *base,
@@ -63,46 +108,24 @@ bdrv_common_block_status_above(BlockDriverState *bs,
int64_t *map, int64_t *map,
BlockDriverState **file, BlockDriverState **file,
int *depth); int *depth);
int coroutine_fn bdrv_co_readv_vmstate(BlockDriverState *bs,
QEMUIOVector *qiov, int64_t pos);
int coroutine_fn bdrv_co_writev_vmstate(BlockDriverState *bs,
QEMUIOVector *qiov, int64_t pos);
int generated_co_wrapper int generated_co_wrapper
nbd_do_establish_connection(BlockDriverState *bs, Error **errp); nbd_do_establish_connection(BlockDriverState *bs, Error **errp);
int coroutine_fn
nbd_co_do_establish_connection(BlockDriverState *bs, Error **errp);
int generated_co_wrapper int generated_co_wrapper
blk_do_preadv(BlockBackend *blk, int64_t offset, int64_t bytes, blk_do_preadv(BlockBackend *blk, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags); QEMUIOVector *qiov, BdrvRequestFlags flags);
int coroutine_fn
blk_co_do_preadv(BlockBackend *blk, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags);
int generated_co_wrapper int generated_co_wrapper
blk_do_pwritev_part(BlockBackend *blk, int64_t offset, int64_t bytes, blk_do_pwritev_part(BlockBackend *blk, 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
blk_co_do_pwritev_part(BlockBackend *blk, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, size_t qiov_offset,
BdrvRequestFlags flags);
int generated_co_wrapper int generated_co_wrapper
blk_do_ioctl(BlockBackend *blk, unsigned long int req, void *buf); blk_do_ioctl(BlockBackend *blk, unsigned long int req, void *buf);
int coroutine_fn
blk_co_do_ioctl(BlockBackend *blk, unsigned long int req, void *buf);
int generated_co_wrapper int generated_co_wrapper
blk_do_pdiscard(BlockBackend *blk, int64_t offset, int64_t bytes); blk_do_pdiscard(BlockBackend *blk, int64_t offset, int64_t bytes);
int coroutine_fn
blk_co_do_pdiscard(BlockBackend *blk, int64_t offset, int64_t bytes);
int generated_co_wrapper blk_do_flush(BlockBackend *blk); int generated_co_wrapper blk_do_flush(BlockBackend *blk);
int coroutine_fn blk_co_do_flush(BlockBackend *blk);
#endif /* BLOCK_COROUTINES_INT_H */ #endif /* BLOCK_COROUTINES_INT_H */
+2
View File
@@ -42,6 +42,8 @@ static int coroutine_fn blockdev_create_run(Job *job, Error **errp)
BlockdevCreateJob *s = container_of(job, BlockdevCreateJob, common); BlockdevCreateJob *s = container_of(job, BlockdevCreateJob, common);
int ret; int ret;
GLOBAL_STATE_CODE();
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);
job_progress_update(&s->common, 1); job_progress_update(&s->common, 1);
+48 -20
View File
@@ -777,6 +777,37 @@ block_crypto_get_specific_info_luks(BlockDriverState *bs, Error **errp)
return spec_info; return spec_info;
} }
static int
block_crypto_amend_prepare(BlockDriverState *bs, Error **errp)
{
BlockCrypto *crypto = bs->opaque;
int ret;
/* apply for exclusive read/write permissions to the underlying file */
crypto->updating_keys = true;
ret = bdrv_child_refresh_perms(bs, bs->file, errp);
if (ret < 0) {
/* Well, in this case we will not be updating any keys */
crypto->updating_keys = false;
}
return ret;
}
static void
block_crypto_amend_cleanup(BlockDriverState *bs)
{
BlockCrypto *crypto = bs->opaque;
Error *errp = NULL;
/* release exclusive read/write permissions to the underlying file */
crypto->updating_keys = false;
bdrv_child_refresh_perms(bs, bs->file, &errp);
if (errp) {
error_report_err(errp);
}
}
static int static int
block_crypto_amend_options_generic_luks(BlockDriverState *bs, block_crypto_amend_options_generic_luks(BlockDriverState *bs,
QCryptoBlockAmendOptions *amend_options, QCryptoBlockAmendOptions *amend_options,
@@ -784,30 +815,17 @@ block_crypto_amend_options_generic_luks(BlockDriverState *bs,
Error **errp) Error **errp)
{ {
BlockCrypto *crypto = bs->opaque; BlockCrypto *crypto = bs->opaque;
int ret;
assert(crypto); assert(crypto);
assert(crypto->block); assert(crypto->block);
/* apply for exclusive read/write permissions to the underlying file*/ return qcrypto_block_amend_options(crypto->block,
crypto->updating_keys = true; block_crypto_read_func,
ret = bdrv_child_refresh_perms(bs, bs->file, errp); block_crypto_write_func,
if (ret) { bs,
goto cleanup; amend_options,
} force,
errp);
ret = qcrypto_block_amend_options(crypto->block,
block_crypto_read_func,
block_crypto_write_func,
bs,
amend_options,
force,
errp);
cleanup:
/* release exclusive read/write permissions to the underlying file*/
crypto->updating_keys = false;
bdrv_child_refresh_perms(bs, bs->file, errp);
return ret;
} }
static int static int
@@ -833,8 +851,16 @@ block_crypto_amend_options_luks(BlockDriverState *bs,
if (!amend_options) { if (!amend_options) {
goto cleanup; goto cleanup;
} }
ret = block_crypto_amend_prepare(bs, errp);
if (ret) {
goto perm_cleanup;
}
ret = block_crypto_amend_options_generic_luks(bs, amend_options, ret = block_crypto_amend_options_generic_luks(bs, amend_options,
force, errp); force, errp);
perm_cleanup:
block_crypto_amend_cleanup(bs);
cleanup: cleanup:
qapi_free_QCryptoBlockAmendOptions(amend_options); qapi_free_QCryptoBlockAmendOptions(amend_options);
return ret; return ret;
@@ -931,6 +957,8 @@ static BlockDriver bdrv_crypto_luks = {
.bdrv_get_specific_info = block_crypto_get_specific_info_luks, .bdrv_get_specific_info = block_crypto_get_specific_info_luks,
.bdrv_amend_options = block_crypto_amend_options_luks, .bdrv_amend_options = block_crypto_amend_options_luks,
.bdrv_co_amend = block_crypto_co_amend_luks, .bdrv_co_amend = block_crypto_co_amend_luks,
.bdrv_amend_pre_run = block_crypto_amend_prepare,
.bdrv_amend_clean = block_crypto_amend_cleanup,
.is_format = true, .is_format = true,
+5
View File
@@ -496,6 +496,7 @@ static void coroutine_fn bdrv_co_can_store_new_dirty_bitmap_entry(void *opaque)
bool bdrv_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name, bool bdrv_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name,
uint32_t granularity, Error **errp) uint32_t granularity, Error **errp)
{ {
IO_CODE();
if (qemu_in_coroutine()) { if (qemu_in_coroutine()) {
return bdrv_co_can_store_new_dirty_bitmap(bs, name, granularity, errp); return bdrv_co_can_store_new_dirty_bitmap(bs, name, granularity, errp);
} else { } else {
@@ -656,6 +657,7 @@ void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out) void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out)
{ {
IO_CODE();
assert(!bdrv_dirty_bitmap_readonly(bitmap)); assert(!bdrv_dirty_bitmap_readonly(bitmap));
bdrv_dirty_bitmaps_lock(bitmap->bs); bdrv_dirty_bitmaps_lock(bitmap->bs);
if (!out) { if (!out) {
@@ -673,6 +675,7 @@ void bdrv_restore_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *backup)
{ {
HBitmap *tmp = bitmap->bitmap; HBitmap *tmp = bitmap->bitmap;
assert(!bdrv_dirty_bitmap_readonly(bitmap)); assert(!bdrv_dirty_bitmap_readonly(bitmap));
GLOBAL_STATE_CODE();
bitmap->bitmap = backup; bitmap->bitmap = backup;
hbitmap_free(tmp); hbitmap_free(tmp);
} }
@@ -737,6 +740,7 @@ void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap)
void bdrv_set_dirty(BlockDriverState *bs, int64_t offset, int64_t bytes) void bdrv_set_dirty(BlockDriverState *bs, int64_t offset, int64_t bytes)
{ {
BdrvDirtyBitmap *bitmap; BdrvDirtyBitmap *bitmap;
IO_CODE();
if (QLIST_EMPTY(&bs->dirty_bitmaps)) { if (QLIST_EMPTY(&bs->dirty_bitmaps)) {
return; return;
@@ -928,6 +932,7 @@ bool bdrv_dirty_bitmap_merge_internal(BdrvDirtyBitmap *dest,
bool lock) bool lock)
{ {
bool ret; bool ret;
IO_CODE();
assert(!bdrv_dirty_bitmap_readonly(dest)); assert(!bdrv_dirty_bitmap_readonly(dest));
assert(!bdrv_dirty_bitmap_inconsistent(dest)); assert(!bdrv_dirty_bitmap_inconsistent(dest));
+1 -1
View File
@@ -139,7 +139,7 @@ BlockExport *blk_exp_add(BlockExportOptions *export, Error **errp)
* access since the export could be available before migration handover. * access since the export could be available before migration handover.
* ctx was acquired in the caller. * ctx was acquired in the caller.
*/ */
bdrv_invalidate_cache(bs, NULL); bdrv_activate(bs, NULL);
perm = BLK_PERM_CONSISTENT_READ; perm = BLK_PERM_CONSISTENT_READ;
if (export->writable) { if (export->writable) {
+18 -7
View File
@@ -86,8 +86,8 @@ static int fuse_export_create(BlockExport *blk_exp,
assert(blk_exp_args->type == BLOCK_EXPORT_TYPE_FUSE); assert(blk_exp_args->type == BLOCK_EXPORT_TYPE_FUSE);
/* For growable exports, take the RESIZE permission */ /* For growable and writable exports, take the RESIZE permission */
if (args->growable) { if (args->growable || blk_exp_args->writable) {
uint64_t blk_perm, blk_shared_perm; uint64_t blk_perm, blk_shared_perm;
blk_get_perm(exp->common.blk, &blk_perm, &blk_shared_perm); blk_get_perm(exp->common.blk, &blk_perm, &blk_shared_perm);
@@ -392,14 +392,23 @@ static int fuse_do_truncate(const FuseExport *exp, int64_t size,
{ {
uint64_t blk_perm, blk_shared_perm; uint64_t blk_perm, blk_shared_perm;
BdrvRequestFlags truncate_flags = 0; BdrvRequestFlags truncate_flags = 0;
int ret; bool add_resize_perm;
int ret, ret_check;
/* Growable and writable exports have a permanent RESIZE permission */
add_resize_perm = !exp->growable && !exp->writable;
if (req_zero_write) { if (req_zero_write) {
truncate_flags |= BDRV_REQ_ZERO_WRITE; truncate_flags |= BDRV_REQ_ZERO_WRITE;
} }
/* Growable exports have a permanent RESIZE permission */ if (add_resize_perm) {
if (!exp->growable) {
if (!qemu_in_main_thread()) {
/* Changing permissions like below only works in the main thread */
return -EPERM;
}
blk_get_perm(exp->common.blk, &blk_perm, &blk_shared_perm); blk_get_perm(exp->common.blk, &blk_perm, &blk_shared_perm);
ret = blk_set_perm(exp->common.blk, blk_perm | BLK_PERM_RESIZE, ret = blk_set_perm(exp->common.blk, blk_perm | BLK_PERM_RESIZE,
@@ -412,9 +421,11 @@ static int fuse_do_truncate(const FuseExport *exp, int64_t size,
ret = blk_truncate(exp->common.blk, size, true, prealloc, ret = blk_truncate(exp->common.blk, size, true, prealloc,
truncate_flags, NULL); truncate_flags, NULL);
if (!exp->growable) { if (add_resize_perm) {
/* Must succeed, because we are only giving up the RESIZE permission */ /* Must succeed, because we are only giving up the RESIZE permission */
blk_set_perm(exp->common.blk, blk_perm, blk_shared_perm, &error_abort); ret_check = blk_set_perm(exp->common.blk, blk_perm,
blk_shared_perm, &error_abort);
assert(ret_check == 0);
} }
return ret; return ret;
+69 -6
View File
@@ -70,6 +70,7 @@ static void bdrv_parent_drained_end_single_no_poll(BdrvChild *c,
void bdrv_parent_drained_end_single(BdrvChild *c) void bdrv_parent_drained_end_single(BdrvChild *c)
{ {
int drained_end_counter = 0; int drained_end_counter = 0;
IO_OR_GS_CODE();
bdrv_parent_drained_end_single_no_poll(c, &drained_end_counter); bdrv_parent_drained_end_single_no_poll(c, &drained_end_counter);
BDRV_POLL_WHILE(c->bs, qatomic_read(&drained_end_counter) > 0); BDRV_POLL_WHILE(c->bs, qatomic_read(&drained_end_counter) > 0);
} }
@@ -114,6 +115,7 @@ static bool bdrv_parent_drained_poll(BlockDriverState *bs, BdrvChild *ignore,
void bdrv_parent_drained_begin_single(BdrvChild *c, bool poll) void bdrv_parent_drained_begin_single(BdrvChild *c, bool poll)
{ {
IO_OR_GS_CODE();
c->parent_quiesce_counter++; c->parent_quiesce_counter++;
if (c->klass->drained_begin) { if (c->klass->drained_begin) {
c->klass->drained_begin(c); c->klass->drained_begin(c);
@@ -164,6 +166,8 @@ void bdrv_refresh_limits(BlockDriverState *bs, Transaction *tran, Error **errp)
BdrvChild *c; BdrvChild *c;
bool have_limits; bool have_limits;
GLOBAL_STATE_CODE();
if (tran) { if (tran) {
BdrvRefreshLimitsState *s = g_new(BdrvRefreshLimitsState, 1); BdrvRefreshLimitsState *s = g_new(BdrvRefreshLimitsState, 1);
*s = (BdrvRefreshLimitsState) { *s = (BdrvRefreshLimitsState) {
@@ -189,10 +193,6 @@ void bdrv_refresh_limits(BlockDriverState *bs, Transaction *tran, Error **errp)
QLIST_FOREACH(c, &bs->children, next) { QLIST_FOREACH(c, &bs->children, next) {
if (c->role & (BDRV_CHILD_DATA | BDRV_CHILD_FILTERED | BDRV_CHILD_COW)) if (c->role & (BDRV_CHILD_DATA | BDRV_CHILD_FILTERED | BDRV_CHILD_COW))
{ {
bdrv_refresh_limits(c->bs, tran, errp);
if (*errp) {
return;
}
bdrv_merge_limits(&bs->bl, &c->bs->bl); bdrv_merge_limits(&bs->bl, &c->bs->bl);
have_limits = true; have_limits = true;
} }
@@ -226,12 +226,14 @@ void bdrv_refresh_limits(BlockDriverState *bs, Transaction *tran, Error **errp)
*/ */
void bdrv_enable_copy_on_read(BlockDriverState *bs) void bdrv_enable_copy_on_read(BlockDriverState *bs)
{ {
IO_CODE();
qatomic_inc(&bs->copy_on_read); qatomic_inc(&bs->copy_on_read);
} }
void bdrv_disable_copy_on_read(BlockDriverState *bs) void bdrv_disable_copy_on_read(BlockDriverState *bs)
{ {
int old = qatomic_fetch_dec(&bs->copy_on_read); int old = qatomic_fetch_dec(&bs->copy_on_read);
IO_CODE();
assert(old >= 1); assert(old >= 1);
} }
@@ -303,6 +305,7 @@ bool bdrv_drain_poll(BlockDriverState *bs, bool recursive,
BdrvChild *ignore_parent, bool ignore_bds_parents) BdrvChild *ignore_parent, bool ignore_bds_parents)
{ {
BdrvChild *child, *next; BdrvChild *child, *next;
IO_OR_GS_CODE();
if (bdrv_parent_drained_poll(bs, ignore_parent, ignore_bds_parents)) { if (bdrv_parent_drained_poll(bs, ignore_parent, ignore_bds_parents)) {
return true; return true;
@@ -426,6 +429,7 @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs,
void bdrv_do_drained_begin_quiesce(BlockDriverState *bs, void bdrv_do_drained_begin_quiesce(BlockDriverState *bs,
BdrvChild *parent, bool ignore_bds_parents) BdrvChild *parent, bool ignore_bds_parents)
{ {
IO_OR_GS_CODE();
assert(!qemu_in_coroutine()); assert(!qemu_in_coroutine());
/* Stop things in parent-to-child order */ /* Stop things in parent-to-child order */
@@ -477,11 +481,13 @@ static void bdrv_do_drained_begin(BlockDriverState *bs, bool recursive,
void bdrv_drained_begin(BlockDriverState *bs) void bdrv_drained_begin(BlockDriverState *bs)
{ {
IO_OR_GS_CODE();
bdrv_do_drained_begin(bs, false, NULL, false, true); bdrv_do_drained_begin(bs, false, NULL, false, true);
} }
void bdrv_subtree_drained_begin(BlockDriverState *bs) void bdrv_subtree_drained_begin(BlockDriverState *bs)
{ {
IO_OR_GS_CODE();
bdrv_do_drained_begin(bs, true, NULL, false, true); bdrv_do_drained_begin(bs, true, NULL, false, true);
} }
@@ -538,18 +544,21 @@ static void bdrv_do_drained_end(BlockDriverState *bs, bool recursive,
void bdrv_drained_end(BlockDriverState *bs) void bdrv_drained_end(BlockDriverState *bs)
{ {
int drained_end_counter = 0; int drained_end_counter = 0;
IO_OR_GS_CODE();
bdrv_do_drained_end(bs, false, NULL, false, &drained_end_counter); bdrv_do_drained_end(bs, false, NULL, false, &drained_end_counter);
BDRV_POLL_WHILE(bs, qatomic_read(&drained_end_counter) > 0); BDRV_POLL_WHILE(bs, qatomic_read(&drained_end_counter) > 0);
} }
void bdrv_drained_end_no_poll(BlockDriverState *bs, int *drained_end_counter) void bdrv_drained_end_no_poll(BlockDriverState *bs, int *drained_end_counter)
{ {
IO_CODE();
bdrv_do_drained_end(bs, false, NULL, false, drained_end_counter); bdrv_do_drained_end(bs, false, NULL, false, drained_end_counter);
} }
void bdrv_subtree_drained_end(BlockDriverState *bs) void bdrv_subtree_drained_end(BlockDriverState *bs)
{ {
int drained_end_counter = 0; int drained_end_counter = 0;
IO_OR_GS_CODE();
bdrv_do_drained_end(bs, true, NULL, false, &drained_end_counter); bdrv_do_drained_end(bs, true, NULL, false, &drained_end_counter);
BDRV_POLL_WHILE(bs, qatomic_read(&drained_end_counter) > 0); BDRV_POLL_WHILE(bs, qatomic_read(&drained_end_counter) > 0);
} }
@@ -557,6 +566,7 @@ void bdrv_subtree_drained_end(BlockDriverState *bs)
void bdrv_apply_subtree_drain(BdrvChild *child, BlockDriverState *new_parent) void bdrv_apply_subtree_drain(BdrvChild *child, BlockDriverState *new_parent)
{ {
int i; int i;
IO_OR_GS_CODE();
for (i = 0; i < new_parent->recursive_quiesce_counter; i++) { for (i = 0; i < new_parent->recursive_quiesce_counter; i++) {
bdrv_do_drained_begin(child->bs, true, child, false, true); bdrv_do_drained_begin(child->bs, true, child, false, true);
@@ -567,6 +577,7 @@ void bdrv_unapply_subtree_drain(BdrvChild *child, BlockDriverState *old_parent)
{ {
int drained_end_counter = 0; int drained_end_counter = 0;
int i; int i;
IO_OR_GS_CODE();
for (i = 0; i < old_parent->recursive_quiesce_counter; i++) { for (i = 0; i < old_parent->recursive_quiesce_counter; i++) {
bdrv_do_drained_end(child->bs, true, child, false, bdrv_do_drained_end(child->bs, true, child, false,
@@ -585,6 +596,7 @@ void bdrv_unapply_subtree_drain(BdrvChild *child, BlockDriverState *old_parent)
*/ */
void coroutine_fn bdrv_co_drain(BlockDriverState *bs) void coroutine_fn bdrv_co_drain(BlockDriverState *bs)
{ {
IO_OR_GS_CODE();
assert(qemu_in_coroutine()); assert(qemu_in_coroutine());
bdrv_drained_begin(bs); bdrv_drained_begin(bs);
bdrv_drained_end(bs); bdrv_drained_end(bs);
@@ -592,6 +604,7 @@ void coroutine_fn bdrv_co_drain(BlockDriverState *bs)
void bdrv_drain(BlockDriverState *bs) void bdrv_drain(BlockDriverState *bs)
{ {
IO_OR_GS_CODE();
bdrv_drained_begin(bs); bdrv_drained_begin(bs);
bdrv_drained_end(bs); bdrv_drained_end(bs);
} }
@@ -612,6 +625,7 @@ static bool bdrv_drain_all_poll(void)
{ {
BlockDriverState *bs = NULL; BlockDriverState *bs = NULL;
bool result = false; bool result = false;
GLOBAL_STATE_CODE();
/* bdrv_drain_poll() can't make changes to the graph and we are holding the /* bdrv_drain_poll() can't make changes to the graph and we are holding the
* main AioContext lock, so iterating bdrv_next_all_states() is safe. */ * main AioContext lock, so iterating bdrv_next_all_states() is safe. */
@@ -640,6 +654,7 @@ static bool bdrv_drain_all_poll(void)
void bdrv_drain_all_begin(void) void bdrv_drain_all_begin(void)
{ {
BlockDriverState *bs = NULL; BlockDriverState *bs = NULL;
GLOBAL_STATE_CODE();
if (qemu_in_coroutine()) { if (qemu_in_coroutine()) {
bdrv_co_yield_to_drain(NULL, true, false, NULL, true, true, NULL); bdrv_co_yield_to_drain(NULL, true, false, NULL, true, true, NULL);
@@ -682,6 +697,7 @@ void bdrv_drain_all_begin(void)
void bdrv_drain_all_end_quiesce(BlockDriverState *bs) void bdrv_drain_all_end_quiesce(BlockDriverState *bs)
{ {
int drained_end_counter = 0; int drained_end_counter = 0;
GLOBAL_STATE_CODE();
g_assert(bs->quiesce_counter > 0); g_assert(bs->quiesce_counter > 0);
g_assert(!bs->refcnt); g_assert(!bs->refcnt);
@@ -696,6 +712,7 @@ void bdrv_drain_all_end(void)
{ {
BlockDriverState *bs = NULL; BlockDriverState *bs = NULL;
int drained_end_counter = 0; int drained_end_counter = 0;
GLOBAL_STATE_CODE();
/* /*
* bdrv queue is managed by record/replay, * bdrv queue is managed by record/replay,
@@ -723,6 +740,7 @@ void bdrv_drain_all_end(void)
void bdrv_drain_all(void) void bdrv_drain_all(void)
{ {
GLOBAL_STATE_CODE();
bdrv_drain_all_begin(); bdrv_drain_all_begin();
bdrv_drain_all_end(); bdrv_drain_all_end();
} }
@@ -867,6 +885,7 @@ BdrvTrackedRequest *coroutine_fn bdrv_co_get_self_request(BlockDriverState *bs)
{ {
BdrvTrackedRequest *req; BdrvTrackedRequest *req;
Coroutine *self = qemu_coroutine_self(); Coroutine *self = qemu_coroutine_self();
IO_CODE();
QLIST_FOREACH(req, &bs->tracked_requests, list) { QLIST_FOREACH(req, &bs->tracked_requests, list) {
if (req->co == self) { if (req->co == self) {
@@ -886,7 +905,7 @@ void bdrv_round_to_clusters(BlockDriverState *bs,
int64_t *cluster_bytes) int64_t *cluster_bytes)
{ {
BlockDriverInfo bdi; BlockDriverInfo bdi;
IO_CODE();
if (bdrv_get_info(bs, &bdi) < 0 || bdi.cluster_size == 0) { if (bdrv_get_info(bs, &bdi) < 0 || bdi.cluster_size == 0) {
*cluster_offset = offset; *cluster_offset = offset;
*cluster_bytes = bytes; *cluster_bytes = bytes;
@@ -912,16 +931,19 @@ static int bdrv_get_cluster_size(BlockDriverState *bs)
void bdrv_inc_in_flight(BlockDriverState *bs) void bdrv_inc_in_flight(BlockDriverState *bs)
{ {
IO_CODE();
qatomic_inc(&bs->in_flight); qatomic_inc(&bs->in_flight);
} }
void bdrv_wakeup(BlockDriverState *bs) void bdrv_wakeup(BlockDriverState *bs)
{ {
IO_CODE();
aio_wait_kick(); aio_wait_kick();
} }
void bdrv_dec_in_flight(BlockDriverState *bs) void bdrv_dec_in_flight(BlockDriverState *bs)
{ {
IO_CODE();
qatomic_dec(&bs->in_flight); qatomic_dec(&bs->in_flight);
bdrv_wakeup(bs); bdrv_wakeup(bs);
} }
@@ -946,6 +968,7 @@ bool coroutine_fn bdrv_make_request_serialising(BdrvTrackedRequest *req,
uint64_t align) uint64_t align)
{ {
bool waited; bool waited;
IO_CODE();
qemu_co_mutex_lock(&req->bs->reqs_lock); qemu_co_mutex_lock(&req->bs->reqs_lock);
@@ -1040,6 +1063,7 @@ static int bdrv_check_request32(int64_t offset, int64_t bytes,
int bdrv_pwrite_zeroes(BdrvChild *child, int64_t offset, int bdrv_pwrite_zeroes(BdrvChild *child, int64_t offset,
int64_t bytes, BdrvRequestFlags flags) int64_t bytes, BdrvRequestFlags flags)
{ {
IO_CODE();
return bdrv_pwritev(child, offset, bytes, NULL, return bdrv_pwritev(child, offset, bytes, NULL,
BDRV_REQ_ZERO_WRITE | flags); BDRV_REQ_ZERO_WRITE | flags);
} }
@@ -1058,6 +1082,7 @@ int bdrv_make_zero(BdrvChild *child, BdrvRequestFlags flags)
int ret; int ret;
int64_t target_size, bytes, offset = 0; int64_t target_size, bytes, offset = 0;
BlockDriverState *bs = child->bs; BlockDriverState *bs = child->bs;
IO_CODE();
target_size = bdrv_getlength(bs); target_size = bdrv_getlength(bs);
if (target_size < 0) { if (target_size < 0) {
@@ -1090,6 +1115,7 @@ int bdrv_pread(BdrvChild *child, int64_t offset, void *buf, int64_t bytes)
{ {
int ret; int ret;
QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes); QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
IO_CODE();
if (bytes < 0) { if (bytes < 0) {
return -EINVAL; return -EINVAL;
@@ -1111,6 +1137,7 @@ int bdrv_pwrite(BdrvChild *child, int64_t offset, const void *buf,
{ {
int ret; int ret;
QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes); QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
IO_CODE();
if (bytes < 0) { if (bytes < 0) {
return -EINVAL; return -EINVAL;
@@ -1131,6 +1158,7 @@ int bdrv_pwrite_sync(BdrvChild *child, int64_t offset,
const void *buf, int64_t count) const void *buf, int64_t count)
{ {
int ret; int ret;
IO_CODE();
ret = bdrv_pwrite(child, offset, buf, count); ret = bdrv_pwrite(child, offset, buf, count);
if (ret < 0) { if (ret < 0) {
@@ -1797,6 +1825,7 @@ int coroutine_fn 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)
{ {
IO_CODE();
return bdrv_co_preadv_part(child, offset, bytes, qiov, 0, flags); return bdrv_co_preadv_part(child, offset, bytes, qiov, 0, flags);
} }
@@ -1809,6 +1838,7 @@ int coroutine_fn bdrv_co_preadv_part(BdrvChild *child,
BdrvTrackedRequest req; BdrvTrackedRequest req;
BdrvRequestPadding pad; BdrvRequestPadding pad;
int ret; int ret;
IO_CODE();
trace_bdrv_co_preadv_part(bs, offset, bytes, flags); trace_bdrv_co_preadv_part(bs, offset, bytes, flags);
@@ -2230,6 +2260,7 @@ int coroutine_fn 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)
{ {
IO_CODE();
return bdrv_co_pwritev_part(child, offset, bytes, qiov, 0, flags); return bdrv_co_pwritev_part(child, offset, bytes, qiov, 0, flags);
} }
@@ -2243,6 +2274,7 @@ int coroutine_fn bdrv_co_pwritev_part(BdrvChild *child,
BdrvRequestPadding pad; BdrvRequestPadding pad;
int ret; int ret;
bool padded = false; bool padded = false;
IO_CODE();
trace_bdrv_co_pwritev_part(child->bs, offset, bytes, flags); trace_bdrv_co_pwritev_part(child->bs, offset, bytes, flags);
@@ -2326,6 +2358,7 @@ out:
int coroutine_fn bdrv_co_pwrite_zeroes(BdrvChild *child, int64_t offset, int coroutine_fn bdrv_co_pwrite_zeroes(BdrvChild *child, int64_t offset,
int64_t bytes, BdrvRequestFlags flags) int64_t bytes, BdrvRequestFlags flags)
{ {
IO_CODE();
trace_bdrv_co_pwrite_zeroes(child->bs, offset, bytes, flags); trace_bdrv_co_pwrite_zeroes(child->bs, offset, bytes, flags);
if (!(child->bs->open_flags & BDRV_O_UNMAP)) { if (!(child->bs->open_flags & BDRV_O_UNMAP)) {
@@ -2345,6 +2378,8 @@ int bdrv_flush_all(void)
BlockDriverState *bs = NULL; BlockDriverState *bs = NULL;
int result = 0; int result = 0;
GLOBAL_STATE_CODE();
/* /*
* bdrv queue is managed by record/replay, * bdrv queue is managed by record/replay,
* creating new flush request for stopping * creating new flush request for stopping
@@ -2639,6 +2674,7 @@ bdrv_co_common_block_status_above(BlockDriverState *bs,
BlockDriverState *p; BlockDriverState *p;
int64_t eof = 0; int64_t eof = 0;
int dummy; int dummy;
IO_CODE();
assert(!include_base || base); /* Can't include NULL base */ assert(!include_base || base); /* Can't include NULL base */
@@ -2728,6 +2764,7 @@ 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)
{ {
IO_CODE();
return bdrv_common_block_status_above(bs, base, false, true, offset, bytes, return bdrv_common_block_status_above(bs, base, false, true, offset, bytes,
pnum, map, file, NULL); pnum, map, file, NULL);
} }
@@ -2735,6 +2772,7 @@ int bdrv_block_status_above(BlockDriverState *bs, BlockDriverState *base,
int bdrv_block_status(BlockDriverState *bs, int64_t offset, int64_t bytes, int bdrv_block_status(BlockDriverState *bs, int64_t offset, int64_t bytes,
int64_t *pnum, int64_t *map, BlockDriverState **file) int64_t *pnum, int64_t *map, BlockDriverState **file)
{ {
IO_CODE();
return bdrv_block_status_above(bs, bdrv_filter_or_cow_bs(bs), return bdrv_block_status_above(bs, bdrv_filter_or_cow_bs(bs),
offset, bytes, pnum, map, file); offset, bytes, pnum, map, file);
} }
@@ -2751,6 +2789,7 @@ int coroutine_fn bdrv_co_is_zero_fast(BlockDriverState *bs, int64_t offset,
{ {
int ret; int ret;
int64_t pnum = bytes; int64_t pnum = bytes;
IO_CODE();
if (!bytes) { if (!bytes) {
return 1; return 1;
@@ -2771,6 +2810,7 @@ int coroutine_fn bdrv_is_allocated(BlockDriverState *bs, int64_t offset,
{ {
int ret; int ret;
int64_t dummy; int64_t dummy;
IO_CODE();
ret = bdrv_common_block_status_above(bs, bs, true, false, offset, ret = bdrv_common_block_status_above(bs, bs, true, false, offset,
bytes, pnum ? pnum : &dummy, NULL, bytes, pnum ? pnum : &dummy, NULL,
@@ -2807,6 +2847,7 @@ int bdrv_is_allocated_above(BlockDriverState *top,
int ret = bdrv_common_block_status_above(top, base, include_base, false, int ret = bdrv_common_block_status_above(top, base, include_base, false,
offset, bytes, pnum, NULL, NULL, offset, bytes, pnum, NULL, NULL,
&depth); &depth);
IO_CODE();
if (ret < 0) { if (ret < 0) {
return ret; return ret;
} }
@@ -2823,6 +2864,7 @@ bdrv_co_readv_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos)
BlockDriver *drv = bs->drv; BlockDriver *drv = bs->drv;
BlockDriverState *child_bs = bdrv_primary_bs(bs); BlockDriverState *child_bs = bdrv_primary_bs(bs);
int ret; int ret;
IO_CODE();
ret = bdrv_check_qiov_request(pos, qiov->size, qiov, 0, NULL); ret = bdrv_check_qiov_request(pos, qiov->size, qiov, 0, NULL);
if (ret < 0) { if (ret < 0) {
@@ -2854,6 +2896,7 @@ bdrv_co_writev_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos)
BlockDriver *drv = bs->drv; BlockDriver *drv = bs->drv;
BlockDriverState *child_bs = bdrv_primary_bs(bs); BlockDriverState *child_bs = bdrv_primary_bs(bs);
int ret; int ret;
IO_CODE();
ret = bdrv_check_qiov_request(pos, qiov->size, qiov, 0, NULL); ret = bdrv_check_qiov_request(pos, qiov->size, qiov, 0, NULL);
if (ret < 0) { if (ret < 0) {
@@ -2884,6 +2927,7 @@ int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
{ {
QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, size); QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, size);
int ret = bdrv_writev_vmstate(bs, &qiov, pos); int ret = bdrv_writev_vmstate(bs, &qiov, pos);
IO_CODE();
return ret < 0 ? ret : size; return ret < 0 ? ret : size;
} }
@@ -2893,6 +2937,7 @@ int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
{ {
QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, size); QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, size);
int ret = bdrv_readv_vmstate(bs, &qiov, pos); int ret = bdrv_readv_vmstate(bs, &qiov, pos);
IO_CODE();
return ret < 0 ? ret : size; return ret < 0 ? ret : size;
} }
@@ -2902,6 +2947,7 @@ int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
void bdrv_aio_cancel(BlockAIOCB *acb) void bdrv_aio_cancel(BlockAIOCB *acb)
{ {
IO_CODE();
qemu_aio_ref(acb); qemu_aio_ref(acb);
bdrv_aio_cancel_async(acb); bdrv_aio_cancel_async(acb);
while (acb->refcnt > 1) { while (acb->refcnt > 1) {
@@ -2926,6 +2972,7 @@ void bdrv_aio_cancel(BlockAIOCB *acb)
* In either case the completion callback must be called. */ * In either case the completion callback must be called. */
void bdrv_aio_cancel_async(BlockAIOCB *acb) void bdrv_aio_cancel_async(BlockAIOCB *acb)
{ {
IO_CODE();
if (acb->aiocb_info->cancel_async) { if (acb->aiocb_info->cancel_async) {
acb->aiocb_info->cancel_async(acb); acb->aiocb_info->cancel_async(acb);
} }
@@ -2940,6 +2987,7 @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
BdrvChild *child; BdrvChild *child;
int current_gen; int current_gen;
int ret = 0; int ret = 0;
IO_CODE();
bdrv_inc_in_flight(bs); bdrv_inc_in_flight(bs);
@@ -3065,6 +3113,7 @@ int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset,
int64_t max_pdiscard; int64_t max_pdiscard;
int head, tail, align; int head, tail, align;
BlockDriverState *bs = child->bs; BlockDriverState *bs = child->bs;
IO_CODE();
if (!bs || !bs->drv || !bdrv_is_inserted(bs)) { if (!bs || !bs->drv || !bdrv_is_inserted(bs)) {
return -ENOMEDIUM; return -ENOMEDIUM;
@@ -3183,6 +3232,7 @@ int bdrv_co_ioctl(BlockDriverState *bs, int req, void *buf)
.coroutine = qemu_coroutine_self(), .coroutine = qemu_coroutine_self(),
}; };
BlockAIOCB *acb; BlockAIOCB *acb;
IO_CODE();
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)) {
@@ -3207,17 +3257,20 @@ out:
void *qemu_blockalign(BlockDriverState *bs, size_t size) void *qemu_blockalign(BlockDriverState *bs, size_t size)
{ {
IO_CODE();
return qemu_memalign(bdrv_opt_mem_align(bs), size); return qemu_memalign(bdrv_opt_mem_align(bs), size);
} }
void *qemu_blockalign0(BlockDriverState *bs, size_t size) void *qemu_blockalign0(BlockDriverState *bs, size_t size)
{ {
IO_CODE();
return memset(qemu_blockalign(bs, size), 0, size); return memset(qemu_blockalign(bs, size), 0, size);
} }
void *qemu_try_blockalign(BlockDriverState *bs, size_t size) void *qemu_try_blockalign(BlockDriverState *bs, size_t size)
{ {
size_t align = bdrv_opt_mem_align(bs); size_t align = bdrv_opt_mem_align(bs);
IO_CODE();
/* Ensure that NULL is never returned on success */ /* Ensure that NULL is never returned on success */
assert(align > 0); assert(align > 0);
@@ -3231,6 +3284,7 @@ void *qemu_try_blockalign(BlockDriverState *bs, size_t size)
void *qemu_try_blockalign0(BlockDriverState *bs, size_t size) void *qemu_try_blockalign0(BlockDriverState *bs, size_t size)
{ {
void *mem = qemu_try_blockalign(bs, size); void *mem = qemu_try_blockalign(bs, size);
IO_CODE();
if (mem) { if (mem) {
memset(mem, 0, size); memset(mem, 0, size);
@@ -3246,6 +3300,7 @@ bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov)
{ {
int i; int i;
size_t alignment = bdrv_min_mem_align(bs); size_t alignment = bdrv_min_mem_align(bs);
IO_CODE();
for (i = 0; i < qiov->niov; i++) { for (i = 0; i < qiov->niov; i++) {
if ((uintptr_t) qiov->iov[i].iov_base % alignment) { if ((uintptr_t) qiov->iov[i].iov_base % alignment) {
@@ -3262,6 +3317,7 @@ bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov)
void bdrv_io_plug(BlockDriverState *bs) void bdrv_io_plug(BlockDriverState *bs)
{ {
BdrvChild *child; BdrvChild *child;
IO_CODE();
QLIST_FOREACH(child, &bs->children, next) { QLIST_FOREACH(child, &bs->children, next) {
bdrv_io_plug(child->bs); bdrv_io_plug(child->bs);
@@ -3278,6 +3334,7 @@ void bdrv_io_plug(BlockDriverState *bs)
void bdrv_io_unplug(BlockDriverState *bs) void bdrv_io_unplug(BlockDriverState *bs)
{ {
BdrvChild *child; BdrvChild *child;
IO_CODE();
assert(bs->io_plugged); assert(bs->io_plugged);
if (qatomic_fetch_dec(&bs->io_plugged) == 1) { if (qatomic_fetch_dec(&bs->io_plugged) == 1) {
@@ -3296,6 +3353,7 @@ void bdrv_register_buf(BlockDriverState *bs, void *host, size_t size)
{ {
BdrvChild *child; BdrvChild *child;
GLOBAL_STATE_CODE();
if (bs->drv && bs->drv->bdrv_register_buf) { if (bs->drv && bs->drv->bdrv_register_buf) {
bs->drv->bdrv_register_buf(bs, host, size); bs->drv->bdrv_register_buf(bs, host, size);
} }
@@ -3308,6 +3366,7 @@ void bdrv_unregister_buf(BlockDriverState *bs, void *host)
{ {
BdrvChild *child; BdrvChild *child;
GLOBAL_STATE_CODE();
if (bs->drv && bs->drv->bdrv_unregister_buf) { if (bs->drv && bs->drv->bdrv_unregister_buf) {
bs->drv->bdrv_unregister_buf(bs, host); bs->drv->bdrv_unregister_buf(bs, host);
} }
@@ -3402,6 +3461,7 @@ int coroutine_fn bdrv_co_copy_range_from(BdrvChild *src, int64_t src_offset,
BdrvRequestFlags read_flags, BdrvRequestFlags read_flags,
BdrvRequestFlags write_flags) BdrvRequestFlags write_flags)
{ {
IO_CODE();
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,
@@ -3418,6 +3478,7 @@ int coroutine_fn bdrv_co_copy_range_to(BdrvChild *src, int64_t src_offset,
BdrvRequestFlags read_flags, BdrvRequestFlags read_flags,
BdrvRequestFlags write_flags) BdrvRequestFlags write_flags)
{ {
IO_CODE();
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,
@@ -3429,6 +3490,7 @@ int coroutine_fn bdrv_co_copy_range(BdrvChild *src, int64_t src_offset,
int64_t bytes, BdrvRequestFlags read_flags, int64_t bytes, BdrvRequestFlags read_flags,
BdrvRequestFlags write_flags) BdrvRequestFlags write_flags)
{ {
IO_CODE();
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);
@@ -3461,7 +3523,7 @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
BdrvTrackedRequest req; BdrvTrackedRequest req;
int64_t old_size, new_bytes; int64_t old_size, new_bytes;
int ret; int ret;
IO_CODE();
/* 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) {
@@ -3579,6 +3641,7 @@ out:
void bdrv_cancel_in_flight(BlockDriverState *bs) void bdrv_cancel_in_flight(BlockDriverState *bs)
{ {
GLOBAL_STATE_CODE();
if (!bs || !bs->drv) { if (!bs || !bs->drv) {
return; return;
} }
+5 -2
View File
@@ -131,8 +131,11 @@ block_ss.add(module_block_h)
wrapper_py = find_program('../scripts/block-coroutine-wrapper.py') wrapper_py = find_program('../scripts/block-coroutine-wrapper.py')
block_gen_c = custom_target('block-gen.c', block_gen_c = custom_target('block-gen.c',
output: 'block-gen.c', output: 'block-gen.c',
input: files('../include/block/block.h', input: files(
'coroutines.h'), '../include/block/block-io.h',
'../include/block/block-global-state.h',
'coroutines.h'
),
command: [wrapper_py, '@OUTPUT@', '@INPUT@']) command: [wrapper_py, '@OUTPUT@', '@INPUT@'])
block_ss.add(block_gen_c) block_ss.add(block_gen_c)
+4
View File
@@ -1864,6 +1864,8 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
bool is_none_mode; bool is_none_mode;
BlockDriverState *base; BlockDriverState *base;
GLOBAL_STATE_CODE();
if ((mode == MIRROR_SYNC_MODE_INCREMENTAL) || if ((mode == MIRROR_SYNC_MODE_INCREMENTAL) ||
(mode == MIRROR_SYNC_MODE_BITMAP)) { (mode == MIRROR_SYNC_MODE_BITMAP)) {
error_setg(errp, "Sync mode '%s' not supported", error_setg(errp, "Sync mode '%s' not supported",
@@ -1889,6 +1891,8 @@ BlockJob *commit_active_start(const char *job_id, BlockDriverState *bs,
bool base_read_only; bool base_read_only;
BlockJob *job; BlockJob *job;
GLOBAL_STATE_CODE();
base_read_only = bdrv_is_read_only(base); base_read_only = bdrv_is_read_only(base);
if (base_read_only) { if (base_read_only) {
+6
View File
@@ -56,6 +56,8 @@ BdrvDirtyBitmap *block_dirty_bitmap_lookup(const char *node,
BlockDriverState *bs; BlockDriverState *bs;
BdrvDirtyBitmap *bitmap; BdrvDirtyBitmap *bitmap;
GLOBAL_STATE_CODE();
if (!node) { if (!node) {
error_setg(errp, "Node cannot be NULL"); error_setg(errp, "Node cannot be NULL");
return NULL; return NULL;
@@ -155,6 +157,8 @@ BdrvDirtyBitmap *block_dirty_bitmap_remove(const char *node, const char *name,
BdrvDirtyBitmap *bitmap; BdrvDirtyBitmap *bitmap;
AioContext *aio_context; AioContext *aio_context;
GLOBAL_STATE_CODE();
bitmap = block_dirty_bitmap_lookup(node, name, &bs, errp); bitmap = block_dirty_bitmap_lookup(node, name, &bs, errp);
if (!bitmap || !bs) { if (!bitmap || !bs) {
return NULL; return NULL;
@@ -261,6 +265,8 @@ BdrvDirtyBitmap *block_dirty_bitmap_merge(const char *node, const char *target,
BlockDirtyBitmapMergeSourceList *lst; BlockDirtyBitmapMergeSourceList *lst;
Error *local_err = NULL; Error *local_err = NULL;
GLOBAL_STATE_CODE();
dst = block_dirty_bitmap_lookup(node, target, &bs, errp); dst = block_dirty_bitmap_lookup(node, target, &bs, errp);
if (!dst) { if (!dst) {
return NULL; return NULL;
+1
View File
@@ -313,6 +313,7 @@ int coroutine_fn nbd_co_do_establish_connection(BlockDriverState *bs,
BDRVNBDState *s = (BDRVNBDState *)bs->opaque; BDRVNBDState *s = (BDRVNBDState *)bs->opaque;
int ret; int ret;
bool blocking = nbd_client_connecting_wait(s); bool blocking = nbd_client_connecting_wait(s);
IO_CODE();
assert(!s->ioc); assert(!s->ioc);
+1 -1
View File
@@ -873,7 +873,7 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
s->bat_dirty_bmap = s->bat_dirty_bmap =
bitmap_new(DIV_ROUND_UP(s->header_size, s->bat_dirty_block)); bitmap_new(DIV_ROUND_UP(s->header_size, s->bat_dirty_block));
/* Disable migration until bdrv_invalidate_cache method is added */ /* Disable migration until bdrv_activate method is added */
error_setg(&s->migration_blocker, "The Parallels format used by node '%s' " error_setg(&s->migration_blocker, "The Parallels format used by node '%s' "
"does not support live migration", "does not support live migration",
bdrv_get_device_or_node_name(bs)); bdrv_get_device_or_node_name(bs));
+28
View File
@@ -57,6 +57,8 @@ int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
QEMUSnapshotInfo *sn_tab, *sn; QEMUSnapshotInfo *sn_tab, *sn;
int nb_sns, i, ret; int nb_sns, i, ret;
GLOBAL_STATE_CODE();
ret = -ENOENT; ret = -ENOENT;
nb_sns = bdrv_snapshot_list(bs, &sn_tab); nb_sns = bdrv_snapshot_list(bs, &sn_tab);
if (nb_sns < 0) { if (nb_sns < 0) {
@@ -105,6 +107,7 @@ bool bdrv_snapshot_find_by_id_and_name(BlockDriverState *bs,
bool ret = false; bool ret = false;
assert(id || name); assert(id || name);
GLOBAL_STATE_CODE();
nb_sns = bdrv_snapshot_list(bs, &sn_tab); nb_sns = bdrv_snapshot_list(bs, &sn_tab);
if (nb_sns < 0) { if (nb_sns < 0) {
@@ -200,6 +203,7 @@ static BlockDriverState *bdrv_snapshot_fallback(BlockDriverState *bs)
int bdrv_can_snapshot(BlockDriverState *bs) int bdrv_can_snapshot(BlockDriverState *bs)
{ {
BlockDriver *drv = bs->drv; BlockDriver *drv = bs->drv;
GLOBAL_STATE_CODE();
if (!drv || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) { if (!drv || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
return 0; return 0;
} }
@@ -220,6 +224,9 @@ int bdrv_snapshot_create(BlockDriverState *bs,
{ {
BlockDriver *drv = bs->drv; BlockDriver *drv = bs->drv;
BlockDriverState *fallback_bs = bdrv_snapshot_fallback(bs); BlockDriverState *fallback_bs = bdrv_snapshot_fallback(bs);
GLOBAL_STATE_CODE();
if (!drv) { if (!drv) {
return -ENOMEDIUM; return -ENOMEDIUM;
} }
@@ -240,6 +247,8 @@ int bdrv_snapshot_goto(BlockDriverState *bs,
BdrvChild **fallback_ptr; BdrvChild **fallback_ptr;
int ret, open_ret; int ret, open_ret;
GLOBAL_STATE_CODE();
if (!drv) { if (!drv) {
error_setg(errp, "Block driver is closed"); error_setg(errp, "Block driver is closed");
return -ENOMEDIUM; return -ENOMEDIUM;
@@ -348,6 +357,8 @@ int bdrv_snapshot_delete(BlockDriverState *bs,
BlockDriverState *fallback_bs = bdrv_snapshot_fallback(bs); BlockDriverState *fallback_bs = bdrv_snapshot_fallback(bs);
int ret; int ret;
GLOBAL_STATE_CODE();
if (!drv) { if (!drv) {
error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, bdrv_get_device_name(bs)); error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, bdrv_get_device_name(bs));
return -ENOMEDIUM; return -ENOMEDIUM;
@@ -380,6 +391,8 @@ int bdrv_snapshot_list(BlockDriverState *bs,
{ {
BlockDriver *drv = bs->drv; BlockDriver *drv = bs->drv;
BlockDriverState *fallback_bs = bdrv_snapshot_fallback(bs); BlockDriverState *fallback_bs = bdrv_snapshot_fallback(bs);
GLOBAL_STATE_CODE();
if (!drv) { if (!drv) {
return -ENOMEDIUM; return -ENOMEDIUM;
} }
@@ -419,6 +432,8 @@ int bdrv_snapshot_load_tmp(BlockDriverState *bs,
{ {
BlockDriver *drv = bs->drv; BlockDriver *drv = bs->drv;
GLOBAL_STATE_CODE();
if (!drv) { if (!drv) {
error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, bdrv_get_device_name(bs)); error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, bdrv_get_device_name(bs));
return -ENOMEDIUM; return -ENOMEDIUM;
@@ -447,6 +462,8 @@ int bdrv_snapshot_load_tmp_by_id_or_name(BlockDriverState *bs,
int ret; int ret;
Error *local_err = NULL; Error *local_err = NULL;
GLOBAL_STATE_CODE();
ret = bdrv_snapshot_load_tmp(bs, id_or_name, NULL, &local_err); ret = bdrv_snapshot_load_tmp(bs, id_or_name, NULL, &local_err);
if (ret == -ENOENT || ret == -EINVAL) { if (ret == -ENOENT || ret == -EINVAL) {
error_free(local_err); error_free(local_err);
@@ -515,6 +532,8 @@ bool bdrv_all_can_snapshot(bool has_devices, strList *devices,
g_autoptr(GList) bdrvs = NULL; g_autoptr(GList) bdrvs = NULL;
GList *iterbdrvs; GList *iterbdrvs;
GLOBAL_STATE_CODE();
if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) { if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) {
return false; return false;
} }
@@ -549,6 +568,8 @@ int bdrv_all_delete_snapshot(const char *name,
g_autoptr(GList) bdrvs = NULL; g_autoptr(GList) bdrvs = NULL;
GList *iterbdrvs; GList *iterbdrvs;
GLOBAL_STATE_CODE();
if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) { if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) {
return -1; return -1;
} }
@@ -588,6 +609,8 @@ int bdrv_all_goto_snapshot(const char *name,
g_autoptr(GList) bdrvs = NULL; g_autoptr(GList) bdrvs = NULL;
GList *iterbdrvs; GList *iterbdrvs;
GLOBAL_STATE_CODE();
if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) { if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) {
return -1; return -1;
} }
@@ -622,6 +645,8 @@ int bdrv_all_has_snapshot(const char *name,
g_autoptr(GList) bdrvs = NULL; g_autoptr(GList) bdrvs = NULL;
GList *iterbdrvs; GList *iterbdrvs;
GLOBAL_STATE_CODE();
if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) { if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) {
return -1; return -1;
} }
@@ -663,6 +688,7 @@ int bdrv_all_create_snapshot(QEMUSnapshotInfo *sn,
{ {
g_autoptr(GList) bdrvs = NULL; g_autoptr(GList) bdrvs = NULL;
GList *iterbdrvs; GList *iterbdrvs;
GLOBAL_STATE_CODE();
if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) { if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) {
return -1; return -1;
@@ -703,6 +729,8 @@ BlockDriverState *bdrv_all_find_vmstate_bs(const char *vmstate_bs,
g_autoptr(GList) bdrvs = NULL; g_autoptr(GList) bdrvs = NULL;
GList *iterbdrvs; GList *iterbdrvs;
GLOBAL_STATE_CODE();
if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) { if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) {
return NULL; return NULL;
} }

Some files were not shown because too many files have changed in this diff Show More