Merge remote-tracking branch 'upstream/master' into main
This commit is contained in:
commit
a0a2480e9c
@ -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
|
||||
|
@ -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" ;
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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; }'
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
|
@ -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"
|
||||
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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
12
block.c
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
108
block/io.c
108
block/io.c
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
46
block/qcow.c
46
block/qcow.c
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
136
block/qcow2.c
136
block/qcow2.c
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
101
block/qed.c
101
block/qed.c
@ -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;
|
||||
|
45
block/qed.h
45
block/qed.h
@ -200,33 +200,40 @@ void qed_commit_l2_cache_entry(L2TableCache *l2_cache, CachedL2Table *l2_table);
|
||||
/**
|
||||
* Table I/O functions
|
||||
*/
|
||||
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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
188
block/rbd.c
188
block/rbd.c
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
11
block/vdi.c
11
block/vdi.c
@ -544,7 +544,7 @@ static int coroutine_fn vdi_co_block_status(BlockDriverState *bs,
|
||||
(s->header.image_type == VDI_TYPE_STATIC ? BDRV_BLOCK_RECURSE : 0);
|
||||
}
|
||||
|
||||
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;
|
||||
|
18
block/vhdx.c
18
block/vhdx.c
@ -1172,8 +1172,9 @@ vhdx_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
||||
}
|
||||
|
||||
|
||||
static coroutine_fn int vhdx_co_readv(BlockDriverState *bs, int64_t sector_num,
|
||||
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;
|
||||
|
132
block/vmdk.c
132
block/vmdk.c
@ -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;
|
||||
|
11
block/vpc.c
11
block/vpc.c
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
8
configure
vendored
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
-------
|
||||
|
||||
|
@ -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)
|
||||
''''''''''''''''''''''''''
|
||||
|
||||
|
@ -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'] : []) + \
|
||||
...
|
||||
|
@ -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".
|
||||
|
@ -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
|
||||
|
67
gdb-xml/microblaze-core.xml
Normal file
67
gdb-xml/microblaze-core.xml
Normal 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>
|
12
gdb-xml/microblaze-stack-protect.xml
Normal file
12
gdb-xml/microblaze-stack-protect.xml
Normal 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>
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)) {
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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)
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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)
|
||||
|
@ -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");
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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.
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user