Merge remote-tracking branch 'upstream/master' into main

This commit is contained in:
Andrea Fioraldi 2023-02-27 17:25:14 +01:00
commit a0a2480e9c
269 changed files with 3506 additions and 3134 deletions

View File

@ -11,6 +11,8 @@
# and show the duration of each line.
FF_SCRIPT_SECTIONS: 1
interruptible: true
rules:
#############################################################
# Stage 1: exclude scenarios where we definitely don't

View File

@ -11,12 +11,10 @@
fi
- mkdir build
- cd build
- if test -n "$TARGETS";
then
../configure --enable-werror --disable-docs ${LD_JOBS:+--meson=git} $CONFIGURE_ARGS --target-list="$TARGETS" ;
else
../configure --enable-werror --disable-docs ${LD_JOBS:+--meson=git} $CONFIGURE_ARGS ;
fi || { cat config.log meson-logs/meson-log.txt && exit 1; }
- ../configure --enable-werror --disable-docs --enable-fdt=system
${LD_JOBS:+--meson=git} ${TARGETS:+--target-list="$TARGETS"}
$CONFIGURE_ARGS ||
{ cat config.log meson-logs/meson-log.txt && exit 1; }
- if test -n "$LD_JOBS";
then
../meson/meson.py configure . -Dbackend_max_links="$LD_JOBS" ;

View File

@ -41,8 +41,8 @@ build-system-ubuntu:
job: amd64-ubuntu2004-container
variables:
IMAGE: ubuntu2004
CONFIGURE_ARGS: --enable-docs --enable-fdt=system --enable-capstone
TARGETS: aarch64-softmmu alpha-softmmu cris-softmmu hppa-softmmu
CONFIGURE_ARGS: --enable-docs
TARGETS: alpha-softmmu cris-softmmu hppa-softmmu
microblazeel-softmmu mips64el-softmmu
MAKE_CHECK_ARGS: check-build
artifacts:
@ -74,6 +74,7 @@ build-system-debian:
job: amd64-debian-container
variables:
IMAGE: debian-amd64
CONFIGURE_ARGS: --with-coroutine=sigaltstack
TARGETS: arm-softmmu avr-softmmu i386-softmmu mipsel-softmmu
riscv64-softmmu sh4eb-softmmu sparc-softmmu xtensaeb-softmmu
MAKE_CHECK_ARGS: check-build
@ -119,7 +120,6 @@ build-system-fedora:
variables:
IMAGE: fedora
CONFIGURE_ARGS: --disable-gcrypt --enable-nettle --enable-docs
--enable-fdt=system --enable-slirp --enable-capstone
TARGETS: tricore-softmmu microblaze-softmmu mips-softmmu
xtensa-softmmu m68k-softmmu riscv32-softmmu ppc-softmmu sparc64-softmmu
MAKE_CHECK_ARGS: check-build
@ -165,9 +165,8 @@ build-system-centos:
job: amd64-centos8-container
variables:
IMAGE: centos8
CONFIGURE_ARGS: --disable-nettle --enable-gcrypt --enable-fdt=system
CONFIGURE_ARGS: --disable-nettle --enable-gcrypt --enable-vfio-user-server
--enable-modules --enable-trace-backends=dtrace --enable-docs
--enable-vfio-user-server
TARGETS: ppc64-softmmu or1k-softmmu s390x-softmmu
x86_64-softmmu rx-softmmu sh4-softmmu nios2-softmmu
MAKE_CHECK_ARGS: check-build
@ -200,7 +199,6 @@ build-system-opensuse:
job: amd64-opensuse-leap-container
variables:
IMAGE: opensuse-leap
CONFIGURE_ARGS: --enable-fdt=system
TARGETS: s390x-softmmu x86_64-softmmu aarch64-softmmu
MAKE_CHECK_ARGS: check-build
artifacts:
@ -463,7 +461,7 @@ tsan-build:
variables:
IMAGE: ubuntu2004
CONFIGURE_ARGS: --enable-tsan --cc=clang-10 --cxx=clang++-10
--enable-trace-backends=ust --enable-fdt=system --disable-slirp
--enable-trace-backends=ust --disable-slirp
TARGETS: x86_64-softmmu ppc64-softmmu riscv64-softmmu x86_64-linux-user
MAKE_CHECK_ARGS: bench V=1
@ -534,18 +532,6 @@ build-tci:
- QTEST_QEMU_BINARY="./qemu-system-s390x" ./tests/qtest/pxe-test -m slow
- make check-tcg
# Alternate coroutines implementations are only really of interest to KVM users
# However we can't test against KVM on Gitlab-CI so we can only run unit tests
build-coroutine-sigaltstack:
extends: .native_build_job_template
needs:
job: amd64-ubuntu2004-container
variables:
IMAGE: ubuntu2004
CONFIGURE_ARGS: --with-coroutine=sigaltstack --disable-tcg
--enable-trace-backends=ftrace
MAKE_CHECK_ARGS: check-unit
# Check our reduced build configurations
build-without-defaults:
extends: .native_build_job_template

View File

@ -6,8 +6,9 @@
script:
- mkdir build
- cd build
- ../configure --enable-werror --disable-docs $QEMU_CONFIGURE_OPTS
--disable-user --target-list-exclude="arm-softmmu cris-softmmu
- ../configure --enable-werror --disable-docs --enable-fdt=system
--disable-user $QEMU_CONFIGURE_OPTS $EXTRA_CONFIGURE_OPTS
--target-list-exclude="arm-softmmu cris-softmmu
i386-softmmu microblaze-softmmu mips-softmmu mipsel-softmmu
mips64-softmmu ppc-softmmu riscv32-softmmu sh4-softmmu
sparc-softmmu xtensa-softmmu $CROSS_SKIP_TARGETS"

View File

@ -159,7 +159,7 @@ cross-s390x-kvm-only:
job: s390x-debian-cross-container
variables:
IMAGE: debian-s390x-cross
EXTRA_CONFIGURE_OPTS: --disable-tcg
EXTRA_CONFIGURE_OPTS: --disable-tcg --enable-trace-backends=ftrace
cross-mips64el-kvm-only:
extends: .cross_accel_build_job
@ -175,6 +175,7 @@ cross-win32-system:
job: win32-fedora-cross-container
variables:
IMAGE: fedora-win32-cross
EXTRA_CONFIGURE_OPTS: --enable-fdt=internal
CROSS_SKIP_TARGETS: alpha-softmmu avr-softmmu hppa-softmmu m68k-softmmu
microblazeel-softmmu mips64el-softmmu nios2-softmmu
artifacts:
@ -187,6 +188,7 @@ cross-win64-system:
job: win64-fedora-cross-container
variables:
IMAGE: fedora-win64-cross
EXTRA_CONFIGURE_OPTS: --enable-fdt=internal
CROSS_SKIP_TARGETS: alpha-softmmu avr-softmmu hppa-softmmu
m68k-softmmu microblazeel-softmmu nios2-softmmu
or1k-softmmu rx-softmmu sh4eb-softmmu sparc64-softmmu

View File

@ -23,12 +23,12 @@ check-dco:
before_script:
- apk -U add git
check-python-pipenv:
check-python-minreqs:
extends: .base_job_template
stage: test
image: $CI_REGISTRY_IMAGE/qemu/python:latest
script:
- make -C python check-pipenv
- make -C python check-minreqs
variables:
GIT_DEPTH: 1
needs:

View File

@ -38,6 +38,7 @@ msys2-64bit:
mingw-w64-x86_64-capstone
mingw-w64-x86_64-curl
mingw-w64-x86_64-cyrus-sasl
mingw-w64-x86_64-dtc
mingw-w64-x86_64-gcc
mingw-w64-x86_64-glib2
mingw-w64-x86_64-gnutls
@ -71,7 +72,7 @@ msys2-64bit:
# for the msys2 64-bit job, due to the build could not complete within
# the project timeout.
- ..\msys64\usr\bin\bash -lc '../configure --target-list=x86_64-softmmu
--without-default-devices'
--without-default-devices --enable-fdt=system'
- ..\msys64\usr\bin\bash -lc 'make'
# qTests don't run successfully with "--without-default-devices",
# so let's exclude the qtests from CI for now.
@ -86,6 +87,7 @@ msys2-32bit:
mingw-w64-i686-capstone
mingw-w64-i686-curl
mingw-w64-i686-cyrus-sasl
mingw-w64-i686-dtc
mingw-w64-i686-gcc
mingw-w64-i686-glib2
mingw-w64-i686-gnutls
@ -113,7 +115,8 @@ msys2-32bit:
- $env:MSYS = 'winsymlinks:native' # Enable native Windows symlink
- mkdir output
- cd output
- ..\msys64\usr\bin\bash -lc '../configure --target-list=ppc64-softmmu'
- ..\msys64\usr\bin\bash -lc '../configure --target-list=ppc64-softmmu
--enable-fdt=system'
- ..\msys64\usr\bin\bash -lc 'make'
- ..\msys64\usr\bin\bash -lc 'make check MTESTARGS=\"--no-suite qtest\" ||
{ cat meson-logs/testlog.txt; exit 1; }'

View File

@ -161,6 +161,7 @@ M: Peter Maydell <peter.maydell@linaro.org>
L: qemu-arm@nongnu.org
S: Maintained
F: target/arm/
F: target/arm/tcg/
F: tests/tcg/arm/
F: tests/tcg/aarch64/
F: tests/qtest/arm-cpu-features.c
@ -287,6 +288,9 @@ RISC-V TCG CPUs
M: Palmer Dabbelt <palmer@dabbelt.com>
M: Alistair Francis <alistair.francis@wdc.com>
M: Bin Meng <bin.meng@windriver.com>
R: Weiwei Li <liweiwei@iscas.ac.cn>
R: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
R: Liu Zhiwei <zhiwei_liu@linux.alibaba.com>
L: qemu-riscv@nongnu.org
S: Supported
F: target/riscv/
@ -2273,7 +2277,6 @@ F: hw/acpi/vmgenid.c
F: include/hw/acpi/vmgenid.h
F: docs/specs/vmgenid.txt
F: tests/qtest/vmgenid-test.c
F: stubs/vmgenid.c
LED
M: Philippe Mathieu-Daudé <philmd@linaro.org>

View File

