Block layer patches
- configure: Enable -Wthread-safety if present - no_co_wrapper to fix bdrv_open*() calls from coroutine context - curl fixes, including enablement of newer libcurl versions - MAINTAINERS: drop Vladimir from parallels block driver - hbitmap: fix hbitmap_status() return value for first dirty bit case - file-posix: Fix assertion failure in write_zeroes after moving bdrv_getlength() to co_wrapper -----BEGIN PGP SIGNATURE----- iQJFBAABCAAvFiEE3D3rFZqa+V09dFb+fwmycsiPL9YFAmPvgm0RHGt3b2xmQHJl ZGhhdC5jb20ACgkQfwmycsiPL9ZxQg//ZWwwh/s/P1PnKAjInNZZNklAWKThNEbZ cF1S94w26IhEQqM0i6MflqcDsPU5t4xZtBUOizx++9M4G8amWnomJSdczUcKULla Az9yweFC1Gu6ENdw+ql5VOzCfpdH5Bn9Jkly5fxuI4vmnBz1PH1Dnd3P4wuLq2sL xna5dijVEhRc5mTKWjbp4nFfvQhucuEBPSNjgnZwEPbhciWxTMmB1GmyRvTxZy8v UY8PcoTlxdKeVQ6DTmkOirphpGj7HeNCEQnZppWs7vHys2oGi9kmR5qTKUNZxGrY 8yWiCiVDqbb50fhEC1srhph79bCij87QC1N33Bm+NuGjnjG4bKVx2B9DC8+6S/JS e3x6u+r0dd6/t0rjKnt1+inYqmM+i5lBJ7+R0yhWUQ+DYkvttNf5yiotD8qvccWJ Kcx14lfjPLK7siAMEY5K0bNMimhN4RR9oCLoPTOHei+vlxdfiMm2XPN61NNht5gD lYZ8JMBsEF/o2ebqTgsJrIHS+Q/8MqcwSunBc54fcXZoF+eiza3W2ArXLNfAEfGE U4JowNK2PrTIrpEjD+Vs0RsBBSmN5PcYIAz04ioODpDnYMq73/t3x9MKdVoxOT64 AM7w58fSyWu8iwvkeA0d3XeVtSHFqZ49PqqIem4IegtnC/AXMUNrJ/VT99xHjeJY oLhOJz7LUg0= =FtaA -----END PGP SIGNATURE----- Merge tag 'for-upstream' of https://repo.or.cz/qemu/kevin into staging Block layer patches - configure: Enable -Wthread-safety if present - no_co_wrapper to fix bdrv_open*() calls from coroutine context - curl fixes, including enablement of newer libcurl versions - MAINTAINERS: drop Vladimir from parallels block driver - hbitmap: fix hbitmap_status() return value for first dirty bit case - file-posix: Fix assertion failure in write_zeroes after moving bdrv_getlength() to co_wrapper # -----BEGIN PGP SIGNATURE----- # # iQJFBAABCAAvFiEE3D3rFZqa+V09dFb+fwmycsiPL9YFAmPvgm0RHGt3b2xmQHJl # ZGhhdC5jb20ACgkQfwmycsiPL9ZxQg//ZWwwh/s/P1PnKAjInNZZNklAWKThNEbZ # cF1S94w26IhEQqM0i6MflqcDsPU5t4xZtBUOizx++9M4G8amWnomJSdczUcKULla # Az9yweFC1Gu6ENdw+ql5VOzCfpdH5Bn9Jkly5fxuI4vmnBz1PH1Dnd3P4wuLq2sL # xna5dijVEhRc5mTKWjbp4nFfvQhucuEBPSNjgnZwEPbhciWxTMmB1GmyRvTxZy8v # UY8PcoTlxdKeVQ6DTmkOirphpGj7HeNCEQnZppWs7vHys2oGi9kmR5qTKUNZxGrY # 8yWiCiVDqbb50fhEC1srhph79bCij87QC1N33Bm+NuGjnjG4bKVx2B9DC8+6S/JS # e3x6u+r0dd6/t0rjKnt1+inYqmM+i5lBJ7+R0yhWUQ+DYkvttNf5yiotD8qvccWJ # Kcx14lfjPLK7siAMEY5K0bNMimhN4RR9oCLoPTOHei+vlxdfiMm2XPN61NNht5gD # lYZ8JMBsEF/o2ebqTgsJrIHS+Q/8MqcwSunBc54fcXZoF+eiza3W2ArXLNfAEfGE # U4JowNK2PrTIrpEjD+Vs0RsBBSmN5PcYIAz04ioODpDnYMq73/t3x9MKdVoxOT64 # AM7w58fSyWu8iwvkeA0d3XeVtSHFqZ49PqqIem4IegtnC/AXMUNrJ/VT99xHjeJY # oLhOJz7LUg0= # =FtaA # -----END PGP SIGNATURE----- # gpg: Signature made Fri 17 Feb 2023 13:34:37 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: (22 commits) hbitmap: fix hbitmap_status() return value for first dirty bit case block/file-posix: don't use functions calling AIO_WAIT_WHILE in worker threads MAINTAINERS: drop Vladimir from parallels block driver block: temporarily hold the new AioContext of bs_top in bdrv_append() block: Handle curl 7.55.0, 7.85.0 version changes block: Assert non-coroutine context for bdrv_open_inherit() block: Fix bdrv_co_create_opts_simple() to open images with no_co_wrapper vpc: Fix .bdrv_co_create(_opts) to open images with no_co_wrapper vmdk: Fix .bdrv_co_create(_opts) to open images with no_co_wrapper vhdx: Fix .bdrv_co_create(_opts) to open images with no_co_wrapper vdi: Fix .bdrv_co_create(_opts) to open images with no_co_wrapper qed: Fix .bdrv_co_create(_opts) to open images with no_co_wrapper qcow2: Fix open/create to open images with no_co_wrapper qcow: Fix .bdrv_co_create(_opts) to open images with no_co_wrapper parallels: Fix .bdrv_co_create(_opts) to open images with no_co_wrapper luks: Fix .bdrv_co_create(_opts) to open images with no_co_wrapper block: Create no_co_wrappers for open functions block-coroutine-wrapper: Introduce no_co_wrapper curl: Fix error path in curl_open() configure: Enable -Wthread-safety if present ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
2d89cb1fe5
@ -3579,13 +3579,11 @@ F: block/dmg.c
|
||||
parallels
|
||||
M: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
M: Denis V. Lunev <den@openvz.org>
|
||||
M: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
|
||||
L: qemu-block@nongnu.org
|
||||
S: Supported
|
||||
F: block/parallels.c
|
||||
F: block/parallels-ext.c
|
||||
F: docs/interop/parallels.txt
|
||||
T: git https://gitlab.com/vsementsov/qemu.git block
|
||||
|
||||
qed
|
||||
M: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
|
40
block.c
40
block.c
@ -657,8 +657,8 @@ int coroutine_fn bdrv_co_create_opts_simple(BlockDriver *drv,
|
||||
options = qdict_new();
|
||||
qdict_put_str(options, "driver", drv->format_name);
|
||||
|
||||
blk = blk_new_open(filename, NULL, options,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE, errp);
|
||||
blk = blk_co_new_open(filename, NULL, options,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE, errp);
|
||||
if (!blk) {
|
||||
error_prepend(errp, "Protocol driver '%s' does not support image "
|
||||
"creation, and opening the image failed: ",
|
||||
@ -3807,13 +3807,11 @@ out:
|
||||
* function eventually calls bdrv_refresh_total_sectors() which polls
|
||||
* when called from non-coroutine context.
|
||||
*/
|
||||
static BlockDriverState *bdrv_open_inherit(const char *filename,
|
||||
const char *reference,
|
||||
QDict *options, int flags,
|
||||
BlockDriverState *parent,
|
||||
const BdrvChildClass *child_class,
|
||||
BdrvChildRole child_role,
|
||||
Error **errp)
|
||||
static BlockDriverState * no_coroutine_fn
|
||||
bdrv_open_inherit(const char *filename, const char *reference, QDict *options,
|
||||
int flags, BlockDriverState *parent,
|
||||
const BdrvChildClass *child_class, BdrvChildRole child_role,
|
||||
Error **errp)
|
||||
{
|
||||
int ret;
|
||||
BlockBackend *file = NULL;
|
||||
@ -3829,6 +3827,7 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
|
||||
assert(!child_class || !flags);
|
||||
assert(!child_class == !parent);
|
||||
GLOBAL_STATE_CODE();
|
||||
assert(!qemu_in_coroutine());
|
||||
|
||||
if (reference) {
|
||||
bool options_non_empty = options ? qdict_size(options) : false;
|
||||
@ -5266,6 +5265,8 @@ int bdrv_drop_filter(BlockDriverState *bs, Error **errp)
|
||||
* child.
|
||||
*
|
||||
* This function does not create any image files.
|
||||
*
|
||||
* The caller must hold the AioContext lock for @bs_top.
|
||||
*/
|
||||
int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top,
|
||||
Error **errp)
|
||||
@ -5273,11 +5274,14 @@ int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top,
|
||||
int ret;
|
||||
BdrvChild *child;
|
||||
Transaction *tran = tran_new();
|
||||
AioContext *old_context, *new_context = NULL;
|
||||
|
||||
GLOBAL_STATE_CODE();
|
||||
|
||||
assert(!bs_new->backing);
|
||||
|
||||
old_context = bdrv_get_aio_context(bs_top);
|
||||
|
||||
child = bdrv_attach_child_noperm(bs_new, bs_top, "backing",
|
||||
&child_of_bds, bdrv_backing_role(bs_new),
|
||||
tran, errp);
|
||||
@ -5286,6 +5290,19 @@ int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top,
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* bdrv_attach_child_noperm could change the AioContext of bs_top.
|
||||
* bdrv_replace_node_noperm calls bdrv_drained_begin, so let's temporarily
|
||||
* hold the new AioContext, since bdrv_drained_begin calls BDRV_POLL_WHILE
|
||||
* that assumes the new lock is taken.
|
||||
*/
|
||||
new_context = bdrv_get_aio_context(bs_top);
|
||||
|
||||
if (old_context != new_context) {
|
||||
aio_context_release(old_context);
|
||||
aio_context_acquire(new_context);
|
||||
}
|
||||
|
||||
ret = bdrv_replace_node_noperm(bs_top, bs_new, true, tran, errp);
|
||||
if (ret < 0) {
|
||||
goto out;
|
||||
@ -5297,6 +5314,11 @@ out:
|
||||
|
||||
bdrv_refresh_limits(bs_top, NULL, NULL);
|
||||
|
||||
if (new_context && old_context != new_context) {
|
||||
aio_context_release(new_context);
|
||||
aio_context_acquire(old_context);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -314,19 +314,18 @@ static int block_crypto_open_generic(QCryptoBlockFormat format,
|
||||
}
|
||||
|
||||
|
||||
static int block_crypto_co_create_generic(BlockDriverState *bs,
|
||||
int64_t size,
|
||||
QCryptoBlockCreateOptions *opts,
|
||||
PreallocMode prealloc,
|
||||
Error **errp)
|
||||
static int coroutine_fn
|
||||
block_crypto_co_create_generic(BlockDriverState *bs, int64_t size,
|
||||
QCryptoBlockCreateOptions *opts,
|
||||
PreallocMode prealloc, Error **errp)
|
||||
{
|
||||
int ret;
|
||||
BlockBackend *blk;
|
||||
QCryptoBlock *crypto = NULL;
|
||||
struct BlockCryptoCreateData data;
|
||||
|
||||
blk = blk_new_with_bs(bs, BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL,
|
||||
errp);
|
||||
blk = blk_co_new_with_bs(bs, BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL,
|
||||
errp);
|
||||
if (!blk) {
|
||||
ret = -EPERM;
|
||||
goto cleanup;
|
||||
@ -639,7 +638,7 @@ block_crypto_co_create_luks(BlockdevCreateOptions *create_options, Error **errp)
|
||||
assert(create_options->driver == BLOCKDEV_DRIVER_LUKS);
|
||||
luks_opts = &create_options->u.luks;
|
||||
|
||||
bs = bdrv_open_blockdev_ref(luks_opts->file, errp);
|
||||
bs = bdrv_co_open_blockdev_ref(luks_opts->file, errp);
|
||||
if (bs == NULL) {
|
||||
return -EIO;
|
||||
}
|
||||
@ -708,8 +707,8 @@ static int coroutine_fn block_crypto_co_create_opts_luks(BlockDriver *drv,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
bs = bdrv_open(filename, NULL, NULL,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
|
||||
bs = bdrv_co_open(filename, NULL, NULL,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
|
||||
if (!bs) {
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
|
50
block/curl.c
50
block/curl.c
@ -38,8 +38,15 @@
|
||||
|
||||
// #define DEBUG_VERBOSE
|
||||
|
||||
/* CURL 7.85.0 switches to a string based API for specifying
|
||||
* the desired protocols.
|
||||
*/
|
||||
#if LIBCURL_VERSION_NUM >= 0x075500
|
||||
#define PROTOCOLS "HTTP,HTTPS,FTP,FTPS"
|
||||
#else
|
||||
#define PROTOCOLS (CURLPROTO_HTTP | CURLPROTO_HTTPS | \
|
||||
CURLPROTO_FTP | CURLPROTO_FTPS)
|
||||
#endif
|
||||
|
||||
#define CURL_NUM_STATES 8
|
||||
#define CURL_NUM_ACB 8
|
||||
@ -510,9 +517,18 @@ static int curl_init_state(BDRVCURLState *s, CURLState *state)
|
||||
* obscure protocols. For example, do not allow POP3/SMTP/IMAP see
|
||||
* CVE-2013-0249.
|
||||
*
|
||||
* Restricting protocols is only supported from 7.19.4 upwards.
|
||||
* Restricting protocols is only supported from 7.19.4 upwards. Note:
|
||||
* version 7.85.0 deprecates CURLOPT_*PROTOCOLS in favour of a string
|
||||
* based CURLOPT_*PROTOCOLS_STR API.
|
||||
*/
|
||||
#if LIBCURL_VERSION_NUM >= 0x071304
|
||||
#if LIBCURL_VERSION_NUM >= 0x075500
|
||||
if (curl_easy_setopt(state->curl,
|
||||
CURLOPT_PROTOCOLS_STR, PROTOCOLS) ||
|
||||
curl_easy_setopt(state->curl,
|
||||
CURLOPT_REDIR_PROTOCOLS_STR, PROTOCOLS)) {
|
||||
goto err;
|
||||
}
|
||||
#elif LIBCURL_VERSION_NUM >= 0x071304
|
||||
if (curl_easy_setopt(state->curl, CURLOPT_PROTOCOLS, PROTOCOLS) ||
|
||||
curl_easy_setopt(state->curl, CURLOPT_REDIR_PROTOCOLS, PROTOCOLS)) {
|
||||
goto err;
|
||||
@ -670,7 +686,12 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
const char *file;
|
||||
const char *cookie;
|
||||
const char *cookie_secret;
|
||||
double d;
|
||||
/* CURL >= 7.55.0 uses curl_off_t for content length instead of a double */
|
||||
#if LIBCURL_VERSION_NUM >= 0x073700
|
||||
curl_off_t cl;
|
||||
#else
|
||||
double cl;
|
||||
#endif
|
||||
const char *secretid;
|
||||
const char *protocol_delimiter;
|
||||
int ret;
|
||||
@ -797,27 +818,36 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
}
|
||||
if (curl_easy_perform(state->curl))
|
||||
goto out;
|
||||
if (curl_easy_getinfo(state->curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &d)) {
|
||||
/* CURL 7.55.0 deprecates CURLINFO_CONTENT_LENGTH_DOWNLOAD in favour of
|
||||
* the *_T version which returns a more sensible type for content length.
|
||||
*/
|
||||
#if LIBCURL_VERSION_NUM >= 0x073700
|
||||
if (curl_easy_getinfo(state->curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &cl)) {
|
||||
goto out;
|
||||
}
|
||||
#else
|
||||
if (curl_easy_getinfo(state->curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &cl)) {
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
/* Prior CURL 7.19.4 return value of 0 could mean that the file size is not
|
||||
* know or the size is zero. From 7.19.4 CURL returns -1 if size is not
|
||||
* known and zero if it is really zero-length file. */
|
||||
#if LIBCURL_VERSION_NUM >= 0x071304
|
||||
if (d < 0) {
|
||||
if (cl < 0) {
|
||||
pstrcpy(state->errmsg, CURL_ERROR_SIZE,
|
||||
"Server didn't report file size.");
|
||||
goto out;
|
||||
}
|
||||
#else
|
||||
if (d <= 0) {
|
||||
if (cl <= 0) {
|
||||
pstrcpy(state->errmsg, CURL_ERROR_SIZE,
|
||||
"Unknown file size or zero-length file.");
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
|
||||
s->len = d;
|
||||
s->len = cl;
|
||||
|
||||
if ((!strncasecmp(s->url, "http://", strlen("http://"))
|
||||
|| !strncasecmp(s->url, "https://", strlen("https://")))
|
||||
@ -850,8 +880,10 @@ out_noclean:
|
||||
g_free(s->username);
|
||||
g_free(s->proxyusername);
|
||||
g_free(s->proxypassword);
|
||||
curl_drop_all_sockets(s->sockets);
|
||||
g_hash_table_destroy(s->sockets);
|
||||
if (s->sockets) {
|
||||
curl_drop_all_sockets(s->sockets);
|
||||
g_hash_table_destroy(s->sockets);
|
||||
}
|
||||
qemu_opts_del(opts);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -1738,7 +1738,7 @@ static int handle_aiocb_write_zeroes(void *opaque)
|
||||
#ifdef CONFIG_FALLOCATE
|
||||
/* Last resort: we are trying to extend the file with zeroed data. This
|
||||
* can be done via fallocate(fd, 0) */
|
||||
len = bdrv_getlength(aiocb->bs);
|
||||
len = raw_co_getlength(aiocb->bs);
|
||||
if (s->has_fallocate && len >= 0 && aiocb->aio_offset >= len) {
|
||||
int ret = do_fallocate(s->fd, 0, aiocb->aio_offset, aiocb->aio_nbytes);
|
||||
if (ret == 0 || ret != -ENOTSUP) {
|
||||
|
@ -141,6 +141,7 @@ block_gen_c = custom_target('block-gen.c',
|
||||
'../include/block/dirty-bitmap.h',
|
||||
'../include/block/block_int-io.h',
|
||||
'../include/block/block-global-state.h',
|
||||
'../include/sysemu/block-backend-global-state.h',
|
||||
'../include/sysemu/block-backend-io.h',
|
||||
'coroutines.h'
|
||||
),
|
||||
|
@ -565,13 +565,13 @@ static int coroutine_fn parallels_co_create(BlockdevCreateOptions* opts,
|
||||
}
|
||||
|
||||
/* Create BlockBackend to write to the image */
|
||||
bs = bdrv_open_blockdev_ref(parallels_opts->file, errp);
|
||||
bs = bdrv_co_open_blockdev_ref(parallels_opts->file, errp);
|
||||
if (bs == NULL) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
blk = blk_new_with_bs(bs, BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL,
|
||||
errp);
|
||||
blk = blk_co_new_with_bs(bs, BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL,
|
||||
errp);
|
||||
if (!blk) {
|
||||
ret = -EPERM;
|
||||
goto out;
|
||||
@ -651,8 +651,8 @@ static int coroutine_fn parallels_co_create_opts(BlockDriver *drv,
|
||||
goto done;
|
||||
}
|
||||
|
||||
bs = bdrv_open(filename, NULL, NULL,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
|
||||
bs = bdrv_co_open(filename, NULL, NULL,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
|
||||
if (bs == NULL) {
|
||||
ret = -EIO;
|
||||
goto done;
|
||||
|
10
block/qcow.c
10
block/qcow.c
@ -833,13 +833,13 @@ static int coroutine_fn qcow_co_create(BlockdevCreateOptions *opts,
|
||||
}
|
||||
|
||||
/* Create BlockBackend to write to the image */
|
||||
bs = bdrv_open_blockdev_ref(qcow_opts->file, errp);
|
||||
bs = bdrv_co_open_blockdev_ref(qcow_opts->file, errp);
|
||||
if (bs == NULL) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
qcow_blk = blk_new_with_bs(bs, BLK_PERM_WRITE | BLK_PERM_RESIZE,
|
||||
BLK_PERM_ALL, errp);
|
||||
qcow_blk = blk_co_new_with_bs(bs, BLK_PERM_WRITE | BLK_PERM_RESIZE,
|
||||
BLK_PERM_ALL, errp);
|
||||
if (!qcow_blk) {
|
||||
ret = -EPERM;
|
||||
goto exit;
|
||||
@ -978,8 +978,8 @@ static int coroutine_fn qcow_co_create_opts(BlockDriver *drv,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
bs = bdrv_open(filename, NULL, NULL,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
|
||||
bs = bdrv_co_open(filename, NULL, NULL,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
|
||||
if (bs == NULL) {
|
||||
ret = -EIO;
|
||||
goto fail;
|
||||
|
@ -1617,9 +1617,9 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
|
||||
|
||||
if (open_data_file) {
|
||||
/* Open external data file */
|
||||
s->data_file = bdrv_open_child(NULL, options, "data-file", bs,
|
||||
&child_of_bds, BDRV_CHILD_DATA,
|
||||
true, errp);
|
||||
s->data_file = bdrv_co_open_child(NULL, options, "data-file", bs,
|
||||
&child_of_bds, BDRV_CHILD_DATA,
|
||||
true, errp);
|
||||
if (*errp) {
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
@ -1627,9 +1627,10 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
|
||||
|
||||
if (s->incompatible_features & QCOW2_INCOMPAT_DATA_FILE) {
|
||||
if (!s->data_file && s->image_data_file) {
|
||||
s->data_file = bdrv_open_child(s->image_data_file, options,
|
||||
"data-file", bs, &child_of_bds,
|
||||
BDRV_CHILD_DATA, false, errp);
|
||||
s->data_file = bdrv_co_open_child(s->image_data_file, options,
|
||||
"data-file", bs,
|
||||
&child_of_bds,
|
||||
BDRV_CHILD_DATA, false, errp);
|
||||
if (!s->data_file) {
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
@ -3454,7 +3455,7 @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
|
||||
assert(create_options->driver == BLOCKDEV_DRIVER_QCOW2);
|
||||
qcow2_opts = &create_options->u.qcow2;
|
||||
|
||||
bs = bdrv_open_blockdev_ref(qcow2_opts->file, errp);
|
||||
bs = bdrv_co_open_blockdev_ref(qcow2_opts->file, errp);
|
||||
if (bs == NULL) {
|
||||
return -EIO;
|
||||
}
|
||||
@ -3596,7 +3597,7 @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
data_bs = bdrv_open_blockdev_ref(qcow2_opts->data_file, errp);
|
||||
data_bs = bdrv_co_open_blockdev_ref(qcow2_opts->data_file, errp);
|
||||
if (data_bs == NULL) {
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
@ -3629,8 +3630,8 @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
|
||||
}
|
||||
|
||||
/* Create BlockBackend to write to the image */
|
||||
blk = blk_new_with_bs(bs, BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL,
|
||||
errp);
|
||||
blk = blk_co_new_with_bs(bs, BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL,
|
||||
errp);
|
||||
if (!blk) {
|
||||
ret = -EPERM;
|
||||
goto out;
|
||||
@ -3712,9 +3713,9 @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
|
||||
if (data_bs) {
|
||||
qdict_put_str(options, "data-file", data_bs->node_name);
|
||||
}
|
||||
blk = blk_new_open(NULL, NULL, options,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_NO_FLUSH,
|
||||
errp);
|
||||
blk = blk_co_new_open(NULL, NULL, options,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_NO_FLUSH,
|
||||
errp);
|
||||
if (blk == NULL) {
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
@ -3793,9 +3794,9 @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
|
||||
if (data_bs) {
|
||||
qdict_put_str(options, "data-file", data_bs->node_name);
|
||||
}
|
||||
blk = blk_new_open(NULL, NULL, options,
|
||||
BDRV_O_RDWR | BDRV_O_NO_BACKING | BDRV_O_NO_IO,
|
||||
errp);
|
||||
blk = blk_co_new_open(NULL, NULL, options,
|
||||
BDRV_O_RDWR | BDRV_O_NO_BACKING | BDRV_O_NO_IO,
|
||||
errp);
|
||||
if (blk == NULL) {
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
@ -3877,8 +3878,8 @@ static int coroutine_fn qcow2_co_create_opts(BlockDriver *drv,
|
||||
goto finish;
|
||||
}
|
||||
|
||||
bs = bdrv_open(filename, NULL, NULL,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
|
||||
bs = bdrv_co_open(filename, NULL, NULL,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
|
||||
if (bs == NULL) {
|
||||
ret = -EIO;
|
||||
goto finish;
|
||||
@ -3892,9 +3893,9 @@ static int coroutine_fn qcow2_co_create_opts(BlockDriver *drv,
|
||||
goto finish;
|
||||
}
|
||||
|
||||
data_bs = bdrv_open(val, NULL, NULL,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL,
|
||||
errp);
|
||||
data_bs = bdrv_co_open(val, NULL, NULL,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL,
|
||||
errp);
|
||||
if (data_bs == NULL) {
|
||||
ret = -EIO;
|
||||
goto finish;
|
||||
|
10
block/qed.c
10
block/qed.c
@ -676,13 +676,13 @@ static int coroutine_fn bdrv_qed_co_create(BlockdevCreateOptions *opts,
|
||||
}
|
||||
|
||||
/* Create BlockBackend to write to the image */
|
||||
bs = bdrv_open_blockdev_ref(qed_opts->file, errp);
|
||||
bs = bdrv_co_open_blockdev_ref(qed_opts->file, errp);
|
||||
if (bs == NULL) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
blk = blk_new_with_bs(bs, BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL,
|
||||
errp);
|
||||
blk = blk_co_new_with_bs(bs, BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL,
|
||||
errp);
|
||||
if (!blk) {
|
||||
ret = -EPERM;
|
||||
goto out;
|
||||
@ -783,8 +783,8 @@ static int coroutine_fn bdrv_qed_co_create_opts(BlockDriver *drv,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
bs = bdrv_open(filename, NULL, NULL,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
|
||||
bs = bdrv_co_open(filename, NULL, NULL,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
|
||||
if (bs == NULL) {
|
||||
ret = -EIO;
|
||||
goto fail;
|
||||
|
10
block/vdi.c
10
block/vdi.c
@ -800,14 +800,14 @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options,
|
||||
}
|
||||
|
||||
/* Create BlockBackend to write to the image */
|
||||
bs_file = bdrv_open_blockdev_ref(vdi_opts->file, errp);
|
||||
bs_file = bdrv_co_open_blockdev_ref(vdi_opts->file, errp);
|
||||
if (!bs_file) {
|
||||
ret = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
blk = blk_new_with_bs(bs_file, BLK_PERM_WRITE | BLK_PERM_RESIZE,
|
||||
BLK_PERM_ALL, errp);
|
||||
blk = blk_co_new_with_bs(bs_file, BLK_PERM_WRITE | BLK_PERM_RESIZE,
|
||||
BLK_PERM_ALL, errp);
|
||||
if (!blk) {
|
||||
ret = -EPERM;
|
||||
goto exit;
|
||||
@ -940,8 +940,8 @@ static int coroutine_fn vdi_co_create_opts(BlockDriver *drv,
|
||||
goto done;
|
||||
}
|
||||
|
||||
bs_file = bdrv_open(filename, NULL, NULL,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
|
||||
bs_file = bdrv_co_open(filename, NULL, NULL,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
|
||||
if (!bs_file) {
|
||||
ret = -EIO;
|
||||
goto done;
|
||||
|
10
block/vhdx.c
10
block/vhdx.c
@ -1991,13 +1991,13 @@ static int coroutine_fn vhdx_co_create(BlockdevCreateOptions *opts,
|
||||
}
|
||||
|
||||
/* Create BlockBackend to write to the image */
|
||||
bs = bdrv_open_blockdev_ref(vhdx_opts->file, errp);
|
||||
bs = bdrv_co_open_blockdev_ref(vhdx_opts->file, errp);
|
||||
if (bs == NULL) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
blk = blk_new_with_bs(bs, BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL,
|
||||
errp);
|
||||
blk = blk_co_new_with_bs(bs, BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL,
|
||||
errp);
|
||||
if (!blk) {
|
||||
ret = -EPERM;
|
||||
goto delete_and_exit;
|
||||
@ -2090,8 +2090,8 @@ static int coroutine_fn vhdx_co_create_opts(BlockDriver *drv,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
bs = bdrv_open(filename, NULL, NULL,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
|
||||
bs = bdrv_co_open(filename, NULL, NULL,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
|
||||
if (bs == NULL) {
|
||||
ret = -EIO;
|
||||
goto fail;
|
||||
|
22
block/vmdk.c
22
block/vmdk.c
@ -2299,9 +2299,9 @@ static int coroutine_fn vmdk_create_extent(const char *filename,
|
||||
goto exit;
|
||||
}
|
||||
|
||||
blk = blk_new_open(filename, NULL, NULL,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL,
|
||||
errp);
|
||||
blk = blk_co_new_open(filename, NULL, NULL,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL,
|
||||
errp);
|
||||
if (blk == NULL) {
|
||||
ret = -EIO;
|
||||
goto exit;
|
||||
@ -2518,8 +2518,8 @@ static int coroutine_fn vmdk_co_do_create(int64_t size,
|
||||
}
|
||||
assert(full_backing);
|
||||
|
||||
backing = blk_new_open(full_backing, NULL, NULL,
|
||||
BDRV_O_NO_BACKING, errp);
|
||||
backing = blk_co_new_open(full_backing, NULL, NULL,
|
||||
BDRV_O_NO_BACKING, errp);
|
||||
g_free(full_backing);
|
||||
if (backing == NULL) {
|
||||
ret = -EIO;
|
||||
@ -2781,7 +2781,7 @@ static BlockBackend * coroutine_fn vmdk_co_create_cb(int64_t size, int idx,
|
||||
BlockdevCreateOptionsVmdk *opts = opaque;
|
||||
|
||||
if (idx == 0) {
|
||||
bs = bdrv_open_blockdev_ref(opts->file, errp);
|
||||
bs = bdrv_co_open_blockdev_ref(opts->file, errp);
|
||||
} else {
|
||||
int i;
|
||||
BlockdevRefList *list = opts->extents;
|
||||
@ -2796,14 +2796,16 @@ static BlockBackend * coroutine_fn vmdk_co_create_cb(int64_t size, int idx,
|
||||
error_setg(errp, "Extent [%d] not specified", idx - 1);
|
||||
return NULL;
|
||||
}
|
||||
bs = bdrv_open_blockdev_ref(list->value, errp);
|
||||
bs = bdrv_co_open_blockdev_ref(list->value, errp);
|
||||
}
|
||||
if (!bs) {
|
||||
return NULL;
|
||||
}
|
||||
blk = blk_new_with_bs(bs,
|
||||
BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE | BLK_PERM_RESIZE,
|
||||
BLK_PERM_ALL, errp);
|
||||
blk = blk_co_new_with_bs(bs,
|
||||
BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE |
|
||||
BLK_PERM_RESIZE,
|
||||
BLK_PERM_ALL,
|
||||
errp);
|
||||
if (!blk) {
|
||||
return NULL;
|
||||
}
|
||||
|
10
block/vpc.c
10
block/vpc.c
@ -1005,13 +1005,13 @@ static int coroutine_fn vpc_co_create(BlockdevCreateOptions *opts,
|
||||
}
|
||||
|
||||
/* Create BlockBackend to write to the image */
|
||||
bs = bdrv_open_blockdev_ref(vpc_opts->file, errp);
|
||||
bs = bdrv_co_open_blockdev_ref(vpc_opts->file, errp);
|
||||
if (bs == NULL) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
blk = blk_new_with_bs(bs, BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL,
|
||||
errp);
|
||||
blk = blk_co_new_with_bs(bs, BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL,
|
||||
errp);
|
||||
if (!blk) {
|
||||
ret = -EPERM;
|
||||
goto out;
|
||||
@ -1117,8 +1117,8 @@ static int coroutine_fn vpc_co_create_opts(BlockDriver *drv,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
bs = bdrv_open(filename, NULL, NULL,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
|
||||
bs = bdrv_co_open(filename, NULL, NULL,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
|
||||
if (bs == NULL) {
|
||||
ret = -EIO;
|
||||
goto fail;
|
||||
|
@ -36,6 +36,7 @@ extern char **environ;
|
||||
#include "target_os_signal.h"
|
||||
#include "target.h"
|
||||
#include "exec/gdbstub.h"
|
||||
#include "qemu/clang-tsa.h"
|
||||
|
||||
/*
|
||||
* This struct is used to hold certain information about the image. Basically,
|
||||
@ -234,8 +235,8 @@ int target_msync(abi_ulong start, abi_ulong len, int flags);
|
||||
extern unsigned long last_brk;
|
||||
extern abi_ulong mmap_next_start;
|
||||
abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size);
|
||||
void mmap_fork_start(void);
|
||||
void mmap_fork_end(int child);
|
||||
void TSA_NO_TSA mmap_fork_start(void);
|
||||
void TSA_NO_TSA mmap_fork_end(int child);
|
||||
|
||||
/* main.c */
|
||||
extern char qemu_proc_pathname[];
|
||||
|
1
configure
vendored
1
configure
vendored
@ -1184,6 +1184,7 @@ add_to warn_flags -Wendif-labels
|
||||
add_to warn_flags -Wexpansion-to-defined
|
||||
add_to warn_flags -Wimplicit-fallthrough=2
|
||||
add_to warn_flags -Wmissing-format-attribute
|
||||
add_to warn_flags -Wthread-safety
|
||||
|
||||
nowarn_flags=
|
||||
add_to nowarn_flags -Wno-initializer-overrides
|
||||
|
@ -54,6 +54,20 @@
|
||||
#define co_wrapper_bdrv_rdlock no_coroutine_fn
|
||||
#define co_wrapper_mixed_bdrv_rdlock no_coroutine_fn coroutine_mixed_fn
|
||||
|
||||
/*
|
||||
* no_co_wrapper: Function specifier used by block-coroutine-wrapper.py
|
||||
*
|
||||
* Function specifier which does nothing but mark functions to be generated by
|
||||
* scripts/block-coroutine-wrapper.py.
|
||||
*
|
||||
* A no_co_wrapper function declaration creates a coroutine_fn wrapper around
|
||||
* functions that must not be called in coroutine context. It achieves this by
|
||||
* scheduling a BH in the bottom half that runs the respective non-coroutine
|
||||
* function. The coroutine yields after scheduling the BH and is reentered when
|
||||
* the wrapped function returns.
|
||||
*/
|
||||
#define no_co_wrapper
|
||||
|
||||
#include "block/blockjob.h"
|
||||
|
||||
/* block.c */
|
||||
|
@ -77,16 +77,26 @@ BlockDriverState *bdrv_insert_node(BlockDriverState *bs, QDict *node_options,
|
||||
int flags, Error **errp);
|
||||
int bdrv_drop_filter(BlockDriverState *bs, Error **errp);
|
||||
|
||||
BdrvChild *bdrv_open_child(const char *filename,
|
||||
QDict *options, const char *bdref_key,
|
||||
BlockDriverState *parent,
|
||||
const BdrvChildClass *child_class,
|
||||
BdrvChildRole child_role,
|
||||
bool allow_none, Error **errp);
|
||||
BdrvChild * no_coroutine_fn
|
||||
bdrv_open_child(const char *filename, QDict *options, const char *bdref_key,
|
||||
BlockDriverState *parent, const BdrvChildClass *child_class,
|
||||
BdrvChildRole child_role, bool allow_none, Error **errp);
|
||||
|
||||
BdrvChild * coroutine_fn no_co_wrapper
|
||||
bdrv_co_open_child(const char *filename, QDict *options, const char *bdref_key,
|
||||
BlockDriverState *parent, const BdrvChildClass *child_class,
|
||||
BdrvChildRole child_role, bool allow_none, Error **errp);
|
||||
|
||||
int bdrv_open_file_child(const char *filename,
|
||||
QDict *options, const char *bdref_key,
|
||||
BlockDriverState *parent, Error **errp);
|
||||
BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp);
|
||||
|
||||
BlockDriverState * no_coroutine_fn
|
||||
bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp);
|
||||
|
||||
BlockDriverState * coroutine_fn no_co_wrapper
|
||||
bdrv_co_open_blockdev_ref(BlockdevRef *ref, Error **errp);
|
||||
|
||||
int bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd,
|
||||
Error **errp);
|
||||
int bdrv_set_backing_hd_drained(BlockDriverState *bs,
|
||||
@ -94,8 +104,15 @@ int bdrv_set_backing_hd_drained(BlockDriverState *bs,
|
||||
Error **errp);
|
||||
int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
|
||||
const char *bdref_key, Error **errp);
|
||||
BlockDriverState *bdrv_open(const char *filename, const char *reference,
|
||||
QDict *options, int flags, Error **errp);
|
||||
|
||||
BlockDriverState * no_coroutine_fn
|
||||
bdrv_open(const char *filename, const char *reference, QDict *options,
|
||||
int flags, Error **errp);
|
||||
|
||||
BlockDriverState * coroutine_fn no_co_wrapper
|
||||
bdrv_co_open(const char *filename, const char *reference,
|
||||
QDict *options, int flags, Error **errp);
|
||||
|
||||
BlockDriverState *bdrv_new_open_driver_opts(BlockDriver *drv,
|
||||
const char *node_name,
|
||||
QDict *options, int flags,
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "exec/cpu_ldst.h"
|
||||
#endif
|
||||
#include "qemu/interval-tree.h"
|
||||
#include "qemu/clang-tsa.h"
|
||||
|
||||
/* allow to see translation results - the slowdown should be negligible, so we leave it */
|
||||
#define DEBUG_DISAS
|
||||
@ -759,8 +760,8 @@ static inline tb_page_addr_t get_page_addr_code(CPUArchState *env,
|
||||
}
|
||||
|
||||
#if defined(CONFIG_USER_ONLY)
|
||||
void mmap_lock(void);
|
||||
void mmap_unlock(void);
|
||||
void TSA_NO_TSA mmap_lock(void);
|
||||
void TSA_NO_TSA mmap_unlock(void);
|
||||
bool have_mmap_lock(void);
|
||||
|
||||
/**
|
||||
|
@ -330,7 +330,7 @@ bool hbitmap_next_dirty_area(const HBitmap *hb, int64_t start, int64_t end,
|
||||
int64_t *dirty_start, int64_t *dirty_count);
|
||||
|
||||
/*
|
||||
* bdrv_dirty_bitmap_status:
|
||||
* hbitmap_status:
|
||||
* @hb: The HBitmap to operate on
|
||||
* @start: The bit to start from
|
||||
* @count: Number of bits to proceed
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include "qemu/processor.h"
|
||||
#include "qemu/atomic.h"
|
||||
#include "qemu/clang-tsa.h"
|
||||
|
||||
typedef struct QemuCond QemuCond;
|
||||
typedef struct QemuSemaphore QemuSemaphore;
|
||||
@ -24,9 +25,12 @@ typedef struct QemuThread QemuThread;
|
||||
|
||||
void qemu_mutex_init(QemuMutex *mutex);
|
||||
void qemu_mutex_destroy(QemuMutex *mutex);
|
||||
int qemu_mutex_trylock_impl(QemuMutex *mutex, const char *file, const int line);
|
||||
void qemu_mutex_lock_impl(QemuMutex *mutex, const char *file, const int line);
|
||||
void qemu_mutex_unlock_impl(QemuMutex *mutex, const char *file, const int line);
|
||||
int TSA_NO_TSA qemu_mutex_trylock_impl(QemuMutex *mutex, const char *file,
|
||||
const int line);
|
||||
void TSA_NO_TSA qemu_mutex_lock_impl(QemuMutex *mutex, const char *file,
|
||||
const int line);
|
||||
void TSA_NO_TSA qemu_mutex_unlock_impl(QemuMutex *mutex, const char *file,
|
||||
const int line);
|
||||
|
||||
void qemu_rec_mutex_init(QemuRecMutex *mutex);
|
||||
void qemu_rec_mutex_destroy(QemuRecMutex *mutex);
|
||||
@ -153,8 +157,8 @@ void qemu_cond_destroy(QemuCond *cond);
|
||||
*/
|
||||
void qemu_cond_signal(QemuCond *cond);
|
||||
void qemu_cond_broadcast(QemuCond *cond);
|
||||
void qemu_cond_wait_impl(QemuCond *cond, QemuMutex *mutex,
|
||||
const char *file, const int line);
|
||||
void TSA_NO_TSA qemu_cond_wait_impl(QemuCond *cond, QemuMutex *mutex,
|
||||
const char *file, const int line);
|
||||
bool qemu_cond_timedwait_impl(QemuCond *cond, QemuMutex *mutex, int ms,
|
||||
const char *file, const int line);
|
||||
|
||||
|
@ -23,10 +23,23 @@
|
||||
*/
|
||||
|
||||
BlockBackend *blk_new(AioContext *ctx, uint64_t perm, uint64_t shared_perm);
|
||||
BlockBackend *blk_new_with_bs(BlockDriverState *bs, uint64_t perm,
|
||||
uint64_t shared_perm, Error **errp);
|
||||
BlockBackend *blk_new_open(const char *filename, const char *reference,
|
||||
QDict *options, int flags, Error **errp);
|
||||
|
||||
BlockBackend * no_coroutine_fn
|
||||
blk_new_with_bs(BlockDriverState *bs, uint64_t perm, uint64_t shared_perm,
|
||||
Error **errp);
|
||||
|
||||
BlockBackend * coroutine_fn no_co_wrapper
|
||||
blk_co_new_with_bs(BlockDriverState *bs, uint64_t perm, uint64_t shared_perm,
|
||||
Error **errp);
|
||||
|
||||
BlockBackend * no_coroutine_fn
|
||||
blk_new_open(const char *filename, const char *reference, QDict *options,
|
||||
int flags, Error **errp);
|
||||
|
||||
BlockBackend * coroutine_fn no_co_wrapper
|
||||
blk_co_new_open(const char *filename, const char *reference, QDict *options,
|
||||
int flags, Error **errp);
|
||||
|
||||
int blk_get_refcnt(BlockBackend *blk);
|
||||
void blk_ref(BlockBackend *blk);
|
||||
void blk_unref(BlockBackend *blk);
|
||||
|
@ -63,8 +63,8 @@ class ParamDecl:
|
||||
|
||||
|
||||
class FuncDecl:
|
||||
def __init__(self, return_type: str, name: str, args: str,
|
||||
variant: str) -> None:
|
||||
def __init__(self, wrapper_type: str, return_type: str, name: str,
|
||||
args: str, variant: str) -> None:
|
||||
self.return_type = return_type.strip()
|
||||
self.name = name.strip()
|
||||
self.struct_name = snake_to_camel(self.name)
|
||||
@ -72,8 +72,21 @@ class FuncDecl:
|
||||
self.create_only_co = 'mixed' not in variant
|
||||
self.graph_rdlock = 'bdrv_rdlock' in variant
|
||||
|
||||
subsystem, subname = self.name.split('_', 1)
|
||||
self.co_name = f'{subsystem}_co_{subname}'
|
||||
self.wrapper_type = wrapper_type
|
||||
|
||||
if wrapper_type == 'co':
|
||||
subsystem, subname = self.name.split('_', 1)
|
||||
self.target_name = f'{subsystem}_co_{subname}'
|
||||
else:
|
||||
assert wrapper_type == 'no_co'
|
||||
subsystem, co_infix, subname = self.name.split('_', 2)
|
||||
if co_infix != 'co':
|
||||
raise ValueError(f"Invalid no_co function name: {self.name}")
|
||||
if not self.create_only_co:
|
||||
raise ValueError(f"no_co function can't be mixed: {self.name}")
|
||||
if self.graph_rdlock:
|
||||
raise ValueError(f"no_co function can't be rdlock: {self.name}")
|
||||
self.target_name = f'{subsystem}_{subname}'
|
||||
|
||||
t = self.args[0].type
|
||||
if t == 'BlockDriverState *':
|
||||
@ -105,7 +118,8 @@ class FuncDecl:
|
||||
|
||||
# Match wrappers declared with a co_wrapper mark
|
||||
func_decl_re = re.compile(r'^(?P<return_type>[a-zA-Z][a-zA-Z0-9_]* [\*]?)'
|
||||
r'\s*co_wrapper'
|
||||
r'(\s*coroutine_fn)?'
|
||||
r'\s*(?P<wrapper_type>(no_)?co)_wrapper'
|
||||
r'(?P<variant>(_[a-z][a-z0-9_]*)?)\s*'
|
||||
r'(?P<wrapper_name>[a-z][a-z0-9_]*)'
|
||||
r'\((?P<args>[^)]*)\);$', re.MULTILINE)
|
||||
@ -113,7 +127,8 @@ func_decl_re = re.compile(r'^(?P<return_type>[a-zA-Z][a-zA-Z0-9_]* [\*]?)'
|
||||
|
||||
def func_decl_iter(text: str) -> Iterator:
|
||||
for m in func_decl_re.finditer(text):
|
||||
yield FuncDecl(return_type=m.group('return_type'),
|
||||
yield FuncDecl(wrapper_type=m.group('wrapper_type'),
|
||||
return_type=m.group('return_type'),
|
||||
name=m.group('wrapper_name'),
|
||||
args=m.group('args'),
|
||||
variant=m.group('variant'))
|
||||
@ -133,7 +148,7 @@ def create_mixed_wrapper(func: FuncDecl) -> str:
|
||||
"""
|
||||
Checks if we are already in coroutine
|
||||
"""
|
||||
name = func.co_name
|
||||
name = func.target_name
|
||||
struct_name = func.struct_name
|
||||
graph_assume_lock = 'assume_graph_lock();' if func.graph_rdlock else ''
|
||||
|
||||
@ -163,7 +178,7 @@ def create_co_wrapper(func: FuncDecl) -> str:
|
||||
"""
|
||||
Assumes we are not in coroutine, and creates one
|
||||
"""
|
||||
name = func.co_name
|
||||
name = func.target_name
|
||||
struct_name = func.struct_name
|
||||
return f"""\
|
||||
{func.return_type} {func.name}({ func.gen_list('{decl}') })
|
||||
@ -183,10 +198,11 @@ def create_co_wrapper(func: FuncDecl) -> str:
|
||||
}}"""
|
||||
|
||||
|
||||
def gen_wrapper(func: FuncDecl) -> str:
|
||||
def gen_co_wrapper(func: FuncDecl) -> str:
|
||||
assert not '_co_' in func.name
|
||||
assert func.wrapper_type == 'co'
|
||||
|
||||
name = func.co_name
|
||||
name = func.target_name
|
||||
struct_name = func.struct_name
|
||||
|
||||
graph_lock=''
|
||||
@ -225,11 +241,56 @@ static void coroutine_fn {name}_entry(void *opaque)
|
||||
{creation_function(func)}"""
|
||||
|
||||
|
||||
def gen_no_co_wrapper(func: FuncDecl) -> str:
|
||||
assert '_co_' in func.name
|
||||
assert func.wrapper_type == 'no_co'
|
||||
|
||||
name = func.target_name
|
||||
struct_name = func.struct_name
|
||||
|
||||
return f"""\
|
||||
/*
|
||||
* Wrappers for {name}
|
||||
*/
|
||||
|
||||
typedef struct {struct_name} {{
|
||||
Coroutine *co;
|
||||
{func.return_field}
|
||||
{ func.gen_block(' {decl};') }
|
||||
}} {struct_name};
|
||||
|
||||
static void {name}_bh(void *opaque)
|
||||
{{
|
||||
{struct_name} *s = opaque;
|
||||
|
||||
{func.get_result}{name}({ func.gen_list('s->{name}') });
|
||||
|
||||
aio_co_wake(s->co);
|
||||
}}
|
||||
|
||||
{func.return_type} coroutine_fn {func.name}({ func.gen_list('{decl}') })
|
||||
{{
|
||||
{struct_name} s = {{
|
||||
.co = qemu_coroutine_self(),
|
||||
{ func.gen_block(' .{name} = {name},') }
|
||||
}};
|
||||
assert(qemu_in_coroutine());
|
||||
|
||||
aio_bh_schedule_oneshot(qemu_get_aio_context(), {name}_bh, &s);
|
||||
qemu_coroutine_yield();
|
||||
|
||||
{func.ret}
|
||||
}}"""
|
||||
|
||||
|
||||
def gen_wrappers(input_code: str) -> str:
|
||||
res = ''
|
||||
for func in func_decl_iter(input_code):
|
||||
res += '\n\n\n'
|
||||
res += gen_wrapper(func)
|
||||
if func.wrapper_type == 'co':
|
||||
res += gen_co_wrapper(func)
|
||||
else:
|
||||
res += gen_no_co_wrapper(func)
|
||||
|
||||
return res
|
||||
|
||||
|
@ -331,7 +331,7 @@ bool hbitmap_status(const HBitmap *hb, int64_t start, int64_t count,
|
||||
|
||||
assert(next_zero > start);
|
||||
*pnum = next_zero - start;
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool hbitmap_empty(const HBitmap *hb)
|
||||
|
@ -223,7 +223,7 @@ void qemu_cond_wait_impl(QemuCond *cond, QemuMutex *mutex, const char *file, con
|
||||
error_exit(err, __func__);
|
||||
}
|
||||
|
||||
static bool
|
||||
static bool TSA_NO_TSA
|
||||
qemu_cond_timedwait_ts(QemuCond *cond, QemuMutex *mutex, struct timespec *ts,
|
||||
const char *file, const int line)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user