1
The following changes since commit b2896c1b09878fd1c4b485b3662f8beecbe0fef4:
1
The following changes since commit 52ed34cbddde1cb89b2ac263e758e349a77f21e1:
2
2
3
Merge tag 'vfio-updates-20230509.0' of https://gitlab.com/alex.williamson/qemu into staging (2023-05-10 11:20:35 +0100)
3
Merge tag 'pull-request-2023-06-26' of https://gitlab.com/thuth/qemu into staging (2023-06-26 10:38:41 +0200)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
https://repo.or.cz/qemu/kevin.git tags/for-upstream
7
https://repo.or.cz/qemu/kevin.git tags/for-upstream
8
8
9
for you to fetch changes up to 58a2e3f5c37be02dac3086b81bdda9414b931edf:
9
for you to fetch changes up to 17362398ee1a7f04e8006a46333145d8b707fd35:
10
10
11
block: compile out assert_bdrv_graph_readable() by default (2023-05-10 14:16:54 +0200)
11
block: use bdrv_co_debug_event in coroutine context (2023-06-28 09:46:34 +0200)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block layer patches
14
Block layer patches
15
15
16
- Graph locking, part 3 (more block drivers)
16
- Re-enable the graph lock
17
- Compile out assert_bdrv_graph_readable() by default
17
- More fixes to coroutine_fn marking
18
- Add configure options for vmdk, vhdx and vpc
19
- Fix use after free in blockdev_mark_auto_del()
20
- migration: Attempt disk reactivation in more failure scenarios
21
- Coroutine correctness fixes
22
18
23
----------------------------------------------------------------
19
----------------------------------------------------------------
24
Emanuele Giuseppe Esposito (5):
20
Kevin Wolf (11):
25
nbd: Mark nbd_co_do_establish_connection() and callers GRAPH_RDLOCK
21
iotests: Test active commit with iothread and background I/O
26
block: Mark bdrv_co_get_allocated_file_size() and callers GRAPH_RDLOCK
22
qdev-properties-system: Lock AioContext for blk_insert_bs()
27
block: Mark bdrv_co_get_info() and callers GRAPH_RDLOCK
23
test-block-iothread: Lock AioContext for blk_insert_bs()
28
block: Mark bdrv_co_debug_event() GRAPH_RDLOCK
24
block: Fix AioContext locking in bdrv_open_child()
29
block: Mark BlockDriver callbacks for amend job GRAPH_RDLOCK
25
block: Fix AioContext locking in bdrv_attach_child_common()
26
block: Fix AioContext locking in bdrv_reopen_parse_file_or_backing()
27
block: Fix AioContext locking in bdrv_open_inherit()
28
block: Fix AioContext locking in bdrv_open_backing_file()
29
blockjob: Fix AioContext locking in block_job_add_bdrv()
30
graph-lock: Unlock the AioContext while polling
31
Revert "graph-lock: Disable locking for now"
30
32
31
Eric Blake (1):
33
Paolo Bonzini (12):
32
migration: Attempt disk reactivation in more failure scenarios
34
file-posix: remove incorrect coroutine_fn calls
35
qed: mark more functions as coroutine_fns and GRAPH_RDLOCK
36
vpc: mark more functions as coroutine_fns and GRAPH_RDLOCK
37
bochs: mark more functions as coroutine_fns and GRAPH_RDLOCK
38
block: mark another function as coroutine_fns and GRAPH_UNLOCKED
39
cloop: mark more functions as coroutine_fns and GRAPH_RDLOCK
40
dmg: mark more functions as coroutine_fns and GRAPH_RDLOCK
41
vmdk: mark more functions as coroutine_fns and GRAPH_RDLOCK
42
vhdx: mark more functions as coroutine_fns and GRAPH_RDLOCK
43
qcow2: mark more functions as coroutine_fns and GRAPH_RDLOCK
44
block: use bdrv_co_getlength in coroutine context
45
block: use bdrv_co_debug_event in coroutine context
33
46
34
Kevin Wolf (18):
47
block/qcow2.h | 33 +++--
35
block: Fix use after free in blockdev_mark_auto_del()
48
block/vhdx.h | 5 +-
36
iotests/nbd-reconnect-on-open: Fix NBD socket path
49
include/block/block-io.h | 7 ++
37
qcow2: Don't call bdrv_getlength() in coroutine_fns
50
include/block/graph-lock.h | 6 +-
38
block: Consistently call bdrv_activate() outside coroutine
51
block.c | 114 ++++++++++++++++--
39
block: bdrv/blk_co_unref() for calls in coroutine context
52
block/bochs.c | 7 +-
40
block: Don't call no_coroutine_fns in qmp_block_resize()
53
block/cloop.c | 9 +-
41
iotests: Test resizing image attached to an iothread
54
block/dmg.c | 21 ++--
42
test-bdrv-drain: Don't modify the graph in coroutines
55
block/file-posix.c | 29 +++--
43
graph-lock: Add GRAPH_UNLOCKED(_PTR)
56
block/graph-lock.c | 43 +++----
44
graph-lock: Fix GRAPH_RDLOCK_GUARD*() to be reader lock
57
block/io.c | 14 +--
45
block: .bdrv_open is non-coroutine and unlocked
58
block/parallels.c | 4 +-
46
nbd: Remove nbd_co_flush() wrapper function
59
block/qcow.c | 30 ++---
47
vhdx: Require GRAPH_RDLOCK for accessing a node's parent list
60
block/qcow2-bitmap.c | 26 ++--
48
mirror: Require GRAPH_RDLOCK for accessing a node's parent list
61
block/qcow2-cluster.c | 24 ++--
49
block: Mark bdrv_query_bds_stats() and callers GRAPH_RDLOCK
62
block/qcow2-refcount.c | 134 +++++++++++----------
50
block: Mark bdrv_query_block_graph_info() and callers GRAPH_RDLOCK
63
block/qcow2.c | 20 +--
51
block: Mark bdrv_recurse_can_replace() and callers GRAPH_RDLOCK
64
block/qed-check.c | 5 +-
52
block: Mark bdrv_refresh_limits() and callers GRAPH_RDLOCK
65
block/qed-table.c | 6 +-
53
66
block/qed.c | 15 +--
54
Paolo Bonzini (1):
67
block/raw-format.c | 4 +-
55
block: add missing coroutine_fn annotations
68
block/vhdx-log.c | 36 +++---
56
69
block/vhdx.c | 73 ++++++-----
57
Stefan Hajnoczi (2):
70
block/vmdk.c | 55 ++++-----
58
aio-wait: avoid AioContext lock in aio_wait_bh_oneshot()
71
block/vpc.c | 52 ++++----
59
block: compile out assert_bdrv_graph_readable() by default
72
blockjob.c | 17 ++-
60
73
hw/core/qdev-properties-system.c | 8 +-
61
Vladimir Sementsov-Ogievskiy (1):
74
tests/unit/test-block-iothread.c | 7 +-
62
block: add configure options for excluding vmdk, vhdx and vpc
75
tests/qemu-iotests/tests/iothreads-commit-active | 85 +++++++++++++
63
76
.../qemu-iotests/tests/iothreads-commit-active.out | 23 ++++
64
meson_options.txt | 8 ++
77
30 files changed, 573 insertions(+), 339 deletions(-)
65
configure | 1 +
78
create mode 100755 tests/qemu-iotests/tests/iothreads-commit-active
66
block/coroutines.h | 5 +-
79
create mode 100644 tests/qemu-iotests/tests/iothreads-commit-active.out
67
block/qcow2.h | 4 +-
68
include/block/aio-wait.h | 2 +-
69
include/block/block-global-state.h | 19 +++-
70
include/block/block-io.h | 23 +++--
71
include/block/block_int-common.h | 37 +++----
72
include/block/block_int-global-state.h | 4 +-
73
include/block/graph-lock.h | 20 ++--
74
include/block/qapi.h | 7 +-
75
include/sysemu/block-backend-global-state.h | 5 +-
76
block.c | 25 ++++-
77
block/amend.c | 8 +-
78
block/blkverify.c | 5 +-
79
block/block-backend.c | 10 +-
80
block/crypto.c | 8 +-
81
block/graph-lock.c | 3 +
82
block/io.c | 12 +--
83
block/mirror.c | 18 +++-
84
block/nbd.c | 50 +++++----
85
block/parallels.c | 6 +-
86
block/qapi.c | 6 +-
87
block/qcow.c | 6 +-
88
block/qcow2-refcount.c | 2 +-
89
block/qcow2.c | 48 ++++-----
90
block/qed.c | 24 ++---
91
block/quorum.c | 4 +-
92
block/raw-format.c | 2 +-
93
block/vdi.c | 6 +-
94
block/vhdx.c | 15 +--
95
block/vmdk.c | 20 ++--
96
block/vpc.c | 6 +-
97
blockdev.c | 25 +++--
98
hw/block/dataplane/virtio-blk.c | 3 +-
99
hw/scsi/virtio-scsi-dataplane.c | 2 -
100
migration/migration.c | 24 +++--
101
qemu-img.c | 2 +
102
tests/unit/test-bdrv-drain.c | 112 ++++++++++++++-------
103
util/aio-wait.c | 2 +-
104
block/meson.build | 18 +++-
105
meson.build | 5 +
106
scripts/meson-buildoptions.sh | 13 +++
107
tests/qemu-iotests/tests/iothreads-resize | 71 +++++++++++++
108
tests/qemu-iotests/tests/iothreads-resize.out | 11 ++
109
tests/qemu-iotests/tests/nbd-reconnect-on-open | 3 +-
110
tests/qemu-iotests/tests/nbd-reconnect-on-open.out | 4 +-
111
47 files changed, 474 insertions(+), 240 deletions(-)
112
create mode 100755 tests/qemu-iotests/tests/iothreads-resize
113
create mode 100644 tests/qemu-iotests/tests/iothreads-resize.out
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
2
1
3
Let's add --enable / --disable configure options for these formats,
4
so that those who don't need them may not build them.
5
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
7
Message-Id: <20230421092758.814122-1-vsementsov@yandex-team.ru>
8
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
meson_options.txt | 6 ++++++
12
block/meson.build | 18 +++++++++++++-----
13
meson.build | 3 +++
14
scripts/meson-buildoptions.sh | 9 +++++++++
15
4 files changed, 31 insertions(+), 5 deletions(-)
16
17
diff --git a/meson_options.txt b/meson_options.txt
18
index XXXXXXX..XXXXXXX 100644
19
--- a/meson_options.txt
20
+++ b/meson_options.txt
21
@@ -XXX,XX +XXX,XX @@ option('qcow1', type: 'feature', value: 'auto',
22
description: 'qcow1 image format support')
23
option('vdi', type: 'feature', value: 'auto',
24
description: 'vdi image format support')
25
+option('vhdx', type: 'feature', value: 'auto',
26
+ description: 'vhdx image format support')
27
+option('vmdk', type: 'feature', value: 'auto',
28
+ description: 'vmdk image format support')
29
+option('vpc', type: 'feature', value: 'auto',
30
+ description: 'vpc image format support')
31
option('vvfat', type: 'feature', value: 'auto',
32
description: 'vvfat image format support')
33
option('qed', type: 'feature', value: 'auto',
34
diff --git a/block/meson.build b/block/meson.build
35
index XXXXXXX..XXXXXXX 100644
36
--- a/block/meson.build
37
+++ b/block/meson.build
38
@@ -XXX,XX +XXX,XX @@ block_ss.add(files(
39
'snapshot-access.c',
40
'throttle-groups.c',
41
'throttle.c',
42
- 'vhdx-endian.c',
43
- 'vhdx-log.c',
44
- 'vhdx.c',
45
- 'vmdk.c',
46
- 'vpc.c',
47
'write-threshold.c',
48
), zstd, zlib, gnutls)
49
50
@@ -XXX,XX +XXX,XX @@ endif
51
if get_option('vdi').allowed()
52
block_ss.add(files('vdi.c'))
53
endif
54
+if get_option('vhdx').allowed()
55
+ block_ss.add(files(
56
+ 'vhdx-endian.c',
57
+ 'vhdx-log.c',
58
+ 'vhdx.c'
59
+ ))
60
+endif
61
+if get_option('vmdk').allowed()
62
+ block_ss.add(files('vmdk.c'))
63
+endif
64
+if get_option('vpc').allowed()
65
+ block_ss.add(files('vpc.c'))
66
+endif
67
if get_option('cloop').allowed()
68
block_ss.add(files('cloop.c'))
69
endif
70
diff --git a/meson.build b/meson.build
71
index XXXXXXX..XXXXXXX 100644
72
--- a/meson.build
73
+++ b/meson.build
74
@@ -XXX,XX +XXX,XX @@ if have_block
75
summary_info += {'dmg support': get_option('dmg').allowed()}
76
summary_info += {'qcow v1 support': get_option('qcow1').allowed()}
77
summary_info += {'vdi support': get_option('vdi').allowed()}
78
+ summary_info += {'vhdx support': get_option('vhdx').allowed()}
79
+ summary_info += {'vmdk support': get_option('vmdk').allowed()}
80
+ summary_info += {'vpc support': get_option('vpc').allowed()}
81
summary_info += {'vvfat support': get_option('vvfat').allowed()}
82
summary_info += {'qed support': get_option('qed').allowed()}
83
summary_info += {'parallels support': get_option('parallels').allowed()}
84
diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh
85
index XXXXXXX..XXXXXXX 100644
86
--- a/scripts/meson-buildoptions.sh
87
+++ b/scripts/meson-buildoptions.sh
88
@@ -XXX,XX +XXX,XX @@ meson_options_help() {
89
printf "%s\n" ' VDUSE block export support'
90
printf "%s\n" ' vfio-user-server'
91
printf "%s\n" ' vfio-user server support'
92
+ printf "%s\n" ' vhdx vhdx image format support'
93
printf "%s\n" ' vhost-crypto vhost-user crypto backend support'
94
printf "%s\n" ' vhost-kernel vhost kernel backend support'
95
printf "%s\n" ' vhost-net vhost-net kernel acceleration support'
96
@@ -XXX,XX +XXX,XX @@ meson_options_help() {
97
printf "%s\n" ' vhost-vdpa vhost-vdpa kernel backend support'
98
printf "%s\n" ' virglrenderer virgl rendering support'
99
printf "%s\n" ' virtfs virtio-9p support'
100
+ printf "%s\n" ' vmdk vmdk image format support'
101
printf "%s\n" ' vmnet vmnet.framework network backend support'
102
printf "%s\n" ' vnc VNC server'
103
printf "%s\n" ' vnc-jpeg JPEG lossy compression for VNC server'
104
printf "%s\n" ' vnc-sasl SASL authentication for VNC server'
105
+ printf "%s\n" ' vpc vpc image format support'
106
printf "%s\n" ' vte vte support for the gtk UI'
107
printf "%s\n" ' vvfat vvfat image format support'
108
printf "%s\n" ' whpx WHPX acceleration support'
109
@@ -XXX,XX +XXX,XX @@ _meson_option_parse() {
110
--disable-vduse-blk-export) printf "%s" -Dvduse_blk_export=disabled ;;
111
--enable-vfio-user-server) printf "%s" -Dvfio_user_server=enabled ;;
112
--disable-vfio-user-server) printf "%s" -Dvfio_user_server=disabled ;;
113
+ --enable-vhdx) printf "%s" -Dvhdx=enabled ;;
114
+ --disable-vhdx) printf "%s" -Dvhdx=disabled ;;
115
--enable-vhost-crypto) printf "%s" -Dvhost_crypto=enabled ;;
116
--disable-vhost-crypto) printf "%s" -Dvhost_crypto=disabled ;;
117
--enable-vhost-kernel) printf "%s" -Dvhost_kernel=enabled ;;
118
@@ -XXX,XX +XXX,XX @@ _meson_option_parse() {
119
--disable-virglrenderer) printf "%s" -Dvirglrenderer=disabled ;;
120
--enable-virtfs) printf "%s" -Dvirtfs=enabled ;;
121
--disable-virtfs) printf "%s" -Dvirtfs=disabled ;;
122
+ --enable-vmdk) printf "%s" -Dvmdk=enabled ;;
123
+ --disable-vmdk) printf "%s" -Dvmdk=disabled ;;
124
--enable-vmnet) printf "%s" -Dvmnet=enabled ;;
125
--disable-vmnet) printf "%s" -Dvmnet=disabled ;;
126
--enable-vnc) printf "%s" -Dvnc=enabled ;;
127
@@ -XXX,XX +XXX,XX @@ _meson_option_parse() {
128
--disable-vnc-jpeg) printf "%s" -Dvnc_jpeg=disabled ;;
129
--enable-vnc-sasl) printf "%s" -Dvnc_sasl=enabled ;;
130
--disable-vnc-sasl) printf "%s" -Dvnc_sasl=disabled ;;
131
+ --enable-vpc) printf "%s" -Dvpc=enabled ;;
132
+ --disable-vpc) printf "%s" -Dvpc=disabled ;;
133
--enable-vte) printf "%s" -Dvte=enabled ;;
134
--disable-vte) printf "%s" -Dvte=disabled ;;
135
--enable-vvfat) printf "%s" -Dvvfat=enabled ;;
136
--
137
2.40.1
diff view generated by jsdifflib
1
This tests that trying to resize an image with QMP block_resize doesn't
1
This is a better regression test for the bugs hidden by commit 80fc5d26
2
hang or otherwise fail when the image is attached to a device running in
2
('graph-lock: Disable locking for now'). With that commit reverted, it
3
an iothread.
3
hangs instantaneously and reliably for me.
4
4
5
This is a regression test for the recent fix that changed
5
It is important to have a reliable test like this, because the following
6
qmp_block_resize, which is a coroutine based QMP handler, to avoid
6
commits will set out to fix the actual root cause of the deadlocks and
7
calling no_coroutine_fns directly.
7
then finally revert commit 80fc5d26, which was only a stopgap solution.
8
8
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Message-Id: <20230509134133.373408-1-kwolf@redhat.com>
10
Message-ID: <20230605085711.21261-2-kwolf@redhat.com>
11
Reviewed-by: Eric Blake <eblake@redhat.com>
11
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
13
---
14
tests/qemu-iotests/tests/iothreads-resize | 71 +++++++++++++++++++
14
.../tests/iothreads-commit-active | 85 +++++++++++++++++++
15
tests/qemu-iotests/tests/iothreads-resize.out | 11 +++
15
.../tests/iothreads-commit-active.out | 23 +++++
16
2 files changed, 82 insertions(+)
16
2 files changed, 108 insertions(+)
17
create mode 100755 tests/qemu-iotests/tests/iothreads-resize
17
create mode 100755 tests/qemu-iotests/tests/iothreads-commit-active
18
create mode 100644 tests/qemu-iotests/tests/iothreads-resize.out
18
create mode 100644 tests/qemu-iotests/tests/iothreads-commit-active.out
19
19
20
diff --git a/tests/qemu-iotests/tests/iothreads-resize b/tests/qemu-iotests/tests/iothreads-resize
20
diff --git a/tests/qemu-iotests/tests/iothreads-commit-active b/tests/qemu-iotests/tests/iothreads-commit-active
21
new file mode 100755
21
new file mode 100755
22
index XXXXXXX..XXXXXXX
22
index XXXXXXX..XXXXXXX
23
--- /dev/null
23
--- /dev/null
24
+++ b/tests/qemu-iotests/tests/iothreads-resize
24
+++ b/tests/qemu-iotests/tests/iothreads-commit-active
25
@@ -XXX,XX +XXX,XX @@
25
@@ -XXX,XX +XXX,XX @@
26
+#!/usr/bin/env bash
26
+#!/usr/bin/env python3
27
+# group: rw auto quick
27
+# group: rw quick auto
28
+#
29
+# Test resizing an image that is attached to a separate iothread
30
+#
28
+#
31
+# Copyright (C) 2023 Red Hat, Inc.
29
+# Copyright (C) 2023 Red Hat, Inc.
32
+#
30
+#
33
+# This program is free software; you can redistribute it and/or modify
31
+# This program is free software; you can redistribute it and/or modify
34
+# it under the terms of the GNU General Public License as published by
32
+# it under the terms of the GNU General Public License as published by
...
...
41
+# GNU General Public License for more details.
39
+# GNU General Public License for more details.
42
+#
40
+#
43
+# You should have received a copy of the GNU General Public License
41
+# You should have received a copy of the GNU General Public License
44
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
42
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
45
+#
43
+#
44
+# Creator/Owner: Kevin Wolf <kwolf@redhat.com>
46
+
45
+
47
+# creator
46
+import asyncio
48
+owner=kwolf@redhat.com
47
+import iotests
49
+
48
+
50
+seq=`basename $0`
49
+iotests.script_initialize(supported_fmts=['qcow2'],
51
+echo "QA output created by $seq"
50
+ supported_platforms=['linux'])
51
+iotests.verify_virtio_scsi_pci_or_ccw()
52
+
52
+
53
+status=1 # failure is the default!
53
+with iotests.FilePath('disk0.img') as img_path, \
54
+ iotests.FilePath('disk0-snap.img') as snap_path, \
55
+ iotests.FilePath('mirror-src.img') as src_path, \
56
+ iotests.FilePath('mirror-dst.img') as dst_path, \
57
+ iotests.VM() as vm:
54
+
58
+
55
+_cleanup()
59
+ img_size = '10M'
56
+{
60
+ iotests.qemu_img_create('-f', iotests.imgfmt, img_path, img_size)
57
+ _cleanup_test_img
61
+ iotests.qemu_img_create('-f', iotests.imgfmt, '-b', img_path,
58
+}
62
+ '-F', iotests.imgfmt, snap_path)
59
+trap "_cleanup; exit \$status" 0 1 2 3 15
63
+ iotests.qemu_img_create('-f', iotests.imgfmt, src_path, img_size)
64
+ iotests.qemu_img_create('-f', iotests.imgfmt, dst_path, img_size)
60
+
65
+
61
+# get standard environment, filters and checks
66
+ iotests.qemu_io_log('-c', 'write 0 64k', img_path)
62
+cd ..
67
+ iotests.qemu_io_log('-c', 'write 1M 64k', snap_path)
63
+. ./common.rc
68
+ iotests.qemu_io_log('-c', 'write 3M 64k', snap_path)
64
+. ./common.filter
65
+
69
+
66
+# Resizing images is only supported by a few block drivers
70
+ iotests.qemu_io_log('-c', f'write 0 {img_size}', src_path)
67
+_supported_fmt raw qcow2 qed
68
+_supported_proto file
69
+_require_devices virtio-scsi-pci
70
+
71
+
71
+size=64M
72
+ iotests.log('Launching VM...')
72
+_make_test_img $size
73
+ vm.add_object('iothread,id=iothread0')
74
+ vm.add_object('throttle-group,x-bps-write=1048576,id=tg0')
75
+ vm.add_blockdev(f'file,node-name=disk0-file,filename={img_path}')
76
+ vm.add_blockdev('qcow2,node-name=disk0-fmt,file=disk0-file')
77
+ vm.add_drive(snap_path, 'backing=disk0-fmt,node-name=disk0',
78
+ interface='none')
79
+ vm.add_device('virtio-scsi,iothread=iothread0')
80
+ vm.add_device('scsi-hd,drive=drive0')
73
+
81
+
74
+qmp() {
82
+ vm.add_blockdev(f'file,filename={src_path},node-name=mirror-src-file')
75
+cat <<EOF
83
+ vm.add_blockdev('qcow2,file=mirror-src-file,node-name=mirror-src')
76
+{"execute":"qmp_capabilities"}
84
+ vm.add_blockdev(f'file,filename={dst_path},node-name=mirror-dst-file')
77
+{'execute': 'block_resize',
85
+ vm.add_blockdev('qcow2,file=mirror-dst-file,node-name=mirror-dst-fmt')
78
+ 'arguments': {'node-name': 'img', 'size': 134217728}}
86
+ vm.add_blockdev('throttle,throttle-group=tg0,file=mirror-dst-fmt,'
79
+{"execute":"quit"}
87
+ 'node-name=mirror-dst')
80
+EOF
88
+ vm.add_device('scsi-hd,drive=mirror-src')
81
+}
82
+
89
+
83
+qmp | $QEMU -S -display none \
90
+ vm.launch()
84
+ -drive if=none,format=$IMGFMT,file="$TEST_IMG",node-name=img \
85
+ -object iothread,id=t0 \
86
+ -device virtio-scsi-pci,iothread=t0 \
87
+ -device scsi-hd,drive=none0 \
88
+ -qmp stdio \
89
+ | _filter_qmp
90
+
91
+
91
+_img_info | _filter_img_info
92
+ # The background I/O is created on unrelated nodes (so that they won't be
93
+ # drained together with the other ones), but on the same iothread
94
+ iotests.log('Creating some background I/O...')
95
+ iotests.log(vm.qmp('blockdev-mirror', job_id='job0', sync='full',
96
+ device='mirror-src', target='mirror-dst',
97
+ auto_dismiss=False))
92
+
98
+
93
+# success, all done
99
+ iotests.log('Starting active commit...')
94
+echo "*** done"
100
+ iotests.log(vm.qmp('block-commit', device='disk0', job_id='job1',
95
+rm -f $seq.full
101
+ auto_dismiss=False))
96
+status=0
102
+
97
diff --git a/tests/qemu-iotests/tests/iothreads-resize.out b/tests/qemu-iotests/tests/iothreads-resize.out
103
+ # Should succeed and not time out
104
+ try:
105
+ vm.run_job('job1', wait=5.0)
106
+ vm.shutdown()
107
+ except asyncio.TimeoutError:
108
+ # VM may be stuck, kill it
109
+ vm.kill()
110
+ raise
111
diff --git a/tests/qemu-iotests/tests/iothreads-commit-active.out b/tests/qemu-iotests/tests/iothreads-commit-active.out
98
new file mode 100644
112
new file mode 100644
99
index XXXXXXX..XXXXXXX
113
index XXXXXXX..XXXXXXX
100
--- /dev/null
114
--- /dev/null
101
+++ b/tests/qemu-iotests/tests/iothreads-resize.out
115
+++ b/tests/qemu-iotests/tests/iothreads-commit-active.out
102
@@ -XXX,XX +XXX,XX @@
116
@@ -XXX,XX +XXX,XX @@
103
+QA output created by iothreads-resize
117
+wrote 65536/65536 bytes at offset 0
104
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
118
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
105
+QMP_VERSION
119
+
120
+wrote 65536/65536 bytes at offset 1048576
121
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
122
+
123
+wrote 65536/65536 bytes at offset 3145728
124
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
125
+
126
+wrote 10485760/10485760 bytes at offset 0
127
+10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
128
+
129
+Launching VM...
130
+Creating some background I/O...
106
+{"return": {}}
131
+{"return": {}}
132
+Starting active commit...
107
+{"return": {}}
133
+{"return": {}}
134
+{"execute": "job-complete", "arguments": {"id": "job1"}}
108
+{"return": {}}
135
+{"return": {}}
109
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
136
+{"data": {"device": "job1", "len": 131072, "offset": 131072, "speed": 0, "type": "commit"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
110
+image: TEST_DIR/t.IMGFMT
137
+{"data": {"device": "job1", "len": 131072, "offset": 131072, "speed": 0, "type": "commit"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
111
+file format: IMGFMT
138
+{"execute": "job-dismiss", "arguments": {"id": "job1"}}
112
+virtual size: 128 MiB (134217728 bytes)
139
+{"return": {}}
113
+*** done
114
--
140
--
115
2.40.1
141
2.41.0
diff view generated by jsdifflib
1
This adds GRAPH_RDLOCK annotations to declare that callers of
1
blk_insert_bs() requires that callers hold the AioContext lock for the
2
bdrv_query_block_graph_info() need to hold a reader lock for the graph
2
node that should be inserted. Take it.
3
because it accesses the children list of a node.
4
3
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Eric Blake <eblake@redhat.com>
5
Message-ID: <20230605085711.21261-3-kwolf@redhat.com>
7
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
6
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
8
Message-Id: <20230504115750.54437-19-kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
8
---
11
include/block/qapi.h | 7 ++++---
9
hw/core/qdev-properties-system.c | 8 ++++++--
12
qemu-img.c | 2 ++
10
1 file changed, 6 insertions(+), 2 deletions(-)
13
2 files changed, 6 insertions(+), 3 deletions(-)
14
11
15
diff --git a/include/block/qapi.h b/include/block/qapi.h
12
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
16
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
17
--- a/include/block/qapi.h
14
--- a/hw/core/qdev-properties-system.c
18
+++ b/include/block/qapi.h
15
+++ b/hw/core/qdev-properties-system.c
19
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@ static void set_drive_helper(Object *obj, Visitor *v, const char *name,
20
#ifndef BLOCK_QAPI_H
17
* aware of iothreads require their BlockBackends to be in the main
21
#define BLOCK_QAPI_H
18
* AioContext.
22
19
*/
23
+#include "block/graph-lock.h"
20
- ctx = iothread ? bdrv_get_aio_context(bs) : qemu_get_aio_context();
24
#include "block/snapshot.h"
21
- blk = blk_new(ctx, 0, BLK_PERM_ALL);
25
#include "qapi/qapi-types-block-core.h"
22
+ ctx = bdrv_get_aio_context(bs);
26
23
+ blk = blk_new(iothread ? ctx : qemu_get_aio_context(),
27
@@ -XXX,XX +XXX,XX @@ void bdrv_query_image_info(BlockDriverState *bs,
24
+ 0, BLK_PERM_ALL);
28
bool flat,
25
blk_created = true;
29
bool skip_implicit_filters,
26
30
Error **errp);
27
+ aio_context_acquire(ctx);
31
-void bdrv_query_block_graph_info(BlockDriverState *bs,
28
ret = blk_insert_bs(blk, bs, errp);
32
- BlockGraphInfo **p_info,
29
+ aio_context_release(ctx);
33
- Error **errp);
34
+void GRAPH_RDLOCK
35
+bdrv_query_block_graph_info(BlockDriverState *bs, BlockGraphInfo **p_info,
36
+ Error **errp);
37
38
void bdrv_snapshot_dump(QEMUSnapshotInfo *sn);
39
void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec,
40
diff --git a/qemu-img.c b/qemu-img.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/qemu-img.c
43
+++ b/qemu-img.c
44
@@ -XXX,XX +XXX,XX @@ static BlockGraphInfoList *collect_image_info_list(bool image_opts,
45
}
46
bs = blk_bs(blk);
47
48
+ GRAPH_RDLOCK_GUARD_MAINLOOP();
49
+
30
+
50
/*
31
if (ret < 0) {
51
* Note that the returned BlockGraphInfo object will not have
32
goto fail;
52
* information about this image's backing node, because we have opened
33
}
53
--
34
--
54
2.40.1
35
2.41.0
diff view generated by jsdifflib
1
This adds GRAPH_RDLOCK annotations to declare that callers of
1
blk_insert_bs() requires that callers hold the AioContext lock for the
2
bdrv_query_bds_stats() need to hold a reader lock for the graph because
2
node that should be inserted. Take it.
3
it accesses the children list of a node.
4
3
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Eric Blake <eblake@redhat.com>
5
Message-ID: <20230605085711.21261-4-kwolf@redhat.com>
7
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
6
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
8
Message-Id: <20230504115750.54437-18-kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
8
---
11
block/qapi.c | 6 ++++--
9
tests/unit/test-block-iothread.c | 7 ++++++-
12
1 file changed, 4 insertions(+), 2 deletions(-)
10
1 file changed, 6 insertions(+), 1 deletion(-)
13
11
14
diff --git a/block/qapi.c b/block/qapi.c
12
diff --git a/tests/unit/test-block-iothread.c b/tests/unit/test-block-iothread.c
15
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
16
--- a/block/qapi.c
14
--- a/tests/unit/test-block-iothread.c
17
+++ b/block/qapi.c
15
+++ b/tests/unit/test-block-iothread.c
18
@@ -XXX,XX +XXX,XX @@ static void bdrv_query_blk_stats(BlockDeviceStats *ds, BlockBackend *blk)
16
@@ -XXX,XX +XXX,XX @@ static void test_attach_second_node(void)
19
= bdrv_latency_histogram_stats(&hgram[BLOCK_ACCT_FLUSH]);
17
BlockDriverState *bs, *filter;
20
}
18
QDict *options;
21
19
22
-static BlockStats *bdrv_query_bds_stats(BlockDriverState *bs,
20
+ aio_context_acquire(main_ctx);
23
- bool blk_level)
21
blk = blk_new(ctx, BLK_PERM_ALL, BLK_PERM_ALL);
24
+static BlockStats * GRAPH_RDLOCK
22
bs = bdrv_new_open_driver(&bdrv_test, "base", BDRV_O_RDWR, &error_abort);
25
+bdrv_query_bds_stats(BlockDriverState *bs, bool blk_level)
23
blk_insert_bs(blk, bs, &error_abort);
24
@@ -XXX,XX +XXX,XX @@ static void test_attach_second_node(void)
25
qdict_put_str(options, "driver", "raw");
26
qdict_put_str(options, "file", "base");
27
28
- aio_context_acquire(main_ctx);
29
filter = bdrv_open(NULL, NULL, options, BDRV_O_RDWR, &error_abort);
30
aio_context_release(main_ctx);
31
32
@@ -XXX,XX +XXX,XX @@ static void test_attach_preserve_blk_ctx(void)
26
{
33
{
27
BdrvChild *parent_child;
34
IOThread *iothread = iothread_new();
28
BlockDriverState *filter_or_cow_bs;
35
AioContext *ctx = iothread_get_aio_context(iothread);
29
@@ -XXX,XX +XXX,XX @@ BlockStatsList *qmp_query_blockstats(bool has_query_nodes,
36
+ AioContext *main_ctx = qemu_get_aio_context();
30
BlockBackend *blk;
37
BlockBackend *blk;
31
BlockDriverState *bs;
38
BlockDriverState *bs;
32
39
33
+ GRAPH_RDLOCK_GUARD_MAINLOOP();
40
+ aio_context_acquire(main_ctx);
34
+
41
blk = blk_new(ctx, BLK_PERM_ALL, BLK_PERM_ALL);
35
/* Just to be safe if query_nodes is not always initialized */
42
bs = bdrv_new_open_driver(&bdrv_test, "base", BDRV_O_RDWR, &error_abort);
36
if (has_query_nodes && query_nodes) {
43
bs->total_sectors = 65536 / BDRV_SECTOR_SIZE;
37
for (bs = bdrv_next_node(NULL); bs; bs = bdrv_next_node(bs)) {
44
@@ -XXX,XX +XXX,XX @@ static void test_attach_preserve_blk_ctx(void)
45
blk_insert_bs(blk, bs, &error_abort);
46
g_assert(blk_get_aio_context(blk) == ctx);
47
g_assert(bdrv_get_aio_context(bs) == ctx);
48
+ aio_context_release(main_ctx);
49
50
/* Remove the node again */
51
aio_context_acquire(ctx);
52
@@ -XXX,XX +XXX,XX @@ static void test_attach_preserve_blk_ctx(void)
53
g_assert(bdrv_get_aio_context(bs) == qemu_get_aio_context());
54
55
/* Re-attach the node */
56
+ aio_context_acquire(main_ctx);
57
blk_insert_bs(blk, bs, &error_abort);
58
+ aio_context_release(main_ctx);
59
g_assert(blk_get_aio_context(blk) == ctx);
60
g_assert(bdrv_get_aio_context(bs) == ctx);
61
38
--
62
--
39
2.40.1
63
2.41.0
diff view generated by jsdifflib
1
This adds GRAPH_RDLOCK annotations to declare that functions accessing
1
bdrv_attach_child() requires that the caller holds the AioContext lock
2
the parent list of a node need to hold a reader lock for the graph. As
2
for the new child node. Take it in bdrv_open_child() and document that
3
it happens, they already do.
3
the caller must not hold any AioContext apart from the main AioContext.
4
4
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Message-Id: <20230504115750.54437-13-kwolf@redhat.com>
6
Message-ID: <20230605085711.21261-5-kwolf@redhat.com>
7
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
7
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
9
---
11
block/mirror.c | 2 +-
10
block.c | 13 +++++++++++--
12
1 file changed, 1 insertion(+), 1 deletion(-)
11
1 file changed, 11 insertions(+), 2 deletions(-)
13
12
14
diff --git a/block/mirror.c b/block/mirror.c
13
diff --git a/block.c b/block.c
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/block/mirror.c
15
--- a/block.c
17
+++ b/block/mirror.c
16
+++ b/block.c
18
@@ -XXX,XX +XXX,XX @@ static MirrorOp *coroutine_fn active_write_prepare(MirrorBlockJob *s,
17
@@ -XXX,XX +XXX,XX @@ done:
19
return op;
18
*
19
* The BlockdevRef will be removed from the options QDict.
20
*
21
+ * The caller must hold the lock of the main AioContext and no other AioContext.
22
* @parent can move to a different AioContext in this function. Callers must
23
* make sure that their AioContext locking is still correct after this.
24
*/
25
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_open_child(const char *filename,
26
bool allow_none, Error **errp)
27
{
28
BlockDriverState *bs;
29
+ BdrvChild *child;
30
+ AioContext *ctx;
31
32
GLOBAL_STATE_CODE();
33
34
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_open_child(const char *filename,
35
return NULL;
36
}
37
38
- return bdrv_attach_child(parent, bs, bdref_key, child_class, child_role,
39
- errp);
40
+ ctx = bdrv_get_aio_context(bs);
41
+ aio_context_acquire(ctx);
42
+ child = bdrv_attach_child(parent, bs, bdref_key, child_class, child_role,
43
+ errp);
44
+ aio_context_release(ctx);
45
+
46
+ return child;
20
}
47
}
21
48
22
-static void coroutine_fn active_write_settle(MirrorOp *op)
49
/*
23
+static void coroutine_fn GRAPH_RDLOCK active_write_settle(MirrorOp *op)
50
* Wrapper on bdrv_open_child() for most popular case: open primary child of bs.
24
{
51
*
25
uint64_t start_chunk = op->offset / op->s->granularity;
52
+ * The caller must hold the lock of the main AioContext and no other AioContext.
26
uint64_t end_chunk = DIV_ROUND_UP(op->offset + op->bytes,
53
* @parent can move to a different AioContext in this function. Callers must
54
* make sure that their AioContext locking is still correct after this.
55
*/
27
--
56
--
28
2.40.1
57
2.41.0
diff view generated by jsdifflib
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
The function can move the child node to a different AioContext. In this
2
case, it also must take the AioContext lock for the new context before
3
calling functions that require the caller to hold the AioContext for the
4
child node.
2
5
3
This adds GRAPH_RDLOCK annotations to declare that callers of
4
bdrv_co_get_allocated_file_size() need to hold a reader lock for the
5
graph.
6
7
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Reviewed-by: Eric Blake <eblake@redhat.com>
7
Message-ID: <20230605085711.21261-6-kwolf@redhat.com>
10
Message-Id: <20230504115750.54437-14-kwolf@redhat.com>
11
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
10
---
14
include/block/block-io.h | 7 +++++--
11
block.c | 21 ++++++++++++++++++++-
15
include/block/block_int-common.h | 2 +-
12
1 file changed, 20 insertions(+), 1 deletion(-)
16
block.c | 4 +++-
17
block/vmdk.c | 2 +-
18
4 files changed, 10 insertions(+), 5 deletions(-)
19
13
20
diff --git a/include/block/block-io.h b/include/block/block-io.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/include/block/block-io.h
23
+++ b/include/block/block-io.h
24
@@ -XXX,XX +XXX,XX @@ int64_t coroutine_mixed_fn bdrv_nb_sectors(BlockDriverState *bs);
25
int64_t coroutine_fn GRAPH_RDLOCK bdrv_co_getlength(BlockDriverState *bs);
26
int64_t co_wrapper_mixed_bdrv_rdlock bdrv_getlength(BlockDriverState *bs);
27
28
-int64_t coroutine_fn bdrv_co_get_allocated_file_size(BlockDriverState *bs);
29
-int64_t co_wrapper bdrv_get_allocated_file_size(BlockDriverState *bs);
30
+int64_t coroutine_fn GRAPH_RDLOCK
31
+bdrv_co_get_allocated_file_size(BlockDriverState *bs);
32
+
33
+int64_t co_wrapper_bdrv_rdlock
34
+bdrv_get_allocated_file_size(BlockDriverState *bs);
35
36
BlockMeasureInfo *bdrv_measure(BlockDriver *drv, QemuOpts *opts,
37
BlockDriverState *in_bs, Error **errp);
38
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
39
index XXXXXXX..XXXXXXX 100644
40
--- a/include/block/block_int-common.h
41
+++ b/include/block/block_int-common.h
42
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
43
int64_t coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_getlength)(
44
BlockDriverState *bs);
45
46
- int64_t coroutine_fn (*bdrv_co_get_allocated_file_size)(
47
+ int64_t coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_get_allocated_file_size)(
48
BlockDriverState *bs);
49
50
BlockMeasureInfo *(*bdrv_measure)(QemuOpts *opts, BlockDriverState *in_bs,
51
diff --git a/block.c b/block.c
14
diff --git a/block.c b/block.c
52
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
53
--- a/block.c
16
--- a/block.c
54
+++ b/block.c
17
+++ b/block.c
55
@@ -XXX,XX +XXX,XX @@ exit:
18
@@ -XXX,XX +XXX,XX @@ static TransactionActionDrv bdrv_attach_child_common_drv = {
56
* sums the size of all data-bearing children. (This excludes backing
19
* Function doesn't update permissions, caller is responsible for this.
57
* children.)
20
*
21
* Returns new created child.
22
+ *
23
+ * The caller must hold the AioContext lock for @child_bs. Both @parent_bs and
24
+ * @child_bs can move to a different AioContext in this function. Callers must
25
+ * make sure that their AioContext locking is still correct after this.
58
*/
26
*/
59
-static int64_t coroutine_fn bdrv_sum_allocated_file_size(BlockDriverState *bs)
27
static BdrvChild *bdrv_attach_child_common(BlockDriverState *child_bs,
60
+static int64_t coroutine_fn GRAPH_RDLOCK
28
const char *child_name,
61
+bdrv_sum_allocated_file_size(BlockDriverState *bs)
29
@@ -XXX,XX +XXX,XX @@ static BdrvChild *bdrv_attach_child_common(BlockDriverState *child_bs,
30
Transaction *tran, Error **errp)
62
{
31
{
63
BdrvChild *child;
32
BdrvChild *new_child;
64
int64_t child_size, sum = 0;
33
- AioContext *parent_ctx;
65
@@ -XXX,XX +XXX,XX @@ int64_t coroutine_fn bdrv_co_get_allocated_file_size(BlockDriverState *bs)
34
+ AioContext *parent_ctx, *new_child_ctx;
66
{
35
AioContext *child_ctx = bdrv_get_aio_context(child_bs);
67
BlockDriver *drv = bs->drv;
36
68
IO_CODE();
37
assert(child_class->get_parent_desc);
69
+ assert_bdrv_graph_readable();
38
@@ -XXX,XX +XXX,XX @@ static BdrvChild *bdrv_attach_child_common(BlockDriverState *child_bs,
70
39
}
71
if (!drv) {
40
}
72
return -ENOMEDIUM;
41
73
diff --git a/block/vmdk.c b/block/vmdk.c
42
+ new_child_ctx = bdrv_get_aio_context(child_bs);
74
index XXXXXXX..XXXXXXX 100644
43
+ if (new_child_ctx != child_ctx) {
75
--- a/block/vmdk.c
44
+ aio_context_release(child_ctx);
76
+++ b/block/vmdk.c
45
+ aio_context_acquire(new_child_ctx);
77
@@ -XXX,XX +XXX,XX @@ static void vmdk_close(BlockDriverState *bs)
46
+ }
78
error_free(s->migration_blocker);
47
+
48
bdrv_ref(child_bs);
49
/*
50
* Let every new BdrvChild start with a drained parent. Inserting the child
51
@@ -XXX,XX +XXX,XX @@ static BdrvChild *bdrv_attach_child_common(BlockDriverState *child_bs,
52
};
53
tran_add(tran, &bdrv_attach_child_common_drv, s);
54
55
+ if (new_child_ctx != child_ctx) {
56
+ aio_context_release(new_child_ctx);
57
+ aio_context_acquire(child_ctx);
58
+ }
59
+
60
return new_child;
79
}
61
}
80
62
81
-static int64_t coroutine_fn
63
/*
82
+static int64_t coroutine_fn GRAPH_RDLOCK
64
* Function doesn't update permissions, caller is responsible for this.
83
vmdk_co_get_allocated_file_size(BlockDriverState *bs)
65
+ *
84
{
66
+ * The caller must hold the AioContext lock for @child_bs. Both @parent_bs and
85
int i;
67
+ * @child_bs can move to a different AioContext in this function. Callers must
68
+ * make sure that their AioContext locking is still correct after this.
69
*/
70
static BdrvChild *bdrv_attach_child_noperm(BlockDriverState *parent_bs,
71
BlockDriverState *child_bs,
86
--
72
--
87
2.40.1
73
2.41.0
diff view generated by jsdifflib
1
For some functions, it is part of their interface to be called without
1
bdrv_set_file_or_backing_noperm() requires the caller to hold the
2
holding the graph lock. Add a new macro to document this.
2
AioContext lock for the child node, but we hold the one for the parent
3
3
node in bdrv_reopen_parse_file_or_backing(). Take the other one
4
The macro expands to TSA_EXCLUDES(), which is a relatively weak check
4
temporarily.
5
because it passes in cases where the compiler just doesn't know if the
6
lock is held. Function pointers can't be checked at all. Therefore, its
7
primary purpose is documentation.
8
5
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Reviewed-by: Eric Blake <eblake@redhat.com>
7
Message-ID: <20230605085711.21261-7-kwolf@redhat.com>
11
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
12
Message-Id: <20230504115750.54437-7-kwolf@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
10
---
15
include/block/graph-lock.h | 2 ++
11
block.c | 35 +++++++++++++++++++++++++++++++++--
16
1 file changed, 2 insertions(+)
12
1 file changed, 33 insertions(+), 2 deletions(-)
17
13
18
diff --git a/include/block/graph-lock.h b/include/block/graph-lock.h
14
diff --git a/block.c b/block.c
19
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
20
--- a/include/block/graph-lock.h
16
--- a/block.c
21
+++ b/include/block/graph-lock.h
17
+++ b/block.c
22
@@ -XXX,XX +XXX,XX @@ extern BdrvGraphLock graph_lock;
18
@@ -XXX,XX +XXX,XX @@ static BdrvChildRole bdrv_backing_role(BlockDriverState *bs)
19
* callers which don't need their own reference any more must call bdrv_unref().
20
*
21
* Function doesn't update permissions, caller is responsible for this.
22
+ *
23
+ * The caller must hold the AioContext lock for @child_bs. Both @parent_bs and
24
+ * @child_bs can move to a different AioContext in this function. Callers must
25
+ * make sure that their AioContext locking is still correct after this.
23
*/
26
*/
24
#define GRAPH_WRLOCK TSA_REQUIRES(graph_lock)
27
static int bdrv_set_file_or_backing_noperm(BlockDriverState *parent_bs,
25
#define GRAPH_RDLOCK TSA_REQUIRES_SHARED(graph_lock)
28
BlockDriverState *child_bs,
26
+#define GRAPH_UNLOCKED TSA_EXCLUDES(graph_lock)
29
@@ -XXX,XX +XXX,XX @@ out:
30
return 0;
31
}
32
33
+/*
34
+ * The caller must hold the AioContext lock for @backing_hd. Both @bs and
35
+ * @backing_hd can move to a different AioContext in this function. Callers must
36
+ * make sure that their AioContext locking is still correct after this.
37
+ */
38
static int bdrv_set_backing_noperm(BlockDriverState *bs,
39
BlockDriverState *backing_hd,
40
Transaction *tran, Error **errp)
41
@@ -XXX,XX +XXX,XX @@ int bdrv_reopen_set_read_only(BlockDriverState *bs, bool read_only,
42
* backing BlockDriverState (or NULL).
43
*
44
* Return 0 on success, otherwise return < 0 and set @errp.
45
+ *
46
+ * The caller must hold the AioContext lock of @reopen_state->bs.
47
+ * @reopen_state->bs can move to a different AioContext in this function.
48
+ * Callers must make sure that their AioContext locking is still correct after
49
+ * this.
50
*/
51
static int bdrv_reopen_parse_file_or_backing(BDRVReopenState *reopen_state,
52
bool is_backing, Transaction *tran,
53
@@ -XXX,XX +XXX,XX @@ static int bdrv_reopen_parse_file_or_backing(BDRVReopenState *reopen_state,
54
const char *child_name = is_backing ? "backing" : "file";
55
QObject *value;
56
const char *str;
57
+ AioContext *ctx, *old_ctx;
58
+ int ret;
59
60
GLOBAL_STATE_CODE();
61
62
@@ -XXX,XX +XXX,XX @@ static int bdrv_reopen_parse_file_or_backing(BDRVReopenState *reopen_state,
63
reopen_state->old_file_bs = old_child_bs;
64
}
65
66
- return bdrv_set_file_or_backing_noperm(bs, new_child_bs, is_backing,
67
- tran, errp);
68
+ old_ctx = bdrv_get_aio_context(bs);
69
+ ctx = bdrv_get_aio_context(new_child_bs);
70
+ if (old_ctx != ctx) {
71
+ aio_context_release(old_ctx);
72
+ aio_context_acquire(ctx);
73
+ }
74
+
75
+ ret = bdrv_set_file_or_backing_noperm(bs, new_child_bs, is_backing,
76
+ tran, errp);
77
+
78
+ if (old_ctx != ctx) {
79
+ aio_context_release(ctx);
80
+ aio_context_acquire(old_ctx);
81
+ }
82
+
83
+ return ret;
84
}
27
85
28
/*
86
/*
29
* TSA annotations are not part of function types, so checks are defeated when
87
@@ -XXX,XX +XXX,XX @@ static int bdrv_reopen_parse_file_or_backing(BDRVReopenState *reopen_state,
30
@@ -XXX,XX +XXX,XX @@ extern BdrvGraphLock graph_lock;
88
* It is the responsibility of the caller to then call the abort() or
89
* commit() for any other BDS that have been left in a prepare() state
90
*
91
+ * The caller must hold the AioContext lock of @reopen_state->bs.
31
*/
92
*/
32
#define GRAPH_RDLOCK_PTR TSA_GUARDED_BY(graph_lock)
93
static int bdrv_reopen_prepare(BDRVReopenState *reopen_state,
33
#define GRAPH_WRLOCK_PTR TSA_GUARDED_BY(graph_lock)
94
BlockReopenQueue *queue,
34
+#define GRAPH_UNLOCKED_PTR
35
36
/*
37
* register_aiocontext:
38
--
95
--
39
2.40.1
96
2.41.0
diff view generated by jsdifflib
1
This adds GRAPH_RDLOCK annotations to declare that callers of
1
bdrv_open_inherit() calls several functions for which it needs to hold
2
bdrv_refresh_limits() need to hold a reader lock for the graph because
2
the AioContext lock, but currently doesn't. This includes calls in
3
it accesses the children list of a node.
3
bdrv_append_temp_snapshot(), for which bdrv_open_inherit() is the only
4
caller. Fix the locking in these places.
4
5
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Eric Blake <eblake@redhat.com>
7
Message-ID: <20230605085711.21261-8-kwolf@redhat.com>
7
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
8
Message-Id: <20230504115750.54437-21-kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
10
---
11
include/block/block-global-state.h | 5 ++++-
11
block.c | 25 ++++++++++++++++++++++++-
12
include/block/block_int-common.h | 3 ++-
12
1 file changed, 24 insertions(+), 1 deletion(-)
13
block.c | 9 +++++++++
14
block/io.c | 1 -
15
4 files changed, 15 insertions(+), 3 deletions(-)
16
13
17
diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/block/block-global-state.h
20
+++ b/include/block/block-global-state.h
21
@@ -XXX,XX +XXX,XX @@ int bdrv_reopen_set_read_only(BlockDriverState *bs, bool read_only,
22
BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
23
const char *backing_file);
24
void bdrv_refresh_filename(BlockDriverState *bs);
25
-void bdrv_refresh_limits(BlockDriverState *bs, Transaction *tran, Error **errp);
26
+
27
+void GRAPH_RDLOCK
28
+bdrv_refresh_limits(BlockDriverState *bs, Transaction *tran, Error **errp);
29
+
30
int bdrv_commit(BlockDriverState *bs);
31
int bdrv_make_empty(BdrvChild *c, Error **errp);
32
int bdrv_change_backing_file(BlockDriverState *bs, const char *backing_file,
33
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
34
index XXXXXXX..XXXXXXX 100644
35
--- a/include/block/block_int-common.h
36
+++ b/include/block/block_int-common.h
37
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
38
int (*bdrv_debug_resume)(BlockDriverState *bs, const char *tag);
39
bool (*bdrv_debug_is_suspended)(BlockDriverState *bs, const char *tag);
40
41
- void (*bdrv_refresh_limits)(BlockDriverState *bs, Error **errp);
42
+ void GRAPH_RDLOCK_PTR (*bdrv_refresh_limits)(
43
+ BlockDriverState *bs, Error **errp);
44
45
/*
46
* Returns 1 if newly created images are guaranteed to contain only
47
diff --git a/block.c b/block.c
14
diff --git a/block.c b/block.c
48
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
49
--- a/block.c
16
--- a/block.c
50
+++ b/block.c
17
+++ b/block.c
51
@@ -XXX,XX +XXX,XX @@ bdrv_open_driver(BlockDriverState *bs, BlockDriver *drv, const char *node_name,
18
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_append_temp_snapshot(BlockDriverState *bs,
52
return ret;
19
int64_t total_size;
20
QemuOpts *opts = NULL;
21
BlockDriverState *bs_snapshot = NULL;
22
+ AioContext *ctx = bdrv_get_aio_context(bs);
23
int ret;
24
25
GLOBAL_STATE_CODE();
26
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_append_temp_snapshot(BlockDriverState *bs,
27
instead of opening 'filename' directly */
28
29
/* Get the required size from the image */
30
+ aio_context_acquire(ctx);
31
total_size = bdrv_getlength(bs);
32
+ aio_context_release(ctx);
33
+
34
if (total_size < 0) {
35
error_setg_errno(errp, -total_size, "Could not get image size");
36
goto out;
37
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_append_temp_snapshot(BlockDriverState *bs,
38
goto out;
53
}
39
}
54
40
55
+ bdrv_graph_rdlock_main_loop();
41
+ aio_context_acquire(ctx);
56
bdrv_refresh_limits(bs, NULL, &local_err);
42
ret = bdrv_append(bs_snapshot, bs, errp);
57
+ bdrv_graph_rdunlock_main_loop();
43
+ aio_context_release(ctx);
58
+
44
+
59
if (local_err) {
45
if (ret < 0) {
60
error_propagate(errp, local_err);
46
bs_snapshot = NULL;
61
return -EINVAL;
47
goto out;
62
@@ -XXX,XX +XXX,XX @@ static int bdrv_set_file_or_backing_noperm(BlockDriverState *parent_bs,
48
@@ -XXX,XX +XXX,XX @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options,
49
Error *local_err = NULL;
50
QDict *snapshot_options = NULL;
51
int snapshot_flags = 0;
52
+ AioContext *ctx = qemu_get_aio_context();
53
54
assert(!child_class || !flags);
55
assert(!child_class == !parent);
56
@@ -XXX,XX +XXX,XX @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options,
57
/* Not requesting BLK_PERM_CONSISTENT_READ because we're only
58
* looking at the header to guess the image format. This works even
59
* in cases where a guest would not see a consistent state. */
60
- file = blk_new(bdrv_get_aio_context(file_bs), 0, BLK_PERM_ALL);
61
+ ctx = bdrv_get_aio_context(file_bs);
62
+ aio_context_acquire(ctx);
63
+ file = blk_new(ctx, 0, BLK_PERM_ALL);
64
blk_insert_bs(file, file_bs, &local_err);
65
bdrv_unref(file_bs);
66
+ aio_context_release(ctx);
67
+
68
if (local_err) {
69
goto fail;
70
}
71
@@ -XXX,XX +XXX,XX @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options,
72
goto fail;
63
}
73
}
64
74
65
out:
75
+ /* The AioContext could have changed during bdrv_open_common() */
66
+ bdrv_graph_rdlock_main_loop();
76
+ ctx = bdrv_get_aio_context(bs);
67
bdrv_refresh_limits(parent_bs, tran, NULL);
77
+
68
+ bdrv_graph_rdunlock_main_loop();
78
if (file) {
69
79
+ aio_context_acquire(ctx);
70
return 0;
80
blk_unref(file);
71
}
81
+ aio_context_release(ctx);
72
@@ -XXX,XX +XXX,XX @@ static void bdrv_reopen_commit(BDRVReopenState *reopen_state)
82
file = NULL;
73
qdict_del(bs->explicit_options, "backing");
83
}
74
qdict_del(bs->options, "backing");
84
75
85
@@ -XXX,XX +XXX,XX @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options,
76
+ bdrv_graph_rdlock_main_loop();
86
* (snapshot_bs); thus, we have to drop the strong reference to bs
77
bdrv_refresh_limits(bs, NULL, NULL);
87
* (which we obtained by calling bdrv_new()). bs will not be deleted,
78
+ bdrv_graph_rdunlock_main_loop();
88
* though, because the overlay still has a reference to it. */
79
bdrv_refresh_total_sectors(bs, bs->total_sectors);
89
+ aio_context_acquire(ctx);
80
}
90
bdrv_unref(bs);
81
91
+ aio_context_release(ctx);
82
@@ -XXX,XX +XXX,XX @@ int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top,
92
bs = snapshot_bs;
83
out:
93
}
84
tran_finalize(tran, ret);
94
85
95
return bs;
86
+ bdrv_graph_rdlock_main_loop();
96
87
bdrv_refresh_limits(bs_top, NULL, NULL);
97
fail:
88
+ bdrv_graph_rdunlock_main_loop();
98
+ aio_context_acquire(ctx);
89
99
blk_unref(file);
90
if (new_context && old_context != new_context) {
100
qobject_unref(snapshot_options);
91
aio_context_release(new_context);
101
qobject_unref(bs->explicit_options);
92
diff --git a/block/io.c b/block/io.c
102
@@ -XXX,XX +XXX,XX @@ fail:
93
index XXXXXXX..XXXXXXX 100644
103
bs->options = NULL;
94
--- a/block/io.c
104
bs->explicit_options = NULL;
95
+++ b/block/io.c
105
bdrv_unref(bs);
96
@@ -XXX,XX +XXX,XX @@ void bdrv_refresh_limits(BlockDriverState *bs, Transaction *tran, Error **errp)
106
+ aio_context_release(ctx);
97
bool have_limits;
107
error_propagate(errp, local_err);
98
108
return NULL;
99
GLOBAL_STATE_CODE();
109
100
- assume_graph_lock(); /* FIXME */
110
close_and_fail:
101
111
+ aio_context_acquire(ctx);
102
if (tran) {
112
bdrv_unref(bs);
103
BdrvRefreshLimitsState *s = g_new(BdrvRefreshLimitsState, 1);
113
+ aio_context_release(ctx);
114
qobject_unref(snapshot_options);
115
qobject_unref(options);
116
error_propagate(errp, local_err);
104
--
117
--
105
2.40.1
118
2.41.0
diff view generated by jsdifflib
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
bdrv_set_backing() requires the caller to hold the AioContext lock for
2
@backing_hd. Take it in bdrv_open_backing_file() before calling the
3
function.
2
4
3
This adds GRAPH_RDLOCK annotations to declare that callers of
4
bdrv_co_debug_event() need to hold a reader lock for the graph.
5
6
Unfortunately we cannot use a co_wrapper_bdrv_rdlock (i.e. make the
7
coroutine wrapper a no_coroutine_fn), because the function is called
8
(using the BLKDBG_EVENT macro) by mixed functions that run both in
9
coroutine and non-coroutine context (for example many of the functions
10
in qcow2-cluster.c and qcow2-refcount.c).
11
12
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
Reviewed-by: Eric Blake <eblake@redhat.com>
6
Message-ID: <20230605085711.21261-9-kwolf@redhat.com>
15
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
7
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
16
Message-Id: <20230504115750.54437-16-kwolf@redhat.com>
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
---
9
---
19
include/block/block-io.h | 9 +++++----
10
block.c | 5 +++++
20
include/block/block_int-common.h | 4 ++--
11
1 file changed, 5 insertions(+)
21
block.c | 2 ++
22
3 files changed, 9 insertions(+), 6 deletions(-)
23
12
24
diff --git a/include/block/block-io.h b/include/block/block-io.h
25
index XXXXXXX..XXXXXXX 100644
26
--- a/include/block/block-io.h
27
+++ b/include/block/block-io.h
28
@@ -XXX,XX +XXX,XX @@ void *qemu_try_blockalign0(BlockDriverState *bs, size_t size);
29
void bdrv_enable_copy_on_read(BlockDriverState *bs);
30
void bdrv_disable_copy_on_read(BlockDriverState *bs);
31
32
-void coroutine_fn bdrv_co_debug_event(BlockDriverState *bs,
33
- BlkdebugEvent event);
34
-void co_wrapper_mixed bdrv_debug_event(BlockDriverState *bs,
35
- BlkdebugEvent event);
36
+void coroutine_fn GRAPH_RDLOCK
37
+bdrv_co_debug_event(BlockDriverState *bs, BlkdebugEvent event);
38
+
39
+void co_wrapper_mixed_bdrv_rdlock
40
+bdrv_debug_event(BlockDriverState *bs, BlkdebugEvent event);
41
42
#define BLKDBG_EVENT(child, evt) \
43
do { \
44
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
45
index XXXXXXX..XXXXXXX 100644
46
--- a/include/block/block_int-common.h
47
+++ b/include/block/block_int-common.h
48
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
49
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_check)(
50
BlockDriverState *bs, BdrvCheckResult *result, BdrvCheckMode fix);
51
52
- void coroutine_fn (*bdrv_co_debug_event)(BlockDriverState *bs,
53
- BlkdebugEvent event);
54
+ void coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_debug_event)(
55
+ BlockDriverState *bs, BlkdebugEvent event);
56
57
/* io queue for linux-aio */
58
void coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_io_plug)(BlockDriverState *bs);
59
diff --git a/block.c b/block.c
13
diff --git a/block.c b/block.c
60
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
61
--- a/block.c
15
--- a/block.c
62
+++ b/block.c
16
+++ b/block.c
63
@@ -XXX,XX +XXX,XX @@ BlockStatsSpecific *bdrv_get_specific_stats(BlockDriverState *bs)
17
@@ -XXX,XX +XXX,XX @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
64
void coroutine_fn bdrv_co_debug_event(BlockDriverState *bs, BlkdebugEvent event)
18
int ret = 0;
65
{
19
bool implicit_backing = false;
66
IO_CODE();
20
BlockDriverState *backing_hd;
67
+ assert_bdrv_graph_readable();
21
+ AioContext *backing_hd_ctx;
22
QDict *options;
23
QDict *tmp_parent_options = NULL;
24
Error *local_err = NULL;
25
@@ -XXX,XX +XXX,XX @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
26
27
/* Hook up the backing file link; drop our reference, bs owns the
28
* backing_hd reference now */
29
+ backing_hd_ctx = bdrv_get_aio_context(backing_hd);
30
+ aio_context_acquire(backing_hd_ctx);
31
ret = bdrv_set_backing_hd(bs, backing_hd, errp);
32
bdrv_unref(backing_hd);
33
+ aio_context_release(backing_hd_ctx);
68
+
34
+
69
if (!bs || !bs->drv || !bs->drv->bdrv_co_debug_event) {
35
if (ret < 0) {
70
return;
36
goto free_exit;
71
}
37
}
72
--
38
--
73
2.40.1
39
2.41.0
diff view generated by jsdifflib
1
test-bdrv-drain contains a few test cases that are run both in coroutine
1
bdrv_root_attach_child() requires callers to hold the AioContext lock
2
and non-coroutine context. Running the entire code including the setup
2
for child_bs. Take it in block_job_add_bdrv() before calling the
3
and shutdown in coroutines is incorrect because graph modifications can
3
function.
4
generally not happen in coroutines.
5
6
Change the test so that creating and destroying the test nodes and
7
BlockBackends always happens outside of coroutine context.
8
4
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Reviewed-by: Eric Blake <eblake@redhat.com>
6
Message-ID: <20230605085711.21261-10-kwolf@redhat.com>
11
Message-Id: <20230504115750.54437-6-kwolf@redhat.com>
12
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
7
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
9
---
15
tests/unit/test-bdrv-drain.c | 112 +++++++++++++++++++++++------------
10
blockjob.c | 17 ++++++++++++-----
16
1 file changed, 75 insertions(+), 37 deletions(-)
11
1 file changed, 12 insertions(+), 5 deletions(-)
17
12
18
diff --git a/tests/unit/test-bdrv-drain.c b/tests/unit/test-bdrv-drain.c
13
diff --git a/blockjob.c b/blockjob.c
19
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
20
--- a/tests/unit/test-bdrv-drain.c
15
--- a/blockjob.c
21
+++ b/tests/unit/test-bdrv-drain.c
16
+++ b/blockjob.c
22
@@ -XXX,XX +XXX,XX @@ static void do_drain_begin_unlocked(enum drain_type drain_type, BlockDriverState
17
@@ -XXX,XX +XXX,XX @@ int block_job_add_bdrv(BlockJob *job, const char *name, BlockDriverState *bs,
18
uint64_t perm, uint64_t shared_perm, Error **errp)
19
{
20
BdrvChild *c;
21
+ AioContext *ctx = bdrv_get_aio_context(bs);
22
bool need_context_ops;
23
GLOBAL_STATE_CODE();
24
25
bdrv_ref(bs);
26
27
- need_context_ops = bdrv_get_aio_context(bs) != job->job.aio_context;
28
+ need_context_ops = ctx != job->job.aio_context;
29
30
- if (need_context_ops && job->job.aio_context != qemu_get_aio_context()) {
31
- aio_context_release(job->job.aio_context);
32
+ if (need_context_ops) {
33
+ if (job->job.aio_context != qemu_get_aio_context()) {
34
+ aio_context_release(job->job.aio_context);
35
+ }
36
+ aio_context_acquire(ctx);
23
}
37
}
24
}
38
c = bdrv_root_attach_child(bs, name, &child_job, 0, perm, shared_perm, job,
25
39
errp);
26
+static BlockBackend * no_coroutine_fn test_setup(void)
40
- if (need_context_ops && job->job.aio_context != qemu_get_aio_context()) {
27
+{
41
- aio_context_acquire(job->job.aio_context);
28
+ BlockBackend *blk;
42
+ if (need_context_ops) {
29
+ BlockDriverState *bs, *backing;
43
+ aio_context_release(ctx);
30
+
44
+ if (job->job.aio_context != qemu_get_aio_context()) {
31
+ blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
45
+ aio_context_acquire(job->job.aio_context);
32
+ bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR,
46
+ }
33
+ &error_abort);
34
+ blk_insert_bs(blk, bs, &error_abort);
35
+
36
+ backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abort);
37
+ bdrv_set_backing_hd(bs, backing, &error_abort);
38
+
39
+ bdrv_unref(backing);
40
+ bdrv_unref(bs);
41
+
42
+ return blk;
43
+}
44
+
45
static void do_drain_end_unlocked(enum drain_type drain_type, BlockDriverState *bs)
46
{
47
if (drain_type != BDRV_DRAIN_ALL) {
48
@@ -XXX,XX +XXX,XX @@ static void do_drain_end_unlocked(enum drain_type drain_type, BlockDriverState *
49
}
47
}
50
}
48
if (c == NULL) {
51
49
return -EPERM;
52
-static void test_drv_cb_common(enum drain_type drain_type, bool recursive)
53
+static void test_drv_cb_common(BlockBackend *blk, enum drain_type drain_type,
54
+ bool recursive)
55
{
56
- BlockBackend *blk;
57
- BlockDriverState *bs, *backing;
58
+ BlockDriverState *bs = blk_bs(blk);
59
+ BlockDriverState *backing = bs->backing->bs;
60
BDRVTestState *s, *backing_s;
61
BlockAIOCB *acb;
62
int aio_ret;
63
64
QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, NULL, 0);
65
66
- blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
67
- bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR,
68
- &error_abort);
69
s = bs->opaque;
70
- blk_insert_bs(blk, bs, &error_abort);
71
-
72
- backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abort);
73
backing_s = backing->opaque;
74
- bdrv_set_backing_hd(bs, backing, &error_abort);
75
76
/* Simple bdrv_drain_all_begin/end pair, check that CBs are called */
77
g_assert_cmpint(s->drain_count, ==, 0);
78
@@ -XXX,XX +XXX,XX @@ static void test_drv_cb_common(enum drain_type drain_type, bool recursive)
79
80
g_assert_cmpint(s->drain_count, ==, 0);
81
g_assert_cmpint(backing_s->drain_count, ==, 0);
82
-
83
- bdrv_unref(backing);
84
- bdrv_unref(bs);
85
- blk_unref(blk);
86
}
87
88
static void test_drv_cb_drain_all(void)
89
{
90
- test_drv_cb_common(BDRV_DRAIN_ALL, true);
91
+ BlockBackend *blk = test_setup();
92
+ test_drv_cb_common(blk, BDRV_DRAIN_ALL, true);
93
+ blk_unref(blk);
94
}
95
96
static void test_drv_cb_drain(void)
97
{
98
- test_drv_cb_common(BDRV_DRAIN, false);
99
+ BlockBackend *blk = test_setup();
100
+ test_drv_cb_common(blk, BDRV_DRAIN, false);
101
+ blk_unref(blk);
102
+}
103
+
104
+static void coroutine_fn test_drv_cb_co_drain_all_entry(void)
105
+{
106
+ BlockBackend *blk = blk_all_next(NULL);
107
+ test_drv_cb_common(blk, BDRV_DRAIN_ALL, true);
108
}
109
110
static void test_drv_cb_co_drain_all(void)
111
{
112
- call_in_coroutine(test_drv_cb_drain_all);
113
+ BlockBackend *blk = test_setup();
114
+ call_in_coroutine(test_drv_cb_co_drain_all_entry);
115
+ blk_unref(blk);
116
}
117
118
-static void test_drv_cb_co_drain(void)
119
+static void coroutine_fn test_drv_cb_co_drain_entry(void)
120
{
121
- call_in_coroutine(test_drv_cb_drain);
122
+ BlockBackend *blk = blk_all_next(NULL);
123
+ test_drv_cb_common(blk, BDRV_DRAIN, false);
124
}
125
126
-static void test_quiesce_common(enum drain_type drain_type, bool recursive)
127
+static void test_drv_cb_co_drain(void)
128
{
129
- BlockBackend *blk;
130
- BlockDriverState *bs, *backing;
131
-
132
- blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
133
- bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR,
134
- &error_abort);
135
- blk_insert_bs(blk, bs, &error_abort);
136
+ BlockBackend *blk = test_setup();
137
+ call_in_coroutine(test_drv_cb_co_drain_entry);
138
+ blk_unref(blk);
139
+}
140
141
- backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abort);
142
- bdrv_set_backing_hd(bs, backing, &error_abort);
143
+static void test_quiesce_common(BlockBackend *blk, enum drain_type drain_type,
144
+ bool recursive)
145
+{
146
+ BlockDriverState *bs = blk_bs(blk);
147
+ BlockDriverState *backing = bs->backing->bs;
148
149
g_assert_cmpint(bs->quiesce_counter, ==, 0);
150
g_assert_cmpint(backing->quiesce_counter, ==, 0);
151
@@ -XXX,XX +XXX,XX @@ static void test_quiesce_common(enum drain_type drain_type, bool recursive)
152
153
g_assert_cmpint(bs->quiesce_counter, ==, 0);
154
g_assert_cmpint(backing->quiesce_counter, ==, 0);
155
-
156
- bdrv_unref(backing);
157
- bdrv_unref(bs);
158
- blk_unref(blk);
159
}
160
161
static void test_quiesce_drain_all(void)
162
{
163
- test_quiesce_common(BDRV_DRAIN_ALL, true);
164
+ BlockBackend *blk = test_setup();
165
+ test_quiesce_common(blk, BDRV_DRAIN_ALL, true);
166
+ blk_unref(blk);
167
}
168
169
static void test_quiesce_drain(void)
170
{
171
- test_quiesce_common(BDRV_DRAIN, false);
172
+ BlockBackend *blk = test_setup();
173
+ test_quiesce_common(blk, BDRV_DRAIN, false);
174
+ blk_unref(blk);
175
+}
176
+
177
+static void coroutine_fn test_quiesce_co_drain_all_entry(void)
178
+{
179
+ BlockBackend *blk = blk_all_next(NULL);
180
+ test_quiesce_common(blk, BDRV_DRAIN_ALL, true);
181
}
182
183
static void test_quiesce_co_drain_all(void)
184
{
185
- call_in_coroutine(test_quiesce_drain_all);
186
+ BlockBackend *blk = test_setup();
187
+ call_in_coroutine(test_quiesce_co_drain_all_entry);
188
+ blk_unref(blk);
189
+}
190
+
191
+static void coroutine_fn test_quiesce_co_drain_entry(void)
192
+{
193
+ BlockBackend *blk = blk_all_next(NULL);
194
+ test_quiesce_common(blk, BDRV_DRAIN, false);
195
}
196
197
static void test_quiesce_co_drain(void)
198
{
199
- call_in_coroutine(test_quiesce_drain);
200
+ BlockBackend *blk = test_setup();
201
+ call_in_coroutine(test_quiesce_co_drain_entry);
202
+ blk_unref(blk);
203
}
204
205
static void test_nested(void)
206
--
50
--
207
2.40.1
51
2.41.0
diff view generated by jsdifflib
1
GRAPH_RDLOCK_GUARD() and GRAPH_RDLOCK_GUARD_MAINLOOP() only take a
1
If the caller keeps the AioContext lock for a block node in an iothread,
2
reader lock for the graph, so the correct annotation for them to use is
2
polling in bdrv_graph_wrlock() deadlocks if the condition isn't
3
TSA_ASSERT_SHARED rather than TSA_ASSERT.
3
fulfilled immediately.
4
5
Now that all callers make sure to actually have the AioContext locked
6
when they call bdrv_replace_child_noperm() like they should, we can
7
change bdrv_graph_wrlock() to take a BlockDriverState whose AioContext
8
lock the caller holds (NULL if it doesn't) and unlock it temporarily
9
while polling.
4
10
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Eric Blake <eblake@redhat.com>
12
Message-ID: <20230605085711.21261-11-kwolf@redhat.com>
7
Message-Id: <20230504115750.54437-8-kwolf@redhat.com>
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
13
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
15
---
11
include/block/graph-lock.h | 16 ++++++++--------
16
include/block/graph-lock.h | 6 ++++--
12
1 file changed, 8 insertions(+), 8 deletions(-)
17
block.c | 4 ++--
18
block/graph-lock.c | 23 ++++++++++++++++++++++-
19
3 files changed, 28 insertions(+), 5 deletions(-)
13
20
14
diff --git a/include/block/graph-lock.h b/include/block/graph-lock.h
21
diff --git a/include/block/graph-lock.h b/include/block/graph-lock.h
15
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
16
--- a/include/block/graph-lock.h
23
--- a/include/block/graph-lock.h
17
+++ b/include/block/graph-lock.h
24
+++ b/include/block/graph-lock.h
18
@@ -XXX,XX +XXX,XX @@ typedef struct GraphLockable { } GraphLockable;
25
@@ -XXX,XX +XXX,XX @@ void unregister_aiocontext(AioContext *ctx);
19
#define GML_OBJ_() (&(GraphLockable) { })
26
* The wrlock can only be taken from the main loop, with BQL held, as only the
27
* main loop is allowed to modify the graph.
28
*
29
+ * If @bs is non-NULL, its AioContext is temporarily released.
30
+ *
31
* This function polls. Callers must not hold the lock of any AioContext other
32
- * than the current one.
33
+ * than the current one and the one of @bs.
34
*/
35
-void bdrv_graph_wrlock(void) TSA_ACQUIRE(graph_lock) TSA_NO_TSA;
36
+void bdrv_graph_wrlock(BlockDriverState *bs) TSA_ACQUIRE(graph_lock) TSA_NO_TSA;
20
37
21
/*
38
/*
22
- * This is not marked as TSA_ACQUIRE() because TSA doesn't understand the
39
* bdrv_graph_wrunlock:
23
+ * This is not marked as TSA_ACQUIRE_SHARED() because TSA doesn't understand the
40
diff --git a/block.c b/block.c
24
* cleanup attribute and would therefore complain that the graph is never
41
index XXXXXXX..XXXXXXX 100644
25
- * unlocked. TSA_ASSERT() makes sure that the following calls know that we
42
--- a/block.c
26
- * hold the lock while unlocking is left unchecked.
43
+++ b/block.c
27
+ * unlocked. TSA_ASSERT_SHARED() makes sure that the following calls know that
44
@@ -XXX,XX +XXX,XX @@ uint64_t bdrv_qapi_perm_to_blk_perm(BlockPermission qapi_perm)
28
+ * we hold the lock while unlocking is left unchecked.
45
* Replaces the node that a BdrvChild points to without updating permissions.
46
*
47
* If @new_bs is non-NULL, the parent of @child must already be drained through
48
- * @child.
49
+ * @child and the caller must hold the AioContext lock for @new_bs.
29
*/
50
*/
30
-static inline GraphLockable * TSA_ASSERT(graph_lock) TSA_NO_TSA coroutine_fn
51
static void bdrv_replace_child_noperm(BdrvChild *child,
31
+static inline GraphLockable * TSA_ASSERT_SHARED(graph_lock) TSA_NO_TSA coroutine_fn
52
BlockDriverState *new_bs)
32
graph_lockable_auto_lock(GraphLockable *x)
53
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child_noperm(BdrvChild *child,
54
}
55
56
/* TODO Pull this up into the callers to avoid polling here */
57
- bdrv_graph_wrlock();
58
+ bdrv_graph_wrlock(new_bs);
59
if (old_bs) {
60
if (child->klass->detach) {
61
child->klass->detach(child);
62
diff --git a/block/graph-lock.c b/block/graph-lock.c
63
index XXXXXXX..XXXXXXX 100644
64
--- a/block/graph-lock.c
65
+++ b/block/graph-lock.c
66
@@ -XXX,XX +XXX,XX @@ static uint32_t reader_count(void)
67
}
68
#endif
69
70
-void bdrv_graph_wrlock(void)
71
+void bdrv_graph_wrlock(BlockDriverState *bs)
33
{
72
{
34
bdrv_graph_co_rdlock();
73
+ AioContext *ctx = NULL;
35
@@ -XXX,XX +XXX,XX @@ typedef struct GraphLockableMainloop { } GraphLockableMainloop;
74
+
36
#define GMLML_OBJ_() (&(GraphLockableMainloop) { })
75
GLOBAL_STATE_CODE();
37
76
/*
38
/*
77
* TODO Some callers hold an AioContext lock when this is called, which
39
- * This is not marked as TSA_ACQUIRE() because TSA doesn't understand the
78
@@ -XXX,XX +XXX,XX @@ void bdrv_graph_wrlock(void)
40
+ * This is not marked as TSA_ACQUIRE_SHARED() because TSA doesn't understand the
79
*/
41
* cleanup attribute and would therefore complain that the graph is never
80
#if 0
42
- * unlocked. TSA_ASSERT() makes sure that the following calls know that we
81
assert(!qatomic_read(&has_writer));
43
- * hold the lock while unlocking is left unchecked.
82
+#endif
44
+ * unlocked. TSA_ASSERT_SHARED() makes sure that the following calls know that
83
+
45
+ * we hold the lock while unlocking is left unchecked.
84
+ /*
46
*/
85
+ * Release only non-mainloop AioContext. The mainloop often relies on the
47
-static inline GraphLockableMainloop * TSA_ASSERT(graph_lock) TSA_NO_TSA
86
+ * BQL and doesn't lock the main AioContext before doing things.
48
+static inline GraphLockableMainloop * TSA_ASSERT_SHARED(graph_lock) TSA_NO_TSA
87
+ */
49
graph_lockable_auto_lock_mainloop(GraphLockableMainloop *x)
88
+ if (bs) {
50
{
89
+ ctx = bdrv_get_aio_context(bs);
51
bdrv_graph_rdlock_main_loop();
90
+ if (ctx != qemu_get_aio_context()) {
91
+ aio_context_release(ctx);
92
+ } else {
93
+ ctx = NULL;
94
+ }
95
+ }
96
97
+#if 0
98
/* Make sure that constantly arriving new I/O doesn't cause starvation */
99
bdrv_drain_all_begin_nopoll();
100
101
@@ -XXX,XX +XXX,XX @@ void bdrv_graph_wrlock(void)
102
103
bdrv_drain_all_end();
104
#endif
105
+
106
+ if (ctx) {
107
+ aio_context_acquire(bdrv_get_aio_context(bs));
108
+ }
109
}
110
111
void bdrv_graph_wrunlock(void)
52
--
112
--
53
2.40.1
113
2.41.0
diff view generated by jsdifflib
1
From: Stefan Hajnoczi <stefanha@redhat.com>
1
Now that bdrv_graph_wrlock() temporarily drops the AioContext lock that
2
its caller holds, it can poll without causing deadlocks. We can now
3
re-enable graph locking.
2
4
3
reader_count() is a performance bottleneck because the global
5
This reverts commit ad128dff0bf4b6f971d05eb4335a627883a19c1d.
4
aio_context_list_lock mutex causes thread contention. Put this debugging
5
assertion behind a new ./configure --enable-debug-graph-lock option and
6
disable it by default.
7
6
8
The --enable-debug-graph-lock option is also enabled by the more general
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
--enable-debug option.
8
Message-ID: <20230605085711.21261-12-kwolf@redhat.com>
10
9
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
11
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
12
Message-Id: <20230501173443.153062-1-stefanha@redhat.com>
13
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
---
11
---
16
meson_options.txt | 2 ++
12
block/graph-lock.c | 26 --------------------------
17
configure | 1 +
13
1 file changed, 26 deletions(-)
18
block/graph-lock.c | 3 +++
19
meson.build | 2 ++
20
scripts/meson-buildoptions.sh | 4 ++++
21
5 files changed, 12 insertions(+)
22
14
23
diff --git a/meson_options.txt b/meson_options.txt
24
index XXXXXXX..XXXXXXX 100644
25
--- a/meson_options.txt
26
+++ b/meson_options.txt
27
@@ -XXX,XX +XXX,XX @@ option('rng_none', type: 'boolean', value: false,
28
description: 'dummy RNG, avoid using /dev/(u)random and getrandom()')
29
option('coroutine_pool', type: 'boolean', value: true,
30
description: 'coroutine freelist (better performance)')
31
+option('debug_graph_lock', type: 'boolean', value: false,
32
+ description: 'graph lock debugging support')
33
option('debug_mutex', type: 'boolean', value: false,
34
description: 'mutex debugging support')
35
option('debug_stack_usage', type: 'boolean', value: false,
36
diff --git a/configure b/configure
37
index XXXXXXX..XXXXXXX 100755
38
--- a/configure
39
+++ b/configure
40
@@ -XXX,XX +XXX,XX @@ for opt do
41
--enable-debug)
42
# Enable debugging options that aren't excessively noisy
43
debug_tcg="yes"
44
+ meson_option_parse --enable-debug-graph-lock ""
45
meson_option_parse --enable-debug-mutex ""
46
meson_option_add -Doptimization=0
47
fortify_source="no"
48
diff --git a/block/graph-lock.c b/block/graph-lock.c
15
diff --git a/block/graph-lock.c b/block/graph-lock.c
49
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
50
--- a/block/graph-lock.c
17
--- a/block/graph-lock.c
51
+++ b/block/graph-lock.c
18
+++ b/block/graph-lock.c
19
@@ -XXX,XX +XXX,XX @@ BdrvGraphLock graph_lock;
20
/* Protects the list of aiocontext and orphaned_reader_count */
21
static QemuMutex aio_context_list_lock;
22
23
-#if 0
24
/* Written and read with atomic operations. */
25
static int has_writer;
26
-#endif
27
28
/*
29
* A reader coroutine could move from an AioContext to another.
30
@@ -XXX,XX +XXX,XX @@ void unregister_aiocontext(AioContext *ctx)
31
g_free(ctx->bdrv_graph);
32
}
33
34
-#if 0
35
static uint32_t reader_count(void)
36
{
37
BdrvGraphRWlock *brdv_graph;
38
@@ -XXX,XX +XXX,XX @@ static uint32_t reader_count(void)
39
assert((int32_t)rd >= 0);
40
return rd;
41
}
42
-#endif
43
44
void bdrv_graph_wrlock(BlockDriverState *bs)
45
{
46
AioContext *ctx = NULL;
47
48
GLOBAL_STATE_CODE();
49
- /*
50
- * TODO Some callers hold an AioContext lock when this is called, which
51
- * causes deadlocks. Reenable once the AioContext locking is cleaned up (or
52
- * AioContext locks are gone).
53
- */
54
-#if 0
55
assert(!qatomic_read(&has_writer));
56
-#endif
57
58
/*
59
* Release only non-mainloop AioContext. The mainloop often relies on the
60
@@ -XXX,XX +XXX,XX @@ void bdrv_graph_wrlock(BlockDriverState *bs)
61
}
62
}
63
64
-#if 0
65
/* Make sure that constantly arriving new I/O doesn't cause starvation */
66
bdrv_drain_all_begin_nopoll();
67
68
@@ -XXX,XX +XXX,XX @@ void bdrv_graph_wrlock(BlockDriverState *bs)
69
} while (reader_count() >= 1);
70
71
bdrv_drain_all_end();
72
-#endif
73
74
if (ctx) {
75
aio_context_acquire(bdrv_get_aio_context(bs));
76
@@ -XXX,XX +XXX,XX @@ void bdrv_graph_wrlock(BlockDriverState *bs)
77
void bdrv_graph_wrunlock(void)
78
{
79
GLOBAL_STATE_CODE();
80
-#if 0
81
QEMU_LOCK_GUARD(&aio_context_list_lock);
82
assert(qatomic_read(&has_writer));
83
84
@@ -XXX,XX +XXX,XX @@ void bdrv_graph_wrunlock(void)
85
86
/* Wake up all coroutine that are waiting to read the graph */
87
qemu_co_enter_all(&reader_queue, &aio_context_list_lock);
88
-#endif
89
}
90
91
void coroutine_fn bdrv_graph_co_rdlock(void)
92
{
93
- /* TODO Reenable when wrlock is reenabled */
94
-#if 0
95
BdrvGraphRWlock *bdrv_graph;
96
bdrv_graph = qemu_get_current_aio_context()->bdrv_graph;
97
98
@@ -XXX,XX +XXX,XX @@ void coroutine_fn bdrv_graph_co_rdlock(void)
99
qemu_co_queue_wait(&reader_queue, &aio_context_list_lock);
100
}
101
}
102
-#endif
103
}
104
105
void coroutine_fn bdrv_graph_co_rdunlock(void)
106
{
107
-#if 0
108
BdrvGraphRWlock *bdrv_graph;
109
bdrv_graph = qemu_get_current_aio_context()->bdrv_graph;
110
111
@@ -XXX,XX +XXX,XX @@ void coroutine_fn bdrv_graph_co_rdunlock(void)
112
if (qatomic_read(&has_writer)) {
113
aio_wait_kick();
114
}
115
-#endif
116
}
117
118
void bdrv_graph_rdlock_main_loop(void)
52
@@ -XXX,XX +XXX,XX @@ void bdrv_graph_rdunlock_main_loop(void)
119
@@ -XXX,XX +XXX,XX @@ void bdrv_graph_rdunlock_main_loop(void)
53
54
void assert_bdrv_graph_readable(void)
120
void assert_bdrv_graph_readable(void)
55
{
121
{
56
+ /* reader_count() is slow due to aio_context_list_lock lock contention */
122
/* reader_count() is slow due to aio_context_list_lock lock contention */
57
+#ifdef CONFIG_DEBUG_GRAPH_LOCK
123
- /* TODO Reenable when wrlock is reenabled */
124
-#if 0
125
#ifdef CONFIG_DEBUG_GRAPH_LOCK
58
assert(qemu_in_main_thread() || reader_count());
126
assert(qemu_in_main_thread() || reader_count());
59
+#endif
127
#endif
128
-#endif
60
}
129
}
61
130
62
void assert_bdrv_graph_writable(void)
131
void assert_bdrv_graph_writable(void)
63
diff --git a/meson.build b/meson.build
132
{
64
index XXXXXXX..XXXXXXX 100644
133
assert(qemu_in_main_thread());
65
--- a/meson.build
134
- /* TODO Reenable when wrlock is reenabled */
66
+++ b/meson.build
135
-#if 0
67
@@ -XXX,XX +XXX,XX @@ if get_option('debug_stack_usage') and have_coroutine_pool
136
assert(qatomic_read(&has_writer));
68
have_coroutine_pool = false
137
-#endif
69
endif
138
}
70
config_host_data.set10('CONFIG_COROUTINE_POOL', have_coroutine_pool)
71
+config_host_data.set('CONFIG_DEBUG_GRAPH_LOCK', get_option('debug_graph_lock'))
72
config_host_data.set('CONFIG_DEBUG_MUTEX', get_option('debug_mutex'))
73
config_host_data.set('CONFIG_DEBUG_STACK_USAGE', get_option('debug_stack_usage'))
74
config_host_data.set('CONFIG_GPROF', get_option('gprof'))
75
@@ -XXX,XX +XXX,XX @@ summary_info += {'PIE': get_option('b_pie')}
76
summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
77
summary_info += {'malloc trim support': has_malloc_trim}
78
summary_info += {'membarrier': have_membarrier}
79
+summary_info += {'debug graph lock': get_option('debug_graph_lock')}
80
summary_info += {'debug stack usage': get_option('debug_stack_usage')}
81
summary_info += {'mutex debugging': get_option('debug_mutex')}
82
summary_info += {'memory allocator': get_option('malloc')}
83
diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh
84
index XXXXXXX..XXXXXXX 100644
85
--- a/scripts/meson-buildoptions.sh
86
+++ b/scripts/meson-buildoptions.sh
87
@@ -XXX,XX +XXX,XX @@ meson_options_help() {
88
printf "%s\n" ' QEMU'
89
printf "%s\n" ' --enable-cfi Control-Flow Integrity (CFI)'
90
printf "%s\n" ' --enable-cfi-debug Verbose errors in case of CFI violation'
91
+ printf "%s\n" ' --enable-debug-graph-lock'
92
+ printf "%s\n" ' graph lock debugging support'
93
printf "%s\n" ' --enable-debug-mutex mutex debugging support'
94
printf "%s\n" ' --enable-debug-stack-usage'
95
printf "%s\n" ' measure coroutine stack usage'
96
@@ -XXX,XX +XXX,XX @@ _meson_option_parse() {
97
--datadir=*) quote_sh "-Ddatadir=$2" ;;
98
--enable-dbus-display) printf "%s" -Ddbus_display=enabled ;;
99
--disable-dbus-display) printf "%s" -Ddbus_display=disabled ;;
100
+ --enable-debug-graph-lock) printf "%s" -Ddebug_graph_lock=true ;;
101
+ --disable-debug-graph-lock) printf "%s" -Ddebug_graph_lock=false ;;
102
--enable-debug-mutex) printf "%s" -Ddebug_mutex=true ;;
103
--disable-debug-mutex) printf "%s" -Ddebug_mutex=false ;;
104
--enable-debug-stack-usage) printf "%s" -Ddebug_stack_usage=true ;;
105
--
139
--
106
2.40.1
140
2.41.0
diff view generated by jsdifflib
1
This QMP handler runs in a coroutine, so it must use the corresponding
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
no_co_wrappers instead.
3
2
4
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2185688
3
raw_co_getlength is called by handle_aiocb_write_zeroes, which is not a coroutine
5
Cc: qemu-stable@nongnu.org
4
function. This is harmless because raw_co_getlength does not actually suspend,
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
but in the interest of clarity make it a non-coroutine_fn that is just wrapped
7
Reviewed-by: Eric Blake <eblake@redhat.com>
6
by the coroutine_fn raw_co_getlength. Likewise, check_cache_dropped was only
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
7
a coroutine_fn because it called raw_co_getlength, so it can be made non-coroutine
9
Message-Id: <20230504115750.54437-5-kwolf@redhat.com>
8
as well.
9
10
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
11
Message-ID: <20230601115145.196465-2-pbonzini@redhat.com>
12
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
14
---
12
blockdev.c | 4 ++--
15
block/file-posix.c | 29 +++++++++++++++++------------
13
1 file changed, 2 insertions(+), 2 deletions(-)
16
1 file changed, 17 insertions(+), 12 deletions(-)
14
17
15
diff --git a/blockdev.c b/blockdev.c
18
diff --git a/block/file-posix.c b/block/file-posix.c
16
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
17
--- a/blockdev.c
20
--- a/block/file-posix.c
18
+++ b/blockdev.c
21
+++ b/block/file-posix.c
19
@@ -XXX,XX +XXX,XX @@ void coroutine_fn qmp_block_resize(const char *device, const char *node_name,
22
@@ -XXX,XX +XXX,XX @@ static int fd_open(BlockDriverState *bs)
20
return;
23
return -EIO;
24
}
25
26
-static int64_t coroutine_fn raw_co_getlength(BlockDriverState *bs);
27
+static int64_t raw_getlength(BlockDriverState *bs);
28
29
typedef struct RawPosixAIOData {
30
BlockDriverState *bs;
31
@@ -XXX,XX +XXX,XX @@ static int handle_aiocb_write_zeroes(void *opaque)
32
#ifdef CONFIG_FALLOCATE
33
/* Last resort: we are trying to extend the file with zeroed data. This
34
* can be done via fallocate(fd, 0) */
35
- len = raw_co_getlength(aiocb->bs);
36
+ len = raw_getlength(aiocb->bs);
37
if (s->has_fallocate && len >= 0 && aiocb->aio_offset >= len) {
38
int ret = do_fallocate(s->fd, 0, aiocb->aio_offset, aiocb->aio_nbytes);
39
if (ret == 0 || ret != -ENOTSUP) {
40
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
21
}
41
}
22
42
23
- blk = blk_new_with_bs(bs, BLK_PERM_RESIZE, BLK_PERM_ALL, errp);
43
if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
24
+ blk = blk_co_new_with_bs(bs, BLK_PERM_RESIZE, BLK_PERM_ALL, errp);
44
- int64_t cur_length = raw_co_getlength(bs);
25
if (!blk) {
45
+ int64_t cur_length = raw_getlength(bs);
26
return;
46
27
}
47
if (offset != cur_length && exact) {
28
@@ -XXX,XX +XXX,XX @@ void coroutine_fn qmp_block_resize(const char *device, const char *node_name,
48
error_setg(errp, "Cannot resize device files");
29
49
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
30
bdrv_co_lock(bs);
31
bdrv_drained_end(bs);
32
- blk_unref(blk);
33
+ blk_co_unref(blk);
34
bdrv_co_unlock(bs);
35
}
50
}
36
51
52
#ifdef __OpenBSD__
53
-static int64_t coroutine_fn raw_co_getlength(BlockDriverState *bs)
54
+static int64_t raw_getlength(BlockDriverState *bs)
55
{
56
BDRVRawState *s = bs->opaque;
57
int fd = s->fd;
58
@@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn raw_co_getlength(BlockDriverState *bs)
59
return st.st_size;
60
}
61
#elif defined(__NetBSD__)
62
-static int64_t coroutine_fn raw_co_getlength(BlockDriverState *bs)
63
+static int64_t raw_getlength(BlockDriverState *bs)
64
{
65
BDRVRawState *s = bs->opaque;
66
int fd = s->fd;
67
@@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn raw_co_getlength(BlockDriverState *bs)
68
return st.st_size;
69
}
70
#elif defined(__sun__)
71
-static int64_t coroutine_fn raw_co_getlength(BlockDriverState *bs)
72
+static int64_t raw_getlength(BlockDriverState *bs)
73
{
74
BDRVRawState *s = bs->opaque;
75
struct dk_minfo minfo;
76
@@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn raw_co_getlength(BlockDriverState *bs)
77
return size;
78
}
79
#elif defined(CONFIG_BSD)
80
-static int64_t coroutine_fn raw_co_getlength(BlockDriverState *bs)
81
+static int64_t raw_getlength(BlockDriverState *bs)
82
{
83
BDRVRawState *s = bs->opaque;
84
int fd = s->fd;
85
@@ -XXX,XX +XXX,XX @@ again:
86
return size;
87
}
88
#else
89
-static int64_t coroutine_fn raw_co_getlength(BlockDriverState *bs)
90
+static int64_t raw_getlength(BlockDriverState *bs)
91
{
92
BDRVRawState *s = bs->opaque;
93
int ret;
94
@@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn raw_co_getlength(BlockDriverState *bs)
95
}
96
#endif
97
98
+static int64_t coroutine_fn raw_co_getlength(BlockDriverState *bs)
99
+{
100
+ return raw_getlength(bs);
101
+}
102
+
103
static int64_t coroutine_fn raw_co_get_allocated_file_size(BlockDriverState *bs)
104
{
105
struct stat st;
106
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_block_status(BlockDriverState *bs,
107
* round up if necessary.
108
*/
109
if (!QEMU_IS_ALIGNED(*pnum, bs->bl.request_alignment)) {
110
- int64_t file_length = raw_co_getlength(bs);
111
+ int64_t file_length = raw_getlength(bs);
112
if (file_length > 0) {
113
/* Ignore errors, this is just a safeguard */
114
assert(hole == file_length);
115
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_block_status(BlockDriverState *bs,
116
117
#if defined(__linux__)
118
/* Verify that the file is not in the page cache */
119
-static void coroutine_fn check_cache_dropped(BlockDriverState *bs, Error **errp)
120
+static void check_cache_dropped(BlockDriverState *bs, Error **errp)
121
{
122
const size_t window_size = 128 * 1024 * 1024;
123
BDRVRawState *s = bs->opaque;
124
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn check_cache_dropped(BlockDriverState *bs, Error **errp)
125
page_size = sysconf(_SC_PAGESIZE);
126
vec = g_malloc(DIV_ROUND_UP(window_size, page_size));
127
128
- end = raw_co_getlength(bs);
129
+ end = raw_getlength(bs);
130
131
for (offset = 0; offset < end; offset += window_size) {
132
void *new_window;
133
@@ -XXX,XX +XXX,XX @@ static int cdrom_reopen(BlockDriverState *bs)
134
135
static bool coroutine_fn cdrom_co_is_inserted(BlockDriverState *bs)
136
{
137
- return raw_co_getlength(bs) > 0;
138
+ return raw_getlength(bs) > 0;
139
}
140
141
static void coroutine_fn cdrom_co_eject(BlockDriverState *bs, bool eject_flag)
37
--
142
--
38
2.40.1
143
2.41.0
diff view generated by jsdifflib
1
From: Eric Blake <eblake@redhat.com>
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
2
3
Commit fe904ea824 added a fail_inactivate label, which tries to
3
Mark functions as coroutine_fn when they are only called by other coroutine_fns
4
reactivate disks on the source after a failure while s->state ==
4
and they can suspend. Change calls to co_wrappers to use the non-wrapped
5
MIGRATION_STATUS_ACTIVE, but didn't actually use the label if
5
functions, which in turn requires adding GRAPH_RDLOCK annotations.
6
qemu_savevm_state_complete_precopy() failed. This failure to
7
reactivate is also present in commit 6039dd5b1c (also covering the new
8
s->state == MIGRATION_STATUS_DEVICE state) and 403d18ae (ensuring
9
s->block_inactive is set more reliably).
10
6
11
Consolidate the two labels back into one - no matter HOW migration is
7
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
12
failed, if there is any chance we can reach vm_start() after having
8
Message-ID: <20230601115145.196465-3-pbonzini@redhat.com>
13
attempted inactivation, it is essential that we have tried to restart
14
disks before then. This also makes the cleanup more like
15
migrate_fd_cancel().
16
17
Suggested-by: Kevin Wolf <kwolf@redhat.com>
18
Signed-off-by: Eric Blake <eblake@redhat.com>
19
Message-Id: <20230502205212.134680-1-eblake@redhat.com>
20
Acked-by: Peter Xu <peterx@redhat.com>
21
Reviewed-by: Juan Quintela <quintela@redhat.com>
22
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
23
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
24
---
11
---
25
migration/migration.c | 24 ++++++++++++++----------
12
block/qed-check.c | 5 +++--
26
1 file changed, 14 insertions(+), 10 deletions(-)
13
block/qed.c | 7 ++++---
14
2 files changed, 7 insertions(+), 5 deletions(-)
27
15
28
diff --git a/migration/migration.c b/migration/migration.c
16
diff --git a/block/qed-check.c b/block/qed-check.c
29
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
30
--- a/migration/migration.c
18
--- a/block/qed-check.c
31
+++ b/migration/migration.c
19
+++ b/block/qed-check.c
32
@@ -XXX,XX +XXX,XX @@ static void migration_completion(MigrationState *s)
20
@@ -XXX,XX +XXX,XX @@ static void qed_check_for_leaks(QEDCheck *check)
33
MIGRATION_STATUS_DEVICE);
21
/**
34
}
22
* Mark an image clean once it passes check or has been repaired
35
if (ret >= 0) {
23
*/
36
+ /*
24
-static void qed_check_mark_clean(BDRVQEDState *s, BdrvCheckResult *result)
37
+ * Inactivate disks except in COLO, and track that we
25
+static void coroutine_fn GRAPH_RDLOCK
38
+ * have done so in order to remember to reactivate
26
+qed_check_mark_clean(BDRVQEDState *s, BdrvCheckResult *result)
39
+ * them if migration fails or is cancelled.
27
{
40
+ */
28
/* Skip if there were unfixable corruptions or I/O errors */
41
s->block_inactive = !migrate_colo();
29
if (result->corruptions > 0 || result->check_errors > 0) {
42
qemu_file_set_rate_limit(s->to_dst_file, INT64_MAX);
30
@@ -XXX,XX +XXX,XX @@ static void qed_check_mark_clean(BDRVQEDState *s, BdrvCheckResult *result)
43
ret = qemu_savevm_state_complete_precopy(s->to_dst_file, false,
44
@@ -XXX,XX +XXX,XX @@ static void migration_completion(MigrationState *s)
45
rp_error = await_return_path_close_on_source(s);
46
trace_migration_return_path_end_after(rp_error);
47
if (rp_error) {
48
- goto fail_invalidate;
49
+ goto fail;
50
}
51
}
31
}
52
32
53
if (qemu_file_get_error(s->to_dst_file)) {
33
/* Ensure fixes reach storage before clearing check bit */
54
trace_migration_completion_file_err();
34
- bdrv_flush(s->bs);
55
- goto fail_invalidate;
35
+ bdrv_co_flush(s->bs);
56
+ goto fail;
36
37
s->header.features &= ~QED_F_NEED_CHECK;
38
qed_write_header_sync(s);
39
diff --git a/block/qed.c b/block/qed.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/block/qed.c
42
+++ b/block/qed.c
43
@@ -XXX,XX +XXX,XX @@ static bool qed_is_image_size_valid(uint64_t image_size, uint32_t cluster_size,
44
*
45
* The string is NUL-terminated.
46
*/
47
-static int qed_read_string(BdrvChild *file, uint64_t offset, size_t n,
48
- char *buf, size_t buflen)
49
+static int coroutine_fn GRAPH_RDLOCK
50
+qed_read_string(BdrvChild *file, uint64_t offset,
51
+ size_t n, char *buf, size_t buflen)
52
{
53
int ret;
54
if (n >= buflen) {
55
return -EINVAL;
57
}
56
}
58
57
- ret = bdrv_pread(file, offset, n, buf, 0);
59
if (migrate_colo() && s->state == MIGRATION_STATUS_ACTIVE) {
58
+ ret = bdrv_co_pread(file, offset, n, buf, 0);
60
@@ -XXX,XX +XXX,XX @@ static void migration_completion(MigrationState *s)
59
if (ret < 0) {
61
60
return ret;
62
return;
63
64
-fail_invalidate:
65
- /* If not doing postcopy, vm_start() will be called: let's regain
66
- * control on images.
67
- */
68
- if (s->state == MIGRATION_STATUS_ACTIVE ||
69
- s->state == MIGRATION_STATUS_DEVICE) {
70
+fail:
71
+ if (s->block_inactive && (s->state == MIGRATION_STATUS_ACTIVE ||
72
+ s->state == MIGRATION_STATUS_DEVICE)) {
73
+ /*
74
+ * If not doing postcopy, vm_start() will be called: let's
75
+ * regain control on images.
76
+ */
77
Error *local_err = NULL;
78
79
qemu_mutex_lock_iothread();
80
bdrv_activate_all(&local_err);
81
if (local_err) {
82
error_report_err(local_err);
83
- s->block_inactive = true;
84
} else {
85
s->block_inactive = false;
86
}
87
qemu_mutex_unlock_iothread();
88
}
61
}
89
90
-fail:
91
migrate_set_state(&s->state, current_active_state,
92
MIGRATION_STATUS_FAILED);
93
}
94
--
62
--
95
2.40.1
63
2.41.0
diff view generated by jsdifflib
1
The only thing nbd_co_flush() does is call nbd_client_co_flush(). Just
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
use that function directly in the BlockDriver definitions and remove the
3
wrapper.
4
2
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
3
Mark functions as coroutine_fn when they are only called by other coroutine_fns
6
Reviewed-by: Eric Blake <eblake@redhat.com>
4
and they can suspend. Change calls to co_wrappers to use the non-wrapped
7
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
5
functions, which in turn requires adding GRAPH_RDLOCK annotations.
8
Message-Id: <20230504115750.54437-10-kwolf@redhat.com>
6
7
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
8
Message-ID: <20230601115145.196465-4-pbonzini@redhat.com>
9
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
---
11
block/nbd.c | 11 +++--------
12
block/vpc.c | 52 ++++++++++++++++++++++++++--------------------------
12
1 file changed, 3 insertions(+), 8 deletions(-)
13
1 file changed, 26 insertions(+), 26 deletions(-)
13
14
14
diff --git a/block/nbd.c b/block/nbd.c
15
diff --git a/block/vpc.c b/block/vpc.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/block/nbd.c
17
--- a/block/vpc.c
17
+++ b/block/nbd.c
18
+++ b/block/vpc.c
19
@@ -XXX,XX +XXX,XX @@ static int vpc_reopen_prepare(BDRVReopenState *state,
20
* operation (the block bitmaps is updated then), 0 otherwise.
21
* If write is true then err must not be NULL.
22
*/
23
-static inline int64_t get_image_offset(BlockDriverState *bs, uint64_t offset,
24
- bool write, int *err)
25
+static int64_t coroutine_fn GRAPH_RDLOCK
26
+get_image_offset(BlockDriverState *bs, uint64_t offset, bool write, int *err)
27
{
28
BDRVVPCState *s = bs->opaque;
29
uint64_t bitmap_offset, block_offset;
30
@@ -XXX,XX +XXX,XX @@ static inline int64_t get_image_offset(BlockDriverState *bs, uint64_t offset,
31
32
s->last_bitmap_offset = bitmap_offset;
33
memset(bitmap, 0xff, s->bitmap_size);
34
- r = bdrv_pwrite_sync(bs->file, bitmap_offset, s->bitmap_size, bitmap,
35
- 0);
36
+ r = bdrv_co_pwrite_sync(bs->file, bitmap_offset, s->bitmap_size, bitmap, 0);
37
if (r < 0) {
38
*err = r;
39
return -2;
40
@@ -XXX,XX +XXX,XX @@ static inline int64_t get_image_offset(BlockDriverState *bs, uint64_t offset,
41
*
42
* Returns 0 on success and < 0 on error
43
*/
44
-static int rewrite_footer(BlockDriverState *bs)
45
+static int coroutine_fn GRAPH_RDLOCK rewrite_footer(BlockDriverState *bs)
46
{
47
int ret;
48
BDRVVPCState *s = bs->opaque;
49
int64_t offset = s->free_data_block_offset;
50
51
- ret = bdrv_pwrite_sync(bs->file, offset, sizeof(s->footer), &s->footer, 0);
52
+ ret = bdrv_co_pwrite_sync(bs->file, offset, sizeof(s->footer), &s->footer, 0);
53
if (ret < 0)
54
return ret;
55
56
@@ -XXX,XX +XXX,XX @@ static int rewrite_footer(BlockDriverState *bs)
57
*
58
* Returns the sectors' offset in the image file on success and < 0 on error
59
*/
60
-static int64_t alloc_block(BlockDriverState *bs, int64_t offset)
61
+static int64_t coroutine_fn GRAPH_RDLOCK
62
+alloc_block(BlockDriverState *bs, int64_t offset)
63
{
64
BDRVVPCState *s = bs->opaque;
65
int64_t bat_offset;
66
@@ -XXX,XX +XXX,XX @@ static int64_t alloc_block(BlockDriverState *bs, int64_t offset)
67
68
/* Initialize the block's bitmap */
69
memset(bitmap, 0xff, s->bitmap_size);
70
- ret = bdrv_pwrite_sync(bs->file, s->free_data_block_offset,
71
- s->bitmap_size, bitmap, 0);
72
+ ret = bdrv_co_pwrite_sync(bs->file, s->free_data_block_offset,
73
+ s->bitmap_size, bitmap, 0);
74
if (ret < 0) {
75
return ret;
76
}
77
@@ -XXX,XX +XXX,XX @@ static int64_t alloc_block(BlockDriverState *bs, int64_t offset)
78
/* Write BAT entry to disk */
79
bat_offset = s->bat_offset + (4 * index);
80
bat_value = cpu_to_be32(s->pagetable[index]);
81
- ret = bdrv_pwrite_sync(bs->file, bat_offset, 4, &bat_value, 0);
82
+ ret = bdrv_co_pwrite_sync(bs->file, bat_offset, 4, &bat_value, 0);
83
if (ret < 0)
84
goto fail;
85
18
@@ -XXX,XX +XXX,XX @@ fail:
86
@@ -XXX,XX +XXX,XX @@ fail:
19
return ret;
87
return ret;
20
}
88
}
21
89
22
-static int coroutine_fn nbd_co_flush(BlockDriverState *bs)
90
-static int coroutine_fn vpc_co_block_status(BlockDriverState *bs,
23
-{
91
- bool want_zero,
24
- return nbd_client_co_flush(bs);
92
- int64_t offset, int64_t bytes,
25
-}
93
- int64_t *pnum, int64_t *map,
26
-
94
- BlockDriverState **file)
27
static void nbd_refresh_limits(BlockDriverState *bs, Error **errp)
95
+static int coroutine_fn GRAPH_RDLOCK
96
+vpc_co_block_status(BlockDriverState *bs, bool want_zero,
97
+ int64_t offset, int64_t bytes,
98
+ int64_t *pnum, int64_t *map,
99
+ BlockDriverState **file)
28
{
100
{
29
BDRVNBDState *s = (BDRVNBDState *)bs->opaque;
101
BDRVVPCState *s = bs->opaque;
30
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_nbd = {
102
int64_t image_offset;
31
.bdrv_co_pwritev = nbd_client_co_pwritev,
103
@@ -XXX,XX +XXX,XX @@ static int calculate_geometry(int64_t total_sectors, uint16_t *cyls,
32
.bdrv_co_pwrite_zeroes = nbd_client_co_pwrite_zeroes,
104
return 0;
33
.bdrv_close = nbd_close,
105
}
34
- .bdrv_co_flush_to_os = nbd_co_flush,
106
35
+ .bdrv_co_flush_to_os = nbd_client_co_flush,
107
-static int create_dynamic_disk(BlockBackend *blk, VHDFooter *footer,
36
.bdrv_co_pdiscard = nbd_client_co_pdiscard,
108
- int64_t total_sectors)
37
.bdrv_refresh_limits = nbd_refresh_limits,
109
+static int coroutine_fn create_dynamic_disk(BlockBackend *blk, VHDFooter *footer,
38
.bdrv_co_truncate = nbd_co_truncate,
110
+ int64_t total_sectors)
39
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_nbd_tcp = {
111
{
40
.bdrv_co_pwritev = nbd_client_co_pwritev,
112
VHDDynDiskHeader dyndisk_header;
41
.bdrv_co_pwrite_zeroes = nbd_client_co_pwrite_zeroes,
113
uint8_t bat_sector[512];
42
.bdrv_close = nbd_close,
114
@@ -XXX,XX +XXX,XX @@ static int create_dynamic_disk(BlockBackend *blk, VHDFooter *footer,
43
- .bdrv_co_flush_to_os = nbd_co_flush,
115
block_size = 0x200000;
44
+ .bdrv_co_flush_to_os = nbd_client_co_flush,
116
num_bat_entries = DIV_ROUND_UP(total_sectors, block_size / 512);
45
.bdrv_co_pdiscard = nbd_client_co_pdiscard,
117
46
.bdrv_refresh_limits = nbd_refresh_limits,
118
- ret = blk_pwrite(blk, offset, sizeof(*footer), footer, 0);
47
.bdrv_co_truncate = nbd_co_truncate,
119
+ ret = blk_co_pwrite(blk, offset, sizeof(*footer), footer, 0);
48
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_nbd_unix = {
120
if (ret < 0) {
49
.bdrv_co_pwritev = nbd_client_co_pwritev,
121
goto fail;
50
.bdrv_co_pwrite_zeroes = nbd_client_co_pwrite_zeroes,
122
}
51
.bdrv_close = nbd_close,
123
52
- .bdrv_co_flush_to_os = nbd_co_flush,
124
offset = 1536 + ((num_bat_entries * 4 + 511) & ~511);
53
+ .bdrv_co_flush_to_os = nbd_client_co_flush,
125
- ret = blk_pwrite(blk, offset, sizeof(*footer), footer, 0);
54
.bdrv_co_pdiscard = nbd_client_co_pdiscard,
126
+ ret = blk_co_pwrite(blk, offset, sizeof(*footer), footer, 0);
55
.bdrv_refresh_limits = nbd_refresh_limits,
127
if (ret < 0) {
56
.bdrv_co_truncate = nbd_co_truncate,
128
goto fail;
129
}
130
@@ -XXX,XX +XXX,XX @@ static int create_dynamic_disk(BlockBackend *blk, VHDFooter *footer,
131
132
memset(bat_sector, 0xFF, 512);
133
for (i = 0; i < DIV_ROUND_UP(num_bat_entries * 4, 512); i++) {
134
- ret = blk_pwrite(blk, offset, 512, bat_sector, 0);
135
+ ret = blk_co_pwrite(blk, offset, 512, bat_sector, 0);
136
if (ret < 0) {
137
goto fail;
138
}
139
@@ -XXX,XX +XXX,XX @@ static int create_dynamic_disk(BlockBackend *blk, VHDFooter *footer,
140
/* Write the header */
141
offset = 512;
142
143
- ret = blk_pwrite(blk, offset, sizeof(dyndisk_header), &dyndisk_header, 0);
144
+ ret = blk_co_pwrite(blk, offset, sizeof(dyndisk_header), &dyndisk_header, 0);
145
if (ret < 0) {
146
goto fail;
147
}
148
@@ -XXX,XX +XXX,XX @@ static int create_dynamic_disk(BlockBackend *blk, VHDFooter *footer,
149
return ret;
150
}
151
152
-static int create_fixed_disk(BlockBackend *blk, VHDFooter *footer,
153
- int64_t total_size, Error **errp)
154
+static int coroutine_fn create_fixed_disk(BlockBackend *blk, VHDFooter *footer,
155
+ int64_t total_size, Error **errp)
156
{
157
int ret;
158
159
/* Add footer to total size */
160
total_size += sizeof(*footer);
161
162
- ret = blk_truncate(blk, total_size, false, PREALLOC_MODE_OFF, 0, errp);
163
+ ret = blk_co_truncate(blk, total_size, false, PREALLOC_MODE_OFF, 0, errp);
164
if (ret < 0) {
165
return ret;
166
}
167
168
- ret = blk_pwrite(blk, total_size - sizeof(*footer), sizeof(*footer),
169
- footer, 0);
170
+ ret = blk_co_pwrite(blk, total_size - sizeof(*footer), sizeof(*footer),
171
+ footer, 0);
172
if (ret < 0) {
173
error_setg_errno(errp, -ret, "Unable to write VHD header");
174
return ret;
57
--
175
--
58
2.40.1
176
2.41.0
diff view generated by jsdifflib
1
This adds GRAPH_RDLOCK annotations to declare that callers of
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
bdrv_recurse_can_replace() need to hold a reader lock for the graph
3
because it accesses the children list of a node.
4
2
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
3
Mark functions as coroutine_fn when they are only called by other coroutine_fns
6
Reviewed-by: Eric Blake <eblake@redhat.com>
4
and they can suspend. Change calls to co_wrappers to use the non-wrapped
7
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
5
functions, which in turn requires adding GRAPH_RDLOCK annotations.
8
Message-Id: <20230504115750.54437-20-kwolf@redhat.com>
6
7
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
8
Message-ID: <20230601115145.196465-5-pbonzini@redhat.com>
9
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
---
11
include/block/block-global-state.h | 5 +++--
12
block/bochs.c | 7 ++++---
12
include/block/block_int-common.h | 4 ++--
13
1 file changed, 4 insertions(+), 3 deletions(-)
13
include/block/block_int-global-state.h | 4 ++--
14
block/blkverify.c | 5 +++--
15
block/mirror.c | 4 ++++
16
block/quorum.c | 4 ++--
17
blockdev.c | 3 +++
18
7 files changed, 19 insertions(+), 10 deletions(-)
19
14
20
diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h
15
diff --git a/block/bochs.c b/block/bochs.c
21
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
22
--- a/include/block/block-global-state.h
17
--- a/block/bochs.c
23
+++ b/include/block/block-global-state.h
18
+++ b/block/bochs.c
24
@@ -XXX,XX +XXX,XX @@ int bdrv_amend_options(BlockDriverState *bs_new, QemuOpts *opts,
19
@@ -XXX,XX +XXX,XX @@ static void bochs_refresh_limits(BlockDriverState *bs, Error **errp)
25
Error **errp);
20
bs->bl.request_alignment = BDRV_SECTOR_SIZE; /* No sub-sector I/O */
26
27
/* check if a named node can be replaced when doing drive-mirror */
28
-BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs,
29
- const char *node_name, Error **errp);
30
+BlockDriverState * GRAPH_RDLOCK
31
+check_to_replace_node(BlockDriverState *parent_bs, const char *node_name,
32
+ Error **errp);
33
34
int no_coroutine_fn bdrv_activate(BlockDriverState *bs, Error **errp);
35
36
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
37
index XXXXXXX..XXXXXXX 100644
38
--- a/include/block/block_int-common.h
39
+++ b/include/block/block_int-common.h
40
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
41
* same data as @bs without it affecting @bs's behavior (that is,
42
* without it being visible to @bs's parents).
43
*/
44
- bool (*bdrv_recurse_can_replace)(BlockDriverState *bs,
45
- BlockDriverState *to_replace);
46
+ bool GRAPH_RDLOCK_PTR (*bdrv_recurse_can_replace)(
47
+ BlockDriverState *bs, BlockDriverState *to_replace);
48
49
int (*bdrv_probe_device)(const char *filename);
50
51
diff --git a/include/block/block_int-global-state.h b/include/block/block_int-global-state.h
52
index XXXXXXX..XXXXXXX 100644
53
--- a/include/block/block_int-global-state.h
54
+++ b/include/block/block_int-global-state.h
55
@@ -XXX,XX +XXX,XX @@ int bdrv_child_try_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared,
56
*/
57
int bdrv_child_refresh_perms(BlockDriverState *bs, BdrvChild *c, Error **errp);
58
59
-bool bdrv_recurse_can_replace(BlockDriverState *bs,
60
- BlockDriverState *to_replace);
61
+bool GRAPH_RDLOCK bdrv_recurse_can_replace(BlockDriverState *bs,
62
+ BlockDriverState *to_replace);
63
64
/*
65
* Default implementation for BlockDriver.bdrv_child_perm() that can
66
diff --git a/block/blkverify.c b/block/blkverify.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/block/blkverify.c
69
+++ b/block/blkverify.c
70
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn GRAPH_RDLOCK blkverify_co_flush(BlockDriverState *bs)
71
return bdrv_co_flush(s->test_file->bs);
72
}
21
}
73
22
74
-static bool blkverify_recurse_can_replace(BlockDriverState *bs,
23
-static int64_t seek_to_sector(BlockDriverState *bs, int64_t sector_num)
75
- BlockDriverState *to_replace)
24
+static int64_t coroutine_fn GRAPH_RDLOCK
76
+static bool GRAPH_RDLOCK
25
+seek_to_sector(BlockDriverState *bs, int64_t sector_num)
77
+blkverify_recurse_can_replace(BlockDriverState *bs,
78
+ BlockDriverState *to_replace)
79
{
26
{
80
BDRVBlkverifyState *s = bs->opaque;
27
BDRVBochsState *s = bs->opaque;
81
28
uint64_t offset = sector_num * 512;
82
diff --git a/block/mirror.c b/block/mirror.c
29
@@ -XXX,XX +XXX,XX @@ static int64_t seek_to_sector(BlockDriverState *bs, int64_t sector_num)
83
index XXXXXXX..XXXXXXX 100644
30
(s->extent_blocks + s->bitmap_blocks));
84
--- a/block/mirror.c
31
85
+++ b/block/mirror.c
32
/* read in bitmap for current extent */
86
@@ -XXX,XX +XXX,XX @@ static int mirror_exit_common(Job *job)
33
- ret = bdrv_pread(bs->file, bitmap_offset + (extent_offset / 8), 1,
87
* Cannot use check_to_replace_node() here, because that would
34
- &bitmap_entry, 0);
88
* check for an op blocker on @to_replace, and we have our own
35
+ ret = bdrv_co_pread(bs->file, bitmap_offset + (extent_offset / 8), 1,
89
* there.
36
+ &bitmap_entry, 0);
90
+ *
37
if (ret < 0) {
91
+ * TODO Pull out the writer lock from bdrv_replace_node() to here
38
return ret;
92
*/
93
+ bdrv_graph_rdlock_main_loop();
94
if (bdrv_recurse_can_replace(src, to_replace)) {
95
bdrv_replace_node(to_replace, target_bs, &local_err);
96
} else {
97
@@ -XXX,XX +XXX,XX @@ static int mirror_exit_common(Job *job)
98
"would not lead to an abrupt change of visible data",
99
to_replace->node_name, target_bs->node_name);
100
}
101
+ bdrv_graph_rdunlock_main_loop();
102
bdrv_drained_end(target_bs);
103
if (local_err) {
104
error_report_err(local_err);
105
diff --git a/block/quorum.c b/block/quorum.c
106
index XXXXXXX..XXXXXXX 100644
107
--- a/block/quorum.c
108
+++ b/block/quorum.c
109
@@ -XXX,XX +XXX,XX @@ static coroutine_fn GRAPH_RDLOCK int quorum_co_flush(BlockDriverState *bs)
110
return result;
111
}
112
113
-static bool quorum_recurse_can_replace(BlockDriverState *bs,
114
- BlockDriverState *to_replace)
115
+static bool GRAPH_RDLOCK
116
+quorum_recurse_can_replace(BlockDriverState *bs, BlockDriverState *to_replace)
117
{
118
BDRVQuorumState *s = bs->opaque;
119
int i;
120
diff --git a/blockdev.c b/blockdev.c
121
index XXXXXXX..XXXXXXX 100644
122
--- a/blockdev.c
123
+++ b/blockdev.c
124
@@ -XXX,XX +XXX,XX @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
125
BlockDriverState *unfiltered_bs;
126
int job_flags = JOB_DEFAULT;
127
128
+ GLOBAL_STATE_CODE();
129
+ GRAPH_RDLOCK_GUARD_MAINLOOP();
130
+
131
if (!has_speed) {
132
speed = 0;
133
}
39
}
134
--
40
--
135
2.40.1
41
2.41.0
diff view generated by jsdifflib
1
Drivers were a bit confused about whether .bdrv_open can run in a
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
coroutine and whether or not it holds a graph lock.
3
2
4
It cannot keep a graph lock from the caller across the whole function
3
Mark functions as coroutine_fn when they are only called by other coroutine_fns
5
because it both changes the graph (requires a writer lock) and does I/O
4
and they can suspend. Because this function operates on a BlockBackend, mark it
6
(requires a reader lock). Therefore, it should take these locks
5
GRAPH_UNLOCKED.
7
internally as needed.
8
6
9
The functions used to be called in coroutine context during image
7
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
10
creation. This was buggy for other reasons, and as of commit 32192301,
8
Message-ID: <20230601115145.196465-6-pbonzini@redhat.com>
11
all block drivers go through no_co_wrappers. So it is not called in
9
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
12
coroutine context any more.
13
14
Fix qcow2 and qed to work with the correct assumptions: The graph lock
15
needs to be taken internally instead of just assuming it's already
16
there, and the coroutine path is dead code that can be removed.
17
18
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
19
Reviewed-by: Eric Blake <eblake@redhat.com>
20
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
21
Message-Id: <20230504115750.54437-9-kwolf@redhat.com>
22
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
23
---
11
---
24
include/block/block_int-common.h | 8 ++++----
12
block.c | 11 ++++++-----
25
block.c | 6 +++---
13
1 file changed, 6 insertions(+), 5 deletions(-)
26
block/qcow2.c | 15 ++++++---------
27
block/qed.c | 18 ++++++++----------
28
4 files changed, 21 insertions(+), 26 deletions(-)
29
14
30
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
31
index XXXXXXX..XXXXXXX 100644
32
--- a/include/block/block_int-common.h
33
+++ b/include/block/block_int-common.h
34
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
35
void (*bdrv_reopen_abort)(BDRVReopenState *reopen_state);
36
void (*bdrv_join_options)(QDict *options, QDict *old_options);
37
38
- int (*bdrv_open)(BlockDriverState *bs, QDict *options, int flags,
39
- Error **errp);
40
+ int GRAPH_UNLOCKED_PTR (*bdrv_open)(
41
+ BlockDriverState *bs, QDict *options, int flags, Error **errp);
42
43
/* Protocol drivers should implement this instead of bdrv_open */
44
- int (*bdrv_file_open)(BlockDriverState *bs, QDict *options, int flags,
45
- Error **errp);
46
+ int GRAPH_UNLOCKED_PTR (*bdrv_file_open)(
47
+ BlockDriverState *bs, QDict *options, int flags, Error **errp);
48
void (*bdrv_close)(BlockDriverState *bs);
49
50
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_create)(
51
diff --git a/block.c b/block.c
15
diff --git a/block.c b/block.c
52
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
53
--- a/block.c
17
--- a/block.c
54
+++ b/block.c
18
+++ b/block.c
55
@@ -XXX,XX +XXX,XX @@ out:
19
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_create(BlockDriver *drv, const char *filename,
56
* bdrv_refresh_total_sectors() which polls when called from non-coroutine
20
* On success, return @blk's actual length.
57
* context.
21
* Otherwise, return -errno.
58
*/
22
*/
59
-static int bdrv_open_driver(BlockDriverState *bs, BlockDriver *drv,
23
-static int64_t create_file_fallback_truncate(BlockBackend *blk,
60
- const char *node_name, QDict *options,
24
- int64_t minimum_size, Error **errp)
61
- int open_flags, Error **errp)
25
+static int64_t coroutine_fn GRAPH_UNLOCKED
62
+static int no_coroutine_fn GRAPH_UNLOCKED
26
+create_file_fallback_truncate(BlockBackend *blk, int64_t minimum_size,
63
+bdrv_open_driver(BlockDriverState *bs, BlockDriver *drv, const char *node_name,
27
+ Error **errp)
64
+ QDict *options, int open_flags, Error **errp)
65
{
28
{
66
Error *local_err = NULL;
29
Error *local_err = NULL;
67
int i, ret;
30
int64_t size;
68
diff --git a/block/qcow2.c b/block/qcow2.c
31
@@ -XXX,XX +XXX,XX @@ static int64_t create_file_fallback_truncate(BlockBackend *blk,
69
index XXXXXXX..XXXXXXX 100644
32
70
--- a/block/qcow2.c
33
GLOBAL_STATE_CODE();
71
+++ b/block/qcow2.c
34
72
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn qcow2_open_entry(void *opaque)
35
- ret = blk_truncate(blk, minimum_size, false, PREALLOC_MODE_OFF, 0,
73
QCow2OpenCo *qoc = opaque;
36
- &local_err);
74
BDRVQcow2State *s = qoc->bs->opaque;
37
+ ret = blk_co_truncate(blk, minimum_size, false, PREALLOC_MODE_OFF, 0,
75
38
+ &local_err);
76
- assume_graph_lock(); /* FIXME */
39
if (ret < 0 && ret != -ENOTSUP) {
77
+ GRAPH_RDLOCK_GUARD();
40
error_propagate(errp, local_err);
78
79
qemu_co_mutex_lock(&s->lock);
80
qoc->ret = qcow2_do_open(qoc->bs, qoc->options, qoc->flags, true,
81
@@ -XXX,XX +XXX,XX @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
82
/* Initialise locks */
83
qemu_co_mutex_init(&s->lock);
84
85
- if (qemu_in_coroutine()) {
86
- /* From bdrv_co_create. */
87
- qcow2_open_entry(&qoc);
88
- } else {
89
- assert(qemu_get_current_aio_context() == qemu_get_aio_context());
90
- qemu_coroutine_enter(qemu_coroutine_create(qcow2_open_entry, &qoc));
91
- BDRV_POLL_WHILE(bs, qoc.ret == -EINPROGRESS);
92
- }
93
+ assert(!qemu_in_coroutine());
94
+ assert(qemu_get_current_aio_context() == qemu_get_aio_context());
95
+ qemu_coroutine_enter(qemu_coroutine_create(qcow2_open_entry, &qoc));
96
+ BDRV_POLL_WHILE(bs, qoc.ret == -EINPROGRESS);
97
+
98
return qoc.ret;
99
}
100
101
diff --git a/block/qed.c b/block/qed.c
102
index XXXXXXX..XXXXXXX 100644
103
--- a/block/qed.c
104
+++ b/block/qed.c
105
@@ -XXX,XX +XXX,XX @@ typedef struct QEDOpenCo {
106
int ret;
107
} QEDOpenCo;
108
109
-static void coroutine_fn GRAPH_RDLOCK bdrv_qed_open_entry(void *opaque)
110
+static void coroutine_fn bdrv_qed_open_entry(void *opaque)
111
{
112
QEDOpenCo *qoc = opaque;
113
BDRVQEDState *s = qoc->bs->opaque;
114
115
+ GRAPH_RDLOCK_GUARD();
116
+
117
qemu_co_mutex_lock(&s->table_lock);
118
qoc->ret = bdrv_qed_do_open(qoc->bs, qoc->options, qoc->flags, qoc->errp);
119
qemu_co_mutex_unlock(&s->table_lock);
120
@@ -XXX,XX +XXX,XX @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
121
};
122
int ret;
123
124
- assume_graph_lock(); /* FIXME */
125
-
126
ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
127
if (ret < 0) {
128
return ret;
41
return ret;
129
}
42
}
130
43
131
bdrv_qed_init_state(bs);
44
- size = blk_getlength(blk);
132
- if (qemu_in_coroutine()) {
45
+ size = blk_co_getlength(blk);
133
- bdrv_qed_open_entry(&qoc);
46
if (size < 0) {
134
- } else {
47
error_free(local_err);
135
- assert(qemu_get_current_aio_context() == qemu_get_aio_context());
48
error_setg_errno(errp, -size,
136
- qemu_coroutine_enter(qemu_coroutine_create(bdrv_qed_open_entry, &qoc));
137
- BDRV_POLL_WHILE(bs, qoc.ret == -EINPROGRESS);
138
- }
139
+ assert(!qemu_in_coroutine());
140
+ assert(qemu_get_current_aio_context() == qemu_get_aio_context());
141
+ qemu_coroutine_enter(qemu_coroutine_create(bdrv_qed_open_entry, &qoc));
142
+ BDRV_POLL_WHILE(bs, qoc.ret == -EINPROGRESS);
143
+
144
return qoc.ret;
145
}
146
147
--
49
--
148
2.40.1
50
2.41.0
diff view generated by jsdifflib
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
2
3
This adds GRAPH_RDLOCK annotations to declare that callers of
3
Mark functions as coroutine_fn when they are only called by other coroutine_fns
4
nbd_co_do_establish_connection() need to hold a reader lock for the
4
and they can suspend. Change calls to co_wrappers to use the non-wrapped
5
graph.
5
functions, which in turn requires adding GRAPH_RDLOCK annotations.
6
6
7
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
7
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Message-ID: <20230601115145.196465-7-pbonzini@redhat.com>
9
Reviewed-by: Eric Blake <eblake@redhat.com>
9
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
10
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
11
Message-Id: <20230504115750.54437-11-kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
11
---
14
block/coroutines.h | 5 +++--
12
block/cloop.c | 9 +++++----
15
block/nbd.c | 39 +++++++++++++++++++++------------------
13
1 file changed, 5 insertions(+), 4 deletions(-)
16
2 files changed, 24 insertions(+), 20 deletions(-)
17
14
18
diff --git a/block/coroutines.h b/block/coroutines.h
15
diff --git a/block/cloop.c b/block/cloop.c
19
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
20
--- a/block/coroutines.h
17
--- a/block/cloop.c
21
+++ b/block/coroutines.h
18
+++ b/block/cloop.c
22
@@ -XXX,XX +XXX,XX @@ bdrv_co_readv_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos);
19
@@ -XXX,XX +XXX,XX @@ static void cloop_refresh_limits(BlockDriverState *bs, Error **errp)
23
int coroutine_fn GRAPH_RDLOCK
20
bs->bl.request_alignment = BDRV_SECTOR_SIZE; /* No sub-sector I/O */
24
bdrv_co_writev_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos);
25
26
-int coroutine_fn
27
+int coroutine_fn GRAPH_RDLOCK
28
nbd_co_do_establish_connection(BlockDriverState *bs, bool blocking,
29
Error **errp);
30
31
@@ -XXX,XX +XXX,XX @@ bdrv_common_block_status_above(BlockDriverState *bs,
32
int64_t *map,
33
BlockDriverState **file,
34
int *depth);
35
-int co_wrapper_mixed
36
+
37
+int co_wrapper_mixed_bdrv_rdlock
38
nbd_do_establish_connection(BlockDriverState *bs, bool blocking, Error **errp);
39
40
#endif /* BLOCK_COROUTINES_H */
41
diff --git a/block/nbd.c b/block/nbd.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/block/nbd.c
44
+++ b/block/nbd.c
45
@@ -XXX,XX +XXX,XX @@ int coroutine_fn nbd_co_do_establish_connection(BlockDriverState *bs,
46
int ret;
47
IO_CODE();
48
49
+ assert_bdrv_graph_readable();
50
assert(!s->ioc);
51
52
s->ioc = nbd_co_establish_connection(s->conn, &s->info, blocking, errp);
53
@@ -XXX,XX +XXX,XX @@ static bool nbd_client_connecting(BDRVNBDState *s)
54
}
21
}
55
22
56
/* Called with s->requests_lock taken. */
23
-static inline int cloop_read_block(BlockDriverState *bs, int block_num)
57
-static coroutine_fn void nbd_reconnect_attempt(BDRVNBDState *s)
24
+static int coroutine_fn GRAPH_RDLOCK
58
+static void coroutine_fn GRAPH_RDLOCK nbd_reconnect_attempt(BDRVNBDState *s)
25
+cloop_read_block(BlockDriverState *bs, int block_num)
59
{
26
{
60
int ret;
27
BDRVCloopState *s = bs->opaque;
61
bool blocking = s->state == NBD_CLIENT_CONNECTING_WAIT;
28
62
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int nbd_receive_replies(BDRVNBDState *s, uint64_t handle)
29
@@ -XXX,XX +XXX,XX @@ static inline int cloop_read_block(BlockDriverState *bs, int block_num)
63
}
30
int ret;
31
uint32_t bytes = s->offsets[block_num + 1] - s->offsets[block_num];
32
33
- ret = bdrv_pread(bs->file, s->offsets[block_num], bytes,
34
- s->compressed_block, 0);
35
+ ret = bdrv_co_pread(bs->file, s->offsets[block_num], bytes,
36
+ s->compressed_block, 0);
37
if (ret < 0) {
38
return -1;
39
}
40
@@ -XXX,XX +XXX,XX @@ static inline int cloop_read_block(BlockDriverState *bs, int block_num)
41
return 0;
64
}
42
}
65
43
66
-static int coroutine_fn nbd_co_send_request(BlockDriverState *bs,
44
-static int coroutine_fn
67
- NBDRequest *request,
68
- QEMUIOVector *qiov)
69
+static int coroutine_fn GRAPH_RDLOCK
45
+static int coroutine_fn GRAPH_RDLOCK
70
+nbd_co_send_request(BlockDriverState *bs, NBDRequest *request,
46
cloop_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
71
+ QEMUIOVector *qiov)
47
QEMUIOVector *qiov, BdrvRequestFlags flags)
72
{
73
BDRVNBDState *s = (BDRVNBDState *)bs->opaque;
74
int rc, i = -1;
75
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn nbd_co_receive_blockstatus_reply(BDRVNBDState *s,
76
return iter.ret;
77
}
78
79
-static int coroutine_fn nbd_co_request(BlockDriverState *bs, NBDRequest *request,
80
- QEMUIOVector *write_qiov)
81
+static int coroutine_fn GRAPH_RDLOCK
82
+nbd_co_request(BlockDriverState *bs, NBDRequest *request,
83
+ QEMUIOVector *write_qiov)
84
{
85
int ret, request_ret;
86
Error *local_err = NULL;
87
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn nbd_co_request(BlockDriverState *bs, NBDRequest *request
88
return ret ? ret : request_ret;
89
}
90
91
-static int coroutine_fn nbd_client_co_preadv(BlockDriverState *bs, int64_t offset,
92
- int64_t bytes, QEMUIOVector *qiov,
93
- BdrvRequestFlags flags)
94
+static int coroutine_fn GRAPH_RDLOCK
95
+nbd_client_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
96
+ QEMUIOVector *qiov, BdrvRequestFlags flags)
97
{
98
int ret, request_ret;
99
Error *local_err = NULL;
100
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn nbd_client_co_preadv(BlockDriverState *bs, int64_t offse
101
return ret ? ret : request_ret;
102
}
103
104
-static int coroutine_fn nbd_client_co_pwritev(BlockDriverState *bs, int64_t offset,
105
- int64_t bytes, QEMUIOVector *qiov,
106
- BdrvRequestFlags flags)
107
+static int coroutine_fn GRAPH_RDLOCK
108
+nbd_client_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
109
+ QEMUIOVector *qiov, BdrvRequestFlags flags)
110
{
111
BDRVNBDState *s = (BDRVNBDState *)bs->opaque;
112
NBDRequest request = {
113
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn nbd_client_co_pwritev(BlockDriverState *bs, int64_t offs
114
return nbd_co_request(bs, &request, qiov);
115
}
116
117
-static int coroutine_fn nbd_client_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
118
- int64_t bytes, BdrvRequestFlags flags)
119
+static int coroutine_fn GRAPH_RDLOCK
120
+nbd_client_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
121
+ BdrvRequestFlags flags)
122
{
123
BDRVNBDState *s = (BDRVNBDState *)bs->opaque;
124
NBDRequest request = {
125
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn nbd_client_co_pwrite_zeroes(BlockDriverState *bs, int64_
126
return nbd_co_request(bs, &request, NULL);
127
}
128
129
-static int coroutine_fn nbd_client_co_flush(BlockDriverState *bs)
130
+static int coroutine_fn GRAPH_RDLOCK nbd_client_co_flush(BlockDriverState *bs)
131
{
132
BDRVNBDState *s = (BDRVNBDState *)bs->opaque;
133
NBDRequest request = { .type = NBD_CMD_FLUSH };
134
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn nbd_client_co_flush(BlockDriverState *bs)
135
return nbd_co_request(bs, &request, NULL);
136
}
137
138
-static int coroutine_fn nbd_client_co_pdiscard(BlockDriverState *bs, int64_t offset,
139
- int64_t bytes)
140
+static int coroutine_fn GRAPH_RDLOCK
141
+nbd_client_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
142
{
143
BDRVNBDState *s = (BDRVNBDState *)bs->opaque;
144
NBDRequest request = {
145
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn nbd_client_co_pdiscard(BlockDriverState *bs, int64_t off
146
return nbd_co_request(bs, &request, NULL);
147
}
148
149
-static int coroutine_fn nbd_client_co_block_status(
150
+static int coroutine_fn GRAPH_RDLOCK nbd_client_co_block_status(
151
BlockDriverState *bs, bool want_zero, int64_t offset, int64_t bytes,
152
int64_t *pnum, int64_t *map, BlockDriverState **file)
153
{
48
{
154
--
49
--
155
2.40.1
50
2.41.0
diff view generated by jsdifflib
1
From: Paolo Bonzini <pbonzini@redhat.com>
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
2
3
After the recent introduction of many new coroutine callbacks,
3
Mark functions as coroutine_fn when they are only called by other coroutine_fns
4
a couple calls from non-coroutine_fn to coroutine_fn have sneaked
4
and they can suspend. Change calls to co_wrappers to use the non-wrapped
5
in; fix them.
5
functions, which in turn requires adding GRAPH_RDLOCK annotations.
6
6
7
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
7
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
8
Message-Id: <20230406101752.242125-1-pbonzini@redhat.com>
8
Message-ID: <20230601115145.196465-8-pbonzini@redhat.com>
9
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
11
---
12
include/block/graph-lock.h | 4 ++--
12
block/dmg.c | 21 +++++++++++----------
13
block/mirror.c | 4 ++--
13
1 file changed, 11 insertions(+), 10 deletions(-)
14
2 files changed, 4 insertions(+), 4 deletions(-)
15
14
16
diff --git a/include/block/graph-lock.h b/include/block/graph-lock.h
15
diff --git a/block/dmg.c b/block/dmg.c
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/include/block/graph-lock.h
17
--- a/block/dmg.c
19
+++ b/include/block/graph-lock.h
18
+++ b/block/dmg.c
20
@@ -XXX,XX +XXX,XX @@ typedef struct GraphLockable { } GraphLockable;
19
@@ -XXX,XX +XXX,XX @@ err:
21
* unlocked. TSA_ASSERT() makes sure that the following calls know that we
20
return s->n_chunks; /* error */
22
* hold the lock while unlocking is left unchecked.
21
}
23
*/
22
24
-static inline GraphLockable * TSA_ASSERT(graph_lock) TSA_NO_TSA
23
-static inline int dmg_read_chunk(BlockDriverState *bs, uint64_t sector_num)
25
+static inline GraphLockable * TSA_ASSERT(graph_lock) TSA_NO_TSA coroutine_fn
24
+static int coroutine_fn GRAPH_RDLOCK
26
graph_lockable_auto_lock(GraphLockable *x)
25
+dmg_read_chunk(BlockDriverState *bs, uint64_t sector_num)
27
{
26
{
28
bdrv_graph_co_rdlock();
27
BDRVDMGState *s = bs->opaque;
29
return x;
28
29
@@ -XXX,XX +XXX,XX @@ static inline int dmg_read_chunk(BlockDriverState *bs, uint64_t sector_num)
30
case UDZO: { /* zlib compressed */
31
/* we need to buffer, because only the chunk as whole can be
32
* inflated. */
33
- ret = bdrv_pread(bs->file, s->offsets[chunk], s->lengths[chunk],
34
- s->compressed_chunk, 0);
35
+ ret = bdrv_co_pread(bs->file, s->offsets[chunk], s->lengths[chunk],
36
+ s->compressed_chunk, 0);
37
if (ret < 0) {
38
return -1;
39
}
40
@@ -XXX,XX +XXX,XX @@ static inline int dmg_read_chunk(BlockDriverState *bs, uint64_t sector_num)
41
}
42
/* we need to buffer, because only the chunk as whole can be
43
* inflated. */
44
- ret = bdrv_pread(bs->file, s->offsets[chunk], s->lengths[chunk],
45
- s->compressed_chunk, 0);
46
+ ret = bdrv_co_pread(bs->file, s->offsets[chunk], s->lengths[chunk],
47
+ s->compressed_chunk, 0);
48
if (ret < 0) {
49
return -1;
50
}
51
@@ -XXX,XX +XXX,XX @@ static inline int dmg_read_chunk(BlockDriverState *bs, uint64_t sector_num)
52
}
53
/* we need to buffer, because only the chunk as whole can be
54
* inflated. */
55
- ret = bdrv_pread(bs->file, s->offsets[chunk], s->lengths[chunk],
56
- s->compressed_chunk, 0);
57
+ ret = bdrv_co_pread(bs->file, s->offsets[chunk], s->lengths[chunk],
58
+ s->compressed_chunk, 0);
59
if (ret < 0) {
60
return -1;
61
}
62
@@ -XXX,XX +XXX,XX @@ static inline int dmg_read_chunk(BlockDriverState *bs, uint64_t sector_num)
63
}
64
break;
65
case UDRW: /* copy */
66
- ret = bdrv_pread(bs->file, s->offsets[chunk], s->lengths[chunk],
67
- s->uncompressed_chunk, 0);
68
+ ret = bdrv_co_pread(bs->file, s->offsets[chunk], s->lengths[chunk],
69
+ s->uncompressed_chunk, 0);
70
if (ret < 0) {
71
return -1;
72
}
73
@@ -XXX,XX +XXX,XX @@ static inline int dmg_read_chunk(BlockDriverState *bs, uint64_t sector_num)
74
return 0;
30
}
75
}
31
76
32
-static inline void TSA_NO_TSA
77
-static int coroutine_fn
33
+static inline void TSA_NO_TSA coroutine_fn
78
+static int coroutine_fn GRAPH_RDLOCK
34
graph_lockable_auto_unlock(GraphLockable *x)
79
dmg_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
80
QEMUIOVector *qiov, BdrvRequestFlags flags)
35
{
81
{
36
bdrv_graph_co_rdunlock();
37
diff --git a/block/mirror.c b/block/mirror.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/block/mirror.c
40
+++ b/block/mirror.c
41
@@ -XXX,XX +XXX,XX @@ static inline int64_t mirror_clip_bytes(MirrorBlockJob *s,
42
43
/* Round offset and/or bytes to target cluster if COW is needed, and
44
* return the offset of the adjusted tail against original. */
45
-static int mirror_cow_align(MirrorBlockJob *s, int64_t *offset,
46
- uint64_t *bytes)
47
+static int coroutine_fn mirror_cow_align(MirrorBlockJob *s, int64_t *offset,
48
+ uint64_t *bytes)
49
{
50
bool need_cow;
51
int ret = 0;
52
--
82
--
53
2.40.1
83
2.41.0
diff view generated by jsdifflib
Deleted patch
1
From: Stefan Hajnoczi <stefanha@redhat.com>
2
1
3
There is no need for the AioContext lock in aio_wait_bh_oneshot().
4
It's easy to remove the lock from existing callers and then switch from
5
AIO_WAIT_WHILE() to AIO_WAIT_WHILE_UNLOCKED() in aio_wait_bh_oneshot().
6
7
Document that the AioContext lock should not be held across
8
aio_wait_bh_oneshot(). Holding a lock across aio_poll() can cause
9
deadlock so we don't want callers to do that.
10
11
This is a step towards getting rid of the AioContext lock.
12
13
Cc: Paolo Bonzini <pbonzini@redhat.com>
14
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
15
Message-Id: <20230404153307.458883-1-stefanha@redhat.com>
16
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
17
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
18
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
19
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
20
---
21
include/block/aio-wait.h | 2 +-
22
hw/block/dataplane/virtio-blk.c | 3 ++-
23
hw/scsi/virtio-scsi-dataplane.c | 2 --
24
util/aio-wait.c | 2 +-
25
4 files changed, 4 insertions(+), 5 deletions(-)
26
27
diff --git a/include/block/aio-wait.h b/include/block/aio-wait.h
28
index XXXXXXX..XXXXXXX 100644
29
--- a/include/block/aio-wait.h
30
+++ b/include/block/aio-wait.h
31
@@ -XXX,XX +XXX,XX @@ void aio_wait_kick(void);
32
*
33
* Run a BH in @ctx and wait for it to complete.
34
*
35
- * Must be called from the main loop thread with @ctx acquired exactly once.
36
+ * Must be called from the main loop thread without @ctx acquired.
37
* Note that main loop event processing may occur.
38
*/
39
void aio_wait_bh_oneshot(AioContext *ctx, QEMUBHFunc *cb, void *opaque);
40
diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/block/dataplane/virtio-blk.c
43
+++ b/hw/block/dataplane/virtio-blk.c
44
@@ -XXX,XX +XXX,XX @@ void virtio_blk_data_plane_stop(VirtIODevice *vdev)
45
s->stopping = true;
46
trace_virtio_blk_data_plane_stop(s);
47
48
- aio_context_acquire(s->ctx);
49
aio_wait_bh_oneshot(s->ctx, virtio_blk_data_plane_stop_bh, s);
50
51
+ aio_context_acquire(s->ctx);
52
+
53
/* Wait for virtio_blk_dma_restart_bh() and in flight I/O to complete */
54
blk_drain(s->conf->conf.blk);
55
56
diff --git a/hw/scsi/virtio-scsi-dataplane.c b/hw/scsi/virtio-scsi-dataplane.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/hw/scsi/virtio-scsi-dataplane.c
59
+++ b/hw/scsi/virtio-scsi-dataplane.c
60
@@ -XXX,XX +XXX,XX @@ void virtio_scsi_dataplane_stop(VirtIODevice *vdev)
61
}
62
s->dataplane_stopping = true;
63
64
- aio_context_acquire(s->ctx);
65
aio_wait_bh_oneshot(s->ctx, virtio_scsi_dataplane_stop_bh, s);
66
- aio_context_release(s->ctx);
67
68
blk_drain_all(); /* ensure there are no in-flight requests */
69
70
diff --git a/util/aio-wait.c b/util/aio-wait.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/util/aio-wait.c
73
+++ b/util/aio-wait.c
74
@@ -XXX,XX +XXX,XX @@ void aio_wait_bh_oneshot(AioContext *ctx, QEMUBHFunc *cb, void *opaque)
75
assert(qemu_get_current_aio_context() == qemu_get_aio_context());
76
77
aio_bh_schedule_oneshot(ctx, aio_wait_bh, &data);
78
- AIO_WAIT_WHILE(ctx, !data.done);
79
+ AIO_WAIT_WHILE_UNLOCKED(NULL, !data.done);
80
}
81
--
82
2.40.1
diff view generated by jsdifflib
Deleted patch
1
job_cancel_locked() drops the job list lock temporarily and it may call
2
aio_poll(). We must assume that the list has changed after this call.
3
Also, with unlucky timing, it can end up freeing the job during
4
job_completed_txn_abort_locked(), making the job pointer invalid, too.
5
1
6
For both reasons, we can't just continue at block_job_next_locked(job).
7
Instead, start at the head of the list again after job_cancel_locked()
8
and skip those jobs that we already cancelled (or that are completing
9
anyway).
10
11
Cc: qemu-stable@nongnu.org
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
Message-Id: <20230503140142.474404-1-kwolf@redhat.com>
14
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
15
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
---
17
blockdev.c | 18 ++++++++++++++----
18
1 file changed, 14 insertions(+), 4 deletions(-)
19
20
diff --git a/blockdev.c b/blockdev.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/blockdev.c
23
+++ b/blockdev.c
24
@@ -XXX,XX +XXX,XX @@ void blockdev_mark_auto_del(BlockBackend *blk)
25
26
JOB_LOCK_GUARD();
27
28
- for (job = block_job_next_locked(NULL); job;
29
- job = block_job_next_locked(job)) {
30
- if (block_job_has_bdrv(job, blk_bs(blk))) {
31
+ do {
32
+ job = block_job_next_locked(NULL);
33
+ while (job && (job->job.cancelled ||
34
+ job->job.deferred_to_main_loop ||
35
+ !block_job_has_bdrv(job, blk_bs(blk))))
36
+ {
37
+ job = block_job_next_locked(job);
38
+ }
39
+ if (job) {
40
+ /*
41
+ * This drops the job lock temporarily and polls, so we need to
42
+ * restart processing the list from the start after this.
43
+ */
44
job_cancel_locked(&job->job, false);
45
}
46
- }
47
+ } while (job);
48
49
dinfo->auto_del = 1;
50
}
51
--
52
2.40.1
diff view generated by jsdifflib
Deleted patch
1
Socket paths need to be short to avoid failures. This is why there is a
2
iotests.sock_dir (defaulting to /tmp) separate from the disk image base
3
directory.
4
1
5
Make use of it to fix failures in too deeply nested test directories.
6
7
Fixes: ab7f7e67a7e7b49964109501dfcde4ec29bae60e
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Message-Id: <20230503165019.8867-1-kwolf@redhat.com>
10
Reviewed-by: Eric Blake <eblake@redhat.com>
11
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
14
tests/qemu-iotests/tests/nbd-reconnect-on-open | 3 ++-
15
tests/qemu-iotests/tests/nbd-reconnect-on-open.out | 4 ++--
16
2 files changed, 4 insertions(+), 3 deletions(-)
17
18
diff --git a/tests/qemu-iotests/tests/nbd-reconnect-on-open b/tests/qemu-iotests/tests/nbd-reconnect-on-open
19
index XXXXXXX..XXXXXXX 100755
20
--- a/tests/qemu-iotests/tests/nbd-reconnect-on-open
21
+++ b/tests/qemu-iotests/tests/nbd-reconnect-on-open
22
@@ -XXX,XX +XXX,XX @@ from iotests import qemu_img_create, file_path, qemu_io_popen, qemu_nbd, \
23
24
iotests.script_initialize(supported_fmts=['qcow2'])
25
26
-disk, nbd_sock = file_path('disk', 'nbd-sock')
27
+disk = file_path('disk')
28
+nbd_sock = file_path('nbd-sock', base_dir=iotests.sock_dir)
29
30
31
def create_args(open_timeout):
32
diff --git a/tests/qemu-iotests/tests/nbd-reconnect-on-open.out b/tests/qemu-iotests/tests/nbd-reconnect-on-open.out
33
index XXXXXXX..XXXXXXX 100644
34
--- a/tests/qemu-iotests/tests/nbd-reconnect-on-open.out
35
+++ b/tests/qemu-iotests/tests/nbd-reconnect-on-open.out
36
@@ -XXX,XX +XXX,XX @@ read 1048576/1048576 bytes at offset 0
37
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
38
39
Check fail to connect with 0 seconds of timeout
40
-qemu-io: can't open: Failed to connect to 'TEST_DIR/PID-nbd-sock': No such file or directory
41
+qemu-io: can't open: Failed to connect to 'SOCK_DIR/PID-nbd-sock': No such file or directory
42
43
qemu_io finished in 0..0.2 seconds, OK
44
Check fail to connect with 1 seconds of timeout
45
-qemu-io: can't open: Failed to connect to 'TEST_DIR/PID-nbd-sock': No such file or directory
46
+qemu-io: can't open: Failed to connect to 'SOCK_DIR/PID-nbd-sock': No such file or directory
47
48
qemu_io finished in 1..1.2 seconds, OK
49
--
50
2.40.1
diff view generated by jsdifflib
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
2
3
This adds GRAPH_RDLOCK annotations to declare that callers of amend
3
Mark functions as coroutine_fn when they are only called by other coroutine_fns
4
callbacks in BlockDriver need to hold a reader lock for the graph.
4
and they can suspend. Change calls to co_wrappers to use the non-wrapped
5
functions, which in turn requires adding GRAPH_RDLOCK annotations.
5
6
6
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
7
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Message-ID: <20230601115145.196465-9-pbonzini@redhat.com>
8
Reviewed-by: Eric Blake <eblake@redhat.com>
9
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
10
Message-Id: <20230504115750.54437-17-kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
11
---
13
include/block/block_int-common.h | 12 ++++++------
12
block/vmdk.c | 27 ++++++++++++++-------------
14
block/amend.c | 8 +++++++-
13
1 file changed, 14 insertions(+), 13 deletions(-)
15
2 files changed, 13 insertions(+), 7 deletions(-)
16
14
17
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
15
diff --git a/block/vmdk.c b/block/vmdk.c
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/include/block/block_int-common.h
17
--- a/block/vmdk.c
20
+++ b/include/block/block_int-common.h
18
+++ b/block/vmdk.c
21
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
19
@@ -XXX,XX +XXX,XX @@ out:
22
* to allow driver-specific initialization code that requires
23
* the BQL, like setting up specific permission flags.
24
*/
25
- int (*bdrv_amend_pre_run)(BlockDriverState *bs, Error **errp);
26
+ int GRAPH_RDLOCK_PTR (*bdrv_amend_pre_run)(
27
+ BlockDriverState *bs, Error **errp);
28
/*
29
* This function is invoked under BQL after .bdrv_co_amend()
30
* to allow cleaning up what was done in .bdrv_amend_pre_run().
31
*/
32
- void (*bdrv_amend_clean)(BlockDriverState *bs);
33
+ void GRAPH_RDLOCK_PTR (*bdrv_amend_clean)(BlockDriverState *bs);
34
35
/*
36
* Return true if @to_replace can be replaced by a BDS with the
37
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
38
39
int (*bdrv_probe)(const uint8_t *buf, int buf_size, const char *filename);
40
41
- int coroutine_fn (*bdrv_co_amend)(BlockDriverState *bs,
42
- BlockdevAmendOptions *opts,
43
- bool force,
44
- Error **errp);
45
+ int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_amend)(
46
+ BlockDriverState *bs, BlockdevAmendOptions *opts, bool force,
47
+ Error **errp);
48
49
/* aio */
50
BlockAIOCB * GRAPH_RDLOCK_PTR (*bdrv_aio_preadv)(BlockDriverState *bs,
51
diff --git a/block/amend.c b/block/amend.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/block/amend.c
54
+++ b/block/amend.c
55
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn blockdev_amend_run(Job *job, Error **errp)
56
{
57
BlockdevAmendJob *s = container_of(job, BlockdevAmendJob, common);
58
int ret;
59
+ GRAPH_RDLOCK_GUARD();
60
61
job_progress_set_remaining(&s->common, 1);
62
ret = s->bs->drv->bdrv_co_amend(s->bs, s->opts, s->force, errp);
63
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn blockdev_amend_run(Job *job, Error **errp)
64
return ret;
20
return ret;
65
}
21
}
66
22
67
-static int blockdev_amend_pre_run(BlockdevAmendJob *s, Error **errp)
23
-static int vmdk_write_cid(BlockDriverState *bs, uint32_t cid)
68
+static int GRAPH_RDLOCK
24
+static int coroutine_fn GRAPH_RDLOCK
69
+blockdev_amend_pre_run(BlockdevAmendJob *s, Error **errp)
25
+vmdk_write_cid(BlockDriverState *bs, uint32_t cid)
70
{
26
{
71
if (s->bs->drv->bdrv_amend_pre_run) {
27
char *desc, *tmp_desc;
72
return s->bs->drv->bdrv_amend_pre_run(s->bs, errp);
28
char *p_name, *tmp_str;
73
@@ -XXX,XX +XXX,XX @@ static void blockdev_amend_free(Job *job)
29
@@ -XXX,XX +XXX,XX @@ static int vmdk_write_cid(BlockDriverState *bs, uint32_t cid)
30
31
desc = g_malloc0(DESC_SIZE);
32
tmp_desc = g_malloc0(DESC_SIZE);
33
- ret = bdrv_pread(bs->file, s->desc_offset, DESC_SIZE, desc, 0);
34
+ ret = bdrv_co_pread(bs->file, s->desc_offset, DESC_SIZE, desc, 0);
35
if (ret < 0) {
36
goto out;
37
}
38
@@ -XXX,XX +XXX,XX @@ static int vmdk_write_cid(BlockDriverState *bs, uint32_t cid)
39
pstrcat(desc, DESC_SIZE, tmp_desc);
40
}
41
42
- ret = bdrv_pwrite_sync(bs->file, s->desc_offset, DESC_SIZE, desc, 0);
43
+ ret = bdrv_co_pwrite_sync(bs->file, s->desc_offset, DESC_SIZE, desc, 0);
44
45
out:
46
g_free(desc);
47
@@ -XXX,XX +XXX,XX @@ vmdk_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
48
return ret;
49
}
50
51
-static int GRAPH_UNLOCKED
52
+static int coroutine_fn GRAPH_UNLOCKED
53
vmdk_init_extent(BlockBackend *blk, int64_t filesize, bool flat, bool compress,
54
bool zeroed_grain, Error **errp)
74
{
55
{
75
BlockdevAmendJob *s = container_of(job, BlockdevAmendJob, common);
56
@@ -XXX,XX +XXX,XX @@ vmdk_init_extent(BlockBackend *blk, int64_t filesize, bool flat, bool compress,
76
57
int gd_buf_size;
77
+ bdrv_graph_rdlock_main_loop();
58
78
if (s->bs->drv->bdrv_amend_clean) {
59
if (flat) {
79
s->bs->drv->bdrv_amend_clean(s->bs);
60
- ret = blk_truncate(blk, filesize, false, PREALLOC_MODE_OFF, 0, errp);
61
+ ret = blk_co_truncate(blk, filesize, false, PREALLOC_MODE_OFF, 0, errp);
62
goto exit;
80
}
63
}
81
+ bdrv_graph_rdunlock_main_loop();
64
magic = cpu_to_be32(VMDK4_MAGIC);
82
65
@@ -XXX,XX +XXX,XX @@ vmdk_init_extent(BlockBackend *blk, int64_t filesize, bool flat, bool compress,
83
bdrv_unref(s->bs);
66
header.check_bytes[3] = 0xa;
84
}
67
85
@@ -XXX,XX +XXX,XX @@ void qmp_x_blockdev_amend(const char *job_id,
68
/* write all the data */
86
BlockDriver *drv = bdrv_find_format(fmt);
69
- ret = blk_pwrite(blk, 0, sizeof(magic), &magic, 0);
87
BlockDriverState *bs;
70
+ ret = blk_co_pwrite(blk, 0, sizeof(magic), &magic, 0);
88
71
if (ret < 0) {
89
+ GRAPH_RDLOCK_GUARD_MAINLOOP();
72
error_setg(errp, QERR_IO_ERROR);
90
+
73
goto exit;
91
bs = bdrv_lookup_bs(NULL, node_name, errp);
74
}
92
if (!bs) {
75
- ret = blk_pwrite(blk, sizeof(magic), sizeof(header), &header, 0);
93
return;
76
+ ret = blk_co_pwrite(blk, sizeof(magic), sizeof(header), &header, 0);
77
if (ret < 0) {
78
error_setg(errp, QERR_IO_ERROR);
79
goto exit;
80
}
81
82
- ret = blk_truncate(blk, le64_to_cpu(header.grain_offset) << 9, false,
83
- PREALLOC_MODE_OFF, 0, errp);
84
+ ret = blk_co_truncate(blk, le64_to_cpu(header.grain_offset) << 9, false,
85
+ PREALLOC_MODE_OFF, 0, errp);
86
if (ret < 0) {
87
goto exit;
88
}
89
@@ -XXX,XX +XXX,XX @@ vmdk_init_extent(BlockBackend *blk, int64_t filesize, bool flat, bool compress,
90
i < gt_count; i++, tmp += gt_size) {
91
gd_buf[i] = cpu_to_le32(tmp);
92
}
93
- ret = blk_pwrite(blk, le64_to_cpu(header.rgd_offset) * BDRV_SECTOR_SIZE,
94
- gd_buf_size, gd_buf, 0);
95
+ ret = blk_co_pwrite(blk, le64_to_cpu(header.rgd_offset) * BDRV_SECTOR_SIZE,
96
+ gd_buf_size, gd_buf, 0);
97
if (ret < 0) {
98
error_setg(errp, QERR_IO_ERROR);
99
goto exit;
100
@@ -XXX,XX +XXX,XX @@ vmdk_init_extent(BlockBackend *blk, int64_t filesize, bool flat, bool compress,
101
i < gt_count; i++, tmp += gt_size) {
102
gd_buf[i] = cpu_to_le32(tmp);
103
}
104
- ret = blk_pwrite(blk, le64_to_cpu(header.gd_offset) * BDRV_SECTOR_SIZE,
105
- gd_buf_size, gd_buf, 0);
106
+ ret = blk_co_pwrite(blk, le64_to_cpu(header.gd_offset) * BDRV_SECTOR_SIZE,
107
+ gd_buf_size, gd_buf, 0);
108
if (ret < 0) {
109
error_setg(errp, QERR_IO_ERROR);
110
}
94
--
111
--
95
2.40.1
112
2.41.0
diff view generated by jsdifflib
1
This adds GRAPH_RDLOCK annotations to declare that functions accessing
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
the parent list of a node need to hold a reader lock for the graph. As
3
it happens, they already do.
4
2
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
3
Mark functions as coroutine_fn when they are only called by other coroutine_fns
6
Reviewed-by: Eric Blake <eblake@redhat.com>
4
and they can suspend. Change calls to co_wrappers to use the non-wrapped
7
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
5
functions, which in turn requires adding GRAPH_RDLOCK annotations.
8
Message-Id: <20230504115750.54437-12-kwolf@redhat.com>
6
7
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
8
Message-ID: <20230601115145.196465-10-pbonzini@redhat.com>
9
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
---
11
block/vhdx.c | 9 +++++----
12
block/vhdx.h | 5 ++--
12
1 file changed, 5 insertions(+), 4 deletions(-)
13
block/vhdx-log.c | 36 +++++++++++++-----------
14
block/vhdx.c | 73 +++++++++++++++++++++++-------------------------
15
3 files changed, 57 insertions(+), 57 deletions(-)
13
16
17
diff --git a/block/vhdx.h b/block/vhdx.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/block/vhdx.h
20
+++ b/block/vhdx.h
21
@@ -XXX,XX +XXX,XX @@ bool vhdx_checksum_is_valid(uint8_t *buf, size_t size, int crc_offset);
22
int vhdx_parse_log(BlockDriverState *bs, BDRVVHDXState *s, bool *flushed,
23
Error **errp);
24
25
-int vhdx_log_write_and_flush(BlockDriverState *bs, BDRVVHDXState *s,
26
- void *data, uint32_t length, uint64_t offset);
27
+int coroutine_fn GRAPH_RDLOCK
28
+vhdx_log_write_and_flush(BlockDriverState *bs, BDRVVHDXState *s,
29
+ void *data, uint32_t length, uint64_t offset);
30
31
static inline void leguid_to_cpus(MSGUID *guid)
32
{
33
diff --git a/block/vhdx-log.c b/block/vhdx-log.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/block/vhdx-log.c
36
+++ b/block/vhdx-log.c
37
@@ -XXX,XX +XXX,XX @@ exit:
38
* It is assumed that 'buffer' is at least 4096*num_sectors large.
39
*
40
* 0 is returned on success, -errno otherwise */
41
-static int vhdx_log_write_sectors(BlockDriverState *bs, VHDXLogEntries *log,
42
- uint32_t *sectors_written, void *buffer,
43
- uint32_t num_sectors)
44
+static int coroutine_fn GRAPH_RDLOCK
45
+vhdx_log_write_sectors(BlockDriverState *bs, VHDXLogEntries *log,
46
+ uint32_t *sectors_written, void *buffer,
47
+ uint32_t num_sectors)
48
{
49
int ret = 0;
50
uint64_t offset;
51
@@ -XXX,XX +XXX,XX @@ static int vhdx_log_write_sectors(BlockDriverState *bs, VHDXLogEntries *log,
52
/* full */
53
break;
54
}
55
- ret = bdrv_pwrite(bs->file, offset, VHDX_LOG_SECTOR_SIZE, buffer_tmp,
56
- 0);
57
+ ret = bdrv_co_pwrite(bs->file, offset, VHDX_LOG_SECTOR_SIZE, buffer_tmp, 0);
58
if (ret < 0) {
59
goto exit;
60
}
61
@@ -XXX,XX +XXX,XX @@ static void vhdx_log_raw_to_le_sector(VHDXLogDescriptor *desc,
62
}
63
64
65
-static int vhdx_log_write(BlockDriverState *bs, BDRVVHDXState *s,
66
- void *data, uint32_t length, uint64_t offset)
67
+static int coroutine_fn GRAPH_RDLOCK
68
+vhdx_log_write(BlockDriverState *bs, BDRVVHDXState *s,
69
+ void *data, uint32_t length, uint64_t offset)
70
{
71
int ret = 0;
72
void *buffer = NULL;
73
@@ -XXX,XX +XXX,XX @@ static int vhdx_log_write(BlockDriverState *bs, BDRVVHDXState *s,
74
75
sectors += partial_sectors;
76
77
- file_length = bdrv_getlength(bs->file->bs);
78
+ file_length = bdrv_co_getlength(bs->file->bs);
79
if (file_length < 0) {
80
ret = file_length;
81
goto exit;
82
@@ -XXX,XX +XXX,XX @@ static int vhdx_log_write(BlockDriverState *bs, BDRVVHDXState *s,
83
84
if (i == 0 && leading_length) {
85
/* partial sector at the front of the buffer */
86
- ret = bdrv_pread(bs->file, file_offset, VHDX_LOG_SECTOR_SIZE,
87
- merged_sector, 0);
88
+ ret = bdrv_co_pread(bs->file, file_offset, VHDX_LOG_SECTOR_SIZE,
89
+ merged_sector, 0);
90
if (ret < 0) {
91
goto exit;
92
}
93
@@ -XXX,XX +XXX,XX @@ static int vhdx_log_write(BlockDriverState *bs, BDRVVHDXState *s,
94
sector_write = merged_sector;
95
} else if (i == sectors - 1 && trailing_length) {
96
/* partial sector at the end of the buffer */
97
- ret = bdrv_pread(bs->file, file_offset + trailing_length,
98
- VHDX_LOG_SECTOR_SIZE - trailing_length,
99
- merged_sector + trailing_length, 0);
100
+ ret = bdrv_co_pread(bs->file, file_offset + trailing_length,
101
+ VHDX_LOG_SECTOR_SIZE - trailing_length,
102
+ merged_sector + trailing_length, 0);
103
if (ret < 0) {
104
goto exit;
105
}
106
@@ -XXX,XX +XXX,XX @@ exit:
107
}
108
109
/* Perform a log write, and then immediately flush the entire log */
110
-int vhdx_log_write_and_flush(BlockDriverState *bs, BDRVVHDXState *s,
111
- void *data, uint32_t length, uint64_t offset)
112
+int coroutine_fn
113
+vhdx_log_write_and_flush(BlockDriverState *bs, BDRVVHDXState *s,
114
+ void *data, uint32_t length, uint64_t offset)
115
{
116
int ret = 0;
117
VHDXLogSequence logs = { .valid = true,
118
@@ -XXX,XX +XXX,XX @@ int vhdx_log_write_and_flush(BlockDriverState *bs, BDRVVHDXState *s,
119
120
/* Make sure data written (new and/or changed blocks) is stable
121
* on disk, before creating log entry */
122
- ret = bdrv_flush(bs);
123
+ ret = bdrv_co_flush(bs);
124
if (ret < 0) {
125
goto exit;
126
}
127
@@ -XXX,XX +XXX,XX @@ int vhdx_log_write_and_flush(BlockDriverState *bs, BDRVVHDXState *s,
128
logs.log = s->log;
129
130
/* Make sure log is stable on disk */
131
- ret = bdrv_flush(bs);
132
+ ret = bdrv_co_flush(bs);
133
if (ret < 0) {
134
goto exit;
135
}
14
diff --git a/block/vhdx.c b/block/vhdx.c
136
diff --git a/block/vhdx.c b/block/vhdx.c
15
index XXXXXXX..XXXXXXX 100644
137
index XXXXXXX..XXXXXXX 100644
16
--- a/block/vhdx.c
138
--- a/block/vhdx.c
17
+++ b/block/vhdx.c
139
+++ b/block/vhdx.c
18
@@ -XXX,XX +XXX,XX @@ exit:
140
@@ -XXX,XX +XXX,XX @@ exit:
19
* There are 2 headers, and the highest sequence number will represent
141
*
20
* the active header
142
* Returns the file offset start of the new payload block
21
*/
143
*/
22
-static int vhdx_create_new_headers(BlockBackend *blk, uint64_t image_size,
144
-static int vhdx_allocate_block(BlockDriverState *bs, BDRVVHDXState *s,
23
- uint32_t log_size)
145
- uint64_t *new_offset, bool *need_zero)
24
+static int coroutine_fn GRAPH_RDLOCK
146
+static int coroutine_fn GRAPH_RDLOCK
25
+vhdx_create_new_headers(BlockBackend *blk, uint64_t image_size,
147
+vhdx_allocate_block(BlockDriverState *bs, BDRVVHDXState *s,
26
+ uint32_t log_size)
148
+ uint64_t *new_offset, bool *need_zero)
27
{
149
{
28
BlockDriverState *bs = blk_bs(blk);
150
int64_t current_len;
29
BdrvChild *child;
151
30
@@ -XXX,XX +XXX,XX @@ exit:
152
- current_len = bdrv_getlength(bs->file->bs);
31
* .---- ~ ----------- ~ ------------ ~ ---------------- ~ -----------.
153
+ current_len = bdrv_co_getlength(bs->file->bs);
32
* 1MB
154
if (current_len < 0) {
33
*/
155
return current_len;
34
-static int coroutine_fn vhdx_co_create(BlockdevCreateOptions *opts,
156
}
35
- Error **errp)
157
@@ -XXX,XX +XXX,XX @@ static int vhdx_allocate_block(BlockDriverState *bs, BDRVVHDXState *s,
36
+static int coroutine_fn GRAPH_RDLOCK
158
if (*need_zero) {
37
+vhdx_co_create(BlockdevCreateOptions *opts, Error **errp)
159
int ret;
38
{
160
39
BlockdevCreateOptionsVhdx *vhdx_opts;
161
- ret = bdrv_truncate(bs->file, *new_offset + s->block_size, false,
40
BlockBackend *blk = NULL;
162
- PREALLOC_MODE_OFF, BDRV_REQ_ZERO_WRITE, NULL);
163
+ ret = bdrv_co_truncate(bs->file, *new_offset + s->block_size, false,
164
+ PREALLOC_MODE_OFF, BDRV_REQ_ZERO_WRITE, NULL);
165
if (ret != -ENOTSUP) {
166
*need_zero = false;
167
return ret;
168
}
169
}
170
171
- return bdrv_truncate(bs->file, *new_offset + s->block_size, false,
172
- PREALLOC_MODE_OFF, 0, NULL);
173
+ return bdrv_co_truncate(bs->file, *new_offset + s->block_size, false,
174
+ PREALLOC_MODE_OFF, 0, NULL);
175
}
176
177
/*
178
@@ -XXX,XX +XXX,XX @@ exit:
179
* The first 64KB of the Metadata section is reserved for the metadata
180
* header and entries; beyond that, the metadata items themselves reside.
181
*/
182
-static int vhdx_create_new_metadata(BlockBackend *blk,
183
- uint64_t image_size,
184
- uint32_t block_size,
185
- uint32_t sector_size,
186
- uint64_t metadata_offset,
187
- VHDXImageType type)
188
+static int coroutine_fn
189
+vhdx_create_new_metadata(BlockBackend *blk, uint64_t image_size,
190
+ uint32_t block_size, uint32_t sector_size,
191
+ uint64_t metadata_offset, VHDXImageType type)
192
{
193
int ret = 0;
194
uint32_t offset = 0;
195
@@ -XXX,XX +XXX,XX @@ static int vhdx_create_new_metadata(BlockBackend *blk,
196
VHDX_META_FLAGS_IS_VIRTUAL_DISK;
197
vhdx_metadata_entry_le_export(&md_table_entry[4]);
198
199
- ret = blk_pwrite(blk, metadata_offset, VHDX_HEADER_BLOCK_SIZE, buffer, 0);
200
+ ret = blk_co_pwrite(blk, metadata_offset, VHDX_HEADER_BLOCK_SIZE, buffer, 0);
201
if (ret < 0) {
202
goto exit;
203
}
204
205
- ret = blk_pwrite(blk, metadata_offset + (64 * KiB),
206
- VHDX_METADATA_ENTRY_BUFFER_SIZE, entry_buffer, 0);
207
+ ret = blk_co_pwrite(blk, metadata_offset + (64 * KiB),
208
+ VHDX_METADATA_ENTRY_BUFFER_SIZE, entry_buffer, 0);
209
if (ret < 0) {
210
goto exit;
211
}
212
@@ -XXX,XX +XXX,XX @@ exit:
213
* Fixed images: default state of the BAT is fully populated, with
214
* file offsets and state PAYLOAD_BLOCK_FULLY_PRESENT.
215
*/
216
-static int vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s,
217
- uint64_t image_size, VHDXImageType type,
218
- bool use_zero_blocks, uint64_t file_offset,
219
- uint32_t length, Error **errp)
220
+static int coroutine_fn
221
+vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s,
222
+ uint64_t image_size, VHDXImageType type,
223
+ bool use_zero_blocks, uint64_t file_offset,
224
+ uint32_t length, Error **errp)
225
{
226
int ret = 0;
227
uint64_t data_file_offset;
228
@@ -XXX,XX +XXX,XX @@ static int vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s,
229
if (type == VHDX_TYPE_DYNAMIC) {
230
/* All zeroes, so we can just extend the file - the end of the BAT
231
* is the furthest thing we have written yet */
232
- ret = blk_truncate(blk, data_file_offset, false, PREALLOC_MODE_OFF,
233
- 0, errp);
234
+ ret = blk_co_truncate(blk, data_file_offset, false, PREALLOC_MODE_OFF,
235
+ 0, errp);
236
if (ret < 0) {
237
goto exit;
238
}
239
} else if (type == VHDX_TYPE_FIXED) {
240
- ret = blk_truncate(blk, data_file_offset + image_size, false,
241
- PREALLOC_MODE_OFF, 0, errp);
242
+ ret = blk_co_truncate(blk, data_file_offset + image_size, false,
243
+ PREALLOC_MODE_OFF, 0, errp);
244
if (ret < 0) {
245
goto exit;
246
}
247
@@ -XXX,XX +XXX,XX @@ static int vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s,
248
s->bat[sinfo.bat_idx] = cpu_to_le64(s->bat[sinfo.bat_idx]);
249
sector_num += s->sectors_per_block;
250
}
251
- ret = blk_pwrite(blk, file_offset, length, s->bat, 0);
252
+ ret = blk_co_pwrite(blk, file_offset, length, s->bat, 0);
253
if (ret < 0) {
254
error_setg_errno(errp, -ret, "Failed to write the BAT");
255
goto exit;
256
@@ -XXX,XX +XXX,XX @@ exit:
257
* to create the BAT itself, we will also cause the BAT to be
258
* created.
259
*/
260
-static int vhdx_create_new_region_table(BlockBackend *blk,
261
- uint64_t image_size,
262
- uint32_t block_size,
263
- uint32_t sector_size,
264
- uint32_t log_size,
265
- bool use_zero_blocks,
266
- VHDXImageType type,
267
- uint64_t *metadata_offset,
268
- Error **errp)
269
+static int coroutine_fn
270
+vhdx_create_new_region_table(BlockBackend *blk, uint64_t image_size,
271
+ uint32_t block_size, uint32_t sector_size,
272
+ uint32_t log_size, bool use_zero_blocks,
273
+ VHDXImageType type, uint64_t *metadata_offset,
274
+ Error **errp)
275
{
276
int ret = 0;
277
uint32_t offset = 0;
278
@@ -XXX,XX +XXX,XX @@ static int vhdx_create_new_region_table(BlockBackend *blk,
279
}
280
281
/* Now write out the region headers to disk */
282
- ret = blk_pwrite(blk, VHDX_REGION_TABLE_OFFSET, VHDX_HEADER_BLOCK_SIZE,
283
- buffer, 0);
284
+ ret = blk_co_pwrite(blk, VHDX_REGION_TABLE_OFFSET, VHDX_HEADER_BLOCK_SIZE,
285
+ buffer, 0);
286
if (ret < 0) {
287
error_setg_errno(errp, -ret, "Failed to write first region table");
288
goto exit;
289
}
290
291
- ret = blk_pwrite(blk, VHDX_REGION_TABLE2_OFFSET, VHDX_HEADER_BLOCK_SIZE,
292
- buffer, 0);
293
+ ret = blk_co_pwrite(blk, VHDX_REGION_TABLE2_OFFSET, VHDX_HEADER_BLOCK_SIZE,
294
+ buffer, 0);
295
if (ret < 0) {
296
error_setg_errno(errp, -ret, "Failed to write second region table");
297
goto exit;
41
--
298
--
42
2.40.1
299
2.41.0
diff view generated by jsdifflib
1
There is a bdrv_co_getlength() now, which should be used in coroutine
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
context.
3
2
4
This requires adding GRAPH_RDLOCK to some functions so that this still
3
Mark functions as coroutine_fn when they are only called by other coroutine_fns
5
compiles with TSA because bdrv_co_getlength() is GRAPH_RDLOCK.
4
and they can suspend. Change calls to co_wrappers to use the non-wrapped
5
functions, which in turn requires adding GRAPH_RDLOCK annotations.
6
6
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
8
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Message-ID: <20230601115145.196465-11-pbonzini@redhat.com>
9
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
10
Message-Id: <20230504115750.54437-2-kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
11
---
13
block/qcow2.h | 4 +++-
12
block/qcow2.h | 33 +++++------
14
block/qcow2-refcount.c | 2 +-
13
block/qcow2-bitmap.c | 26 +++++----
15
block/qcow2.c | 19 +++++++++----------
14
block/qcow2-cluster.c | 12 ++--
16
3 files changed, 13 insertions(+), 12 deletions(-)
15
block/qcow2-refcount.c | 130 +++++++++++++++++++++--------------------
16
block/qcow2.c | 2 +-
17
5 files changed, 105 insertions(+), 98 deletions(-)
17
18
18
diff --git a/block/qcow2.h b/block/qcow2.h
19
diff --git a/block/qcow2.h b/block/qcow2.h
19
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
20
--- a/block/qcow2.h
21
--- a/block/qcow2.h
21
+++ b/block/qcow2.h
22
+++ b/block/qcow2.h
22
@@ -XXX,XX +XXX,XX @@ int qcow2_change_refcount_order(BlockDriverState *bs, int refcount_order,
23
@@ -XXX,XX +XXX,XX @@ int64_t qcow2_refcount_metadata_size(int64_t clusters, size_t cluster_size,
23
void *cb_opaque, Error **errp);
24
24
int coroutine_fn GRAPH_RDLOCK qcow2_shrink_reftable(BlockDriverState *bs);
25
int qcow2_mark_dirty(BlockDriverState *bs);
25
int64_t coroutine_fn qcow2_get_last_cluster(BlockDriverState *bs, int64_t size);
26
int qcow2_mark_corrupt(BlockDriverState *bs);
26
-int coroutine_fn qcow2_detect_metadata_preallocation(BlockDriverState *bs);
27
-int qcow2_mark_consistent(BlockDriverState *bs);
27
+
28
int qcow2_update_header(BlockDriverState *bs);
29
30
void qcow2_signal_corruption(BlockDriverState *bs, bool fatal, int64_t offset,
31
@@ -XXX,XX +XXX,XX @@ int64_t qcow2_refcount_area(BlockDriverState *bs, uint64_t offset,
32
int64_t qcow2_alloc_clusters(BlockDriverState *bs, uint64_t size);
33
int64_t coroutine_fn qcow2_alloc_clusters_at(BlockDriverState *bs, uint64_t offset,
34
int64_t nb_clusters);
35
-int64_t coroutine_fn qcow2_alloc_bytes(BlockDriverState *bs, int size);
36
+int64_t coroutine_fn GRAPH_RDLOCK qcow2_alloc_bytes(BlockDriverState *bs, int size);
37
void qcow2_free_clusters(BlockDriverState *bs,
38
int64_t offset, int64_t size,
39
enum qcow2_discard_type type);
40
@@ -XXX,XX +XXX,XX @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
41
42
int qcow2_flush_caches(BlockDriverState *bs);
43
int qcow2_write_caches(BlockDriverState *bs);
44
-int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
45
- BdrvCheckMode fix);
46
+int coroutine_fn qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
47
+ BdrvCheckMode fix);
48
49
void qcow2_process_discards(BlockDriverState *bs, int ret);
50
51
@@ -XXX,XX +XXX,XX @@ int qcow2_check_metadata_overlap(BlockDriverState *bs, int ign, int64_t offset,
52
int64_t size);
53
int qcow2_pre_write_overlap_check(BlockDriverState *bs, int ign, int64_t offset,
54
int64_t size, bool data_file);
55
-int qcow2_inc_refcounts_imrt(BlockDriverState *bs, BdrvCheckResult *res,
56
- void **refcount_table,
57
- int64_t *refcount_table_size,
58
- int64_t offset, int64_t size);
59
+int coroutine_fn qcow2_inc_refcounts_imrt(BlockDriverState *bs, BdrvCheckResult *res,
60
+ void **refcount_table,
61
+ int64_t *refcount_table_size,
62
+ int64_t offset, int64_t size);
63
64
int qcow2_change_refcount_order(BlockDriverState *bs, int refcount_order,
65
BlockDriverAmendStatusCB *status_cb,
66
@@ -XXX,XX +XXX,XX @@ int qcow2_get_host_offset(BlockDriverState *bs, uint64_t offset,
67
int coroutine_fn qcow2_alloc_host_offset(BlockDriverState *bs, uint64_t offset,
68
unsigned int *bytes,
69
uint64_t *host_offset, QCowL2Meta **m);
70
-int coroutine_fn qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
71
- uint64_t offset,
72
- int compressed_size,
73
- uint64_t *host_offset);
28
+int coroutine_fn GRAPH_RDLOCK
74
+int coroutine_fn GRAPH_RDLOCK
29
+qcow2_detect_metadata_preallocation(BlockDriverState *bs);
75
+qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs, uint64_t offset,
30
76
+ int compressed_size, uint64_t *host_offset);
31
/* qcow2-cluster.c functions */
77
void qcow2_parse_compressed_l2_entry(BlockDriverState *bs, uint64_t l2_entry,
32
int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
78
uint64_t *coffset, int *csize);
79
80
@@ -XXX,XX +XXX,XX @@ void *qcow2_cache_is_table_offset(Qcow2Cache *c, uint64_t offset);
81
void qcow2_cache_discard(Qcow2Cache *c, void *table);
82
83
/* qcow2-bitmap.c functions */
84
-int qcow2_check_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
85
- void **refcount_table,
86
- int64_t *refcount_table_size);
87
-bool coroutine_fn qcow2_load_dirty_bitmaps(BlockDriverState *bs,
88
- bool *header_updated, Error **errp);
89
+int coroutine_fn
90
+qcow2_check_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
91
+ void **refcount_table,
92
+ int64_t *refcount_table_size);
93
+bool coroutine_fn GRAPH_RDLOCK
94
+qcow2_load_dirty_bitmaps(BlockDriverState *bs, bool *header_updated, Error **errp);
95
bool qcow2_get_bitmap_info_list(BlockDriverState *bs,
96
Qcow2BitmapInfoList **info_list, Error **errp);
97
int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp);
98
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/block/qcow2-bitmap.c
101
+++ b/block/qcow2-bitmap.c
102
@@ -XXX,XX +XXX,XX @@ static int free_bitmap_clusters(BlockDriverState *bs, Qcow2BitmapTable *tb)
103
/* load_bitmap_data
104
* @bitmap_table entries must satisfy specification constraints.
105
* @bitmap must be cleared */
106
-static int load_bitmap_data(BlockDriverState *bs,
107
- const uint64_t *bitmap_table,
108
- uint32_t bitmap_table_size,
109
- BdrvDirtyBitmap *bitmap)
110
+static int coroutine_fn GRAPH_RDLOCK
111
+load_bitmap_data(BlockDriverState *bs, const uint64_t *bitmap_table,
112
+ uint32_t bitmap_table_size, BdrvDirtyBitmap *bitmap)
113
{
114
int ret = 0;
115
BDRVQcow2State *s = bs->opaque;
116
@@ -XXX,XX +XXX,XX @@ static int load_bitmap_data(BlockDriverState *bs,
117
* already cleared */
118
}
119
} else {
120
- ret = bdrv_pread(bs->file, data_offset, s->cluster_size, buf, 0);
121
+ ret = bdrv_co_pread(bs->file, data_offset, s->cluster_size, buf, 0);
122
if (ret < 0) {
123
goto finish;
124
}
125
@@ -XXX,XX +XXX,XX @@ finish:
126
return ret;
127
}
128
129
-static BdrvDirtyBitmap *load_bitmap(BlockDriverState *bs,
130
- Qcow2Bitmap *bm, Error **errp)
131
+static coroutine_fn GRAPH_RDLOCK
132
+BdrvDirtyBitmap *load_bitmap(BlockDriverState *bs,
133
+ Qcow2Bitmap *bm, Error **errp)
134
{
135
int ret;
136
uint64_t *bitmap_table = NULL;
137
@@ -XXX,XX +XXX,XX @@ fail:
138
return NULL;
139
}
140
141
-int qcow2_check_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
142
- void **refcount_table,
143
- int64_t *refcount_table_size)
144
+int coroutine_fn
145
+qcow2_check_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
146
+ void **refcount_table,
147
+ int64_t *refcount_table_size)
148
{
149
int ret;
150
BDRVQcow2State *s = bs->opaque;
151
@@ -XXX,XX +XXX,XX @@ static void set_readonly_helper(gpointer bitmap, gpointer value)
152
* If header_updated is not NULL then it is set appropriately regardless of
153
* the return value.
154
*/
155
-bool coroutine_fn qcow2_load_dirty_bitmaps(BlockDriverState *bs,
156
- bool *header_updated, Error **errp)
157
+bool coroutine_fn GRAPH_RDLOCK
158
+qcow2_load_dirty_bitmaps(BlockDriverState *bs,
159
+ bool *header_updated, Error **errp)
160
{
161
BDRVQcow2State *s = bs->opaque;
162
Qcow2BitmapList *bm_list;
163
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
164
index XXXXXXX..XXXXXXX 100644
165
--- a/block/qcow2-cluster.c
166
+++ b/block/qcow2-cluster.c
167
@@ -XXX,XX +XXX,XX @@ static int get_cluster_table(BlockDriverState *bs, uint64_t offset,
168
*
169
* Return 0 on success and -errno in error cases
170
*/
171
-int coroutine_fn qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
172
- uint64_t offset,
173
- int compressed_size,
174
- uint64_t *host_offset)
175
+int coroutine_fn GRAPH_RDLOCK
176
+qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs, uint64_t offset,
177
+ int compressed_size, uint64_t *host_offset)
178
{
179
BDRVQcow2State *s = bs->opaque;
180
int l2_index, ret;
181
@@ -XXX,XX +XXX,XX @@ fail:
182
* all clusters in the same L2 slice) and returns the number of zeroed
183
* clusters.
184
*/
185
-static int zero_in_l2_slice(BlockDriverState *bs, uint64_t offset,
186
- uint64_t nb_clusters, int flags)
187
+static int coroutine_fn
188
+zero_in_l2_slice(BlockDriverState *bs, uint64_t offset,
189
+ uint64_t nb_clusters, int flags)
190
{
191
BDRVQcow2State *s = bs->opaque;
192
uint64_t *l2_slice;
33
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
193
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
34
index XXXXXXX..XXXXXXX 100644
194
index XXXXXXX..XXXXXXX 100644
35
--- a/block/qcow2-refcount.c
195
--- a/block/qcow2-refcount.c
36
+++ b/block/qcow2-refcount.c
196
+++ b/block/qcow2-refcount.c
37
@@ -XXX,XX +XXX,XX @@ int coroutine_fn qcow2_detect_metadata_preallocation(BlockDriverState *bs)
197
@@ -XXX,XX +XXX,XX @@ int64_t coroutine_fn qcow2_alloc_clusters_at(BlockDriverState *bs, uint64_t offs
38
198
39
qemu_co_mutex_assert_locked(&s->lock);
199
/* only used to allocate compressed sectors. We try to allocate
40
200
contiguous sectors. size must be <= cluster_size */
41
- file_length = bdrv_getlength(bs->file->bs);
201
-int64_t coroutine_fn qcow2_alloc_bytes(BlockDriverState *bs, int size)
42
+ file_length = bdrv_co_getlength(bs->file->bs);
202
+int64_t coroutine_fn GRAPH_RDLOCK qcow2_alloc_bytes(BlockDriverState *bs, int size)
43
if (file_length < 0) {
203
{
44
return file_length;
204
BDRVQcow2State *s = bs->opaque;
205
int64_t offset;
206
@@ -XXX,XX +XXX,XX @@ static int realloc_refcount_array(BDRVQcow2State *s, void **array,
207
*
208
* Modifies the number of errors in res.
209
*/
210
-int qcow2_inc_refcounts_imrt(BlockDriverState *bs, BdrvCheckResult *res,
211
- void **refcount_table,
212
- int64_t *refcount_table_size,
213
- int64_t offset, int64_t size)
214
+int coroutine_fn GRAPH_RDLOCK
215
+qcow2_inc_refcounts_imrt(BlockDriverState *bs, BdrvCheckResult *res,
216
+ void **refcount_table,
217
+ int64_t *refcount_table_size,
218
+ int64_t offset, int64_t size)
219
{
220
BDRVQcow2State *s = bs->opaque;
221
uint64_t start, last, cluster_offset, k, refcount;
222
@@ -XXX,XX +XXX,XX @@ int qcow2_inc_refcounts_imrt(BlockDriverState *bs, BdrvCheckResult *res,
223
return 0;
45
}
224
}
225
226
- file_len = bdrv_getlength(bs->file->bs);
227
+ file_len = bdrv_co_getlength(bs->file->bs);
228
if (file_len < 0) {
229
return file_len;
230
}
231
@@ -XXX,XX +XXX,XX @@ enum {
232
*
233
* On failure in-memory @l2_table may be modified.
234
*/
235
-static int fix_l2_entry_by_zero(BlockDriverState *bs, BdrvCheckResult *res,
236
- uint64_t l2_offset,
237
- uint64_t *l2_table, int l2_index, bool active,
238
- bool *metadata_overlap)
239
+static int coroutine_fn GRAPH_RDLOCK
240
+fix_l2_entry_by_zero(BlockDriverState *bs, BdrvCheckResult *res,
241
+ uint64_t l2_offset, uint64_t *l2_table,
242
+ int l2_index, bool active,
243
+ bool *metadata_overlap)
244
{
245
BDRVQcow2State *s = bs->opaque;
246
int ret;
247
@@ -XXX,XX +XXX,XX @@ static int fix_l2_entry_by_zero(BlockDriverState *bs, BdrvCheckResult *res,
248
goto fail;
249
}
250
251
- ret = bdrv_pwrite_sync(bs->file, l2e_offset, l2_entry_size(s),
252
- &l2_table[idx], 0);
253
+ ret = bdrv_co_pwrite_sync(bs->file, l2e_offset, l2_entry_size(s),
254
+ &l2_table[idx], 0);
255
if (ret < 0) {
256
fprintf(stderr, "ERROR: Failed to overwrite L2 "
257
"table entry: %s\n", strerror(-ret));
258
@@ -XXX,XX +XXX,XX @@ fail:
259
* Returns the number of errors found by the checks or -errno if an internal
260
* error occurred.
261
*/
262
-static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
263
- void **refcount_table,
264
- int64_t *refcount_table_size, int64_t l2_offset,
265
- int flags, BdrvCheckMode fix, bool active)
266
+static int coroutine_fn GRAPH_RDLOCK
267
+check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
268
+ void **refcount_table,
269
+ int64_t *refcount_table_size, int64_t l2_offset,
270
+ int flags, BdrvCheckMode fix, bool active)
271
{
272
BDRVQcow2State *s = bs->opaque;
273
uint64_t l2_entry, l2_bitmap;
274
@@ -XXX,XX +XXX,XX @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
275
bool metadata_overlap;
276
277
/* Read L2 table from disk */
278
- ret = bdrv_pread(bs->file, l2_offset, l2_size_bytes, l2_table, 0);
279
+ ret = bdrv_co_pread(bs->file, l2_offset, l2_size_bytes, l2_table, 0);
280
if (ret < 0) {
281
fprintf(stderr, "ERROR: I/O error in check_refcounts_l2\n");
282
res->check_errors++;
283
@@ -XXX,XX +XXX,XX @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
284
* Returns the number of errors found by the checks or -errno if an internal
285
* error occurred.
286
*/
287
-static int check_refcounts_l1(BlockDriverState *bs,
288
- BdrvCheckResult *res,
289
- void **refcount_table,
290
- int64_t *refcount_table_size,
291
- int64_t l1_table_offset, int l1_size,
292
- int flags, BdrvCheckMode fix, bool active)
293
+static int coroutine_fn GRAPH_RDLOCK
294
+check_refcounts_l1(BlockDriverState *bs, BdrvCheckResult *res,
295
+ void **refcount_table, int64_t *refcount_table_size,
296
+ int64_t l1_table_offset, int l1_size,
297
+ int flags, BdrvCheckMode fix, bool active)
298
{
299
BDRVQcow2State *s = bs->opaque;
300
size_t l1_size_bytes = l1_size * L1E_SIZE;
301
@@ -XXX,XX +XXX,XX @@ static int check_refcounts_l1(BlockDriverState *bs,
302
}
303
304
/* Read L1 table entries from disk */
305
- ret = bdrv_pread(bs->file, l1_table_offset, l1_size_bytes, l1_table, 0);
306
+ ret = bdrv_co_pread(bs->file, l1_table_offset, l1_size_bytes, l1_table, 0);
307
if (ret < 0) {
308
fprintf(stderr, "ERROR: I/O error in check_refcounts_l1\n");
309
res->check_errors++;
310
@@ -XXX,XX +XXX,XX @@ static int check_refcounts_l1(BlockDriverState *bs,
311
* have been already detected and sufficiently signaled by the calling function
312
* (qcow2_check_refcounts) by the time this function is called).
313
*/
314
-static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
315
- BdrvCheckMode fix)
316
+static int coroutine_fn GRAPH_RDLOCK
317
+check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix)
318
{
319
BDRVQcow2State *s = bs->opaque;
320
uint64_t *l2_table = qemu_blockalign(bs, s->cluster_size);
321
@@ -XXX,XX +XXX,XX @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
322
}
323
}
324
325
- ret = bdrv_pread(bs->file, l2_offset, s->l2_size * l2_entry_size(s),
326
- l2_table, 0);
327
+ ret = bdrv_co_pread(bs->file, l2_offset, s->l2_size * l2_entry_size(s),
328
+ l2_table, 0);
329
if (ret < 0) {
330
fprintf(stderr, "ERROR: Could not read L2 table: %s\n",
331
strerror(-ret));
332
@@ -XXX,XX +XXX,XX @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
333
goto fail;
334
}
335
336
- ret = bdrv_pwrite(bs->file, l2_offset, s->cluster_size, l2_table,
337
- 0);
338
+ ret = bdrv_co_pwrite(bs->file, l2_offset, s->cluster_size, l2_table, 0);
339
if (ret < 0) {
340
fprintf(stderr, "ERROR: Could not write L2 table: %s\n",
341
strerror(-ret));
342
@@ -XXX,XX +XXX,XX @@ fail:
343
* Checks consistency of refblocks and accounts for each refblock in
344
* *refcount_table.
345
*/
346
-static int check_refblocks(BlockDriverState *bs, BdrvCheckResult *res,
347
- BdrvCheckMode fix, bool *rebuild,
348
- void **refcount_table, int64_t *nb_clusters)
349
+static int coroutine_fn GRAPH_RDLOCK
350
+check_refblocks(BlockDriverState *bs, BdrvCheckResult *res,
351
+ BdrvCheckMode fix, bool *rebuild,
352
+ void **refcount_table, int64_t *nb_clusters)
353
{
354
BDRVQcow2State *s = bs->opaque;
355
int64_t i, size;
356
@@ -XXX,XX +XXX,XX @@ static int check_refblocks(BlockDriverState *bs, BdrvCheckResult *res,
357
goto resize_fail;
358
}
359
360
- ret = bdrv_truncate(bs->file, offset + s->cluster_size, false,
361
- PREALLOC_MODE_OFF, 0, &local_err);
362
+ ret = bdrv_co_truncate(bs->file, offset + s->cluster_size, false,
363
+ PREALLOC_MODE_OFF, 0, &local_err);
364
if (ret < 0) {
365
error_report_err(local_err);
366
goto resize_fail;
367
}
368
- size = bdrv_getlength(bs->file->bs);
369
+ size = bdrv_co_getlength(bs->file->bs);
370
if (size < 0) {
371
ret = size;
372
goto resize_fail;
373
@@ -XXX,XX +XXX,XX @@ resize_fail:
374
/*
375
* Calculates an in-memory refcount table.
376
*/
377
-static int calculate_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
378
- BdrvCheckMode fix, bool *rebuild,
379
- void **refcount_table, int64_t *nb_clusters)
380
+static int coroutine_fn GRAPH_RDLOCK
381
+calculate_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
382
+ BdrvCheckMode fix, bool *rebuild,
383
+ void **refcount_table, int64_t *nb_clusters)
384
{
385
BDRVQcow2State *s = bs->opaque;
386
int64_t i;
387
@@ -XXX,XX +XXX,XX @@ static int calculate_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
388
* Compares the actual reference count for each cluster in the image against the
389
* refcount as reported by the refcount structures on-disk.
390
*/
391
-static void compare_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
392
- BdrvCheckMode fix, bool *rebuild,
393
- int64_t *highest_cluster,
394
- void *refcount_table, int64_t nb_clusters)
395
+static void coroutine_fn
396
+compare_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
397
+ BdrvCheckMode fix, bool *rebuild,
398
+ int64_t *highest_cluster,
399
+ void *refcount_table, int64_t nb_clusters)
400
{
401
BDRVQcow2State *s = bs->opaque;
402
int64_t i;
403
@@ -XXX,XX +XXX,XX @@ static int64_t alloc_clusters_imrt(BlockDriverState *bs,
404
* Return whether the on-disk reftable array was resized (true/false),
405
* or -errno on error.
406
*/
407
-static int rebuild_refcounts_write_refblocks(
408
+static int coroutine_fn GRAPH_RDLOCK
409
+rebuild_refcounts_write_refblocks(
410
BlockDriverState *bs, void **refcount_table, int64_t *nb_clusters,
411
int64_t first_cluster, int64_t end_cluster,
412
uint64_t **on_disk_reftable_ptr, uint32_t *on_disk_reftable_entries_ptr,
413
@@ -XXX,XX +XXX,XX @@ static int rebuild_refcounts_write_refblocks(
414
on_disk_refblock = (void *)((char *) *refcount_table +
415
refblock_index * s->cluster_size);
416
417
- ret = bdrv_pwrite(bs->file, refblock_offset, s->cluster_size,
418
- on_disk_refblock, 0);
419
+ ret = bdrv_co_pwrite(bs->file, refblock_offset, s->cluster_size,
420
+ on_disk_refblock, 0);
421
if (ret < 0) {
422
error_setg_errno(errp, -ret, "ERROR writing refblock");
423
return ret;
424
@@ -XXX,XX +XXX,XX @@ static int rebuild_refcounts_write_refblocks(
425
* On success, the old refcount structure is leaked (it will be covered by the
426
* new refcount structure).
427
*/
428
-static int rebuild_refcount_structure(BlockDriverState *bs,
429
- BdrvCheckResult *res,
430
- void **refcount_table,
431
- int64_t *nb_clusters,
432
- Error **errp)
433
+static int coroutine_fn GRAPH_RDLOCK
434
+rebuild_refcount_structure(BlockDriverState *bs, BdrvCheckResult *res,
435
+ void **refcount_table, int64_t *nb_clusters,
436
+ Error **errp)
437
{
438
BDRVQcow2State *s = bs->opaque;
439
int64_t reftable_offset = -1;
440
@@ -XXX,XX +XXX,XX @@ static int rebuild_refcount_structure(BlockDriverState *bs,
441
}
442
443
assert(reftable_length < INT_MAX);
444
- ret = bdrv_pwrite(bs->file, reftable_offset, reftable_length,
445
- on_disk_reftable, 0);
446
+ ret = bdrv_co_pwrite(bs->file, reftable_offset, reftable_length,
447
+ on_disk_reftable, 0);
448
if (ret < 0) {
449
error_setg_errno(errp, -ret, "ERROR writing reftable");
450
goto fail;
451
@@ -XXX,XX +XXX,XX @@ static int rebuild_refcount_structure(BlockDriverState *bs,
452
reftable_offset_and_clusters.reftable_offset = cpu_to_be64(reftable_offset);
453
reftable_offset_and_clusters.reftable_clusters =
454
cpu_to_be32(reftable_clusters);
455
- ret = bdrv_pwrite_sync(bs->file,
456
- offsetof(QCowHeader, refcount_table_offset),
457
- sizeof(reftable_offset_and_clusters),
458
- &reftable_offset_and_clusters, 0);
459
+ ret = bdrv_co_pwrite_sync(bs->file,
460
+ offsetof(QCowHeader, refcount_table_offset),
461
+ sizeof(reftable_offset_and_clusters),
462
+ &reftable_offset_and_clusters, 0);
463
if (ret < 0) {
464
error_setg_errno(errp, -ret, "ERROR setting reftable");
465
goto fail;
466
@@ -XXX,XX +XXX,XX @@ fail:
467
* Returns 0 if no errors are found, the number of errors in case the image is
468
* detected as corrupted, and -errno when an internal error occurred.
469
*/
470
-int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
471
- BdrvCheckMode fix)
472
+int coroutine_fn GRAPH_RDLOCK
473
+qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix)
474
{
475
BDRVQcow2State *s = bs->opaque;
476
BdrvCheckResult pre_compare_res;
477
@@ -XXX,XX +XXX,XX @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
478
bool rebuild = false;
479
int ret;
480
481
- size = bdrv_getlength(bs->file->bs);
482
+ size = bdrv_co_getlength(bs->file->bs);
483
if (size < 0) {
484
res->check_errors++;
485
return size;
486
@@ -XXX,XX +XXX,XX @@ done:
487
return ret;
488
}
489
490
-static int64_t get_refblock_offset(BlockDriverState *bs, uint64_t offset)
491
+static int64_t coroutine_fn get_refblock_offset(BlockDriverState *bs,
492
+ uint64_t offset)
493
{
494
BDRVQcow2State *s = bs->opaque;
495
uint32_t index = offset_to_reftable_index(s, offset);
496
@@ -XXX,XX +XXX,XX @@ int64_t coroutine_fn qcow2_get_last_cluster(BlockDriverState *bs, int64_t size)
497
return -EIO;
498
}
499
500
-int coroutine_fn qcow2_detect_metadata_preallocation(BlockDriverState *bs)
501
+int coroutine_fn GRAPH_RDLOCK
502
+qcow2_detect_metadata_preallocation(BlockDriverState *bs)
503
{
504
BDRVQcow2State *s = bs->opaque;
505
int64_t i, end_cluster, cluster_count = 0, threshold;
46
diff --git a/block/qcow2.c b/block/qcow2.c
506
diff --git a/block/qcow2.c b/block/qcow2.c
47
index XXXXXXX..XXXXXXX 100644
507
index XXXXXXX..XXXXXXX 100644
48
--- a/block/qcow2.c
508
--- a/block/qcow2.c
49
+++ b/block/qcow2.c
509
+++ b/block/qcow2.c
50
@@ -XXX,XX +XXX,XX @@ static void qcow2_join_options(QDict *options, QDict *old_options)
510
@@ -XXX,XX +XXX,XX @@ int qcow2_mark_corrupt(BlockDriverState *bs)
51
}
511
* Marks the image as consistent, i.e., unsets the corrupt bit, and flushes
52
}
512
* before if necessary.
53
513
*/
54
-static int coroutine_fn qcow2_co_block_status(BlockDriverState *bs,
514
-int qcow2_mark_consistent(BlockDriverState *bs)
55
- bool want_zero,
515
+static int coroutine_fn qcow2_mark_consistent(BlockDriverState *bs)
56
- int64_t offset, int64_t count,
516
{
57
- int64_t *pnum, int64_t *map,
517
BDRVQcow2State *s = bs->opaque;
58
- BlockDriverState **file)
518
59
+static int coroutine_fn GRAPH_RDLOCK
60
+qcow2_co_block_status(BlockDriverState *bs, bool want_zero, int64_t offset,
61
+ int64_t count, int64_t *pnum, int64_t *map,
62
+ BlockDriverState **file)
63
{
64
BDRVQcow2State *s = bs->opaque;
65
uint64_t host_offset;
66
@@ -XXX,XX +XXX,XX @@ preallocate_co(BlockDriverState *bs, uint64_t offset, uint64_t new_length,
67
* all of the allocated clusters (otherwise we get failing reads after
68
* EOF). Extend the image to the last allocated sector.
69
*/
70
- file_length = bdrv_getlength(s->data_file->bs);
71
+ file_length = bdrv_co_getlength(s->data_file->bs);
72
if (file_length < 0) {
73
error_setg_errno(errp, -file_length, "Could not get file size");
74
ret = file_length;
75
@@ -XXX,XX +XXX,XX @@ qcow2_co_copy_range_from(BlockDriverState *bs,
76
case QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN:
77
case QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC:
78
if (bs->backing && bs->backing->bs) {
79
- int64_t backing_length = bdrv_getlength(bs->backing->bs);
80
+ int64_t backing_length = bdrv_co_getlength(bs->backing->bs);
81
if (src_offset >= backing_length) {
82
cur_write_flags |= BDRV_REQ_ZERO_WRITE;
83
} else {
84
@@ -XXX,XX +XXX,XX @@ qcow2_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
85
goto fail;
86
}
87
88
- old_file_size = bdrv_getlength(bs->file->bs);
89
+ old_file_size = bdrv_co_getlength(bs->file->bs);
90
if (old_file_size < 0) {
91
error_setg_errno(errp, -old_file_size,
92
"Failed to inquire current file length");
93
@@ -XXX,XX +XXX,XX @@ qcow2_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
94
break;
95
}
96
97
- old_file_size = bdrv_getlength(bs->file->bs);
98
+ old_file_size = bdrv_co_getlength(bs->file->bs);
99
if (old_file_size < 0) {
100
error_setg_errno(errp, -old_file_size,
101
"Failed to inquire current file length");
102
@@ -XXX,XX +XXX,XX @@ qcow2_co_pwritev_compressed_part(BlockDriverState *bs,
103
* align end of file to a sector boundary to ease reading with
104
* sector based I/Os
105
*/
106
- int64_t len = bdrv_getlength(bs->file->bs);
107
+ int64_t len = bdrv_co_getlength(bs->file->bs);
108
if (len < 0) {
109
return len;
110
}
111
--
519
--
112
2.40.1
520
2.41.0
diff view generated by jsdifflib
Deleted patch
1
Migration code can call bdrv_activate() in coroutine context, whereas
2
other callers call it outside of coroutines. As it calls other code that
3
is not supposed to run in coroutines, standardise on running outside of
4
coroutines.
5
1
6
This adds a no_co_wrapper to switch to the main loop before calling
7
bdrv_activate().
8
9
Cc: qemu-stable@nongnu.org
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Reviewed-by: Eric Blake <eblake@redhat.com>
12
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
13
Message-Id: <20230504115750.54437-3-kwolf@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
---
16
include/block/block-global-state.h | 6 +++++-
17
block/block-backend.c | 10 +++++++++-
18
2 files changed, 14 insertions(+), 2 deletions(-)
19
20
diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/include/block/block-global-state.h
23
+++ b/include/block/block-global-state.h
24
@@ -XXX,XX +XXX,XX @@ int bdrv_amend_options(BlockDriverState *bs_new, QemuOpts *opts,
25
BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs,
26
const char *node_name, Error **errp);
27
28
-int bdrv_activate(BlockDriverState *bs, Error **errp);
29
+int no_coroutine_fn bdrv_activate(BlockDriverState *bs, Error **errp);
30
+
31
+int coroutine_fn no_co_wrapper
32
+bdrv_co_activate(BlockDriverState *bs, Error **errp);
33
+
34
void bdrv_activate_all(Error **errp);
35
int bdrv_inactivate_all(void);
36
37
diff --git a/block/block-backend.c b/block/block-backend.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/block/block-backend.c
40
+++ b/block/block-backend.c
41
@@ -XXX,XX +XXX,XX @@ void blk_activate(BlockBackend *blk, Error **errp)
42
return;
43
}
44
45
- bdrv_activate(bs, errp);
46
+ /*
47
+ * Migration code can call this function in coroutine context, so leave
48
+ * coroutine context if necessary.
49
+ */
50
+ if (qemu_in_coroutine()) {
51
+ bdrv_co_activate(bs, errp);
52
+ } else {
53
+ bdrv_activate(bs, errp);
54
+ }
55
}
56
57
bool coroutine_fn blk_co_is_inserted(BlockBackend *blk)
58
--
59
2.40.1
diff view generated by jsdifflib
1
These functions must not be called in coroutine context, because they
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
need write access to the graph.
3
2
4
Cc: qemu-stable@nongnu.org
3
bdrv_co_getlength was recently introduced, with bdrv_getlength becoming
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
a wrapper for use in unknown context. Switch to bdrv_co_getlength when
6
Reviewed-by: Eric Blake <eblake@redhat.com>
5
possible.
7
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
6
8
Message-Id: <20230504115750.54437-4-kwolf@redhat.com>
7
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
8
Message-ID: <20230601115145.196465-12-pbonzini@redhat.com>
9
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
---
11
include/block/block-global-state.h | 3 ++-
12
block/io.c | 10 +++++-----
12
include/sysemu/block-backend-global-state.h | 5 ++++-
13
block/parallels.c | 4 ++--
13
block.c | 2 +-
14
block/qcow.c | 6 +++---
14
block/crypto.c | 6 +++---
15
block/vmdk.c | 4 ++--
15
block/parallels.c | 6 +++---
16
4 files changed, 12 insertions(+), 12 deletions(-)
16
block/qcow.c | 6 +++---
17
block/qcow2.c | 14 +++++++-------
18
block/qed.c | 6 +++---
19
block/vdi.c | 6 +++---
20
block/vhdx.c | 6 +++---
21
block/vmdk.c | 18 +++++++++---------
22
block/vpc.c | 6 +++---
23
12 files changed, 44 insertions(+), 40 deletions(-)
24
17
25
diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h
18
diff --git a/block/io.c b/block/io.c
26
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
27
--- a/include/block/block-global-state.h
20
--- a/block/io.c
28
+++ b/include/block/block-global-state.h
21
+++ b/block/io.c
29
@@ -XXX,XX +XXX,XX @@ void bdrv_img_create(const char *filename, const char *fmt,
22
@@ -XXX,XX +XXX,XX @@ bdrv_aligned_preadv(BdrvChild *child, BdrvTrackedRequest *req,
30
bool quiet, Error **errp);
31
32
void bdrv_ref(BlockDriverState *bs);
33
-void bdrv_unref(BlockDriverState *bs);
34
+void no_coroutine_fn bdrv_unref(BlockDriverState *bs);
35
+void coroutine_fn no_co_wrapper bdrv_co_unref(BlockDriverState *bs);
36
void bdrv_unref_child(BlockDriverState *parent, BdrvChild *child);
37
BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
38
BlockDriverState *child_bs,
39
diff --git a/include/sysemu/block-backend-global-state.h b/include/sysemu/block-backend-global-state.h
40
index XXXXXXX..XXXXXXX 100644
41
--- a/include/sysemu/block-backend-global-state.h
42
+++ b/include/sysemu/block-backend-global-state.h
43
@@ -XXX,XX +XXX,XX @@ blk_co_new_open(const char *filename, const char *reference, QDict *options,
44
45
int blk_get_refcnt(BlockBackend *blk);
46
void blk_ref(BlockBackend *blk);
47
-void blk_unref(BlockBackend *blk);
48
+
49
+void no_coroutine_fn blk_unref(BlockBackend *blk);
50
+void coroutine_fn no_co_wrapper blk_co_unref(BlockBackend *blk);
51
+
52
void blk_remove_all_bs(void);
53
BlockBackend *blk_by_name(const char *name);
54
BlockBackend *blk_next(BlockBackend *blk);
55
diff --git a/block.c b/block.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/block.c
58
+++ b/block.c
59
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_create_opts_simple(BlockDriver *drv,
60
61
ret = 0;
62
out:
63
- blk_unref(blk);
64
+ blk_co_unref(blk);
65
return ret;
66
}
67
68
diff --git a/block/crypto.c b/block/crypto.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/block/crypto.c
71
+++ b/block/crypto.c
72
@@ -XXX,XX +XXX,XX @@ block_crypto_co_create_generic(BlockDriverState *bs, int64_t size,
73
ret = 0;
74
cleanup:
75
qcrypto_block_free(crypto);
76
- blk_unref(blk);
77
+ blk_co_unref(blk);
78
return ret;
79
}
80
81
@@ -XXX,XX +XXX,XX @@ block_crypto_co_create_luks(BlockdevCreateOptions *create_options, Error **errp)
82
83
ret = 0;
84
fail:
85
- bdrv_unref(bs);
86
+ bdrv_co_unref(bs);
87
return ret;
88
}
89
90
@@ -XXX,XX +XXX,XX @@ fail:
91
bdrv_co_delete_file_noerr(bs);
92
}
23
}
93
24
94
- bdrv_unref(bs);
25
/* Forward the request to the BlockDriver, possibly fragmenting it */
95
+ bdrv_co_unref(bs);
26
- total_bytes = bdrv_getlength(bs);
96
qapi_free_QCryptoBlockCreateOptions(create_opts);
27
+ total_bytes = bdrv_co_getlength(bs);
97
qobject_unref(cryptoopts);
28
if (total_bytes < 0) {
98
return ret;
29
ret = total_bytes;
30
goto out;
31
@@ -XXX,XX +XXX,XX @@ bdrv_co_block_status(BlockDriverState *bs, bool want_zero,
32
assert(pnum);
33
assert_bdrv_graph_readable();
34
*pnum = 0;
35
- total_size = bdrv_getlength(bs);
36
+ total_size = bdrv_co_getlength(bs);
37
if (total_size < 0) {
38
ret = total_size;
39
goto early_out;
40
@@ -XXX,XX +XXX,XX @@ bdrv_co_block_status(BlockDriverState *bs, bool want_zero,
41
bytes = n;
42
}
43
44
- /* Must be non-NULL or bdrv_getlength() would have failed */
45
+ /* Must be non-NULL or bdrv_co_getlength() would have failed */
46
assert(bs->drv);
47
has_filtered_child = bdrv_filter_child(bs);
48
if (!bs->drv->bdrv_co_block_status && !has_filtered_child) {
49
@@ -XXX,XX +XXX,XX @@ bdrv_co_block_status(BlockDriverState *bs, bool want_zero,
50
if (!cow_bs) {
51
ret |= BDRV_BLOCK_ZERO;
52
} else if (want_zero) {
53
- int64_t size2 = bdrv_getlength(cow_bs);
54
+ int64_t size2 = bdrv_co_getlength(cow_bs);
55
56
if (size2 >= 0 && offset >= size2) {
57
ret |= BDRV_BLOCK_ZERO;
58
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
59
return ret;
60
}
61
62
- old_size = bdrv_getlength(bs);
63
+ old_size = bdrv_co_getlength(bs);
64
if (old_size < 0) {
65
error_setg_errno(errp, -old_size, "Failed to get old image size");
66
return old_size;
99
diff --git a/block/parallels.c b/block/parallels.c
67
diff --git a/block/parallels.c b/block/parallels.c
100
index XXXXXXX..XXXXXXX 100644
68
index XXXXXXX..XXXXXXX 100644
101
--- a/block/parallels.c
69
--- a/block/parallels.c
102
+++ b/block/parallels.c
70
+++ b/block/parallels.c
103
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn parallels_co_create(BlockdevCreateOptions* opts,
71
@@ -XXX,XX +XXX,XX @@ allocate_clusters(BlockDriverState *bs, int64_t sector_num,
104
72
assert(idx < s->bat_size && idx + to_allocate <= s->bat_size);
105
ret = 0;
73
106
out:
74
space = to_allocate * s->tracks;
107
- blk_unref(blk);
75
- len = bdrv_getlength(bs->file->bs);
108
- bdrv_unref(bs);
76
+ len = bdrv_co_getlength(bs->file->bs);
109
+ blk_co_unref(blk);
77
if (len < 0) {
110
+ bdrv_co_unref(bs);
78
return len;
111
return ret;
79
}
112
80
@@ -XXX,XX +XXX,XX @@ parallels_check_outside_image(BlockDriverState *bs, BdrvCheckResult *res,
113
exit:
81
uint32_t i;
114
@@ -XXX,XX +XXX,XX @@ parallels_co_create_opts(BlockDriver *drv, const char *filename,
82
int64_t off, high_off, size;
115
83
116
done:
84
- size = bdrv_getlength(bs->file->bs);
117
qobject_unref(qdict);
85
+ size = bdrv_co_getlength(bs->file->bs);
118
- bdrv_unref(bs);
86
if (size < 0) {
119
+ bdrv_co_unref(bs);
87
res->check_errors++;
120
qapi_free_BlockdevCreateOptions(create_options);
88
return size;
121
return ret;
122
}
123
diff --git a/block/qcow.c b/block/qcow.c
89
diff --git a/block/qcow.c b/block/qcow.c
124
index XXXXXXX..XXXXXXX 100644
90
index XXXXXXX..XXXXXXX 100644
125
--- a/block/qcow.c
91
--- a/block/qcow.c
126
+++ b/block/qcow.c
92
+++ b/block/qcow.c
127
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow_co_create(BlockdevCreateOptions *opts,
93
@@ -XXX,XX +XXX,XX @@ get_cluster_offset(BlockDriverState *bs, uint64_t offset, int allocate,
128
g_free(tmp);
94
if (!allocate)
129
ret = 0;
95
return 0;
130
exit:
96
/* allocate a new l2 entry */
131
- blk_unref(qcow_blk);
97
- l2_offset = bdrv_getlength(bs->file->bs);
132
- bdrv_unref(bs);
98
+ l2_offset = bdrv_co_getlength(bs->file->bs);
133
+ blk_co_unref(qcow_blk);
99
if (l2_offset < 0) {
134
+ bdrv_co_unref(bs);
100
return l2_offset;
135
qcrypto_block_free(crypto);
136
return ret;
137
}
138
@@ -XXX,XX +XXX,XX @@ qcow_co_create_opts(BlockDriver *drv, const char *filename,
139
fail:
140
g_free(backing_fmt);
141
qobject_unref(qdict);
142
- bdrv_unref(bs);
143
+ bdrv_co_unref(bs);
144
qapi_free_BlockdevCreateOptions(create_options);
145
return ret;
146
}
147
diff --git a/block/qcow2.c b/block/qcow2.c
148
index XXXXXXX..XXXXXXX 100644
149
--- a/block/qcow2.c
150
+++ b/block/qcow2.c
151
@@ -XXX,XX +XXX,XX @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
152
goto out;
153
}
154
155
- blk_unref(blk);
156
+ blk_co_unref(blk);
157
blk = NULL;
158
159
/*
160
@@ -XXX,XX +XXX,XX @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
161
}
101
}
162
}
102
@@ -XXX,XX +XXX,XX @@ get_cluster_offset(BlockDriverState *bs, uint64_t offset, int allocate,
163
103
if (decompress_cluster(bs, cluster_offset) < 0) {
164
- blk_unref(blk);
104
return -EIO;
165
+ blk_co_unref(blk);
105
}
166
blk = NULL;
106
- cluster_offset = bdrv_getlength(bs->file->bs);
167
107
+ cluster_offset = bdrv_co_getlength(bs->file->bs);
168
/* Reopen the image without BDRV_O_NO_FLUSH to flush it before returning.
108
if ((int64_t) cluster_offset < 0) {
169
@@ -XXX,XX +XXX,XX @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
109
return cluster_offset;
170
110
}
171
ret = 0;
111
@@ -XXX,XX +XXX,XX @@ get_cluster_offset(BlockDriverState *bs, uint64_t offset, int allocate,
172
out:
112
return ret;
173
- blk_unref(blk);
113
}
174
- bdrv_unref(bs);
114
} else {
175
- bdrv_unref(data_bs);
115
- cluster_offset = bdrv_getlength(bs->file->bs);
176
+ blk_co_unref(blk);
116
+ cluster_offset = bdrv_co_getlength(bs->file->bs);
177
+ bdrv_co_unref(bs);
117
if ((int64_t) cluster_offset < 0) {
178
+ bdrv_co_unref(data_bs);
118
return cluster_offset;
179
return ret;
119
}
180
}
181
182
@@ -XXX,XX +XXX,XX @@ finish:
183
}
184
185
qobject_unref(qdict);
186
- bdrv_unref(bs);
187
- bdrv_unref(data_bs);
188
+ bdrv_co_unref(bs);
189
+ bdrv_co_unref(data_bs);
190
qapi_free_BlockdevCreateOptions(create_options);
191
return ret;
192
}
193
diff --git a/block/qed.c b/block/qed.c
194
index XXXXXXX..XXXXXXX 100644
195
--- a/block/qed.c
196
+++ b/block/qed.c
197
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_co_create(BlockdevCreateOptions *opts,
198
ret = 0; /* success */
199
out:
200
g_free(l1_table);
201
- blk_unref(blk);
202
- bdrv_unref(bs);
203
+ blk_co_unref(blk);
204
+ bdrv_co_unref(bs);
205
return ret;
206
}
207
208
@@ -XXX,XX +XXX,XX @@ bdrv_qed_co_create_opts(BlockDriver *drv, const char *filename,
209
210
fail:
211
qobject_unref(qdict);
212
- bdrv_unref(bs);
213
+ bdrv_co_unref(bs);
214
qapi_free_BlockdevCreateOptions(create_options);
215
return ret;
216
}
217
diff --git a/block/vdi.c b/block/vdi.c
218
index XXXXXXX..XXXXXXX 100644
219
--- a/block/vdi.c
220
+++ b/block/vdi.c
221
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options,
222
223
ret = 0;
224
exit:
225
- blk_unref(blk);
226
- bdrv_unref(bs_file);
227
+ blk_co_unref(blk);
228
+ bdrv_co_unref(bs_file);
229
g_free(bmap);
230
return ret;
231
}
232
@@ -XXX,XX +XXX,XX @@ vdi_co_create_opts(BlockDriver *drv, const char *filename,
233
done:
234
qobject_unref(qdict);
235
qapi_free_BlockdevCreateOptions(create_options);
236
- bdrv_unref(bs_file);
237
+ bdrv_co_unref(bs_file);
238
return ret;
239
}
240
241
diff --git a/block/vhdx.c b/block/vhdx.c
242
index XXXXXXX..XXXXXXX 100644
243
--- a/block/vhdx.c
244
+++ b/block/vhdx.c
245
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vhdx_co_create(BlockdevCreateOptions *opts,
246
247
ret = 0;
248
delete_and_exit:
249
- blk_unref(blk);
250
- bdrv_unref(bs);
251
+ blk_co_unref(blk);
252
+ bdrv_co_unref(bs);
253
g_free(creator);
254
return ret;
255
}
256
@@ -XXX,XX +XXX,XX @@ vhdx_co_create_opts(BlockDriver *drv, const char *filename,
257
258
fail:
259
qobject_unref(qdict);
260
- bdrv_unref(bs);
261
+ bdrv_co_unref(bs);
262
qapi_free_BlockdevCreateOptions(create_options);
263
return ret;
264
}
265
diff --git a/block/vmdk.c b/block/vmdk.c
120
diff --git a/block/vmdk.c b/block/vmdk.c
266
index XXXXXXX..XXXXXXX 100644
121
index XXXXXXX..XXXXXXX 100644
267
--- a/block/vmdk.c
122
--- a/block/vmdk.c
268
+++ b/block/vmdk.c
123
+++ b/block/vmdk.c
269
@@ -XXX,XX +XXX,XX @@ exit:
124
@@ -XXX,XX +XXX,XX @@ vmdk_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes,
270
if (pbb) {
125
int64_t length;
271
*pbb = blk;
126
272
} else {
127
for (i = 0; i < s->num_extents; i++) {
273
- blk_unref(blk);
128
- length = bdrv_getlength(s->extents[i].file->bs);
274
+ blk_co_unref(blk);
129
+ length = bdrv_co_getlength(s->extents[i].file->bs);
275
blk = NULL;
130
if (length < 0) {
131
return length;
132
}
133
@@ -XXX,XX +XXX,XX @@ vmdk_co_check(BlockDriverState *bs, BdrvCheckResult *result, BdrvCheckMode fix)
134
break;
276
}
135
}
277
}
136
if (ret == VMDK_OK) {
278
@@ -XXX,XX +XXX,XX @@ vmdk_co_do_create(int64_t size,
137
- int64_t extent_len = bdrv_getlength(extent->file->bs);
279
if (strcmp(blk_bs(backing)->drv->format_name, "vmdk")) {
138
+ int64_t extent_len = bdrv_co_getlength(extent->file->bs);
280
error_setg(errp, "Invalid backing file format: %s. Must be vmdk",
139
if (extent_len < 0) {
281
blk_bs(backing)->drv->format_name);
140
fprintf(stderr,
282
- blk_unref(backing);
141
"ERROR: could not get extent file length for sector %"
283
+ blk_co_unref(backing);
284
ret = -EINVAL;
285
goto exit;
286
}
287
ret = vmdk_read_cid(blk_bs(backing), 0, &parent_cid);
288
- blk_unref(backing);
289
+ blk_co_unref(backing);
290
if (ret) {
291
error_setg(errp, "Failed to read parent CID");
292
goto exit;
293
@@ -XXX,XX +XXX,XX @@ vmdk_co_do_create(int64_t size,
294
blk_bs(extent_blk)->filename);
295
created_size += cur_size;
296
extent_idx++;
297
- blk_unref(extent_blk);
298
+ blk_co_unref(extent_blk);
299
}
300
301
/* Check whether we got excess extents */
302
extent_blk = extent_fn(-1, extent_idx, flat, split, compress, zeroed_grain,
303
opaque, NULL);
304
if (extent_blk) {
305
- blk_unref(extent_blk);
306
+ blk_co_unref(extent_blk);
307
error_setg(errp, "List of extents contains unused extents");
308
ret = -EINVAL;
309
goto exit;
310
@@ -XXX,XX +XXX,XX @@ vmdk_co_do_create(int64_t size,
311
ret = 0;
312
exit:
313
if (blk) {
314
- blk_unref(blk);
315
+ blk_co_unref(blk);
316
}
317
g_free(desc);
318
g_free(parent_desc_line);
319
@@ -XXX,XX +XXX,XX @@ vmdk_co_create_opts_cb(int64_t size, int idx, bool flat, bool split,
320
errp)) {
321
goto exit;
322
}
323
- bdrv_unref(bs);
324
+ bdrv_co_unref(bs);
325
exit:
326
g_free(ext_filename);
327
return blk;
328
@@ -XXX,XX +XXX,XX @@ static BlockBackend * coroutine_fn vmdk_co_create_cb(int64_t size, int idx,
329
return NULL;
330
}
331
blk_set_allow_write_beyond_eof(blk, true);
332
- bdrv_unref(bs);
333
+ bdrv_co_unref(bs);
334
335
if (size != -1) {
336
ret = vmdk_init_extent(blk, size, flat, compress, zeroed_grain, errp);
337
if (ret) {
338
- blk_unref(blk);
339
+ blk_co_unref(blk);
340
blk = NULL;
341
}
342
}
343
diff --git a/block/vpc.c b/block/vpc.c
344
index XXXXXXX..XXXXXXX 100644
345
--- a/block/vpc.c
346
+++ b/block/vpc.c
347
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vpc_co_create(BlockdevCreateOptions *opts,
348
}
349
350
out:
351
- blk_unref(blk);
352
- bdrv_unref(bs);
353
+ blk_co_unref(blk);
354
+ bdrv_co_unref(bs);
355
return ret;
356
}
357
358
@@ -XXX,XX +XXX,XX @@ vpc_co_create_opts(BlockDriver *drv, const char *filename,
359
360
fail:
361
qobject_unref(qdict);
362
- bdrv_unref(bs);
363
+ bdrv_co_unref(bs);
364
qapi_free_BlockdevCreateOptions(create_options);
365
return ret;
366
}
367
--
142
--
368
2.40.1
143
2.41.0
diff view generated by jsdifflib
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
2
3
This adds GRAPH_RDLOCK annotations to declare that callers of
3
bdrv_co_debug_event was recently introduced, with bdrv_debug_event
4
bdrv_co_get_info() need to hold a reader lock for the graph.
4
becoming a wrapper for use in unknown context. Because most of the
5
time bdrv_debug_event is used on a BdrvChild via the wrapper macro
6
BLKDBG_EVENT, introduce a similar macro BLKDBG_CO_EVENT that calls
7
bdrv_co_debug_event, and switch whenever possible.
5
8
6
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
9
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Message-ID: <20230601115145.196465-13-pbonzini@redhat.com>
8
Reviewed-by: Eric Blake <eblake@redhat.com>
11
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
10
Message-Id: <20230504115750.54437-15-kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
13
---
13
include/block/block-io.h | 7 +++++--
14
include/block/block-io.h | 7 +++++++
14
include/block/block_int-common.h | 4 ++--
15
block/io.c | 4 ++--
15
block.c | 2 ++
16
block/qcow.c | 24 ++++++++++++------------
16
block/crypto.c | 2 +-
17
block/qcow2-cluster.c | 12 ++++++------
17
block/io.c | 11 +++++------
18
block/qcow2-refcount.c | 4 ++--
18
block/mirror.c | 8 ++++++--
19
block/qcow2.c | 18 +++++++++---------
19
block/raw-format.c | 2 +-
20
block/qed-table.c | 6 +++---
20
7 files changed, 22 insertions(+), 14 deletions(-)
21
block/qed.c | 8 ++++----
22
block/raw-format.c | 4 ++--
23
block/vmdk.c | 24 ++++++++++++------------
24
10 files changed, 59 insertions(+), 52 deletions(-)
21
25
22
diff --git a/include/block/block-io.h b/include/block/block-io.h
26
diff --git a/include/block/block-io.h b/include/block/block-io.h
23
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
24
--- a/include/block/block-io.h
28
--- a/include/block/block-io.h
25
+++ b/include/block/block-io.h
29
+++ b/include/block/block-io.h
26
@@ -XXX,XX +XXX,XX @@ const char *bdrv_get_node_name(const BlockDriverState *bs);
30
@@ -XXX,XX +XXX,XX @@ bdrv_co_debug_event(BlockDriverState *bs, BlkdebugEvent event);
27
const char *bdrv_get_device_name(const BlockDriverState *bs);
31
void co_wrapper_mixed_bdrv_rdlock
28
const char *bdrv_get_device_or_node_name(const BlockDriverState *bs);
32
bdrv_debug_event(BlockDriverState *bs, BlkdebugEvent event);
29
33
30
-int coroutine_fn bdrv_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi);
34
+#define BLKDBG_CO_EVENT(child, evt) \
31
-int co_wrapper_mixed bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi);
35
+ do { \
32
+int coroutine_fn GRAPH_RDLOCK
36
+ if (child) { \
33
+bdrv_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi);
37
+ bdrv_co_debug_event(child->bs, evt); \
38
+ } \
39
+ } while (0)
34
+
40
+
35
+int co_wrapper_mixed_bdrv_rdlock
41
#define BLKDBG_EVENT(child, evt) \
36
+bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi);
42
do { \
37
43
if (child) { \
38
ImageInfoSpecific *bdrv_get_specific_info(BlockDriverState *bs,
39
Error **errp);
40
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
41
index XXXXXXX..XXXXXXX 100644
42
--- a/include/block/block_int-common.h
43
+++ b/include/block/block_int-common.h
44
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
45
BlockDriverState *bs, int64_t offset, int64_t bytes,
46
QEMUIOVector *qiov, size_t qiov_offset);
47
48
- int coroutine_fn (*bdrv_co_get_info)(BlockDriverState *bs,
49
- BlockDriverInfo *bdi);
50
+ int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_get_info)(
51
+ BlockDriverState *bs, BlockDriverInfo *bdi);
52
53
ImageInfoSpecific *(*bdrv_get_specific_info)(BlockDriverState *bs,
54
Error **errp);
55
diff --git a/block.c b/block.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/block.c
58
+++ b/block.c
59
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
60
int ret;
61
BlockDriver *drv = bs->drv;
62
IO_CODE();
63
+ assert_bdrv_graph_readable();
64
+
65
/* if bs->drv == NULL, bs is closed, so there's nothing to do here */
66
if (!drv) {
67
return -ENOMEDIUM;
68
diff --git a/block/crypto.c b/block/crypto.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/block/crypto.c
71
+++ b/block/crypto.c
72
@@ -XXX,XX +XXX,XX @@ fail:
73
return ret;
74
}
75
76
-static int coroutine_fn
77
+static int coroutine_fn GRAPH_RDLOCK
78
block_crypto_co_get_info_luks(BlockDriverState *bs, BlockDriverInfo *bdi)
79
{
80
BlockDriverInfo subbdi;
81
diff --git a/block/io.c b/block/io.c
44
diff --git a/block/io.c b/block/io.c
82
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
83
--- a/block/io.c
46
--- a/block/io.c
84
+++ b/block/io.c
47
+++ b/block/io.c
85
@@ -XXX,XX +XXX,XX @@ BdrvTrackedRequest *coroutine_fn bdrv_co_get_self_request(BlockDriverState *bs)
48
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
86
/**
49
}
87
* Round a region to cluster boundaries
50
88
*/
51
/* Write back cached data to the OS even with cache=unsafe */
89
-void coroutine_fn bdrv_round_to_clusters(BlockDriverState *bs,
52
- BLKDBG_EVENT(primary_child, BLKDBG_FLUSH_TO_OS);
90
- int64_t offset, int64_t bytes,
53
+ BLKDBG_CO_EVENT(primary_child, BLKDBG_FLUSH_TO_OS);
91
- int64_t *cluster_offset,
54
if (bs->drv->bdrv_co_flush_to_os) {
92
- int64_t *cluster_bytes)
55
ret = bs->drv->bdrv_co_flush_to_os(bs);
93
+void coroutine_fn GRAPH_RDLOCK
56
if (ret < 0) {
94
+bdrv_round_to_clusters(BlockDriverState *bs, int64_t offset, int64_t bytes,
57
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
95
+ int64_t *cluster_offset, int64_t *cluster_bytes)
58
goto flush_children;
59
}
60
61
- BLKDBG_EVENT(primary_child, BLKDBG_FLUSH_TO_DISK);
62
+ BLKDBG_CO_EVENT(primary_child, BLKDBG_FLUSH_TO_DISK);
63
if (!bs->drv) {
64
/* bs->drv->bdrv_co_flush() might have ejected the BDS
65
* (even in case of apparent success) */
66
diff --git a/block/qcow.c b/block/qcow.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/block/qcow.c
69
+++ b/block/qcow.c
70
@@ -XXX,XX +XXX,XX @@ get_cluster_offset(BlockDriverState *bs, uint64_t offset, int allocate,
71
/* update the L1 entry */
72
s->l1_table[l1_index] = l2_offset;
73
tmp = cpu_to_be64(l2_offset);
74
- BLKDBG_EVENT(bs->file, BLKDBG_L1_UPDATE);
75
+ BLKDBG_CO_EVENT(bs->file, BLKDBG_L1_UPDATE);
76
ret = bdrv_co_pwrite_sync(bs->file,
77
s->l1_table_offset + l1_index * sizeof(tmp),
78
sizeof(tmp), &tmp, 0);
79
@@ -XXX,XX +XXX,XX @@ get_cluster_offset(BlockDriverState *bs, uint64_t offset, int allocate,
80
}
81
}
82
l2_table = s->l2_cache + (min_index << s->l2_bits);
83
- BLKDBG_EVENT(bs->file, BLKDBG_L2_LOAD);
84
+ BLKDBG_CO_EVENT(bs->file, BLKDBG_L2_LOAD);
85
if (new_l2_table) {
86
memset(l2_table, 0, s->l2_size * sizeof(uint64_t));
87
ret = bdrv_co_pwrite_sync(bs->file, l2_offset,
88
@@ -XXX,XX +XXX,XX @@ get_cluster_offset(BlockDriverState *bs, uint64_t offset, int allocate,
89
((cluster_offset & QCOW_OFLAG_COMPRESSED) && allocate == 1)) {
90
if (!allocate)
91
return 0;
92
- BLKDBG_EVENT(bs->file, BLKDBG_CLUSTER_ALLOC);
93
+ BLKDBG_CO_EVENT(bs->file, BLKDBG_CLUSTER_ALLOC);
94
assert(QEMU_IS_ALIGNED(n_start | n_end, BDRV_SECTOR_SIZE));
95
/* allocate a new cluster */
96
if ((cluster_offset & QCOW_OFLAG_COMPRESSED) &&
97
@@ -XXX,XX +XXX,XX @@ get_cluster_offset(BlockDriverState *bs, uint64_t offset, int allocate,
98
}
99
cluster_offset = QEMU_ALIGN_UP(cluster_offset, s->cluster_size);
100
/* write the cluster content */
101
- BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
102
+ BLKDBG_CO_EVENT(bs->file, BLKDBG_WRITE_AIO);
103
ret = bdrv_co_pwrite(bs->file, cluster_offset, s->cluster_size,
104
s->cluster_cache, 0);
105
if (ret < 0) {
106
@@ -XXX,XX +XXX,XX @@ get_cluster_offset(BlockDriverState *bs, uint64_t offset, int allocate,
107
NULL) < 0) {
108
return -EIO;
109
}
110
- BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
111
+ BLKDBG_CO_EVENT(bs->file, BLKDBG_WRITE_AIO);
112
ret = bdrv_co_pwrite(bs->file, cluster_offset + i,
113
BDRV_SECTOR_SIZE,
114
s->cluster_data, 0);
115
@@ -XXX,XX +XXX,XX @@ get_cluster_offset(BlockDriverState *bs, uint64_t offset, int allocate,
116
tmp = cpu_to_be64(cluster_offset);
117
l2_table[l2_index] = tmp;
118
if (allocate == 2) {
119
- BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE_COMPRESSED);
120
+ BLKDBG_CO_EVENT(bs->file, BLKDBG_L2_UPDATE_COMPRESSED);
121
} else {
122
- BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE);
123
+ BLKDBG_CO_EVENT(bs->file, BLKDBG_L2_UPDATE);
124
}
125
ret = bdrv_co_pwrite_sync(bs->file, l2_offset + l2_index * sizeof(tmp),
126
sizeof(tmp), &tmp, 0);
127
@@ -XXX,XX +XXX,XX @@ decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset)
128
if (s->cluster_cache_offset != coffset) {
129
csize = cluster_offset >> (63 - s->cluster_bits);
130
csize &= (s->cluster_size - 1);
131
- BLKDBG_EVENT(bs->file, BLKDBG_READ_COMPRESSED);
132
+ BLKDBG_CO_EVENT(bs->file, BLKDBG_READ_COMPRESSED);
133
ret = bdrv_co_pread(bs->file, coffset, csize, s->cluster_data, 0);
134
if (ret < 0)
135
return -1;
136
@@ -XXX,XX +XXX,XX @@ qcow_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
137
/* read from the base image */
138
qemu_co_mutex_unlock(&s->lock);
139
/* qcow2 emits this on bs->file instead of bs->backing */
140
- BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
141
+ BLKDBG_CO_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
142
ret = bdrv_co_pread(bs->backing, offset, n, buf, 0);
143
qemu_co_mutex_lock(&s->lock);
144
if (ret < 0) {
145
@@ -XXX,XX +XXX,XX @@ qcow_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
146
break;
147
}
148
qemu_co_mutex_unlock(&s->lock);
149
- BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
150
+ BLKDBG_CO_EVENT(bs->file, BLKDBG_READ_AIO);
151
ret = bdrv_co_pread(bs->file, cluster_offset + offset_in_cluster,
152
n, buf, 0);
153
qemu_co_mutex_lock(&s->lock);
154
@@ -XXX,XX +XXX,XX @@ qcow_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
155
}
156
157
qemu_co_mutex_unlock(&s->lock);
158
- BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
159
+ BLKDBG_CO_EVENT(bs->file, BLKDBG_WRITE_AIO);
160
ret = bdrv_co_pwrite(bs->file, cluster_offset + offset_in_cluster,
161
n, buf, 0);
162
qemu_co_mutex_lock(&s->lock);
163
@@ -XXX,XX +XXX,XX @@ qcow_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes,
164
}
165
cluster_offset &= s->cluster_offset_mask;
166
167
- BLKDBG_EVENT(bs->file, BLKDBG_WRITE_COMPRESSED);
168
+ BLKDBG_CO_EVENT(bs->file, BLKDBG_WRITE_COMPRESSED);
169
ret = bdrv_co_pwrite(bs->file, cluster_offset, out_len, out_buf, 0);
170
if (ret < 0) {
171
goto fail;
172
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
173
index XXXXXXX..XXXXXXX 100644
174
--- a/block/qcow2-cluster.c
175
+++ b/block/qcow2-cluster.c
176
@@ -XXX,XX +XXX,XX @@ int coroutine_fn qcow2_shrink_l1_table(BlockDriverState *bs,
177
fprintf(stderr, "shrink l1_table from %d to %d\n", s->l1_size, new_l1_size);
178
#endif
179
180
- BLKDBG_EVENT(bs->file, BLKDBG_L1_SHRINK_WRITE_TABLE);
181
+ BLKDBG_CO_EVENT(bs->file, BLKDBG_L1_SHRINK_WRITE_TABLE);
182
ret = bdrv_co_pwrite_zeroes(bs->file,
183
s->l1_table_offset + new_l1_size * L1E_SIZE,
184
(s->l1_size - new_l1_size) * L1E_SIZE, 0);
185
@@ -XXX,XX +XXX,XX @@ int coroutine_fn qcow2_shrink_l1_table(BlockDriverState *bs,
186
goto fail;
187
}
188
189
- BLKDBG_EVENT(bs->file, BLKDBG_L1_SHRINK_FREE_L2_CLUSTERS);
190
+ BLKDBG_CO_EVENT(bs->file, BLKDBG_L1_SHRINK_FREE_L2_CLUSTERS);
191
for (i = s->l1_size - 1; i > new_l1_size - 1; i--) {
192
if ((s->l1_table[i] & L1E_OFFSET_MASK) == 0) {
193
continue;
194
@@ -XXX,XX +XXX,XX @@ do_perform_cow_read(BlockDriverState *bs, uint64_t src_cluster_offset,
195
return 0;
196
}
197
198
- BLKDBG_EVENT(bs->file, BLKDBG_COW_READ);
199
+ BLKDBG_CO_EVENT(bs->file, BLKDBG_COW_READ);
200
201
if (!bs->drv) {
202
return -ENOMEDIUM;
203
@@ -XXX,XX +XXX,XX @@ do_perform_cow_write(BlockDriverState *bs, uint64_t cluster_offset,
204
return ret;
205
}
206
207
- BLKDBG_EVENT(bs->file, BLKDBG_COW_WRITE);
208
+ BLKDBG_CO_EVENT(bs->file, BLKDBG_COW_WRITE);
209
ret = bdrv_co_pwritev(s->data_file, cluster_offset + offset_in_cluster,
210
qiov->size, qiov, 0);
211
if (ret < 0) {
212
@@ -XXX,XX +XXX,XX @@ qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs, uint64_t offset,
213
214
/* compressed clusters never have the copied flag */
215
216
- BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE_COMPRESSED);
217
+ BLKDBG_CO_EVENT(bs->file, BLKDBG_L2_UPDATE_COMPRESSED);
218
qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_slice);
219
set_l2_entry(s, l2_slice, l2_index, cluster_offset);
220
if (has_subclusters(s)) {
221
@@ -XXX,XX +XXX,XX @@ perform_cow(BlockDriverState *bs, QCowL2Meta *m)
222
/* NOTE: we have a write_aio blkdebug event here followed by
223
* a cow_write one in do_perform_cow_write(), but there's only
224
* one single I/O operation */
225
- BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
226
+ BLKDBG_CO_EVENT(bs->file, BLKDBG_WRITE_AIO);
227
ret = do_perform_cow_write(bs, m->alloc_offset, start->offset, &qiov);
228
} else {
229
/* If there's no guest data then write both COW regions separately */
230
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
231
index XXXXXXX..XXXXXXX 100644
232
--- a/block/qcow2-refcount.c
233
+++ b/block/qcow2-refcount.c
234
@@ -XXX,XX +XXX,XX @@ int coroutine_fn qcow2_refcount_init(BlockDriverState *bs)
235
ret = -ENOMEM;
236
goto fail;
237
}
238
- BLKDBG_EVENT(bs->file, BLKDBG_REFTABLE_LOAD);
239
+ BLKDBG_CO_EVENT(bs->file, BLKDBG_REFTABLE_LOAD);
240
ret = bdrv_co_pread(bs->file, s->refcount_table_offset,
241
refcount_table_size2, s->refcount_table, 0);
242
if (ret < 0) {
243
@@ -XXX,XX +XXX,XX @@ int64_t coroutine_fn GRAPH_RDLOCK qcow2_alloc_bytes(BlockDriverState *bs, int si
244
size_t free_in_cluster;
245
int ret;
246
247
- BLKDBG_EVENT(bs->file, BLKDBG_CLUSTER_ALLOC_BYTES);
248
+ BLKDBG_CO_EVENT(bs->file, BLKDBG_CLUSTER_ALLOC_BYTES);
249
assert(size > 0 && size <= s->cluster_size);
250
assert(!s->free_byte_offset || offset_into_cluster(s, s->free_byte_offset));
251
252
diff --git a/block/qcow2.c b/block/qcow2.c
253
index XXXXXXX..XXXXXXX 100644
254
--- a/block/qcow2.c
255
+++ b/block/qcow2.c
256
@@ -XXX,XX +XXX,XX @@ qcow2_co_preadv_encrypted(BlockDriverState *bs,
257
return -ENOMEM;
258
}
259
260
- BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
261
+ BLKDBG_CO_EVENT(bs->file, BLKDBG_READ_AIO);
262
ret = bdrv_co_pread(s->data_file, host_offset, bytes, buf, 0);
263
if (ret < 0) {
264
goto fail;
265
@@ -XXX,XX +XXX,XX @@ qcow2_co_preadv_task(BlockDriverState *bs, QCow2SubclusterType subc_type,
266
case QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC:
267
assert(bs->backing); /* otherwise handled in qcow2_co_preadv_part */
268
269
- BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
270
+ BLKDBG_CO_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
271
return bdrv_co_preadv_part(bs->backing, offset, bytes,
272
qiov, qiov_offset, 0);
273
274
@@ -XXX,XX +XXX,XX @@ qcow2_co_preadv_task(BlockDriverState *bs, QCow2SubclusterType subc_type,
275
offset, bytes, qiov, qiov_offset);
276
}
277
278
- BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
279
+ BLKDBG_CO_EVENT(bs->file, BLKDBG_READ_AIO);
280
return bdrv_co_preadv_part(s->data_file, host_offset,
281
bytes, qiov, qiov_offset, 0);
282
283
@@ -XXX,XX +XXX,XX @@ handle_alloc_space(BlockDriverState *bs, QCowL2Meta *l2meta)
284
return ret;
285
}
286
287
- BLKDBG_EVENT(bs->file, BLKDBG_CLUSTER_ALLOC_SPACE);
288
+ BLKDBG_CO_EVENT(bs->file, BLKDBG_CLUSTER_ALLOC_SPACE);
289
ret = bdrv_co_pwrite_zeroes(s->data_file, start_offset, nb_bytes,
290
BDRV_REQ_NO_FALLBACK);
291
if (ret < 0) {
292
@@ -XXX,XX +XXX,XX @@ int qcow2_co_pwritev_task(BlockDriverState *bs, uint64_t host_offset,
293
* guest data now.
294
*/
295
if (!merge_cow(offset, bytes, qiov, qiov_offset, l2meta)) {
296
- BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
297
+ BLKDBG_CO_EVENT(bs->file, BLKDBG_WRITE_AIO);
298
trace_qcow2_writev_data(qemu_coroutine_self(), host_offset);
299
ret = bdrv_co_pwritev_part(s->data_file, host_offset,
300
bytes, qiov, qiov_offset, 0);
301
@@ -XXX,XX +XXX,XX @@ qcow2_co_pwritev_compressed_task(BlockDriverState *bs,
302
goto fail;
303
}
304
305
- BLKDBG_EVENT(s->data_file, BLKDBG_WRITE_COMPRESSED);
306
+ BLKDBG_CO_EVENT(s->data_file, BLKDBG_WRITE_COMPRESSED);
307
ret = bdrv_co_pwrite(s->data_file, cluster_offset, out_len, out_buf, 0);
308
if (ret < 0) {
309
goto fail;
310
@@ -XXX,XX +XXX,XX @@ qcow2_co_preadv_compressed(BlockDriverState *bs,
311
312
out_buf = qemu_blockalign(bs, s->cluster_size);
313
314
- BLKDBG_EVENT(bs->file, BLKDBG_READ_COMPRESSED);
315
+ BLKDBG_CO_EVENT(bs->file, BLKDBG_READ_COMPRESSED);
316
ret = bdrv_co_pread(bs->file, coffset, csize, buf, 0);
317
if (ret < 0) {
318
goto fail;
319
@@ -XXX,XX +XXX,XX @@ qcow2_co_save_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos)
320
return offset;
321
}
322
323
- BLKDBG_EVENT(bs->file, BLKDBG_VMSTATE_SAVE);
324
+ BLKDBG_CO_EVENT(bs->file, BLKDBG_VMSTATE_SAVE);
325
return bs->drv->bdrv_co_pwritev_part(bs, offset, qiov->size, qiov, 0, 0);
326
}
327
328
@@ -XXX,XX +XXX,XX @@ qcow2_co_load_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos)
329
return offset;
330
}
331
332
- BLKDBG_EVENT(bs->file, BLKDBG_VMSTATE_LOAD);
333
+ BLKDBG_CO_EVENT(bs->file, BLKDBG_VMSTATE_LOAD);
334
return bs->drv->bdrv_co_preadv_part(bs, offset, qiov->size, qiov, 0, 0);
335
}
336
337
diff --git a/block/qed-table.c b/block/qed-table.c
338
index XXXXXXX..XXXXXXX 100644
339
--- a/block/qed-table.c
340
+++ b/block/qed-table.c
341
@@ -XXX,XX +XXX,XX @@ int coroutine_fn qed_read_l1_table_sync(BDRVQEDState *s)
342
int coroutine_fn qed_write_l1_table(BDRVQEDState *s, unsigned int index,
343
unsigned int n)
96
{
344
{
97
BlockDriverInfo bdi;
345
- BLKDBG_EVENT(s->bs->file, BLKDBG_L1_UPDATE);
98
IO_CODE();
346
+ BLKDBG_CO_EVENT(s->bs->file, BLKDBG_L1_UPDATE);
99
@@ -XXX,XX +XXX,XX @@ void coroutine_fn bdrv_round_to_clusters(BlockDriverState *bs,
347
return qed_write_table(s, s->header.l1_table_offset,
100
}
348
s->l1_table, index, n, false);
101
}
349
}
102
350
@@ -XXX,XX +XXX,XX @@ int coroutine_fn qed_read_l2_table(BDRVQEDState *s, QEDRequest *request,
103
-static coroutine_fn int bdrv_get_cluster_size(BlockDriverState *bs)
351
request->l2_table = qed_alloc_l2_cache_entry(&s->l2_cache);
104
+static int coroutine_fn GRAPH_RDLOCK bdrv_get_cluster_size(BlockDriverState *bs)
352
request->l2_table->table = qed_alloc_table(s);
353
354
- BLKDBG_EVENT(s->bs->file, BLKDBG_L2_LOAD);
355
+ BLKDBG_CO_EVENT(s->bs->file, BLKDBG_L2_LOAD);
356
ret = qed_read_table(s, offset, request->l2_table->table);
357
358
if (ret) {
359
@@ -XXX,XX +XXX,XX @@ int coroutine_fn qed_write_l2_table(BDRVQEDState *s, QEDRequest *request,
360
unsigned int index, unsigned int n,
361
bool flush)
105
{
362
{
106
BlockDriverInfo bdi;
363
- BLKDBG_EVENT(s->bs->file, BLKDBG_L2_UPDATE);
107
int ret;
364
+ BLKDBG_CO_EVENT(s->bs->file, BLKDBG_L2_UPDATE);
108
@@ -XXX,XX +XXX,XX @@ fail:
365
return qed_write_table(s, request->l2_table->offset,
109
return ret;
366
request->l2_table->table, index, n, flush);
110
}
367
}
111
368
diff --git a/block/qed.c b/block/qed.c
112
-static inline int coroutine_fn
369
index XXXXXXX..XXXXXXX 100644
113
+static inline int coroutine_fn GRAPH_RDLOCK
370
--- a/block/qed.c
114
bdrv_co_write_req_prepare(BdrvChild *child, int64_t offset, int64_t bytes,
371
+++ b/block/qed.c
115
BdrvTrackedRequest *req, int flags)
372
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn GRAPH_RDLOCK
373
qed_read_backing_file(BDRVQEDState *s, uint64_t pos, QEMUIOVector *qiov)
116
{
374
{
117
diff --git a/block/mirror.c b/block/mirror.c
375
if (s->bs->backing) {
118
index XXXXXXX..XXXXXXX 100644
376
- BLKDBG_EVENT(s->bs->file, BLKDBG_READ_BACKING_AIO);
119
--- a/block/mirror.c
377
+ BLKDBG_CO_EVENT(s->bs->file, BLKDBG_READ_BACKING_AIO);
120
+++ b/block/mirror.c
378
return bdrv_co_preadv(s->bs->backing, pos, qiov->size, qiov, 0);
121
@@ -XXX,XX +XXX,XX @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
379
}
122
} else if (ret >= 0 && !(ret & BDRV_BLOCK_DATA)) {
380
qemu_iovec_memset(qiov, 0, 0, qiov->size);
123
int64_t target_offset;
381
@@ -XXX,XX +XXX,XX @@ qed_copy_from_backing_file(BDRVQEDState *s, uint64_t pos, uint64_t len,
124
int64_t target_bytes;
382
goto out;
125
- bdrv_round_to_clusters(blk_bs(s->target), offset, io_bytes,
383
}
126
- &target_offset, &target_bytes);
384
127
+ WITH_GRAPH_RDLOCK_GUARD() {
385
- BLKDBG_EVENT(s->bs->file, BLKDBG_COW_WRITE);
128
+ bdrv_round_to_clusters(blk_bs(s->target), offset, io_bytes,
386
+ BLKDBG_CO_EVENT(s->bs->file, BLKDBG_COW_WRITE);
129
+ &target_offset, &target_bytes);
387
ret = bdrv_co_pwritev(s->bs->file, offset, qiov.size, &qiov, 0);
130
+ }
388
if (ret < 0) {
131
if (target_offset == offset &&
389
goto out;
132
target_bytes == io_bytes) {
390
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn GRAPH_RDLOCK qed_aio_write_main(QEDAIOCB *acb)
133
mirror_method = ret & BDRV_BLOCK_ZERO ?
391
134
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
392
trace_qed_aio_write_main(s, acb, 0, offset, acb->cur_qiov.size);
135
*/
393
136
bdrv_get_backing_filename(target_bs, backing_filename,
394
- BLKDBG_EVENT(s->bs->file, BLKDBG_WRITE_AIO);
137
sizeof(backing_filename));
395
+ BLKDBG_CO_EVENT(s->bs->file, BLKDBG_WRITE_AIO);
138
+ bdrv_graph_co_rdlock();
396
return bdrv_co_pwritev(s->bs->file, offset, acb->cur_qiov.size,
139
if (!bdrv_co_get_info(target_bs, &bdi) && bdi.cluster_size) {
397
&acb->cur_qiov, 0);
140
s->target_cluster_size = bdi.cluster_size;
398
}
399
@@ -XXX,XX +XXX,XX @@ qed_aio_read_data(void *opaque, int ret, uint64_t offset, size_t len)
400
} else if (ret != QED_CLUSTER_FOUND) {
401
r = qed_read_backing_file(s, acb->cur_pos, &acb->cur_qiov);
141
} else {
402
} else {
142
s->target_cluster_size = BDRV_SECTOR_SIZE;
403
- BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
143
}
404
+ BLKDBG_CO_EVENT(bs->file, BLKDBG_READ_AIO);
144
+ bdrv_graph_co_rdunlock();
405
r = bdrv_co_preadv(bs->file, offset, acb->cur_qiov.size,
145
if (backing_filename[0] && !bdrv_backing_chain_next(target_bs) &&
406
&acb->cur_qiov, 0);
146
s->granularity < s->target_cluster_size) {
407
}
147
s->buf_size = MAX(s->buf_size, s->target_cluster_size);
148
diff --git a/block/raw-format.c b/block/raw-format.c
408
diff --git a/block/raw-format.c b/block/raw-format.c
149
index XXXXXXX..XXXXXXX 100644
409
index XXXXXXX..XXXXXXX 100644
150
--- a/block/raw-format.c
410
--- a/block/raw-format.c
151
+++ b/block/raw-format.c
411
+++ b/block/raw-format.c
152
@@ -XXX,XX +XXX,XX @@ static BlockMeasureInfo *raw_measure(QemuOpts *opts, BlockDriverState *in_bs,
412
@@ -XXX,XX +XXX,XX @@ raw_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
153
return info;
413
return ret;
414
}
415
416
- BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
417
+ BLKDBG_CO_EVENT(bs->file, BLKDBG_READ_AIO);
418
return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
154
}
419
}
155
420
156
-static int coroutine_fn
421
@@ -XXX,XX +XXX,XX @@ raw_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
157
+static int coroutine_fn GRAPH_RDLOCK
422
goto fail;
158
raw_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
423
}
424
425
- BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
426
+ BLKDBG_CO_EVENT(bs->file, BLKDBG_WRITE_AIO);
427
ret = bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
428
429
fail:
430
diff --git a/block/vmdk.c b/block/vmdk.c
431
index XXXXXXX..XXXXXXX 100644
432
--- a/block/vmdk.c
433
+++ b/block/vmdk.c
434
@@ -XXX,XX +XXX,XX @@ get_whole_cluster(BlockDriverState *bs, VmdkExtent *extent,
435
if (skip_start_bytes > 0) {
436
if (copy_from_backing) {
437
/* qcow2 emits this on bs->file instead of bs->backing */
438
- BLKDBG_EVENT(extent->file, BLKDBG_COW_READ);
439
+ BLKDBG_CO_EVENT(extent->file, BLKDBG_COW_READ);
440
ret = bdrv_co_pread(bs->backing, offset, skip_start_bytes,
441
whole_grain, 0);
442
if (ret < 0) {
443
@@ -XXX,XX +XXX,XX @@ get_whole_cluster(BlockDriverState *bs, VmdkExtent *extent,
444
goto exit;
445
}
446
}
447
- BLKDBG_EVENT(extent->file, BLKDBG_COW_WRITE);
448
+ BLKDBG_CO_EVENT(extent->file, BLKDBG_COW_WRITE);
449
ret = bdrv_co_pwrite(extent->file, cluster_offset, skip_start_bytes,
450
whole_grain, 0);
451
if (ret < 0) {
452
@@ -XXX,XX +XXX,XX @@ get_whole_cluster(BlockDriverState *bs, VmdkExtent *extent,
453
if (skip_end_bytes < cluster_bytes) {
454
if (copy_from_backing) {
455
/* qcow2 emits this on bs->file instead of bs->backing */
456
- BLKDBG_EVENT(extent->file, BLKDBG_COW_READ);
457
+ BLKDBG_CO_EVENT(extent->file, BLKDBG_COW_READ);
458
ret = bdrv_co_pread(bs->backing, offset + skip_end_bytes,
459
cluster_bytes - skip_end_bytes,
460
whole_grain + skip_end_bytes, 0);
461
@@ -XXX,XX +XXX,XX @@ get_whole_cluster(BlockDriverState *bs, VmdkExtent *extent,
462
goto exit;
463
}
464
}
465
- BLKDBG_EVENT(extent->file, BLKDBG_COW_WRITE);
466
+ BLKDBG_CO_EVENT(extent->file, BLKDBG_COW_WRITE);
467
ret = bdrv_co_pwrite(extent->file, cluster_offset + skip_end_bytes,
468
cluster_bytes - skip_end_bytes,
469
whole_grain + skip_end_bytes, 0);
470
@@ -XXX,XX +XXX,XX @@ vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data, uint32_t offset)
159
{
471
{
160
return bdrv_co_get_info(bs->file->bs, bdi);
472
offset = cpu_to_le32(offset);
473
/* update L2 table */
474
- BLKDBG_EVENT(extent->file, BLKDBG_L2_UPDATE);
475
+ BLKDBG_CO_EVENT(extent->file, BLKDBG_L2_UPDATE);
476
if (bdrv_co_pwrite(extent->file,
477
((int64_t)m_data->l2_offset * 512)
478
+ (m_data->l2_index * sizeof(offset)),
479
@@ -XXX,XX +XXX,XX @@ get_cluster_offset(BlockDriverState *bs, VmdkExtent *extent,
480
}
481
}
482
l2_table = (char *)extent->l2_cache + (min_index * l2_size_bytes);
483
- BLKDBG_EVENT(extent->file, BLKDBG_L2_LOAD);
484
+ BLKDBG_CO_EVENT(extent->file, BLKDBG_L2_LOAD);
485
if (bdrv_co_pread(extent->file,
486
(int64_t)l2_offset * 512,
487
l2_size_bytes,
488
@@ -XXX,XX +XXX,XX @@ vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset,
489
n_bytes = buf_len + sizeof(VmdkGrainMarker);
490
qemu_iovec_init_buf(&local_qiov, data, n_bytes);
491
492
- BLKDBG_EVENT(extent->file, BLKDBG_WRITE_COMPRESSED);
493
+ BLKDBG_CO_EVENT(extent->file, BLKDBG_WRITE_COMPRESSED);
494
} else {
495
qemu_iovec_init(&local_qiov, qiov->niov);
496
qemu_iovec_concat(&local_qiov, qiov, qiov_offset, n_bytes);
497
498
- BLKDBG_EVENT(extent->file, BLKDBG_WRITE_AIO);
499
+ BLKDBG_CO_EVENT(extent->file, BLKDBG_WRITE_AIO);
500
}
501
502
write_offset = cluster_offset + offset_in_cluster;
503
@@ -XXX,XX +XXX,XX @@ vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset,
504
505
506
if (!extent->compressed) {
507
- BLKDBG_EVENT(extent->file, BLKDBG_READ_AIO);
508
+ BLKDBG_CO_EVENT(extent->file, BLKDBG_READ_AIO);
509
ret = bdrv_co_preadv(extent->file,
510
cluster_offset + offset_in_cluster, bytes,
511
qiov, 0);
512
@@ -XXX,XX +XXX,XX @@ vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset,
513
buf_bytes = cluster_bytes * 2;
514
cluster_buf = g_malloc(buf_bytes);
515
uncomp_buf = g_malloc(cluster_bytes);
516
- BLKDBG_EVENT(extent->file, BLKDBG_READ_COMPRESSED);
517
+ BLKDBG_CO_EVENT(extent->file, BLKDBG_READ_COMPRESSED);
518
ret = bdrv_co_pread(extent->file, cluster_offset, buf_bytes, cluster_buf,
519
0);
520
if (ret < 0) {
521
@@ -XXX,XX +XXX,XX @@ vmdk_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
522
qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes);
523
524
/* qcow2 emits this on bs->file instead of bs->backing */
525
- BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
526
+ BLKDBG_CO_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
527
ret = bdrv_co_preadv(bs->backing, offset, n_bytes,
528
&local_qiov, 0);
529
if (ret < 0) {
530
@@ -XXX,XX +XXX,XX @@ vmdk_co_check(BlockDriverState *bs, BdrvCheckResult *result, BdrvCheckMode fix)
531
BDRVVmdkState *s = bs->opaque;
532
VmdkExtent *extent = NULL;
533
int64_t sector_num = 0;
534
- int64_t total_sectors = bdrv_nb_sectors(bs);
535
+ int64_t total_sectors = bdrv_co_nb_sectors(bs);
536
int ret;
537
uint64_t cluster_offset;
538
161
--
539
--
162
2.40.1
540
2.41.0
diff view generated by jsdifflib