@ -286,8 +286,16 @@ static void *translator_access(CPUArchState *env, DisasContextBase *db,
if (host == NULL) {
tb_page_addr_t phys_page =
get_page_addr_code_hostp(env, base, &db->host_addr[1]);
/* We cannot handle MMIO as second page. */
assert(phys_page != -1);
/*
* If the second page is MMIO, treat as if the first page
* was MMIO as well, so that we do not cache the TB.
*/
if (unlikely(phys_page == -1)) {
tb_set_page_addr0(tb, -1);
return NULL;
}
tb_set_page_addr1(tb, phys_page);
#ifdef CONFIG_USER_ONLY
page_protect(end);

View File

@ -30,7 +30,6 @@
#include "qapi/qapi-visit-authz.h"
#include "qapi/qmp/qjson.h"
#include "qapi/qmp/qobject.h"
#include "qapi/qmp/qerror.h"
#include "qapi/qobject-input-visitor.h"

View File

@ -28,7 +28,6 @@
#ifdef CONFIG_VHOST_CRYPTO
#include "qapi/error.h"
#include "qapi/qmp/qerror.h"
#include "qemu/error-report.h"
#include "hw/virtio/virtio-crypto.h"
#include "sysemu/cryptodev-vhost-user.h"

View File

@ -13,7 +13,6 @@
#include "qemu/osdep.h"
#include "sysemu/rng.h"
#include "qapi/error.h"
#include "qapi/qmp/qerror.h"
#include "qemu/module.h"
#include "qom/object_interfaces.h"

View File

@ -13,7 +13,6 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qapi/qmp/qerror.h"
#include "qemu/error-report.h"
#include "qom/object_interfaces.h"
#include "sysemu/vhost-user-backend.h"

12
block.c
View File

@ -277,8 +277,8 @@ bool bdrv_is_read_only(BlockDriverState *bs)
return !(bs->open_flags & BDRV_O_RDWR);
}
int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
bool ignore_allow_rdw, Error **errp)
static int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
bool ignore_allow_rdw, Error **errp)
{
IO_CODE();
@ -533,6 +533,7 @@ int coroutine_fn bdrv_co_create(BlockDriver *drv, const char *filename,
int ret;
GLOBAL_STATE_CODE();
ERRP_GUARD();
assert_bdrv_graph_readable();
if (!drv->bdrv_co_create_opts) {
error_setg(errp, "Driver '%s' does not support image creation",
@ -739,6 +740,7 @@ int coroutine_fn bdrv_co_delete_file(BlockDriverState *bs, Error **errp)
IO_CODE();
assert(bs != NULL);
assert_bdrv_graph_readable();
if (!bs->drv) {
error_setg(errp, "Block node '%s' is not opened", bs->filename);
@ -1040,6 +1042,7 @@ int coroutine_fn bdrv_co_refresh_total_sectors(BlockDriverState *bs,
{
BlockDriver *drv = bs->drv;
IO_CODE();
assert_bdrv_graph_readable();
if (!drv) {
return -ENOMEDIUM;
@ -5841,6 +5844,7 @@ int64_t coroutine_fn bdrv_co_nb_sectors(BlockDriverState *bs)
{
BlockDriver *drv = bs->drv;
IO_CODE();
assert_bdrv_graph_readable();
if (!drv)
return -ENOMEDIUM;
@ -5862,6 +5866,7 @@ int64_t coroutine_fn bdrv_co_getlength(BlockDriverState *bs)
{
int64_t ret;
IO_CODE();
assert_bdrv_graph_readable();
ret = bdrv_co_nb_sectors(bs);
if (ret < 0) {
@ -6825,6 +6830,7 @@ bool coroutine_fn bdrv_co_is_inserted(BlockDriverState *bs)
BlockDriver *drv = bs->drv;
BdrvChild *child;
IO_CODE();
assert_bdrv_graph_readable();
if (!drv) {
return false;
@ -6847,6 +6853,7 @@ void coroutine_fn bdrv_co_eject(BlockDriverState *bs, bool eject_flag)
{
BlockDriver *drv = bs->drv;
IO_CODE();
assert_bdrv_graph_readable();
if (drv && drv->bdrv_co_eject) {
drv->bdrv_co_eject(bs, eject_flag);
@ -6861,6 +6868,7 @@ void coroutine_fn bdrv_co_lock_medium(BlockDriverState *bs, bool locked)
{
BlockDriver *drv = bs->drv;
IO_CODE();
assert_bdrv_graph_readable();
trace_bdrv_lock_medium(bs, locked);
if (drv && drv->bdrv_co_lock_medium) {

View File

@ -22,7 +22,6 @@
#include "block/block-copy.h"
#include "block/dirty-bitmap.h"
#include "qapi/error.h"
#include "qapi/qmp/qerror.h"
#include "qemu/cutils.h"
#include "sysemu/block-backend.h"
#include "qemu/bitmap.h"
@ -270,7 +269,10 @@ static int coroutine_fn backup_run(Job *job, Error **errp)
return -ECANCELED;
}
/* rdlock protects the subsequent call to bdrv_is_allocated() */
bdrv_graph_co_rdlock();
ret = block_copy_reset_unallocated(s->bcs, offset, &count);
bdrv_graph_co_rdunlock();
if (ret < 0) {
return ret;
}

View File

@ -626,7 +626,7 @@ static int rule_check(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
return -error;
}
static int coroutine_fn
static int coroutine_fn GRAPH_RDLOCK
blkdebug_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{
@ -647,7 +647,7 @@ blkdebug_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
}
static int coroutine_fn
static int coroutine_fn GRAPH_RDLOCK
blkdebug_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{
@ -668,7 +668,7 @@ blkdebug_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
}
static int coroutine_fn blkdebug_co_flush(BlockDriverState *bs)
static int GRAPH_RDLOCK coroutine_fn blkdebug_co_flush(BlockDriverState *bs)
{
int err = rule_check(bs, 0, 0, BLKDEBUG_IO_TYPE_FLUSH);
@ -679,9 +679,9 @@ static int coroutine_fn blkdebug_co_flush(BlockDriverState *bs)
return bdrv_co_flush(bs->file->bs);
}
static int coroutine_fn blkdebug_co_pwrite_zeroes(BlockDriverState *bs,
int64_t offset, int64_t bytes,
BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
blkdebug_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
BdrvRequestFlags flags)
{
uint32_t align = MAX(bs->bl.request_alignment,
bs->bl.pwrite_zeroes_alignment);
@ -712,8 +712,8 @@ static int coroutine_fn blkdebug_co_pwrite_zeroes(BlockDriverState *bs,
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
}
static int coroutine_fn blkdebug_co_pdiscard(BlockDriverState *bs,
int64_t offset, int64_t bytes)
static int coroutine_fn GRAPH_RDLOCK
blkdebug_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
{
uint32_t align = bs->bl.pdiscard_alignment;
int err;
@ -967,7 +967,8 @@ static bool blkdebug_debug_is_suspended(BlockDriverState *bs, const char *tag)
return false;
}
static int64_t coroutine_fn blkdebug_co_getlength(BlockDriverState *bs)
static int64_t coroutine_fn GRAPH_RDLOCK
blkdebug_co_getlength(BlockDriverState *bs)
{
return bdrv_co_getlength(bs->file->bs);
}

View File

@ -267,7 +267,8 @@ static void blk_log_writes_close(BlockDriverState *bs)
s->log_file = NULL;
}
static int64_t coroutine_fn blk_log_writes_co_getlength(BlockDriverState *bs)
static int64_t coroutine_fn GRAPH_RDLOCK
blk_log_writes_co_getlength(BlockDriverState *bs)
{
return bdrv_co_getlength(bs->file->bs);
}
@ -294,7 +295,7 @@ static void blk_log_writes_refresh_limits(BlockDriverState *bs, Error **errp)
bs->bl.request_alignment = s->sectorsize;
}
static int coroutine_fn
static int coroutine_fn GRAPH_RDLOCK
blk_log_writes_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{
@ -307,7 +308,7 @@ typedef struct BlkLogWritesFileReq {
uint64_t bytes;
int file_flags;
QEMUIOVector *qiov;
int (*func)(struct BlkLogWritesFileReq *r);
int GRAPH_RDLOCK_PTR (*func)(struct BlkLogWritesFileReq *r);
int file_ret;
} BlkLogWritesFileReq;
@ -319,7 +320,8 @@ typedef struct {
int log_ret;
} BlkLogWritesLogReq;
static void coroutine_fn blk_log_writes_co_do_log(BlkLogWritesLogReq *lr)
static void coroutine_fn GRAPH_RDLOCK
blk_log_writes_co_do_log(BlkLogWritesLogReq *lr)
{
BDRVBlkLogWritesState *s = lr->bs->opaque;
uint64_t cur_log_offset = s->cur_log_sector << s->sectorbits;
@ -368,15 +370,16 @@ static void coroutine_fn blk_log_writes_co_do_log(BlkLogWritesLogReq *lr)
}
}
static void coroutine_fn blk_log_writes_co_do_file(BlkLogWritesFileReq *fr)
static void coroutine_fn GRAPH_RDLOCK
blk_log_writes_co_do_file(BlkLogWritesFileReq *fr)
{
fr->file_ret = fr->func(fr);
}
static int coroutine_fn
static int coroutine_fn GRAPH_RDLOCK
blk_log_writes_co_log(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
QEMUIOVector *qiov, int flags,
int (*file_func)(BlkLogWritesFileReq *r),
int /*GRAPH_RDLOCK*/ (*file_func)(BlkLogWritesFileReq *r),
uint64_t entry_flags, bool is_zero_write)
{
QEMUIOVector log_qiov;
@ -428,32 +431,33 @@ blk_log_writes_co_log(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
return fr.file_ret;
}
static int coroutine_fn
static int coroutine_fn GRAPH_RDLOCK
blk_log_writes_co_do_file_pwritev(BlkLogWritesFileReq *fr)
{
return bdrv_co_pwritev(fr->bs->file, fr->offset, fr->bytes,
fr->qiov, fr->file_flags);
}
static int coroutine_fn
static int coroutine_fn GRAPH_RDLOCK
blk_log_writes_co_do_file_pwrite_zeroes(BlkLogWritesFileReq *fr)
{
return bdrv_co_pwrite_zeroes(fr->bs->file, fr->offset, fr->bytes,
fr->file_flags);
}
static int coroutine_fn blk_log_writes_co_do_file_flush(BlkLogWritesFileReq *fr)
static int coroutine_fn GRAPH_RDLOCK
blk_log_writes_co_do_file_flush(BlkLogWritesFileReq *fr)
{
return bdrv_co_flush(fr->bs->file->bs);
}
static int coroutine_fn
static int coroutine_fn GRAPH_RDLOCK
blk_log_writes_co_do_file_pdiscard(BlkLogWritesFileReq *fr)
{
return bdrv_co_pdiscard(fr->bs->file, fr->offset, fr->bytes);
}
static int coroutine_fn
static int coroutine_fn GRAPH_RDLOCK
blk_log_writes_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{
@ -461,7 +465,7 @@ blk_log_writes_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
blk_log_writes_co_do_file_pwritev, 0, false);
}
static int coroutine_fn
static int coroutine_fn GRAPH_RDLOCK
blk_log_writes_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
int64_t bytes, BdrvRequestFlags flags)
{
@ -470,14 +474,15 @@ blk_log_writes_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
true);
}
static int coroutine_fn blk_log_writes_co_flush_to_disk(BlockDriverState *bs)
static int coroutine_fn GRAPH_RDLOCK
blk_log_writes_co_flush_to_disk(BlockDriverState *bs)
{
return blk_log_writes_co_log(bs, 0, 0, NULL, 0,
blk_log_writes_co_do_file_flush,
LOG_FLUSH_FLAG, false);
}
static int coroutine_fn
static int coroutine_fn GRAPH_RDLOCK
blk_log_writes_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
{
return blk_log_writes_co_log(bs, offset, bytes, NULL, 0,

View File

@ -40,7 +40,8 @@ fail:
return ret;
}
static int64_t coroutine_fn blkreplay_co_getlength(BlockDriverState *bs)
static int64_t coroutine_fn GRAPH_RDLOCK
blkreplay_co_getlength(BlockDriverState *bs)
{
return bdrv_co_getlength(bs->file->bs);
}
@ -69,8 +70,9 @@ static void block_request_create(uint64_t reqid, BlockDriverState *bs,
replay_block_event(req->bh, reqid);
}
static int coroutine_fn blkreplay_co_preadv(BlockDriverState *bs,
int64_t offset, int64_t bytes, QEMUIOVector *qiov, BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
blkreplay_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{
uint64_t reqid = blkreplay_next_id();
int ret = bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
@ -80,8 +82,9 @@ static int coroutine_fn blkreplay_co_preadv(BlockDriverState *bs,
return ret;
}
static int coroutine_fn blkreplay_co_pwritev(BlockDriverState *bs,
int64_t offset, int64_t bytes, QEMUIOVector *qiov, BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
blkreplay_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{
uint64_t reqid = blkreplay_next_id();
int ret = bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
@ -91,8 +94,9 @@ static int coroutine_fn blkreplay_co_pwritev(BlockDriverState *bs,
return ret;
}
static int coroutine_fn blkreplay_co_pwrite_zeroes(BlockDriverState *bs,
int64_t offset, int64_t bytes, BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
blkreplay_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
BdrvRequestFlags flags)
{
uint64_t reqid = blkreplay_next_id();
int ret = bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
@ -102,8 +106,8 @@ static int coroutine_fn blkreplay_co_pwrite_zeroes(BlockDriverState *bs,
return ret;
}
static int coroutine_fn blkreplay_co_pdiscard(BlockDriverState *bs,
int64_t offset, int64_t bytes)
static int coroutine_fn GRAPH_RDLOCK
blkreplay_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
{
uint64_t reqid = blkreplay_next_id();
int ret = bdrv_co_pdiscard(bs->file, offset, bytes);
@ -113,7 +117,7 @@ static int coroutine_fn blkreplay_co_pdiscard(BlockDriverState *bs,
return ret;
}
static int coroutine_fn blkreplay_co_flush(BlockDriverState *bs)
static int coroutine_fn GRAPH_RDLOCK blkreplay_co_flush(BlockDriverState *bs)
{
uint64_t reqid = blkreplay_next_id();
int ret = bdrv_co_flush(bs->file->bs);

View File

@ -155,7 +155,8 @@ static void blkverify_close(BlockDriverState *bs)
s->test_file = NULL;
}
static int64_t coroutine_fn blkverify_co_getlength(BlockDriverState *bs)
static int64_t coroutine_fn GRAPH_RDLOCK
blkverify_co_getlength(BlockDriverState *bs)
{
BDRVBlkverifyState *s = bs->opaque;
@ -256,7 +257,7 @@ blkverify_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
return blkverify_co_prwv(bs, &r, offset, bytes, qiov, qiov, flags, true);
}
static int coroutine_fn blkverify_co_flush(BlockDriverState *bs)
static int coroutine_fn GRAPH_RDLOCK blkverify_co_flush(BlockDriverState *bs)
{
BDRVBlkverifyState *s = bs->opaque;

View File

@ -1235,8 +1235,8 @@ void blk_set_disable_request_queuing(BlockBackend *blk, bool disable)
blk->disable_request_queuing = disable;
}
static coroutine_fn int blk_check_byte_request(BlockBackend *blk,
int64_t offset, int64_t bytes)
static int coroutine_fn GRAPH_RDLOCK
blk_check_byte_request(BlockBackend *blk, int64_t offset, int64_t bytes)
{
int64_t len;
@ -1244,7 +1244,7 @@ static coroutine_fn int blk_check_byte_request(BlockBackend *blk,
return -EIO;
}
if (!blk_is_available(blk)) {
if (!blk_co_is_available(blk)) {
return -ENOMEDIUM;
}
@ -1289,6 +1289,7 @@ blk_co_do_preadv_part(BlockBackend *blk, int64_t offset, int64_t bytes,
IO_CODE();
blk_wait_while_drained(blk);
GRAPH_RDLOCK_GUARD();
/* Call blk_bs() only after waiting, the graph may have changed */
bs = blk_bs(blk);
@ -1363,6 +1364,7 @@ blk_co_do_pwritev_part(BlockBackend *blk, int64_t offset, int64_t bytes,
IO_CODE();
blk_wait_while_drained(blk);
GRAPH_RDLOCK_GUARD();
/* Call blk_bs() only after waiting, the graph may have changed */
bs = blk_bs(blk);
@ -1431,6 +1433,7 @@ int coroutine_fn blk_co_block_status_above(BlockBackend *blk,
BlockDriverState **file)
{
IO_CODE();
GRAPH_RDLOCK_GUARD();
return bdrv_co_block_status_above(blk_bs(blk), base, offset, bytes, pnum,
map, file);
}
@ -1441,6 +1444,7 @@ int coroutine_fn blk_co_is_allocated_above(BlockBackend *blk,
int64_t bytes, int64_t *pnum)
{
IO_CODE();
GRAPH_RDLOCK_GUARD();
return bdrv_co_is_allocated_above(blk_bs(blk), base, include_base, offset,
bytes, pnum);
}
@ -1602,8 +1606,9 @@ BlockAIOCB *blk_aio_pwrite_zeroes(BlockBackend *blk, int64_t offset,
int64_t coroutine_fn blk_co_getlength(BlockBackend *blk)
{
IO_CODE();
GRAPH_RDLOCK_GUARD();
if (!blk_is_available(blk)) {
if (!blk_co_is_available(blk)) {
return -ENOMEDIUM;
}
@ -1623,8 +1628,9 @@ void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr)
int64_t coroutine_fn blk_co_nb_sectors(BlockBackend *blk)
{
IO_CODE();
GRAPH_RDLOCK_GUARD();
if (!blk_is_available(blk)) {
if (!blk_co_is_available(blk)) {
return -ENOMEDIUM;
}
@ -1670,8 +1676,9 @@ blk_co_do_ioctl(BlockBackend *blk, unsigned long int req, void *buf)
IO_CODE();
blk_wait_while_drained(blk);
GRAPH_RDLOCK_GUARD();
if (!blk_is_available(blk)) {
if (!blk_co_is_available(blk)) {
return -ENOMEDIUM;
}
@ -1716,6 +1723,7 @@ blk_co_do_pdiscard(BlockBackend *blk, int64_t offset, int64_t bytes)
IO_CODE();
blk_wait_while_drained(blk);
GRAPH_RDLOCK_GUARD();
ret = blk_check_byte_request(blk, offset, bytes);
if (ret < 0) {
@ -1759,10 +1767,11 @@ int coroutine_fn blk_co_pdiscard(BlockBackend *blk, int64_t offset,
/* To be called between exactly one pair of blk_inc/dec_in_flight() */
static int coroutine_fn blk_co_do_flush(BlockBackend *blk)
{
blk_wait_while_drained(blk);
IO_CODE();
blk_wait_while_drained(blk);
GRAPH_RDLOCK_GUARD();
if (!blk_is_available(blk)) {
if (!blk_co_is_available(blk)) {
return -ENOMEDIUM;
}
@ -1989,20 +1998,22 @@ bool coroutine_fn blk_co_is_inserted(BlockBackend *blk)
{
BlockDriverState *bs = blk_bs(blk);
IO_CODE();
assert_bdrv_graph_readable();
return bs && bdrv_co_is_inserted(bs);
}
bool blk_is_available(BlockBackend *blk)
bool coroutine_fn blk_co_is_available(BlockBackend *blk)
{
IO_CODE();
return blk_is_inserted(blk) && !blk_dev_is_tray_open(blk);
return blk_co_is_inserted(blk) && !blk_dev_is_tray_open(blk);
}
void coroutine_fn blk_co_lock_medium(BlockBackend *blk, bool locked)
{
BlockDriverState *bs = blk_bs(blk);
IO_CODE();
GRAPH_RDLOCK_GUARD();
if (bs) {
bdrv_co_lock_medium(bs, locked);
@ -2014,6 +2025,7 @@ void coroutine_fn blk_co_eject(BlockBackend *blk, bool eject_flag)
BlockDriverState *bs = blk_bs(blk);
char *id;
IO_CODE();
GRAPH_RDLOCK_GUARD();
if (bs) {
bdrv_co_eject(bs, eject_flag);
@ -2321,6 +2333,7 @@ void coroutine_fn blk_co_io_plug(BlockBackend *blk)
{
BlockDriverState *bs = blk_bs(blk);
IO_CODE();
GRAPH_RDLOCK_GUARD();
if (bs) {
bdrv_co_io_plug(bs);
@ -2331,6 +2344,7 @@ void coroutine_fn blk_co_io_unplug(BlockBackend *blk)
{
BlockDriverState *bs = blk_bs(blk);
IO_CODE();
GRAPH_RDLOCK_GUARD();
if (bs) {
bdrv_co_io_unplug(bs);
@ -2372,7 +2386,8 @@ int coroutine_fn blk_co_truncate(BlockBackend *blk, int64_t offset, bool exact,
Error **errp)
{
IO_OR_GS_CODE();
if (!blk_is_available(blk)) {
GRAPH_RDLOCK_GUARD();
if (!blk_co_is_available(blk)) {
error_setg(errp, "No medium inserted");
return -ENOMEDIUM;
}
@ -2627,6 +2642,7 @@ int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in,
{
int r;
IO_CODE();
GRAPH_RDLOCK_GUARD();
r = blk_check_byte_request(blk_in, off_in, bytes);
if (r) {
@ -2636,6 +2652,7 @@ int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in,
if (r) {
return r;
}
return bdrv_co_copy_range(blk_in->root, off_in,
blk_out->root, off_out,
bytes, read_flags, write_flags);

View File

@ -469,10 +469,9 @@ static coroutine_fn int block_copy_task_run(AioTaskPool *pool,
* value of @method should be used for subsequent tasks.
* Returns 0 on success.
*/
static int coroutine_fn block_copy_do_copy(BlockCopyState *s,
int64_t offset, int64_t bytes,
BlockCopyMethod *method,
bool *error_is_read)
static int coroutine_fn GRAPH_RDLOCK
block_copy_do_copy(BlockCopyState *s, int64_t offset, int64_t bytes,
BlockCopyMethod *method, bool *error_is_read)
{
int ret;
int64_t nbytes = MIN(offset + bytes, s->len) - offset;
@ -558,8 +557,10 @@ static coroutine_fn int block_copy_task_entry(AioTask *task)
BlockCopyMethod method = t->method;
int ret;
ret = block_copy_do_copy(s, t->req.offset, t->req.bytes, &method,
&error_is_read);
WITH_GRAPH_RDLOCK_GUARD() {
ret = block_copy_do_copy(s, t->req.offset, t->req.bytes, &method,
&error_is_read);
}
WITH_QEMU_LOCK_GUARD(&s->lock) {
if (s->method == t->method) {
@ -581,9 +582,9 @@ static coroutine_fn int block_copy_task_entry(AioTask *task)
return ret;
}
static coroutine_fn int block_copy_block_status(BlockCopyState *s,
int64_t offset,
int64_t bytes, int64_t *pnum)
static coroutine_fn GRAPH_RDLOCK
int block_copy_block_status(BlockCopyState *s, int64_t offset, int64_t bytes,
int64_t *pnum)
{
int64_t num;
BlockDriverState *base;
@ -618,9 +619,9 @@ static coroutine_fn int block_copy_block_status(BlockCopyState *s,
* Check if the cluster starting at offset is allocated or not.
* return via pnum the number of contiguous clusters sharing this allocation.
*/
static int coroutine_fn block_copy_is_cluster_allocated(BlockCopyState *s,
int64_t offset,
int64_t *pnum)
static int coroutine_fn GRAPH_RDLOCK
block_copy_is_cluster_allocated(BlockCopyState *s, int64_t offset,
int64_t *pnum)
{
BlockDriverState *bs = s->source->bs;
int64_t count, total_count = 0;
@ -630,6 +631,7 @@ static int coroutine_fn block_copy_is_cluster_allocated(BlockCopyState *s,
assert(QEMU_IS_ALIGNED(offset, s->cluster_size));
while (true) {
/* protected in backup_run() */
ret = bdrv_co_is_allocated(bs, offset, bytes, &count);
if (ret < 0) {
return ret;
@ -704,7 +706,7 @@ int64_t coroutine_fn block_copy_reset_unallocated(BlockCopyState *s,
* Returns 1 if dirty clusters found and successfully copied, 0 if no dirty
* clusters found and -errno on failure.
*/
static int coroutine_fn
static int coroutine_fn GRAPH_RDLOCK
block_copy_dirty_clusters(BlockCopyCallState *call_state)
{
BlockCopyState *s = call_state->s;
@ -827,7 +829,8 @@ void block_copy_kick(BlockCopyCallState *call_state)
* it means that some I/O operation failed in context of _this_ block_copy call,
* not some parallel operation.
*/
static int coroutine_fn block_copy_common(BlockCopyCallState *call_state)
static int coroutine_fn GRAPH_RDLOCK
block_copy_common(BlockCopyCallState *call_state)
{
int ret;
BlockCopyState *s = call_state->s;
@ -892,6 +895,7 @@ static int coroutine_fn block_copy_common(BlockCopyCallState *call_state)
static void coroutine_fn block_copy_async_co_entry(void *opaque)
{
GRAPH_RDLOCK_GUARD();
block_copy_common(opaque);
}

View File

@ -237,7 +237,7 @@ static int64_t seek_to_sector(BlockDriverState *bs, int64_t sector_num)
return bitmap_offset + (512 * (s->bitmap_blocks + extent_offset));
}
static int coroutine_fn
static int coroutine_fn GRAPH_RDLOCK
bochs_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{

View File

@ -18,7 +18,6 @@
#include "block/block_int.h"
#include "block/blockjob_int.h"
#include "qapi/error.h"
#include "qapi/qmp/qerror.h"
#include "qemu/ratelimit.h"
#include "qemu/memalign.h"
#include "sysemu/block-backend.h"
@ -207,8 +206,9 @@ static const BlockJobDriver commit_job_driver = {
},
};
static int coroutine_fn bdrv_commit_top_preadv(BlockDriverState *bs,
int64_t offset, int64_t bytes, QEMUIOVector *qiov, BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
bdrv_commit_top_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{
return bdrv_co_preadv(bs->backing, offset, bytes, qiov, flags);
}

View File

@ -78,9 +78,9 @@ typedef struct BDRVCopyBeforeWriteState {
int snapshot_error;
} BDRVCopyBeforeWriteState;
static coroutine_fn int cbw_co_preadv(
BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
cbw_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{
return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
}
@ -149,8 +149,8 @@ static coroutine_fn int cbw_do_copy_before_write(BlockDriverState *bs,
return 0;
}
static int coroutine_fn cbw_co_pdiscard(BlockDriverState *bs,
int64_t offset, int64_t bytes)
static int coroutine_fn GRAPH_RDLOCK
cbw_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
{
int ret = cbw_do_copy_before_write(bs, offset, bytes, 0);
if (ret < 0) {
@ -160,8 +160,9 @@ static int coroutine_fn cbw_co_pdiscard(BlockDriverState *bs,
return bdrv_co_pdiscard(bs->file, offset, bytes);
}
static int coroutine_fn cbw_co_pwrite_zeroes(BlockDriverState *bs,
int64_t offset, int64_t bytes, BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
cbw_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
BdrvRequestFlags flags)
{
int ret = cbw_do_copy_before_write(bs, offset, bytes, flags);
if (ret < 0) {
@ -171,11 +172,9 @@ static int coroutine_fn cbw_co_pwrite_zeroes(BlockDriverState *bs,
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
}
static coroutine_fn int cbw_co_pwritev(BlockDriverState *bs,
int64_t offset,
int64_t bytes,
QEMUIOVector *qiov,
BdrvRequestFlags flags)
static coroutine_fn GRAPH_RDLOCK
int cbw_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{
int ret = cbw_do_copy_before_write(bs, offset, bytes, flags);
if (ret < 0) {
@ -185,7 +184,7 @@ static coroutine_fn int cbw_co_pwritev(BlockDriverState *bs,
return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
}
static int coroutine_fn cbw_co_flush(BlockDriverState *bs)
static int coroutine_fn GRAPH_RDLOCK cbw_co_flush(BlockDriverState *bs)
{
if (!bs->file) {
return 0;
@ -257,7 +256,7 @@ cbw_snapshot_read_unlock(BlockDriverState *bs, BlockReq *req)
g_free(req);
}
static coroutine_fn int
static int coroutine_fn GRAPH_RDLOCK
cbw_co_preadv_snapshot(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, size_t qiov_offset)
{
@ -289,7 +288,7 @@ cbw_co_preadv_snapshot(BlockDriverState *bs, int64_t offset, int64_t bytes,
return 0;
}
static int coroutine_fn
static int coroutine_fn GRAPH_RDLOCK
cbw_co_snapshot_block_status(BlockDriverState *bs,
bool want_zero, int64_t offset, int64_t bytes,
int64_t *pnum, int64_t *map,
@ -322,8 +321,8 @@ cbw_co_snapshot_block_status(BlockDriverState *bs,
return ret;
}
static int coroutine_fn cbw_co_pdiscard_snapshot(BlockDriverState *bs,
int64_t offset, int64_t bytes)
static int coroutine_fn GRAPH_RDLOCK
cbw_co_pdiscard_snapshot(BlockDriverState *bs, int64_t offset, int64_t bytes)
{
BDRVCopyBeforeWriteState *s = bs->opaque;

View File

@ -121,17 +121,16 @@ static void cor_child_perm(BlockDriverState *bs, BdrvChild *c,
}
static int64_t coroutine_fn cor_co_getlength(BlockDriverState *bs)
static int64_t coroutine_fn GRAPH_RDLOCK cor_co_getlength(BlockDriverState *bs)
{
return bdrv_co_getlength(bs->file->bs);
}
static int coroutine_fn cor_co_preadv_part(BlockDriverState *bs,
int64_t offset, int64_t bytes,
QEMUIOVector *qiov,
size_t qiov_offset,
BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
cor_co_preadv_part(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, size_t qiov_offset,
BdrvRequestFlags flags)
{
int64_t n;
int local_flags;
@ -180,50 +179,49 @@ static int coroutine_fn cor_co_preadv_part(BlockDriverState *bs,
}
static int coroutine_fn cor_co_pwritev_part(BlockDriverState *bs,
int64_t offset,
int64_t bytes,
QEMUIOVector *qiov,
size_t qiov_offset,
BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
cor_co_pwritev_part(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, size_t qiov_offset,
BdrvRequestFlags flags)
{
return bdrv_co_pwritev_part(bs->file, offset, bytes, qiov, qiov_offset,
flags);
}
static int coroutine_fn cor_co_pwrite_zeroes(BlockDriverState *bs,
int64_t offset, int64_t bytes,
BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
cor_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
BdrvRequestFlags flags)
{
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
}
static int coroutine_fn cor_co_pdiscard(BlockDriverState *bs,
int64_t offset, int64_t bytes)
static int coroutine_fn GRAPH_RDLOCK
cor_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
{
return bdrv_co_pdiscard(bs->file, offset, bytes);
}
static int coroutine_fn cor_co_pwritev_compressed(BlockDriverState *bs,
int64_t offset,
int64_t bytes,
QEMUIOVector *qiov)
static int coroutine_fn GRAPH_RDLOCK
cor_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov)
{
return bdrv_co_pwritev(bs->file, offset, bytes, qiov,
BDRV_REQ_WRITE_COMPRESSED);
}
static void coroutine_fn cor_co_eject(BlockDriverState *bs, bool eject_flag)
static void coroutine_fn GRAPH_RDLOCK
cor_co_eject(BlockDriverState *bs, bool eject_flag)
{
bdrv_co_eject(bs->file->bs, eject_flag);
}
static void coroutine_fn cor_co_lock_medium(BlockDriverState *bs, bool locked)
static void coroutine_fn GRAPH_RDLOCK
cor_co_lock_medium(BlockDriverState *bs, bool locked)
{
bdrv_co_lock_medium(bs->file->bs, locked);
}

View File

@ -43,7 +43,7 @@ bdrv_co_check(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix);
int coroutine_fn GRAPH_RDLOCK
bdrv_co_invalidate_cache(BlockDriverState *bs, Error **errp);
int coroutine_fn
int coroutine_fn GRAPH_RDLOCK
bdrv_co_common_block_status_above(BlockDriverState *bs,
BlockDriverState *base,
bool include_base,

View File

@ -43,6 +43,7 @@ static int coroutine_fn blockdev_create_run(Job *job, Error **errp)
int ret;
GLOBAL_STATE_CODE();
GRAPH_RDLOCK_GUARD();
job_progress_set_remaining(&s->common, 1);
ret = s->drv->bdrv_co_create(s->opts, errp);
@ -59,6 +60,12 @@ static const JobDriver blockdev_create_job_driver = {
.run = blockdev_create_run,
};
/* Checking whether the function is present doesn't require the graph lock */
static inline bool TSA_NO_TSA has_bdrv_co_create(BlockDriver *drv)
{
return drv->bdrv_co_create;
}
void qmp_blockdev_create(const char *job_id, BlockdevCreateOptions *options,
Error **errp)
{
@ -79,7 +86,7 @@ void qmp_blockdev_create(const char *job_id, BlockdevCreateOptions *options,
}
/* Error out if the driver doesn't support .bdrv_co_create */
if (!drv->bdrv_co_create) {
if (!has_bdrv_co_create(drv)) {
error_setg(errp, "Driver does not support blockdev-create");
return;
}

View File

@ -359,7 +359,7 @@ block_crypto_co_create_generic(BlockDriverState *bs, int64_t size,
return ret;
}
static int coroutine_fn
static int coroutine_fn GRAPH_RDLOCK
block_crypto_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
PreallocMode prealloc, BdrvRequestFlags flags,
Error **errp)
@ -397,7 +397,7 @@ static int block_crypto_reopen_prepare(BDRVReopenState *state,
*/
#define BLOCK_CRYPTO_MAX_IO_SIZE (1024 * 1024)
static coroutine_fn int
static int coroutine_fn GRAPH_RDLOCK
block_crypto_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{
@ -459,7 +459,7 @@ block_crypto_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
}
static coroutine_fn int
static int coroutine_fn GRAPH_RDLOCK
block_crypto_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{
@ -530,7 +530,8 @@ static void block_crypto_refresh_limits(BlockDriverState *bs, Error **errp)
}
static int64_t coroutine_fn block_crypto_co_getlength(BlockDriverState *bs)
static int64_t coroutine_fn GRAPH_RDLOCK
block_crypto_co_getlength(BlockDriverState *bs)
{
BlockCrypto *crypto = bs->opaque;
int64_t len = bdrv_co_getlength(bs->file->bs);
@ -664,10 +665,9 @@ fail:
return ret;
}
static int coroutine_fn block_crypto_co_create_opts_luks(BlockDriver *drv,
const char *filename,
QemuOpts *opts,
Error **errp)
static int coroutine_fn GRAPH_RDLOCK
block_crypto_co_create_opts_luks(BlockDriver *drv, const char *filename,
QemuOpts *opts, Error **errp)
{
QCryptoBlockCreateOptions *create_opts = NULL;
BlockDriverState *bs = NULL;

View File

@ -394,6 +394,7 @@ int coroutine_fn
bdrv_co_remove_persistent_dirty_bitmap(BlockDriverState *bs, const char *name,
Error **errp)
{
assert_bdrv_graph_readable();
if (bs->drv && bs->drv->bdrv_co_remove_persistent_dirty_bitmap) {
return bs->drv->bdrv_co_remove_persistent_dirty_bitmap(bs, name, errp);
}
@ -415,6 +416,7 @@ bdrv_co_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name,
uint32_t granularity, Error **errp)
{
BlockDriver *drv = bs->drv;
assert_bdrv_graph_readable();
if (!drv) {
error_setg_errno(errp, ENOMEDIUM,

View File

@ -2607,10 +2607,9 @@ out:
return result;
}
static int coroutine_fn raw_co_create_opts(BlockDriver *drv,
const char *filename,
QemuOpts *opts,
Error **errp)
static int coroutine_fn GRAPH_RDLOCK
raw_co_create_opts(BlockDriver *drv, const char *filename,
QemuOpts *opts, Error **errp)
{
BlockdevCreateOptions options;
int64_t total_size = 0;
@ -2920,8 +2919,8 @@ static void coroutine_fn check_cache_dropped(BlockDriverState *bs, Error **errp)
}
#endif /* __linux__ */
static void coroutine_fn raw_co_invalidate_cache(BlockDriverState *bs,
Error **errp)
static void coroutine_fn GRAPH_RDLOCK
raw_co_invalidate_cache(BlockDriverState *bs, Error **errp)
{
BDRVRawState *s = bs->opaque;
int ret;
@ -3272,7 +3271,7 @@ static void raw_abort_perm_update(BlockDriverState *bs)
raw_handle_perm_lock(bs, RAW_PL_ABORT, 0, 0, NULL);
}
static int coroutine_fn raw_co_copy_range_from(
static int coroutine_fn GRAPH_RDLOCK raw_co_copy_range_from(
BlockDriverState *bs, BdrvChild *src, int64_t src_offset,
BdrvChild *dst, int64_t dst_offset, int64_t bytes,
BdrvRequestFlags read_flags, BdrvRequestFlags write_flags)
@ -3281,14 +3280,12 @@ static int coroutine_fn raw_co_copy_range_from(
read_flags, write_flags);
}
static int coroutine_fn raw_co_copy_range_to(BlockDriverState *bs,
BdrvChild *src,
int64_t src_offset,
BdrvChild *dst,
int64_t dst_offset,
int64_t bytes,
BdrvRequestFlags read_flags,
BdrvRequestFlags write_flags)
static int coroutine_fn GRAPH_RDLOCK
raw_co_copy_range_to(BlockDriverState *bs,
BdrvChild *src, int64_t src_offset,
BdrvChild *dst, int64_t dst_offset,
int64_t bytes, BdrvRequestFlags read_flags,
BdrvRequestFlags write_flags)
{
RawPosixAIOData acb;
BDRVRawState *s = bs->opaque;

View File

@ -613,10 +613,9 @@ static int raw_co_create(BlockdevCreateOptions *options, Error **errp)
return 0;
}
static int coroutine_fn raw_co_create_opts(BlockDriver *drv,
const char *filename,
QemuOpts *opts,
Error **errp)
static int coroutine_fn GRAPH_RDLOCK
raw_co_create_opts(BlockDriver *drv, const char *filename,
QemuOpts *opts, Error **errp)
{
BlockdevCreateOptions options;
int64_t total_size = 0;

View File

@ -55,45 +55,43 @@ static int compress_open(BlockDriverState *bs, QDict *options, int flags,
}
static int64_t coroutine_fn compress_co_getlength(BlockDriverState *bs)
static int64_t coroutine_fn GRAPH_RDLOCK
compress_co_getlength(BlockDriverState *bs)
{
return bdrv_co_getlength(bs->file->bs);
}
static int coroutine_fn compress_co_preadv_part(BlockDriverState *bs,
int64_t offset, int64_t bytes,
QEMUIOVector *qiov,
size_t qiov_offset,
BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
compress_co_preadv_part(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, size_t qiov_offset,
BdrvRequestFlags flags)
{
return bdrv_co_preadv_part(bs->file, offset, bytes, qiov, qiov_offset,
flags);
}
static int coroutine_fn compress_co_pwritev_part(BlockDriverState *bs,
int64_t offset,
int64_t bytes,
QEMUIOVector *qiov,
size_t qiov_offset,
BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
compress_co_pwritev_part(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, size_t qiov_offset,
BdrvRequestFlags flags)
{
return bdrv_co_pwritev_part(bs->file, offset, bytes, qiov, qiov_offset,
flags | BDRV_REQ_WRITE_COMPRESSED);
}
static int coroutine_fn compress_co_pwrite_zeroes(BlockDriverState *bs,
int64_t offset, int64_t bytes,
BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
compress_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
BdrvRequestFlags flags)
{
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
}
static int coroutine_fn compress_co_pdiscard(BlockDriverState *bs,
int64_t offset, int64_t bytes)
static int coroutine_fn GRAPH_RDLOCK
compress_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
{
return bdrv_co_pdiscard(bs->file, offset, bytes);
}
@ -117,14 +115,14 @@ static void compress_refresh_limits(BlockDriverState *bs, Error **errp)
}
static void coroutine_fn
static void coroutine_fn GRAPH_RDLOCK
compress_co_eject(BlockDriverState *bs, bool eject_flag)
{
bdrv_co_eject(bs->file->bs, eject_flag);
}
static void coroutine_fn
static void coroutine_fn GRAPH_RDLOCK
compress_co_lock_medium(BlockDriverState *bs, bool locked)
{
bdrv_co_lock_medium(bs->file->bs, locked);

View File

@ -160,6 +160,7 @@ void bdrv_refresh_limits(BlockDriverState *bs, Transaction *tran, Error **errp)
bool have_limits;
GLOBAL_STATE_CODE();
assume_graph_lock(); /* FIXME */
if (tran) {
BdrvRefreshLimitsState *s = g_new(BdrvRefreshLimitsState, 1);
@ -932,6 +933,7 @@ int coroutine_fn bdrv_co_pwrite_sync(BdrvChild *child, int64_t offset,
{
int ret;
IO_CODE();
assert_bdrv_graph_readable();
ret = bdrv_co_pwrite(child, offset, bytes, buf, flags);
if (ret < 0) {
@ -959,16 +961,16 @@ static void bdrv_co_io_em_complete(void *opaque, int ret)
aio_co_wake(co->coroutine);
}
static int coroutine_fn bdrv_driver_preadv(BlockDriverState *bs,
int64_t offset, int64_t bytes,
QEMUIOVector *qiov,
size_t qiov_offset, int flags)
static int coroutine_fn GRAPH_RDLOCK
bdrv_driver_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, size_t qiov_offset, int flags)
{
BlockDriver *drv = bs->drv;
int64_t sector_num;
unsigned int nb_sectors;
QEMUIOVector local_qiov;
int ret;
assert_bdrv_graph_readable();
bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort);
assert(!(flags & ~bs->supported_read_flags));
@ -1028,11 +1030,10 @@ out:
return ret;
}
static int coroutine_fn bdrv_driver_pwritev(BlockDriverState *bs,
int64_t offset, int64_t bytes,
QEMUIOVector *qiov,
size_t qiov_offset,
BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
bdrv_driver_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, size_t qiov_offset,
BdrvRequestFlags flags)
{
BlockDriver *drv = bs->drv;
bool emulate_fua = false;
@ -1040,6 +1041,7 @@ static int coroutine_fn bdrv_driver_pwritev(BlockDriverState *bs,
unsigned int nb_sectors;
QEMUIOVector local_qiov;
int ret;
assert_bdrv_graph_readable();
bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort);
@ -1110,7 +1112,7 @@ emulate_flags:
return ret;
}
static int coroutine_fn
static int coroutine_fn GRAPH_RDLOCK
bdrv_driver_pwritev_compressed(BlockDriverState *bs, int64_t offset,
int64_t bytes, QEMUIOVector *qiov,
size_t qiov_offset)
@ -1118,6 +1120,7 @@ bdrv_driver_pwritev_compressed(BlockDriverState *bs, int64_t offset,
BlockDriver *drv = bs->drv;
QEMUIOVector local_qiov;
int ret;
assert_bdrv_graph_readable();
bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort);
@ -1145,9 +1148,9 @@ bdrv_driver_pwritev_compressed(BlockDriverState *bs, int64_t offset,
return ret;
}
static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child,
int64_t offset, int64_t bytes, QEMUIOVector *qiov,
size_t qiov_offset, int flags)
static int coroutine_fn GRAPH_RDLOCK
bdrv_co_do_copy_on_readv(BdrvChild *child, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, size_t qiov_offset, int flags)
{
BlockDriverState *bs = child->bs;
@ -1309,9 +1312,10 @@ err:
* handles copy on read, zeroing after EOF, and fragmentation of large
* reads; any other features must be implemented by the caller.
*/
static int coroutine_fn bdrv_aligned_preadv(BdrvChild *child,
BdrvTrackedRequest *req, int64_t offset, int64_t bytes,
int64_t align, QEMUIOVector *qiov, size_t qiov_offset, int flags)
static int coroutine_fn GRAPH_RDLOCK
bdrv_aligned_preadv(BdrvChild *child, BdrvTrackedRequest *req,
int64_t offset, int64_t bytes, int64_t align,
QEMUIOVector *qiov, size_t qiov_offset, int flags)
{
BlockDriverState *bs = child->bs;
int64_t total_bytes, max_bytes;
@ -1478,10 +1482,9 @@ static bool bdrv_init_padding(BlockDriverState *bs,
return true;
}
static coroutine_fn int bdrv_padding_rmw_read(BdrvChild *child,
BdrvTrackedRequest *req,
BdrvRequestPadding *pad,
bool zero_middle)
static int coroutine_fn GRAPH_RDLOCK
bdrv_padding_rmw_read(BdrvChild *child, BdrvTrackedRequest *req,
BdrvRequestPadding *pad, bool zero_middle)
{
QEMUIOVector local_qiov;
BlockDriverState *bs = child->bs;
@ -1669,8 +1672,9 @@ fail:
return ret;
}
static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
int64_t offset, int64_t bytes, BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
bdrv_co_do_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
BdrvRequestFlags flags)
{
BlockDriver *drv = bs->drv;
QEMUIOVector qiov;
@ -1686,6 +1690,7 @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
bs->bl.request_alignment);
int max_transfer = MIN_NON_ZERO(bs->bl.max_transfer, MAX_BOUNCE_BUFFER);
assert_bdrv_graph_readable();
bdrv_check_request(offset, bytes, &error_abort);
if (!drv) {
@ -1889,10 +1894,11 @@ bdrv_co_write_req_finish(BdrvChild *child, int64_t offset, int64_t bytes,
* Forwards an already correctly aligned write request to the BlockDriver,
* after possibly fragmenting it.
*/
static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child,
BdrvTrackedRequest *req, int64_t offset, int64_t bytes,
int64_t align, QEMUIOVector *qiov, size_t qiov_offset,
BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
bdrv_aligned_pwritev(BdrvChild *child, BdrvTrackedRequest *req,
int64_t offset, int64_t bytes, int64_t align,
QEMUIOVector *qiov, size_t qiov_offset,
BdrvRequestFlags flags)
{
BlockDriverState *bs = child->bs;
BlockDriver *drv = bs->drv;
@ -1976,11 +1982,9 @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child,
return ret;
}
static int coroutine_fn bdrv_co_do_zero_pwritev(BdrvChild *child,
int64_t offset,
int64_t bytes,
BdrvRequestFlags flags,
BdrvTrackedRequest *req)
static int coroutine_fn GRAPH_RDLOCK
bdrv_co_do_zero_pwritev(BdrvChild *child, int64_t offset, int64_t bytes,
BdrvRequestFlags flags, BdrvTrackedRequest *req)
{
BlockDriverState *bs = child->bs;
QEMUIOVector local_qiov;
@ -2153,6 +2157,7 @@ int coroutine_fn bdrv_co_pwrite_zeroes(BdrvChild *child, int64_t offset,
{
IO_CODE();
trace_bdrv_co_pwrite_zeroes(child->bs, offset, bytes, flags);
assert_bdrv_graph_readable();
if (!(child->bs->open_flags & BDRV_O_UNMAP)) {
flags &= ~BDRV_REQ_MAY_UNMAP;
@ -2224,11 +2229,10 @@ int bdrv_flush_all(void)
* BDRV_BLOCK_OFFSET_VALID bit is set, 'map' and 'file' (if non-NULL) are
* set to the host mapping and BDS corresponding to the guest offset.
*/
static int coroutine_fn bdrv_co_block_status(BlockDriverState *bs,
bool want_zero,
int64_t offset, int64_t bytes,
int64_t *pnum, int64_t *map,
BlockDriverState **file)
static int coroutine_fn GRAPH_RDLOCK
bdrv_co_block_status(BlockDriverState *bs, bool want_zero,
int64_t offset, int64_t bytes,
int64_t *pnum, int64_t *map, BlockDriverState **file)
{
int64_t total_size;
int64_t n; /* bytes */
@ -2240,6 +2244,7 @@ static int coroutine_fn bdrv_co_block_status(BlockDriverState *bs,
bool has_filtered_child;
assert(pnum);
assert_bdrv_graph_readable();
*pnum = 0;
total_size = bdrv_getlength(bs);
if (total_size < 0) {
@ -2470,6 +2475,7 @@ bdrv_co_common_block_status_above(BlockDriverState *bs,
IO_CODE();
assert(!include_base || base); /* Can't include NULL base */
assert_bdrv_graph_readable();
if (!depth) {
depth = &dummy;
@ -2836,6 +2842,7 @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
int ret = 0;
IO_CODE();
assert_bdrv_graph_readable();
bdrv_inc_in_flight(bs);
if (!bdrv_co_is_inserted(bs) || bdrv_is_read_only(bs) ||
@ -2961,6 +2968,7 @@ int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset,
int head, tail, align;
BlockDriverState *bs = child->bs;
IO_CODE();
assert_bdrv_graph_readable();
if (!bs || !bs->drv || !bdrv_co_is_inserted(bs)) {
return -ENOMEDIUM;
@ -3080,6 +3088,7 @@ int coroutine_fn bdrv_co_ioctl(BlockDriverState *bs, int req, void *buf)
};
BlockAIOCB *acb;
IO_CODE();
assert_bdrv_graph_readable();
bdrv_inc_in_flight(bs);
if (!drv || (!drv->bdrv_aio_ioctl && !drv->bdrv_co_ioctl)) {
@ -3144,6 +3153,7 @@ void coroutine_fn bdrv_co_io_plug(BlockDriverState *bs)
{
BdrvChild *child;
IO_CODE();
assert_bdrv_graph_readable();
QLIST_FOREACH(child, &bs->children, next) {
bdrv_co_io_plug(child->bs);
@ -3161,6 +3171,7 @@ void coroutine_fn bdrv_co_io_unplug(BlockDriverState *bs)
{
BdrvChild *child;
IO_CODE();
assert_bdrv_graph_readable();
assert(bs->io_plugged);
if (qatomic_fetch_dec(&bs->io_plugged) == 1) {
@ -3176,13 +3187,15 @@ void coroutine_fn bdrv_co_io_unplug(BlockDriverState *bs)
}
/* Helper that undoes bdrv_register_buf() when it fails partway through */
static void bdrv_register_buf_rollback(BlockDriverState *bs,
void *host,
size_t size,
BdrvChild *final_child)
static void GRAPH_RDLOCK
bdrv_register_buf_rollback(BlockDriverState *bs, void *host, size_t size,
BdrvChild *final_child)
{
BdrvChild *child;
GLOBAL_STATE_CODE();
assert_bdrv_graph_readable();
QLIST_FOREACH(child, &bs->children, next) {
if (child == final_child) {
break;
@ -3202,6 +3215,8 @@ bool bdrv_register_buf(BlockDriverState *bs, void *host, size_t size,
BdrvChild *child;
GLOBAL_STATE_CODE();
GRAPH_RDLOCK_GUARD_MAINLOOP();
if (bs->drv && bs->drv->bdrv_register_buf) {
if (!bs->drv->bdrv_register_buf(bs, host, size, errp)) {
return false;
@ -3221,6 +3236,8 @@ void bdrv_unregister_buf(BlockDriverState *bs, void *host, size_t size)
BdrvChild *child;
GLOBAL_STATE_CODE();
GRAPH_RDLOCK_GUARD_MAINLOOP();
if (bs->drv && bs->drv->bdrv_unregister_buf) {
bs->drv->bdrv_unregister_buf(bs, host, size);
}
@ -3229,7 +3246,7 @@ void bdrv_unregister_buf(BlockDriverState *bs, void *host, size_t size)
}
}
static int coroutine_fn bdrv_co_copy_range_internal(
static int coroutine_fn GRAPH_RDLOCK bdrv_co_copy_range_internal(
BdrvChild *src, int64_t src_offset, BdrvChild *dst,
int64_t dst_offset, int64_t bytes,
BdrvRequestFlags read_flags, BdrvRequestFlags write_flags,
@ -3237,6 +3254,7 @@ static int coroutine_fn bdrv_co_copy_range_internal(
{
BdrvTrackedRequest req;
int ret;
assert_bdrv_graph_readable();
/* TODO We can support BDRV_REQ_NO_FALLBACK here */
assert(!(read_flags & BDRV_REQ_NO_FALLBACK));
@ -3318,6 +3336,7 @@ int coroutine_fn bdrv_co_copy_range_from(BdrvChild *src, int64_t src_offset,
BdrvRequestFlags write_flags)
{
IO_CODE();
assert_bdrv_graph_readable();
trace_bdrv_co_copy_range_from(src, src_offset, dst, dst_offset, bytes,
read_flags, write_flags);
return bdrv_co_copy_range_internal(src, src_offset, dst, dst_offset,
@ -3335,6 +3354,7 @@ int coroutine_fn bdrv_co_copy_range_to(BdrvChild *src, int64_t src_offset,
BdrvRequestFlags write_flags)
{
IO_CODE();
assert_bdrv_graph_readable();
trace_bdrv_co_copy_range_to(src, src_offset, dst, dst_offset, bytes,
read_flags, write_flags);
return bdrv_co_copy_range_internal(src, src_offset, dst, dst_offset,
@ -3347,6 +3367,8 @@ int coroutine_fn bdrv_co_copy_range(BdrvChild *src, int64_t src_offset,
BdrvRequestFlags write_flags)
{
IO_CODE();
assert_bdrv_graph_readable();
return bdrv_co_copy_range_from(src, src_offset,
dst, dst_offset,
bytes, read_flags, write_flags);
@ -3380,6 +3402,7 @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
int64_t old_size, new_bytes;
int ret;
IO_CODE();
assert_bdrv_graph_readable();
/* if bs->drv == NULL, bs is closed, so there's nothing to do here */
if (!drv) {
@ -3517,6 +3540,7 @@ bdrv_co_preadv_snapshot(BdrvChild *child, int64_t offset, int64_t bytes,
BlockDriver *drv = bs->drv;
int ret;
IO_CODE();
assert_bdrv_graph_readable();
if (!drv) {
return -ENOMEDIUM;
@ -3542,6 +3566,7 @@ bdrv_co_snapshot_block_status(BlockDriverState *bs,
BlockDriver *drv = bs->drv;
int ret;
IO_CODE();
assert_bdrv_graph_readable();
if (!drv) {
return -ENOMEDIUM;
@ -3565,6 +3590,7 @@ bdrv_co_pdiscard_snapshot(BlockDriverState *bs, int64_t offset, int64_t bytes)
BlockDriver *drv = bs->drv;
int ret;
IO_CODE();
assert_bdrv_graph_readable();
if (!drv) {
return -ENOMEDIUM;

View File

@ -2190,14 +2190,12 @@ static void coroutine_fn iscsi_co_invalidate_cache(BlockDriverState *bs,
iscsi_allocmap_invalidate(iscsilun);
}
static int coroutine_fn iscsi_co_copy_range_from(BlockDriverState *bs,
BdrvChild *src,
int64_t src_offset,
BdrvChild *dst,
int64_t dst_offset,
int64_t bytes,
BdrvRequestFlags read_flags,
BdrvRequestFlags write_flags)
static int coroutine_fn GRAPH_RDLOCK
iscsi_co_copy_range_from(BlockDriverState *bs,
BdrvChild *src, int64_t src_offset,
BdrvChild *dst, int64_t dst_offset,
int64_t bytes, BdrvRequestFlags read_flags,
BdrvRequestFlags write_flags)
{
return bdrv_co_copy_range_to(src, src_offset, dst, dst_offset, bytes,
read_flags, write_flags);
@ -2331,14 +2329,12 @@ static void iscsi_xcopy_data(struct iscsi_data *data,
src_lba, dst_lba);
}
static int coroutine_fn iscsi_co_copy_range_to(BlockDriverState *bs,
BdrvChild *src,
int64_t src_offset,
BdrvChild *dst,
int64_t dst_offset,
int64_t bytes,
BdrvRequestFlags read_flags,
BdrvRequestFlags write_flags)
static int coroutine_fn GRAPH_RDLOCK
iscsi_co_copy_range_to(BlockDriverState *bs,
BdrvChild *src, int64_t src_offset,
BdrvChild *dst, int64_t dst_offset,
int64_t bytes, BdrvRequestFlags read_flags,
BdrvRequestFlags write_flags)
{
IscsiLun *dst_lun = dst->bs->opaque;
IscsiLun *src_lun;

View File

@ -21,7 +21,6 @@
#include "block/dirty-bitmap.h"
#include "sysemu/block-backend.h"
#include "qapi/error.h"
#include "qapi/qmp/qerror.h"
#include "qemu/ratelimit.h"
#include "qemu/bitmap.h"
#include "qemu/memalign.h"
@ -390,8 +389,10 @@ static void coroutine_fn mirror_co_read(void *opaque)
op->is_in_flight = true;
trace_mirror_one_iteration(s, op->offset, op->bytes);
ret = bdrv_co_preadv(s->mirror_top_bs->backing, op->offset, op->bytes,
&op->qiov, 0);
WITH_GRAPH_RDLOCK_GUARD() {
ret = bdrv_co_preadv(s->mirror_top_bs->backing, op->offset, op->bytes,
&op->qiov, 0);
}
mirror_read_complete(op, ret);
}
@ -558,9 +559,11 @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
MirrorMethod mirror_method = MIRROR_METHOD_COPY;
assert(!(offset % s->granularity));
ret = bdrv_block_status_above(source, NULL, offset,
nb_chunks * s->granularity,
&io_bytes, NULL, NULL);
WITH_GRAPH_RDLOCK_GUARD() {
ret = bdrv_block_status_above(source, NULL, offset,
nb_chunks * s->granularity,
&io_bytes, NULL, NULL);
}
if (ret < 0) {
io_bytes = MIN(nb_chunks * s->granularity, max_io_bytes);
} else if (ret & BDRV_BLOCK_DATA) {
@ -863,8 +866,10 @@ static int coroutine_fn mirror_dirty_init(MirrorBlockJob *s)
return 0;
}
ret = bdrv_is_allocated_above(bs, s->base_overlay, true, offset, bytes,
&count);
WITH_GRAPH_RDLOCK_GUARD() {
ret = bdrv_is_allocated_above(bs, s->base_overlay, true, offset,
bytes, &count);
}
if (ret < 0) {
return ret;
}
@ -896,6 +901,7 @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
{
MirrorBlockJob *s = container_of(job, MirrorBlockJob, common.job);
BlockDriverState *bs = s->mirror_top_bs->backing->bs;
MirrorBDSOpaque *mirror_top_opaque = s->mirror_top_bs->opaque;
BlockDriverState *target_bs = blk_bs(s->target);
bool need_drain = true;
BlockDeviceIoStatus iostatus;
@ -910,7 +916,10 @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
goto immediate_exit;
}
bdrv_graph_co_rdlock();
s->bdev_length = bdrv_co_getlength(bs);
bdrv_graph_co_rdunlock();
if (s->bdev_length < 0) {
ret = s->bdev_length;
goto immediate_exit;
@ -985,6 +994,12 @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
}
}
/*
* Only now the job is fully initialised and mirror_top_bs should start
* accessing it.
*/
mirror_top_opaque->job = s;
assert(!s->dbi);
s->dbi = bdrv_dirty_iter_new(s->dirty_bitmap);
for (;;) {
@ -1426,15 +1441,17 @@ static void coroutine_fn active_write_settle(MirrorOp *op)
g_free(op);
}
static int coroutine_fn bdrv_mirror_top_preadv(BlockDriverState *bs,
int64_t offset, int64_t bytes, QEMUIOVector *qiov, BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
bdrv_mirror_top_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{
return bdrv_co_preadv(bs->backing, offset, bytes, qiov, flags);
}
static int coroutine_fn bdrv_mirror_top_do_write(BlockDriverState *bs,
MirrorMethod method, uint64_t offset, uint64_t bytes, QEMUIOVector *qiov,
int flags)
static int coroutine_fn GRAPH_RDLOCK
bdrv_mirror_top_do_write(BlockDriverState *bs, MirrorMethod method,
uint64_t offset, uint64_t bytes, QEMUIOVector *qiov,
int flags)
{
MirrorOp *op = NULL;
MirrorBDSOpaque *s = bs->opaque;
@ -1483,8 +1500,9 @@ out:
return ret;
}
static int coroutine_fn bdrv_mirror_top_pwritev(BlockDriverState *bs,
int64_t offset, int64_t bytes, QEMUIOVector *qiov, BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
bdrv_mirror_top_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{
MirrorBDSOpaque *s = bs->opaque;
QEMUIOVector bounce_qiov;
@ -1524,7 +1542,7 @@ static int coroutine_fn bdrv_mirror_top_pwritev(BlockDriverState *bs,
return ret;
}
static int coroutine_fn bdrv_mirror_top_flush(BlockDriverState *bs)
static int coroutine_fn GRAPH_RDLOCK bdrv_mirror_top_flush(BlockDriverState *bs)
{
if (bs->backing == NULL) {
/* we can be here after failed bdrv_append in mirror_start_job */
@ -1533,15 +1551,16 @@ static int coroutine_fn bdrv_mirror_top_flush(BlockDriverState *bs)
return bdrv_co_flush(bs->backing->bs);
}
static int coroutine_fn bdrv_mirror_top_pwrite_zeroes(BlockDriverState *bs,
int64_t offset, int64_t bytes, BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
bdrv_mirror_top_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
int64_t bytes, BdrvRequestFlags flags)
{
return bdrv_mirror_top_do_write(bs, MIRROR_METHOD_ZERO, offset, bytes, NULL,
flags);
}
static int coroutine_fn bdrv_mirror_top_pdiscard(BlockDriverState *bs,
int64_t offset, int64_t bytes)
static int coroutine_fn GRAPH_RDLOCK
bdrv_mirror_top_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
{
return bdrv_mirror_top_do_write(bs, MIRROR_METHOD_DISCARD, offset, bytes,
NULL, 0);
@ -1704,7 +1723,6 @@ static BlockJob *mirror_start_job(
if (!s) {
goto fail;
}
bs_opaque->job = s;
/* The block job now has a reference to this node */
bdrv_unref(mirror_top_bs);

View File

@ -165,9 +165,9 @@ static int64_t block_status(BDRVParallelsState *s, int64_t sector_num,
return start_off;
}
static coroutine_fn int64_t allocate_clusters(BlockDriverState *bs,
int64_t sector_num,
int nb_sectors, int *pnum)
static int64_t coroutine_fn GRAPH_RDLOCK
allocate_clusters(BlockDriverState *bs, int64_t sector_num,
int nb_sectors, int *pnum)
{
int ret = 0;
BDRVParallelsState *s = bs->opaque;
@ -261,7 +261,8 @@ static coroutine_fn int64_t allocate_clusters(BlockDriverState *bs,
}
static coroutine_fn int parallels_co_flush_to_os(BlockDriverState *bs)
static int coroutine_fn GRAPH_RDLOCK
parallels_co_flush_to_os(BlockDriverState *bs)
{
BDRVParallelsState *s = bs->opaque;
unsigned long size = DIV_ROUND_UP(s->header_size, s->bat_dirty_block);
@ -320,9 +321,9 @@ static int coroutine_fn parallels_co_block_status(BlockDriverState *bs,
return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID;
}
static coroutine_fn int parallels_co_writev(BlockDriverState *bs,
int64_t sector_num, int nb_sectors,
QEMUIOVector *qiov, int flags)
static int coroutine_fn GRAPH_RDLOCK
parallels_co_writev(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
QEMUIOVector *qiov, int flags)
{
BDRVParallelsState *s = bs->opaque;
uint64_t bytes_done = 0;
@ -363,8 +364,9 @@ static coroutine_fn int parallels_co_writev(BlockDriverState *bs,
return ret;
}
static coroutine_fn int parallels_co_readv(BlockDriverState *bs,
int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
static int coroutine_fn GRAPH_RDLOCK
parallels_co_readv(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
QEMUIOVector *qiov)
{
BDRVParallelsState *s = bs->opaque;
uint64_t bytes_done = 0;
@ -414,9 +416,9 @@ static coroutine_fn int parallels_co_readv(BlockDriverState *bs,
}
static int coroutine_fn parallels_co_check(BlockDriverState *bs,
BdrvCheckResult *res,
BdrvCheckMode fix)
static int coroutine_fn GRAPH_RDLOCK
parallels_co_check(BlockDriverState *bs, BdrvCheckResult *res,
BdrvCheckMode fix)
{
BDRVParallelsState *s = bs->opaque;
int64_t size, prev_off, high_off;
@ -620,10 +622,9 @@ exit:
goto out;
}
static int coroutine_fn parallels_co_create_opts(BlockDriver *drv,
const char *filename,
QemuOpts *opts,
Error **errp)
static int coroutine_fn GRAPH_RDLOCK
parallels_co_create_opts(BlockDriver *drv, const char *filename,
QemuOpts *opts, Error **errp)
{
BlockdevCreateOptions *create_options = NULL;
BlockDriverState *bs = NULL;

View File

@ -226,16 +226,17 @@ static void preallocate_reopen_abort(BDRVReopenState *state)
state->opaque = NULL;
}
static coroutine_fn int preallocate_co_preadv_part(
BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, size_t qiov_offset, BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
preallocate_co_preadv_part(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, size_t qiov_offset,
BdrvRequestFlags flags)
{
return bdrv_co_preadv_part(bs->file, offset, bytes, qiov, qiov_offset,
flags);
}
static int coroutine_fn preallocate_co_pdiscard(BlockDriverState *bs,
int64_t offset, int64_t bytes)
static int coroutine_fn GRAPH_RDLOCK
preallocate_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
{
return bdrv_co_pdiscard(bs->file, offset, bytes);
}
@ -269,8 +270,9 @@ static bool has_prealloc_perms(BlockDriverState *bs)
* want_merge_zero is used to merge write-zero request with preallocation in
* one bdrv_co_pwrite_zeroes() call.
*/
static bool coroutine_fn handle_write(BlockDriverState *bs, int64_t offset,
int64_t bytes, bool want_merge_zero)
static bool coroutine_fn GRAPH_RDLOCK
handle_write(BlockDriverState *bs, int64_t offset, int64_t bytes,
bool want_merge_zero)
{
BDRVPreallocateState *s = bs->opaque;
int64_t end = offset + bytes;
@ -345,8 +347,9 @@ static bool coroutine_fn handle_write(BlockDriverState *bs, int64_t offset,
return want_merge_zero;
}
static int coroutine_fn preallocate_co_pwrite_zeroes(BlockDriverState *bs,
int64_t offset, int64_t bytes, BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
preallocate_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
int64_t bytes, BdrvRequestFlags flags)
{
bool want_merge_zero =
!(flags & ~(BDRV_REQ_ZERO_WRITE | BDRV_REQ_NO_FALLBACK));
@ -357,12 +360,10 @@ static int coroutine_fn preallocate_co_pwrite_zeroes(BlockDriverState *bs,
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
}
static coroutine_fn int preallocate_co_pwritev_part(BlockDriverState *bs,
int64_t offset,
int64_t bytes,
QEMUIOVector *qiov,
size_t qiov_offset,
BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
preallocate_co_pwritev_part(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, size_t qiov_offset,
BdrvRequestFlags flags)
{
handle_write(bs, offset, bytes, false);
@ -370,7 +371,7 @@ static coroutine_fn int preallocate_co_pwritev_part(BlockDriverState *bs,
flags);
}
static int coroutine_fn
static int coroutine_fn GRAPH_RDLOCK
preallocate_co_truncate(BlockDriverState *bs, int64_t offset,
bool exact, PreallocMode prealloc,
BdrvRequestFlags flags, Error **errp)
@ -437,12 +438,13 @@ preallocate_co_truncate(BlockDriverState *bs, int64_t offset,
return 0;
}
static int coroutine_fn preallocate_co_flush(BlockDriverState *bs)
static int coroutine_fn GRAPH_RDLOCK preallocate_co_flush(BlockDriverState *bs)
{
return bdrv_co_flush(bs->file->bs);
}
static int64_t coroutine_fn preallocate_co_getlength(BlockDriverState *bs)
static int64_t coroutine_fn GRAPH_RDLOCK
preallocate_co_getlength(BlockDriverState *bs)
{
int64_t ret;
BDRVPreallocateState *s = bs->opaque;

View File

@ -92,8 +92,8 @@ typedef struct BDRVQcowState {
static QemuOptsList qcow_create_opts;
static int coroutine_fn decompress_cluster(BlockDriverState *bs,
uint64_t cluster_offset);
static int coroutine_fn GRAPH_RDLOCK
decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset);
static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename)
{
@ -350,11 +350,10 @@ static int qcow_reopen_prepare(BDRVReopenState *state,
* return 0 if not allocated, 1 if *result is assigned, and negative
* errno on failure.
*/
static int coroutine_fn get_cluster_offset(BlockDriverState *bs,
uint64_t offset, int allocate,
int compressed_size,
int n_start, int n_end,
uint64_t *result)
static int coroutine_fn GRAPH_RDLOCK
get_cluster_offset(BlockDriverState *bs, uint64_t offset, int allocate,
int compressed_size, int n_start, int n_end,
uint64_t *result)
{
BDRVQcowState *s = bs->opaque;
int min_index, i, j, l1_index, l2_index, ret;
@ -525,11 +524,10 @@ static int coroutine_fn get_cluster_offset(BlockDriverState *bs,
return 1;
}
static int coroutine_fn qcow_co_block_status(BlockDriverState *bs,
bool want_zero,
int64_t offset, int64_t bytes,
int64_t *pnum, int64_t *map,
BlockDriverState **file)
static int coroutine_fn GRAPH_RDLOCK
qcow_co_block_status(BlockDriverState *bs, bool want_zero,
int64_t offset, int64_t bytes, int64_t *pnum,
int64_t *map, BlockDriverState **file)
{
BDRVQcowState *s = bs->opaque;
int index_in_cluster, ret;
@ -586,8 +584,8 @@ static int decompress_buffer(uint8_t *out_buf, int out_buf_size,
return 0;
}
static int coroutine_fn decompress_cluster(BlockDriverState *bs,
uint64_t cluster_offset)
static int coroutine_fn GRAPH_RDLOCK
decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset)
{
BDRVQcowState *s = bs->opaque;
int ret, csize;
@ -619,9 +617,9 @@ static void qcow_refresh_limits(BlockDriverState *bs, Error **errp)
bs->bl.request_alignment = BDRV_SECTOR_SIZE;
}
static coroutine_fn int qcow_co_preadv(BlockDriverState *bs, int64_t offset,
int64_t bytes, QEMUIOVector *qiov,
BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
qcow_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{
BDRVQcowState *s = bs->opaque;
int offset_in_cluster;
@ -715,9 +713,9 @@ static coroutine_fn int qcow_co_preadv(BlockDriverState *bs, int64_t offset,
return ret;
}
static coroutine_fn int qcow_co_pwritev(BlockDriverState *bs, int64_t offset,
int64_t bytes, QEMUIOVector *qiov,
BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
qcow_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{
BDRVQcowState *s = bs->opaque;
int offset_in_cluster;
@ -923,9 +921,9 @@ exit:
return ret;
}
static int coroutine_fn qcow_co_create_opts(BlockDriver *drv,
const char *filename,
QemuOpts *opts, Error **errp)
static int coroutine_fn GRAPH_RDLOCK
qcow_co_create_opts(BlockDriver *drv, const char *filename,
QemuOpts *opts, Error **errp)
{
BlockdevCreateOptions *create_options = NULL;
BlockDriverState *bs = NULL;
@ -1046,7 +1044,7 @@ static int qcow_make_empty(BlockDriverState *bs)
/* XXX: put compressed sectors first, then all the cluster aligned
tables to avoid losing bytes in alignment */
static coroutine_fn int
static int coroutine_fn GRAPH_RDLOCK
qcow_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov)
{

View File

@ -491,10 +491,9 @@ static int count_contiguous_subclusters(BlockDriverState *bs, int nb_clusters,
return count;
}
static int coroutine_fn do_perform_cow_read(BlockDriverState *bs,
uint64_t src_cluster_offset,
unsigned offset_in_cluster,
QEMUIOVector *qiov)
static int coroutine_fn GRAPH_RDLOCK
do_perform_cow_read(BlockDriverState *bs, uint64_t src_cluster_offset,
unsigned offset_in_cluster, QEMUIOVector *qiov)
{
int ret;
@ -535,10 +534,9 @@ static int coroutine_fn do_perform_cow_read(BlockDriverState *bs,
return 0;
}
static int coroutine_fn do_perform_cow_write(BlockDriverState *bs,
uint64_t cluster_offset,
unsigned offset_in_cluster,
QEMUIOVector *qiov)
static int coroutine_fn GRAPH_RDLOCK
do_perform_cow_write(BlockDriverState *bs, uint64_t cluster_offset,
unsigned offset_in_cluster, QEMUIOVector *qiov)
{
BDRVQcow2State *s = bs->opaque;
int ret;
@ -886,7 +884,8 @@ int coroutine_fn qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
return 0;
}
static int coroutine_fn perform_cow(BlockDriverState *bs, QCowL2Meta *m)
static int coroutine_fn GRAPH_RDLOCK
perform_cow(BlockDriverState *bs, QCowL2Meta *m)
{
BDRVQcow2State *s = bs->opaque;
Qcow2COWRegion *start = &m->cow_start;

View File

@ -601,9 +601,9 @@ static void qcow2_add_check_result(BdrvCheckResult *out,
}
}
static int coroutine_fn qcow2_co_check_locked(BlockDriverState *bs,
BdrvCheckResult *result,
BdrvCheckMode fix)
static int coroutine_fn GRAPH_RDLOCK
qcow2_co_check_locked(BlockDriverState *bs, BdrvCheckResult *result,
BdrvCheckMode fix)
{
BdrvCheckResult snapshot_res = {};
BdrvCheckResult refcount_res = {};
@ -640,9 +640,9 @@ static int coroutine_fn qcow2_co_check_locked(BlockDriverState *bs,
return ret;
}
static int coroutine_fn qcow2_co_check(BlockDriverState *bs,
BdrvCheckResult *result,
BdrvCheckMode fix)
static int coroutine_fn GRAPH_RDLOCK
qcow2_co_check(BlockDriverState *bs, BdrvCheckResult *result,
BdrvCheckMode fix)
{
BDRVQcow2State *s = bs->opaque;
int ret;
@ -1294,9 +1294,9 @@ static int validate_compression_type(BDRVQcow2State *s, Error **errp)
}
/* Called with s->lock held. */
static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
int flags, bool open_data_file,
Error **errp)
static int coroutine_fn GRAPH_RDLOCK
qcow2_do_open(BlockDriverState *bs, QDict *options, int flags,
bool open_data_file, Error **errp)
{
ERRP_GUARD();
BDRVQcow2State *s = bs->opaque;
@ -1890,6 +1890,8 @@ static void coroutine_fn qcow2_open_entry(void *opaque)
QCow2OpenCo *qoc = opaque;
BDRVQcow2State *s = qoc->bs->opaque;
assume_graph_lock(); /* FIXME */
qemu_co_mutex_lock(&s->lock);
qoc->ret = qcow2_do_open(qoc->bs, qoc->options, qoc->flags, true,
qoc->errp);
@ -2137,9 +2139,8 @@ static int coroutine_fn qcow2_co_block_status(BlockDriverState *bs,
return status;
}
static coroutine_fn int qcow2_handle_l2meta(BlockDriverState *bs,
QCowL2Meta **pl2meta,
bool link_l2)
static int coroutine_fn GRAPH_RDLOCK
qcow2_handle_l2meta(BlockDriverState *bs, QCowL2Meta **pl2meta, bool link_l2)
{
int ret = 0;
QCowL2Meta *l2meta = *pl2meta;
@ -2170,7 +2171,7 @@ out:
return ret;
}
static coroutine_fn int
static int coroutine_fn GRAPH_RDLOCK
qcow2_co_preadv_encrypted(BlockDriverState *bs,
uint64_t host_offset,
uint64_t offset,
@ -2271,12 +2272,10 @@ static coroutine_fn int qcow2_add_task(BlockDriverState *bs,
return 0;
}
static coroutine_fn int qcow2_co_preadv_task(BlockDriverState *bs,
QCow2SubclusterType subc_type,
uint64_t host_offset,
uint64_t offset, uint64_t bytes,
QEMUIOVector *qiov,
size_t qiov_offset)
static int coroutine_fn GRAPH_RDLOCK
qcow2_co_preadv_task(BlockDriverState *bs, QCow2SubclusterType subc_type,
uint64_t host_offset, uint64_t offset, uint64_t bytes,
QEMUIOVector *qiov, size_t qiov_offset)
{
BDRVQcow2State *s = bs->opaque;
@ -2315,7 +2314,11 @@ static coroutine_fn int qcow2_co_preadv_task(BlockDriverState *bs,
g_assert_not_reached();
}
static coroutine_fn int qcow2_co_preadv_task_entry(AioTask *task)
/*
* This function can count as GRAPH_RDLOCK because qcow2_co_preadv_part() holds
* the graph lock and keeps it until this coroutine has terminated.
*/
static int coroutine_fn GRAPH_RDLOCK qcow2_co_preadv_task_entry(AioTask *task)
{
Qcow2AioTask *t = container_of(task, Qcow2AioTask, task);
@ -2326,11 +2329,10 @@ static coroutine_fn int qcow2_co_preadv_task_entry(AioTask *task)
t->qiov, t->qiov_offset);
}
static coroutine_fn int qcow2_co_preadv_part(BlockDriverState *bs,
int64_t offset, int64_t bytes,
QEMUIOVector *qiov,
size_t qiov_offset,
BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
qcow2_co_preadv_part(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, size_t qiov_offset,
BdrvRequestFlags flags)
{
BDRVQcow2State *s = bs->opaque;
int ret = 0;
@ -2450,7 +2452,8 @@ static bool merge_cow(uint64_t offset, unsigned bytes,
* Return 1 if the COW regions read as zeroes, 0 if not, < 0 on error.
* Note that returning 0 does not guarantee non-zero data.
*/
static int coroutine_fn is_zero_cow(BlockDriverState *bs, QCowL2Meta *m)
static int coroutine_fn GRAPH_RDLOCK
is_zero_cow(BlockDriverState *bs, QCowL2Meta *m)
{
/*
* This check is designed for optimization shortcut so it must be
@ -2468,8 +2471,8 @@ static int coroutine_fn is_zero_cow(BlockDriverState *bs, QCowL2Meta *m)
m->cow_end.nb_bytes);
}
static int coroutine_fn handle_alloc_space(BlockDriverState *bs,
QCowL2Meta *l2meta)
static int coroutine_fn GRAPH_RDLOCK
handle_alloc_space(BlockDriverState *bs, QCowL2Meta *l2meta)
{
BDRVQcow2State *s = bs->opaque;
QCowL2Meta *m;
@ -2532,12 +2535,10 @@ static int coroutine_fn handle_alloc_space(BlockDriverState *bs,
* l2meta - if not NULL, qcow2_co_pwritev_task() will consume it. Caller must
* not use it somehow after qcow2_co_pwritev_task() call
*/
static coroutine_fn int qcow2_co_pwritev_task(BlockDriverState *bs,
uint64_t host_offset,
uint64_t offset, uint64_t bytes,
QEMUIOVector *qiov,
uint64_t qiov_offset,
QCowL2Meta *l2meta)
static coroutine_fn GRAPH_RDLOCK
int qcow2_co_pwritev_task(BlockDriverState *bs, uint64_t host_offset,
uint64_t offset, uint64_t bytes, QEMUIOVector *qiov,
uint64_t qiov_offset, QCowL2Meta *l2meta)
{
int ret;
BDRVQcow2State *s = bs->opaque;
@ -2603,7 +2604,11 @@ out_locked:
return ret;
}
static coroutine_fn int qcow2_co_pwritev_task_entry(AioTask *task)
/*
* This function can count as GRAPH_RDLOCK because qcow2_co_pwritev_part() holds
* the graph lock and keeps it until this coroutine has terminated.
*/
static coroutine_fn GRAPH_RDLOCK int qcow2_co_pwritev_task_entry(AioTask *task)
{
Qcow2AioTask *t = container_of(task, Qcow2AioTask, task);
@ -2614,9 +2619,10 @@ static coroutine_fn int qcow2_co_pwritev_task_entry(AioTask *task)
t->l2meta);
}
static coroutine_fn int qcow2_co_pwritev_part(
BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, size_t qiov_offset, BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
qcow2_co_pwritev_part(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, size_t qiov_offset,
BdrvRequestFlags flags)
{
BDRVQcow2State *s = bs->opaque;
int offset_in_cluster;
@ -2771,8 +2777,8 @@ static void qcow2_close(BlockDriverState *bs)
qcow2_do_close(bs, true);
}
static void coroutine_fn qcow2_co_invalidate_cache(BlockDriverState *bs,
Error **errp)
static void coroutine_fn GRAPH_RDLOCK
qcow2_co_invalidate_cache(BlockDriverState *bs, Error **errp)
{
ERRP_GUARD();
BDRVQcow2State *s = bs->opaque;
@ -3183,9 +3189,9 @@ static int qcow2_set_up_encryption(BlockDriverState *bs,
*
* Returns: 0 on success, -errno on failure.
*/
static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset,
uint64_t new_length, PreallocMode mode,
Error **errp)
static int coroutine_fn GRAPH_RDLOCK
preallocate_co(BlockDriverState *bs, uint64_t offset, uint64_t new_length,
PreallocMode mode, Error **errp)
{
BDRVQcow2State *s = bs->opaque;
uint64_t bytes;
@ -3810,10 +3816,9 @@ out:
return ret;
}
static int coroutine_fn qcow2_co_create_opts(BlockDriver *drv,
const char *filename,
QemuOpts *opts,
Error **errp)
static int coroutine_fn GRAPH_RDLOCK
qcow2_co_create_opts(BlockDriver *drv, const char *filename, QemuOpts *opts,
Error **errp)
{
BlockdevCreateOptions *create_options = NULL;
QDict *qdict;
@ -3974,8 +3979,9 @@ static bool is_zero(BlockDriverState *bs, int64_t offset, int64_t bytes)
return res >= 0 && (res & BDRV_BLOCK_ZERO) && bytes == 0;
}
static coroutine_fn int qcow2_co_pwrite_zeroes(BlockDriverState *bs,
int64_t offset, int64_t bytes, BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
qcow2_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
BdrvRequestFlags flags)
{
int ret;
BDRVQcow2State *s = bs->opaque;
@ -4058,7 +4064,7 @@ static coroutine_fn int qcow2_co_pdiscard(BlockDriverState *bs,
return ret;
}
static int coroutine_fn
static int coroutine_fn GRAPH_RDLOCK
qcow2_co_copy_range_from(BlockDriverState *bs,
BdrvChild *src, int64_t src_offset,
BdrvChild *dst, int64_t dst_offset,
@ -4141,7 +4147,7 @@ out:
return ret;
}
static int coroutine_fn
static int coroutine_fn GRAPH_RDLOCK
qcow2_co_copy_range_to(BlockDriverState *bs,
BdrvChild *src, int64_t src_offset,
BdrvChild *dst, int64_t dst_offset,
@ -4209,9 +4215,9 @@ fail:
return ret;
}
static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
bool exact, PreallocMode prealloc,
BdrvRequestFlags flags, Error **errp)
static int coroutine_fn GRAPH_RDLOCK
qcow2_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
PreallocMode prealloc, BdrvRequestFlags flags, Error **errp)
{
BDRVQcow2State *s = bs->opaque;
uint64_t old_length;
@ -4585,7 +4591,7 @@ fail:
return ret;
}
static coroutine_fn int
static int coroutine_fn GRAPH_RDLOCK
qcow2_co_pwritev_compressed_task(BlockDriverState *bs,
uint64_t offset, uint64_t bytes,
QEMUIOVector *qiov, size_t qiov_offset)
@ -4649,7 +4655,13 @@ fail:
return ret;
}
static coroutine_fn int qcow2_co_pwritev_compressed_task_entry(AioTask *task)
/*
* This function can count as GRAPH_RDLOCK because
* qcow2_co_pwritev_compressed_part() holds the graph lock and keeps it until
* this coroutine has terminated.
*/
static int coroutine_fn GRAPH_RDLOCK
qcow2_co_pwritev_compressed_task_entry(AioTask *task)
{
Qcow2AioTask *t = container_of(task, Qcow2AioTask, task);
@ -4663,7 +4675,7 @@ static coroutine_fn int qcow2_co_pwritev_compressed_task_entry(AioTask *task)
* XXX: put compressed sectors first, then all the cluster aligned
* tables to avoid losing bytes in alignment
*/
static coroutine_fn int
static int coroutine_fn GRAPH_RDLOCK
qcow2_co_pwritev_compressed_part(BlockDriverState *bs,
int64_t offset, int64_t bytes,
QEMUIOVector *qiov, size_t qiov_offset)
@ -4726,7 +4738,7 @@ qcow2_co_pwritev_compressed_part(BlockDriverState *bs,
return ret;
}
static int coroutine_fn
static int coroutine_fn GRAPH_RDLOCK
qcow2_co_preadv_compressed(BlockDriverState *bs,
uint64_t l2_entry,
uint64_t offset,
@ -5288,8 +5300,8 @@ static int64_t qcow2_check_vmstate_request(BlockDriverState *bs,
return pos;
}
static coroutine_fn int qcow2_co_save_vmstate(BlockDriverState *bs,
QEMUIOVector *qiov, int64_t pos)
static int coroutine_fn GRAPH_RDLOCK
qcow2_co_save_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos)
{
int64_t offset = qcow2_check_vmstate_request(bs, qiov, pos);
if (offset < 0) {
@ -5300,8 +5312,8 @@ static coroutine_fn int qcow2_co_save_vmstate(BlockDriverState *bs,
return bs->drv->bdrv_co_pwritev_part(bs, offset, qiov->size, qiov, 0, 0);
}
static coroutine_fn int qcow2_co_load_vmstate(BlockDriverState *bs,
QEMUIOVector *qiov, int64_t pos)
static int coroutine_fn GRAPH_RDLOCK
qcow2_co_load_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos)
{
int64_t offset = qcow2_check_vmstate_request(bs, qiov, pos);
if (offset < 0) {

View File

@ -846,7 +846,7 @@ int qcow2_validate_table(BlockDriverState *bs, uint64_t offset,
Error **errp);
/* qcow2-refcount.c functions */
int coroutine_fn qcow2_refcount_init(BlockDriverState *bs);
int coroutine_fn GRAPH_RDLOCK qcow2_refcount_init(BlockDriverState *bs);
void qcow2_refcount_close(BlockDriverState *bs);
int qcow2_get_refcount(BlockDriverState *bs, int64_t cluster_index,
@ -893,14 +893,17 @@ int qcow2_inc_refcounts_imrt(BlockDriverState *bs, BdrvCheckResult *res,
int qcow2_change_refcount_order(BlockDriverState *bs, int refcount_order,
BlockDriverAmendStatusCB *status_cb,
void *cb_opaque, Error **errp);
int coroutine_fn qcow2_shrink_reftable(BlockDriverState *bs);
int coroutine_fn GRAPH_RDLOCK qcow2_shrink_reftable(BlockDriverState *bs);
int64_t qcow2_get_last_cluster(BlockDriverState *bs, int64_t size);
int coroutine_fn qcow2_detect_metadata_preallocation(BlockDriverState *bs);
/* qcow2-cluster.c functions */
int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
bool exact_size);
int coroutine_fn qcow2_shrink_l1_table(BlockDriverState *bs, uint64_t max_size);
int coroutine_fn GRAPH_RDLOCK
qcow2_shrink_l1_table(BlockDriverState *bs, uint64_t max_size);
int qcow2_write_l1_entry(BlockDriverState *bs, int l1_index);
int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num,
uint8_t *buf, int nb_sectors, bool enc, Error **errp);
@ -918,14 +921,17 @@ int coroutine_fn qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
void qcow2_parse_compressed_l2_entry(BlockDriverState *bs, uint64_t l2_entry,
uint64_t *coffset, int *csize);
int coroutine_fn qcow2_alloc_cluster_link_l2(BlockDriverState *bs,
QCowL2Meta *m);
int coroutine_fn GRAPH_RDLOCK
qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m);
void qcow2_alloc_cluster_abort(BlockDriverState *bs, QCowL2Meta *m);
int qcow2_cluster_discard(BlockDriverState *bs, uint64_t offset,
uint64_t bytes, enum qcow2_discard_type type,
bool full_discard);
int coroutine_fn qcow2_subcluster_zeroize(BlockDriverState *bs, uint64_t offset,
uint64_t bytes, int flags);
int coroutine_fn GRAPH_RDLOCK
qcow2_subcluster_zeroize(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
int flags);
int qcow2_expand_zero_clusters(BlockDriverState *bs,
BlockDriverAmendStatusCB *status_cb,
@ -948,9 +954,10 @@ void qcow2_free_snapshots(BlockDriverState *bs);
int qcow2_read_snapshots(BlockDriverState *bs, Error **errp);
int qcow2_write_snapshots(BlockDriverState *bs);
int coroutine_fn qcow2_check_read_snapshot_table(BlockDriverState *bs,
BdrvCheckResult *result,
BdrvCheckMode fix);
int coroutine_fn GRAPH_RDLOCK
qcow2_check_read_snapshot_table(BlockDriverState *bs, BdrvCheckResult *result,
BdrvCheckMode fix);
int coroutine_fn qcow2_check_fix_snapshot_table(BlockDriverState *bs,
BdrvCheckResult *result,
BdrvCheckMode fix);

View File

@ -107,7 +107,8 @@ static unsigned int qed_check_l2_table(QEDCheck *check, QEDTable *table)
/**
* Descend tables and check each cluster is referenced once only
*/
static int coroutine_fn qed_check_l1_table(QEDCheck *check, QEDTable *table)
static int coroutine_fn GRAPH_RDLOCK
qed_check_l1_table(QEDCheck *check, QEDTable *table)
{
BDRVQEDState *s = check->s;
unsigned int i, num_invalid_l1 = 0;

View File

@ -21,8 +21,8 @@
#include "qemu/memalign.h"
/* Called with table_lock held. */
static int coroutine_fn qed_read_table(BDRVQEDState *s, uint64_t offset,
QEDTable *table)
static int coroutine_fn GRAPH_RDLOCK
qed_read_table(BDRVQEDState *s, uint64_t offset, QEDTable *table)
{
unsigned int bytes = s->header.cluster_size * s->header.table_size;
@ -63,9 +63,9 @@ out:
*
* Called with table_lock held.
*/
static int coroutine_fn qed_write_table(BDRVQEDState *s, uint64_t offset,
QEDTable *table, unsigned int index,
unsigned int n, bool flush)
static int coroutine_fn GRAPH_RDLOCK
qed_write_table(BDRVQEDState *s, uint64_t offset, QEDTable *table,
unsigned int index, unsigned int n, bool flush)
{
unsigned int sector_mask = BDRV_SECTOR_SIZE / sizeof(uint64_t) - 1;
unsigned int start, end, i;

View File

@ -100,7 +100,7 @@ int qed_write_header_sync(BDRVQEDState *s)
*
* No new allocating reqs can start while this function runs.
*/
static int coroutine_fn qed_write_header(BDRVQEDState *s)
static int coroutine_fn GRAPH_RDLOCK qed_write_header(BDRVQEDState *s)
{
/* We must write full sectors for O_DIRECT but cannot necessarily generate
* the data following the header if an unrecognized compat feature is
@ -282,11 +282,12 @@ static void coroutine_fn qed_unplug_allocating_write_reqs(BDRVQEDState *s)
qemu_co_mutex_unlock(&s->table_lock);
}
static void coroutine_fn qed_need_check_timer(BDRVQEDState *s)
static void coroutine_fn GRAPH_RDLOCK qed_need_check_timer(BDRVQEDState *s)
{
int ret;
trace_qed_need_check_timer_cb(s);
assert_bdrv_graph_readable();
if (!qed_plug_allocating_write_reqs(s)) {
return;
@ -312,6 +313,7 @@ static void coroutine_fn qed_need_check_timer(BDRVQEDState *s)
static void coroutine_fn qed_need_check_timer_entry(void *opaque)
{
BDRVQEDState *s = opaque;
GRAPH_RDLOCK_GUARD();
qed_need_check_timer(opaque);
bdrv_dec_in_flight(s->bs);
@ -393,8 +395,8 @@ static void bdrv_qed_init_state(BlockDriverState *bs)
}
/* Called with table_lock held. */
static int coroutine_fn bdrv_qed_do_open(BlockDriverState *bs, QDict *options,
int flags, Error **errp)
static int coroutine_fn GRAPH_RDLOCK
bdrv_qed_do_open(BlockDriverState *bs, QDict *options, int flags, Error **errp)
{
BDRVQEDState *s = bs->opaque;
QEDHeader le_header;
@ -555,7 +557,7 @@ typedef struct QEDOpenCo {
int ret;
} QEDOpenCo;
static void coroutine_fn bdrv_qed_open_entry(void *opaque)
static void coroutine_fn GRAPH_RDLOCK bdrv_qed_open_entry(void *opaque)
{
QEDOpenCo *qoc = opaque;
BDRVQEDState *s = qoc->bs->opaque;
@ -577,6 +579,8 @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
};
int ret;
assume_graph_lock(); /* FIXME */
ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
if (ret < 0) {
return ret;
@ -750,10 +754,9 @@ out:
return ret;
}
static int coroutine_fn bdrv_qed_co_create_opts(BlockDriver *drv,
const char *filename,
QemuOpts *opts,
Error **errp)
static int coroutine_fn GRAPH_RDLOCK
bdrv_qed_co_create_opts(BlockDriver *drv, const char *filename,
QemuOpts *opts, Error **errp)
{
BlockdevCreateOptions *create_options = NULL;
QDict *qdict;
@ -822,11 +825,10 @@ fail:
return ret;
}
static int coroutine_fn bdrv_qed_co_block_status(BlockDriverState *bs,
bool want_zero,
int64_t pos, int64_t bytes,
int64_t *pnum, int64_t *map,
BlockDriverState **file)
static int coroutine_fn GRAPH_RDLOCK
bdrv_qed_co_block_status(BlockDriverState *bs, bool want_zero, int64_t pos,
int64_t bytes, int64_t *pnum, int64_t *map,
BlockDriverState **file)
{
BDRVQEDState *s = bs->opaque;
size_t len = MIN(bytes, SIZE_MAX);
@ -879,8 +881,8 @@ static BDRVQEDState *acb_to_s(QEDAIOCB *acb)
* This function reads qiov->size bytes starting at pos from the backing file.
* If there is no backing file then zeroes are read.
*/
static int coroutine_fn qed_read_backing_file(BDRVQEDState *s, uint64_t pos,
QEMUIOVector *qiov)
static int coroutine_fn GRAPH_RDLOCK
qed_read_backing_file(BDRVQEDState *s, uint64_t pos, QEMUIOVector *qiov)
{
if (s->bs->backing) {
BLKDBG_EVENT(s->bs->file, BLKDBG_READ_BACKING_AIO);
@ -898,9 +900,9 @@ static int coroutine_fn qed_read_backing_file(BDRVQEDState *s, uint64_t pos,
* @len: Number of bytes
* @offset: Byte offset in image file
*/
static int coroutine_fn qed_copy_from_backing_file(BDRVQEDState *s,
uint64_t pos, uint64_t len,
uint64_t offset)
static int coroutine_fn GRAPH_RDLOCK
qed_copy_from_backing_file(BDRVQEDState *s, uint64_t pos, uint64_t len,
uint64_t offset)
{
QEMUIOVector qiov;
int ret;
@ -993,7 +995,7 @@ static void coroutine_fn qed_aio_complete(QEDAIOCB *acb)
*
* Called with table_lock held.
*/
static int coroutine_fn qed_aio_write_l1_update(QEDAIOCB *acb)
static int coroutine_fn GRAPH_RDLOCK qed_aio_write_l1_update(QEDAIOCB *acb)
{
BDRVQEDState *s = acb_to_s(acb);
CachedL2Table *l2_table = acb->request.l2_table;
@ -1023,7 +1025,8 @@ static int coroutine_fn qed_aio_write_l1_update(QEDAIOCB *acb)
*
* Called with table_lock held.
*/
static int coroutine_fn qed_aio_write_l2_update(QEDAIOCB *acb, uint64_t offset)
static int coroutine_fn GRAPH_RDLOCK
qed_aio_write_l2_update(QEDAIOCB *acb, uint64_t offset)
{
BDRVQEDState *s = acb_to_s(acb);
bool need_alloc = acb->find_cluster_ret == QED_CLUSTER_L1;
@ -1061,7 +1064,7 @@ static int coroutine_fn qed_aio_write_l2_update(QEDAIOCB *acb, uint64_t offset)
*
* Called with table_lock *not* held.
*/
static int coroutine_fn qed_aio_write_main(QEDAIOCB *acb)
static int coroutine_fn GRAPH_RDLOCK qed_aio_write_main(QEDAIOCB *acb)
{
BDRVQEDState *s = acb_to_s(acb);
uint64_t offset = acb->cur_cluster +
@ -1079,7 +1082,7 @@ static int coroutine_fn qed_aio_write_main(QEDAIOCB *acb)
*
* Called with table_lock held.
*/
static int coroutine_fn qed_aio_write_cow(QEDAIOCB *acb)
static int coroutine_fn GRAPH_RDLOCK qed_aio_write_cow(QEDAIOCB *acb)
{
BDRVQEDState *s = acb_to_s(acb);
uint64_t start, len, offset;
@ -1157,7 +1160,8 @@ static bool qed_should_set_need_check(BDRVQEDState *s)
*
* Called with table_lock held.
*/
static int coroutine_fn qed_aio_write_alloc(QEDAIOCB *acb, size_t len)
static int coroutine_fn GRAPH_RDLOCK
qed_aio_write_alloc(QEDAIOCB *acb, size_t len)
{
BDRVQEDState *s = acb_to_s(acb);
int ret;
@ -1220,8 +1224,8 @@ static int coroutine_fn qed_aio_write_alloc(QEDAIOCB *acb, size_t len)
*
* Called with table_lock held.
*/
static int coroutine_fn qed_aio_write_inplace(QEDAIOCB *acb, uint64_t offset,
size_t len)
static int coroutine_fn GRAPH_RDLOCK
qed_aio_write_inplace(QEDAIOCB *acb, uint64_t offset, size_t len)
{
BDRVQEDState *s = acb_to_s(acb);
int r;
@ -1263,8 +1267,8 @@ out:
*
* Called with table_lock held.
*/
static int coroutine_fn qed_aio_write_data(void *opaque, int ret,
uint64_t offset, size_t len)
static int coroutine_fn GRAPH_RDLOCK
qed_aio_write_data(void *opaque, int ret, uint64_t offset, size_t len)
{
QEDAIOCB *acb = opaque;
@ -1296,8 +1300,8 @@ static int coroutine_fn qed_aio_write_data(void *opaque, int ret,
*
* Called with table_lock held.
*/
static int coroutine_fn qed_aio_read_data(void *opaque, int ret,
uint64_t offset, size_t len)
static int coroutine_fn GRAPH_RDLOCK
qed_aio_read_data(void *opaque, int ret, uint64_t offset, size_t len)
{
QEDAIOCB *acb = opaque;
BDRVQEDState *s = acb_to_s(acb);
@ -1334,7 +1338,7 @@ static int coroutine_fn qed_aio_read_data(void *opaque, int ret,
/**
* Begin next I/O or complete the request
*/
static int coroutine_fn qed_aio_next_io(QEDAIOCB *acb)
static int coroutine_fn GRAPH_RDLOCK qed_aio_next_io(QEDAIOCB *acb)
{
BDRVQEDState *s = acb_to_s(acb);
uint64_t offset;
@ -1379,9 +1383,9 @@ static int coroutine_fn qed_aio_next_io(QEDAIOCB *acb)
return ret;
}
static int coroutine_fn qed_co_request(BlockDriverState *bs, int64_t sector_num,
QEMUIOVector *qiov, int nb_sectors,
int flags)
static int coroutine_fn GRAPH_RDLOCK
qed_co_request(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov,
int nb_sectors, int flags)
{
QEDAIOCB acb = {
.bs = bs,
@ -1398,24 +1402,23 @@ static int coroutine_fn qed_co_request(BlockDriverState *bs, int64_t sector_num,
return qed_aio_next_io(&acb);
}
static int coroutine_fn bdrv_qed_co_readv(BlockDriverState *bs,
int64_t sector_num, int nb_sectors,
QEMUIOVector *qiov)
static int coroutine_fn GRAPH_RDLOCK
bdrv_qed_co_readv(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
QEMUIOVector *qiov)
{
return qed_co_request(bs, sector_num, qiov, nb_sectors, 0);
}
static int coroutine_fn bdrv_qed_co_writev(BlockDriverState *bs,
int64_t sector_num, int nb_sectors,
QEMUIOVector *qiov, int flags)
static int coroutine_fn GRAPH_RDLOCK
bdrv_qed_co_writev(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
QEMUIOVector *qiov, int flags)
{
return qed_co_request(bs, sector_num, qiov, nb_sectors, QED_AIOCB_WRITE);
}
static int coroutine_fn bdrv_qed_co_pwrite_zeroes(BlockDriverState *bs,
int64_t offset,
int64_t bytes,
BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
bdrv_qed_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
BdrvRequestFlags flags)
{
BDRVQEDState *s = bs->opaque;
@ -1569,8 +1572,8 @@ static int bdrv_qed_change_backing_file(BlockDriverState *bs,
return ret;
}
static void coroutine_fn bdrv_qed_co_invalidate_cache(BlockDriverState *bs,
Error **errp)
static void coroutine_fn GRAPH_RDLOCK
bdrv_qed_co_invalidate_cache(BlockDriverState *bs, Error **errp)
{
BDRVQEDState *s = bs->opaque;
int ret;
@ -1586,9 +1589,9 @@ static void coroutine_fn bdrv_qed_co_invalidate_cache(BlockDriverState *bs,
}
}
static int coroutine_fn bdrv_qed_co_check(BlockDriverState *bs,
BdrvCheckResult *result,
BdrvCheckMode fix)
static int coroutine_fn GRAPH_RDLOCK
bdrv_qed_co_check(BlockDriverState *bs, BdrvCheckResult *result,
BdrvCheckMode fix)
{
BDRVQEDState *s = bs->opaque;
int ret;

View File

@ -200,33 +200,40 @@ void qed_commit_l2_cache_entry(L2TableCache *l2_cache, CachedL2Table *l2_table);
/**
* Table I/O functions
*/
int coroutine_fn qed_read_l1_table_sync(BDRVQEDState *s);
int coroutine_fn qed_write_l1_table(BDRVQEDState *s, unsigned int index,
unsigned int n);
int coroutine_fn qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index,
unsigned int n);
int coroutine_fn qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
uint64_t offset);
int coroutine_fn qed_read_l2_table(BDRVQEDState *s, QEDRequest *request,
uint64_t offset);
int coroutine_fn qed_write_l2_table(BDRVQEDState *s, QEDRequest *request,
unsigned int index, unsigned int n,
bool flush);
int coroutine_fn qed_write_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
unsigned int index, unsigned int n,
bool flush);
int coroutine_fn GRAPH_RDLOCK qed_read_l1_table_sync(BDRVQEDState *s);
int coroutine_fn GRAPH_RDLOCK
qed_write_l1_table(BDRVQEDState *s, unsigned int index, unsigned int n);
int coroutine_fn GRAPH_RDLOCK
qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index, unsigned int n);
int coroutine_fn GRAPH_RDLOCK
qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request, uint64_t offset);
int coroutine_fn GRAPH_RDLOCK
qed_read_l2_table(BDRVQEDState *s, QEDRequest *request, uint64_t offset);
int coroutine_fn GRAPH_RDLOCK
qed_write_l2_table(BDRVQEDState *s, QEDRequest *request, unsigned int index,
unsigned int n, bool flush);
int coroutine_fn GRAPH_RDLOCK
qed_write_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
unsigned int index, unsigned int n, bool flush);
/**
* Cluster functions
*/
int coroutine_fn qed_find_cluster(BDRVQEDState *s, QEDRequest *request,
uint64_t pos, size_t *len,
uint64_t *img_offset);
int coroutine_fn GRAPH_RDLOCK
qed_find_cluster(BDRVQEDState *s, QEDRequest *request, uint64_t pos,
size_t *len, uint64_t *img_offset);
/**
* Consistency check
*/
int coroutine_fn qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix);
int coroutine_fn GRAPH_RDLOCK
qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix);
QEDTable *qed_alloc_table(BDRVQEDState *s);

View File

@ -270,7 +270,11 @@ static void quorum_report_bad_versions(BDRVQuorumState *s,
}
}
static void coroutine_fn quorum_rewrite_entry(void *opaque)
/*
* This function can count as GRAPH_RDLOCK because read_quorum_children() holds
* the graph lock and keeps it until this coroutine has terminated.
*/
static void coroutine_fn GRAPH_RDLOCK quorum_rewrite_entry(void *opaque)
{
QuorumCo *co = opaque;
QuorumAIOCB *acb = co->acb;
@ -290,8 +294,8 @@ static void coroutine_fn quorum_rewrite_entry(void *opaque)
}
}
static bool quorum_rewrite_bad_versions(QuorumAIOCB *acb,
QuorumVoteValue *value)
static bool coroutine_fn GRAPH_RDLOCK
quorum_rewrite_bad_versions(QuorumAIOCB *acb, QuorumVoteValue *value)
{
QuorumVoteVersion *version;
QuorumVoteItem *item;
@ -491,7 +495,7 @@ static int quorum_vote_error(QuorumAIOCB *acb)
return ret;
}
static void quorum_vote(QuorumAIOCB *acb)
static void coroutine_fn GRAPH_RDLOCK quorum_vote(QuorumAIOCB *acb)
{
bool quorum = true;
int i, j, ret;
@ -571,7 +575,11 @@ free_exit:
quorum_free_vote_list(&acb->votes);
}
static void coroutine_fn read_quorum_children_entry(void *opaque)
/*
* This function can count as GRAPH_RDLOCK because read_quorum_children() holds
* the graph lock and keeps it until this coroutine has terminated.
*/
static void coroutine_fn GRAPH_RDLOCK read_quorum_children_entry(void *opaque)
{
QuorumCo *co = opaque;
QuorumAIOCB *acb = co->acb;
@ -599,7 +607,7 @@ static void coroutine_fn read_quorum_children_entry(void *opaque)
}
}
static int coroutine_fn read_quorum_children(QuorumAIOCB *acb)
static int coroutine_fn GRAPH_RDLOCK read_quorum_children(QuorumAIOCB *acb)
{
BDRVQuorumState *s = acb->bs->opaque;
int i;
@ -640,7 +648,7 @@ static int coroutine_fn read_quorum_children(QuorumAIOCB *acb)
return acb->vote_ret;
}
static int coroutine_fn read_fifo_child(QuorumAIOCB *acb)
static int coroutine_fn GRAPH_RDLOCK read_fifo_child(QuorumAIOCB *acb)
{
BDRVQuorumState *s = acb->bs->opaque;
int n, ret;
@ -661,10 +669,9 @@ static int coroutine_fn read_fifo_child(QuorumAIOCB *acb)
return ret;
}
static int coroutine_fn quorum_co_preadv(BlockDriverState *bs,
int64_t offset, int64_t bytes,
QEMUIOVector *qiov,
BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
quorum_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{
BDRVQuorumState *s = bs->opaque;
QuorumAIOCB *acb = quorum_aio_get(bs, qiov, offset, bytes, flags);
@ -683,7 +690,11 @@ static int coroutine_fn quorum_co_preadv(BlockDriverState *bs,
return ret;
}
static void coroutine_fn write_quorum_entry(void *opaque)
/*
* This function can count as GRAPH_RDLOCK because quorum_co_pwritev() holds the
* graph lock and keeps it until this coroutine has terminated.
*/
static void coroutine_fn GRAPH_RDLOCK write_quorum_entry(void *opaque)
{
QuorumCo *co = opaque;
QuorumAIOCB *acb = co->acb;
@ -714,9 +725,9 @@ static void coroutine_fn write_quorum_entry(void *opaque)
}
}
static int coroutine_fn quorum_co_pwritev(BlockDriverState *bs, int64_t offset,
int64_t bytes, QEMUIOVector *qiov,
BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
quorum_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{
BDRVQuorumState *s = bs->opaque;
QuorumAIOCB *acb = quorum_aio_get(bs, qiov, offset, bytes, flags);
@ -745,16 +756,16 @@ static int coroutine_fn quorum_co_pwritev(BlockDriverState *bs, int64_t offset,
return ret;
}
static int coroutine_fn quorum_co_pwrite_zeroes(BlockDriverState *bs,
int64_t offset, int64_t bytes,
BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
quorum_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
BdrvRequestFlags flags)
{
return quorum_co_pwritev(bs, offset, bytes, NULL,
flags | BDRV_REQ_ZERO_WRITE);
}
static int64_t coroutine_fn quorum_co_getlength(BlockDriverState *bs)
static int64_t coroutine_fn GRAPH_RDLOCK
quorum_co_getlength(BlockDriverState *bs)
{
BDRVQuorumState *s = bs->opaque;
int64_t result;
@ -778,7 +789,7 @@ static int64_t coroutine_fn quorum_co_getlength(BlockDriverState *bs)
return result;
}
static coroutine_fn int quorum_co_flush(BlockDriverState *bs)
static coroutine_fn GRAPH_RDLOCK int quorum_co_flush(BlockDriverState *bs)
{
BDRVQuorumState *s = bs->opaque;
QuorumVoteVersion *winner = NULL;
@ -1217,11 +1228,10 @@ static void quorum_child_perm(BlockDriverState *bs, BdrvChild *c,
* return BDRV_BLOCK_ZERO if *all* children agree that a certain
* region contains zeroes, and BDRV_BLOCK_DATA otherwise.
*/
static int coroutine_fn quorum_co_block_status(BlockDriverState *bs,
bool want_zero,
int64_t offset, int64_t count,
int64_t *pnum, int64_t *map,
BlockDriverState **file)
static int coroutine_fn GRAPH_RDLOCK
quorum_co_block_status(BlockDriverState *bs, bool want_zero,
int64_t offset, int64_t count,
int64_t *pnum, int64_t *map, BlockDriverState **file)
{
BDRVQuorumState *s = bs->opaque;
int i, ret;

View File

@ -203,9 +203,9 @@ static inline int raw_adjust_offset(BlockDriverState *bs, int64_t *offset,
return 0;
}
static int coroutine_fn raw_co_preadv(BlockDriverState *bs, int64_t offset,
int64_t bytes, QEMUIOVector *qiov,
BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
raw_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{
int ret;
@ -218,9 +218,9 @@ static int coroutine_fn raw_co_preadv(BlockDriverState *bs, int64_t offset,
return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
}
static int coroutine_fn raw_co_pwritev(BlockDriverState *bs, int64_t offset,
int64_t bytes, QEMUIOVector *qiov,
BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
raw_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{
void *buf = NULL;
BlockDriver *drv;
@ -292,9 +292,9 @@ static int coroutine_fn raw_co_block_status(BlockDriverState *bs,
return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID;
}
static int coroutine_fn raw_co_pwrite_zeroes(BlockDriverState *bs,
int64_t offset, int64_t bytes,
BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
raw_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
BdrvRequestFlags flags)
{
int ret;
@ -305,8 +305,8 @@ static int coroutine_fn raw_co_pwrite_zeroes(BlockDriverState *bs,
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
}
static int coroutine_fn raw_co_pdiscard(BlockDriverState *bs,
int64_t offset, int64_t bytes)
static int coroutine_fn GRAPH_RDLOCK
raw_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
{
int ret;
@ -317,7 +317,8 @@ static int coroutine_fn raw_co_pdiscard(BlockDriverState *bs,
return bdrv_co_pdiscard(bs->file, offset, bytes);
}
static int64_t coroutine_fn raw_co_getlength(BlockDriverState *bs)
static int64_t coroutine_fn GRAPH_RDLOCK
raw_co_getlength(BlockDriverState *bs)
{
int64_t len;
BDRVRawState *s = bs->opaque;
@ -384,9 +385,9 @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
}
}
static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
bool exact, PreallocMode prealloc,
BdrvRequestFlags flags, Error **errp)
static int coroutine_fn GRAPH_RDLOCK
raw_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
PreallocMode prealloc, BdrvRequestFlags flags, Error **errp)
{
BDRVRawState *s = bs->opaque;
@ -405,18 +406,20 @@ static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
return bdrv_co_truncate(bs->file, offset, exact, prealloc, flags, errp);
}
static void coroutine_fn raw_co_eject(BlockDriverState *bs, bool eject_flag)
static void coroutine_fn GRAPH_RDLOCK
raw_co_eject(BlockDriverState *bs, bool eject_flag)
{
bdrv_co_eject(bs->file->bs, eject_flag);
}
static void coroutine_fn raw_co_lock_medium(BlockDriverState *bs, bool locked)
static void coroutine_fn GRAPH_RDLOCK
raw_co_lock_medium(BlockDriverState *bs, bool locked)
{
bdrv_co_lock_medium(bs->file->bs, locked);
}
static int coroutine_fn raw_co_ioctl(BlockDriverState *bs,
unsigned long int req, void *buf)
static int coroutine_fn GRAPH_RDLOCK
raw_co_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
{
BDRVRawState *s = bs->opaque;
if (s->offset || s->has_size) {
@ -430,10 +433,9 @@ static int raw_has_zero_init(BlockDriverState *bs)
return bdrv_has_zero_init(bs->file->bs);
}
static int coroutine_fn raw_co_create_opts(BlockDriver *drv,
const char *filename,
QemuOpts *opts,
Error **errp)
static int coroutine_fn GRAPH_RDLOCK
raw_co_create_opts(BlockDriver *drv, const char *filename,
QemuOpts *opts, Error **errp)
{
return bdrv_co_create_file(filename, opts, errp);
}
@ -536,14 +538,12 @@ static int raw_probe_geometry(BlockDriverState *bs, HDGeometry *geo)
return bdrv_probe_geometry(bs->file->bs, geo);
}
static int coroutine_fn raw_co_copy_range_from(BlockDriverState *bs,
BdrvChild *src,
int64_t src_offset,
BdrvChild *dst,
int64_t dst_offset,
int64_t bytes,
BdrvRequestFlags read_flags,
BdrvRequestFlags write_flags)
static int coroutine_fn GRAPH_RDLOCK
raw_co_copy_range_from(BlockDriverState *bs,
BdrvChild *src, int64_t src_offset,
BdrvChild *dst, int64_t dst_offset,
int64_t bytes, BdrvRequestFlags read_flags,
BdrvRequestFlags write_flags)
{
int ret;
@ -555,14 +555,12 @@ static int coroutine_fn raw_co_copy_range_from(BlockDriverState *bs,
bytes, read_flags, write_flags);
}
static int coroutine_fn raw_co_copy_range_to(BlockDriverState *bs,
BdrvChild *src,
int64_t src_offset,
BdrvChild *dst,
int64_t dst_offset,
int64_t bytes,
BdrvRequestFlags read_flags,
BdrvRequestFlags write_flags)
static int coroutine_fn GRAPH_RDLOCK
raw_co_copy_range_to(BlockDriverState *bs,
BdrvChild *src, int64_t src_offset,
BdrvChild *dst, int64_t dst_offset,
int64_t bytes, BdrvRequestFlags read_flags,
BdrvRequestFlags write_flags)
{
int ret;

View File

@ -72,6 +72,16 @@ static const char rbd_luks2_header_verification[
'L', 'U', 'K', 'S', 0xBA, 0xBE, 0, 2
};
static const char rbd_layered_luks_header_verification[
RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN] = {
'R', 'B', 'D', 'L', 0xBA, 0xBE, 0, 1
};
static const char rbd_layered_luks2_header_verification[
RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN] = {
'R', 'B', 'D', 'L', 0xBA, 0xBE, 0, 2
};
typedef enum {
RBD_AIO_READ,
RBD_AIO_WRITE,
@ -386,7 +396,6 @@ static int qemu_rbd_encryption_format(rbd_image_t image,
{
int r = 0;
g_autofree char *passphrase = NULL;
size_t passphrase_len;
rbd_encryption_format_t format;
rbd_encryption_options_t opts;
rbd_encryption_luks1_format_options_t luks_opts;
@ -408,12 +417,12 @@ static int qemu_rbd_encryption_format(rbd_image_t image,
opts_size = sizeof(luks_opts);
r = qemu_rbd_convert_luks_create_options(
qapi_RbdEncryptionCreateOptionsLUKS_base(&encrypt->u.luks),
&luks_opts.alg, &passphrase, &passphrase_len, errp);
&luks_opts.alg, &passphrase, &luks_opts.passphrase_size,
errp);
if (r < 0) {
return r;
}
luks_opts.passphrase = passphrase;
luks_opts.passphrase_size = passphrase_len;
break;
}
case RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2: {
@ -424,12 +433,12 @@ static int qemu_rbd_encryption_format(rbd_image_t image,
r = qemu_rbd_convert_luks_create_options(
qapi_RbdEncryptionCreateOptionsLUKS2_base(
&encrypt->u.luks2),
&luks2_opts.alg, &passphrase, &passphrase_len, errp);
&luks2_opts.alg, &passphrase, &luks2_opts.passphrase_size,
errp);
if (r < 0) {
return r;
}
luks2_opts.passphrase = passphrase;
luks2_opts.passphrase_size = passphrase_len;
break;
}
default: {
@ -468,9 +477,11 @@ static int qemu_rbd_encryption_load(rbd_image_t image,
{
int r = 0;
g_autofree char *passphrase = NULL;
size_t passphrase_len;
rbd_encryption_luks1_format_options_t luks_opts;
rbd_encryption_luks2_format_options_t luks2_opts;
#ifdef LIBRBD_SUPPORTS_ENCRYPTION_LOAD2
rbd_encryption_luks_format_options_t luks_any_opts;
#endif
rbd_encryption_format_t format;
rbd_encryption_options_t opts;
size_t opts_size;
@ -483,12 +494,11 @@ static int qemu_rbd_encryption_load(rbd_image_t image,
opts_size = sizeof(luks_opts);
r = qemu_rbd_convert_luks_options(
qapi_RbdEncryptionOptionsLUKS_base(&encrypt->u.luks),
&passphrase, &passphrase_len, errp);
&passphrase, &luks_opts.passphrase_size, errp);
if (r < 0) {
return r;
}
luks_opts.passphrase = passphrase;
luks_opts.passphrase_size = passphrase_len;
break;
}
case RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2: {
@ -498,14 +508,29 @@ static int qemu_rbd_encryption_load(rbd_image_t image,
opts_size = sizeof(luks2_opts);
r = qemu_rbd_convert_luks_options(
qapi_RbdEncryptionOptionsLUKS2_base(&encrypt->u.luks2),
&passphrase, &passphrase_len, errp);
&passphrase, &luks2_opts.passphrase_size, errp);
if (r < 0) {
return r;
}
luks2_opts.passphrase = passphrase;
luks2_opts.passphrase_size = passphrase_len;
break;
}
#ifdef LIBRBD_SUPPORTS_ENCRYPTION_LOAD2
case RBD_IMAGE_ENCRYPTION_FORMAT_LUKS_ANY: {
memset(&luks_any_opts, 0, sizeof(luks_any_opts));
format = RBD_ENCRYPTION_FORMAT_LUKS;
opts = &luks_any_opts;
opts_size = sizeof(luks_any_opts);
r = qemu_rbd_convert_luks_options(
qapi_RbdEncryptionOptionsLUKSAny_base(&encrypt->u.luks_any),
&passphrase, &luks_any_opts.passphrase_size, errp);
if (r < 0) {
return r;
}
luks_any_opts.passphrase = passphrase;
break;
}
#endif
default: {
r = -ENOTSUP;
error_setg_errno(
@ -523,6 +548,128 @@ static int qemu_rbd_encryption_load(rbd_image_t image,
return 0;
}
#ifdef LIBRBD_SUPPORTS_ENCRYPTION_LOAD2
static int qemu_rbd_encryption_load2(rbd_image_t image,
RbdEncryptionOptions *encrypt,
Error **errp)
{
int r = 0;
int encrypt_count = 1;
int i;
RbdEncryptionOptions *curr_encrypt;
rbd_encryption_spec_t *specs;
rbd_encryption_luks1_format_options_t *luks_opts;
rbd_encryption_luks2_format_options_t *luks2_opts;
rbd_encryption_luks_format_options_t *luks_any_opts;
/* count encryption options */
for (curr_encrypt = encrypt->parent; curr_encrypt;
curr_encrypt = curr_encrypt->parent) {
++encrypt_count;
}
specs = g_new0(rbd_encryption_spec_t, encrypt_count);
curr_encrypt = encrypt;
for (i = 0; i < encrypt_count; ++i) {
switch (curr_encrypt->format) {
case RBD_IMAGE_ENCRYPTION_FORMAT_LUKS: {
specs[i].format = RBD_ENCRYPTION_FORMAT_LUKS1;
luks_opts = g_new0(rbd_encryption_luks1_format_options_t, 1);
specs[i].opts = luks_opts;
specs[i].opts_size = sizeof(*luks_opts);
r = qemu_rbd_convert_luks_options(
qapi_RbdEncryptionOptionsLUKS_base(
&curr_encrypt->u.luks),
(char **)&luks_opts->passphrase,
&luks_opts->passphrase_size,
errp);
break;
}
case RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2: {
specs[i].format = RBD_ENCRYPTION_FORMAT_LUKS2;
luks2_opts = g_new0(rbd_encryption_luks2_format_options_t, 1);
specs[i].opts = luks2_opts;
specs[i].opts_size = sizeof(*luks2_opts);
r = qemu_rbd_convert_luks_options(
qapi_RbdEncryptionOptionsLUKS2_base(
&curr_encrypt->u.luks2),
(char **)&luks2_opts->passphrase,
&luks2_opts->passphrase_size,
errp);
break;
}
case RBD_IMAGE_ENCRYPTION_FORMAT_LUKS_ANY: {
specs[i].format = RBD_ENCRYPTION_FORMAT_LUKS;
luks_any_opts = g_new0(rbd_encryption_luks_format_options_t, 1);
specs[i].opts = luks_any_opts;
specs[i].opts_size = sizeof(*luks_any_opts);
r = qemu_rbd_convert_luks_options(
qapi_RbdEncryptionOptionsLUKSAny_base(
&curr_encrypt->u.luks_any),
(char **)&luks_any_opts->passphrase,
&luks_any_opts->passphrase_size,
errp);
break;
}
default: {
r = -ENOTSUP;
error_setg_errno(
errp, -r, "unknown image encryption format: %u",
curr_encrypt->format);
}
}
if (r < 0) {
goto exit;
}
curr_encrypt = curr_encrypt->parent;
}
r = rbd_encryption_load2(image, specs, encrypt_count);
if (r < 0) {
error_setg_errno(errp, -r, "layered encryption load fail");
goto exit;
}
exit:
for (i = 0; i < encrypt_count; ++i) {
if (!specs[i].opts) {
break;
}
switch (specs[i].format) {
case RBD_ENCRYPTION_FORMAT_LUKS1: {
luks_opts = specs[i].opts;
g_free((void *)luks_opts->passphrase);
break;
}
case RBD_ENCRYPTION_FORMAT_LUKS2: {
luks2_opts = specs[i].opts;
g_free((void *)luks2_opts->passphrase);
break;
}
case RBD_ENCRYPTION_FORMAT_LUKS: {
luks_any_opts = specs[i].opts;
g_free((void *)luks_any_opts->passphrase);
break;
}
}
g_free(specs[i].opts);
}
g_free(specs);
return r;
}
#endif
#endif
/* FIXME Deprecate and remove keypairs or make it available in QMP. */
@ -989,7 +1136,16 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
if (opts->encrypt) {
#ifdef LIBRBD_SUPPORTS_ENCRYPTION
r = qemu_rbd_encryption_load(s->image, opts->encrypt, errp);
if (opts->encrypt->parent) {
#ifdef LIBRBD_SUPPORTS_ENCRYPTION_LOAD2
r = qemu_rbd_encryption_load2(s->image, opts->encrypt, errp);
#else
r = -ENOTSUP;
error_setg(errp, "RBD library does not support layered encryption");
#endif
} else {
r = qemu_rbd_encryption_load(s->image, opts->encrypt, errp);
}
if (r < 0) {
goto failed_post_open;
}
@ -1281,6 +1437,16 @@ static ImageInfoSpecific *qemu_rbd_get_specific_info(BlockDriverState *bs,
spec_info->u.rbd.data->encryption_format =
RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2;
spec_info->u.rbd.data->has_encryption_format = true;
} else if (memcmp(buf, rbd_layered_luks_header_verification,
RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN) == 0) {
spec_info->u.rbd.data->encryption_format =
RBD_IMAGE_ENCRYPTION_FORMAT_LUKS;
spec_info->u.rbd.data->has_encryption_format = true;
} else if (memcmp(buf, rbd_layered_luks2_header_verification,
RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN) == 0) {
spec_info->u.rbd.data->encryption_format =
RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2;
spec_info->u.rbd.data->has_encryption_format = true;
} else {
spec_info->u.rbd.data->has_encryption_format = false;
}

View File

@ -179,7 +179,8 @@ static void replication_child_perm(BlockDriverState *bs, BdrvChild *c,
return;
}
static int64_t coroutine_fn replication_co_getlength(BlockDriverState *bs)
static int64_t coroutine_fn GRAPH_RDLOCK
replication_co_getlength(BlockDriverState *bs)
{
return bdrv_co_getlength(bs->file->bs);
}
@ -220,10 +221,9 @@ static int replication_return_value(BDRVReplicationState *s, int ret)
return ret;
}
static coroutine_fn int replication_co_readv(BlockDriverState *bs,
int64_t sector_num,
int remaining_sectors,
QEMUIOVector *qiov)
static int coroutine_fn GRAPH_RDLOCK
replication_co_readv(BlockDriverState *bs, int64_t sector_num,
int remaining_sectors, QEMUIOVector *qiov)
{
BDRVReplicationState *s = bs->opaque;
int ret;
@ -244,11 +244,9 @@ static coroutine_fn int replication_co_readv(BlockDriverState *bs,
return replication_return_value(s, ret);
}
static coroutine_fn int replication_co_writev(BlockDriverState *bs,
int64_t sector_num,
int remaining_sectors,
QEMUIOVector *qiov,
int flags)
static int coroutine_fn GRAPH_RDLOCK
replication_co_writev(BlockDriverState *bs, int64_t sector_num,
int remaining_sectors, QEMUIOVector *qiov, int flags)
{
BDRVReplicationState *s = bs->opaque;
QEMUIOVector hd_qiov;

View File

@ -26,7 +26,7 @@
#include "qemu/cutils.h"
#include "block/block_int.h"
static coroutine_fn int
static int coroutine_fn GRAPH_RDLOCK
snapshot_access_co_preadv_part(BlockDriverState *bs,
int64_t offset, int64_t bytes,
QEMUIOVector *qiov, size_t qiov_offset,
@ -39,7 +39,7 @@ snapshot_access_co_preadv_part(BlockDriverState *bs,
return bdrv_co_preadv_snapshot(bs->file, offset, bytes, qiov, qiov_offset);
}
static int coroutine_fn
static int coroutine_fn GRAPH_RDLOCK
snapshot_access_co_block_status(BlockDriverState *bs,
bool want_zero, int64_t offset,
int64_t bytes, int64_t *pnum,
@ -49,8 +49,8 @@ snapshot_access_co_block_status(BlockDriverState *bs,
bytes, pnum, map, file);
}
static int coroutine_fn snapshot_access_co_pdiscard(BlockDriverState *bs,
int64_t offset, int64_t bytes)
static int coroutine_fn GRAPH_RDLOCK
snapshot_access_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
{
return bdrv_co_pdiscard_snapshot(bs->file->bs, offset, bytes);
}

View File

@ -16,7 +16,6 @@
#include "block/block_int.h"
#include "block/blockjob_int.h"
#include "qapi/error.h"
#include "qapi/qmp/qerror.h"
#include "qapi/qmp/qdict.h"
#include "qemu/ratelimit.h"
#include "sysemu/block-backend.h"
@ -141,9 +140,11 @@ static int coroutine_fn stream_run(Job *job, Error **errp)
return 0;
}
len = bdrv_getlength(s->target_bs);
if (len < 0) {
return len;
WITH_GRAPH_RDLOCK_GUARD() {
len = bdrv_co_getlength(s->target_bs);
if (len < 0) {
return len;
}
}
job_progress_set_remaining(&s->common.job, len);
@ -161,21 +162,25 @@ static int coroutine_fn stream_run(Job *job, Error **errp)
copy = false;
ret = bdrv_is_allocated(unfiltered_bs, offset, STREAM_CHUNK, &n);
if (ret == 1) {
/* Allocated in the top, no need to copy. */
} else if (ret >= 0) {
/* Copy if allocated in the intermediate images. Limit to the
* known-unallocated area [offset, offset+n*BDRV_SECTOR_SIZE). */
ret = bdrv_is_allocated_above(bdrv_cow_bs(unfiltered_bs),
s->base_overlay, true,
offset, n, &n);
/* Finish early if end of backing file has been reached */
if (ret == 0 && n == 0) {
n = len - offset;
}
WITH_GRAPH_RDLOCK_GUARD() {
ret = bdrv_is_allocated(unfiltered_bs, offset, STREAM_CHUNK, &n);
if (ret == 1) {
/* Allocated in the top, no need to copy. */
} else if (ret >= 0) {
/*
* Copy if allocated in the intermediate images. Limit to the
* known-unallocated area [offset, offset+n*BDRV_SECTOR_SIZE).
*/
ret = bdrv_is_allocated_above(bdrv_cow_bs(unfiltered_bs),
s->base_overlay, true,
offset, n, &n);
/* Finish early if end of backing file has been reached */
if (ret == 0 && n == 0) {
n = len - offset;
}
copy = (ret > 0);
copy = (ret > 0);
}
}
trace_stream_one_iteration(s, offset, n, ret);
if (copy) {

View File

@ -106,15 +106,15 @@ static void throttle_close(BlockDriverState *bs)
}
static int64_t coroutine_fn throttle_co_getlength(BlockDriverState *bs)
static int64_t coroutine_fn GRAPH_RDLOCK
throttle_co_getlength(BlockDriverState *bs)
{
return bdrv_co_getlength(bs->file->bs);
}
static int coroutine_fn throttle_co_preadv(BlockDriverState *bs,
int64_t offset, int64_t bytes,
QEMUIOVector *qiov,
BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
throttle_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{
ThrottleGroupMember *tgm = bs->opaque;
@ -123,10 +123,9 @@ static int coroutine_fn throttle_co_preadv(BlockDriverState *bs,
return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
}
static int coroutine_fn throttle_co_pwritev(BlockDriverState *bs,
int64_t offset, int64_t bytes,
QEMUIOVector *qiov,
BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
throttle_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{
ThrottleGroupMember *tgm = bs->opaque;
throttle_group_co_io_limits_intercept(tgm, bytes, true);
@ -134,9 +133,9 @@ static int coroutine_fn throttle_co_pwritev(BlockDriverState *bs,
return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
}
static int coroutine_fn throttle_co_pwrite_zeroes(BlockDriverState *bs,
int64_t offset, int64_t bytes,
BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
throttle_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
BdrvRequestFlags flags)
{
ThrottleGroupMember *tgm = bs->opaque;
throttle_group_co_io_limits_intercept(tgm, bytes, true);
@ -144,8 +143,8 @@ static int coroutine_fn throttle_co_pwrite_zeroes(BlockDriverState *bs,
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
}
static int coroutine_fn throttle_co_pdiscard(BlockDriverState *bs,
int64_t offset, int64_t bytes)
static int coroutine_fn GRAPH_RDLOCK
throttle_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
{
ThrottleGroupMember *tgm = bs->opaque;
throttle_group_co_io_limits_intercept(tgm, bytes, true);
@ -153,16 +152,15 @@ static int coroutine_fn throttle_co_pdiscard(BlockDriverState *bs,
return bdrv_co_pdiscard(bs->file, offset, bytes);
}
static int coroutine_fn throttle_co_pwritev_compressed(BlockDriverState *bs,
int64_t offset,
int64_t bytes,
QEMUIOVector *qiov)
static int coroutine_fn GRAPH_RDLOCK
throttle_co_pwritev_compressed(BlockDriverState *bs, int64_t offset,
int64_t bytes, QEMUIOVector *qiov)
{
return throttle_co_pwritev(bs, offset, bytes, qiov,
BDRV_REQ_WRITE_COMPRESSED);
}
static int coroutine_fn throttle_co_flush(BlockDriverState *bs)
static int coroutine_fn GRAPH_RDLOCK throttle_co_flush(BlockDriverState *bs)
{
return bdrv_co_flush(bs->file->bs);
}

View File

@ -544,7 +544,7 @@ static int coroutine_fn vdi_co_block_status(BlockDriverState *bs,
(s->header.image_type == VDI_TYPE_STATIC ? BDRV_BLOCK_RECURSE : 0);
}
static int coroutine_fn
static int coroutine_fn GRAPH_RDLOCK
vdi_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{
@ -600,7 +600,7 @@ vdi_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
return ret;
}
static int coroutine_fn
static int coroutine_fn GRAPH_RDLOCK
vdi_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{
@ -898,10 +898,9 @@ static int coroutine_fn vdi_co_create(BlockdevCreateOptions *create_options,
return vdi_co_do_create(create_options, DEFAULT_CLUSTER_SIZE, errp);
}
static int coroutine_fn vdi_co_create_opts(BlockDriver *drv,
const char *filename,
QemuOpts *opts,
Error **errp)
static int coroutine_fn GRAPH_RDLOCK
vdi_co_create_opts(BlockDriver *drv, const char *filename,
QemuOpts *opts, Error **errp)
{
QDict *qdict = NULL;
BlockdevCreateOptions *create_options = NULL;

View File

@ -1172,8 +1172,9 @@ vhdx_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
}
static coroutine_fn int vhdx_co_readv(BlockDriverState *bs, int64_t sector_num,
int nb_sectors, QEMUIOVector *qiov)
static int coroutine_fn GRAPH_RDLOCK
vhdx_co_readv(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
QEMUIOVector *qiov)
{
BDRVVHDXState *s = bs->opaque;
int ret = 0;
@ -1324,9 +1325,9 @@ int vhdx_user_visible_write(BlockDriverState *bs, BDRVVHDXState *s)
return ret;
}
static coroutine_fn int vhdx_co_writev(BlockDriverState *bs, int64_t sector_num,
int nb_sectors, QEMUIOVector *qiov,
int flags)
static int coroutine_fn GRAPH_RDLOCK
vhdx_co_writev(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
QEMUIOVector *qiov, int flags)
{
int ret = -ENOTSUP;
BDRVVHDXState *s = bs->opaque;
@ -2058,10 +2059,9 @@ delete_and_exit:
return ret;
}
static int coroutine_fn vhdx_co_create_opts(BlockDriver *drv,
const char *filename,
QemuOpts *opts,
Error **errp)
static int coroutine_fn GRAPH_RDLOCK
vhdx_co_create_opts(BlockDriver *drv, const char *filename,
QemuOpts *opts, Error **errp)
{
BlockdevCreateOptions *create_options = NULL;
QDict *qdict;

View File

@ -1403,13 +1403,11 @@ static void vmdk_refresh_limits(BlockDriverState *bs, Error **errp)
* [@skip_start_sector, @skip_end_sector) is not copied or written, and leave
* it for call to write user data in the request.
*/
static int coroutine_fn get_whole_cluster(BlockDriverState *bs,
VmdkExtent *extent,
uint64_t cluster_offset,
uint64_t offset,
uint64_t skip_start_bytes,
uint64_t skip_end_bytes,
bool zeroed)
static int coroutine_fn GRAPH_RDLOCK
get_whole_cluster(BlockDriverState *bs, VmdkExtent *extent,
uint64_t cluster_offset, uint64_t offset,
uint64_t skip_start_bytes, uint64_t skip_end_bytes,
bool zeroed)
{
int ret = VMDK_OK;
int64_t cluster_bytes;
@ -1484,8 +1482,8 @@ exit:
return ret;
}
static int coroutine_fn vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data,
uint32_t offset)
static int coroutine_fn GRAPH_RDLOCK
vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data, uint32_t offset)
{
offset = cpu_to_le32(offset);
/* update L2 table */
@ -1536,14 +1534,11 @@ static int coroutine_fn vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data,
* VMDK_UNALLOC if cluster is not mapped and @allocate is false.
* VMDK_ERROR if failed.
*/
static int coroutine_fn get_cluster_offset(BlockDriverState *bs,
VmdkExtent *extent,
VmdkMetaData *m_data,
uint64_t offset,
bool allocate,
uint64_t *cluster_offset,
uint64_t skip_start_bytes,
uint64_t skip_end_bytes)
static int coroutine_fn GRAPH_RDLOCK
get_cluster_offset(BlockDriverState *bs, VmdkExtent *extent,
VmdkMetaData *m_data, uint64_t offset, bool allocate,
uint64_t *cluster_offset, uint64_t skip_start_bytes,
uint64_t skip_end_bytes)
{
unsigned int l1_index, l2_offset, l2_index;
int min_index, i, j;
@ -1736,11 +1731,10 @@ static inline uint64_t vmdk_find_offset_in_cluster(VmdkExtent *extent,
return extent_relative_offset % cluster_size;
}
static int coroutine_fn vmdk_co_block_status(BlockDriverState *bs,
bool want_zero,
int64_t offset, int64_t bytes,
int64_t *pnum, int64_t *map,
BlockDriverState **file)
static int coroutine_fn GRAPH_RDLOCK
vmdk_co_block_status(BlockDriverState *bs, bool want_zero,
int64_t offset, int64_t bytes, int64_t *pnum,
int64_t *map, BlockDriverState **file)
{
BDRVVmdkState *s = bs->opaque;
int64_t index_in_cluster, n, ret;
@ -1785,7 +1779,7 @@ static int coroutine_fn vmdk_co_block_status(BlockDriverState *bs,
return ret;
}
static int coroutine_fn
static int coroutine_fn GRAPH_RDLOCK
vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset,
int64_t offset_in_cluster, QEMUIOVector *qiov,
uint64_t qiov_offset, uint64_t n_bytes,
@ -1867,10 +1861,9 @@ vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset,
return ret;
}
static int coroutine_fn
static int coroutine_fn GRAPH_RDLOCK
vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset,
int64_t offset_in_cluster, QEMUIOVector *qiov,
int bytes)
int64_t offset_in_cluster, QEMUIOVector *qiov, int bytes)
{
int ret;
int cluster_bytes, buf_bytes;
@ -1934,7 +1927,7 @@ vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset,
return ret;
}
static int coroutine_fn
static int coroutine_fn GRAPH_RDLOCK
vmdk_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{
@ -2016,9 +2009,9 @@ fail:
*
* Returns: error code with 0 for success.
*/
static int coroutine_fn vmdk_pwritev(BlockDriverState *bs, uint64_t offset,
uint64_t bytes, QEMUIOVector *qiov,
bool zeroed, bool zero_dry_run)
static int coroutine_fn GRAPH_RDLOCK
vmdk_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
QEMUIOVector *qiov, bool zeroed, bool zero_dry_run)
{
BDRVVmdkState *s = bs->opaque;
VmdkExtent *extent = NULL;
@ -2114,7 +2107,7 @@ static int coroutine_fn vmdk_pwritev(BlockDriverState *bs, uint64_t offset,
return 0;
}
static int coroutine_fn
static int coroutine_fn GRAPH_RDLOCK
vmdk_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{
@ -2126,7 +2119,7 @@ vmdk_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
return ret;
}
static int coroutine_fn
static int coroutine_fn GRAPH_RDLOCK
vmdk_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov)
{
@ -2154,10 +2147,9 @@ vmdk_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes,
return vmdk_co_pwritev(bs, offset, bytes, qiov, 0);
}
static int coroutine_fn vmdk_co_pwrite_zeroes(BlockDriverState *bs,
int64_t offset,
int64_t bytes,
BdrvRequestFlags flags)
static int coroutine_fn GRAPH_RDLOCK
vmdk_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
BdrvRequestFlags flags)
{
int ret;
BDRVVmdkState *s = bs->opaque;
@ -2285,11 +2277,10 @@ exit:
return ret;
}
static int coroutine_fn vmdk_create_extent(const char *filename,
int64_t filesize, bool flat,
bool compress, bool zeroed_grain,
BlockBackend **pbb,
QemuOpts *opts, Error **errp)
static int coroutine_fn GRAPH_RDLOCK
vmdk_create_extent(const char *filename, int64_t filesize, bool flat,
bool compress, bool zeroed_grain, BlockBackend **pbb,
QemuOpts *opts, Error **errp)
{
int ret;
BlockBackend *blk = NULL;
@ -2367,14 +2358,10 @@ static int filename_decompose(const char *filename, char *path, char *prefix,
* non-split format.
* idx >= 1: get the n-th extent if in a split subformat
*/
typedef BlockBackend * coroutine_fn (*vmdk_create_extent_fn)(int64_t size,
int idx,
bool flat,
bool split,
bool compress,
bool zeroed_grain,
void *opaque,
Error **errp);
typedef BlockBackend * coroutine_fn /* GRAPH_RDLOCK */
(*vmdk_create_extent_fn)(int64_t size, int idx, bool flat, bool split,
bool compress, bool zeroed_grain, void *opaque,
Error **errp);
static void vmdk_desc_add_extent(GString *desc,
const char *extent_line_fmt,
@ -2387,17 +2374,18 @@ static void vmdk_desc_add_extent(GString *desc,
g_free(basename);
}
static int coroutine_fn vmdk_co_do_create(int64_t size,
BlockdevVmdkSubformat subformat,
BlockdevVmdkAdapterType adapter_type,
const char *backing_file,
const char *hw_version,
const char *toolsversion,
bool compat6,
bool zeroed_grain,
vmdk_create_extent_fn extent_fn,
void *opaque,
Error **errp)
static int coroutine_fn GRAPH_RDLOCK
vmdk_co_do_create(int64_t size,
BlockdevVmdkSubformat subformat,
BlockdevVmdkAdapterType adapter_type,
const char *backing_file,
const char *hw_version,
const char *toolsversion,
bool compat6,
bool zeroed_grain,
vmdk_create_extent_fn extent_fn,
void *opaque,
Error **errp)
{
int extent_idx;
BlockBackend *blk = NULL;
@ -2617,10 +2605,10 @@ typedef struct {
QemuOpts *opts;
} VMDKCreateOptsData;
static BlockBackend * coroutine_fn vmdk_co_create_opts_cb(int64_t size, int idx,
bool flat, bool split, bool compress,
bool zeroed_grain, void *opaque,
Error **errp)
static BlockBackend * coroutine_fn GRAPH_RDLOCK
vmdk_co_create_opts_cb(int64_t size, int idx, bool flat, bool split,
bool compress, bool zeroed_grain, void *opaque,
Error **errp)
{
BlockBackend *blk = NULL;
BlockDriverState *bs = NULL;
@ -2659,10 +2647,9 @@ exit:
return blk;
}
static int coroutine_fn vmdk_co_create_opts(BlockDriver *drv,
const char *filename,
QemuOpts *opts,
Error **errp)
static int coroutine_fn GRAPH_RDLOCK
vmdk_co_create_opts(BlockDriver *drv, const char *filename,
QemuOpts *opts, Error **errp)
{
Error *local_err = NULL;
char *desc = NULL;
@ -2822,8 +2809,8 @@ static BlockBackend * coroutine_fn vmdk_co_create_cb(int64_t size, int idx,
return blk;
}
static int coroutine_fn vmdk_co_create(BlockdevCreateOptions *create_options,
Error **errp)
static int coroutine_fn GRAPH_RDLOCK
vmdk_co_create(BlockdevCreateOptions *create_options, Error **errp)
{
BlockdevCreateOptionsVmdk *opts;
@ -2918,9 +2905,8 @@ static VmdkExtentInfo *vmdk_get_extent_info(VmdkExtent *extent)
return info;
}
static int coroutine_fn vmdk_co_check(BlockDriverState *bs,
BdrvCheckResult *result,
BdrvCheckMode fix)
static int coroutine_fn GRAPH_RDLOCK
vmdk_co_check(BlockDriverState *bs, BdrvCheckResult *result, BdrvCheckMode fix)
{
BDRVVmdkState *s = bs->opaque;
VmdkExtent *extent = NULL;

View File

@ -610,7 +610,7 @@ vpc_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
return 0;
}
static int coroutine_fn
static int coroutine_fn GRAPH_RDLOCK
vpc_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{
@ -660,7 +660,7 @@ fail:
return ret;
}
static int coroutine_fn
static int coroutine_fn GRAPH_RDLOCK
vpc_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{
@ -1087,10 +1087,9 @@ out:
return ret;
}
static int coroutine_fn vpc_co_create_opts(BlockDriver *drv,
const char *filename,
QemuOpts *opts,
Error **errp)
static int coroutine_fn GRAPH_RDLOCK
vpc_co_create_opts(BlockDriver *drv, const char *filename,
QemuOpts *opts, Error **errp)
{
BlockdevCreateOptions *create_options = NULL;
QDict *qdict;

View File

@ -3,3 +3,4 @@ TARGET_SYSTBL_ABI=common
TARGET_SYSTBL=syscall.tbl
TARGET_BIG_ENDIAN=y
TARGET_HAS_BFLT=y
TARGET_XML_FILES=gdb-xml/microblaze-core.xml gdb-xml/microblaze-stack-protect.xml

View File

@ -2,3 +2,4 @@ TARGET_ARCH=microblaze
TARGET_BIG_ENDIAN=y
TARGET_SUPPORTS_MTTCG=y
TARGET_NEED_FDT=y
TARGET_XML_FILES=gdb-xml/microblaze-core.xml gdb-xml/microblaze-stack-protect.xml

View File

@ -2,3 +2,4 @@ TARGET_ARCH=microblaze
TARGET_SYSTBL_ABI=common
TARGET_SYSTBL=syscall.tbl
TARGET_HAS_BFLT=y
TARGET_XML_FILES=gdb-xml/microblaze-core.xml gdb-xml/microblaze-stack-protect.xml

View File

@ -1,3 +1,4 @@
TARGET_ARCH=microblaze
TARGET_SUPPORTS_MTTCG=y
TARGET_NEED_FDT=y
TARGET_XML_FILES=gdb-xml/microblaze-core.xml gdb-xml/microblaze-stack-protect.xml

8
configure vendored
View File

@ -31,8 +31,12 @@ then
fi
fi
mkdir build
touch $MARKER
if ! mkdir build || ! touch $MARKER
then
echo "ERROR: Could not create ./build directory. Check the permissions on"
echo "your source directory, or try doing an out-of-tree build."
exit 1
fi
cat > GNUmakefile <<'EOF'
# This file is auto-generated by configure to support in-source tree

View File

@ -12,8 +12,7 @@
# GNU Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# Authors : Gregorio Robles <grex@gsyc.escet.urjc.es>
# Authors : Germán Póo-Caamaño <gpoo@gnome.org>

View File

@ -192,6 +192,11 @@ void start_exclusive(void)
CPUState *other_cpu;
int running_cpus;
if (current_cpu->exclusive_context_count) {
current_cpu->exclusive_context_count++;
return;
}
qemu_mutex_lock(&qemu_cpu_list_lock);
exclusive_idle();
@ -219,13 +224,16 @@ void start_exclusive(void)
*/
qemu_mutex_unlock(&qemu_cpu_list_lock);
current_cpu->in_exclusive_context = true;
current_cpu->exclusive_context_count = 1;
}
/* Finish an exclusive operation. */
void end_exclusive(void)
{
current_cpu->in_exclusive_context = false;
current_cpu->exclusive_context_count--;
if (current_cpu->exclusive_context_count) {
return;
}
qemu_mutex_lock(&qemu_cpu_list_lock);
qatomic_set(&pending_cpus, 0);

View File

@ -86,6 +86,38 @@ respective ports repository, while NetBSD will use the pkgsrc repository.
For macOS, `Homebrew`_ will be used, although `MacPorts`_ is expected to carry
similar versions.
Some build dependencies may follow less conservative rules:
Python runtime
Distributions with long-term support often provide multiple versions
of the Python runtime. While QEMU will initially aim to support the
distribution's default runtime, it may later increase its minimum version
to any newer python that is available as an option from the vendor.
In this case, it will be necessary to use the ``--python`` command line
option of the ``configure`` script to point QEMU to a supported
version of the Python runtime.
As of QEMU |version|, the minimum supported version of Python is 3.6.
Python build dependencies
Some of QEMU's build dependencies are written in Python. Usually these
are only packaged by distributions for the default Python runtime.
If QEMU bumps its minimum Python version and a non-default runtime is
required, it may be necessary to fetch python modules from the Python
Package Index (PyPI) via ``pip``, in order to build QEMU.
Optional build dependencies
Build components whose absence does not affect the ability to build
QEMU may not be available in distros, or may be too old for QEMU's
requirements. Many of these, such as the Avocado testing framework
or various linters, are written in Python and therefore can also
be installed using ``pip``. Cross compilers are another example
of optional build-time dependency; in this case it is possible to
download them from repositories such as EPEL, to use container-based
cross compilation using ``docker`` or ``podman``, or to use pre-built
binaries distributed with QEMU.
Windows
-------

View File

@ -99,6 +99,12 @@ form is preferred.
The HPET setting has been turned into a machine property.
Use ``-machine hpet=off`` instead.
``-no-acpi`` (since 8.0)
''''''''''''''''''''''''
The ``-no-acpi`` setting has been turned into a machine property.
Use ``-machine acpi=off`` instead.
``-accel hax`` (since 8.0)
''''''''''''''''''''''''''

View File

@ -306,6 +306,6 @@ variable::
host_kconfig = \
(have_tpm ? ['CONFIG_TPM=y'] : []) + \
('CONFIG_SPICE' in config_host ? ['CONFIG_SPICE=y'] : []) + \
('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
(have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
...

View File

@ -685,9 +685,10 @@ change in the QMP syntax (usually by allowing values or operations
that previously resulted in an error). QMP clients may still need to
know whether the extension is available.
For this purpose, a list of features can be specified for a command or
struct type. Each list member can either be ``{ 'name': STRING, '*if':
COND }``, or STRING, which is shorthand for ``{ 'name': STRING }``.
For this purpose, a list of features can be specified for definitions,
enumeration values, and struct members. Each feature list member can
either be ``{ 'name': STRING, '*if': COND }``, or STRING, which is
shorthand for ``{ 'name': STRING }``.
The optional 'if' member specifies a conditional. See `Configuring
the schema`_ below for more on this.
@ -817,8 +818,8 @@ member 'bar' ::
A union's discriminator may not be conditional.
Likewise, individual enumeration values be conditional. This requires
the longhand form of ENUM-VALUE_.
Likewise, individual enumeration values may be conditional. This
requires the longhand form of ENUM-VALUE_.
Example: an enum type with unconditional value 'foo' and conditional
value 'bar' ::
@ -1157,9 +1158,8 @@ Example: the SchemaInfo for EVENT_C from section Events_ ::
Type "q_obj-EVENT_C-arg" is an implicitly defined object type with
the two members from the event's definition.
The SchemaInfo for struct and union types has meta-type "object".
The SchemaInfo for a struct type has variant member "members".
The SchemaInfo for struct and union types has meta-type "object" and
variant member "members".
The SchemaInfo for a union type additionally has variant members "tag"
and "variants".

View File

@ -1854,7 +1854,8 @@ static void dump_init(DumpState *s, int fd, bool has_format,
*/
ret = cpu_get_dump_info(&s->dump_info, &s->guest_phys_blocks);
if (ret < 0) {
error_setg(errp, QERR_UNSUPPORTED);
error_setg(errp,
"dumping guest memory is not supported on this target");
goto cleanup;
}
@ -1864,10 +1865,7 @@ static void dump_init(DumpState *s, int fd, bool has_format,
s->note_size = cpu_get_note_size(s->dump_info.d_class,
s->dump_info.d_machine, nr_cpus);
if (s->note_size < 0) {
error_setg(errp, QERR_UNSUPPORTED);
goto cleanup;
}
assert(s->note_size >= 0);
/*
* The goal of this block is to (a) update the previously guessed

View File

@ -0,0 +1,67 @@
<?xml version="1.0"?>
<!-- Copyright (C) 2008 Free Software Foundation, Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. -->
<!DOCTYPE feature SYSTEM "gdb-target.dtd">
<feature name="org.gnu.gdb.microblaze.core">
<reg name="r0" bitsize="32" regnum="0"/>
<reg name="r1" bitsize="32" type="data_ptr"/>
<reg name="r2" bitsize="32"/>
<reg name="r3" bitsize="32"/>
<reg name="r4" bitsize="32"/>
<reg name="r5" bitsize="32"/>
<reg name="r6" bitsize="32"/>
<reg name="r7" bitsize="32"/>
<reg name="r8" bitsize="32"/>
<reg name="r9" bitsize="32"/>
<reg name="r10" bitsize="32"/>
<reg name="r11" bitsize="32"/>
<reg name="r12" bitsize="32"/>
<reg name="r13" bitsize="32"/>
<reg name="r14" bitsize="32"/>
<reg name="r15" bitsize="32"/>
<reg name="r16" bitsize="32"/>
<reg name="r17" bitsize="32"/>
<reg name="r18" bitsize="32"/>
<reg name="r19" bitsize="32"/>
<reg name="r20" bitsize="32"/>
<reg name="r21" bitsize="32"/>
<reg name="r22" bitsize="32"/>
<reg name="r23" bitsize="32"/>
<reg name="r24" bitsize="32"/>
<reg name="r25" bitsize="32"/>
<reg name="r26" bitsize="32"/>
<reg name="r27" bitsize="32"/>
<reg name="r28" bitsize="32"/>
<reg name="r29" bitsize="32"/>
<reg name="r30" bitsize="32"/>
<reg name="r31" bitsize="32"/>
<reg name="rpc" bitsize="32" type="code_ptr"/>
<reg name="rmsr" bitsize="32"/>
<reg name="rear" bitsize="32"/>
<reg name="resr" bitsize="32"/>
<reg name="rfsr" bitsize="32"/>
<reg name="rbtr" bitsize="32"/>
<reg name="rpvr0" bitsize="32"/>
<reg name="rpvr1" bitsize="32"/>
<reg name="rpvr2" bitsize="32"/>
<reg name="rpvr3" bitsize="32"/>
<reg name="rpvr4" bitsize="32"/>
<reg name="rpvr5" bitsize="32"/>
<reg name="rpvr6" bitsize="32"/>
<reg name="rpvr7" bitsize="32"/>
<reg name="rpvr8" bitsize="32"/>
<reg name="rpvr9" bitsize="32"/>
<reg name="rpvr10" bitsize="32"/>
<reg name="rpvr11" bitsize="32"/>
<reg name="redr" bitsize="32"/>
<reg name="rpid" bitsize="32"/>
<reg name="rzpr" bitsize="32"/>
<reg name="rtlbx" bitsize="32"/>
<reg name="rtlbsx" bitsize="32"/>
<reg name="rtlblo" bitsize="32"/>
<reg name="rtlbhi" bitsize="32"/>
</feature>

View File

@ -0,0 +1,12 @@
<?xml version="1.0"?>
<!-- Copyright (C) 2008 Free Software Foundation, Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. -->
<!DOCTYPE feature SYSTEM "gdb-target.dtd">
<feature name="org.gnu.gdb.microblaze.stack-protect">
<reg name="rslr" bitsize="32"/>
<reg name="rshr" bitsize="32"/>
</feature>

View File

@ -19,11 +19,9 @@
*/
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qapi/qmp/qerror.h"
#include "hw/acpi/acpi.h"
void acpi_table_add(const QemuOpts *opts, Error **errp)
{
error_setg(errp, QERR_UNSUPPORTED);
g_assert_not_reached();
}

View File

@ -12,7 +12,6 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-machine.h"
#include "qemu/module.h"
#include "hw/acpi/acpi.h"
#include "hw/acpi/aml-build.h"
@ -244,20 +243,3 @@ static void vmgenid_register_types(void)
}
type_init(vmgenid_register_types)
GuidInfo *qmp_query_vm_generation_id(Error **errp)
{
GuidInfo *info;
VmGenIdState *vms;
Object *obj = find_vmgenid_dev();
if (!obj) {
error_setg(errp, "VM Generation ID device not found");
return NULL;
}
vms = VMGENID(obj);
info = g_malloc0(sizeof(*info));
info->guid = qemu_uuid_unparse_strdup(&vms->guid);
return info;
}

View File

@ -18,6 +18,7 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu/module.h"
#include "hw/char/serial.h"
#include "hw/sysbus.h"
#include "hw/arm/allwinner-a10.h"
#include "hw/misc/unimp.h"

View File

@ -15,6 +15,7 @@
#include "hw/arm/boot.h"
#include "hw/arm/linux-boot-if.h"
#include "sysemu/kvm.h"
#include "sysemu/tcg.h"
#include "sysemu/sysemu.h"
#include "sysemu/numa.h"
#include "hw/boards.h"
@ -827,7 +828,10 @@ static void do_cpu_reset(void *opaque)
info->secondary_cpu_reset_hook(cpu, info);
}
}
arm_rebuild_hflags(env);
if (tcg_enabled()) {
arm_rebuild_hflags(env);
}
}
}

View File

@ -507,7 +507,7 @@ static uint64_t exynos4210_calc_affinity(int cpu)
return (0x9 << ARM_AFF1_SHIFT) | cpu;
}
static DeviceState *pl330_create(uint32_t base, qemu_or_irq *orgate,
static DeviceState *pl330_create(uint32_t base, OrIRQState *orgate,
qemu_irq irq, int nreq, int nevents, int width)
{
SysBusDevice *busdev;
@ -806,7 +806,7 @@ static void exynos4210_init(Object *obj)
for (i = 0; i < ARRAY_SIZE(s->pl330_irq_orgate); i++) {
char *name = g_strdup_printf("pl330-irq-orgate%d", i);
qemu_or_irq *orgate = &s->pl330_irq_orgate[i];
OrIRQState *orgate = &s->pl330_irq_orgate[i];
object_initialize_child(obj, name, orgate, TYPE_OR_IRQ);
g_free(name);

View File

@ -152,7 +152,7 @@ struct MPS2TZMachineState {
TZMSC msc[4];
CMSDKAPBUART uart[6];
SplitIRQ sec_resp_splitter;
qemu_or_irq uart_irq_orgate;
OrIRQState uart_irq_orgate;
DeviceState *lan9118;
SplitIRQ cpu_irq_splitter[MPS2TZ_NUMIRQ_MAX];
Clock *sysclk;

View File

@ -35,6 +35,7 @@
#include "hw/boards.h"
#include "exec/address-spaces.h"
#include "sysemu/sysemu.h"
#include "hw/qdev-properties.h"
#include "hw/misc/unimp.h"
#include "hw/char/cmsdk-apb-uart.h"
#include "hw/timer/cmsdk-apb-timer.h"
@ -282,6 +283,9 @@ static void mps2_common_init(MachineState *machine)
qdev_connect_gpio_out(orgate_dev, 0, qdev_get_gpio_in(armv7m, 12));
for (i = 0; i < 5; i++) {
DeviceState *dev;
SysBusDevice *s;
static const hwaddr uartbase[] = {0x40004000, 0x40005000,
0x40006000, 0x40007000,
0x40009000};
@ -294,12 +298,16 @@ static void mps2_common_init(MachineState *machine)
rxovrint = qdev_get_gpio_in(orgate_dev, i * 2 + 1);
}
cmsdk_apb_uart_create(uartbase[i],
qdev_get_gpio_in(armv7m, uartirq[i] + 1),
qdev_get_gpio_in(armv7m, uartirq[i]),
txovrint, rxovrint,
NULL,
serial_hd(i), SYSCLK_FRQ);
dev = qdev_new(TYPE_CMSDK_APB_UART);
s = SYS_BUS_DEVICE(dev);
qdev_prop_set_chr(dev, "chardev", serial_hd(i));
qdev_prop_set_uint32(dev, "pclk-frq", SYSCLK_FRQ);
sysbus_realize_and_unref(s, &error_fatal);
sysbus_mmio_map(s, 0, uartbase[i]);
sysbus_connect_irq(s, 0, qdev_get_gpio_in(armv7m, uartirq[i] + 1));
sysbus_connect_irq(s, 1, qdev_get_gpio_in(armv7m, uartirq[i]));
sysbus_connect_irq(s, 2, txovrint);
sysbus_connect_irq(s, 3, rxovrint);
}
break;
}
@ -324,7 +332,8 @@ static void mps2_common_init(MachineState *machine)
0x4002c000, 0x4002d000,
0x4002e000};
Object *txrx_orgate;
DeviceState *txrx_orgate_dev;
DeviceState *txrx_orgate_dev, *dev;
SysBusDevice *s;
txrx_orgate = object_new(TYPE_OR_IRQ);
object_property_set_int(txrx_orgate, "num-lines", 2, &error_fatal);
@ -332,13 +341,17 @@ static void mps2_common_init(MachineState *machine)
txrx_orgate_dev = DEVICE(txrx_orgate);
qdev_connect_gpio_out(txrx_orgate_dev, 0,
qdev_get_gpio_in(armv7m, uart_txrx_irqno[i]));
cmsdk_apb_uart_create(uartbase[i],
qdev_get_gpio_in(txrx_orgate_dev, 0),
qdev_get_gpio_in(txrx_orgate_dev, 1),
qdev_get_gpio_in(orgate_dev, i * 2),
qdev_get_gpio_in(orgate_dev, i * 2 + 1),
NULL,
serial_hd(i), SYSCLK_FRQ);
dev = qdev_new(TYPE_CMSDK_APB_UART);
s = SYS_BUS_DEVICE(dev);
qdev_prop_set_chr(dev, "chardev", serial_hd(i));
qdev_prop_set_uint32(dev, "pclk-frq", SYSCLK_FRQ);
sysbus_realize_and_unref(s, &error_fatal);
sysbus_mmio_map(s, 0, uartbase[i]);
sysbus_connect_irq(s, 0, qdev_get_gpio_in(txrx_orgate_dev, 0));
sysbus_connect_irq(s, 1, qdev_get_gpio_in(txrx_orgate_dev, 1));
sysbus_connect_irq(s, 2, qdev_get_gpio_in(orgate_dev, i * 2));
sysbus_connect_irq(s, 3, qdev_get_gpio_in(orgate_dev, i * 2 + 1));
}
break;
}

View File

@ -1072,7 +1072,6 @@ struct musicpal_key_state {
SysBusDevice parent_obj;
/*< public >*/
MemoryRegion iomem;
uint32_t kbd_extended;
uint32_t pressed_keys;
qemu_irq out[8];
@ -1161,9 +1160,6 @@ static void musicpal_key_init(Object *obj)
DeviceState *dev = DEVICE(sbd);
musicpal_key_state *s = MUSICPAL_KEY(dev);
memory_region_init(&s->iomem, obj, "dummy", 0);
sysbus_init_mmio(sbd, &s->iomem);
s->kbd_extended = 0;
s->pressed_keys = 0;

View File

@ -1146,9 +1146,14 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
for (i = 0; i < 4; i++) {
if (board->dc2 & (1 << i)) {
pl011_luminary_create(0x4000c000 + i * 0x1000,
qdev_get_gpio_in(nvic, uart_irq[i]),
serial_hd(i));
SysBusDevice *sbd;
dev = qdev_new("pl011_luminary");
sbd = SYS_BUS_DEVICE(dev);
qdev_prop_set_chr(dev, "chardev", serial_hd(i));
sysbus_realize_and_unref(sbd, &error_fatal);
sysbus_mmio_map(sbd, 0, 0x4000c000 + i * 0x1000);
sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(nvic, uart_irq[i]));
}
}
if (board->dc2 & (1 << 4)) {

View File

@ -19,10 +19,12 @@
*/
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "hw/char/pl011.h"
#include "hw/irq.h"
#include "hw/sysbus.h"
#include "hw/qdev-clock.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"
#include "migration/vmstate.h"
#include "chardev/char-fe.h"
@ -31,6 +33,21 @@
#include "qemu/module.h"
#include "trace.h"
DeviceState *pl011_create(hwaddr addr, qemu_irq irq, Chardev *chr)
{
DeviceState *dev;
SysBusDevice *s;
dev = qdev_new("pl011");
s = SYS_BUS_DEVICE(dev);
qdev_prop_set_chr(dev, "chardev", chr);
sysbus_realize_and_unref(s, &error_fatal);
sysbus_mmio_map(s, 0, addr);
sysbus_connect_irq(s, 0, irq);
return dev;
}
#define PL011_INT_TX 0x20
#define PL011_INT_RX 0x10

View File

@ -24,6 +24,7 @@
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "hw/char/xilinx_uartlite.h"
#include "hw/irq.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"
@ -53,9 +54,6 @@
#define CONTROL_RST_RX 0x02
#define CONTROL_IE 0x10
#define TYPE_XILINX_UARTLITE "xlnx.xps-uartlite"
OBJECT_DECLARE_SIMPLE_TYPE(XilinxUARTLite, XILINX_UARTLITE)
struct XilinxUARTLite {
SysBusDevice parent_obj;

View File

@ -26,8 +26,7 @@
#include "hw/irq.h"
#include "qom/object.h"
DECLARE_INSTANCE_CHECKER(struct IRQState, IRQ,
TYPE_IRQ)
OBJECT_DECLARE_SIMPLE_TYPE(IRQState, IRQ)
struct IRQState {
Object parent_obj;
@ -68,7 +67,7 @@ qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n)
qemu_irq qemu_allocate_irq(qemu_irq_handler handler, void *opaque, int n)
{
struct IRQState *irq;
IRQState *irq;
irq = IRQ(object_new(TYPE_IRQ));
irq->handler = handler;
@ -94,7 +93,7 @@ void qemu_free_irq(qemu_irq irq)
static void qemu_notirq(void *opaque, int line, int level)
{
struct IRQState *irq = opaque;
IRQState *irq = opaque;
irq->handler(irq->opaque, irq->n, !level);
}
@ -120,7 +119,7 @@ void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n)
static const TypeInfo irq_type_info = {
.name = TYPE_IRQ,
.parent = TYPE_OBJECT,
.instance_size = sizeof(struct IRQState),
.instance_size = sizeof(IRQState),
};
static void irq_register_types(void)

View File

@ -8,6 +8,7 @@
*/
#include "qemu/osdep.h"
#include "hw/acpi/vmgenid.h"
#include "hw/boards.h"
#include "hw/intc/intc.h"
#include "hw/mem/memory-device.h"
@ -15,7 +16,6 @@
#include "qapi/error.h"
#include "qapi/qapi-builtin-visit.h"
#include "qapi/qapi-commands-machine.h"
#include "qapi/qmp/qerror.h"
#include "qapi/qmp/qobject.h"
#include "qapi/qobject-input-visitor.h"
#include "qapi/type-helpers.h"
@ -140,7 +140,7 @@ HotpluggableCPUList *qmp_query_hotpluggable_cpus(Error **errp)
MachineClass *mc = MACHINE_GET_CLASS(ms);
if (!mc->has_hotpluggable_cpus) {
error_setg(errp, QERR_FEATURE_DISABLED, "query-hotpluggable-cpus");
error_setg(errp, "machine does not support hot-plugging CPUs");
return NULL;
}
@ -383,3 +383,20 @@ HumanReadableText *qmp_x_query_irq(Error **errp)
return human_readable_text_from_str(buf);
}
GuidInfo *qmp_query_vm_generation_id(Error **errp)
{
GuidInfo *info;
VmGenIdState *vms;
Object *obj = find_vmgenid_dev();
if (!obj) {
error_setg(errp, "VM Generation ID device not found");
return NULL;
}
vms = VMGENID(obj);
info = g_malloc0(sizeof(*info));
info->guid = qemu_uuid_unparse_strdup(&vms->guid);
return info;
}

View File

@ -13,7 +13,6 @@
#include "qemu/osdep.h"
#include "qemu/option.h"
#include "qemu/accel.h"
#include "qapi/qmp/qerror.h"
#include "sysemu/replay.h"
#include "qemu/units.h"
#include "hw/boards.h"

View File

@ -22,7 +22,6 @@
#include "qemu/osdep.h"
#include "hw/nmi.h"
#include "qapi/error.h"
#include "qapi/qmp/qerror.h"
#include "qemu/module.h"
#include "monitor/monitor.h"
@ -70,7 +69,7 @@ void nmi_monitor_handle(int cpu_index, Error **errp)
if (ns.handled) {
error_propagate(errp, ns.err);
} else {
error_setg(errp, QERR_UNSUPPORTED);
error_setg(errp, "machine does not provide NMIs");
}
}

View File

@ -31,7 +31,7 @@
static void or_irq_handler(void *opaque, int n, int level)
{
qemu_or_irq *s = OR_IRQ(opaque);
OrIRQState *s = OR_IRQ(opaque);
int or_level = 0;
int i;
@ -46,7 +46,7 @@ static void or_irq_handler(void *opaque, int n, int level)
static void or_irq_reset(DeviceState *dev)
{
qemu_or_irq *s = OR_IRQ(dev);
OrIRQState *s = OR_IRQ(dev);
int i;
for (i = 0; i < MAX_OR_LINES; i++) {
@ -56,7 +56,7 @@ static void or_irq_reset(DeviceState *dev)
static void or_irq_realize(DeviceState *dev, Error **errp)
{
qemu_or_irq *s = OR_IRQ(dev);
OrIRQState *s = OR_IRQ(dev);
assert(s->num_lines <= MAX_OR_LINES);
@ -65,7 +65,7 @@ static void or_irq_realize(DeviceState *dev, Error **errp)
static void or_irq_init(Object *obj)
{
qemu_or_irq *s = OR_IRQ(obj);
OrIRQState *s = OR_IRQ(obj);
qdev_init_gpio_out(DEVICE(obj), &s->out_irq, 1);
}
@ -84,7 +84,7 @@ static void or_irq_init(Object *obj)
static bool vmstate_extras_needed(void *opaque)
{
qemu_or_irq *s = OR_IRQ(opaque);
OrIRQState *s = OR_IRQ(opaque);
return s->num_lines >= OLD_MAX_OR_LINES;
}
@ -95,7 +95,7 @@ static const VMStateDescription vmstate_or_irq_extras = {
.minimum_version_id = 1,
.needed = vmstate_extras_needed,
.fields = (VMStateField[]) {
VMSTATE_VARRAY_UINT16_UNSAFE(levels, qemu_or_irq, num_lines, 0,
VMSTATE_VARRAY_UINT16_UNSAFE(levels, OrIRQState, num_lines, 0,
vmstate_info_bool, bool),
VMSTATE_END_OF_LIST(),
},
@ -106,7 +106,7 @@ static const VMStateDescription vmstate_or_irq = {
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
VMSTATE_BOOL_SUB_ARRAY(levels, qemu_or_irq, 0, OLD_MAX_OR_LINES),
VMSTATE_BOOL_SUB_ARRAY(levels, OrIRQState, 0, OLD_MAX_OR_LINES),
VMSTATE_END_OF_LIST(),
},
.subsections = (const VMStateDescription*[]) {
@ -116,7 +116,7 @@ static const VMStateDescription vmstate_or_irq = {
};
static Property or_irq_properties[] = {
DEFINE_PROP_UINT16("num-lines", qemu_or_irq, num_lines, 1),
DEFINE_PROP_UINT16("num-lines", OrIRQState, num_lines, 1),
DEFINE_PROP_END_OF_LIST(),
};
@ -136,7 +136,7 @@ static void or_irq_class_init(ObjectClass *klass, void *data)
static const TypeInfo or_irq_type_info = {
.name = TYPE_OR_IRQ,
.parent = TYPE_DEVICE,
.instance_size = sizeof(qemu_or_irq),
.instance_size = sizeof(OrIRQState),
.instance_init = or_irq_init,
.class_init = or_irq_class_init,
};

View File

@ -183,11 +183,10 @@ static void max7310_gpio_set(void *opaque, int line, int level)
* but also accepts sequences that are not SMBus so return an I2C device. */
static void max7310_realize(DeviceState *dev, Error **errp)
{
I2CSlave *i2c = I2C_SLAVE(dev);
MAX7310State *s = MAX7310(dev);
qdev_init_gpio_in(&i2c->qdev, max7310_gpio_set, 8);
qdev_init_gpio_out(&i2c->qdev, s->handler, 8);
qdev_init_gpio_in(dev, max7310_gpio_set, ARRAY_SIZE(s->handler));
qdev_init_gpio_out(dev, s->handler, ARRAY_SIZE(s->handler));
}
static void max7310_class_init(ObjectClass *klass, void *data)

View File

@ -92,7 +92,6 @@
#include "hw/mem/memory-device.h"
#include "sysemu/replay.h"
#include "target/i386/cpu.h"
#include "qapi/qmp/qerror.h"
#include "e820_memory_layout.h"
#include "fw_cfg.h"
#include "trace.h"

View File

@ -28,7 +28,6 @@
#include "qemu/datadir.h"
#include "qemu/guest-random.h"
#include "qapi/error.h"
#include "qapi/qmp/qerror.h"
#include "qapi/qapi-visit-common.h"
#include "qapi/clone-visitor.h"
#include "qapi/qapi-visit-machine.h"

View File

@ -18,6 +18,7 @@
#include "hw/intc/armv7m_nvic.h"
#include "hw/irq.h"
#include "hw/qdev-properties.h"
#include "sysemu/tcg.h"
#include "sysemu/runstate.h"
#include "target/arm/cpu.h"
#include "exec/exec-all.h"
@ -577,7 +578,7 @@ static void do_armv7m_nvic_set_pending(void *opaque, int irq, bool secure,
* which saves having to have an extra argument is_terminal
* that we'd only use in one place.
*/
cpu_abort(&s->cpu->parent_obj,
cpu_abort(CPU(s->cpu),
"Lockup: can't take terminal derived exception "
"(original exception priority %d)\n",
s->vectpending_prio);
@ -643,7 +644,7 @@ static void do_armv7m_nvic_set_pending(void *opaque, int irq, bool secure,
* Lockup condition due to a guest bug. We don't model
* Lockup, so report via cpu_abort() instead.
*/
cpu_abort(&s->cpu->parent_obj,
cpu_abort(CPU(s->cpu),
"Lockup: can't escalate %d to HardFault "
"(current priority %d)\n", irq, running);
}
@ -741,7 +742,7 @@ void armv7m_nvic_set_pending_lazyfp(NVICState *s, int irq, bool secure)
* We want to escalate to HardFault but the context the
* FP state belongs to prevents the exception pre-empting.
*/
cpu_abort(&s->cpu->parent_obj,
cpu_abort(CPU(s->cpu),
"Lockup: can't escalate to HardFault during "
"lazy FP register stacking\n");
}
@ -2454,8 +2455,10 @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr,
/* This is UNPREDICTABLE; treat as RAZ/WI */
exit_ok:
/* Ensure any changes made are reflected in the cached hflags. */
arm_rebuild_hflags(&s->cpu->env);
if (tcg_enabled()) {
/* Ensure any changes made are reflected in the cached hflags. */
arm_rebuild_hflags(&s->cpu->env);
}
return MEMTX_OK;
}
@ -2636,11 +2639,14 @@ static void armv7m_nvic_reset(DeviceState *dev)
}
}
/*
* We updated state that affects the CPU's MMUidx and thus its hflags;
* and we can't guarantee that we run before the CPU reset function.
*/
arm_rebuild_hflags(&s->cpu->env);
if (tcg_enabled()) {
/*
* We updated state that affects the CPU's MMUidx and thus its
* hflags; and we can't guarantee that we run before the CPU
* reset function.
*/
arm_rebuild_hflags(&s->cpu->env);
}
}
static void nvic_systick_trigger(void *opaque, int n, int level)

View File

@ -100,8 +100,11 @@ petalogix_s3adsp1800_init(MachineState *machine)
irq[i] = qdev_get_gpio_in(dev, i);
}
xilinx_uartlite_create(UARTLITE_BASEADDR, irq[UARTLITE_IRQ],
serial_hd(0));
dev = qdev_new(TYPE_XILINX_UARTLITE);
qdev_prop_set_chr(dev, "chardev", serial_hd(0));
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, UARTLITE_BASEADDR);
sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[UARTLITE_IRQ]);
/* 2 timers at irq 2 @ 62 Mhz. */
dev = qdev_new("xlnx.xps-timer");

View File

@ -18,7 +18,6 @@
#include "hw/register.h"
#include "qemu/bitops.h"
#include "qapi/qmp/qerror.h"
#include "hw/misc/xlnx-zynqmp-apu-ctrl.h"

View File

@ -1,6 +1,5 @@
/*
* QMP Target options - Commands handled based on a target config
* versus a host config
* QMP command stubs
*
* Copyright (c) 2015 David Ahern <dsahern@gmail.com>
*
@ -18,17 +17,16 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-rocker.h"
#include "qapi/qmp/qerror.h"
RockerSwitch *qmp_query_rocker(const char *name, Error **errp)
{
error_setg(errp, QERR_FEATURE_DISABLED, "rocker");
error_setg(errp, "rocker %s not found", name);
return NULL;
};
RockerPortList *qmp_query_rocker_ports(const char *name, Error **errp)
{
error_setg(errp, QERR_FEATURE_DISABLED, "rocker");
error_setg(errp, "rocker %s not found", name);
return NULL;
};
@ -37,7 +35,7 @@ RockerOfDpaFlowList *qmp_query_rocker_of_dpa_flows(const char *name,
uint32_t tbl_id,
Error **errp)
{
error_setg(errp, QERR_FEATURE_DISABLED, "rocker");
error_setg(errp, "rocker %s not found", name);
return NULL;
};
@ -46,6 +44,6 @@ RockerOfDpaGroupList *qmp_query_rocker_of_dpa_groups(const char *name,
uint8_t type,
Error **errp)
{
error_setg(errp, QERR_FEATURE_DISABLED, "rocker");
error_setg(errp, "rocker %s not found", name);
return NULL;
};

View File

@ -11,7 +11,6 @@
#include "qemu/osdep.h"
#include "qemu/units.h"
#include "qapi/error.h"
#include "hw/hw.h"
#include "hw/sysbus.h"
#include "hw/pci/pci_device.h"
#include "hw/pci/pci_host.h"

View File

@ -60,7 +60,7 @@ DECLARE_INSTANCE_CHECKER(PREPPCIState, RAVEN_PCI_HOST_BRIDGE,
struct PRePPCIState {
PCIHostState parent_obj;
qemu_or_irq *or_irq;
OrIRQState *or_irq;
qemu_irq pci_irqs[PCI_NUM_PINS];
PCIBus pci_bus;
AddressSpace pci_io_as;

View File

@ -10,7 +10,6 @@
#include "qemu/osdep.h"
#include "qemu/units.h"
#include "qapi/error.h"
#include "hw/hw.h"
#include "hw/ppc/ppc.h"
#include "hw/sysbus.h"
#include "hw/pci/pci_host.h"

View File

@ -173,43 +173,7 @@ target_ulong riscv_load_firmware(const char *firmware_filename,
exit(1);
}
target_ulong riscv_load_kernel(MachineState *machine,
target_ulong kernel_start_addr,
symbol_fn_t sym_cb)
{
const char *kernel_filename = machine->kernel_filename;
uint64_t kernel_load_base, kernel_entry;
g_assert(kernel_filename != NULL);
/*
* NB: Use low address not ELF entry point to ensure that the fw_dynamic
* behaviour when loading an ELF matches the fw_payload, fw_jump and BBL
* behaviour, as well as fw_dynamic with a raw binary, all of which jump to
* the (expected) load address load address. This allows kernels to have
* separate SBI and ELF entry points (used by FreeBSD, for example).
*/
if (load_elf_ram_sym(kernel_filename, NULL, NULL, NULL,
NULL, &kernel_load_base, NULL, NULL, 0,
EM_RISCV, 1, 0, NULL, true, sym_cb) > 0) {
return kernel_load_base;
}
if (load_uimage_as(kernel_filename, &kernel_entry, NULL, NULL,
NULL, NULL, NULL) > 0) {
return kernel_entry;
}
if (load_image_targphys_as(kernel_filename, kernel_start_addr,
current_machine->ram_size, NULL) > 0) {
return kernel_start_addr;
}
error_report("could not load kernel '%s'", kernel_filename);
exit(1);
}
void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry)
static void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry)
{
const char *filename = machine->initrd_filename;
uint64_t mem_size = machine->ram_size;
@ -249,6 +213,67 @@ void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry)
}
}
target_ulong riscv_load_kernel(MachineState *machine,
RISCVHartArrayState *harts,
target_ulong kernel_start_addr,
bool load_initrd,
symbol_fn_t sym_cb)
{
const char *kernel_filename = machine->kernel_filename;
uint64_t kernel_load_base, kernel_entry;
void *fdt = machine->fdt;
g_assert(kernel_filename != NULL);
/*
* NB: Use low address not ELF entry point to ensure that the fw_dynamic
* behaviour when loading an ELF matches the fw_payload, fw_jump and BBL
* behaviour, as well as fw_dynamic with a raw binary, all of which jump to
* the (expected) load address load address. This allows kernels to have
* separate SBI and ELF entry points (used by FreeBSD, for example).
*/
if (load_elf_ram_sym(kernel_filename, NULL, NULL, NULL,
NULL, &kernel_load_base, NULL, NULL, 0,
EM_RISCV, 1, 0, NULL, true, sym_cb) > 0) {
kernel_entry = kernel_load_base;
goto out;
}
if (load_uimage_as(kernel_filename, &kernel_entry, NULL, NULL,
NULL, NULL, NULL) > 0) {
goto out;
}
if (load_image_targphys_as(kernel_filename, kernel_start_addr,
current_machine->ram_size, NULL) > 0) {
kernel_entry = kernel_start_addr;
goto out;
}
error_report("could not load kernel '%s'", kernel_filename);
exit(1);
out:
/*
* For 32 bit CPUs 'kernel_entry' can be sign-extended by
* load_elf_ram_sym().
*/
if (riscv_is_32bit(harts)) {
kernel_entry = extract64(kernel_entry, 0, 32);
}
if (load_initrd && machine->initrd_filename) {
riscv_load_initrd(machine, kernel_entry);
}
if (fdt && machine->kernel_cmdline && *machine->kernel_cmdline) {
qemu_fdt_setprop_string(fdt, "/chosen", "bootargs",
machine->kernel_cmdline);
}
return kernel_entry;
}
/*
* This function makes an assumption that the DRAM interval
* 'dram_base' + 'dram_size' is contiguous.

View File

@ -629,16 +629,8 @@ static void microchip_icicle_kit_machine_init(MachineState *machine)
kernel_start_addr = riscv_calc_kernel_start_addr(&s->soc.u_cpus,
firmware_end_addr);
kernel_entry = riscv_load_kernel(machine, kernel_start_addr, NULL);
if (machine->initrd_filename) {
riscv_load_initrd(machine, kernel_entry);
}
if (machine->kernel_cmdline && *machine->kernel_cmdline) {
qemu_fdt_setprop_string(machine->fdt, "/chosen",
"bootargs", machine->kernel_cmdline);
}
kernel_entry = riscv_load_kernel(machine, &s->soc.u_cpus,
kernel_start_addr, true, NULL);
/* Compute the fdt load address in dram */
fdt_load_addr = riscv_compute_fdt_addr(memmap[MICROCHIP_PFSOC_DRAM_LO].base,

View File

@ -101,7 +101,9 @@ static void opentitan_board_init(MachineState *machine)
}
if (machine->kernel_filename) {
riscv_load_kernel(machine, memmap[IBEX_DEV_RAM].base, NULL);
riscv_load_kernel(machine, &s->soc.cpus,
memmap[IBEX_DEV_RAM].base,
false, NULL);
}
}

View File

@ -114,7 +114,9 @@ static void sifive_e_machine_init(MachineState *machine)
memmap[SIFIVE_E_DEV_MROM].base, &address_space_memory);
if (machine->kernel_filename) {
riscv_load_kernel(machine, memmap[SIFIVE_E_DEV_DTIM].base, NULL);
riscv_load_kernel(machine, &s->soc.cpus,
memmap[SIFIVE_E_DEV_DTIM].base,
false, NULL);
}
}

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