1
The following changes since commit 0280396a33c7210c4df5306afeab63411a41535a:
1
The following changes since commit 239b8b0699a222fd21da1c5fdeba0a2456085a47:
2
2
3
Merge remote-tracking branch 'remotes/stsquad/tags/pull-testing-gdbstub-150221-1' into staging (2021-02-15 10:13:13 +0000)
3
Merge tag 'trivial-branch-for-8.0-pull-request' of https://gitlab.com/laurent_vivier/qemu into staging (2023-01-19 15:05:29 +0000)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
git://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 b248e61652e20c3353af4b0ccb90f17d76f4db21:
9
for you to fetch changes up to 4711b0a8490827c332b3f9281f689ce9555b7fab:
10
10
11
monitor/qmp: Stop processing requests when shutdown is requested (2021-02-15 15:10:14 +0100)
11
qemu-img: Change info key names for protocol nodes (2023-01-20 13:11:01 +0100)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block layer patches:
14
Block layer patches
15
15
16
- qemu-storage-daemon: Enable object-add
16
- qemu-img info: Show protocol-level information
17
- blockjob: Fix crash with IOthread when block commit after snapshot
17
- Move more functions to coroutines
18
- monitor: Shutdown fixes
18
- Make coroutine annotations ready for static analysis
19
- xen-block: fix reporting of discard feature
19
- qemu-img: Fix exit code for errors closing the image
20
- qcow2: Remove half-initialised image file after failed image creation
20
- qcow2 bitmaps: Fix theoretical corruption in error path
21
- ahci: Fix DMA direction
21
- pflash: Only load non-zero parts of backend image to save memory
22
- iotests fixes
22
- Code cleanup and test case improvements
23
23
24
----------------------------------------------------------------
24
----------------------------------------------------------------
25
Alexander Bulekov (1):
25
Alberto Faria (2):
26
hw/ide/ahci: map cmd_fis as DMA_DIRECTION_TO_DEVICE
26
coroutine: annotate coroutine_fn for libclang
27
block: Add no_coroutine_fn and coroutine_mixed_fn marker
27
28
28
Kevin Wolf (3):
29
Emanuele Giuseppe Esposito (14):
29
qemu-storage-daemon: Enable object-add
30
block-coroutine-wrapper: support void functions
30
monitor: Fix assertion failure on shutdown
31
block: Convert bdrv_io_plug() to co_wrapper
31
monitor/qmp: Stop processing requests when shutdown is requested
32
block: Convert bdrv_io_unplug() to co_wrapper
33
block: Convert bdrv_is_inserted() to co_wrapper
34
block: Rename refresh_total_sectors to bdrv_refresh_total_sectors
35
block: Convert bdrv_refresh_total_sectors() to co_wrapper_mixed
36
block-backend: use bdrv_getlength instead of blk_getlength
37
block: use bdrv_co_refresh_total_sectors when possible
38
block: Convert bdrv_get_allocated_file_size() to co_wrapper
39
block: Convert bdrv_get_info() to co_wrapper_mixed
40
block: Convert bdrv_eject() to co_wrapper
41
block: Convert bdrv_lock_medium() to co_wrapper
42
block: Convert bdrv_debug_event() to co_wrapper_mixed
43
block: Rename bdrv_load/save_vmstate() to bdrv_co_load/save_vmstate()
32
44
33
Max Reitz (1):
45
Hanna Reitz (12):
34
iotests: Consistent $IMGOPTS boundary matching
46
block: Improve empty format-specific info dump
47
block/file: Add file-specific image info
48
block/vmdk: Change extent info type
49
block: Split BlockNodeInfo off of ImageInfo
50
qemu-img: Use BlockNodeInfo
51
block/qapi: Let bdrv_query_image_info() recurse
52
block/qapi: Introduce BlockGraphInfo
53
block/qapi: Add indentation to bdrv_node_info_dump()
54
iotests: Filter child node information
55
iotests/106, 214, 308: Read only one size line
56
qemu-img: Let info print block graph
57
qemu-img: Change info key names for protocol nodes
35
58
36
Maxim Levitsky (3):
59
Kevin Wolf (4):
37
crypto: luks: Fix tiny memory leak
60
qcow2: Fix theoretical corruption in store_bitmap() error path
38
block: add bdrv_co_delete_file_noerr
61
qemu-img commit: Report errors while closing the image
39
block: qcow2: remove the created file on initialization error
62
qemu-img bitmap: Report errors while closing the image
63
qemu-iotests: Test qemu-img bitmap/commit exit code on error
40
64
41
Michael Qiu (1):
65
Paolo Bonzini (2):
42
blockjob: Fix crash with IOthread when block commit after snapshot
66
qemu-io: do not reinvent the blk_pwrite_zeroes wheel
67
block: remove bdrv_coroutine_enter
43
68
44
Roger Pau Monné (1):
69
Philippe Mathieu-Daudé (1):
45
xen-block: fix reporting of discard feature
70
block/nbd: Add missing <qemu/bswap.h> include
46
71
47
Thomas Huth (1):
72
Thomas Huth (2):
48
tests/qemu-iotests: Remove test 259 from the "auto" group
73
tests/qemu-iotests/312: Mark "quorum" as required driver
74
tests/qemu-iotests/262: Check for availability of "blkverify" first
49
75
50
include/block/block.h | 1 +
76
Xiang Zheng (1):
51
block.c | 22 ++++++++++++++++++++++
77
pflash: Only read non-zero parts of backend image
52
block/crypto.c | 13 ++-----------
78
53
block/qcow2.c | 8 +++++---
79
qapi/block-core.json | 123 +++++++-
54
blockjob.c | 8 ++++++--
80
include/block/block-common.h | 11 +-
55
hw/block/xen-block.c | 1 +
81
include/block/block-io.h | 41 ++-
56
hw/ide/ahci.c | 12 ++++++------
82
include/block/block_int-common.h | 26 +-
57
monitor/monitor.c | 25 +++++++++++++++----------
83
include/block/block_int-io.h | 5 +-
58
monitor/qmp.c | 5 +++++
84
include/block/nbd.h | 1 +
59
storage-daemon/qemu-storage-daemon.c | 2 ++
85
include/block/qapi.h | 14 +-
60
tests/qemu-iotests/259 | 2 +-
86
include/qemu/coroutine.h | 43 +++
61
tests/qemu-iotests/common.rc | 4 +++-
87
include/sysemu/block-backend-io.h | 31 +-
62
12 files changed, 69 insertions(+), 34 deletions(-)
88
block.c | 88 +++---
89
block/blkdebug.c | 11 +-
90
block/blkio.c | 15 +-
91
block/blklogwrites.c | 6 +-
92
block/blkreplay.c | 6 +-
93
block/blkverify.c | 6 +-
94
block/block-backend.c | 38 +--
95
block/commit.c | 4 +-
96
block/copy-on-read.c | 18 +-
97
block/crypto.c | 14 +-
98
block/curl.c | 10 +-
99
block/file-posix.c | 137 +++++----
100
block/file-win32.c | 18 +-
101
block/filter-compress.c | 20 +-
102
block/gluster.c | 23 +-
103
block/io.c | 76 ++---
104
block/iscsi.c | 17 +-
105
block/mirror.c | 6 +-
106
block/monitor/block-hmp-cmds.c | 2 +-
107
block/nbd.c | 8 +-
108
block/nfs.c | 4 +-
109
block/null.c | 13 +-
110
block/nvme.c | 14 +-
111
block/preallocate.c | 16 +-
112
block/qapi.c | 317 ++++++++++++++++-----
113
block/qcow.c | 5 +-
114
block/qcow2-bitmap.c | 5 +-
115
block/qcow2-refcount.c | 2 +-
116
block/qcow2.c | 17 +-
117
block/qed.c | 11 +-
118
block/quorum.c | 8 +-
119
block/raw-format.c | 25 +-
120
block/rbd.c | 9 +-
121
block/replication.c | 6 +-
122
block/ssh.c | 4 +-
123
block/throttle.c | 6 +-
124
block/vdi.c | 7 +-
125
block/vhdx.c | 5 +-
126
block/vmdk.c | 22 +-
127
block/vpc.c | 5 +-
128
blockdev.c | 8 +-
129
hw/block/block.c | 36 ++-
130
hw/scsi/scsi-disk.c | 5 +
131
qemu-img.c | 100 +++++--
132
qemu-io-cmds.c | 62 +---
133
tests/unit/test-block-iothread.c | 3 +
134
scripts/block-coroutine-wrapper.py | 20 +-
135
tests/qemu-iotests/iotests.py | 18 +-
136
block/meson.build | 1 +
137
tests/qemu-iotests/065 | 2 +-
138
tests/qemu-iotests/106 | 4 +-
139
tests/qemu-iotests/214 | 6 +-
140
tests/qemu-iotests/262 | 3 +-
141
tests/qemu-iotests/302.out | 5 +
142
tests/qemu-iotests/308 | 4 +-
143
tests/qemu-iotests/312 | 1 +
144
tests/qemu-iotests/common.filter | 22 +-
145
tests/qemu-iotests/common.rc | 22 +-
146
tests/qemu-iotests/tests/qemu-img-close-errors | 95 ++++++
147
tests/qemu-iotests/tests/qemu-img-close-errors.out | 23 ++
148
69 files changed, 1207 insertions(+), 552 deletions(-)
149
create mode 100755 tests/qemu-iotests/tests/qemu-img-close-errors
150
create mode 100644 tests/qemu-iotests/tests/qemu-img-close-errors.out
63
151
64
152
diff view generated by jsdifflib
1
Before this patch, monitor_qmp_dispatcher_co() used to check whether
1
From: Thomas Huth <thuth@redhat.com>
2
shutdown is requested only when it would have to wait for new requests.
3
If there were still some queued requests, it would try to execute all of
4
them before shutting down.
5
2
6
This can be surprising when the queued QMP commands take long or hang
3
"quorum" is required by iotest 312 - if it is not compiled into the
7
because Ctrl-C may not actually exit QEMU as soon as possible.
4
QEMU binary, the test fails. Thus list "quorum" as required driver
5
so that the test gets skipped in case it is not available.
8
6
9
Change monitor_qmp_dispatcher_co() so that it additionally checks
7
Signed-off-by: Thomas Huth <thuth@redhat.com>
10
whether shutdown is request before it gets a new request from the queue.
8
Message-Id: <20230104114601.269351-1-thuth@redhat.com>
11
9
Reviewed-by: Alberto Garcia <berto@igalia.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
13
Message-Id: <20210212172028.288825-3-kwolf@redhat.com>
11
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
14
Tested-by: Markus Armbruster <armbru@redhat.com>
15
Reviewed-by: Markus Armbruster <armbru@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
---
13
---
18
monitor/qmp.c | 5 +++++
14
tests/qemu-iotests/312 | 1 +
19
1 file changed, 5 insertions(+)
15
1 file changed, 1 insertion(+)
20
16
21
diff --git a/monitor/qmp.c b/monitor/qmp.c
17
diff --git a/tests/qemu-iotests/312 b/tests/qemu-iotests/312
22
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100755
23
--- a/monitor/qmp.c
19
--- a/tests/qemu-iotests/312
24
+++ b/monitor/qmp.c
20
+++ b/tests/qemu-iotests/312
25
@@ -XXX,XX +XXX,XX @@ void coroutine_fn monitor_qmp_dispatcher_co(void *data)
21
@@ -XXX,XX +XXX,XX @@ _supported_fmt qcow2
26
*/
22
_supported_proto file
27
qatomic_mb_set(&qmp_dispatcher_co_busy, false);
23
_supported_os Linux
28
24
_unsupported_imgopts cluster_size data_file
29
+ /* On shutdown, don't take any more requests from the queue */
25
+_require_drivers quorum
30
+ if (qmp_dispatcher_co_shutdown) {
26
31
+ return;
27
echo
32
+ }
28
echo '### Create all images' # three source (quorum), one destination
33
+
34
while (!(req_obj = monitor_qmp_requests_pop_any_with_lock())) {
35
/*
36
* No more requests to process. Wait to be reentered from
37
--
29
--
38
2.29.2
30
2.38.1
39
31
40
32
diff view generated by jsdifflib
1
From: Thomas Huth <thuth@redhat.com>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
Tests in the "auto" group should support qcow2 so that they can
3
In downstream RHEL builds, we do not have "blkverify" enabled, so
4
be run during "make check-block". Test 259 only supports "raw", so
4
iotest 262 is currently failing there. Thus let's list "blkverify"
5
it currently always gets skipped when running "make check-block".
5
as required item so that the test properly gets skipped instead if
6
Let's skip this unnecessary step and remove it from the auto group.
6
"blkverify" is missing.
7
7
8
Signed-off-by: Thomas Huth <thuth@redhat.com>
8
Signed-off-by: Thomas Huth <thuth@redhat.com>
9
Message-Id: <20210215103835.1129145-1-thuth@redhat.com>
9
Message-Id: <20230104112850.261480-1-thuth@redhat.com>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
13
---
12
tests/qemu-iotests/259 | 2 +-
14
tests/qemu-iotests/262 | 3 ++-
13
1 file changed, 1 insertion(+), 1 deletion(-)
15
1 file changed, 2 insertions(+), 1 deletion(-)
14
16
15
diff --git a/tests/qemu-iotests/259 b/tests/qemu-iotests/259
17
diff --git a/tests/qemu-iotests/262 b/tests/qemu-iotests/262
16
index XXXXXXX..XXXXXXX 100755
18
index XXXXXXX..XXXXXXX 100755
17
--- a/tests/qemu-iotests/259
19
--- a/tests/qemu-iotests/262
18
+++ b/tests/qemu-iotests/259
20
+++ b/tests/qemu-iotests/262
19
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ import iotests
20
#!/usr/bin/env bash
22
import os
21
-# group: rw auto quick
23
22
+# group: rw quick
24
iotests.script_initialize(supported_fmts=['qcow2'],
23
#
25
- supported_platforms=['linux'])
24
# Test generic image creation fallback (by using NBD)
26
+ supported_platforms=['linux'],
25
#
27
+ required_fmts=['blkverify'])
28
29
with iotests.FilePath('img') as img_path, \
30
iotests.FilePath('mig_fifo') as fifo, \
26
--
31
--
27
2.29.2
32
2.38.1
28
33
29
34
diff view generated by jsdifflib
1
From: Michael Qiu <qiudayu@huayun.com>
1
From: Xiang Zheng <zhengxiang9@huawei.com>
2
2
3
Currently, if guest has workloads, IO thread will acquire aio_context
3
Currently we fill the VIRT_FLASH memory space with two 64MB NOR images
4
lock before do io_submit, it leads to segmentfault when do block commit
4
when using persistent UEFI variables on virt board. Actually we only use
5
after snapshot. Just like below:
5
a very small(non-zero) part of the memory while the rest significant
6
large(zero) part of memory is wasted.
6
7
7
Program received signal SIGSEGV, Segmentation fault.
8
So this patch checks the block status and only writes the non-zero part
9
into memory. This requires pflash devices to use sparse files for
10
backends.
8
11
9
[Switching to Thread 0x7f7c7d91f700 (LWP 99907)]
12
Signed-off-by: Xiang Zheng <zhengxiang9@huawei.com>
10
0x00005576d0f65aab in bdrv_mirror_top_pwritev at ../block/mirror.c:1437
11
1437 ../block/mirror.c: No such file or directory.
12
(gdb) p s->job
13
$17 = (MirrorBlockJob *) 0x0
14
(gdb) p s->stop
15
$18 = false
16
13
17
Call trace of IO thread:
14
[ kraxel: rebased to latest master ]
18
0 0x00005576d0f65aab in bdrv_mirror_top_pwritev at ../block/mirror.c:1437
19
1 0x00005576d0f7f3ab in bdrv_driver_pwritev at ../block/io.c:1174
20
2 0x00005576d0f8139d in bdrv_aligned_pwritev at ../block/io.c:1988
21
3 0x00005576d0f81b65 in bdrv_co_pwritev_part at ../block/io.c:2156
22
4 0x00005576d0f8e6b7 in blk_do_pwritev_part at ../block/block-backend.c:1260
23
5 0x00005576d0f8e84d in blk_aio_write_entry at ../block/block-backend.c:1476
24
...
25
15
26
Switch to qemu main thread:
16
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
27
0 0x00007f903be704ed in __lll_lock_wait at
17
Message-Id: <20221220084246.1984871-1-kraxel@redhat.com>
28
/lib/../lib64/libpthread.so.0
18
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
29
1 0x00007f903be6bde6 in _L_lock_941 at /lib/../lib64/libpthread.so.0
19
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
30
2 0x00007f903be6bcdf in pthread_mutex_lock at
31
/lib/../lib64/libpthread.so.0
32
3 0x0000564b21456889 in qemu_mutex_lock_impl at
33
../util/qemu-thread-posix.c:79
34
4 0x0000564b213af8a5 in block_job_add_bdrv at ../blockjob.c:224
35
5 0x0000564b213b00ad in block_job_create at ../blockjob.c:440
36
6 0x0000564b21357c0a in mirror_start_job at ../block/mirror.c:1622
37
7 0x0000564b2135a9af in commit_active_start at ../block/mirror.c:1867
38
8 0x0000564b2133d132 in qmp_block_commit at ../blockdev.c:2768
39
9 0x0000564b2141fef3 in qmp_marshal_block_commit at
40
qapi/qapi-commands-block-core.c:346
41
10 0x0000564b214503c9 in do_qmp_dispatch_bh at
42
../qapi/qmp-dispatch.c:110
43
11 0x0000564b21451996 in aio_bh_poll at ../util/async.c:164
44
12 0x0000564b2146018e in aio_dispatch at ../util/aio-posix.c:381
45
13 0x0000564b2145187e in aio_ctx_dispatch at ../util/async.c:306
46
14 0x00007f9040239049 in g_main_context_dispatch at
47
/lib/../lib64/libglib-2.0.so.0
48
15 0x0000564b21447368 in main_loop_wait at ../util/main-loop.c:232
49
16 0x0000564b21447368 in main_loop_wait at ../util/main-loop.c:255
50
17 0x0000564b21447368 in main_loop_wait at ../util/main-loop.c:531
51
18 0x0000564b212304e1 in qemu_main_loop at ../softmmu/runstate.c:721
52
19 0x0000564b20f7975e in main at ../softmmu/main.c:50
53
54
In IO thread when do bdrv_mirror_top_pwritev, the job is NULL, and stop field
55
is false, this means the MirrorBDSOpaque "s" object has not been initialized
56
yet, and this object is initialized by block_job_create(), but the initialize
57
process is stuck in acquiring the lock.
58
59
In this situation, IO thread come to bdrv_mirror_top_pwritev(),which means that
60
mirror-top node is already inserted into block graph, but its bs->opaque->job
61
is not initialized.
62
63
The root cause is that qemu main thread do release/acquire when hold the lock,
64
at the same time, IO thread get the lock after release stage, and the crash
65
occured.
66
67
Actually, in this situation, job->job.aio_context will not equal to
68
qemu_get_aio_context(), and will be the same as bs->aio_context,
69
thus, no need to release the lock, becasue bdrv_root_attach_child()
70
will not change the context.
71
72
This patch fix this issue.
73
74
Fixes: 132ada80 "block: Adjust AioContexts when attaching nodes"
75
76
Signed-off-by: Michael Qiu <qiudayu@huayun.com>
77
Message-Id: <20210203024059.52683-1-08005325@163.com>
78
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
20
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
79
---
21
---
80
blockjob.c | 8 ++++++--
22
hw/block/block.c | 36 +++++++++++++++++++++++++++++++++++-
81
1 file changed, 6 insertions(+), 2 deletions(-)
23
1 file changed, 35 insertions(+), 1 deletion(-)
82
24
83
diff --git a/blockjob.c b/blockjob.c
25
diff --git a/hw/block/block.c b/hw/block/block.c
84
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
85
--- a/blockjob.c
27
--- a/hw/block/block.c
86
+++ b/blockjob.c
28
+++ b/hw/block/block.c
87
@@ -XXX,XX +XXX,XX @@ int block_job_add_bdrv(BlockJob *job, const char *name, BlockDriverState *bs,
29
@@ -XXX,XX +XXX,XX @@
88
uint64_t perm, uint64_t shared_perm, Error **errp)
30
#include "qapi/error.h"
89
{
31
#include "qapi/qapi-types-block.h"
90
BdrvChild *c;
32
91
+ bool need_context_ops;
33
+/*
92
34
+ * Read the non-zeroes parts of @blk into @buf
93
bdrv_ref(bs);
35
+ * Reading all of the @blk is expensive if the zeroes parts of @blk
94
- if (job->job.aio_context != qemu_get_aio_context()) {
36
+ * is large enough. Therefore check the block status and only write
37
+ * the non-zeroes block into @buf.
38
+ *
39
+ * Return 0 on success, non-zero on error.
40
+ */
41
+static int blk_pread_nonzeroes(BlockBackend *blk, hwaddr size, void *buf)
42
+{
43
+ int ret;
44
+ int64_t bytes, offset = 0;
45
+ BlockDriverState *bs = blk_bs(blk);
95
+
46
+
96
+ need_context_ops = bdrv_get_aio_context(bs) != job->job.aio_context;
47
+ for (;;) {
48
+ bytes = MIN(size - offset, BDRV_REQUEST_MAX_SECTORS);
49
+ if (bytes <= 0) {
50
+ return 0;
51
+ }
52
+ ret = bdrv_block_status(bs, offset, bytes, &bytes, NULL, NULL);
53
+ if (ret < 0) {
54
+ return ret;
55
+ }
56
+ if (!(ret & BDRV_BLOCK_ZERO)) {
57
+ ret = bdrv_pread(bs->file, offset, bytes,
58
+ (uint8_t *) buf + offset, 0);
59
+ if (ret < 0) {
60
+ return ret;
61
+ }
62
+ }
63
+ offset += bytes;
64
+ }
65
+}
97
+
66
+
98
+ if (need_context_ops && job->job.aio_context != qemu_get_aio_context()) {
67
/*
99
aio_context_release(job->job.aio_context);
68
* Read the entire contents of @blk into @buf.
100
}
69
* @blk's contents must be @size bytes, and @size must be at most
101
c = bdrv_root_attach_child(bs, name, &child_job, 0,
70
@@ -XXX,XX +XXX,XX @@ bool blk_check_size_and_read_all(BlockBackend *blk, void *buf, hwaddr size,
102
job->job.aio_context, perm, shared_perm, job,
71
* block device and read only on demand.
103
errp);
72
*/
104
- if (job->job.aio_context != qemu_get_aio_context()) {
73
assert(size <= BDRV_REQUEST_MAX_BYTES);
105
+ if (need_context_ops && job->job.aio_context != qemu_get_aio_context()) {
74
- ret = blk_pread(blk, 0, size, buf, 0);
106
aio_context_acquire(job->job.aio_context);
75
+ ret = blk_pread_nonzeroes(blk, size, buf);
107
}
76
if (ret < 0) {
108
if (c == NULL) {
77
error_setg_errno(errp, -ret, "can't read block backend");
78
return false;
109
--
79
--
110
2.29.2
80
2.38.1
111
81
112
82
diff view generated by jsdifflib
New patch
1
From: Alberto Faria <afaria@redhat.com>
1
2
3
Clang has a generic __annotate__ attribute that can be used by
4
static analyzers to understand properties of functions and
5
analyze the control flow. Furthermore, unlike TSA annotations, the
6
__annotate__ attribute applies to function pointers as well.
7
8
As a first step towards static analysis of coroutine_fn markers,
9
attach the attribute to the marker when compiling with clang.
10
11
Signed-off-by: Alberto Faria <afaria@redhat.com>
12
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
13
Message-Id: <20221216110758.559947-2-pbonzini@redhat.com>
14
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
15
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
---
17
include/qemu/coroutine.h | 4 ++++
18
1 file changed, 4 insertions(+)
19
20
diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/include/qemu/coroutine.h
23
+++ b/include/qemu/coroutine.h
24
@@ -XXX,XX +XXX,XX @@
25
* ....
26
* }
27
*/
28
+#ifdef __clang__
29
+#define coroutine_fn __attribute__((__annotate__("coroutine_fn")))
30
+#else
31
#define coroutine_fn
32
+#endif
33
34
typedef struct Coroutine Coroutine;
35
36
--
37
2.38.1
diff view generated by jsdifflib
New patch
1
From: Alberto Faria <afaria@redhat.com>
1
2
3
Add more annotations to functions, describing valid and invalid
4
calls from coroutine to non-coroutine context.
5
6
When applied to a function, no_coroutine_fn advertises that it should
7
not be called from coroutine_fn functions. This can be because the
8
function blocks or, in the case of generated_co_wrapper, to enforce
9
that coroutine_fn functions directly call the coroutine_fn that backs
10
the generated_co_wrapper.
11
12
coroutine_mixed_fn instead is for function that can be called in
13
both coroutine and non-coroutine context, but will suspend when
14
called in coroutine context. Annotating them is a first step
15
towards enforcing that non-annotated functions are absolutely
16
not going to suspend.
17
18
These can be used for example with the vrc tool:
19
20
# find functions that *really* cannot be called from no_coroutine_fn
21
(vrc) load --loader clang libblock.fa.p/meson-generated_.._block_block-gen.c.o
22
(vrc) paths [no_coroutine_fn,!coroutine_mixed_fn]
23
bdrv_remove_persistent_dirty_bitmap
24
bdrv_create
25
bdrv_can_store_new_dirty_bitmap
26
27
# find how coroutine_fns end up calling a mixed function
28
(vrc) load --loader clang --force libblock.fa.p/*.c.o
29
(vrc) paths [coroutine_fn] [!no_coroutine_fn]* [coroutine_mixed_fn]
30
...
31
bdrv_pread <- vhdx_log_write <- vhdx_log_write_and_flush <- vhdx_co_writev
32
...
33
34
Signed-off-by: Alberto Faria <afaria@redhat.com>
35
[Rebase, add coroutine_mixed_fn. - Paolo]
36
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
37
Message-Id: <20221216110758.559947-3-pbonzini@redhat.com>
38
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
39
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
40
---
41
include/block/block-common.h | 11 ++++++----
42
include/qemu/coroutine.h | 39 ++++++++++++++++++++++++++++++++++++
43
2 files changed, 46 insertions(+), 4 deletions(-)
44
45
diff --git a/include/block/block-common.h b/include/block/block-common.h
46
index XXXXXXX..XXXXXXX 100644
47
--- a/include/block/block-common.h
48
+++ b/include/block/block-common.h
49
@@ -XXX,XX +XXX,XX @@
50
* - co_wrapper_mixed_bdrv_rdlock are co_wrapper_mixed functions but
51
* automatically take and release the graph rdlock when creating a new
52
* coroutine.
53
+ *
54
+ * These functions should not be called from a coroutine_fn; instead,
55
+ * call the wrapped function directly.
56
*/
57
-#define co_wrapper
58
-#define co_wrapper_mixed
59
-#define co_wrapper_bdrv_rdlock
60
-#define co_wrapper_mixed_bdrv_rdlock
61
+#define co_wrapper no_coroutine_fn
62
+#define co_wrapper_mixed no_coroutine_fn coroutine_mixed_fn
63
+#define co_wrapper_bdrv_rdlock no_coroutine_fn
64
+#define co_wrapper_mixed_bdrv_rdlock no_coroutine_fn coroutine_mixed_fn
65
66
#include "block/dirty-bitmap.h"
67
#include "block/blockjob.h"
68
diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h
69
index XXXXXXX..XXXXXXX 100644
70
--- a/include/qemu/coroutine.h
71
+++ b/include/qemu/coroutine.h
72
@@ -XXX,XX +XXX,XX @@
73
#define coroutine_fn
74
#endif
75
76
+/**
77
+ * Mark a function that can suspend when executed in coroutine context,
78
+ * but can handle running in non-coroutine context too.
79
+ */
80
+#ifdef __clang__
81
+#define coroutine_mixed_fn __attribute__((__annotate__("coroutine_mixed_fn")))
82
+#else
83
+#define coroutine_mixed_fn
84
+#endif
85
+
86
+/**
87
+ * Mark a function that should not be called from a coroutine context.
88
+ * Usually there will be an analogous, coroutine_fn function that should
89
+ * be used instead.
90
+ *
91
+ * When the function is also marked as coroutine_mixed_fn, the function should
92
+ * only be called if the caller does not know whether it is in coroutine
93
+ * context.
94
+ *
95
+ * Functions that are only no_coroutine_fn, on the other hand, should not
96
+ * be called from within coroutines at all. This for example includes
97
+ * functions that block.
98
+ *
99
+ * In the future it would be nice to enable compiler or static checker
100
+ * support for catching such errors. This annotation is the first step
101
+ * towards this, and in the meantime it serves as documentation.
102
+ *
103
+ * For example:
104
+ *
105
+ * static void no_coroutine_fn foo(void) {
106
+ * ....
107
+ * }
108
+ */
109
+#ifdef __clang__
110
+#define no_coroutine_fn __attribute__((__annotate__("no_coroutine_fn")))
111
+#else
112
+#define no_coroutine_fn
113
+#endif
114
+
115
typedef struct Coroutine Coroutine;
116
117
/**
118
--
119
2.38.1
diff view generated by jsdifflib
New patch
1
From: Paolo Bonzini <pbonzini@redhat.com>
1
2
3
qemu-io's do_co_pwrite_zeroes is reinventing the coroutine wrapper
4
blk_pwrite_zeroes. Just use the real thing directly.
5
6
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
7
Message-Id: <20221215130225.476477-1-pbonzini@redhat.com>
8
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
qemu-io-cmds.c | 57 +++++++++-----------------------------------------
12
1 file changed, 10 insertions(+), 47 deletions(-)
13
14
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/qemu-io-cmds.c
17
+++ b/qemu-io-cmds.c
18
@@ -XXX,XX +XXX,XX @@ static int do_pwrite(BlockBackend *blk, char *buf, int64_t offset,
19
return 1;
20
}
21
22
-typedef struct {
23
- BlockBackend *blk;
24
- int64_t offset;
25
- int64_t bytes;
26
- int64_t *total;
27
- int flags;
28
- int ret;
29
- bool done;
30
-} CoWriteZeroes;
31
-
32
-static void coroutine_fn co_pwrite_zeroes_entry(void *opaque)
33
-{
34
- CoWriteZeroes *data = opaque;
35
-
36
- data->ret = blk_co_pwrite_zeroes(data->blk, data->offset, data->bytes,
37
- data->flags);
38
- data->done = true;
39
- if (data->ret < 0) {
40
- *data->total = data->ret;
41
- return;
42
- }
43
-
44
- *data->total = data->bytes;
45
-}
46
-
47
-static int do_co_pwrite_zeroes(BlockBackend *blk, int64_t offset,
48
+static int do_pwrite_zeroes(BlockBackend *blk, int64_t offset,
49
int64_t bytes, int flags, int64_t *total)
50
{
51
- Coroutine *co;
52
- CoWriteZeroes data = {
53
- .blk = blk,
54
- .offset = offset,
55
- .bytes = bytes,
56
- .total = total,
57
- .flags = flags,
58
- .done = false,
59
- };
60
-
61
- co = qemu_coroutine_create(co_pwrite_zeroes_entry, &data);
62
- bdrv_coroutine_enter(blk_bs(blk), co);
63
- while (!data.done) {
64
- aio_poll(blk_get_aio_context(blk), true);
65
- }
66
- if (data.ret < 0) {
67
- return data.ret;
68
- } else {
69
- return 1;
70
+ int ret = blk_pwrite_zeroes(blk, offset, bytes,
71
+ flags | BDRV_REQ_ZERO_WRITE);
72
+
73
+ if (ret < 0) {
74
+ return ret;
75
}
76
+ *total = bytes;
77
+ return 1;
78
}
79
80
static int do_write_compressed(BlockBackend *blk, char *buf, int64_t offset,
81
@@ -XXX,XX +XXX,XX @@ static void write_help(void)
82
" -C, -- report statistics in a machine parsable format\n"
83
" -q, -- quiet mode, do not show I/O statistics\n"
84
" -u, -- with -z, allow unmapping\n"
85
-" -z, -- write zeroes using blk_co_pwrite_zeroes\n"
86
+" -z, -- write zeroes using blk_pwrite_zeroes\n"
87
"\n");
88
}
89
90
@@ -XXX,XX +XXX,XX @@ static int write_f(BlockBackend *blk, int argc, char **argv)
91
if (bflag) {
92
ret = do_save_vmstate(blk, buf, offset, count, &total);
93
} else if (zflag) {
94
- ret = do_co_pwrite_zeroes(blk, offset, count, flags, &total);
95
+ ret = do_pwrite_zeroes(blk, offset, count, flags, &total);
96
} else if (cflag) {
97
ret = do_write_compressed(blk, buf, offset, count, &total);
98
} else {
99
--
100
2.38.1
diff view generated by jsdifflib
New patch
1
From: Paolo Bonzini <pbonzini@redhat.com>
1
2
3
It has only one caller---inline it and remove the function.
4
5
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
6
Message-Id: <20221215130225.476477-2-pbonzini@redhat.com>
7
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
10
include/block/block-io.h | 5 -----
11
block.c | 6 ------
12
block/block-backend.c | 2 +-
13
3 files changed, 1 insertion(+), 12 deletions(-)
14
15
diff --git a/include/block/block-io.h b/include/block/block-io.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/block/block-io.h
18
+++ b/include/block/block-io.h
19
@@ -XXX,XX +XXX,XX @@ AioContext *coroutine_fn bdrv_co_enter(BlockDriverState *bs);
20
*/
21
void coroutine_fn bdrv_co_leave(BlockDriverState *bs, AioContext *old_ctx);
22
23
-/**
24
- * Transfer control to @co in the aio context of @bs
25
- */
26
-void bdrv_coroutine_enter(BlockDriverState *bs, Coroutine *co);
27
-
28
AioContext *child_of_bds_get_parent_aio_context(BdrvChild *c);
29
30
void bdrv_io_plug(BlockDriverState *bs);
31
diff --git a/block.c b/block.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/block.c
34
+++ b/block.c
35
@@ -XXX,XX +XXX,XX @@ void coroutine_fn bdrv_co_unlock(BlockDriverState *bs)
36
}
37
}
38
39
-void bdrv_coroutine_enter(BlockDriverState *bs, Coroutine *co)
40
-{
41
- IO_CODE();
42
- aio_co_enter(bdrv_get_aio_context(bs), co);
43
-}
44
-
45
static void bdrv_do_remove_aio_context_notifier(BdrvAioNotifier *ban)
46
{
47
GLOBAL_STATE_CODE();
48
diff --git a/block/block-backend.c b/block/block-backend.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/block/block-backend.c
51
+++ b/block/block-backend.c
52
@@ -XXX,XX +XXX,XX @@ static BlockAIOCB *blk_aio_prwv(BlockBackend *blk, int64_t offset,
53
acb->has_returned = false;
54
55
co = qemu_coroutine_create(co_entry, acb);
56
- bdrv_coroutine_enter(blk_bs(blk), co);
57
+ aio_co_enter(blk_get_aio_context(blk), co);
58
59
acb->has_returned = true;
60
if (acb->rwco.ret != NOT_DONE) {
61
--
62
2.38.1
diff view generated by jsdifflib
1
From: Roger Pau Monne <roger.pau@citrix.com>
1
In order to write the bitmap table to the image file, it is converted to
2
big endian. If the write fails, it is passed to clear_bitmap_table() to
3
free all of the clusters it had allocated before. However, if we don't
4
convert it back to native endianness first, we'll free things at a wrong
5
offset.
2
6
3
Linux blkfront expects both "discard-granularity" and
7
In practical terms, the offsets will be so high that we won't actually
4
"discard-alignment" present on xenbus in order to properly enable the
8
free any allocated clusters, but just run into an error, but in theory
5
feature, not exposing "discard-alignment" left some Linux blkfront
9
this can cause image corruption.
6
versions with a broken discard setup. This has also been addressed in
7
Linux with:
8
10
9
https://lore.kernel.org/lkml/20210118151528.81668-1-roger.pau@citrix.com/T/#u
11
Cc: qemu-stable@nongnu.org
10
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Fix QEMU to report a "discard-alignment" of 0, in order for it to work
13
Message-Id: <20230112191454.169353-2-kwolf@redhat.com>
12
with older Linux frontends.
14
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
13
15
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
14
Reported-by: Arthur Borsboom <arthurborsboom@gmail.com>
15
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
16
Message-Id: <20210118153330.82324-1-roger.pau@citrix.com>
17
Reviewed-by: Paul Durrant <paul@xen.org>
18
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
19
---
17
---
20
hw/block/xen-block.c | 1 +
18
block/qcow2-bitmap.c | 5 +++--
21
1 file changed, 1 insertion(+)
19
1 file changed, 3 insertions(+), 2 deletions(-)
22
20
23
diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c
21
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
24
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/block/xen-block.c
23
--- a/block/qcow2-bitmap.c
26
+++ b/hw/block/xen-block.c
24
+++ b/block/qcow2-bitmap.c
27
@@ -XXX,XX +XXX,XX @@ static void xen_block_realize(XenDevice *xendev, Error **errp)
25
@@ -XXX,XX +XXX,XX @@ static int update_header_sync(BlockDriverState *bs)
28
xen_device_backend_printf(xendev, "feature-discard", "%u", 1);
26
return bdrv_flush(bs->file->bs);
29
xen_device_backend_printf(xendev, "discard-granularity", "%u",
27
}
30
conf->discard_granularity);
28
31
+ xen_device_backend_printf(xendev, "discard-alignment", "%u", 0);
29
-static inline void bitmap_table_to_be(uint64_t *bitmap_table, size_t size)
30
+static inline void bitmap_table_bswap_be(uint64_t *bitmap_table, size_t size)
31
{
32
size_t i;
33
34
@@ -XXX,XX +XXX,XX @@ static int store_bitmap(BlockDriverState *bs, Qcow2Bitmap *bm, Error **errp)
35
goto fail;
32
}
36
}
33
37
34
xen_device_backend_printf(xendev, "feature-flush-cache", "%u", 1);
38
- bitmap_table_to_be(tb, tb_size);
39
+ bitmap_table_bswap_be(tb, tb_size);
40
ret = bdrv_pwrite(bs->file, tb_offset, tb_size * sizeof(tb[0]), tb, 0);
41
if (ret < 0) {
42
+ bitmap_table_bswap_be(tb, tb_size);
43
error_setg_errno(errp, -ret, "Failed to write bitmap '%s' to file",
44
bm_name);
45
goto fail;
35
--
46
--
36
2.29.2
47
2.38.1
37
48
38
49
diff view generated by jsdifflib
New patch
1
blk_unref() can't report any errors that happen while closing the image.
2
For example, if qcow2 hits an -ENOSPC error while writing out dirty
3
bitmaps when it's closed, it prints error messages to stderr, but
4
'qemu-img commit' won't see any error return value and will therefore
5
look successful with exit code 0.
1
6
7
In order to fix this, manually inactivate the image first before calling
8
blk_unref(). This already performs the operations that would be most
9
likely to fail while closing the image, but it can still return errors.
10
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Message-Id: <20230112191454.169353-3-kwolf@redhat.com>
13
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
---
16
qemu-img.c | 13 +++++++++++++
17
1 file changed, 13 insertions(+)
18
19
diff --git a/qemu-img.c b/qemu-img.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/qemu-img.c
22
+++ b/qemu-img.c
23
@@ -XXX,XX +XXX,XX @@ static BlockBackend *img_open(bool image_opts,
24
blk = img_open_file(filename, NULL, fmt, flags, writethrough, quiet,
25
force_share);
26
}
27
+
28
+ if (blk) {
29
+ blk_set_force_allow_inactivate(blk);
30
+ }
31
+
32
return blk;
33
}
34
35
@@ -XXX,XX +XXX,XX @@ unref_backing:
36
done:
37
qemu_progress_end();
38
39
+ /*
40
+ * Manually inactivate the image first because this way we can know whether
41
+ * an error occurred. blk_unref() doesn't tell us about failures.
42
+ */
43
+ ret = bdrv_inactivate_all();
44
+ if (ret < 0 && !local_err) {
45
+ error_setg_errno(&local_err, -ret, "Error while closing the image");
46
+ }
47
blk_unref(blk);
48
49
if (local_err) {
50
--
51
2.38.1
diff view generated by jsdifflib
1
Commit 357bda95 already tried to fix the order in monitor_cleanup() by
1
blk_unref() can't report any errors that happen while closing the image.
2
moving shutdown of the dispatcher coroutine further to the start.
2
For example, if qcow2 hits an -ENOSPC error while writing out dirty
3
However, it didn't go far enough:
3
bitmaps when it's closed, it prints error messages to stderr, but
4
'qemu-img bitmap' won't see any error return value and will therefore
5
look successful with exit code 0.
4
6
5
iothread_stop() makes sure that all pending work (bottom halves) in the
7
In order to fix this, manually inactivate the image first before calling
6
AioContext of the monitor iothread is completed. iothread_destroy()
8
blk_unref(). This already performs the operations that would be most
7
depends on this and fails an assertion if there is still a pending BH.
9
likely to fail while closing the image, but it can still return errors.
8
10
9
While the dispatcher coroutine is running, it will try to resume the
11
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1330
10
monitor after taking a request out of the queue, which involves a BH.
11
The dispatcher is run until it terminates in the AIO_WAIT_WHILE() loop.
12
However, adding new BHs between iothread_stop() and iothread_destroy()
13
is forbidden.
14
15
Fix this by stopping the dispatcher first before shutting down the other
16
parts of the monitor. This means we can now receive requests that aren't
17
handled any more when QEMU is shutting down, but this is unlikely to be
18
a problem for QMP clients.
19
20
Fixes: 357bda9590784ff75803d52de43150d4107ed98e
21
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
22
Message-Id: <20210212172028.288825-2-kwolf@redhat.com>
13
Message-Id: <20230112191454.169353-4-kwolf@redhat.com>
23
Tested-by: Markus Armbruster <armbru@redhat.com>
14
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
24
Reviewed-by: Markus Armbruster <armbru@redhat.com>
15
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
25
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
26
---
17
---
27
monitor/monitor.c | 25 +++++++++++++++----------
18
qemu-img.c | 11 +++++++++++
28
1 file changed, 15 insertions(+), 10 deletions(-)
19
1 file changed, 11 insertions(+)
29
20
30
diff --git a/monitor/monitor.c b/monitor/monitor.c
21
diff --git a/qemu-img.c b/qemu-img.c
31
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
32
--- a/monitor/monitor.c
23
--- a/qemu-img.c
33
+++ b/monitor/monitor.c
24
+++ b/qemu-img.c
34
@@ -XXX,XX +XXX,XX @@ void monitor_data_destroy(Monitor *mon)
25
@@ -XXX,XX +XXX,XX @@ static int img_bitmap(int argc, char **argv)
35
26
QSIMPLEQ_HEAD(, ImgBitmapAction) actions;
36
void monitor_cleanup(void)
27
ImgBitmapAction *act, *act_next;
37
{
28
const char *op;
38
- /*
29
+ int inactivate_ret;
39
- * We need to explicitly stop the I/O thread (but not destroy it),
30
40
- * clean up the monitor resources, then destroy the I/O thread since
31
QSIMPLEQ_INIT(&actions);
41
- * we need to unregister from chardev below in
32
42
- * monitor_data_destroy(), and chardev is not thread-safe yet
33
@@ -XXX,XX +XXX,XX @@ static int img_bitmap(int argc, char **argv)
43
- */
34
ret = 0;
44
- if (mon_iothread) {
35
45
- iothread_stop(mon_iothread);
36
out:
46
- }
47
-
48
/*
49
* The dispatcher needs to stop before destroying the monitor and
50
* the I/O thread.
51
@@ -XXX,XX +XXX,XX @@ void monitor_cleanup(void)
52
* eventually terminates. qemu_aio_context is automatically
53
* polled by calling AIO_WAIT_WHILE on it, but we must poll
54
* iohandler_ctx manually.
55
+ *
56
+ * Letting the iothread continue while shutting down the dispatcher
57
+ * means that new requests may still be coming in. This is okay,
58
+ * we'll just leave them in the queue without sending a response
59
+ * and monitor_data_destroy() will free them.
60
*/
61
qmp_dispatcher_co_shutdown = true;
62
if (!qatomic_xchg(&qmp_dispatcher_co_busy, true)) {
63
@@ -XXX,XX +XXX,XX @@ void monitor_cleanup(void)
64
(aio_poll(iohandler_get_aio_context(), false),
65
qatomic_mb_read(&qmp_dispatcher_co_busy)));
66
67
+ /*
37
+ /*
68
+ * We need to explicitly stop the I/O thread (but not destroy it),
38
+ * Manually inactivate the images first because this way we can know whether
69
+ * clean up the monitor resources, then destroy the I/O thread since
39
+ * an error occurred. blk_unref() doesn't tell us about failures.
70
+ * we need to unregister from chardev below in
71
+ * monitor_data_destroy(), and chardev is not thread-safe yet
72
+ */
40
+ */
73
+ if (mon_iothread) {
41
+ inactivate_ret = bdrv_inactivate_all();
74
+ iothread_stop(mon_iothread);
42
+ if (inactivate_ret < 0) {
43
+ error_report("Error while closing the image: %s", strerror(-inactivate_ret));
44
+ ret = 1;
75
+ }
45
+ }
76
+
46
+
77
/* Flush output buffers and destroy monitors */
47
blk_unref(src);
78
qemu_mutex_lock(&monitor_lock);
48
blk_unref(blk);
79
monitor_destroyed = true;
49
qemu_opts_del(opts);
80
--
50
--
81
2.29.2
51
2.38.1
82
52
83
53
diff view generated by jsdifflib
New patch
1
This tests that when an error happens while writing back bitmaps to the
2
image file in qcow2_inactivate(), 'qemu-img bitmap/commit' actually
3
return an error value in their exit code instead of making the operation
4
look successful to scripts.
1
5
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
Message-Id: <20230112191454.169353-5-kwolf@redhat.com>
8
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
.../qemu-iotests/tests/qemu-img-close-errors | 95 +++++++++++++++++++
12
.../tests/qemu-img-close-errors.out | 23 +++++
13
2 files changed, 118 insertions(+)
14
create mode 100755 tests/qemu-iotests/tests/qemu-img-close-errors
15
create mode 100644 tests/qemu-iotests/tests/qemu-img-close-errors.out
16
17
diff --git a/tests/qemu-iotests/tests/qemu-img-close-errors b/tests/qemu-iotests/tests/qemu-img-close-errors
18
new file mode 100755
19
index XXXXXXX..XXXXXXX
20
--- /dev/null
21
+++ b/tests/qemu-iotests/tests/qemu-img-close-errors
22
@@ -XXX,XX +XXX,XX @@
23
+#!/usr/bin/env bash
24
+# group: rw auto quick
25
+#
26
+# Check that errors while closing the image, in particular writing back dirty
27
+# bitmaps, is correctly reported with a failing qemu-img exit code.
28
+#
29
+# Copyright (C) 2023 Red Hat, Inc.
30
+#
31
+# This program is free software; you can redistribute it and/or modify
32
+# it under the terms of the GNU General Public License as published by
33
+# the Free Software Foundation; either version 2 of the License, or
34
+# (at your option) any later version.
35
+#
36
+# This program is distributed in the hope that it will be useful,
37
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
38
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39
+# GNU General Public License for more details.
40
+#
41
+# You should have received a copy of the GNU General Public License
42
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
43
+#
44
+
45
+# creator
46
+owner=kwolf@redhat.com
47
+
48
+seq="$(basename $0)"
49
+echo "QA output created by $seq"
50
+
51
+status=1    # failure is the default!
52
+
53
+_cleanup()
54
+{
55
+ _cleanup_test_img
56
+}
57
+trap "_cleanup; exit \$status" 0 1 2 3 15
58
+
59
+# get standard environment, filters and checks
60
+cd ..
61
+. ./common.rc
62
+. ./common.filter
63
+
64
+_supported_fmt qcow2
65
+_supported_proto generic
66
+
67
+size=1G
68
+
69
+# The error we are going to use is ENOSPC. Depending on how many bitmaps we
70
+# create in the backing file (and therefore increase the used up space), we get
71
+# failures in different places. With a low number, only merging the bitmap
72
+# fails, whereas with a higher number, already 'qemu-img commit' fails.
73
+for max_bitmap in 6 7; do
74
+ echo
75
+ echo "=== Test with $max_bitmap bitmaps ==="
76
+
77
+ TEST_IMG="$TEST_IMG.base" _make_test_img -q $size
78
+ for i in $(seq 1 $max_bitmap); do
79
+ $QEMU_IMG bitmap --add "$TEST_IMG.base" "stale-bitmap-$i"
80
+ done
81
+
82
+ # Simulate a block device of 128 MB by resizing the image file accordingly
83
+ # and then enforcing the size with the raw driver
84
+ truncate "$TEST_IMG.base" --size 128M
85
+ BASE_JSON='json:{
86
+ "driver": "qcow2",
87
+ "file": {
88
+ "driver": "raw",
89
+ "size": 134217728,
90
+ "file": {
91
+ "driver": "file",
92
+ "filename":"'"$TEST_IMG.base"'"
93
+ }
94
+ }
95
+ }'
96
+
97
+ _make_test_img -q -b "$BASE_JSON" -F $IMGFMT
98
+ $QEMU_IMG bitmap --add "$TEST_IMG" "good-bitmap"
99
+
100
+ $QEMU_IO -c 'write 0 126m' "$TEST_IMG" | _filter_qemu_io
101
+
102
+ $QEMU_IMG commit -d "$TEST_IMG" 2>&1 | _filter_generated_node_ids
103
+ echo "qemu-img commit exit code: ${PIPESTATUS[0]}"
104
+
105
+ $QEMU_IMG bitmap --add "$BASE_JSON" "good-bitmap"
106
+ echo "qemu-img bitmap --add exit code: $?"
107
+
108
+ $QEMU_IMG bitmap --merge "good-bitmap" -b "$TEST_IMG" "$BASE_JSON" \
109
+ "good-bitmap" 2>&1 | _filter_generated_node_ids
110
+ echo "qemu-img bitmap --merge exit code: ${PIPESTATUS[0]}"
111
+done
112
+
113
+# success, all done
114
+echo "*** done"
115
+rm -f $seq.full
116
+status=0
117
+
118
diff --git a/tests/qemu-iotests/tests/qemu-img-close-errors.out b/tests/qemu-iotests/tests/qemu-img-close-errors.out
119
new file mode 100644
120
index XXXXXXX..XXXXXXX
121
--- /dev/null
122
+++ b/tests/qemu-iotests/tests/qemu-img-close-errors.out
123
@@ -XXX,XX +XXX,XX @@
124
+QA output created by qemu-img-close-errors
125
+
126
+=== Test with 6 bitmaps ===
127
+wrote 132120576/132120576 bytes at offset 0
128
+126 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
129
+Image committed.
130
+qemu-img commit exit code: 0
131
+qemu-img bitmap --add exit code: 0
132
+qemu-img: Lost persistent bitmaps during inactivation of node 'NODE_NAME': Failed to write bitmap 'good-bitmap' to file: No space left on device
133
+qemu-img: Error while closing the image: Invalid argument
134
+qemu-img: Lost persistent bitmaps during inactivation of node 'NODE_NAME': Failed to write bitmap 'good-bitmap' to file: No space left on device
135
+qemu-img bitmap --merge exit code: 1
136
+
137
+=== Test with 7 bitmaps ===
138
+wrote 132120576/132120576 bytes at offset 0
139
+126 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
140
+qemu-img: Lost persistent bitmaps during inactivation of node 'NODE_NAME': Failed to write bitmap 'stale-bitmap-7' to file: No space left on device
141
+qemu-img: Lost persistent bitmaps during inactivation of node 'NODE_NAME': Failed to write bitmap 'stale-bitmap-7' to file: No space left on device
142
+qemu-img: Error while closing the image: Invalid argument
143
+qemu-img commit exit code: 1
144
+qemu-img bitmap --add exit code: 0
145
+qemu-img bitmap --merge exit code: 0
146
+*** done
147
--
148
2.38.1
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
Just omit the various 'return' when the return type is void.
4
5
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
Message-Id: <20230113204212.359076-2-kwolf@redhat.com>
8
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
scripts/block-coroutine-wrapper.py | 20 +++++++++++++++-----
12
1 file changed, 15 insertions(+), 5 deletions(-)
13
14
diff --git a/scripts/block-coroutine-wrapper.py b/scripts/block-coroutine-wrapper.py
15
index XXXXXXX..XXXXXXX 100644
16
--- a/scripts/block-coroutine-wrapper.py
17
+++ b/scripts/block-coroutine-wrapper.py
18
@@ -XXX,XX +XXX,XX @@ def __init__(self, return_type: str, name: str, args: str,
19
ctx = 'qemu_get_aio_context()'
20
self.ctx = ctx
21
22
+ self.get_result = 's->ret = '
23
+ self.ret = 'return s.ret;'
24
+ self.co_ret = 'return '
25
+ self.return_field = self.return_type + " ret;"
26
+ if self.return_type == 'void':
27
+ self.get_result = ''
28
+ self.ret = ''
29
+ self.co_ret = ''
30
+ self.return_field = ''
31
+
32
def gen_list(self, format: str) -> str:
33
return ', '.join(format.format_map(arg.__dict__) for arg in self.args)
34
35
@@ -XXX,XX +XXX,XX @@ def create_mixed_wrapper(func: FuncDecl) -> str:
36
{{
37
if (qemu_in_coroutine()) {{
38
{graph_assume_lock}
39
- return {name}({ func.gen_list('{name}') });
40
+ {func.co_ret}{name}({ func.gen_list('{name}') });
41
}} else {{
42
{struct_name} s = {{
43
.poll_state.ctx = {func.ctx},
44
@@ -XXX,XX +XXX,XX @@ def create_mixed_wrapper(func: FuncDecl) -> str:
45
s.poll_state.co = qemu_coroutine_create({name}_entry, &s);
46
47
bdrv_poll_co(&s.poll_state);
48
- return s.ret;
49
+ {func.ret}
50
}}
51
}}"""
52
53
@@ -XXX,XX +XXX,XX @@ def create_co_wrapper(func: FuncDecl) -> str:
54
s.poll_state.co = qemu_coroutine_create({name}_entry, &s);
55
56
bdrv_poll_co(&s.poll_state);
57
- return s.ret;
58
+ {func.ret}
59
}}"""
60
61
62
@@ -XXX,XX +XXX,XX @@ def gen_wrapper(func: FuncDecl) -> str:
63
64
typedef struct {struct_name} {{
65
BdrvPollCo poll_state;
66
- {func.return_type} ret;
67
+ {func.return_field}
68
{ func.gen_block(' {decl};') }
69
}} {struct_name};
70
71
@@ -XXX,XX +XXX,XX @@ def gen_wrapper(func: FuncDecl) -> str:
72
{struct_name} *s = opaque;
73
74
{graph_lock}
75
- s->ret = {name}({ func.gen_list('s->{name}') });
76
+ {func.get_result}{name}({ func.gen_list('s->{name}') });
77
{graph_unlock}
78
s->poll_state.in_progress = false;
79
80
--
81
2.38.1
diff view generated by jsdifflib
1
From: Alexander Bulekov <alxndr@bu.edu>
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
2
2
3
cmd_fis is mapped as DMA_DIRECTION_FROM_DEVICE, however, it is read
3
BlockDriver->bdrv_io_plug is categorized as IO callback, and it
4
from, and not written to anywhere. Fix the DMA_DIRECTION and mark
4
currently doesn't run in a coroutine. We should let it take a graph
5
cmd_fis as read-only in the code.
5
rdlock since the callback traverses the block nodes graph, which however
6
is only possible in a coroutine.
6
7
7
Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
8
The only caller of this function is blk_io_plug(), therefore make
8
Message-Id: <20210119164051.89268-1-alxndr@bu.edu>
9
blk_io_plug() a co_wrapper, so that we're always running in a coroutine
10
where the lock can be taken.
11
12
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
Message-Id: <20230113204212.359076-3-kwolf@redhat.com>
15
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
17
---
11
hw/ide/ahci.c | 12 ++++++------
18
include/block/block-io.h | 3 ++-
12
1 file changed, 6 insertions(+), 6 deletions(-)
19
include/block/block_int-common.h | 2 +-
20
include/sysemu/block-backend-io.h | 4 +++-
21
block/block-backend.c | 4 ++--
22
block/file-posix.c | 10 +++++-----
23
block/io.c | 8 ++++----
24
block/nvme.c | 4 ++--
25
7 files changed, 19 insertions(+), 16 deletions(-)
13
26
14
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
27
diff --git a/include/block/block-io.h b/include/block/block-io.h
15
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/ide/ahci.c
29
--- a/include/block/block-io.h
17
+++ b/hw/ide/ahci.c
30
+++ b/include/block/block-io.h
18
@@ -XXX,XX +XXX,XX @@ static void ahci_reset_port(AHCIState *s, int port)
31
@@ -XXX,XX +XXX,XX @@ void coroutine_fn bdrv_co_leave(BlockDriverState *bs, AioContext *old_ctx);
32
33
AioContext *child_of_bds_get_parent_aio_context(BdrvChild *c);
34
35
-void bdrv_io_plug(BlockDriverState *bs);
36
+void coroutine_fn bdrv_co_io_plug(BlockDriverState *bs);
37
+
38
void bdrv_io_unplug(BlockDriverState *bs);
39
40
bool coroutine_fn bdrv_co_can_store_new_dirty_bitmap(BlockDriverState *bs,
41
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
42
index XXXXXXX..XXXXXXX 100644
43
--- a/include/block/block_int-common.h
44
+++ b/include/block/block_int-common.h
45
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
46
void (*bdrv_debug_event)(BlockDriverState *bs, BlkdebugEvent event);
47
48
/* io queue for linux-aio */
49
- void (*bdrv_io_plug)(BlockDriverState *bs);
50
+ void coroutine_fn (*bdrv_co_io_plug)(BlockDriverState *bs);
51
void (*bdrv_io_unplug)(BlockDriverState *bs);
52
53
/**
54
diff --git a/include/sysemu/block-backend-io.h b/include/sysemu/block-backend-io.h
55
index XXXXXXX..XXXXXXX 100644
56
--- a/include/sysemu/block-backend-io.h
57
+++ b/include/sysemu/block-backend-io.h
58
@@ -XXX,XX +XXX,XX @@ void blk_iostatus_set_err(BlockBackend *blk, int error);
59
int blk_get_max_iov(BlockBackend *blk);
60
int blk_get_max_hw_iov(BlockBackend *blk);
61
62
-void blk_io_plug(BlockBackend *blk);
63
+void coroutine_fn blk_co_io_plug(BlockBackend *blk);
64
+void co_wrapper blk_io_plug(BlockBackend *blk);
65
+
66
void blk_io_unplug(BlockBackend *blk);
67
AioContext *blk_get_aio_context(BlockBackend *blk);
68
BlockAcctStats *blk_get_stats(BlockBackend *blk);
69
diff --git a/block/block-backend.c b/block/block-backend.c
70
index XXXXXXX..XXXXXXX 100644
71
--- a/block/block-backend.c
72
+++ b/block/block-backend.c
73
@@ -XXX,XX +XXX,XX @@ void blk_add_insert_bs_notifier(BlockBackend *blk, Notifier *notify)
74
notifier_list_add(&blk->insert_bs_notifiers, notify);
19
}
75
}
20
76
21
/* Buffer pretty output based on a raw FIS structure. */
77
-void blk_io_plug(BlockBackend *blk)
22
-static char *ahci_pretty_buffer_fis(uint8_t *fis, int cmd_len)
78
+void coroutine_fn blk_co_io_plug(BlockBackend *blk)
23
+static char *ahci_pretty_buffer_fis(const uint8_t *fis, int cmd_len)
24
{
79
{
25
int i;
80
BlockDriverState *bs = blk_bs(blk);
26
GString *s = g_string_new("FIS:");
81
IO_CODE();
27
@@ -XXX,XX +XXX,XX @@ static void execute_ncq_command(NCQTransferState *ncq_tfs)
82
83
if (bs) {
84
- bdrv_io_plug(bs);
85
+ bdrv_co_io_plug(bs);
86
}
28
}
87
}
29
88
30
89
diff --git a/block/file-posix.c b/block/file-posix.c
31
-static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis,
90
index XXXXXXX..XXXXXXX 100644
32
+static void process_ncq_command(AHCIState *s, int port, const uint8_t *cmd_fis,
91
--- a/block/file-posix.c
33
uint8_t slot)
92
+++ b/block/file-posix.c
93
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_pwritev(BlockDriverState *bs, int64_t offset,
94
return raw_co_prw(bs, offset, bytes, qiov, QEMU_AIO_WRITE);
95
}
96
97
-static void raw_aio_plug(BlockDriverState *bs)
98
+static void coroutine_fn raw_co_io_plug(BlockDriverState *bs)
34
{
99
{
35
AHCIDevice *ad = &s->dev[port];
100
BDRVRawState __attribute__((unused)) *s = bs->opaque;
36
- NCQFrame *ncq_fis = (NCQFrame*)cmd_fis;
101
#ifdef CONFIG_LINUX_AIO
37
+ const NCQFrame *ncq_fis = (NCQFrame *)cmd_fis;
102
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_file = {
38
uint8_t tag = ncq_fis->tag >> 3;
103
.bdrv_co_copy_range_from = raw_co_copy_range_from,
39
NCQTransferState *ncq_tfs = &ad->ncq_tfs[tag];
104
.bdrv_co_copy_range_to = raw_co_copy_range_to,
40
size_t size;
105
.bdrv_refresh_limits = raw_refresh_limits,
41
@@ -XXX,XX +XXX,XX @@ static AHCICmdHdr *get_cmd_header(AHCIState *s, uint8_t port, uint8_t slot)
106
- .bdrv_io_plug = raw_aio_plug,
107
+ .bdrv_co_io_plug = raw_co_io_plug,
108
.bdrv_io_unplug = raw_aio_unplug,
109
.bdrv_attach_aio_context = raw_aio_attach_aio_context,
110
111
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_device = {
112
.bdrv_co_copy_range_from = raw_co_copy_range_from,
113
.bdrv_co_copy_range_to = raw_co_copy_range_to,
114
.bdrv_refresh_limits = raw_refresh_limits,
115
- .bdrv_io_plug = raw_aio_plug,
116
+ .bdrv_co_io_plug = raw_co_io_plug,
117
.bdrv_io_unplug = raw_aio_unplug,
118
.bdrv_attach_aio_context = raw_aio_attach_aio_context,
119
120
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_cdrom = {
121
.bdrv_co_pwritev = raw_co_pwritev,
122
.bdrv_co_flush_to_disk = raw_co_flush_to_disk,
123
.bdrv_refresh_limits = raw_refresh_limits,
124
- .bdrv_io_plug = raw_aio_plug,
125
+ .bdrv_co_io_plug = raw_co_io_plug,
126
.bdrv_io_unplug = raw_aio_unplug,
127
.bdrv_attach_aio_context = raw_aio_attach_aio_context,
128
129
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_cdrom = {
130
.bdrv_co_pwritev = raw_co_pwritev,
131
.bdrv_co_flush_to_disk = raw_co_flush_to_disk,
132
.bdrv_refresh_limits = raw_refresh_limits,
133
- .bdrv_io_plug = raw_aio_plug,
134
+ .bdrv_co_io_plug = raw_co_io_plug,
135
.bdrv_io_unplug = raw_aio_unplug,
136
.bdrv_attach_aio_context = raw_aio_attach_aio_context,
137
138
diff --git a/block/io.c b/block/io.c
139
index XXXXXXX..XXXXXXX 100644
140
--- a/block/io.c
141
+++ b/block/io.c
142
@@ -XXX,XX +XXX,XX @@ void *qemu_try_blockalign0(BlockDriverState *bs, size_t size)
143
return mem;
42
}
144
}
43
145
44
static void handle_reg_h2d_fis(AHCIState *s, int port,
146
-void bdrv_io_plug(BlockDriverState *bs)
45
- uint8_t slot, uint8_t *cmd_fis)
147
+void coroutine_fn bdrv_co_io_plug(BlockDriverState *bs)
46
+ uint8_t slot, const uint8_t *cmd_fis)
47
{
148
{
48
IDEState *ide_state = &s->dev[port].port.ifs[0];
149
BdrvChild *child;
49
AHCICmdHdr *cmd = get_cmd_header(s, port, slot);
150
IO_CODE();
50
@@ -XXX,XX +XXX,XX @@ static int handle_cmd(AHCIState *s, int port, uint8_t slot)
151
51
tbl_addr = le64_to_cpu(cmd->tbl_addr);
152
QLIST_FOREACH(child, &bs->children, next) {
52
cmd_len = 0x80;
153
- bdrv_io_plug(child->bs);
53
cmd_fis = dma_memory_map(s->as, tbl_addr, &cmd_len,
154
+ bdrv_co_io_plug(child->bs);
54
- DMA_DIRECTION_FROM_DEVICE);
55
+ DMA_DIRECTION_TO_DEVICE);
56
if (!cmd_fis) {
57
trace_handle_cmd_badfis(s, port);
58
return -1;
59
@@ -XXX,XX +XXX,XX @@ static int handle_cmd(AHCIState *s, int port, uint8_t slot)
60
}
155
}
61
156
62
out:
157
if (qatomic_fetch_inc(&bs->io_plugged) == 0) {
63
- dma_memory_unmap(s->as, cmd_fis, cmd_len, DMA_DIRECTION_FROM_DEVICE,
158
BlockDriver *drv = bs->drv;
64
+ dma_memory_unmap(s->as, cmd_fis, cmd_len, DMA_DIRECTION_TO_DEVICE,
159
- if (drv && drv->bdrv_io_plug) {
65
cmd_len);
160
- drv->bdrv_io_plug(bs);
66
161
+ if (drv && drv->bdrv_co_io_plug) {
67
if (s->dev[port].port.ifs[0].status & (BUSY_STAT|DRQ_STAT)) {
162
+ drv->bdrv_co_io_plug(bs);
163
}
164
}
165
}
166
diff --git a/block/nvme.c b/block/nvme.c
167
index XXXXXXX..XXXXXXX 100644
168
--- a/block/nvme.c
169
+++ b/block/nvme.c
170
@@ -XXX,XX +XXX,XX @@ static void nvme_attach_aio_context(BlockDriverState *bs,
171
}
172
}
173
174
-static void nvme_aio_plug(BlockDriverState *bs)
175
+static void coroutine_fn nvme_co_io_plug(BlockDriverState *bs)
176
{
177
BDRVNVMeState *s = bs->opaque;
178
assert(!s->plugged);
179
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_nvme = {
180
.bdrv_detach_aio_context = nvme_detach_aio_context,
181
.bdrv_attach_aio_context = nvme_attach_aio_context,
182
183
- .bdrv_io_plug = nvme_aio_plug,
184
+ .bdrv_co_io_plug = nvme_co_io_plug,
185
.bdrv_io_unplug = nvme_aio_unplug,
186
187
.bdrv_register_buf = nvme_register_buf,
68
--
188
--
69
2.29.2
189
2.38.1
70
71
diff view generated by jsdifflib
New patch
1
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
2
3
BlockDriver->bdrv_io_unplug is categorized as IO callback, and it
4
currently doesn't run in a coroutine. We should let it take a graph
5
rdlock since the callback traverses the block nodes graph, which however
6
is only possible in a coroutine.
7
8
The only caller of this function is blk_io_unplug(), therefore make
9
blk_io_unplug() a co_wrapper, so that we're always running in a
10
coroutine where the lock can be taken.
11
12
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
Message-Id: <20230113204212.359076-4-kwolf@redhat.com>
15
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
---
18
include/block/block-io.h | 3 +--
19
include/block/block_int-common.h | 2 +-
20
include/sysemu/block-backend-io.h | 4 +++-
21
block/blkio.c | 4 ++--
22
block/block-backend.c | 4 ++--
23
block/file-posix.c | 10 +++++-----
24
block/io.c | 8 ++++----
25
block/nvme.c | 4 ++--
26
8 files changed, 20 insertions(+), 19 deletions(-)
27
28
diff --git a/include/block/block-io.h b/include/block/block-io.h
29
index XXXXXXX..XXXXXXX 100644
30
--- a/include/block/block-io.h
31
+++ b/include/block/block-io.h
32
@@ -XXX,XX +XXX,XX @@ void coroutine_fn bdrv_co_leave(BlockDriverState *bs, AioContext *old_ctx);
33
AioContext *child_of_bds_get_parent_aio_context(BdrvChild *c);
34
35
void coroutine_fn bdrv_co_io_plug(BlockDriverState *bs);
36
-
37
-void bdrv_io_unplug(BlockDriverState *bs);
38
+void coroutine_fn bdrv_co_io_unplug(BlockDriverState *bs);
39
40
bool coroutine_fn bdrv_co_can_store_new_dirty_bitmap(BlockDriverState *bs,
41
const char *name,
42
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
43
index XXXXXXX..XXXXXXX 100644
44
--- a/include/block/block_int-common.h
45
+++ b/include/block/block_int-common.h
46
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
47
48
/* io queue for linux-aio */
49
void coroutine_fn (*bdrv_co_io_plug)(BlockDriverState *bs);
50
- void (*bdrv_io_unplug)(BlockDriverState *bs);
51
+ void coroutine_fn (*bdrv_co_io_unplug)(BlockDriverState *bs);
52
53
/**
54
* bdrv_drain_begin is called if implemented in the beginning of a
55
diff --git a/include/sysemu/block-backend-io.h b/include/sysemu/block-backend-io.h
56
index XXXXXXX..XXXXXXX 100644
57
--- a/include/sysemu/block-backend-io.h
58
+++ b/include/sysemu/block-backend-io.h
59
@@ -XXX,XX +XXX,XX @@ int blk_get_max_hw_iov(BlockBackend *blk);
60
void coroutine_fn blk_co_io_plug(BlockBackend *blk);
61
void co_wrapper blk_io_plug(BlockBackend *blk);
62
63
-void blk_io_unplug(BlockBackend *blk);
64
+void coroutine_fn blk_co_io_unplug(BlockBackend *blk);
65
+void co_wrapper blk_io_unplug(BlockBackend *blk);
66
+
67
AioContext *blk_get_aio_context(BlockBackend *blk);
68
BlockAcctStats *blk_get_stats(BlockBackend *blk);
69
void *blk_aio_get(const AIOCBInfo *aiocb_info, BlockBackend *blk,
70
diff --git a/block/blkio.c b/block/blkio.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/block/blkio.c
73
+++ b/block/blkio.c
74
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn blkio_co_pwrite_zeroes(BlockDriverState *bs,
75
return cod.ret;
76
}
77
78
-static void blkio_io_unplug(BlockDriverState *bs)
79
+static void coroutine_fn blkio_co_io_unplug(BlockDriverState *bs)
80
{
81
BDRVBlkioState *s = bs->opaque;
82
83
@@ -XXX,XX +XXX,XX @@ static void blkio_refresh_limits(BlockDriverState *bs, Error **errp)
84
.bdrv_co_pwritev = blkio_co_pwritev, \
85
.bdrv_co_flush_to_disk = blkio_co_flush, \
86
.bdrv_co_pwrite_zeroes = blkio_co_pwrite_zeroes, \
87
- .bdrv_io_unplug = blkio_io_unplug, \
88
+ .bdrv_co_io_unplug = blkio_co_io_unplug, \
89
.bdrv_refresh_limits = blkio_refresh_limits, \
90
.bdrv_register_buf = blkio_register_buf, \
91
.bdrv_unregister_buf = blkio_unregister_buf, \
92
diff --git a/block/block-backend.c b/block/block-backend.c
93
index XXXXXXX..XXXXXXX 100644
94
--- a/block/block-backend.c
95
+++ b/block/block-backend.c
96
@@ -XXX,XX +XXX,XX @@ void coroutine_fn blk_co_io_plug(BlockBackend *blk)
97
}
98
}
99
100
-void blk_io_unplug(BlockBackend *blk)
101
+void coroutine_fn blk_co_io_unplug(BlockBackend *blk)
102
{
103
BlockDriverState *bs = blk_bs(blk);
104
IO_CODE();
105
106
if (bs) {
107
- bdrv_io_unplug(bs);
108
+ bdrv_co_io_unplug(bs);
109
}
110
}
111
112
diff --git a/block/file-posix.c b/block/file-posix.c
113
index XXXXXXX..XXXXXXX 100644
114
--- a/block/file-posix.c
115
+++ b/block/file-posix.c
116
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn raw_co_io_plug(BlockDriverState *bs)
117
#endif
118
}
119
120
-static void raw_aio_unplug(BlockDriverState *bs)
121
+static void coroutine_fn raw_co_io_unplug(BlockDriverState *bs)
122
{
123
BDRVRawState __attribute__((unused)) *s = bs->opaque;
124
#ifdef CONFIG_LINUX_AIO
125
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_file = {
126
.bdrv_co_copy_range_to = raw_co_copy_range_to,
127
.bdrv_refresh_limits = raw_refresh_limits,
128
.bdrv_co_io_plug = raw_co_io_plug,
129
- .bdrv_io_unplug = raw_aio_unplug,
130
+ .bdrv_co_io_unplug = raw_co_io_unplug,
131
.bdrv_attach_aio_context = raw_aio_attach_aio_context,
132
133
.bdrv_co_truncate = raw_co_truncate,
134
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_device = {
135
.bdrv_co_copy_range_to = raw_co_copy_range_to,
136
.bdrv_refresh_limits = raw_refresh_limits,
137
.bdrv_co_io_plug = raw_co_io_plug,
138
- .bdrv_io_unplug = raw_aio_unplug,
139
+ .bdrv_co_io_unplug = raw_co_io_unplug,
140
.bdrv_attach_aio_context = raw_aio_attach_aio_context,
141
142
.bdrv_co_truncate = raw_co_truncate,
143
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_cdrom = {
144
.bdrv_co_flush_to_disk = raw_co_flush_to_disk,
145
.bdrv_refresh_limits = raw_refresh_limits,
146
.bdrv_co_io_plug = raw_co_io_plug,
147
- .bdrv_io_unplug = raw_aio_unplug,
148
+ .bdrv_co_io_unplug = raw_co_io_unplug,
149
.bdrv_attach_aio_context = raw_aio_attach_aio_context,
150
151
.bdrv_co_truncate = raw_co_truncate,
152
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_cdrom = {
153
.bdrv_co_flush_to_disk = raw_co_flush_to_disk,
154
.bdrv_refresh_limits = raw_refresh_limits,
155
.bdrv_co_io_plug = raw_co_io_plug,
156
- .bdrv_io_unplug = raw_aio_unplug,
157
+ .bdrv_co_io_unplug = raw_co_io_unplug,
158
.bdrv_attach_aio_context = raw_aio_attach_aio_context,
159
160
.bdrv_co_truncate = raw_co_truncate,
161
diff --git a/block/io.c b/block/io.c
162
index XXXXXXX..XXXXXXX 100644
163
--- a/block/io.c
164
+++ b/block/io.c
165
@@ -XXX,XX +XXX,XX @@ void coroutine_fn bdrv_co_io_plug(BlockDriverState *bs)
166
}
167
}
168
169
-void bdrv_io_unplug(BlockDriverState *bs)
170
+void coroutine_fn bdrv_co_io_unplug(BlockDriverState *bs)
171
{
172
BdrvChild *child;
173
IO_CODE();
174
@@ -XXX,XX +XXX,XX @@ void bdrv_io_unplug(BlockDriverState *bs)
175
assert(bs->io_plugged);
176
if (qatomic_fetch_dec(&bs->io_plugged) == 1) {
177
BlockDriver *drv = bs->drv;
178
- if (drv && drv->bdrv_io_unplug) {
179
- drv->bdrv_io_unplug(bs);
180
+ if (drv && drv->bdrv_co_io_unplug) {
181
+ drv->bdrv_co_io_unplug(bs);
182
}
183
}
184
185
QLIST_FOREACH(child, &bs->children, next) {
186
- bdrv_io_unplug(child->bs);
187
+ bdrv_co_io_unplug(child->bs);
188
}
189
}
190
191
diff --git a/block/nvme.c b/block/nvme.c
192
index XXXXXXX..XXXXXXX 100644
193
--- a/block/nvme.c
194
+++ b/block/nvme.c
195
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn nvme_co_io_plug(BlockDriverState *bs)
196
s->plugged = true;
197
}
198
199
-static void nvme_aio_unplug(BlockDriverState *bs)
200
+static void coroutine_fn nvme_co_io_unplug(BlockDriverState *bs)
201
{
202
BDRVNVMeState *s = bs->opaque;
203
assert(s->plugged);
204
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_nvme = {
205
.bdrv_attach_aio_context = nvme_attach_aio_context,
206
207
.bdrv_co_io_plug = nvme_co_io_plug,
208
- .bdrv_io_unplug = nvme_aio_unplug,
209
+ .bdrv_co_io_unplug = nvme_co_io_unplug,
210
211
.bdrv_register_buf = nvme_register_buf,
212
.bdrv_unregister_buf = nvme_unregister_buf,
213
--
214
2.38.1
diff view generated by jsdifflib
New patch
1
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
2
3
bdrv_is_inserted() is categorized as an I/O function, and it currently
4
doesn't run in a coroutine. We should let it take a graph rdlock since
5
it traverses the block nodes graph, which however is only possible in a
6
coroutine.
7
8
Therefore turn it into a co_wrapper to move the actual function into a
9
coroutine where the lock can be taken.
10
11
At the same time, add also blk_is_inserted as co_wrapper_mixed, since it
12
is called in both coroutine and non-coroutine contexts.
13
14
Because now this function creates a new coroutine and polls, we need to
15
take the AioContext lock where it is missing, for the only reason that
16
internally c_w_mixed_bdrv_rdlock calls AIO_WAIT_WHILE and it expects to
17
release the AioContext lock. Once the rwlock is ultimated and placed in
18
every place it needs to be, we will poll using AIO_WAIT_WHILE_UNLOCKED
19
and remove the AioContext lock.
20
21
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
22
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
23
Message-Id: <20230113204212.359076-5-kwolf@redhat.com>
24
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
25
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
26
---
27
include/block/block-io.h | 5 ++++-
28
include/block/block_int-common.h | 2 +-
29
include/sysemu/block-backend-io.h | 5 ++++-
30
block.c | 8 ++++----
31
block/block-backend.c | 4 ++--
32
block/file-posix.c | 8 ++++----
33
block/io.c | 12 ++++++------
34
blockdev.c | 8 +++++++-
35
8 files changed, 32 insertions(+), 20 deletions(-)
36
37
diff --git a/include/block/block-io.h b/include/block/block-io.h
38
index XXXXXXX..XXXXXXX 100644
39
--- a/include/block/block-io.h
40
+++ b/include/block/block-io.h
41
@@ -XXX,XX +XXX,XX @@ bool bdrv_is_read_only(BlockDriverState *bs);
42
bool bdrv_is_writable(BlockDriverState *bs);
43
bool bdrv_is_sg(BlockDriverState *bs);
44
int bdrv_get_flags(BlockDriverState *bs);
45
-bool bdrv_is_inserted(BlockDriverState *bs);
46
+
47
+bool coroutine_fn bdrv_co_is_inserted(BlockDriverState *bs);
48
+bool co_wrapper bdrv_is_inserted(BlockDriverState *bs);
49
+
50
void bdrv_lock_medium(BlockDriverState *bs, bool locked);
51
void bdrv_eject(BlockDriverState *bs, bool eject_flag);
52
const char *bdrv_get_format_name(BlockDriverState *bs);
53
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
54
index XXXXXXX..XXXXXXX 100644
55
--- a/include/block/block_int-common.h
56
+++ b/include/block/block_int-common.h
57
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
58
BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos);
59
60
/* removable device specific */
61
- bool (*bdrv_is_inserted)(BlockDriverState *bs);
62
+ bool coroutine_fn (*bdrv_co_is_inserted)(BlockDriverState *bs);
63
void (*bdrv_eject)(BlockDriverState *bs, bool eject_flag);
64
void (*bdrv_lock_medium)(BlockDriverState *bs, bool locked);
65
66
diff --git a/include/sysemu/block-backend-io.h b/include/sysemu/block-backend-io.h
67
index XXXXXXX..XXXXXXX 100644
68
--- a/include/sysemu/block-backend-io.h
69
+++ b/include/sysemu/block-backend-io.h
70
@@ -XXX,XX +XXX,XX @@ BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf,
71
72
void blk_inc_in_flight(BlockBackend *blk);
73
void blk_dec_in_flight(BlockBackend *blk);
74
-bool blk_is_inserted(BlockBackend *blk);
75
+
76
+bool coroutine_fn blk_co_is_inserted(BlockBackend *blk);
77
+bool co_wrapper_mixed blk_is_inserted(BlockBackend *blk);
78
+
79
bool blk_is_available(BlockBackend *blk);
80
void blk_lock_medium(BlockBackend *blk, bool locked);
81
void blk_eject(BlockBackend *blk, bool eject_flag);
82
diff --git a/block.c b/block.c
83
index XXXXXXX..XXXXXXX 100644
84
--- a/block.c
85
+++ b/block.c
86
@@ -XXX,XX +XXX,XX @@ out:
87
/**
88
* Return TRUE if the media is present
89
*/
90
-bool bdrv_is_inserted(BlockDriverState *bs)
91
+bool coroutine_fn bdrv_co_is_inserted(BlockDriverState *bs)
92
{
93
BlockDriver *drv = bs->drv;
94
BdrvChild *child;
95
@@ -XXX,XX +XXX,XX @@ bool bdrv_is_inserted(BlockDriverState *bs)
96
if (!drv) {
97
return false;
98
}
99
- if (drv->bdrv_is_inserted) {
100
- return drv->bdrv_is_inserted(bs);
101
+ if (drv->bdrv_co_is_inserted) {
102
+ return drv->bdrv_co_is_inserted(bs);
103
}
104
QLIST_FOREACH(child, &bs->children, next) {
105
- if (!bdrv_is_inserted(child->bs)) {
106
+ if (!bdrv_co_is_inserted(child->bs)) {
107
return false;
108
}
109
}
110
diff --git a/block/block-backend.c b/block/block-backend.c
111
index XXXXXXX..XXXXXXX 100644
112
--- a/block/block-backend.c
113
+++ b/block/block-backend.c
114
@@ -XXX,XX +XXX,XX @@ void blk_activate(BlockBackend *blk, Error **errp)
115
bdrv_activate(bs, errp);
116
}
117
118
-bool blk_is_inserted(BlockBackend *blk)
119
+bool coroutine_fn blk_co_is_inserted(BlockBackend *blk)
120
{
121
BlockDriverState *bs = blk_bs(blk);
122
IO_CODE();
123
124
- return bs && bdrv_is_inserted(bs);
125
+ return bs && bdrv_co_is_inserted(bs);
126
}
127
128
bool blk_is_available(BlockBackend *blk)
129
diff --git a/block/file-posix.c b/block/file-posix.c
130
index XXXXXXX..XXXXXXX 100644
131
--- a/block/file-posix.c
132
+++ b/block/file-posix.c
133
@@ -XXX,XX +XXX,XX @@ out:
134
return prio;
135
}
136
137
-static bool cdrom_is_inserted(BlockDriverState *bs)
138
+static bool coroutine_fn cdrom_co_is_inserted(BlockDriverState *bs)
139
{
140
BDRVRawState *s = bs->opaque;
141
int ret;
142
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_cdrom = {
143
= raw_get_allocated_file_size,
144
145
/* removable device support */
146
- .bdrv_is_inserted = cdrom_is_inserted,
147
+ .bdrv_co_is_inserted = cdrom_co_is_inserted,
148
.bdrv_eject = cdrom_eject,
149
.bdrv_lock_medium = cdrom_lock_medium,
150
151
@@ -XXX,XX +XXX,XX @@ static int cdrom_reopen(BlockDriverState *bs)
152
return 0;
153
}
154
155
-static bool cdrom_is_inserted(BlockDriverState *bs)
156
+static bool coroutine_fn cdrom_co_is_inserted(BlockDriverState *bs)
157
{
158
return raw_getlength(bs) > 0;
159
}
160
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_cdrom = {
161
= raw_get_allocated_file_size,
162
163
/* removable device support */
164
- .bdrv_is_inserted = cdrom_is_inserted,
165
+ .bdrv_co_is_inserted = cdrom_co_is_inserted,
166
.bdrv_eject = cdrom_eject,
167
.bdrv_lock_medium = cdrom_lock_medium,
168
};
169
diff --git a/block/io.c b/block/io.c
170
index XXXXXXX..XXXXXXX 100644
171
--- a/block/io.c
172
+++ b/block/io.c
173
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_preadv_part(BdrvChild *child,
174
175
trace_bdrv_co_preadv_part(bs, offset, bytes, flags);
176
177
- if (!bdrv_is_inserted(bs)) {
178
+ if (!bdrv_co_is_inserted(bs)) {
179
return -ENOMEDIUM;
180
}
181
182
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pwritev_part(BdrvChild *child,
183
184
trace_bdrv_co_pwritev_part(child->bs, offset, bytes, flags);
185
186
- if (!bdrv_is_inserted(bs)) {
187
+ if (!bdrv_co_is_inserted(bs)) {
188
return -ENOMEDIUM;
189
}
190
191
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
192
193
bdrv_inc_in_flight(bs);
194
195
- if (!bdrv_is_inserted(bs) || bdrv_is_read_only(bs) ||
196
+ if (!bdrv_co_is_inserted(bs) || bdrv_is_read_only(bs) ||
197
bdrv_is_sg(bs)) {
198
goto early_exit;
199
}
200
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset,
201
BlockDriverState *bs = child->bs;
202
IO_CODE();
203
204
- if (!bs || !bs->drv || !bdrv_is_inserted(bs)) {
205
+ if (!bs || !bs->drv || !bdrv_co_is_inserted(bs)) {
206
return -ENOMEDIUM;
207
}
208
209
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_copy_range_internal(
210
assert(!(read_flags & BDRV_REQ_NO_WAIT));
211
assert(!(write_flags & BDRV_REQ_NO_WAIT));
212
213
- if (!dst || !dst->bs || !bdrv_is_inserted(dst->bs)) {
214
+ if (!dst || !dst->bs || !bdrv_co_is_inserted(dst->bs)) {
215
return -ENOMEDIUM;
216
}
217
ret = bdrv_check_request32(dst_offset, bytes, NULL, 0);
218
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_copy_range_internal(
219
return bdrv_co_pwrite_zeroes(dst, dst_offset, bytes, write_flags);
220
}
221
222
- if (!src || !src->bs || !bdrv_is_inserted(src->bs)) {
223
+ if (!src || !src->bs || !bdrv_co_is_inserted(src->bs)) {
224
return -ENOMEDIUM;
225
}
226
ret = bdrv_check_request32(src_offset, bytes, NULL, 0);
227
diff --git a/blockdev.c b/blockdev.c
228
index XXXXXXX..XXXXXXX 100644
229
--- a/blockdev.c
230
+++ b/blockdev.c
231
@@ -XXX,XX +XXX,XX @@ fail:
232
static BlockDriverState *qmp_get_root_bs(const char *name, Error **errp)
233
{
234
BlockDriverState *bs;
235
+ AioContext *aio_context;
236
237
bs = bdrv_lookup_bs(name, name, errp);
238
if (bs == NULL) {
239
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *qmp_get_root_bs(const char *name, Error **errp)
240
return NULL;
241
}
242
243
+ aio_context = bdrv_get_aio_context(bs);
244
+ aio_context_acquire(aio_context);
245
+
246
if (!bdrv_is_inserted(bs)) {
247
error_setg(errp, "Device has no medium");
248
- return NULL;
249
+ bs = NULL;
250
}
251
252
+ aio_context_release(aio_context);
253
+
254
return bs;
255
}
256
257
--
258
2.38.1
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
The name is not good, not the least because we are going to convert this
4
to a generated co_wrapper, which adds a _co infix after the first part
5
of the name.
6
7
No functional change intended.
8
9
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Message-Id: <20230113204212.359076-6-kwolf@redhat.com>
12
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
15
include/block/block_int-io.h | 2 +-
16
block.c | 8 ++++----
17
block/io.c | 8 +++++---
18
3 files changed, 10 insertions(+), 8 deletions(-)
19
20
diff --git a/include/block/block_int-io.h b/include/block/block_int-io.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/include/block/block_int-io.h
23
+++ b/include/block/block_int-io.h
24
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_copy_range_to(BdrvChild *src, int64_t src_offset,
25
BdrvRequestFlags read_flags,
26
BdrvRequestFlags write_flags);
27
28
-int refresh_total_sectors(BlockDriverState *bs, int64_t hint);
29
+int bdrv_refresh_total_sectors(BlockDriverState *bs, int64_t hint);
30
31
BdrvChild *bdrv_cow_child(BlockDriverState *bs);
32
BdrvChild *bdrv_filter_child(BlockDriverState *bs);
33
diff --git a/block.c b/block.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/block.c
36
+++ b/block.c
37
@@ -XXX,XX +XXX,XX @@ static int find_image_format(BlockBackend *file, const char *filename,
38
* Set the current 'total_sectors' value
39
* Return 0 on success, -errno on error.
40
*/
41
-int refresh_total_sectors(BlockDriverState *bs, int64_t hint)
42
+int bdrv_refresh_total_sectors(BlockDriverState *bs, int64_t hint)
43
{
44
BlockDriver *drv = bs->drv;
45
IO_CODE();
46
@@ -XXX,XX +XXX,XX @@ static int bdrv_open_driver(BlockDriverState *bs, BlockDriver *drv,
47
bs->supported_read_flags |= BDRV_REQ_REGISTERED_BUF;
48
bs->supported_write_flags |= BDRV_REQ_REGISTERED_BUF;
49
50
- ret = refresh_total_sectors(bs, bs->total_sectors);
51
+ ret = bdrv_refresh_total_sectors(bs, bs->total_sectors);
52
if (ret < 0) {
53
error_setg_errno(errp, -ret, "Could not refresh total sector count");
54
return ret;
55
@@ -XXX,XX +XXX,XX @@ int64_t bdrv_nb_sectors(BlockDriverState *bs)
56
return -ENOMEDIUM;
57
58
if (drv->has_variable_length) {
59
- int ret = refresh_total_sectors(bs, bs->total_sectors);
60
+ int ret = bdrv_refresh_total_sectors(bs, bs->total_sectors);
61
if (ret < 0) {
62
return ret;
63
}
64
@@ -XXX,XX +XXX,XX @@ int bdrv_activate(BlockDriverState *bs, Error **errp)
65
bdrv_dirty_bitmap_skip_store(bm, false);
66
}
67
68
- ret = refresh_total_sectors(bs, bs->total_sectors);
69
+ ret = bdrv_refresh_total_sectors(bs, bs->total_sectors);
70
if (ret < 0) {
71
bs->open_flags |= BDRV_O_INACTIVE;
72
error_setg_errno(errp, -ret, "Could not refresh total sector count");
73
diff --git a/block/io.c b/block/io.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/block/io.c
76
+++ b/block/io.c
77
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
78
goto out;
79
}
80
81
- ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS);
82
+ ret = bdrv_refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS);
83
if (ret < 0) {
84
error_setg_errno(errp, -ret, "Could not refresh total sector count");
85
} else {
86
offset = bs->total_sectors * BDRV_SECTOR_SIZE;
87
}
88
- /* It's possible that truncation succeeded but refresh_total_sectors
89
+ /*
90
+ * It's possible that truncation succeeded but bdrv_refresh_total_sectors
91
* failed, but the latter doesn't affect how we should finish the request.
92
- * Pass 0 as the last parameter so that dirty bitmaps etc. are handled. */
93
+ * Pass 0 as the last parameter so that dirty bitmaps etc. are handled.
94
+ */
95
bdrv_co_write_req_finish(child, offset - new_bytes, new_bytes, &req, 0);
96
97
out:
98
--
99
2.38.1
diff view generated by jsdifflib
1
From: Maxim Levitsky <mlevitsk@redhat.com>
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
2
2
3
This function wraps bdrv_co_delete_file for the common case of removing a file,
3
BlockDriver->bdrv_getlength is categorized as IO callback, and it
4
which was just created by format driver, on an error condition.
4
currently doesn't run in a coroutine. We should let it take a graph
5
rdlock since the callback traverses the block nodes graph, which however
6
is only possible in a coroutine.
5
7
6
It hides the -ENOTSUPP error, and reports all other errors otherwise.
8
Therefore turn it into a co_wrapper to move the actual function into a
9
coroutine where the lock can be taken.
7
10
8
Use it in luks driver
11
Because now this function creates a new coroutine and polls, we need to
12
take the AioContext lock where it is missing, for the only reason that
13
internally co_wrapper calls AIO_WAIT_WHILE and it expects to release the
14
AioContext lock.
9
15
10
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
16
This is especially messy when a co_wrapper creates a coroutine and polls
11
Reviewed-by: Alberto Garcia <berto@igalia.com>
17
in bdrv_open_driver, because this function has so many callers in so
12
Message-Id: <20201217170904.946013-3-mlevitsk@redhat.com>
18
many context that it can easily lead to deadlocks. Therefore the new
13
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
19
rule for bdrv_open_driver is that the caller must always hold the
20
AioContext lock of the given bs (except if it is a coroutine), because
21
the function calls bdrv_refresh_total_sectors() which is now a
22
co_wrapper.
23
24
Once the rwlock is ultimated and placed in every place it needs to be,
25
we will poll using AIO_WAIT_WHILE_UNLOCKED and remove the AioContext
26
lock.
27
28
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
29
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
30
Message-Id: <20230113204212.359076-7-kwolf@redhat.com>
31
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
32
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
---
33
---
16
include/block/block.h | 1 +
34
include/block/block-io.h | 8 ++++--
17
block.c | 22 ++++++++++++++++++++++
35
include/block/block_int-common.h | 2 +-
18
block/crypto.c | 15 ++-------------
36
include/block/block_int-io.h | 5 +++-
19
3 files changed, 25 insertions(+), 13 deletions(-)
37
include/sysemu/block-backend-io.h | 10 ++++++--
38
block.c | 32 +++++++++++++++++------
39
block/blkdebug.c | 6 ++---
40
block/blkio.c | 6 ++---
41
block/blklogwrites.c | 6 ++---
42
block/blkreplay.c | 6 ++---
43
block/blkverify.c | 6 ++---
44
block/block-backend.c | 10 +++++---
45
block/commit.c | 4 +--
46
block/copy-on-read.c | 6 ++---
47
block/crypto.c | 6 ++---
48
block/curl.c | 10 ++++----
49
block/file-posix.c | 42 +++++++++++++++----------------
50
block/file-win32.c | 8 +++---
51
block/filter-compress.c | 6 ++---
52
block/gluster.c | 12 ++++-----
53
block/iscsi.c | 10 ++++----
54
block/mirror.c | 4 +--
55
block/nbd.c | 8 +++---
56
block/null.c | 6 ++---
57
block/nvme.c | 6 ++---
58
block/preallocate.c | 10 ++++----
59
block/qed.c | 4 +--
60
block/quorum.c | 8 +++---
61
block/raw-format.c | 6 ++---
62
block/rbd.c | 4 +--
63
block/replication.c | 6 ++---
64
block/ssh.c | 4 +--
65
block/throttle.c | 6 ++---
66
hw/scsi/scsi-disk.c | 5 ++++
67
tests/unit/test-block-iothread.c | 3 +++
68
block/meson.build | 1 +
69
35 files changed, 161 insertions(+), 121 deletions(-)
20
70
21
diff --git a/include/block/block.h b/include/block/block.h
71
diff --git a/include/block/block-io.h b/include/block/block-io.h
22
index XXXXXXX..XXXXXXX 100644
72
index XXXXXXX..XXXXXXX 100644
23
--- a/include/block/block.h
73
--- a/include/block/block-io.h
24
+++ b/include/block/block.h
74
+++ b/include/block/block-io.h
25
@@ -XXX,XX +XXX,XX @@ int bdrv_freeze_backing_chain(BlockDriverState *bs, BlockDriverState *base,
75
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
26
Error **errp);
76
PreallocMode prealloc, BdrvRequestFlags flags,
27
void bdrv_unfreeze_backing_chain(BlockDriverState *bs, BlockDriverState *base);
77
Error **errp);
28
int coroutine_fn bdrv_co_delete_file(BlockDriverState *bs, Error **errp);
78
29
+void coroutine_fn bdrv_co_delete_file_noerr(BlockDriverState *bs);
79
-int64_t bdrv_nb_sectors(BlockDriverState *bs);
30
80
-int64_t bdrv_getlength(BlockDriverState *bs);
31
81
+int64_t coroutine_fn bdrv_co_nb_sectors(BlockDriverState *bs);
32
typedef struct BdrvCheckResult {
82
+int64_t co_wrapper_mixed bdrv_nb_sectors(BlockDriverState *bs);
83
+
84
+int64_t coroutine_fn bdrv_co_getlength(BlockDriverState *bs);
85
+int64_t co_wrapper_mixed bdrv_getlength(BlockDriverState *bs);
86
+
87
int64_t bdrv_get_allocated_file_size(BlockDriverState *bs);
88
BlockMeasureInfo *bdrv_measure(BlockDriver *drv, QemuOpts *opts,
89
BlockDriverState *in_bs, Error **errp);
90
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
91
index XXXXXXX..XXXXXXX 100644
92
--- a/include/block/block_int-common.h
93
+++ b/include/block/block_int-common.h
94
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
95
int coroutine_fn (*bdrv_co_truncate)(BlockDriverState *bs, int64_t offset,
96
bool exact, PreallocMode prealloc,
97
BdrvRequestFlags flags, Error **errp);
98
- int64_t (*bdrv_getlength)(BlockDriverState *bs);
99
+ int64_t coroutine_fn (*bdrv_co_getlength)(BlockDriverState *bs);
100
int64_t (*bdrv_get_allocated_file_size)(BlockDriverState *bs);
101
BlockMeasureInfo *(*bdrv_measure)(QemuOpts *opts, BlockDriverState *in_bs,
102
Error **errp);
103
diff --git a/include/block/block_int-io.h b/include/block/block_int-io.h
104
index XXXXXXX..XXXXXXX 100644
105
--- a/include/block/block_int-io.h
106
+++ b/include/block/block_int-io.h
107
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_copy_range_to(BdrvChild *src, int64_t src_offset,
108
BdrvRequestFlags read_flags,
109
BdrvRequestFlags write_flags);
110
111
-int bdrv_refresh_total_sectors(BlockDriverState *bs, int64_t hint);
112
+int coroutine_fn bdrv_co_refresh_total_sectors(BlockDriverState *bs,
113
+ int64_t hint);
114
+int co_wrapper_mixed
115
+bdrv_refresh_total_sectors(BlockDriverState *bs, int64_t hint);
116
117
BdrvChild *bdrv_cow_child(BlockDriverState *bs);
118
BdrvChild *bdrv_filter_child(BlockDriverState *bs);
119
diff --git a/include/sysemu/block-backend-io.h b/include/sysemu/block-backend-io.h
120
index XXXXXXX..XXXXXXX 100644
121
--- a/include/sysemu/block-backend-io.h
122
+++ b/include/sysemu/block-backend-io.h
123
@@ -XXX,XX +XXX,XX @@ bool co_wrapper_mixed blk_is_inserted(BlockBackend *blk);
124
bool blk_is_available(BlockBackend *blk);
125
void blk_lock_medium(BlockBackend *blk, bool locked);
126
void blk_eject(BlockBackend *blk, bool eject_flag);
127
-int64_t blk_getlength(BlockBackend *blk);
128
+
129
+int64_t coroutine_fn blk_co_getlength(BlockBackend *blk);
130
+int64_t co_wrapper_mixed blk_getlength(BlockBackend *blk);
131
+
132
void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr);
133
-int64_t blk_nb_sectors(BlockBackend *blk);
134
+
135
+int64_t coroutine_fn blk_co_nb_sectors(BlockBackend *blk);
136
+int64_t co_wrapper_mixed blk_nb_sectors(BlockBackend *blk);
137
+
138
void *blk_try_blockalign(BlockBackend *blk, size_t size);
139
void *blk_blockalign(BlockBackend *blk, size_t size);
140
bool blk_is_writable(BlockBackend *blk);
33
diff --git a/block.c b/block.c
141
diff --git a/block.c b/block.c
34
index XXXXXXX..XXXXXXX 100644
142
index XXXXXXX..XXXXXXX 100644
35
--- a/block.c
143
--- a/block.c
36
+++ b/block.c
144
+++ b/block.c
37
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_delete_file(BlockDriverState *bs, Error **errp)
145
@@ -XXX,XX +XXX,XX @@ static int find_image_format(BlockBackend *file, const char *filename,
146
* Set the current 'total_sectors' value
147
* Return 0 on success, -errno on error.
148
*/
149
-int bdrv_refresh_total_sectors(BlockDriverState *bs, int64_t hint)
150
+int coroutine_fn bdrv_co_refresh_total_sectors(BlockDriverState *bs,
151
+ int64_t hint)
152
{
153
BlockDriver *drv = bs->drv;
154
IO_CODE();
155
@@ -XXX,XX +XXX,XX @@ int bdrv_refresh_total_sectors(BlockDriverState *bs, int64_t hint)
156
return -ENOMEDIUM;
157
}
158
159
- /* Do not attempt drv->bdrv_getlength() on scsi-generic devices */
160
+ /* Do not attempt drv->bdrv_co_getlength() on scsi-generic devices */
161
if (bdrv_is_sg(bs))
162
return 0;
163
164
/* query actual device if possible, otherwise just trust the hint */
165
- if (drv->bdrv_getlength) {
166
- int64_t length = drv->bdrv_getlength(bs);
167
+ if (drv->bdrv_co_getlength) {
168
+ int64_t length = drv->bdrv_co_getlength(bs);
169
if (length < 0) {
170
return length;
171
}
172
@@ -XXX,XX +XXX,XX @@ out:
173
g_free(gen_node_name);
174
}
175
176
+/*
177
+ * The caller must always hold @bs AioContext lock, because this function calls
178
+ * bdrv_refresh_total_sectors() which polls when called from non-coroutine
179
+ * context.
180
+ */
181
static int bdrv_open_driver(BlockDriverState *bs, BlockDriver *drv,
182
const char *node_name, QDict *options,
183
int open_flags, Error **errp)
184
@@ -XXX,XX +XXX,XX @@ out:
185
* The reference parameter may be used to specify an existing block device which
186
* should be opened. If specified, neither options nor a filename may be given,
187
* nor can an existing BDS be reused (that is, *pbs has to be NULL).
188
+ *
189
+ * The caller must always hold @filename AioContext lock, because this
190
+ * function eventually calls bdrv_refresh_total_sectors() which polls
191
+ * when called from non-coroutine context.
192
*/
193
static BlockDriverState *bdrv_open_inherit(const char *filename,
194
const char *reference,
195
@@ -XXX,XX +XXX,XX @@ close_and_fail:
196
return NULL;
197
}
198
199
+/*
200
+ * The caller must always hold @filename AioContext lock, because this
201
+ * function eventually calls bdrv_refresh_total_sectors() which polls
202
+ * when called from non-coroutine context.
203
+ */
204
BlockDriverState *bdrv_open(const char *filename, const char *reference,
205
QDict *options, int flags, Error **errp)
206
{
207
@@ -XXX,XX +XXX,XX @@ BlockMeasureInfo *bdrv_measure(BlockDriver *drv, QemuOpts *opts,
208
/**
209
* Return number of sectors on success, -errno on error.
210
*/
211
-int64_t bdrv_nb_sectors(BlockDriverState *bs)
212
+int64_t coroutine_fn bdrv_co_nb_sectors(BlockDriverState *bs)
213
{
214
BlockDriver *drv = bs->drv;
215
IO_CODE();
216
@@ -XXX,XX +XXX,XX @@ int64_t bdrv_nb_sectors(BlockDriverState *bs)
217
return -ENOMEDIUM;
218
219
if (drv->has_variable_length) {
220
- int ret = bdrv_refresh_total_sectors(bs, bs->total_sectors);
221
+ int ret = bdrv_co_refresh_total_sectors(bs, bs->total_sectors);
222
if (ret < 0) {
223
return ret;
224
}
225
@@ -XXX,XX +XXX,XX @@ int64_t bdrv_nb_sectors(BlockDriverState *bs)
226
* Return length in bytes on success, -errno on error.
227
* The length is always a multiple of BDRV_SECTOR_SIZE.
228
*/
229
-int64_t bdrv_getlength(BlockDriverState *bs)
230
+int64_t coroutine_fn bdrv_co_getlength(BlockDriverState *bs)
231
{
232
- int64_t ret = bdrv_nb_sectors(bs);
233
+ int64_t ret;
234
IO_CODE();
235
236
+ ret = bdrv_co_nb_sectors(bs);
237
if (ret < 0) {
238
return ret;
239
}
240
diff --git a/block/blkdebug.c b/block/blkdebug.c
241
index XXXXXXX..XXXXXXX 100644
242
--- a/block/blkdebug.c
243
+++ b/block/blkdebug.c
244
@@ -XXX,XX +XXX,XX @@ static bool blkdebug_debug_is_suspended(BlockDriverState *bs, const char *tag)
245
return false;
246
}
247
248
-static int64_t blkdebug_getlength(BlockDriverState *bs)
249
+static int64_t coroutine_fn blkdebug_co_getlength(BlockDriverState *bs)
250
{
251
- return bdrv_getlength(bs->file->bs);
252
+ return bdrv_co_getlength(bs->file->bs);
253
}
254
255
static void blkdebug_refresh_filename(BlockDriverState *bs)
256
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_blkdebug = {
257
.bdrv_reopen_prepare = blkdebug_reopen_prepare,
258
.bdrv_child_perm = blkdebug_child_perm,
259
260
- .bdrv_getlength = blkdebug_getlength,
261
+ .bdrv_co_getlength = blkdebug_co_getlength,
262
.bdrv_refresh_filename = blkdebug_refresh_filename,
263
.bdrv_refresh_limits = blkdebug_refresh_limits,
264
265
diff --git a/block/blkio.c b/block/blkio.c
266
index XXXXXXX..XXXXXXX 100644
267
--- a/block/blkio.c
268
+++ b/block/blkio.c
269
@@ -XXX,XX +XXX,XX @@ static void blkio_close(BlockDriverState *bs)
270
}
271
}
272
273
-static int64_t blkio_getlength(BlockDriverState *bs)
274
+static int64_t coroutine_fn blkio_co_getlength(BlockDriverState *bs)
275
{
276
BDRVBlkioState *s = bs->opaque;
277
uint64_t capacity;
278
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn blkio_truncate(BlockDriverState *bs, int64_t offset,
279
return -ENOTSUP;
280
}
281
282
- current_length = blkio_getlength(bs);
283
+ current_length = blkio_co_getlength(bs);
284
285
if (offset > current_length) {
286
error_setg(errp, "Cannot grow device");
287
@@ -XXX,XX +XXX,XX @@ static void blkio_refresh_limits(BlockDriverState *bs, Error **errp)
288
.instance_size = sizeof(BDRVBlkioState), \
289
.bdrv_file_open = blkio_file_open, \
290
.bdrv_close = blkio_close, \
291
- .bdrv_getlength = blkio_getlength, \
292
+ .bdrv_co_getlength = blkio_co_getlength, \
293
.bdrv_co_truncate = blkio_truncate, \
294
.bdrv_get_info = blkio_get_info, \
295
.bdrv_attach_aio_context = blkio_attach_aio_context, \
296
diff --git a/block/blklogwrites.c b/block/blklogwrites.c
297
index XXXXXXX..XXXXXXX 100644
298
--- a/block/blklogwrites.c
299
+++ b/block/blklogwrites.c
300
@@ -XXX,XX +XXX,XX @@ static void blk_log_writes_close(BlockDriverState *bs)
301
s->log_file = NULL;
302
}
303
304
-static int64_t blk_log_writes_getlength(BlockDriverState *bs)
305
+static int64_t coroutine_fn blk_log_writes_co_getlength(BlockDriverState *bs)
306
{
307
- return bdrv_getlength(bs->file->bs);
308
+ return bdrv_co_getlength(bs->file->bs);
309
}
310
311
static void blk_log_writes_child_perm(BlockDriverState *bs, BdrvChild *c,
312
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_blk_log_writes = {
313
314
.bdrv_open = blk_log_writes_open,
315
.bdrv_close = blk_log_writes_close,
316
- .bdrv_getlength = blk_log_writes_getlength,
317
+ .bdrv_co_getlength = blk_log_writes_co_getlength,
318
.bdrv_child_perm = blk_log_writes_child_perm,
319
.bdrv_refresh_limits = blk_log_writes_refresh_limits,
320
321
diff --git a/block/blkreplay.c b/block/blkreplay.c
322
index XXXXXXX..XXXXXXX 100644
323
--- a/block/blkreplay.c
324
+++ b/block/blkreplay.c
325
@@ -XXX,XX +XXX,XX @@ fail:
38
return ret;
326
return ret;
39
}
327
}
40
328
41
+void coroutine_fn bdrv_co_delete_file_noerr(BlockDriverState *bs)
329
-static int64_t blkreplay_getlength(BlockDriverState *bs)
42
+{
330
+static int64_t coroutine_fn blkreplay_co_getlength(BlockDriverState *bs)
43
+ Error *local_err = NULL;
331
{
44
+ int ret;
332
- return bdrv_getlength(bs->file->bs);
333
+ return bdrv_co_getlength(bs->file->bs);
334
}
335
336
/* This bh is used for synchronization of return from coroutines.
337
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_blkreplay = {
338
339
.bdrv_open = blkreplay_open,
340
.bdrv_child_perm = bdrv_default_perms,
341
- .bdrv_getlength = blkreplay_getlength,
342
+ .bdrv_co_getlength = blkreplay_co_getlength,
343
344
.bdrv_co_preadv = blkreplay_co_preadv,
345
.bdrv_co_pwritev = blkreplay_co_pwritev,
346
diff --git a/block/blkverify.c b/block/blkverify.c
347
index XXXXXXX..XXXXXXX 100644
348
--- a/block/blkverify.c
349
+++ b/block/blkverify.c
350
@@ -XXX,XX +XXX,XX @@ static void blkverify_close(BlockDriverState *bs)
351
s->test_file = NULL;
352
}
353
354
-static int64_t blkverify_getlength(BlockDriverState *bs)
355
+static int64_t coroutine_fn blkverify_co_getlength(BlockDriverState *bs)
356
{
357
BDRVBlkverifyState *s = bs->opaque;
358
359
- return bdrv_getlength(s->test_file->bs);
360
+ return bdrv_co_getlength(s->test_file->bs);
361
}
362
363
static void coroutine_fn blkverify_do_test_req(void *opaque)
364
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_blkverify = {
365
.bdrv_file_open = blkverify_open,
366
.bdrv_close = blkverify_close,
367
.bdrv_child_perm = bdrv_default_perms,
368
- .bdrv_getlength = blkverify_getlength,
369
+ .bdrv_co_getlength = blkverify_co_getlength,
370
.bdrv_refresh_filename = blkverify_refresh_filename,
371
.bdrv_dirname = blkverify_dirname,
372
373
diff --git a/block/block-backend.c b/block/block-backend.c
374
index XXXXXXX..XXXXXXX 100644
375
--- a/block/block-backend.c
376
+++ b/block/block-backend.c
377
@@ -XXX,XX +XXX,XX @@ BlockAIOCB *blk_aio_pwrite_zeroes(BlockBackend *blk, int64_t offset,
378
flags | BDRV_REQ_ZERO_WRITE, cb, opaque);
379
}
380
381
-int64_t blk_getlength(BlockBackend *blk)
382
+int64_t coroutine_fn blk_co_getlength(BlockBackend *blk)
383
{
384
IO_CODE();
45
+
385
+
46
+ if (!bs) {
386
if (!blk_is_available(blk)) {
47
+ return;
387
return -ENOMEDIUM;
48
+ }
388
}
389
390
- return bdrv_getlength(blk_bs(blk));
391
+ return bdrv_co_getlength(blk_bs(blk));
392
}
393
394
void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr)
395
@@ -XXX,XX +XXX,XX @@ void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr)
396
}
397
}
398
399
-int64_t blk_nb_sectors(BlockBackend *blk)
400
+int64_t coroutine_fn blk_co_nb_sectors(BlockBackend *blk)
401
{
402
IO_CODE();
49
+
403
+
50
+ ret = bdrv_co_delete_file(bs, &local_err);
404
if (!blk_is_available(blk)) {
51
+ /*
405
return -ENOMEDIUM;
52
+ * ENOTSUP will happen if the block driver doesn't support
406
}
53
+ * the 'bdrv_co_delete_file' interface. This is a predictable
407
54
+ * scenario and shouldn't be reported back to the user.
408
- return bdrv_nb_sectors(blk_bs(blk));
55
+ */
409
+ return bdrv_co_nb_sectors(blk_bs(blk));
56
+ if (ret == -ENOTSUP) {
410
}
57
+ error_free(local_err);
411
58
+ } else if (ret < 0) {
412
BlockAIOCB *blk_aio_preadv(BlockBackend *blk, int64_t offset,
59
+ error_report_err(local_err);
413
diff --git a/block/commit.c b/block/commit.c
60
+ }
414
index XXXXXXX..XXXXXXX 100644
61
+}
415
--- a/block/commit.c
62
+
416
+++ b/block/commit.c
63
/**
417
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn commit_run(Job *job, Error **errp)
64
* Try to get @bs's logical and physical block size.
418
QEMU_AUTO_VFREE void *buf = NULL;
65
* On success, store them in @bsz struct and return 0.
419
int64_t len, base_len;
420
421
- len = blk_getlength(s->top);
422
+ len = blk_co_getlength(s->top);
423
if (len < 0) {
424
return len;
425
}
426
job_progress_set_remaining(&s->common.job, len);
427
428
- base_len = blk_getlength(s->base);
429
+ base_len = blk_co_getlength(s->base);
430
if (base_len < 0) {
431
return base_len;
432
}
433
diff --git a/block/copy-on-read.c b/block/copy-on-read.c
434
index XXXXXXX..XXXXXXX 100644
435
--- a/block/copy-on-read.c
436
+++ b/block/copy-on-read.c
437
@@ -XXX,XX +XXX,XX @@ static void cor_child_perm(BlockDriverState *bs, BdrvChild *c,
438
}
439
440
441
-static int64_t cor_getlength(BlockDriverState *bs)
442
+static int64_t coroutine_fn cor_co_getlength(BlockDriverState *bs)
443
{
444
- return bdrv_getlength(bs->file->bs);
445
+ return bdrv_co_getlength(bs->file->bs);
446
}
447
448
449
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_copy_on_read = {
450
.bdrv_close = cor_close,
451
.bdrv_child_perm = cor_child_perm,
452
453
- .bdrv_getlength = cor_getlength,
454
+ .bdrv_co_getlength = cor_co_getlength,
455
456
.bdrv_co_preadv_part = cor_co_preadv_part,
457
.bdrv_co_pwritev_part = cor_co_pwritev_part,
66
diff --git a/block/crypto.c b/block/crypto.c
458
diff --git a/block/crypto.c b/block/crypto.c
67
index XXXXXXX..XXXXXXX 100644
459
index XXXXXXX..XXXXXXX 100644
68
--- a/block/crypto.c
460
--- a/block/crypto.c
69
+++ b/block/crypto.c
461
+++ b/block/crypto.c
462
@@ -XXX,XX +XXX,XX @@ static void block_crypto_refresh_limits(BlockDriverState *bs, Error **errp)
463
}
464
465
466
-static int64_t block_crypto_getlength(BlockDriverState *bs)
467
+static int64_t coroutine_fn block_crypto_co_getlength(BlockDriverState *bs)
468
{
469
BlockCrypto *crypto = bs->opaque;
470
- int64_t len = bdrv_getlength(bs->file->bs);
471
+ int64_t len = bdrv_co_getlength(bs->file->bs);
472
473
uint64_t offset = qcrypto_block_get_payload_offset(crypto->block);
474
assert(offset < INT64_MAX);
475
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_crypto_luks = {
476
.bdrv_refresh_limits = block_crypto_refresh_limits,
477
.bdrv_co_preadv = block_crypto_co_preadv,
478
.bdrv_co_pwritev = block_crypto_co_pwritev,
479
- .bdrv_getlength = block_crypto_getlength,
480
+ .bdrv_co_getlength = block_crypto_co_getlength,
481
.bdrv_measure = block_crypto_measure,
482
.bdrv_get_info = block_crypto_get_info_luks,
483
.bdrv_get_specific_info = block_crypto_get_specific_info_luks,
484
diff --git a/block/curl.c b/block/curl.c
485
index XXXXXXX..XXXXXXX 100644
486
--- a/block/curl.c
487
+++ b/block/curl.c
488
@@ -XXX,XX +XXX,XX @@ static void curl_close(BlockDriverState *bs)
489
g_free(s->proxypassword);
490
}
491
492
-static int64_t curl_getlength(BlockDriverState *bs)
493
+static int64_t coroutine_fn curl_co_getlength(BlockDriverState *bs)
494
{
495
BDRVCURLState *s = bs->opaque;
496
return s->len;
497
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_http = {
498
.bdrv_parse_filename = curl_parse_filename,
499
.bdrv_file_open = curl_open,
500
.bdrv_close = curl_close,
501
- .bdrv_getlength = curl_getlength,
502
+ .bdrv_co_getlength = curl_co_getlength,
503
504
.bdrv_co_preadv = curl_co_preadv,
505
506
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_https = {
507
.bdrv_parse_filename = curl_parse_filename,
508
.bdrv_file_open = curl_open,
509
.bdrv_close = curl_close,
510
- .bdrv_getlength = curl_getlength,
511
+ .bdrv_co_getlength = curl_co_getlength,
512
513
.bdrv_co_preadv = curl_co_preadv,
514
515
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_ftp = {
516
.bdrv_parse_filename = curl_parse_filename,
517
.bdrv_file_open = curl_open,
518
.bdrv_close = curl_close,
519
- .bdrv_getlength = curl_getlength,
520
+ .bdrv_co_getlength = curl_co_getlength,
521
522
.bdrv_co_preadv = curl_co_preadv,
523
524
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_ftps = {
525
.bdrv_parse_filename = curl_parse_filename,
526
.bdrv_file_open = curl_open,
527
.bdrv_close = curl_close,
528
- .bdrv_getlength = curl_getlength,
529
+ .bdrv_co_getlength = curl_co_getlength,
530
531
.bdrv_co_preadv = curl_co_preadv,
532
533
diff --git a/block/file-posix.c b/block/file-posix.c
534
index XXXXXXX..XXXXXXX 100644
535
--- a/block/file-posix.c
536
+++ b/block/file-posix.c
537
@@ -XXX,XX +XXX,XX @@ static int fd_open(BlockDriverState *bs)
538
return -EIO;
539
}
540
541
-static int64_t raw_getlength(BlockDriverState *bs);
542
+static int64_t coroutine_fn raw_co_getlength(BlockDriverState *bs);
543
544
typedef struct RawPosixAIOData {
545
BlockDriverState *bs;
546
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
547
}
548
549
if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
550
- int64_t cur_length = raw_getlength(bs);
551
+ int64_t cur_length = raw_co_getlength(bs);
552
553
if (offset != cur_length && exact) {
554
error_setg(errp, "Cannot resize device files");
555
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
556
}
557
558
#ifdef __OpenBSD__
559
-static int64_t raw_getlength(BlockDriverState *bs)
560
+static int64_t coroutine_fn raw_co_getlength(BlockDriverState *bs)
561
{
562
BDRVRawState *s = bs->opaque;
563
int fd = s->fd;
564
@@ -XXX,XX +XXX,XX @@ static int64_t raw_getlength(BlockDriverState *bs)
565
return st.st_size;
566
}
567
#elif defined(__NetBSD__)
568
-static int64_t raw_getlength(BlockDriverState *bs)
569
+static int64_t coroutine_fn raw_co_getlength(BlockDriverState *bs)
570
{
571
BDRVRawState *s = bs->opaque;
572
int fd = s->fd;
573
@@ -XXX,XX +XXX,XX @@ static int64_t raw_getlength(BlockDriverState *bs)
574
return st.st_size;
575
}
576
#elif defined(__sun__)
577
-static int64_t raw_getlength(BlockDriverState *bs)
578
+static int64_t coroutine_fn raw_co_getlength(BlockDriverState *bs)
579
{
580
BDRVRawState *s = bs->opaque;
581
struct dk_minfo minfo;
582
@@ -XXX,XX +XXX,XX @@ static int64_t raw_getlength(BlockDriverState *bs)
583
return size;
584
}
585
#elif defined(CONFIG_BSD)
586
-static int64_t raw_getlength(BlockDriverState *bs)
587
+static int64_t coroutine_fn raw_co_getlength(BlockDriverState *bs)
588
{
589
BDRVRawState *s = bs->opaque;
590
int fd = s->fd;
591
@@ -XXX,XX +XXX,XX @@ again:
592
return size;
593
}
594
#else
595
-static int64_t raw_getlength(BlockDriverState *bs)
596
+static int64_t coroutine_fn raw_co_getlength(BlockDriverState *bs)
597
{
598
BDRVRawState *s = bs->opaque;
599
int ret;
600
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_block_status(BlockDriverState *bs,
601
* round up if necessary.
602
*/
603
if (!QEMU_IS_ALIGNED(*pnum, bs->bl.request_alignment)) {
604
- int64_t file_length = raw_getlength(bs);
605
+ int64_t file_length = raw_co_getlength(bs);
606
if (file_length > 0) {
607
/* Ignore errors, this is just a safeguard */
608
assert(hole == file_length);
609
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_block_status(BlockDriverState *bs,
610
611
#if defined(__linux__)
612
/* Verify that the file is not in the page cache */
613
-static void check_cache_dropped(BlockDriverState *bs, Error **errp)
614
+static void coroutine_fn check_cache_dropped(BlockDriverState *bs, Error **errp)
615
{
616
const size_t window_size = 128 * 1024 * 1024;
617
BDRVRawState *s = bs->opaque;
618
@@ -XXX,XX +XXX,XX @@ static void check_cache_dropped(BlockDriverState *bs, Error **errp)
619
page_size = sysconf(_SC_PAGESIZE);
620
vec = g_malloc(DIV_ROUND_UP(window_size, page_size));
621
622
- end = raw_getlength(bs);
623
+ end = raw_co_getlength(bs);
624
625
for (offset = 0; offset < end; offset += window_size) {
626
void *new_window;
627
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_file = {
628
.bdrv_co_io_unplug = raw_co_io_unplug,
629
.bdrv_attach_aio_context = raw_aio_attach_aio_context,
630
631
- .bdrv_co_truncate = raw_co_truncate,
632
- .bdrv_getlength = raw_getlength,
633
+ .bdrv_co_truncate = raw_co_truncate,
634
+ .bdrv_co_getlength = raw_co_getlength,
635
.bdrv_get_info = raw_get_info,
636
.bdrv_get_allocated_file_size
637
= raw_get_allocated_file_size,
638
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_device = {
639
.bdrv_co_io_unplug = raw_co_io_unplug,
640
.bdrv_attach_aio_context = raw_aio_attach_aio_context,
641
642
- .bdrv_co_truncate = raw_co_truncate,
643
- .bdrv_getlength    = raw_getlength,
644
+ .bdrv_co_truncate = raw_co_truncate,
645
+ .bdrv_co_getlength = raw_co_getlength,
646
.bdrv_get_info = raw_get_info,
647
.bdrv_get_allocated_file_size
648
= raw_get_allocated_file_size,
649
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_cdrom = {
650
.bdrv_co_io_unplug = raw_co_io_unplug,
651
.bdrv_attach_aio_context = raw_aio_attach_aio_context,
652
653
- .bdrv_co_truncate = raw_co_truncate,
654
- .bdrv_getlength = raw_getlength,
655
- .has_variable_length = true,
656
+ .bdrv_co_truncate = raw_co_truncate,
657
+ .bdrv_co_getlength = raw_co_getlength,
658
+ .has_variable_length = true,
659
.bdrv_get_allocated_file_size
660
= raw_get_allocated_file_size,
661
662
@@ -XXX,XX +XXX,XX @@ static int cdrom_reopen(BlockDriverState *bs)
663
664
static bool coroutine_fn cdrom_co_is_inserted(BlockDriverState *bs)
665
{
666
- return raw_getlength(bs) > 0;
667
+ return raw_co_getlength(bs) > 0;
668
}
669
670
static void cdrom_eject(BlockDriverState *bs, bool eject_flag)
671
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_cdrom = {
672
.bdrv_co_io_unplug = raw_co_io_unplug,
673
.bdrv_attach_aio_context = raw_aio_attach_aio_context,
674
675
- .bdrv_co_truncate = raw_co_truncate,
676
- .bdrv_getlength = raw_getlength,
677
- .has_variable_length = true,
678
+ .bdrv_co_truncate = raw_co_truncate,
679
+ .bdrv_co_getlength = raw_co_getlength,
680
+ .has_variable_length = true,
681
.bdrv_get_allocated_file_size
682
= raw_get_allocated_file_size,
683
684
diff --git a/block/file-win32.c b/block/file-win32.c
685
index XXXXXXX..XXXXXXX 100644
686
--- a/block/file-win32.c
687
+++ b/block/file-win32.c
688
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
689
return 0;
690
}
691
692
-static int64_t raw_getlength(BlockDriverState *bs)
693
+static int64_t coroutine_fn raw_co_getlength(BlockDriverState *bs)
694
{
695
BDRVRawState *s = bs->opaque;
696
LARGE_INTEGER l;
697
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_file = {
698
.bdrv_aio_flush = raw_aio_flush,
699
700
.bdrv_co_truncate = raw_co_truncate,
701
- .bdrv_getlength    = raw_getlength,
702
+ .bdrv_co_getlength = raw_co_getlength,
703
.bdrv_get_allocated_file_size
704
= raw_get_allocated_file_size,
705
706
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_device = {
707
.bdrv_detach_aio_context = raw_detach_aio_context,
708
.bdrv_attach_aio_context = raw_attach_aio_context,
709
710
- .bdrv_getlength = raw_getlength,
711
- .has_variable_length = true,
712
+ .bdrv_co_getlength = raw_co_getlength,
713
+ .has_variable_length = true,
714
715
.bdrv_get_allocated_file_size
716
= raw_get_allocated_file_size,
717
diff --git a/block/filter-compress.c b/block/filter-compress.c
718
index XXXXXXX..XXXXXXX 100644
719
--- a/block/filter-compress.c
720
+++ b/block/filter-compress.c
721
@@ -XXX,XX +XXX,XX @@ static int compress_open(BlockDriverState *bs, QDict *options, int flags,
722
}
723
724
725
-static int64_t compress_getlength(BlockDriverState *bs)
726
+static int64_t coroutine_fn compress_co_getlength(BlockDriverState *bs)
727
{
728
- return bdrv_getlength(bs->file->bs);
729
+ return bdrv_co_getlength(bs->file->bs);
730
}
731
732
733
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_compress = {
734
.bdrv_open = compress_open,
735
.bdrv_child_perm = bdrv_default_perms,
736
737
- .bdrv_getlength = compress_getlength,
738
+ .bdrv_co_getlength = compress_co_getlength,
739
740
.bdrv_co_preadv_part = compress_co_preadv_part,
741
.bdrv_co_pwritev_part = compress_co_pwritev_part,
742
diff --git a/block/gluster.c b/block/gluster.c
743
index XXXXXXX..XXXXXXX 100644
744
--- a/block/gluster.c
745
+++ b/block/gluster.c
746
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qemu_gluster_co_pdiscard(BlockDriverState *bs,
747
}
748
#endif
749
750
-static int64_t qemu_gluster_getlength(BlockDriverState *bs)
751
+static int64_t coroutine_fn qemu_gluster_co_getlength(BlockDriverState *bs)
752
{
753
BDRVGlusterState *s = bs->opaque;
754
int64_t ret;
755
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qemu_gluster_co_block_status(BlockDriverState *bs,
756
* round up if necessary.
757
*/
758
if (!QEMU_IS_ALIGNED(*pnum, bs->bl.request_alignment)) {
759
- int64_t file_length = qemu_gluster_getlength(bs);
760
+ int64_t file_length = qemu_gluster_co_getlength(bs);
761
if (file_length > 0) {
762
/* Ignore errors, this is just a safeguard */
763
assert(hole == file_length);
764
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_gluster = {
765
.bdrv_close = qemu_gluster_close,
766
.bdrv_co_create = qemu_gluster_co_create,
767
.bdrv_co_create_opts = qemu_gluster_co_create_opts,
768
- .bdrv_getlength = qemu_gluster_getlength,
769
+ .bdrv_co_getlength = qemu_gluster_co_getlength,
770
.bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
771
.bdrv_co_truncate = qemu_gluster_co_truncate,
772
.bdrv_co_readv = qemu_gluster_co_readv,
773
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_gluster_tcp = {
774
.bdrv_close = qemu_gluster_close,
775
.bdrv_co_create = qemu_gluster_co_create,
776
.bdrv_co_create_opts = qemu_gluster_co_create_opts,
777
- .bdrv_getlength = qemu_gluster_getlength,
778
+ .bdrv_co_getlength = qemu_gluster_co_getlength,
779
.bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
780
.bdrv_co_truncate = qemu_gluster_co_truncate,
781
.bdrv_co_readv = qemu_gluster_co_readv,
782
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_gluster_unix = {
783
.bdrv_close = qemu_gluster_close,
784
.bdrv_co_create = qemu_gluster_co_create,
785
.bdrv_co_create_opts = qemu_gluster_co_create_opts,
786
- .bdrv_getlength = qemu_gluster_getlength,
787
+ .bdrv_co_getlength = qemu_gluster_co_getlength,
788
.bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
789
.bdrv_co_truncate = qemu_gluster_co_truncate,
790
.bdrv_co_readv = qemu_gluster_co_readv,
791
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_gluster_rdma = {
792
.bdrv_close = qemu_gluster_close,
793
.bdrv_co_create = qemu_gluster_co_create,
794
.bdrv_co_create_opts = qemu_gluster_co_create_opts,
795
- .bdrv_getlength = qemu_gluster_getlength,
796
+ .bdrv_co_getlength = qemu_gluster_co_getlength,
797
.bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
798
.bdrv_co_truncate = qemu_gluster_co_truncate,
799
.bdrv_co_readv = qemu_gluster_co_readv,
800
diff --git a/block/iscsi.c b/block/iscsi.c
801
index XXXXXXX..XXXXXXX 100644
802
--- a/block/iscsi.c
803
+++ b/block/iscsi.c
804
@@ -XXX,XX +XXX,XX @@ static BlockAIOCB *iscsi_aio_ioctl(BlockDriverState *bs,
805
806
#endif
807
808
-static int64_t
809
-iscsi_getlength(BlockDriverState *bs)
810
+static int64_t coroutine_fn
811
+iscsi_co_getlength(BlockDriverState *bs)
812
{
813
IscsiLun *iscsilun = bs->opaque;
814
int64_t len;
815
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn iscsi_co_truncate(BlockDriverState *bs, int64_t offset,
816
return -EIO;
817
}
818
819
- cur_length = iscsi_getlength(bs);
820
+ cur_length = iscsi_co_getlength(bs);
821
if (offset != cur_length && exact) {
822
error_setg(errp, "Cannot resize iSCSI devices");
823
return -ENOTSUP;
824
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_iscsi = {
825
.bdrv_reopen_commit = iscsi_reopen_commit,
826
.bdrv_co_invalidate_cache = iscsi_co_invalidate_cache,
827
828
- .bdrv_getlength = iscsi_getlength,
829
+ .bdrv_co_getlength = iscsi_co_getlength,
830
.bdrv_get_info = iscsi_get_info,
831
.bdrv_co_truncate = iscsi_co_truncate,
832
.bdrv_refresh_limits = iscsi_refresh_limits,
833
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_iser = {
834
.bdrv_reopen_commit = iscsi_reopen_commit,
835
.bdrv_co_invalidate_cache = iscsi_co_invalidate_cache,
836
837
- .bdrv_getlength = iscsi_getlength,
838
+ .bdrv_co_getlength = iscsi_co_getlength,
839
.bdrv_get_info = iscsi_get_info,
840
.bdrv_co_truncate = iscsi_co_truncate,
841
.bdrv_refresh_limits = iscsi_refresh_limits,
842
diff --git a/block/mirror.c b/block/mirror.c
843
index XXXXXXX..XXXXXXX 100644
844
--- a/block/mirror.c
845
+++ b/block/mirror.c
846
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
847
goto immediate_exit;
848
}
849
850
- s->bdev_length = bdrv_getlength(bs);
851
+ s->bdev_length = bdrv_co_getlength(bs);
852
if (s->bdev_length < 0) {
853
ret = s->bdev_length;
854
goto immediate_exit;
855
}
856
857
- target_length = blk_getlength(s->target);
858
+ target_length = blk_co_getlength(s->target);
859
if (target_length < 0) {
860
ret = target_length;
861
goto immediate_exit;
862
diff --git a/block/nbd.c b/block/nbd.c
863
index XXXXXXX..XXXXXXX 100644
864
--- a/block/nbd.c
865
+++ b/block/nbd.c
866
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn nbd_co_truncate(BlockDriverState *bs, int64_t offset,
867
return 0;
868
}
869
870
-static int64_t nbd_getlength(BlockDriverState *bs)
871
+static int64_t coroutine_fn nbd_co_getlength(BlockDriverState *bs)
872
{
873
BDRVNBDState *s = bs->opaque;
874
875
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_nbd = {
876
.bdrv_co_pdiscard = nbd_client_co_pdiscard,
877
.bdrv_refresh_limits = nbd_refresh_limits,
878
.bdrv_co_truncate = nbd_co_truncate,
879
- .bdrv_getlength = nbd_getlength,
880
+ .bdrv_co_getlength = nbd_co_getlength,
881
.bdrv_refresh_filename = nbd_refresh_filename,
882
.bdrv_co_block_status = nbd_client_co_block_status,
883
.bdrv_dirname = nbd_dirname,
884
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_nbd_tcp = {
885
.bdrv_co_pdiscard = nbd_client_co_pdiscard,
886
.bdrv_refresh_limits = nbd_refresh_limits,
887
.bdrv_co_truncate = nbd_co_truncate,
888
- .bdrv_getlength = nbd_getlength,
889
+ .bdrv_co_getlength = nbd_co_getlength,
890
.bdrv_refresh_filename = nbd_refresh_filename,
891
.bdrv_co_block_status = nbd_client_co_block_status,
892
.bdrv_dirname = nbd_dirname,
893
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_nbd_unix = {
894
.bdrv_co_pdiscard = nbd_client_co_pdiscard,
895
.bdrv_refresh_limits = nbd_refresh_limits,
896
.bdrv_co_truncate = nbd_co_truncate,
897
- .bdrv_getlength = nbd_getlength,
898
+ .bdrv_co_getlength = nbd_co_getlength,
899
.bdrv_refresh_filename = nbd_refresh_filename,
900
.bdrv_co_block_status = nbd_client_co_block_status,
901
.bdrv_dirname = nbd_dirname,
902
diff --git a/block/null.c b/block/null.c
903
index XXXXXXX..XXXXXXX 100644
904
--- a/block/null.c
905
+++ b/block/null.c
906
@@ -XXX,XX +XXX,XX @@ static int null_file_open(BlockDriverState *bs, QDict *options, int flags,
907
return ret;
908
}
909
910
-static int64_t null_getlength(BlockDriverState *bs)
911
+static int64_t coroutine_fn null_co_getlength(BlockDriverState *bs)
912
{
913
BDRVNullState *s = bs->opaque;
914
return s->length;
915
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_null_co = {
916
917
.bdrv_file_open = null_file_open,
918
.bdrv_parse_filename = null_co_parse_filename,
919
- .bdrv_getlength = null_getlength,
920
+ .bdrv_co_getlength = null_co_getlength,
921
.bdrv_get_allocated_file_size = null_allocated_file_size,
922
923
.bdrv_co_preadv = null_co_preadv,
924
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_null_aio = {
925
926
.bdrv_file_open = null_file_open,
927
.bdrv_parse_filename = null_aio_parse_filename,
928
- .bdrv_getlength = null_getlength,
929
+ .bdrv_co_getlength = null_co_getlength,
930
.bdrv_get_allocated_file_size = null_allocated_file_size,
931
932
.bdrv_aio_preadv = null_aio_preadv,
933
diff --git a/block/nvme.c b/block/nvme.c
934
index XXXXXXX..XXXXXXX 100644
935
--- a/block/nvme.c
936
+++ b/block/nvme.c
70
@@ -XXX,XX +XXX,XX @@ fail:
937
@@ -XXX,XX +XXX,XX @@ fail:
71
* If an error occurred, delete 'filename'. Even if the file existed
938
return ret;
72
* beforehand, it has been truncated and corrupted in the process.
939
}
73
*/
940
74
- if (ret && bs) {
941
-static int64_t nvme_getlength(BlockDriverState *bs)
75
- Error *local_delete_err = NULL;
942
+static int64_t coroutine_fn nvme_co_getlength(BlockDriverState *bs)
76
- int r_del = bdrv_co_delete_file(bs, &local_delete_err);
943
{
77
- /*
944
BDRVNVMeState *s = bs->opaque;
78
- * ENOTSUP will happen if the block driver doesn't support
945
return s->nsze << s->blkshift;
79
- * the 'bdrv_co_delete_file' interface. This is a predictable
946
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn nvme_co_truncate(BlockDriverState *bs, int64_t offset,
80
- * scenario and shouldn't be reported back to the user.
947
return -ENOTSUP;
81
- */
948
}
82
- if ((r_del < 0) && (r_del != -ENOTSUP)) {
949
83
- error_report_err(local_delete_err);
950
- cur_length = nvme_getlength(bs);
84
- } else {
951
+ cur_length = nvme_co_getlength(bs);
85
- error_free(local_delete_err);
952
if (offset != cur_length && exact) {
86
- }
953
error_setg(errp, "Cannot resize NVMe devices");
87
+ if (ret) {
954
return -ENOTSUP;
88
+ bdrv_co_delete_file_noerr(bs);
955
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_nvme = {
89
}
956
.bdrv_parse_filename = nvme_parse_filename,
90
957
.bdrv_file_open = nvme_file_open,
91
bdrv_unref(bs);
958
.bdrv_close = nvme_close,
959
- .bdrv_getlength = nvme_getlength,
960
+ .bdrv_co_getlength = nvme_co_getlength,
961
.bdrv_probe_blocksizes = nvme_probe_blocksizes,
962
.bdrv_co_truncate = nvme_co_truncate,
963
964
diff --git a/block/preallocate.c b/block/preallocate.c
965
index XXXXXXX..XXXXXXX 100644
966
--- a/block/preallocate.c
967
+++ b/block/preallocate.c
968
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn preallocate_co_flush(BlockDriverState *bs)
969
return bdrv_co_flush(bs->file->bs);
970
}
971
972
-static int64_t preallocate_getlength(BlockDriverState *bs)
973
+static int64_t coroutine_fn preallocate_co_getlength(BlockDriverState *bs)
974
{
975
int64_t ret;
976
BDRVPreallocateState *s = bs->opaque;
977
@@ -XXX,XX +XXX,XX @@ static int64_t preallocate_getlength(BlockDriverState *bs)
978
return s->data_end;
979
}
980
981
- ret = bdrv_getlength(bs->file->bs);
982
+ ret = bdrv_co_getlength(bs->file->bs);
983
984
if (has_prealloc_perms(bs)) {
985
s->file_end = s->zero_start = s->data_end = ret;
986
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_preallocate_filter = {
987
.format_name = "preallocate",
988
.instance_size = sizeof(BDRVPreallocateState),
989
990
- .bdrv_getlength = preallocate_getlength,
991
- .bdrv_open = preallocate_open,
992
- .bdrv_close = preallocate_close,
993
+ .bdrv_co_getlength = preallocate_co_getlength,
994
+ .bdrv_open = preallocate_open,
995
+ .bdrv_close = preallocate_close,
996
997
.bdrv_reopen_prepare = preallocate_reopen_prepare,
998
.bdrv_reopen_commit = preallocate_reopen_commit,
999
diff --git a/block/qed.c b/block/qed.c
1000
index XXXXXXX..XXXXXXX 100644
1001
--- a/block/qed.c
1002
+++ b/block/qed.c
1003
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_co_truncate(BlockDriverState *bs,
1004
return ret;
1005
}
1006
1007
-static int64_t bdrv_qed_getlength(BlockDriverState *bs)
1008
+static int64_t coroutine_fn bdrv_qed_co_getlength(BlockDriverState *bs)
1009
{
1010
BDRVQEDState *s = bs->opaque;
1011
return s->header.image_size;
1012
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_qed = {
1013
.bdrv_co_writev = bdrv_qed_co_writev,
1014
.bdrv_co_pwrite_zeroes = bdrv_qed_co_pwrite_zeroes,
1015
.bdrv_co_truncate = bdrv_qed_co_truncate,
1016
- .bdrv_getlength = bdrv_qed_getlength,
1017
+ .bdrv_co_getlength = bdrv_qed_co_getlength,
1018
.bdrv_get_info = bdrv_qed_get_info,
1019
.bdrv_refresh_limits = bdrv_qed_refresh_limits,
1020
.bdrv_change_backing_file = bdrv_qed_change_backing_file,
1021
diff --git a/block/quorum.c b/block/quorum.c
1022
index XXXXXXX..XXXXXXX 100644
1023
--- a/block/quorum.c
1024
+++ b/block/quorum.c
1025
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn quorum_co_pwrite_zeroes(BlockDriverState *bs,
1026
flags | BDRV_REQ_ZERO_WRITE);
1027
}
1028
1029
-static int64_t quorum_getlength(BlockDriverState *bs)
1030
+static int64_t coroutine_fn quorum_co_getlength(BlockDriverState *bs)
1031
{
1032
BDRVQuorumState *s = bs->opaque;
1033
int64_t result;
1034
int i;
1035
1036
/* check that all file have the same length */
1037
- result = bdrv_getlength(s->children[0]->bs);
1038
+ result = bdrv_co_getlength(s->children[0]->bs);
1039
if (result < 0) {
1040
return result;
1041
}
1042
for (i = 1; i < s->num_children; i++) {
1043
- int64_t value = bdrv_getlength(s->children[i]->bs);
1044
+ int64_t value = bdrv_co_getlength(s->children[i]->bs);
1045
if (value < 0) {
1046
return value;
1047
}
1048
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_quorum = {
1049
1050
.bdrv_co_flush = quorum_co_flush,
1051
1052
- .bdrv_getlength = quorum_getlength,
1053
+ .bdrv_co_getlength = quorum_co_getlength,
1054
1055
.bdrv_co_preadv = quorum_co_preadv,
1056
.bdrv_co_pwritev = quorum_co_pwritev,
1057
diff --git a/block/raw-format.c b/block/raw-format.c
1058
index XXXXXXX..XXXXXXX 100644
1059
--- a/block/raw-format.c
1060
+++ b/block/raw-format.c
1061
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_pdiscard(BlockDriverState *bs,
1062
return bdrv_co_pdiscard(bs->file, offset, bytes);
1063
}
1064
1065
-static int64_t raw_getlength(BlockDriverState *bs)
1066
+static int64_t coroutine_fn raw_co_getlength(BlockDriverState *bs)
1067
{
1068
int64_t len;
1069
BDRVRawState *s = bs->opaque;
1070
1071
/* Update size. It should not change unless the file was externally
1072
* modified. */
1073
- len = bdrv_getlength(bs->file->bs);
1074
+ len = bdrv_co_getlength(bs->file->bs);
1075
if (len < 0) {
1076
return len;
1077
}
1078
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_raw = {
1079
.bdrv_co_copy_range_from = &raw_co_copy_range_from,
1080
.bdrv_co_copy_range_to = &raw_co_copy_range_to,
1081
.bdrv_co_truncate = &raw_co_truncate,
1082
- .bdrv_getlength = &raw_getlength,
1083
+ .bdrv_co_getlength = &raw_co_getlength,
1084
.is_format = true,
1085
.has_variable_length = true,
1086
.bdrv_measure = &raw_measure,
1087
diff --git a/block/rbd.c b/block/rbd.c
1088
index XXXXXXX..XXXXXXX 100644
1089
--- a/block/rbd.c
1090
+++ b/block/rbd.c
1091
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qemu_rbd_co_block_status(BlockDriverState *bs,
1092
return status;
1093
}
1094
1095
-static int64_t qemu_rbd_getlength(BlockDriverState *bs)
1096
+static int64_t coroutine_fn qemu_rbd_co_getlength(BlockDriverState *bs)
1097
{
1098
BDRVRBDState *s = bs->opaque;
1099
int r;
1100
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_rbd = {
1101
.bdrv_get_info = qemu_rbd_getinfo,
1102
.bdrv_get_specific_info = qemu_rbd_get_specific_info,
1103
.create_opts = &qemu_rbd_create_opts,
1104
- .bdrv_getlength = qemu_rbd_getlength,
1105
+ .bdrv_co_getlength = qemu_rbd_co_getlength,
1106
.bdrv_co_truncate = qemu_rbd_co_truncate,
1107
.protocol_name = "rbd",
1108
1109
diff --git a/block/replication.c b/block/replication.c
1110
index XXXXXXX..XXXXXXX 100644
1111
--- a/block/replication.c
1112
+++ b/block/replication.c
1113
@@ -XXX,XX +XXX,XX @@ static void replication_child_perm(BlockDriverState *bs, BdrvChild *c,
1114
return;
1115
}
1116
1117
-static int64_t replication_getlength(BlockDriverState *bs)
1118
+static int64_t coroutine_fn replication_co_getlength(BlockDriverState *bs)
1119
{
1120
- return bdrv_getlength(bs->file->bs);
1121
+ return bdrv_co_getlength(bs->file->bs);
1122
}
1123
1124
static int replication_get_io_status(BDRVReplicationState *s)
1125
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_replication = {
1126
.bdrv_close = replication_close,
1127
.bdrv_child_perm = replication_child_perm,
1128
1129
- .bdrv_getlength = replication_getlength,
1130
+ .bdrv_co_getlength = replication_co_getlength,
1131
.bdrv_co_readv = replication_co_readv,
1132
.bdrv_co_writev = replication_co_writev,
1133
1134
diff --git a/block/ssh.c b/block/ssh.c
1135
index XXXXXXX..XXXXXXX 100644
1136
--- a/block/ssh.c
1137
+++ b/block/ssh.c
1138
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int ssh_co_flush(BlockDriverState *bs)
1139
return ret;
1140
}
1141
1142
-static int64_t ssh_getlength(BlockDriverState *bs)
1143
+static int64_t coroutine_fn ssh_co_getlength(BlockDriverState *bs)
1144
{
1145
BDRVSSHState *s = bs->opaque;
1146
int64_t length;
1147
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_ssh = {
1148
.bdrv_has_zero_init = ssh_has_zero_init,
1149
.bdrv_co_readv = ssh_co_readv,
1150
.bdrv_co_writev = ssh_co_writev,
1151
- .bdrv_getlength = ssh_getlength,
1152
+ .bdrv_co_getlength = ssh_co_getlength,
1153
.bdrv_co_truncate = ssh_co_truncate,
1154
.bdrv_co_flush_to_disk = ssh_co_flush,
1155
.bdrv_refresh_filename = ssh_refresh_filename,
1156
diff --git a/block/throttle.c b/block/throttle.c
1157
index XXXXXXX..XXXXXXX 100644
1158
--- a/block/throttle.c
1159
+++ b/block/throttle.c
1160
@@ -XXX,XX +XXX,XX @@ static void throttle_close(BlockDriverState *bs)
1161
}
1162
1163
1164
-static int64_t throttle_getlength(BlockDriverState *bs)
1165
+static int64_t coroutine_fn throttle_co_getlength(BlockDriverState *bs)
1166
{
1167
- return bdrv_getlength(bs->file->bs);
1168
+ return bdrv_co_getlength(bs->file->bs);
1169
}
1170
1171
static int coroutine_fn throttle_co_preadv(BlockDriverState *bs,
1172
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_throttle = {
1173
1174
.bdrv_child_perm = bdrv_default_perms,
1175
1176
- .bdrv_getlength = throttle_getlength,
1177
+ .bdrv_co_getlength = throttle_co_getlength,
1178
1179
.bdrv_co_preadv = throttle_co_preadv,
1180
.bdrv_co_pwritev = throttle_co_pwritev,
1181
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
1182
index XXXXXXX..XXXXXXX 100644
1183
--- a/hw/scsi/scsi-disk.c
1184
+++ b/hw/scsi/scsi-disk.c
1185
@@ -XXX,XX +XXX,XX @@ static void scsi_disk_reset(DeviceState *dev)
1186
{
1187
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev.qdev, dev);
1188
uint64_t nb_sectors;
1189
+ AioContext *ctx;
1190
1191
scsi_device_purge_requests(&s->qdev, SENSE_CODE(RESET));
1192
1193
+ ctx = blk_get_aio_context(s->qdev.conf.blk);
1194
+ aio_context_acquire(ctx);
1195
blk_get_geometry(s->qdev.conf.blk, &nb_sectors);
1196
+ aio_context_release(ctx);
1197
+
1198
nb_sectors /= s->qdev.blocksize / BDRV_SECTOR_SIZE;
1199
if (nb_sectors) {
1200
nb_sectors--;
1201
diff --git a/tests/unit/test-block-iothread.c b/tests/unit/test-block-iothread.c
1202
index XXXXXXX..XXXXXXX 100644
1203
--- a/tests/unit/test-block-iothread.c
1204
+++ b/tests/unit/test-block-iothread.c
1205
@@ -XXX,XX +XXX,XX @@ static void test_attach_second_node(void)
1206
qdict_put_str(options, "driver", "raw");
1207
qdict_put_str(options, "file", "base");
1208
1209
+ aio_context_acquire(ctx);
1210
filter = bdrv_open(NULL, NULL, options, BDRV_O_RDWR, &error_abort);
1211
+ aio_context_release(ctx);
1212
+
1213
g_assert(blk_get_aio_context(blk) == ctx);
1214
g_assert(bdrv_get_aio_context(bs) == ctx);
1215
g_assert(bdrv_get_aio_context(filter) == ctx);
1216
diff --git a/block/meson.build b/block/meson.build
1217
index XXXXXXX..XXXXXXX 100644
1218
--- a/block/meson.build
1219
+++ b/block/meson.build
1220
@@ -XXX,XX +XXX,XX @@ block_gen_c = custom_target('block-gen.c',
1221
input: files(
1222
'../include/block/block-io.h',
1223
'../include/block/dirty-bitmap.h',
1224
+ '../include/block/block_int-io.h',
1225
'../include/block/block-global-state.h',
1226
'../include/sysemu/block-backend-io.h',
1227
'coroutines.h'
92
--
1228
--
93
2.29.2
1229
2.38.1
94
95
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
The only difference is that blk_ checks if the block is available,
4
but this check is already performed above in blk_check_byte_request().
5
6
This is in preparation for the graph rdlock, which will be taken
7
by both the callers of blk_check_byte_request() and blk_getlength().
8
9
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Message-Id: <20230113204212.359076-8-kwolf@redhat.com>
12
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
15
block/block-backend.c | 2 +-
16
1 file changed, 1 insertion(+), 1 deletion(-)
17
18
diff --git a/block/block-backend.c b/block/block-backend.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/block/block-backend.c
21
+++ b/block/block-backend.c
22
@@ -XXX,XX +XXX,XX @@ static int blk_check_byte_request(BlockBackend *blk, int64_t offset,
23
}
24
25
if (!blk->allow_write_beyond_eof) {
26
- len = blk_getlength(blk);
27
+ len = bdrv_getlength(blk_bs(blk));
28
if (len < 0) {
29
return len;
30
}
31
--
32
2.38.1
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
In some places we are sure we are always running in a
4
coroutine, therefore it's useless to call the generated_co_wrapper,
5
instead call directly the _co_ function.
6
7
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Message-Id: <20230113204212.359076-9-kwolf@redhat.com>
10
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
13
block/block-backend.c | 6 +++---
14
block/io.c | 4 ++--
15
block/preallocate.c | 6 +++---
16
block/qed.c | 2 +-
17
4 files changed, 9 insertions(+), 9 deletions(-)
18
19
diff --git a/block/block-backend.c b/block/block-backend.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/block/block-backend.c
22
+++ b/block/block-backend.c
23
@@ -XXX,XX +XXX,XX @@ void blk_set_disable_request_queuing(BlockBackend *blk, bool disable)
24
blk->disable_request_queuing = disable;
25
}
26
27
-static int blk_check_byte_request(BlockBackend *blk, int64_t offset,
28
- int64_t bytes)
29
+static coroutine_fn int blk_check_byte_request(BlockBackend *blk,
30
+ int64_t offset, int64_t bytes)
31
{
32
int64_t len;
33
34
@@ -XXX,XX +XXX,XX @@ static int blk_check_byte_request(BlockBackend *blk, int64_t offset,
35
}
36
37
if (!blk->allow_write_beyond_eof) {
38
- len = bdrv_getlength(blk_bs(blk));
39
+ len = bdrv_co_getlength(blk_bs(blk));
40
if (len < 0) {
41
return len;
42
}
43
diff --git a/block/io.c b/block/io.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/block/io.c
46
+++ b/block/io.c
47
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
48
if (new_bytes && backing) {
49
int64_t backing_len;
50
51
- backing_len = bdrv_getlength(backing->bs);
52
+ backing_len = bdrv_co_getlength(backing->bs);
53
if (backing_len < 0) {
54
ret = backing_len;
55
error_setg_errno(errp, -ret, "Could not get backing file size");
56
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
57
goto out;
58
}
59
60
- ret = bdrv_refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS);
61
+ ret = bdrv_co_refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS);
62
if (ret < 0) {
63
error_setg_errno(errp, -ret, "Could not refresh total sector count");
64
} else {
65
diff --git a/block/preallocate.c b/block/preallocate.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/block/preallocate.c
68
+++ b/block/preallocate.c
69
@@ -XXX,XX +XXX,XX @@ static bool coroutine_fn handle_write(BlockDriverState *bs, int64_t offset,
70
}
71
72
if (s->data_end < 0) {
73
- s->data_end = bdrv_getlength(bs->file->bs);
74
+ s->data_end = bdrv_co_getlength(bs->file->bs);
75
if (s->data_end < 0) {
76
return false;
77
}
78
@@ -XXX,XX +XXX,XX @@ static bool coroutine_fn handle_write(BlockDriverState *bs, int64_t offset,
79
}
80
81
if (s->file_end < 0) {
82
- s->file_end = bdrv_getlength(bs->file->bs);
83
+ s->file_end = bdrv_co_getlength(bs->file->bs);
84
if (s->file_end < 0) {
85
return false;
86
}
87
@@ -XXX,XX +XXX,XX @@ preallocate_co_truncate(BlockDriverState *bs, int64_t offset,
88
89
if (s->data_end >= 0 && offset > s->data_end) {
90
if (s->file_end < 0) {
91
- s->file_end = bdrv_getlength(bs->file->bs);
92
+ s->file_end = bdrv_co_getlength(bs->file->bs);
93
if (s->file_end < 0) {
94
error_setg(errp, "failed to get file length");
95
return s->file_end;
96
diff --git a/block/qed.c b/block/qed.c
97
index XXXXXXX..XXXXXXX 100644
98
--- a/block/qed.c
99
+++ b/block/qed.c
100
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_do_open(BlockDriverState *bs, QDict *options,
101
}
102
103
/* Round down file size to the last cluster */
104
- file_size = bdrv_getlength(bs->file->bs);
105
+ file_size = bdrv_co_getlength(bs->file->bs);
106
if (file_size < 0) {
107
error_setg(errp, "Failed to get file length");
108
return file_size;
109
--
110
2.38.1
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
bdrv_get_allocated_file_size() is categorized as an I/O function, and it
4
currently doesn't run in a coroutine. We should let it take a graph
5
rdlock since it traverses the block nodes graph, which however is only
6
possible in a coroutine.
7
8
Therefore turn it into a co_wrapper to move the actual function into a
9
coroutine where the lock can be taken.
10
11
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
Message-Id: <20230113204212.359076-10-kwolf@redhat.com>
14
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
15
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
---
17
include/block/block-io.h | 4 +++-
18
include/block/block_int-common.h | 4 +++-
19
block.c | 12 ++++++------
20
block/file-posix.c | 14 +++++---------
21
block/file-win32.c | 10 ++++------
22
block/gluster.c | 11 ++++++-----
23
block/nfs.c | 4 ++--
24
block/null.c | 7 ++++---
25
block/qcow2-refcount.c | 2 +-
26
block/vmdk.c | 9 +++++----
27
10 files changed, 39 insertions(+), 38 deletions(-)
28
29
diff --git a/include/block/block-io.h b/include/block/block-io.h
30
index XXXXXXX..XXXXXXX 100644
31
--- a/include/block/block-io.h
32
+++ b/include/block/block-io.h
33
@@ -XXX,XX +XXX,XX @@ int64_t co_wrapper_mixed bdrv_nb_sectors(BlockDriverState *bs);
34
int64_t coroutine_fn bdrv_co_getlength(BlockDriverState *bs);
35
int64_t co_wrapper_mixed bdrv_getlength(BlockDriverState *bs);
36
37
-int64_t bdrv_get_allocated_file_size(BlockDriverState *bs);
38
+int64_t coroutine_fn bdrv_co_get_allocated_file_size(BlockDriverState *bs);
39
+int64_t co_wrapper bdrv_get_allocated_file_size(BlockDriverState *bs);
40
+
41
BlockMeasureInfo *bdrv_measure(BlockDriver *drv, QemuOpts *opts,
42
BlockDriverState *in_bs, Error **errp);
43
void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr);
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
bool exact, PreallocMode prealloc,
50
BdrvRequestFlags flags, Error **errp);
51
int64_t coroutine_fn (*bdrv_co_getlength)(BlockDriverState *bs);
52
- int64_t (*bdrv_get_allocated_file_size)(BlockDriverState *bs);
53
+ int64_t coroutine_fn (*bdrv_co_get_allocated_file_size)(
54
+ BlockDriverState *bs);
55
+
56
BlockMeasureInfo *(*bdrv_measure)(QemuOpts *opts, BlockDriverState *in_bs,
57
Error **errp);
58
59
diff --git a/block.c b/block.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/block.c
62
+++ b/block.c
63
@@ -XXX,XX +XXX,XX @@ exit:
64
}
65
66
/**
67
- * Implementation of BlockDriver.bdrv_get_allocated_file_size() that
68
+ * Implementation of BlockDriver.bdrv_co_get_allocated_file_size() that
69
* sums the size of all data-bearing children. (This excludes backing
70
* children.)
71
*/
72
@@ -XXX,XX +XXX,XX @@ static int64_t bdrv_sum_allocated_file_size(BlockDriverState *bs)
73
if (child->role & (BDRV_CHILD_DATA | BDRV_CHILD_METADATA |
74
BDRV_CHILD_FILTERED))
75
{
76
- child_size = bdrv_get_allocated_file_size(child->bs);
77
+ child_size = bdrv_co_get_allocated_file_size(child->bs);
78
if (child_size < 0) {
79
return child_size;
80
}
81
@@ -XXX,XX +XXX,XX @@ static int64_t bdrv_sum_allocated_file_size(BlockDriverState *bs)
82
* Length of a allocated file in bytes. Sparse files are counted by actual
83
* allocated space. Return < 0 if error or unknown.
84
*/
85
-int64_t bdrv_get_allocated_file_size(BlockDriverState *bs)
86
+int64_t coroutine_fn bdrv_co_get_allocated_file_size(BlockDriverState *bs)
87
{
88
BlockDriver *drv = bs->drv;
89
IO_CODE();
90
@@ -XXX,XX +XXX,XX @@ int64_t bdrv_get_allocated_file_size(BlockDriverState *bs)
91
if (!drv) {
92
return -ENOMEDIUM;
93
}
94
- if (drv->bdrv_get_allocated_file_size) {
95
- return drv->bdrv_get_allocated_file_size(bs);
96
+ if (drv->bdrv_co_get_allocated_file_size) {
97
+ return drv->bdrv_co_get_allocated_file_size(bs);
98
}
99
100
if (drv->bdrv_file_open) {
101
@@ -XXX,XX +XXX,XX @@ int64_t bdrv_get_allocated_file_size(BlockDriverState *bs)
102
return -ENOTSUP;
103
} else if (drv->is_filter) {
104
/* Filter drivers default to the size of their filtered child */
105
- return bdrv_get_allocated_file_size(bdrv_filter_bs(bs));
106
+ return bdrv_co_get_allocated_file_size(bdrv_filter_bs(bs));
107
} else {
108
/* Other drivers default to summing their children's sizes */
109
return bdrv_sum_allocated_file_size(bs);
110
diff --git a/block/file-posix.c b/block/file-posix.c
111
index XXXXXXX..XXXXXXX 100644
112
--- a/block/file-posix.c
113
+++ b/block/file-posix.c
114
@@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn raw_co_getlength(BlockDriverState *bs)
115
}
116
#endif
117
118
-static int64_t raw_get_allocated_file_size(BlockDriverState *bs)
119
+static int64_t coroutine_fn raw_co_get_allocated_file_size(BlockDriverState *bs)
120
{
121
struct stat st;
122
BDRVRawState *s = bs->opaque;
123
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_file = {
124
.bdrv_co_truncate = raw_co_truncate,
125
.bdrv_co_getlength = raw_co_getlength,
126
.bdrv_get_info = raw_get_info,
127
- .bdrv_get_allocated_file_size
128
- = raw_get_allocated_file_size,
129
+ .bdrv_co_get_allocated_file_size = raw_co_get_allocated_file_size,
130
.bdrv_get_specific_stats = raw_get_specific_stats,
131
.bdrv_check_perm = raw_check_perm,
132
.bdrv_set_perm = raw_set_perm,
133
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_device = {
134
.bdrv_co_truncate = raw_co_truncate,
135
.bdrv_co_getlength = raw_co_getlength,
136
.bdrv_get_info = raw_get_info,
137
- .bdrv_get_allocated_file_size
138
- = raw_get_allocated_file_size,
139
+ .bdrv_co_get_allocated_file_size = raw_co_get_allocated_file_size,
140
.bdrv_get_specific_stats = hdev_get_specific_stats,
141
.bdrv_check_perm = raw_check_perm,
142
.bdrv_set_perm = raw_set_perm,
143
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_cdrom = {
144
.bdrv_co_truncate = raw_co_truncate,
145
.bdrv_co_getlength = raw_co_getlength,
146
.has_variable_length = true,
147
- .bdrv_get_allocated_file_size
148
- = raw_get_allocated_file_size,
149
+ .bdrv_co_get_allocated_file_size = raw_co_get_allocated_file_size,
150
151
/* removable device support */
152
.bdrv_co_is_inserted = cdrom_co_is_inserted,
153
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_cdrom = {
154
.bdrv_co_truncate = raw_co_truncate,
155
.bdrv_co_getlength = raw_co_getlength,
156
.has_variable_length = true,
157
- .bdrv_get_allocated_file_size
158
- = raw_get_allocated_file_size,
159
+ .bdrv_co_get_allocated_file_size = raw_co_get_allocated_file_size,
160
161
/* removable device support */
162
.bdrv_co_is_inserted = cdrom_co_is_inserted,
163
diff --git a/block/file-win32.c b/block/file-win32.c
164
index XXXXXXX..XXXXXXX 100644
165
--- a/block/file-win32.c
166
+++ b/block/file-win32.c
167
@@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn raw_co_getlength(BlockDriverState *bs)
168
return l.QuadPart;
169
}
170
171
-static int64_t raw_get_allocated_file_size(BlockDriverState *bs)
172
+static int64_t coroutine_fn raw_co_get_allocated_file_size(BlockDriverState *bs)
173
{
174
typedef DWORD (WINAPI * get_compressed_t)(const char *filename,
175
DWORD * high);
176
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_file = {
177
178
.bdrv_co_truncate = raw_co_truncate,
179
.bdrv_co_getlength = raw_co_getlength,
180
- .bdrv_get_allocated_file_size
181
- = raw_get_allocated_file_size,
182
+ .bdrv_co_get_allocated_file_size
183
+ = raw_co_get_allocated_file_size,
184
185
.create_opts = &raw_create_opts,
186
};
187
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_device = {
188
189
.bdrv_co_getlength = raw_co_getlength,
190
.has_variable_length = true,
191
-
192
- .bdrv_get_allocated_file_size
193
- = raw_get_allocated_file_size,
194
+ .bdrv_co_get_allocated_file_size = raw_co_get_allocated_file_size,
195
};
196
197
static void bdrv_file_init(void)
198
diff --git a/block/gluster.c b/block/gluster.c
199
index XXXXXXX..XXXXXXX 100644
200
--- a/block/gluster.c
201
+++ b/block/gluster.c
202
@@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn qemu_gluster_co_getlength(BlockDriverState *bs)
203
}
204
}
205
206
-static int64_t qemu_gluster_allocated_file_size(BlockDriverState *bs)
207
+static int64_t coroutine_fn
208
+qemu_gluster_co_get_allocated_file_size(BlockDriverState *bs)
209
{
210
BDRVGlusterState *s = bs->opaque;
211
struct stat st;
212
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_gluster = {
213
.bdrv_co_create = qemu_gluster_co_create,
214
.bdrv_co_create_opts = qemu_gluster_co_create_opts,
215
.bdrv_co_getlength = qemu_gluster_co_getlength,
216
- .bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
217
+ .bdrv_co_get_allocated_file_size = qemu_gluster_co_get_allocated_file_size,
218
.bdrv_co_truncate = qemu_gluster_co_truncate,
219
.bdrv_co_readv = qemu_gluster_co_readv,
220
.bdrv_co_writev = qemu_gluster_co_writev,
221
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_gluster_tcp = {
222
.bdrv_co_create = qemu_gluster_co_create,
223
.bdrv_co_create_opts = qemu_gluster_co_create_opts,
224
.bdrv_co_getlength = qemu_gluster_co_getlength,
225
- .bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
226
+ .bdrv_co_get_allocated_file_size = qemu_gluster_co_get_allocated_file_size,
227
.bdrv_co_truncate = qemu_gluster_co_truncate,
228
.bdrv_co_readv = qemu_gluster_co_readv,
229
.bdrv_co_writev = qemu_gluster_co_writev,
230
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_gluster_unix = {
231
.bdrv_co_create = qemu_gluster_co_create,
232
.bdrv_co_create_opts = qemu_gluster_co_create_opts,
233
.bdrv_co_getlength = qemu_gluster_co_getlength,
234
- .bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
235
+ .bdrv_co_get_allocated_file_size = qemu_gluster_co_get_allocated_file_size,
236
.bdrv_co_truncate = qemu_gluster_co_truncate,
237
.bdrv_co_readv = qemu_gluster_co_readv,
238
.bdrv_co_writev = qemu_gluster_co_writev,
239
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_gluster_rdma = {
240
.bdrv_co_create = qemu_gluster_co_create,
241
.bdrv_co_create_opts = qemu_gluster_co_create_opts,
242
.bdrv_co_getlength = qemu_gluster_co_getlength,
243
- .bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
244
+ .bdrv_co_get_allocated_file_size = qemu_gluster_co_get_allocated_file_size,
245
.bdrv_co_truncate = qemu_gluster_co_truncate,
246
.bdrv_co_readv = qemu_gluster_co_readv,
247
.bdrv_co_writev = qemu_gluster_co_writev,
248
diff --git a/block/nfs.c b/block/nfs.c
249
index XXXXXXX..XXXXXXX 100644
250
--- a/block/nfs.c
251
+++ b/block/nfs.c
252
@@ -XXX,XX +XXX,XX @@ nfs_get_allocated_file_size_cb(int ret, struct nfs_context *nfs, void *data,
253
bdrv_wakeup(task->bs);
254
}
255
256
-static int64_t nfs_get_allocated_file_size(BlockDriverState *bs)
257
+static int64_t coroutine_fn nfs_co_get_allocated_file_size(BlockDriverState *bs)
258
{
259
NFSClient *client = bs->opaque;
260
NFSRPC task = {0};
261
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_nfs = {
262
.bdrv_has_zero_init = nfs_has_zero_init,
263
/* libnfs does not provide the allocated filesize of a file on win32. */
264
#if !defined(_WIN32)
265
- .bdrv_get_allocated_file_size = nfs_get_allocated_file_size,
266
+ .bdrv_co_get_allocated_file_size = nfs_co_get_allocated_file_size,
267
#endif
268
.bdrv_co_truncate = nfs_file_co_truncate,
269
270
diff --git a/block/null.c b/block/null.c
271
index XXXXXXX..XXXXXXX 100644
272
--- a/block/null.c
273
+++ b/block/null.c
274
@@ -XXX,XX +XXX,XX @@ static void null_refresh_filename(BlockDriverState *bs)
275
bs->drv->format_name);
276
}
277
278
-static int64_t null_allocated_file_size(BlockDriverState *bs)
279
+static int64_t coroutine_fn
280
+null_co_get_allocated_file_size(BlockDriverState *bs)
281
{
282
return 0;
283
}
284
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_null_co = {
285
.bdrv_file_open = null_file_open,
286
.bdrv_parse_filename = null_co_parse_filename,
287
.bdrv_co_getlength = null_co_getlength,
288
- .bdrv_get_allocated_file_size = null_allocated_file_size,
289
+ .bdrv_co_get_allocated_file_size = null_co_get_allocated_file_size,
290
291
.bdrv_co_preadv = null_co_preadv,
292
.bdrv_co_pwritev = null_co_pwritev,
293
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_null_aio = {
294
.bdrv_file_open = null_file_open,
295
.bdrv_parse_filename = null_aio_parse_filename,
296
.bdrv_co_getlength = null_co_getlength,
297
- .bdrv_get_allocated_file_size = null_allocated_file_size,
298
+ .bdrv_co_get_allocated_file_size = null_co_get_allocated_file_size,
299
300
.bdrv_aio_preadv = null_aio_preadv,
301
.bdrv_aio_pwritev = null_aio_pwritev,
302
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
303
index XXXXXXX..XXXXXXX 100644
304
--- a/block/qcow2-refcount.c
305
+++ b/block/qcow2-refcount.c
306
@@ -XXX,XX +XXX,XX @@ int coroutine_fn qcow2_detect_metadata_preallocation(BlockDriverState *bs)
307
return file_length;
308
}
309
310
- real_allocation = bdrv_get_allocated_file_size(bs->file->bs);
311
+ real_allocation = bdrv_co_get_allocated_file_size(bs->file->bs);
312
if (real_allocation < 0) {
313
return real_allocation;
314
}
315
diff --git a/block/vmdk.c b/block/vmdk.c
316
index XXXXXXX..XXXXXXX 100644
317
--- a/block/vmdk.c
318
+++ b/block/vmdk.c
319
@@ -XXX,XX +XXX,XX @@ static void vmdk_close(BlockDriverState *bs)
320
error_free(s->migration_blocker);
321
}
322
323
-static int64_t vmdk_get_allocated_file_size(BlockDriverState *bs)
324
+static int64_t coroutine_fn
325
+vmdk_co_get_allocated_file_size(BlockDriverState *bs)
326
{
327
int i;
328
int64_t ret = 0;
329
int64_t r;
330
BDRVVmdkState *s = bs->opaque;
331
332
- ret = bdrv_get_allocated_file_size(bs->file->bs);
333
+ ret = bdrv_co_get_allocated_file_size(bs->file->bs);
334
if (ret < 0) {
335
return ret;
336
}
337
@@ -XXX,XX +XXX,XX @@ static int64_t vmdk_get_allocated_file_size(BlockDriverState *bs)
338
if (s->extents[i].file == bs->file) {
339
continue;
340
}
341
- r = bdrv_get_allocated_file_size(s->extents[i].file->bs);
342
+ r = bdrv_co_get_allocated_file_size(s->extents[i].file->bs);
343
if (r < 0) {
344
return r;
345
}
346
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_vmdk = {
347
.bdrv_co_create_opts = vmdk_co_create_opts,
348
.bdrv_co_create = vmdk_co_create,
349
.bdrv_co_block_status = vmdk_co_block_status,
350
- .bdrv_get_allocated_file_size = vmdk_get_allocated_file_size,
351
+ .bdrv_co_get_allocated_file_size = vmdk_co_get_allocated_file_size,
352
.bdrv_has_zero_init = vmdk_has_zero_init,
353
.bdrv_get_specific_info = vmdk_get_specific_info,
354
.bdrv_refresh_limits = vmdk_refresh_limits,
355
--
356
2.38.1
diff view generated by jsdifflib
1
From: Maxim Levitsky <mlevitsk@redhat.com>
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
2
2
3
When the underlying block device doesn't support the
3
bdrv_get_info() is categorized as an I/O function, and it currently
4
bdrv_co_delete_file interface, an 'Error' object was leaked.
4
doesn't run in a coroutine. We should let it take a graph rdlock since
5
it traverses the block nodes graph, which however is only possible in a
6
coroutine.
5
7
6
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
8
Therefore turn it into a co_wrapper to move the actual function into a
7
Reviewed-by: Alberto Garcia <berto@igalia.com>
9
coroutine where the lock can be taken.
8
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10
9
Message-Id: <20201217170904.946013-2-mlevitsk@redhat.com>
11
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
Message-Id: <20230113204212.359076-11-kwolf@redhat.com>
14
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
16
---
12
block/crypto.c | 2 ++
17
include/block/block-io.h | 5 ++++-
13
1 file changed, 2 insertions(+)
18
include/block/block_int-common.h | 3 ++-
19
block.c | 8 ++++----
20
block/blkio.c | 5 +++--
21
block/crypto.c | 8 ++++----
22
block/file-posix.c | 7 ++++---
23
block/io.c | 8 ++++----
24
block/iscsi.c | 7 ++++---
25
block/mirror.c | 2 +-
26
block/qcow.c | 5 +++--
27
block/qcow2.c | 5 +++--
28
block/qed.c | 5 +++--
29
block/raw-format.c | 7 ++++---
30
block/rbd.c | 5 +++--
31
block/vdi.c | 7 ++++---
32
block/vhdx.c | 5 +++--
33
block/vmdk.c | 5 +++--
34
block/vpc.c | 5 +++--
35
18 files changed, 59 insertions(+), 43 deletions(-)
14
36
37
diff --git a/include/block/block-io.h b/include/block/block-io.h
38
index XXXXXXX..XXXXXXX 100644
39
--- a/include/block/block-io.h
40
+++ b/include/block/block-io.h
41
@@ -XXX,XX +XXX,XX @@ bool bdrv_supports_compressed_writes(BlockDriverState *bs);
42
const char *bdrv_get_node_name(const BlockDriverState *bs);
43
const char *bdrv_get_device_name(const BlockDriverState *bs);
44
const char *bdrv_get_device_or_node_name(const BlockDriverState *bs);
45
-int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi);
46
+
47
+int coroutine_fn bdrv_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi);
48
+int co_wrapper_mixed bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi);
49
+
50
ImageInfoSpecific *bdrv_get_specific_info(BlockDriverState *bs,
51
Error **errp);
52
BlockStatsSpecific *bdrv_get_specific_stats(BlockDriverState *bs);
53
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
54
index XXXXXXX..XXXXXXX 100644
55
--- a/include/block/block_int-common.h
56
+++ b/include/block/block_int-common.h
57
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
58
int64_t offset, int64_t bytes, QEMUIOVector *qiov,
59
size_t qiov_offset);
60
61
- int (*bdrv_get_info)(BlockDriverState *bs, BlockDriverInfo *bdi);
62
+ int coroutine_fn (*bdrv_co_get_info)(BlockDriverState *bs,
63
+ BlockDriverInfo *bdi);
64
65
ImageInfoSpecific *(*bdrv_get_specific_info)(BlockDriverState *bs,
66
Error **errp);
67
diff --git a/block.c b/block.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/block.c
70
+++ b/block.c
71
@@ -XXX,XX +XXX,XX @@ void bdrv_get_backing_filename(BlockDriverState *bs,
72
pstrcpy(filename, filename_size, bs->backing_file);
73
}
74
75
-int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
76
+int coroutine_fn bdrv_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
77
{
78
int ret;
79
BlockDriver *drv = bs->drv;
80
@@ -XXX,XX +XXX,XX @@ int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
81
if (!drv) {
82
return -ENOMEDIUM;
83
}
84
- if (!drv->bdrv_get_info) {
85
+ if (!drv->bdrv_co_get_info) {
86
BlockDriverState *filtered = bdrv_filter_bs(bs);
87
if (filtered) {
88
- return bdrv_get_info(filtered, bdi);
89
+ return bdrv_co_get_info(filtered, bdi);
90
}
91
return -ENOTSUP;
92
}
93
memset(bdi, 0, sizeof(*bdi));
94
- ret = drv->bdrv_get_info(bs, bdi);
95
+ ret = drv->bdrv_co_get_info(bs, bdi);
96
if (ret < 0) {
97
return ret;
98
}
99
diff --git a/block/blkio.c b/block/blkio.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/block/blkio.c
102
+++ b/block/blkio.c
103
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn blkio_truncate(BlockDriverState *bs, int64_t offset,
104
return 0;
105
}
106
107
-static int blkio_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
108
+static int coroutine_fn
109
+blkio_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
110
{
111
return 0;
112
}
113
@@ -XXX,XX +XXX,XX @@ static void blkio_refresh_limits(BlockDriverState *bs, Error **errp)
114
.bdrv_close = blkio_close, \
115
.bdrv_co_getlength = blkio_co_getlength, \
116
.bdrv_co_truncate = blkio_truncate, \
117
- .bdrv_get_info = blkio_get_info, \
118
+ .bdrv_co_get_info = blkio_co_get_info, \
119
.bdrv_attach_aio_context = blkio_attach_aio_context, \
120
.bdrv_detach_aio_context = blkio_detach_aio_context, \
121
.bdrv_co_pdiscard = blkio_co_pdiscard, \
15
diff --git a/block/crypto.c b/block/crypto.c
122
diff --git a/block/crypto.c b/block/crypto.c
16
index XXXXXXX..XXXXXXX 100644
123
index XXXXXXX..XXXXXXX 100644
17
--- a/block/crypto.c
124
--- a/block/crypto.c
18
+++ b/block/crypto.c
125
+++ b/block/crypto.c
19
@@ -XXX,XX +XXX,XX @@ fail:
126
@@ -XXX,XX +XXX,XX @@ fail:
20
*/
127
return ret;
21
if ((r_del < 0) && (r_del != -ENOTSUP)) {
128
}
22
error_report_err(local_delete_err);
129
23
+ } else {
130
-static int block_crypto_get_info_luks(BlockDriverState *bs,
24
+ error_free(local_delete_err);
131
- BlockDriverInfo *bdi)
25
}
132
+static int coroutine_fn
133
+block_crypto_co_get_info_luks(BlockDriverState *bs, BlockDriverInfo *bdi)
134
{
135
BlockDriverInfo subbdi;
136
int ret;
137
138
- ret = bdrv_get_info(bs->file->bs, &subbdi);
139
+ ret = bdrv_co_get_info(bs->file->bs, &subbdi);
140
if (ret != 0) {
141
return ret;
26
}
142
}
27
143
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_crypto_luks = {
144
.bdrv_co_pwritev = block_crypto_co_pwritev,
145
.bdrv_co_getlength = block_crypto_co_getlength,
146
.bdrv_measure = block_crypto_measure,
147
- .bdrv_get_info = block_crypto_get_info_luks,
148
+ .bdrv_co_get_info = block_crypto_co_get_info_luks,
149
.bdrv_get_specific_info = block_crypto_get_specific_info_luks,
150
.bdrv_amend_options = block_crypto_amend_options_luks,
151
.bdrv_co_amend = block_crypto_co_amend_luks,
152
diff --git a/block/file-posix.c b/block/file-posix.c
153
index XXXXXXX..XXXXXXX 100644
154
--- a/block/file-posix.c
155
+++ b/block/file-posix.c
156
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_pwrite_zeroes(
157
return raw_do_pwrite_zeroes(bs, offset, bytes, flags, false);
158
}
159
160
-static int raw_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
161
+static int coroutine_fn
162
+raw_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
163
{
164
return 0;
165
}
166
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_file = {
167
168
.bdrv_co_truncate = raw_co_truncate,
169
.bdrv_co_getlength = raw_co_getlength,
170
- .bdrv_get_info = raw_get_info,
171
+ .bdrv_co_get_info = raw_co_get_info,
172
.bdrv_co_get_allocated_file_size = raw_co_get_allocated_file_size,
173
.bdrv_get_specific_stats = raw_get_specific_stats,
174
.bdrv_check_perm = raw_check_perm,
175
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_device = {
176
177
.bdrv_co_truncate = raw_co_truncate,
178
.bdrv_co_getlength = raw_co_getlength,
179
- .bdrv_get_info = raw_get_info,
180
+ .bdrv_co_get_info = raw_co_get_info,
181
.bdrv_co_get_allocated_file_size = raw_co_get_allocated_file_size,
182
.bdrv_get_specific_stats = hdev_get_specific_stats,
183
.bdrv_check_perm = raw_check_perm,
184
diff --git a/block/io.c b/block/io.c
185
index XXXXXXX..XXXXXXX 100644
186
--- a/block/io.c
187
+++ b/block/io.c
188
@@ -XXX,XX +XXX,XX @@ BdrvTrackedRequest *coroutine_fn bdrv_co_get_self_request(BlockDriverState *bs)
189
/**
190
* Round a region to cluster boundaries
191
*/
192
-void bdrv_round_to_clusters(BlockDriverState *bs,
193
+void coroutine_fn bdrv_round_to_clusters(BlockDriverState *bs,
194
int64_t offset, int64_t bytes,
195
int64_t *cluster_offset,
196
int64_t *cluster_bytes)
197
{
198
BlockDriverInfo bdi;
199
IO_CODE();
200
- if (bdrv_get_info(bs, &bdi) < 0 || bdi.cluster_size == 0) {
201
+ if (bdrv_co_get_info(bs, &bdi) < 0 || bdi.cluster_size == 0) {
202
*cluster_offset = offset;
203
*cluster_bytes = bytes;
204
} else {
205
@@ -XXX,XX +XXX,XX @@ void bdrv_round_to_clusters(BlockDriverState *bs,
206
}
207
}
208
209
-static int bdrv_get_cluster_size(BlockDriverState *bs)
210
+static coroutine_fn int bdrv_get_cluster_size(BlockDriverState *bs)
211
{
212
BlockDriverInfo bdi;
213
int ret;
214
215
- ret = bdrv_get_info(bs, &bdi);
216
+ ret = bdrv_co_get_info(bs, &bdi);
217
if (ret < 0 || bdi.cluster_size == 0) {
218
return bs->bl.request_alignment;
219
} else {
220
diff --git a/block/iscsi.c b/block/iscsi.c
221
index XXXXXXX..XXXXXXX 100644
222
--- a/block/iscsi.c
223
+++ b/block/iscsi.c
224
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn iscsi_co_truncate(BlockDriverState *bs, int64_t offset,
225
return 0;
226
}
227
228
-static int iscsi_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
229
+static int coroutine_fn
230
+iscsi_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
231
{
232
IscsiLun *iscsilun = bs->opaque;
233
bdi->cluster_size = iscsilun->cluster_size;
234
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_iscsi = {
235
.bdrv_co_invalidate_cache = iscsi_co_invalidate_cache,
236
237
.bdrv_co_getlength = iscsi_co_getlength,
238
- .bdrv_get_info = iscsi_get_info,
239
+ .bdrv_co_get_info = iscsi_co_get_info,
240
.bdrv_co_truncate = iscsi_co_truncate,
241
.bdrv_refresh_limits = iscsi_refresh_limits,
242
243
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_iser = {
244
.bdrv_co_invalidate_cache = iscsi_co_invalidate_cache,
245
246
.bdrv_co_getlength = iscsi_co_getlength,
247
- .bdrv_get_info = iscsi_get_info,
248
+ .bdrv_co_get_info = iscsi_co_get_info,
249
.bdrv_co_truncate = iscsi_co_truncate,
250
.bdrv_refresh_limits = iscsi_refresh_limits,
251
252
diff --git a/block/mirror.c b/block/mirror.c
253
index XXXXXXX..XXXXXXX 100644
254
--- a/block/mirror.c
255
+++ b/block/mirror.c
256
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
257
*/
258
bdrv_get_backing_filename(target_bs, backing_filename,
259
sizeof(backing_filename));
260
- if (!bdrv_get_info(target_bs, &bdi) && bdi.cluster_size) {
261
+ if (!bdrv_co_get_info(target_bs, &bdi) && bdi.cluster_size) {
262
s->target_cluster_size = bdi.cluster_size;
263
} else {
264
s->target_cluster_size = BDRV_SECTOR_SIZE;
265
diff --git a/block/qcow.c b/block/qcow.c
266
index XXXXXXX..XXXXXXX 100644
267
--- a/block/qcow.c
268
+++ b/block/qcow.c
269
@@ -XXX,XX +XXX,XX @@ fail:
270
return ret;
271
}
272
273
-static int qcow_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
274
+static int coroutine_fn
275
+qcow_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
276
{
277
BDRVQcowState *s = bs->opaque;
278
bdi->cluster_size = s->cluster_size;
279
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_qcow = {
280
281
.bdrv_make_empty = qcow_make_empty,
282
.bdrv_co_pwritev_compressed = qcow_co_pwritev_compressed,
283
- .bdrv_get_info = qcow_get_info,
284
+ .bdrv_co_get_info = qcow_co_get_info,
285
286
.create_opts = &qcow_create_opts,
287
.strong_runtime_opts = qcow_strong_runtime_opts,
288
diff --git a/block/qcow2.c b/block/qcow2.c
289
index XXXXXXX..XXXXXXX 100644
290
--- a/block/qcow2.c
291
+++ b/block/qcow2.c
292
@@ -XXX,XX +XXX,XX @@ err:
293
return NULL;
294
}
295
296
-static int qcow2_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
297
+static int coroutine_fn
298
+qcow2_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
299
{
300
BDRVQcow2State *s = bs->opaque;
301
bdi->cluster_size = s->cluster_size;
302
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_qcow2 = {
303
.bdrv_snapshot_list = qcow2_snapshot_list,
304
.bdrv_snapshot_load_tmp = qcow2_snapshot_load_tmp,
305
.bdrv_measure = qcow2_measure,
306
- .bdrv_get_info = qcow2_get_info,
307
+ .bdrv_co_get_info = qcow2_co_get_info,
308
.bdrv_get_specific_info = qcow2_get_specific_info,
309
310
.bdrv_save_vmstate = qcow2_save_vmstate,
311
diff --git a/block/qed.c b/block/qed.c
312
index XXXXXXX..XXXXXXX 100644
313
--- a/block/qed.c
314
+++ b/block/qed.c
315
@@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn bdrv_qed_co_getlength(BlockDriverState *bs)
316
return s->header.image_size;
317
}
318
319
-static int bdrv_qed_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
320
+static int coroutine_fn
321
+bdrv_qed_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
322
{
323
BDRVQEDState *s = bs->opaque;
324
325
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_qed = {
326
.bdrv_co_pwrite_zeroes = bdrv_qed_co_pwrite_zeroes,
327
.bdrv_co_truncate = bdrv_qed_co_truncate,
328
.bdrv_co_getlength = bdrv_qed_co_getlength,
329
- .bdrv_get_info = bdrv_qed_get_info,
330
+ .bdrv_co_get_info = bdrv_qed_co_get_info,
331
.bdrv_refresh_limits = bdrv_qed_refresh_limits,
332
.bdrv_change_backing_file = bdrv_qed_change_backing_file,
333
.bdrv_co_invalidate_cache = bdrv_qed_co_invalidate_cache,
334
diff --git a/block/raw-format.c b/block/raw-format.c
335
index XXXXXXX..XXXXXXX 100644
336
--- a/block/raw-format.c
337
+++ b/block/raw-format.c
338
@@ -XXX,XX +XXX,XX @@ static BlockMeasureInfo *raw_measure(QemuOpts *opts, BlockDriverState *in_bs,
339
return info;
340
}
341
342
-static int raw_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
343
+static int coroutine_fn
344
+raw_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
345
{
346
- return bdrv_get_info(bs->file->bs, bdi);
347
+ return bdrv_co_get_info(bs->file->bs, bdi);
348
}
349
350
static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
351
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_raw = {
352
.is_format = true,
353
.has_variable_length = true,
354
.bdrv_measure = &raw_measure,
355
- .bdrv_get_info = &raw_get_info,
356
+ .bdrv_co_get_info = &raw_co_get_info,
357
.bdrv_refresh_limits = &raw_refresh_limits,
358
.bdrv_probe_blocksizes = &raw_probe_blocksizes,
359
.bdrv_probe_geometry = &raw_probe_geometry,
360
diff --git a/block/rbd.c b/block/rbd.c
361
index XXXXXXX..XXXXXXX 100644
362
--- a/block/rbd.c
363
+++ b/block/rbd.c
364
@@ -XXX,XX +XXX,XX @@ coroutine_fn qemu_rbd_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
365
}
366
#endif
367
368
-static int qemu_rbd_getinfo(BlockDriverState *bs, BlockDriverInfo *bdi)
369
+static int coroutine_fn
370
+qemu_rbd_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
371
{
372
BDRVRBDState *s = bs->opaque;
373
bdi->cluster_size = s->object_size;
374
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_rbd = {
375
.bdrv_co_create = qemu_rbd_co_create,
376
.bdrv_co_create_opts = qemu_rbd_co_create_opts,
377
.bdrv_has_zero_init = bdrv_has_zero_init_1,
378
- .bdrv_get_info = qemu_rbd_getinfo,
379
+ .bdrv_co_get_info = qemu_rbd_co_get_info,
380
.bdrv_get_specific_info = qemu_rbd_get_specific_info,
381
.create_opts = &qemu_rbd_create_opts,
382
.bdrv_co_getlength = qemu_rbd_co_getlength,
383
diff --git a/block/vdi.c b/block/vdi.c
384
index XXXXXXX..XXXXXXX 100644
385
--- a/block/vdi.c
386
+++ b/block/vdi.c
387
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vdi_co_check(BlockDriverState *bs, BdrvCheckResult *res,
388
return 0;
389
}
390
391
-static int vdi_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
392
+static int coroutine_fn
393
+vdi_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
394
{
395
- /* TODO: vdi_get_info would be needed for machine snapshots.
396
+ /* TODO: vdi_co_get_info would be needed for machine snapshots.
397
vm_state_offset is still missing. */
398
BDRVVdiState *s = (BDRVVdiState *)bs->opaque;
399
logout("\n");
400
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_vdi = {
401
.bdrv_co_pwritev = vdi_co_pwritev,
402
#endif
403
404
- .bdrv_get_info = vdi_get_info,
405
+ .bdrv_co_get_info = vdi_co_get_info,
406
407
.is_format = true,
408
.create_opts = &vdi_create_opts,
409
diff --git a/block/vhdx.c b/block/vhdx.c
410
index XXXXXXX..XXXXXXX 100644
411
--- a/block/vhdx.c
412
+++ b/block/vhdx.c
413
@@ -XXX,XX +XXX,XX @@ static void vhdx_block_translate(BDRVVHDXState *s, int64_t sector_num,
414
}
415
416
417
-static int vhdx_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
418
+static int coroutine_fn
419
+vhdx_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
420
{
421
BDRVVHDXState *s = bs->opaque;
422
423
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_vhdx = {
424
.bdrv_co_writev = vhdx_co_writev,
425
.bdrv_co_create = vhdx_co_create,
426
.bdrv_co_create_opts = vhdx_co_create_opts,
427
- .bdrv_get_info = vhdx_get_info,
428
+ .bdrv_co_get_info = vhdx_co_get_info,
429
.bdrv_co_check = vhdx_co_check,
430
.bdrv_has_zero_init = vhdx_has_zero_init,
431
432
diff --git a/block/vmdk.c b/block/vmdk.c
433
index XXXXXXX..XXXXXXX 100644
434
--- a/block/vmdk.c
435
+++ b/block/vmdk.c
436
@@ -XXX,XX +XXX,XX @@ static bool vmdk_extents_type_eq(const VmdkExtent *a, const VmdkExtent *b)
437
(a->flat || a->cluster_sectors == b->cluster_sectors);
438
}
439
440
-static int vmdk_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
441
+static int coroutine_fn
442
+vmdk_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
443
{
444
int i;
445
BDRVVmdkState *s = bs->opaque;
446
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_vmdk = {
447
.bdrv_has_zero_init = vmdk_has_zero_init,
448
.bdrv_get_specific_info = vmdk_get_specific_info,
449
.bdrv_refresh_limits = vmdk_refresh_limits,
450
- .bdrv_get_info = vmdk_get_info,
451
+ .bdrv_co_get_info = vmdk_co_get_info,
452
.bdrv_gather_child_options = vmdk_gather_child_options,
453
454
.is_format = true,
455
diff --git a/block/vpc.c b/block/vpc.c
456
index XXXXXXX..XXXXXXX 100644
457
--- a/block/vpc.c
458
+++ b/block/vpc.c
459
@@ -XXX,XX +XXX,XX @@ fail:
460
return ret;
461
}
462
463
-static int vpc_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
464
+static int coroutine_fn
465
+vpc_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
466
{
467
BDRVVPCState *s = (BDRVVPCState *)bs->opaque;
468
469
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_vpc = {
470
.bdrv_co_pwritev = vpc_co_pwritev,
471
.bdrv_co_block_status = vpc_co_block_status,
472
473
- .bdrv_get_info = vpc_get_info,
474
+ .bdrv_co_get_info = vpc_co_get_info,
475
476
.is_format = true,
477
.create_opts = &vpc_create_opts,
28
--
478
--
29
2.29.2
479
2.38.1
30
31
diff view generated by jsdifflib
New patch
1
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
2
3
bdrv_eject() is categorized as an I/O function, and it currently
4
doesn't run in a coroutine. We should let it take a graph rdlock since
5
it traverses the block nodes graph, which however is only possible in a
6
coroutine.
7
8
The only caller of this function is blk_eject(). Therefore make
9
blk_eject() a co_wrapper, so that it always creates a new coroutine, and
10
then make bdrv_eject() coroutine_fn where the lock can be taken.
11
12
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
Message-Id: <20230113204212.359076-12-kwolf@redhat.com>
15
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
---
18
include/block/block-io.h | 3 ++-
19
include/block/block_int-common.h | 2 +-
20
include/sysemu/block-backend-io.h | 4 +++-
21
block.c | 6 +++---
22
block/block-backend.c | 4 ++--
23
block/copy-on-read.c | 6 +++---
24
block/file-posix.c | 8 ++++----
25
block/filter-compress.c | 7 ++++---
26
block/raw-format.c | 6 +++---
27
9 files changed, 25 insertions(+), 21 deletions(-)
28
29
diff --git a/include/block/block-io.h b/include/block/block-io.h
30
index XXXXXXX..XXXXXXX 100644
31
--- a/include/block/block-io.h
32
+++ b/include/block/block-io.h
33
@@ -XXX,XX +XXX,XX @@ bool coroutine_fn bdrv_co_is_inserted(BlockDriverState *bs);
34
bool co_wrapper bdrv_is_inserted(BlockDriverState *bs);
35
36
void bdrv_lock_medium(BlockDriverState *bs, bool locked);
37
-void bdrv_eject(BlockDriverState *bs, bool eject_flag);
38
+void coroutine_fn bdrv_co_eject(BlockDriverState *bs, bool eject_flag);
39
+
40
const char *bdrv_get_format_name(BlockDriverState *bs);
41
42
bool bdrv_supports_compressed_writes(BlockDriverState *bs);
43
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
44
index XXXXXXX..XXXXXXX 100644
45
--- a/include/block/block_int-common.h
46
+++ b/include/block/block_int-common.h
47
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
48
49
/* removable device specific */
50
bool coroutine_fn (*bdrv_co_is_inserted)(BlockDriverState *bs);
51
- void (*bdrv_eject)(BlockDriverState *bs, bool eject_flag);
52
+ void coroutine_fn (*bdrv_co_eject)(BlockDriverState *bs, bool eject_flag);
53
void (*bdrv_lock_medium)(BlockDriverState *bs, bool locked);
54
55
/* to control generic scsi devices */
56
diff --git a/include/sysemu/block-backend-io.h b/include/sysemu/block-backend-io.h
57
index XXXXXXX..XXXXXXX 100644
58
--- a/include/sysemu/block-backend-io.h
59
+++ b/include/sysemu/block-backend-io.h
60
@@ -XXX,XX +XXX,XX @@ bool co_wrapper_mixed blk_is_inserted(BlockBackend *blk);
61
62
bool blk_is_available(BlockBackend *blk);
63
void blk_lock_medium(BlockBackend *blk, bool locked);
64
-void blk_eject(BlockBackend *blk, bool eject_flag);
65
+
66
+void coroutine_fn blk_co_eject(BlockBackend *blk, bool eject_flag);
67
+void co_wrapper blk_eject(BlockBackend *blk, bool eject_flag);
68
69
int64_t coroutine_fn blk_co_getlength(BlockBackend *blk);
70
int64_t co_wrapper_mixed blk_getlength(BlockBackend *blk);
71
diff --git a/block.c b/block.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/block.c
74
+++ b/block.c
75
@@ -XXX,XX +XXX,XX @@ bool coroutine_fn bdrv_co_is_inserted(BlockDriverState *bs)
76
/**
77
* If eject_flag is TRUE, eject the media. Otherwise, close the tray
78
*/
79
-void bdrv_eject(BlockDriverState *bs, bool eject_flag)
80
+void coroutine_fn bdrv_co_eject(BlockDriverState *bs, bool eject_flag)
81
{
82
BlockDriver *drv = bs->drv;
83
IO_CODE();
84
85
- if (drv && drv->bdrv_eject) {
86
- drv->bdrv_eject(bs, eject_flag);
87
+ if (drv && drv->bdrv_co_eject) {
88
+ drv->bdrv_co_eject(bs, eject_flag);
89
}
90
}
91
92
diff --git a/block/block-backend.c b/block/block-backend.c
93
index XXXXXXX..XXXXXXX 100644
94
--- a/block/block-backend.c
95
+++ b/block/block-backend.c
96
@@ -XXX,XX +XXX,XX @@ void blk_lock_medium(BlockBackend *blk, bool locked)
97
}
98
}
99
100
-void blk_eject(BlockBackend *blk, bool eject_flag)
101
+void coroutine_fn blk_co_eject(BlockBackend *blk, bool eject_flag)
102
{
103
BlockDriverState *bs = blk_bs(blk);
104
char *id;
105
IO_CODE();
106
107
if (bs) {
108
- bdrv_eject(bs, eject_flag);
109
+ bdrv_co_eject(bs, eject_flag);
110
}
111
112
/* Whether or not we ejected on the backend,
113
diff --git a/block/copy-on-read.c b/block/copy-on-read.c
114
index XXXXXXX..XXXXXXX 100644
115
--- a/block/copy-on-read.c
116
+++ b/block/copy-on-read.c
117
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn cor_co_pwritev_compressed(BlockDriverState *bs,
118
}
119
120
121
-static void cor_eject(BlockDriverState *bs, bool eject_flag)
122
+static void coroutine_fn cor_co_eject(BlockDriverState *bs, bool eject_flag)
123
{
124
- bdrv_eject(bs->file->bs, eject_flag);
125
+ bdrv_co_eject(bs->file->bs, eject_flag);
126
}
127
128
129
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_copy_on_read = {
130
.bdrv_co_pdiscard = cor_co_pdiscard,
131
.bdrv_co_pwritev_compressed = cor_co_pwritev_compressed,
132
133
- .bdrv_eject = cor_eject,
134
+ .bdrv_co_eject = cor_co_eject,
135
.bdrv_lock_medium = cor_lock_medium,
136
137
.has_variable_length = true,
138
diff --git a/block/file-posix.c b/block/file-posix.c
139
index XXXXXXX..XXXXXXX 100644
140
--- a/block/file-posix.c
141
+++ b/block/file-posix.c
142
@@ -XXX,XX +XXX,XX @@ static bool coroutine_fn cdrom_co_is_inserted(BlockDriverState *bs)
143
return ret == CDS_DISC_OK;
144
}
145
146
-static void cdrom_eject(BlockDriverState *bs, bool eject_flag)
147
+static void coroutine_fn cdrom_co_eject(BlockDriverState *bs, bool eject_flag)
148
{
149
BDRVRawState *s = bs->opaque;
150
151
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_cdrom = {
152
153
/* removable device support */
154
.bdrv_co_is_inserted = cdrom_co_is_inserted,
155
- .bdrv_eject = cdrom_eject,
156
+ .bdrv_co_eject = cdrom_co_eject,
157
.bdrv_lock_medium = cdrom_lock_medium,
158
159
/* generic scsi device */
160
@@ -XXX,XX +XXX,XX @@ static bool coroutine_fn cdrom_co_is_inserted(BlockDriverState *bs)
161
return raw_co_getlength(bs) > 0;
162
}
163
164
-static void cdrom_eject(BlockDriverState *bs, bool eject_flag)
165
+static void coroutine_fn cdrom_co_eject(BlockDriverState *bs, bool eject_flag)
166
{
167
BDRVRawState *s = bs->opaque;
168
169
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_cdrom = {
170
171
/* removable device support */
172
.bdrv_co_is_inserted = cdrom_co_is_inserted,
173
- .bdrv_eject = cdrom_eject,
174
+ .bdrv_co_eject = cdrom_co_eject,
175
.bdrv_lock_medium = cdrom_lock_medium,
176
};
177
#endif /* __FreeBSD__ */
178
diff --git a/block/filter-compress.c b/block/filter-compress.c
179
index XXXXXXX..XXXXXXX 100644
180
--- a/block/filter-compress.c
181
+++ b/block/filter-compress.c
182
@@ -XXX,XX +XXX,XX @@ static void compress_refresh_limits(BlockDriverState *bs, Error **errp)
183
}
184
185
186
-static void compress_eject(BlockDriverState *bs, bool eject_flag)
187
+static void coroutine_fn
188
+compress_co_eject(BlockDriverState *bs, bool eject_flag)
189
{
190
- bdrv_eject(bs->file->bs, eject_flag);
191
+ bdrv_co_eject(bs->file->bs, eject_flag);
192
}
193
194
195
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_compress = {
196
.bdrv_co_pdiscard = compress_co_pdiscard,
197
.bdrv_refresh_limits = compress_refresh_limits,
198
199
- .bdrv_eject = compress_eject,
200
+ .bdrv_co_eject = compress_co_eject,
201
.bdrv_lock_medium = compress_lock_medium,
202
203
.has_variable_length = true,
204
diff --git a/block/raw-format.c b/block/raw-format.c
205
index XXXXXXX..XXXXXXX 100644
206
--- a/block/raw-format.c
207
+++ b/block/raw-format.c
208
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
209
return bdrv_co_truncate(bs->file, offset, exact, prealloc, flags, errp);
210
}
211
212
-static void raw_eject(BlockDriverState *bs, bool eject_flag)
213
+static void coroutine_fn raw_co_eject(BlockDriverState *bs, bool eject_flag)
214
{
215
- bdrv_eject(bs->file->bs, eject_flag);
216
+ bdrv_co_eject(bs->file->bs, eject_flag);
217
}
218
219
static void raw_lock_medium(BlockDriverState *bs, bool locked)
220
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_raw = {
221
.bdrv_refresh_limits = &raw_refresh_limits,
222
.bdrv_probe_blocksizes = &raw_probe_blocksizes,
223
.bdrv_probe_geometry = &raw_probe_geometry,
224
- .bdrv_eject = &raw_eject,
225
+ .bdrv_co_eject = &raw_co_eject,
226
.bdrv_lock_medium = &raw_lock_medium,
227
.bdrv_co_ioctl = &raw_co_ioctl,
228
.create_opts = &raw_create_opts,
229
--
230
2.38.1
diff view generated by jsdifflib
New patch
1
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
2
3
bdrv_lock_medium() is categorized as an I/O function, and it currently
4
doesn't run in a coroutine. We should let it take a graph rdlock since
5
it traverses the block nodes graph, which however is only possible in a
6
coroutine.
7
8
The only caller of this function is blk_lock_medium(). Therefore make
9
blk_lock_medium() a co_wrapper, so that it always creates a new
10
coroutine, and then make bdrv_lock_medium() a coroutine_fn where the
11
lock can be taken.
12
13
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
Message-Id: <20230113204212.359076-13-kwolf@redhat.com>
16
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
---
19
include/block/block-io.h | 2 +-
20
include/block/block_int-common.h | 2 +-
21
include/sysemu/block-backend-io.h | 4 +++-
22
block.c | 6 +++---
23
block/block-backend.c | 4 ++--
24
block/copy-on-read.c | 6 +++---
25
block/file-posix.c | 8 ++++----
26
block/filter-compress.c | 7 ++++---
27
block/raw-format.c | 6 +++---
28
9 files changed, 24 insertions(+), 21 deletions(-)
29
30
diff --git a/include/block/block-io.h b/include/block/block-io.h
31
index XXXXXXX..XXXXXXX 100644
32
--- a/include/block/block-io.h
33
+++ b/include/block/block-io.h
34
@@ -XXX,XX +XXX,XX @@ int bdrv_get_flags(BlockDriverState *bs);
35
bool coroutine_fn bdrv_co_is_inserted(BlockDriverState *bs);
36
bool co_wrapper bdrv_is_inserted(BlockDriverState *bs);
37
38
-void bdrv_lock_medium(BlockDriverState *bs, bool locked);
39
+void coroutine_fn bdrv_co_lock_medium(BlockDriverState *bs, bool locked);
40
void coroutine_fn bdrv_co_eject(BlockDriverState *bs, bool eject_flag);
41
42
const char *bdrv_get_format_name(BlockDriverState *bs);
43
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
44
index XXXXXXX..XXXXXXX 100644
45
--- a/include/block/block_int-common.h
46
+++ b/include/block/block_int-common.h
47
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
48
/* removable device specific */
49
bool coroutine_fn (*bdrv_co_is_inserted)(BlockDriverState *bs);
50
void coroutine_fn (*bdrv_co_eject)(BlockDriverState *bs, bool eject_flag);
51
- void (*bdrv_lock_medium)(BlockDriverState *bs, bool locked);
52
+ void coroutine_fn (*bdrv_co_lock_medium)(BlockDriverState *bs, bool locked);
53
54
/* to control generic scsi devices */
55
BlockAIOCB *(*bdrv_aio_ioctl)(BlockDriverState *bs,
56
diff --git a/include/sysemu/block-backend-io.h b/include/sysemu/block-backend-io.h
57
index XXXXXXX..XXXXXXX 100644
58
--- a/include/sysemu/block-backend-io.h
59
+++ b/include/sysemu/block-backend-io.h
60
@@ -XXX,XX +XXX,XX @@ bool coroutine_fn blk_co_is_inserted(BlockBackend *blk);
61
bool co_wrapper_mixed blk_is_inserted(BlockBackend *blk);
62
63
bool blk_is_available(BlockBackend *blk);
64
-void blk_lock_medium(BlockBackend *blk, bool locked);
65
+
66
+void coroutine_fn blk_co_lock_medium(BlockBackend *blk, bool locked);
67
+void co_wrapper blk_lock_medium(BlockBackend *blk, bool locked);
68
69
void coroutine_fn blk_co_eject(BlockBackend *blk, bool eject_flag);
70
void co_wrapper blk_eject(BlockBackend *blk, bool eject_flag);
71
diff --git a/block.c b/block.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/block.c
74
+++ b/block.c
75
@@ -XXX,XX +XXX,XX @@ void coroutine_fn bdrv_co_eject(BlockDriverState *bs, bool eject_flag)
76
* Lock or unlock the media (if it is locked, the user won't be able
77
* to eject it manually).
78
*/
79
-void bdrv_lock_medium(BlockDriverState *bs, bool locked)
80
+void coroutine_fn bdrv_co_lock_medium(BlockDriverState *bs, bool locked)
81
{
82
BlockDriver *drv = bs->drv;
83
IO_CODE();
84
trace_bdrv_lock_medium(bs, locked);
85
86
- if (drv && drv->bdrv_lock_medium) {
87
- drv->bdrv_lock_medium(bs, locked);
88
+ if (drv && drv->bdrv_co_lock_medium) {
89
+ drv->bdrv_co_lock_medium(bs, locked);
90
}
91
}
92
93
diff --git a/block/block-backend.c b/block/block-backend.c
94
index XXXXXXX..XXXXXXX 100644
95
--- a/block/block-backend.c
96
+++ b/block/block-backend.c
97
@@ -XXX,XX +XXX,XX @@ bool blk_is_available(BlockBackend *blk)
98
return blk_is_inserted(blk) && !blk_dev_is_tray_open(blk);
99
}
100
101
-void blk_lock_medium(BlockBackend *blk, bool locked)
102
+void coroutine_fn blk_co_lock_medium(BlockBackend *blk, bool locked)
103
{
104
BlockDriverState *bs = blk_bs(blk);
105
IO_CODE();
106
107
if (bs) {
108
- bdrv_lock_medium(bs, locked);
109
+ bdrv_co_lock_medium(bs, locked);
110
}
111
}
112
113
diff --git a/block/copy-on-read.c b/block/copy-on-read.c
114
index XXXXXXX..XXXXXXX 100644
115
--- a/block/copy-on-read.c
116
+++ b/block/copy-on-read.c
117
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn cor_co_eject(BlockDriverState *bs, bool eject_flag)
118
}
119
120
121
-static void cor_lock_medium(BlockDriverState *bs, bool locked)
122
+static void coroutine_fn cor_co_lock_medium(BlockDriverState *bs, bool locked)
123
{
124
- bdrv_lock_medium(bs->file->bs, locked);
125
+ bdrv_co_lock_medium(bs->file->bs, locked);
126
}
127
128
129
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_copy_on_read = {
130
.bdrv_co_pwritev_compressed = cor_co_pwritev_compressed,
131
132
.bdrv_co_eject = cor_co_eject,
133
- .bdrv_lock_medium = cor_lock_medium,
134
+ .bdrv_co_lock_medium = cor_co_lock_medium,
135
136
.has_variable_length = true,
137
.is_filter = true,
138
diff --git a/block/file-posix.c b/block/file-posix.c
139
index XXXXXXX..XXXXXXX 100644
140
--- a/block/file-posix.c
141
+++ b/block/file-posix.c
142
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn cdrom_co_eject(BlockDriverState *bs, bool eject_flag)
143
}
144
}
145
146
-static void cdrom_lock_medium(BlockDriverState *bs, bool locked)
147
+static void coroutine_fn cdrom_co_lock_medium(BlockDriverState *bs, bool locked)
148
{
149
BDRVRawState *s = bs->opaque;
150
151
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_cdrom = {
152
/* removable device support */
153
.bdrv_co_is_inserted = cdrom_co_is_inserted,
154
.bdrv_co_eject = cdrom_co_eject,
155
- .bdrv_lock_medium = cdrom_lock_medium,
156
+ .bdrv_co_lock_medium = cdrom_co_lock_medium,
157
158
/* generic scsi device */
159
.bdrv_co_ioctl = hdev_co_ioctl,
160
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn cdrom_co_eject(BlockDriverState *bs, bool eject_flag)
161
cdrom_reopen(bs);
162
}
163
164
-static void cdrom_lock_medium(BlockDriverState *bs, bool locked)
165
+static void coroutine_fn cdrom_co_lock_medium(BlockDriverState *bs, bool locked)
166
{
167
BDRVRawState *s = bs->opaque;
168
169
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_cdrom = {
170
/* removable device support */
171
.bdrv_co_is_inserted = cdrom_co_is_inserted,
172
.bdrv_co_eject = cdrom_co_eject,
173
- .bdrv_lock_medium = cdrom_lock_medium,
174
+ .bdrv_co_lock_medium = cdrom_co_lock_medium,
175
};
176
#endif /* __FreeBSD__ */
177
178
diff --git a/block/filter-compress.c b/block/filter-compress.c
179
index XXXXXXX..XXXXXXX 100644
180
--- a/block/filter-compress.c
181
+++ b/block/filter-compress.c
182
@@ -XXX,XX +XXX,XX @@ compress_co_eject(BlockDriverState *bs, bool eject_flag)
183
}
184
185
186
-static void compress_lock_medium(BlockDriverState *bs, bool locked)
187
+static void coroutine_fn
188
+compress_co_lock_medium(BlockDriverState *bs, bool locked)
189
{
190
- bdrv_lock_medium(bs->file->bs, locked);
191
+ bdrv_co_lock_medium(bs->file->bs, locked);
192
}
193
194
195
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_compress = {
196
.bdrv_refresh_limits = compress_refresh_limits,
197
198
.bdrv_co_eject = compress_co_eject,
199
- .bdrv_lock_medium = compress_lock_medium,
200
+ .bdrv_co_lock_medium = compress_co_lock_medium,
201
202
.has_variable_length = true,
203
.is_filter = true,
204
diff --git a/block/raw-format.c b/block/raw-format.c
205
index XXXXXXX..XXXXXXX 100644
206
--- a/block/raw-format.c
207
+++ b/block/raw-format.c
208
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn raw_co_eject(BlockDriverState *bs, bool eject_flag)
209
bdrv_co_eject(bs->file->bs, eject_flag);
210
}
211
212
-static void raw_lock_medium(BlockDriverState *bs, bool locked)
213
+static void coroutine_fn raw_co_lock_medium(BlockDriverState *bs, bool locked)
214
{
215
- bdrv_lock_medium(bs->file->bs, locked);
216
+ bdrv_co_lock_medium(bs->file->bs, locked);
217
}
218
219
static int coroutine_fn raw_co_ioctl(BlockDriverState *bs,
220
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_raw = {
221
.bdrv_probe_blocksizes = &raw_probe_blocksizes,
222
.bdrv_probe_geometry = &raw_probe_geometry,
223
.bdrv_co_eject = &raw_co_eject,
224
- .bdrv_lock_medium = &raw_lock_medium,
225
+ .bdrv_co_lock_medium = &raw_co_lock_medium,
226
.bdrv_co_ioctl = &raw_co_ioctl,
227
.create_opts = &raw_create_opts,
228
.bdrv_has_zero_init = &raw_has_zero_init,
229
--
230
2.38.1
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
bdrv_debug_event() is categorized as an I/O function, and it currently
4
doesn't run in a coroutine. We should let it take a graph rdlock since
5
it traverses the block nodes graph, which however is only possible in a
6
coroutine.
7
8
Therefore turn it into a co_wrapper_mixed to move the actual function
9
into a coroutine where the lock can be taken.
10
11
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
Message-Id: <20230113204212.359076-14-kwolf@redhat.com>
14
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
15
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
---
17
include/block/block-io.h | 5 ++++-
18
include/block/block_int-common.h | 3 ++-
19
block.c | 6 +++---
20
block/blkdebug.c | 5 +++--
21
block/io.c | 22 +++++++++++-----------
22
5 files changed, 23 insertions(+), 18 deletions(-)
23
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 bdrv_debug_event(BlockDriverState *bs, BlkdebugEvent event);
33
+void coroutine_fn bdrv_co_debug_event(BlockDriverState *bs,
34
+ BlkdebugEvent event);
35
+void co_wrapper_mixed bdrv_debug_event(BlockDriverState *bs,
36
+ BlkdebugEvent event);
37
38
#define BLKDBG_EVENT(child, evt) \
39
do { \
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
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_check)(
46
BlockDriverState *bs, BdrvCheckResult *result, BdrvCheckMode fix);
47
48
- void (*bdrv_debug_event)(BlockDriverState *bs, BlkdebugEvent event);
49
+ void coroutine_fn (*bdrv_co_debug_event)(BlockDriverState *bs,
50
+ BlkdebugEvent event);
51
52
/* io queue for linux-aio */
53
void coroutine_fn (*bdrv_co_io_plug)(BlockDriverState *bs);
54
diff --git a/block.c b/block.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/block.c
57
+++ b/block.c
58
@@ -XXX,XX +XXX,XX @@ BlockStatsSpecific *bdrv_get_specific_stats(BlockDriverState *bs)
59
return drv->bdrv_get_specific_stats(bs);
60
}
61
62
-void bdrv_debug_event(BlockDriverState *bs, BlkdebugEvent event)
63
+void coroutine_fn bdrv_co_debug_event(BlockDriverState *bs, BlkdebugEvent event)
64
{
65
IO_CODE();
66
- if (!bs || !bs->drv || !bs->drv->bdrv_debug_event) {
67
+ if (!bs || !bs->drv || !bs->drv->bdrv_co_debug_event) {
68
return;
69
}
70
71
- bs->drv->bdrv_debug_event(bs, event);
72
+ bs->drv->bdrv_co_debug_event(bs, event);
73
}
74
75
static BlockDriverState *bdrv_find_debug_node(BlockDriverState *bs)
76
diff --git a/block/blkdebug.c b/block/blkdebug.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/block/blkdebug.c
79
+++ b/block/blkdebug.c
80
@@ -XXX,XX +XXX,XX @@ static void process_rule(BlockDriverState *bs, struct BlkdebugRule *rule,
81
}
82
}
83
84
-static void blkdebug_debug_event(BlockDriverState *bs, BlkdebugEvent event)
85
+static void coroutine_fn
86
+blkdebug_co_debug_event(BlockDriverState *bs, BlkdebugEvent event)
87
{
88
BDRVBlkdebugState *s = bs->opaque;
89
struct BlkdebugRule *rule, *next;
90
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_blkdebug = {
91
.bdrv_co_pdiscard = blkdebug_co_pdiscard,
92
.bdrv_co_block_status = blkdebug_co_block_status,
93
94
- .bdrv_debug_event = blkdebug_debug_event,
95
+ .bdrv_co_debug_event = blkdebug_co_debug_event,
96
.bdrv_debug_breakpoint = blkdebug_debug_breakpoint,
97
.bdrv_debug_remove_breakpoint
98
= blkdebug_debug_remove_breakpoint,
99
diff --git a/block/io.c b/block/io.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/block/io.c
102
+++ b/block/io.c
103
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child,
104
goto err;
105
}
106
107
- bdrv_debug_event(bs, BLKDBG_COR_WRITE);
108
+ bdrv_co_debug_event(bs, BLKDBG_COR_WRITE);
109
if (drv->bdrv_co_pwrite_zeroes &&
110
buffer_is_zero(bounce_buffer, pnum)) {
111
/* FIXME: Should we (perhaps conditionally) be setting
112
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int bdrv_padding_rmw_read(BdrvChild *child,
113
qemu_iovec_init_buf(&local_qiov, pad->buf, bytes);
114
115
if (pad->head) {
116
- bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_HEAD);
117
+ bdrv_co_debug_event(bs, BLKDBG_PWRITEV_RMW_HEAD);
118
}
119
if (pad->merge_reads && pad->tail) {
120
- bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_TAIL);
121
+ bdrv_co_debug_event(bs, BLKDBG_PWRITEV_RMW_TAIL);
122
}
123
ret = bdrv_aligned_preadv(child, req, req->overlap_offset, bytes,
124
align, &local_qiov, 0, 0);
125
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int bdrv_padding_rmw_read(BdrvChild *child,
126
return ret;
127
}
128
if (pad->head) {
129
- bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_HEAD);
130
+ bdrv_co_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_HEAD);
131
}
132
if (pad->merge_reads && pad->tail) {
133
- bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_TAIL);
134
+ bdrv_co_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_TAIL);
135
}
136
137
if (pad->merge_reads) {
138
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int bdrv_padding_rmw_read(BdrvChild *child,
139
if (pad->tail) {
140
qemu_iovec_init_buf(&local_qiov, pad->tail_buf, align);
141
142
- bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_TAIL);
143
+ bdrv_co_debug_event(bs, BLKDBG_PWRITEV_RMW_TAIL);
144
ret = bdrv_aligned_preadv(
145
child, req,
146
req->overlap_offset + req->overlap_bytes - align,
147
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int bdrv_padding_rmw_read(BdrvChild *child,
148
if (ret < 0) {
149
return ret;
150
}
151
- bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_TAIL);
152
+ bdrv_co_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_TAIL);
153
}
154
155
zero_mem:
156
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child,
157
if (ret < 0) {
158
/* Do nothing, write notifier decided to fail this request */
159
} else if (flags & BDRV_REQ_ZERO_WRITE) {
160
- bdrv_debug_event(bs, BLKDBG_PWRITEV_ZERO);
161
+ bdrv_co_debug_event(bs, BLKDBG_PWRITEV_ZERO);
162
ret = bdrv_co_do_pwrite_zeroes(bs, offset, bytes, flags);
163
} else if (flags & BDRV_REQ_WRITE_COMPRESSED) {
164
ret = bdrv_driver_pwritev_compressed(bs, offset, bytes,
165
qiov, qiov_offset);
166
} else if (bytes <= max_transfer) {
167
- bdrv_debug_event(bs, BLKDBG_PWRITEV);
168
+ bdrv_co_debug_event(bs, BLKDBG_PWRITEV);
169
ret = bdrv_driver_pwritev(bs, offset, bytes, qiov, qiov_offset, flags);
170
} else {
171
- bdrv_debug_event(bs, BLKDBG_PWRITEV);
172
+ bdrv_co_debug_event(bs, BLKDBG_PWRITEV);
173
while (bytes_remaining) {
174
int num = MIN(bytes_remaining, max_transfer);
175
int local_flags = flags;
176
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child,
177
bytes_remaining -= num;
178
}
179
}
180
- bdrv_debug_event(bs, BLKDBG_PWRITEV_DONE);
181
+ bdrv_co_debug_event(bs, BLKDBG_PWRITEV_DONE);
182
183
if (ret >= 0) {
184
ret = 0;
185
--
186
2.38.1
diff view generated by jsdifflib
1
From: Maxim Levitsky <mlevitsk@redhat.com>
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
2
2
3
If the qcow initialization fails, we should remove the file if it was
3
Since these functions always run in coroutine context, adjust
4
already created, to avoid leaving stale files around.
4
their name to include "_co_", just like all other BlockDriver callbacks.
5
5
6
We already do this for luks raw images.
6
No functional change intended.
7
7
8
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
8
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
9
Reviewed-by: Alberto Garcia <berto@igalia.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Message-Id: <20201217170904.946013-4-mlevitsk@redhat.com>
10
Message-Id: <20230113204212.359076-15-kwolf@redhat.com>
11
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
11
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
13
---
14
block/qcow2.c | 8 +++++---
14
include/block/block_int-common.h | 4 ++--
15
1 file changed, 5 insertions(+), 3 deletions(-)
15
block/io.c | 8 ++++----
16
block/qcow2.c | 12 ++++++------
17
3 files changed, 12 insertions(+), 12 deletions(-)
16
18
19
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/include/block/block_int-common.h
22
+++ b/include/block/block_int-common.h
23
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
24
Error **errp);
25
BlockStatsSpecific *(*bdrv_get_specific_stats)(BlockDriverState *bs);
26
27
- int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_save_vmstate)(
28
+ int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_save_vmstate)(
29
BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos);
30
31
- int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_load_vmstate)(
32
+ int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_load_vmstate)(
33
BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos);
34
35
/* removable device specific */
36
diff --git a/block/io.c b/block/io.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/block/io.c
39
+++ b/block/io.c
40
@@ -XXX,XX +XXX,XX @@ bdrv_co_readv_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos)
41
42
bdrv_inc_in_flight(bs);
43
44
- if (drv->bdrv_load_vmstate) {
45
- ret = drv->bdrv_load_vmstate(bs, qiov, pos);
46
+ if (drv->bdrv_co_load_vmstate) {
47
+ ret = drv->bdrv_co_load_vmstate(bs, qiov, pos);
48
} else if (child_bs) {
49
ret = bdrv_co_readv_vmstate(child_bs, qiov, pos);
50
} else {
51
@@ -XXX,XX +XXX,XX @@ bdrv_co_writev_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos)
52
53
bdrv_inc_in_flight(bs);
54
55
- if (drv->bdrv_save_vmstate) {
56
- ret = drv->bdrv_save_vmstate(bs, qiov, pos);
57
+ if (drv->bdrv_co_save_vmstate) {
58
+ ret = drv->bdrv_co_save_vmstate(bs, qiov, pos);
59
} else if (child_bs) {
60
ret = bdrv_co_writev_vmstate(child_bs, qiov, pos);
61
} else {
17
diff --git a/block/qcow2.c b/block/qcow2.c
62
diff --git a/block/qcow2.c b/block/qcow2.c
18
index XXXXXXX..XXXXXXX 100644
63
index XXXXXXX..XXXXXXX 100644
19
--- a/block/qcow2.c
64
--- a/block/qcow2.c
20
+++ b/block/qcow2.c
65
+++ b/block/qcow2.c
21
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_create_opts(BlockDriver *drv,
66
@@ -XXX,XX +XXX,XX @@ static int64_t qcow2_check_vmstate_request(BlockDriverState *bs,
22
67
return pos;
23
/* Create the qcow2 image (format layer) */
68
}
24
ret = qcow2_co_create(create_options, errp);
69
25
+finish:
70
-static coroutine_fn int qcow2_save_vmstate(BlockDriverState *bs,
26
if (ret < 0) {
71
- QEMUIOVector *qiov, int64_t pos)
27
- goto finish;
72
+static coroutine_fn int qcow2_co_save_vmstate(BlockDriverState *bs,
28
+ bdrv_co_delete_file_noerr(bs);
73
+ QEMUIOVector *qiov, int64_t pos)
29
+ bdrv_co_delete_file_noerr(data_bs);
74
{
30
+ } else {
75
int64_t offset = qcow2_check_vmstate_request(bs, qiov, pos);
31
+ ret = 0;
76
if (offset < 0) {
32
}
77
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_save_vmstate(BlockDriverState *bs,
33
78
return bs->drv->bdrv_co_pwritev_part(bs, offset, qiov->size, qiov, 0, 0);
34
- ret = 0;
79
}
35
-finish:
80
36
qobject_unref(qdict);
81
-static coroutine_fn int qcow2_load_vmstate(BlockDriverState *bs,
37
bdrv_unref(bs);
82
- QEMUIOVector *qiov, int64_t pos)
38
bdrv_unref(data_bs);
83
+static coroutine_fn int qcow2_co_load_vmstate(BlockDriverState *bs,
84
+ QEMUIOVector *qiov, int64_t pos)
85
{
86
int64_t offset = qcow2_check_vmstate_request(bs, qiov, pos);
87
if (offset < 0) {
88
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_qcow2 = {
89
.bdrv_co_get_info = qcow2_co_get_info,
90
.bdrv_get_specific_info = qcow2_get_specific_info,
91
92
- .bdrv_save_vmstate = qcow2_save_vmstate,
93
- .bdrv_load_vmstate = qcow2_load_vmstate,
94
+ .bdrv_co_save_vmstate = qcow2_co_save_vmstate,
95
+ .bdrv_co_load_vmstate = qcow2_co_load_vmstate,
96
97
.is_format = true,
98
.supports_backing = true,
39
--
99
--
40
2.29.2
100
2.38.1
41
42
diff view generated by jsdifflib
1
As we don't have a fully QAPIfied version of object-add yet and it still
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
has 'gen': false in the schema, it needs to be registered explicitly in
3
init_qmp_commands() to be available for users.
4
2
5
Fixes: 2af282ec51a27116d0402cab237b8970800f870c
3
The inlined nbd_readXX() functions call beXX_to_cpu(), themselves
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
declared in <qemu/bswap.h>. This fixes when refactoring:
7
Message-Id: <20210204072137.19663-1-kwolf@redhat.com>
5
8
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
6
In file included from ../../block/nbd.c:44:
7
include/block/nbd.h: In function 'nbd_read16':
8
include/block/nbd.h:383:12: error: implicit declaration of function 'be16_to_cpu' [-Werror=implicit-function-declaration]
9
383 | *val = be##bits##_to_cpu(*val); \
10
| ^~
11
include/block/nbd.h:387:1: note: in expansion of macro 'DEF_NBD_READ_N'
12
387 | DEF_NBD_READ_N(16) /* Defines nbd_read16(). */
13
| ^~~~~~~~~~~~~~
14
15
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
16
Message-Id: <20221125175328.48539-1-philmd@linaro.org>
17
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
18
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
19
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
20
---
11
storage-daemon/qemu-storage-daemon.c | 2 ++
21
include/block/nbd.h | 1 +
12
1 file changed, 2 insertions(+)
22
1 file changed, 1 insertion(+)
13
23
14
diff --git a/storage-daemon/qemu-storage-daemon.c b/storage-daemon/qemu-storage-daemon.c
24
diff --git a/include/block/nbd.h b/include/block/nbd.h
15
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
16
--- a/storage-daemon/qemu-storage-daemon.c
26
--- a/include/block/nbd.h
17
+++ b/storage-daemon/qemu-storage-daemon.c
27
+++ b/include/block/nbd.h
18
@@ -XXX,XX +XXX,XX @@ static void init_qmp_commands(void)
28
@@ -XXX,XX +XXX,XX @@
19
qmp_init_marshal(&qmp_commands);
29
#include "io/channel-socket.h"
20
qmp_register_command(&qmp_commands, "query-qmp-schema",
30
#include "crypto/tlscreds.h"
21
qmp_query_qmp_schema, QCO_ALLOW_PRECONFIG);
31
#include "qapi/error.h"
22
+ qmp_register_command(&qmp_commands, "object-add", qmp_object_add,
32
+#include "qemu/bswap.h"
23
+ QCO_NO_OPTIONS);
33
24
34
extern const BlockExportDriver blk_exp_nbd;
25
QTAILQ_INIT(&qmp_cap_negotiation_commands);
35
26
qmp_register_command(&qmp_cap_negotiation_commands, "qmp_capabilities",
27
--
36
--
28
2.29.2
37
2.38.1
29
38
30
39
diff view generated by jsdifflib
New patch
1
From: Hanna Reitz <hreitz@redhat.com>
1
2
3
When a block driver supports obtaining format-specific information, but
4
that object only contains optional fields, it is possible that none of
5
them are present, so that dump_qobject() (called by
6
bdrv_image_info_specific_dump()) will not print anything.
7
8
The callers of bdrv_image_info_specific_dump() put a header above this
9
information ("Format specific information:\n"), which will look strange
10
when there is nothing below. Modify bdrv_image_info_specific_dump() to
11
print this header instead of its callers, and only if there is indeed
12
something to be printed.
13
14
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
15
Message-Id: <20220620162704.80987-2-hreitz@redhat.com>
16
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
---
19
include/block/qapi.h | 3 ++-
20
block/qapi.c | 41 +++++++++++++++++++++++++++++++++++++----
21
qemu-io-cmds.c | 4 ++--
22
3 files changed, 41 insertions(+), 7 deletions(-)
23
24
diff --git a/include/block/qapi.h b/include/block/qapi.h
25
index XXXXXXX..XXXXXXX 100644
26
--- a/include/block/qapi.h
27
+++ b/include/block/qapi.h
28
@@ -XXX,XX +XXX,XX @@ void bdrv_query_image_info(BlockDriverState *bs,
29
Error **errp);
30
31
void bdrv_snapshot_dump(QEMUSnapshotInfo *sn);
32
-void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec);
33
+void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec,
34
+ const char *prefix);
35
void bdrv_image_info_dump(ImageInfo *info);
36
#endif
37
diff --git a/block/qapi.c b/block/qapi.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/block/qapi.c
40
+++ b/block/qapi.c
41
@@ -XXX,XX +XXX,XX @@ static void dump_qdict(int indentation, QDict *dict)
42
}
43
}
44
45
-void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec)
46
+/*
47
+ * Return whether dumping the given QObject with dump_qobject() would
48
+ * yield an empty dump, i.e. not print anything.
49
+ */
50
+static bool qobject_is_empty_dump(const QObject *obj)
51
+{
52
+ switch (qobject_type(obj)) {
53
+ case QTYPE_QNUM:
54
+ case QTYPE_QSTRING:
55
+ case QTYPE_QBOOL:
56
+ return false;
57
+
58
+ case QTYPE_QDICT:
59
+ return qdict_size(qobject_to(QDict, obj)) == 0;
60
+
61
+ case QTYPE_QLIST:
62
+ return qlist_empty(qobject_to(QList, obj));
63
+
64
+ default:
65
+ abort();
66
+ }
67
+}
68
+
69
+/**
70
+ * Dumps the given ImageInfoSpecific object in a human-readable form,
71
+ * prepending an optional prefix if the dump is not empty.
72
+ */
73
+void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec,
74
+ const char *prefix)
75
{
76
QObject *obj, *data;
77
Visitor *v = qobject_output_visitor_new(&obj);
78
@@ -XXX,XX +XXX,XX @@ void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec)
79
visit_type_ImageInfoSpecific(v, NULL, &info_spec, &error_abort);
80
visit_complete(v, &obj);
81
data = qdict_get(qobject_to(QDict, obj), "data");
82
- dump_qobject(1, data);
83
+ if (!qobject_is_empty_dump(data)) {
84
+ if (prefix) {
85
+ qemu_printf("%s", prefix);
86
+ }
87
+ dump_qobject(1, data);
88
+ }
89
qobject_unref(obj);
90
visit_free(v);
91
}
92
@@ -XXX,XX +XXX,XX @@ void bdrv_image_info_dump(ImageInfo *info)
93
}
94
95
if (info->format_specific) {
96
- qemu_printf("Format specific information:\n");
97
- bdrv_image_info_specific_dump(info->format_specific);
98
+ bdrv_image_info_specific_dump(info->format_specific,
99
+ "Format specific information:\n");
100
}
101
}
102
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
103
index XXXXXXX..XXXXXXX 100644
104
--- a/qemu-io-cmds.c
105
+++ b/qemu-io-cmds.c
106
@@ -XXX,XX +XXX,XX @@ static int info_f(BlockBackend *blk, int argc, char **argv)
107
return -EIO;
108
}
109
if (spec_info) {
110
- printf("Format specific information:\n");
111
- bdrv_image_info_specific_dump(spec_info);
112
+ bdrv_image_info_specific_dump(spec_info,
113
+ "Format specific information:\n");
114
qapi_free_ImageInfoSpecific(spec_info);
115
}
116
117
--
118
2.38.1
diff view generated by jsdifflib
New patch
1
From: Hanna Reitz <hreitz@redhat.com>
1
2
3
Add some (optional) information that the file driver can provide for
4
image files, namely the extent size hint.
5
6
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
7
Message-Id: <20220620162704.80987-3-hreitz@redhat.com>
8
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
qapi/block-core.json | 26 ++++++++++++++++++++++++--
12
block/file-posix.c | 30 ++++++++++++++++++++++++++++++
13
2 files changed, 54 insertions(+), 2 deletions(-)
14
15
diff --git a/qapi/block-core.json b/qapi/block-core.json
16
index XXXXXXX..XXXXXXX 100644
17
--- a/qapi/block-core.json
18
+++ b/qapi/block-core.json
19
@@ -XXX,XX +XXX,XX @@
20
'*encryption-format': 'RbdImageEncryptionFormat'
21
} }
22
23
+##
24
+# @ImageInfoSpecificFile:
25
+#
26
+# @extent-size-hint: Extent size hint (if available)
27
+#
28
+# Since: 8.0
29
+##
30
+{ 'struct': 'ImageInfoSpecificFile',
31
+ 'data': {
32
+ '*extent-size-hint': 'size'
33
+ } }
34
+
35
##
36
# @ImageInfoSpecificKind:
37
#
38
# @luks: Since 2.7
39
# @rbd: Since 6.1
40
+# @file: Since 8.0
41
#
42
# Since: 1.7
43
##
44
{ 'enum': 'ImageInfoSpecificKind',
45
- 'data': [ 'qcow2', 'vmdk', 'luks', 'rbd' ] }
46
+ 'data': [ 'qcow2', 'vmdk', 'luks', 'rbd', 'file' ] }
47
48
##
49
# @ImageInfoSpecificQCow2Wrapper:
50
@@ -XXX,XX +XXX,XX @@
51
{ 'struct': 'ImageInfoSpecificRbdWrapper',
52
'data': { 'data': 'ImageInfoSpecificRbd' } }
53
54
+##
55
+# @ImageInfoSpecificFileWrapper:
56
+#
57
+# Since: 8.0
58
+##
59
+{ 'struct': 'ImageInfoSpecificFileWrapper',
60
+ 'data': { 'data': 'ImageInfoSpecificFile' } }
61
+
62
##
63
# @ImageInfoSpecific:
64
#
65
@@ -XXX,XX +XXX,XX @@
66
'qcow2': 'ImageInfoSpecificQCow2Wrapper',
67
'vmdk': 'ImageInfoSpecificVmdkWrapper',
68
'luks': 'ImageInfoSpecificLUKSWrapper',
69
- 'rbd': 'ImageInfoSpecificRbdWrapper'
70
+ 'rbd': 'ImageInfoSpecificRbdWrapper',
71
+ 'file': 'ImageInfoSpecificFileWrapper'
72
} }
73
74
##
75
diff --git a/block/file-posix.c b/block/file-posix.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/block/file-posix.c
78
+++ b/block/file-posix.c
79
@@ -XXX,XX +XXX,XX @@ raw_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
80
return 0;
81
}
82
83
+static ImageInfoSpecific *raw_get_specific_info(BlockDriverState *bs,
84
+ Error **errp)
85
+{
86
+ BDRVRawState *s = bs->opaque;
87
+ ImageInfoSpecificFile *file_info = g_new0(ImageInfoSpecificFile, 1);
88
+ ImageInfoSpecific *spec_info = g_new(ImageInfoSpecific, 1);
89
+
90
+ *spec_info = (ImageInfoSpecific){
91
+ .type = IMAGE_INFO_SPECIFIC_KIND_FILE,
92
+ .u.file.data = file_info,
93
+ };
94
+
95
+#ifdef FS_IOC_FSGETXATTR
96
+ {
97
+ struct fsxattr attr;
98
+ int ret;
99
+
100
+ ret = ioctl(s->fd, FS_IOC_FSGETXATTR, &attr);
101
+ if (!ret && attr.fsx_extsize != 0) {
102
+ file_info->has_extent_size_hint = true;
103
+ file_info->extent_size_hint = attr.fsx_extsize;
104
+ }
105
+ }
106
+#endif
107
+
108
+ return spec_info;
109
+}
110
+
111
static BlockStatsSpecificFile get_blockstats_specific_file(BlockDriverState *bs)
112
{
113
BDRVRawState *s = bs->opaque;
114
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_file = {
115
.bdrv_co_truncate = raw_co_truncate,
116
.bdrv_co_getlength = raw_co_getlength,
117
.bdrv_co_get_info = raw_co_get_info,
118
+ .bdrv_get_specific_info = raw_get_specific_info,
119
.bdrv_co_get_allocated_file_size = raw_co_get_allocated_file_size,
120
.bdrv_get_specific_stats = raw_get_specific_stats,
121
.bdrv_check_perm = raw_check_perm,
122
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_device = {
123
.bdrv_co_truncate = raw_co_truncate,
124
.bdrv_co_getlength = raw_co_getlength,
125
.bdrv_co_get_info = raw_co_get_info,
126
+ .bdrv_get_specific_info = raw_get_specific_info,
127
.bdrv_co_get_allocated_file_size = raw_co_get_allocated_file_size,
128
.bdrv_get_specific_stats = hdev_get_specific_stats,
129
.bdrv_check_perm = raw_check_perm,
130
--
131
2.38.1
diff view generated by jsdifflib
New patch
1
From: Hanna Reitz <hreitz@redhat.com>
1
2
3
VMDK's implementation of .bdrv_get_specific_info() returns information
4
about its extent files, ostensibly in the form of ImageInfo objects.
5
However, it does not get this information through
6
bdrv_query_image_info(), but fills only a select few fields with custom
7
information that does not always match the fields' purposes.
8
9
For example, @format, which is supposed to be a block driver name, is
10
filled with the extent type, e.g. SPARSE or FLAT.
11
12
In ImageInfo, @compressed shows whether the data that can be seen in the
13
image is stored in compressed form or not. For example, a compressed
14
qcow2 image will store compressed data in its data file, but when
15
accessing the qcow2 node, you will see normal data. This is not how
16
VMDK uses the @compressed field for its extent files: Instead, it
17
signifies whether accessing the extent file will yield compressed data
18
(which the VMDK driver then (de-)compresses).
19
20
Create a new structure to represent the extent information. This allows
21
us to clarify the fields' meanings, and it clearly shows that these are
22
not complete ImageInfo objects. (That is, if a user wants an extent
23
file's ImageInfo object, they will need to query it separately, and will
24
not get it from ImageInfoSpecificVmdk.extents.)
25
26
Note that this removes the last use of ['ImageInfo'] (i.e. an array of
27
ImageInfo objects), so the QAPI generator will no longer generate
28
ImageInfoList by default. However, we use it in qemu-img.c, so we need
29
to create a dummy object to force the generate to create that type,
30
similarly to DummyForceArrays in machine.json (introduced in commit
31
9f08c8ec73878122ad4b061ed334f0437afaaa32 ("qapi: Lazy creation of array
32
types")).
33
34
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
35
Message-Id: <20220620162704.80987-4-hreitz@redhat.com>
36
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
37
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
38
---
39
qapi/block-core.json | 38 +++++++++++++++++++++++++++++++++++++-
40
block/vmdk.c | 8 ++++----
41
2 files changed, 41 insertions(+), 5 deletions(-)
42
43
diff --git a/qapi/block-core.json b/qapi/block-core.json
44
index XXXXXXX..XXXXXXX 100644
45
--- a/qapi/block-core.json
46
+++ b/qapi/block-core.json
47
@@ -XXX,XX +XXX,XX @@
48
'create-type': 'str',
49
'cid': 'int',
50
'parent-cid': 'int',
51
- 'extents': ['ImageInfo']
52
+ 'extents': ['VmdkExtentInfo']
53
+ } }
54
+
55
+##
56
+# @VmdkExtentInfo:
57
+#
58
+# Information about a VMDK extent file
59
+#
60
+# @filename: Name of the extent file
61
+#
62
+# @format: Extent type (e.g. FLAT or SPARSE)
63
+#
64
+# @virtual-size: Number of bytes covered by this extent
65
+#
66
+# @cluster-size: Cluster size in bytes (for non-flat extents)
67
+#
68
+# @compressed: Whether this extent contains compressed data
69
+#
70
+# Since: 8.0
71
+##
72
+{ 'struct': 'VmdkExtentInfo',
73
+ 'data': {
74
+ 'filename': 'str',
75
+ 'format': 'str',
76
+ 'virtual-size': 'int',
77
+ '*cluster-size': 'int',
78
+ '*compressed': 'bool'
79
} }
80
81
##
82
@@ -XXX,XX +XXX,XX @@
83
'data': { 'device': 'str', '*id': 'str', '*name': 'str'},
84
'returns': 'SnapshotInfo',
85
'allow-preconfig': true }
86
+
87
+##
88
+# @DummyBlockCoreForceArrays:
89
+#
90
+# Not used by QMP; hack to let us use ImageInfoList internally
91
+#
92
+# Since: 8.0
93
+##
94
+{ 'struct': 'DummyBlockCoreForceArrays',
95
+ 'data': { 'unused-image-info': ['ImageInfo'] } }
96
diff --git a/block/vmdk.c b/block/vmdk.c
97
index XXXXXXX..XXXXXXX 100644
98
--- a/block/vmdk.c
99
+++ b/block/vmdk.c
100
@@ -XXX,XX +XXX,XX @@ static int vmdk_has_zero_init(BlockDriverState *bs)
101
return 1;
102
}
103
104
-static ImageInfo *vmdk_get_extent_info(VmdkExtent *extent)
105
+static VmdkExtentInfo *vmdk_get_extent_info(VmdkExtent *extent)
106
{
107
- ImageInfo *info = g_new0(ImageInfo, 1);
108
+ VmdkExtentInfo *info = g_new0(VmdkExtentInfo, 1);
109
110
bdrv_refresh_filename(extent->file->bs);
111
- *info = (ImageInfo){
112
+ *info = (VmdkExtentInfo){
113
.filename = g_strdup(extent->file->bs->filename),
114
.format = g_strdup(extent->type),
115
.virtual_size = extent->sectors * BDRV_SECTOR_SIZE,
116
@@ -XXX,XX +XXX,XX @@ static ImageInfoSpecific *vmdk_get_specific_info(BlockDriverState *bs,
117
int i;
118
BDRVVmdkState *s = bs->opaque;
119
ImageInfoSpecific *spec_info = g_new0(ImageInfoSpecific, 1);
120
- ImageInfoList **tail;
121
+ VmdkExtentInfoList **tail;
122
123
*spec_info = (ImageInfoSpecific){
124
.type = IMAGE_INFO_SPECIFIC_KIND_VMDK,
125
--
126
2.38.1
diff view generated by jsdifflib
New patch
1
1
From: Hanna Reitz <hreitz@redhat.com>
2
3
ImageInfo sometimes contains flat information, and sometimes it does
4
not. Split off a BlockNodeInfo struct, which only contains information
5
about a single node and has no link to the backing image.
6
7
We do this so we can extend BlockNodeInfo to a BlockGraphInfo struct,
8
which has links to all child nodes, not just the backing node. It would
9
be strange to base BlockGraphInfo on ImageInfo, because then this
10
extended struct would have two links to the backing node (one in
11
BlockGraphInfo as one of all the child links, and one in ImageInfo).
12
13
Furthermore, it is quite common to ignore the backing-image field
14
altogether: bdrv_query_image_info() does not set it, and
15
bdrv_image_info_dump() does not evaluate it. That signals that we
16
should have different structs for describing a single node and one that
17
has a link to the backing image.
18
19
Still, bdrv_query_image_info() and bdrv_image_info_dump() are not
20
changed too much in this patch. Follow-up patches will handle them.
21
22
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
23
Message-Id: <20220620162704.80987-5-hreitz@redhat.com>
24
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
25
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
26
---
27
qapi/block-core.json | 24 +++++++++----
28
include/block/qapi.h | 3 ++
29
block/qapi.c | 86 ++++++++++++++++++++++++++++++++------------
30
3 files changed, 85 insertions(+), 28 deletions(-)
31
32
diff --git a/qapi/block-core.json b/qapi/block-core.json
33
index XXXXXXX..XXXXXXX 100644
34
--- a/qapi/block-core.json
35
+++ b/qapi/block-core.json
36
@@ -XXX,XX +XXX,XX @@
37
} }
38
39
##
40
-# @ImageInfo:
41
+# @BlockNodeInfo:
42
#
43
# Information about a QEMU image file
44
#
45
@@ -XXX,XX +XXX,XX @@
46
#
47
# @snapshots: list of VM snapshots
48
#
49
-# @backing-image: info of the backing image (since 1.6)
50
-#
51
# @format-specific: structure supplying additional format-specific
52
# information (since 1.7)
53
#
54
-# Since: 1.3
55
+# Since: 8.0
56
##
57
-{ 'struct': 'ImageInfo',
58
+{ 'struct': 'BlockNodeInfo',
59
'data': {'filename': 'str', 'format': 'str', '*dirty-flag': 'bool',
60
'*actual-size': 'int', 'virtual-size': 'int',
61
'*cluster-size': 'int', '*encrypted': 'bool', '*compressed': 'bool',
62
'*backing-filename': 'str', '*full-backing-filename': 'str',
63
'*backing-filename-format': 'str', '*snapshots': ['SnapshotInfo'],
64
- '*backing-image': 'ImageInfo',
65
'*format-specific': 'ImageInfoSpecific' } }
66
67
+##
68
+# @ImageInfo:
69
+#
70
+# Information about a QEMU image file, and potentially its backing image
71
+#
72
+# @backing-image: info of the backing image
73
+#
74
+# Since: 1.3
75
+##
76
+{ 'struct': 'ImageInfo',
77
+ 'base': 'BlockNodeInfo',
78
+ 'data': {
79
+ '*backing-image': 'ImageInfo'
80
+ } }
81
+
82
##
83
# @ImageCheck:
84
#
85
diff --git a/include/block/qapi.h b/include/block/qapi.h
86
index XXXXXXX..XXXXXXX 100644
87
--- a/include/block/qapi.h
88
+++ b/include/block/qapi.h
89
@@ -XXX,XX +XXX,XX @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
90
int bdrv_query_snapshot_info_list(BlockDriverState *bs,
91
SnapshotInfoList **p_list,
92
Error **errp);
93
+void bdrv_query_block_node_info(BlockDriverState *bs,
94
+ BlockNodeInfo **p_info,
95
+ Error **errp);
96
void bdrv_query_image_info(BlockDriverState *bs,
97
ImageInfo **p_info,
98
Error **errp);
99
diff --git a/block/qapi.c b/block/qapi.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/block/qapi.c
102
+++ b/block/qapi.c
103
@@ -XXX,XX +XXX,XX @@ int bdrv_query_snapshot_info_list(BlockDriverState *bs,
104
}
105
106
/**
107
- * bdrv_query_image_info:
108
- * @bs: block device to examine
109
- * @p_info: location to store image information
110
- * @errp: location to store error information
111
- *
112
- * Store "flat" image information in @p_info.
113
- *
114
- * "Flat" means it does *not* query backing image information,
115
- * i.e. (*pinfo)->has_backing_image will be set to false and
116
- * (*pinfo)->backing_image to NULL even when the image does in fact have
117
- * a backing image.
118
- *
119
- * @p_info will be set only on success. On error, store error in @errp.
120
+ * Helper function for other query info functions. Store information about @bs
121
+ * in @info, setting @errp on error.
122
*/
123
-void bdrv_query_image_info(BlockDriverState *bs,
124
- ImageInfo **p_info,
125
- Error **errp)
126
+static void bdrv_do_query_node_info(BlockDriverState *bs,
127
+ BlockNodeInfo *info,
128
+ Error **errp)
129
{
130
int64_t size;
131
const char *backing_filename;
132
BlockDriverInfo bdi;
133
int ret;
134
Error *err = NULL;
135
- ImageInfo *info;
136
137
aio_context_acquire(bdrv_get_aio_context(bs));
138
139
@@ -XXX,XX +XXX,XX @@ void bdrv_query_image_info(BlockDriverState *bs,
140
141
bdrv_refresh_filename(bs);
142
143
- info = g_new0(ImageInfo, 1);
144
info->filename = g_strdup(bs->filename);
145
info->format = g_strdup(bdrv_get_format_name(bs));
146
info->virtual_size = size;
147
@@ -XXX,XX +XXX,XX @@ void bdrv_query_image_info(BlockDriverState *bs,
148
info->format_specific = bdrv_get_specific_info(bs, &err);
149
if (err) {
150
error_propagate(errp, err);
151
- qapi_free_ImageInfo(info);
152
goto out;
153
}
154
backing_filename = bs->backing_file;
155
@@ -XXX,XX +XXX,XX @@ void bdrv_query_image_info(BlockDriverState *bs,
156
break;
157
default:
158
error_propagate(errp, err);
159
- qapi_free_ImageInfo(info);
160
goto out;
161
}
162
163
- *p_info = info;
164
-
165
out:
166
aio_context_release(bdrv_get_aio_context(bs));
167
}
168
169
+/**
170
+ * bdrv_query_block_node_info:
171
+ * @bs: block node to examine
172
+ * @p_info: location to store node information
173
+ * @errp: location to store error information
174
+ *
175
+ * Store image information about @bs in @p_info.
176
+ *
177
+ * @p_info will be set only on success. On error, store error in @errp.
178
+ */
179
+void bdrv_query_block_node_info(BlockDriverState *bs,
180
+ BlockNodeInfo **p_info,
181
+ Error **errp)
182
+{
183
+ BlockNodeInfo *info;
184
+ ERRP_GUARD();
185
+
186
+ info = g_new0(BlockNodeInfo, 1);
187
+ bdrv_do_query_node_info(bs, info, errp);
188
+ if (*errp) {
189
+ qapi_free_BlockNodeInfo(info);
190
+ return;
191
+ }
192
+
193
+ *p_info = info;
194
+}
195
+
196
+/**
197
+ * bdrv_query_image_info:
198
+ * @bs: block node to examine
199
+ * @p_info: location to store image information
200
+ * @errp: location to store error information
201
+ *
202
+ * Store "flat" image information in @p_info.
203
+ *
204
+ * "Flat" means it does *not* query backing image information,
205
+ * i.e. (*pinfo)->has_backing_image will be set to false and
206
+ * (*pinfo)->backing_image to NULL even when the image does in fact have
207
+ * a backing image.
208
+ *
209
+ * @p_info will be set only on success. On error, store error in @errp.
210
+ */
211
+void bdrv_query_image_info(BlockDriverState *bs,
212
+ ImageInfo **p_info,
213
+ Error **errp)
214
+{
215
+ ImageInfo *info;
216
+ ERRP_GUARD();
217
+
218
+ info = g_new0(ImageInfo, 1);
219
+ bdrv_do_query_node_info(bs, qapi_ImageInfo_base(info), errp);
220
+ if (*errp) {
221
+ qapi_free_ImageInfo(info);
222
+ return;
223
+ }
224
+
225
+ *p_info = info;
226
+}
227
+
228
/* @p_info will be set only on success. */
229
static void bdrv_query_info(BlockBackend *blk, BlockInfo **p_info,
230
Error **errp)
231
--
232
2.38.1
diff view generated by jsdifflib
New patch
1
1
From: Hanna Reitz <hreitz@redhat.com>
2
3
qemu-img info never uses ImageInfo's backing-image field, because it
4
opens the backing chain one by one with BDRV_O_NO_BACKING, and prints
5
all backing chain nodes' information consecutively. Use BlockNodeInfo
6
to make it clear that we only print information about a single node, and
7
that we are not using the backing-image field.
8
9
Notably, bdrv_image_info_dump() does not evaluate the backing-image
10
field, so we can easily make it take a BlockNodeInfo pointer (and
11
consequentially rename it to bdrv_node_info_dump()). It makes more
12
sense this way, because again, the interface now makes it syntactically
13
clear that backing-image is ignored by this function.
14
15
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
16
Message-Id: <20220620162704.80987-6-hreitz@redhat.com>
17
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
18
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
19
---
20
qapi/block-core.json | 4 +--
21
include/block/qapi.h | 2 +-
22
block/monitor/block-hmp-cmds.c | 2 +-
23
block/qapi.c | 2 +-
24
qemu-img.c | 48 +++++++++++++++++-----------------
25
5 files changed, 29 insertions(+), 29 deletions(-)
26
27
diff --git a/qapi/block-core.json b/qapi/block-core.json
28
index XXXXXXX..XXXXXXX 100644
29
--- a/qapi/block-core.json
30
+++ b/qapi/block-core.json
31
@@ -XXX,XX +XXX,XX @@
32
##
33
# @DummyBlockCoreForceArrays:
34
#
35
-# Not used by QMP; hack to let us use ImageInfoList internally
36
+# Not used by QMP; hack to let us use BlockNodeInfoList internally
37
#
38
# Since: 8.0
39
##
40
{ 'struct': 'DummyBlockCoreForceArrays',
41
- 'data': { 'unused-image-info': ['ImageInfo'] } }
42
+ 'data': { 'unused-block-node-info': ['BlockNodeInfo'] } }
43
diff --git a/include/block/qapi.h b/include/block/qapi.h
44
index XXXXXXX..XXXXXXX 100644
45
--- a/include/block/qapi.h
46
+++ b/include/block/qapi.h
47
@@ -XXX,XX +XXX,XX @@ void bdrv_query_image_info(BlockDriverState *bs,
48
void bdrv_snapshot_dump(QEMUSnapshotInfo *sn);
49
void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec,
50
const char *prefix);
51
-void bdrv_image_info_dump(ImageInfo *info);
52
+void bdrv_node_info_dump(BlockNodeInfo *info);
53
#endif
54
diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/block/monitor/block-hmp-cmds.c
57
+++ b/block/monitor/block-hmp-cmds.c
58
@@ -XXX,XX +XXX,XX @@ static void print_block_info(Monitor *mon, BlockInfo *info,
59
monitor_printf(mon, "\nImages:\n");
60
image_info = inserted->image;
61
while (1) {
62
- bdrv_image_info_dump(image_info);
63
+ bdrv_node_info_dump(qapi_ImageInfo_base(image_info));
64
if (image_info->backing_image) {
65
image_info = image_info->backing_image;
66
} else {
67
diff --git a/block/qapi.c b/block/qapi.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/block/qapi.c
70
+++ b/block/qapi.c
71
@@ -XXX,XX +XXX,XX @@ void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec,
72
visit_free(v);
73
}
74
75
-void bdrv_image_info_dump(ImageInfo *info)
76
+void bdrv_node_info_dump(BlockNodeInfo *info)
77
{
78
char *size_buf, *dsize_buf;
79
if (!info->has_actual_size) {
80
diff --git a/qemu-img.c b/qemu-img.c
81
index XXXXXXX..XXXXXXX 100644
82
--- a/qemu-img.c
83
+++ b/qemu-img.c
84
@@ -XXX,XX +XXX,XX @@ static void dump_snapshots(BlockDriverState *bs)
85
g_free(sn_tab);
86
}
87
88
-static void dump_json_image_info_list(ImageInfoList *list)
89
+static void dump_json_block_node_info_list(BlockNodeInfoList *list)
90
{
91
GString *str;
92
QObject *obj;
93
Visitor *v = qobject_output_visitor_new(&obj);
94
95
- visit_type_ImageInfoList(v, NULL, &list, &error_abort);
96
+ visit_type_BlockNodeInfoList(v, NULL, &list, &error_abort);
97
visit_complete(v, &obj);
98
str = qobject_to_json_pretty(obj, true);
99
assert(str != NULL);
100
@@ -XXX,XX +XXX,XX @@ static void dump_json_image_info_list(ImageInfoList *list)
101
g_string_free(str, true);
102
}
103
104
-static void dump_json_image_info(ImageInfo *info)
105
+static void dump_json_block_node_info(BlockNodeInfo *info)
106
{
107
GString *str;
108
QObject *obj;
109
Visitor *v = qobject_output_visitor_new(&obj);
110
111
- visit_type_ImageInfo(v, NULL, &info, &error_abort);
112
+ visit_type_BlockNodeInfo(v, NULL, &info, &error_abort);
113
visit_complete(v, &obj);
114
str = qobject_to_json_pretty(obj, true);
115
assert(str != NULL);
116
@@ -XXX,XX +XXX,XX @@ static void dump_json_image_info(ImageInfo *info)
117
g_string_free(str, true);
118
}
119
120
-static void dump_human_image_info_list(ImageInfoList *list)
121
+static void dump_human_image_info_list(BlockNodeInfoList *list)
122
{
123
- ImageInfoList *elem;
124
+ BlockNodeInfoList *elem;
125
bool delim = false;
126
127
for (elem = list; elem; elem = elem->next) {
128
@@ -XXX,XX +XXX,XX @@ static void dump_human_image_info_list(ImageInfoList *list)
129
}
130
delim = true;
131
132
- bdrv_image_info_dump(elem->value);
133
+ bdrv_node_info_dump(elem->value);
134
}
135
}
136
137
@@ -XXX,XX +XXX,XX @@ static gboolean str_equal_func(gconstpointer a, gconstpointer b)
138
}
139
140
/**
141
- * Open an image file chain and return an ImageInfoList
142
+ * Open an image file chain and return an BlockNodeInfoList
143
*
144
* @filename: topmost image filename
145
* @fmt: topmost image format (may be NULL to autodetect)
146
* @chain: true - enumerate entire backing file chain
147
* false - only topmost image file
148
*
149
- * Returns a list of ImageInfo objects or NULL if there was an error opening an
150
- * image file. If there was an error a message will have been printed to
151
- * stderr.
152
+ * Returns a list of BlockNodeInfo objects or NULL if there was an error
153
+ * opening an image file. If there was an error a message will have been
154
+ * printed to stderr.
155
*/
156
-static ImageInfoList *collect_image_info_list(bool image_opts,
157
- const char *filename,
158
- const char *fmt,
159
- bool chain, bool force_share)
160
+static BlockNodeInfoList *collect_image_info_list(bool image_opts,
161
+ const char *filename,
162
+ const char *fmt,
163
+ bool chain, bool force_share)
164
{
165
- ImageInfoList *head = NULL;
166
- ImageInfoList **tail = &head;
167
+ BlockNodeInfoList *head = NULL;
168
+ BlockNodeInfoList **tail = &head;
169
GHashTable *filenames;
170
Error *err = NULL;
171
172
@@ -XXX,XX +XXX,XX @@ static ImageInfoList *collect_image_info_list(bool image_opts,
173
while (filename) {
174
BlockBackend *blk;
175
BlockDriverState *bs;
176
- ImageInfo *info;
177
+ BlockNodeInfo *info;
178
179
if (g_hash_table_lookup_extended(filenames, filename, NULL, NULL)) {
180
error_report("Backing file '%s' creates an infinite loop.",
181
@@ -XXX,XX +XXX,XX @@ static ImageInfoList *collect_image_info_list(bool image_opts,
182
}
183
bs = blk_bs(blk);
184
185
- bdrv_query_image_info(bs, &info, &err);
186
+ bdrv_query_block_node_info(bs, &info, &err);
187
if (err) {
188
error_report_err(err);
189
blk_unref(blk);
190
@@ -XXX,XX +XXX,XX @@ static ImageInfoList *collect_image_info_list(bool image_opts,
191
return head;
192
193
err:
194
- qapi_free_ImageInfoList(head);
195
+ qapi_free_BlockNodeInfoList(head);
196
g_hash_table_destroy(filenames);
197
return NULL;
198
}
199
@@ -XXX,XX +XXX,XX @@ static int img_info(int argc, char **argv)
200
OutputFormat output_format = OFORMAT_HUMAN;
201
bool chain = false;
202
const char *filename, *fmt, *output;
203
- ImageInfoList *list;
204
+ BlockNodeInfoList *list;
205
bool image_opts = false;
206
bool force_share = false;
207
208
@@ -XXX,XX +XXX,XX @@ static int img_info(int argc, char **argv)
209
break;
210
case OFORMAT_JSON:
211
if (chain) {
212
- dump_json_image_info_list(list);
213
+ dump_json_block_node_info_list(list);
214
} else {
215
- dump_json_image_info(list->value);
216
+ dump_json_block_node_info(list->value);
217
}
218
break;
219
}
220
221
- qapi_free_ImageInfoList(list);
222
+ qapi_free_BlockNodeInfoList(list);
223
return 0;
224
}
225
226
--
227
2.38.1
diff view generated by jsdifflib
New patch
1
From: Hanna Reitz <hreitz@redhat.com>
1
2
3
There is no real reason why bdrv_query_image_info() should generally not
4
recurse. The ImageInfo struct has a pointer to the backing image, so it
5
should generally be filled, unless the caller explicitly opts out.
6
7
This moves the recursing code from bdrv_block_device_info() into
8
bdrv_query_image_info().
9
10
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
11
Message-Id: <20220620162704.80987-7-hreitz@redhat.com>
12
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
15
include/block/qapi.h | 2 +
16
block/qapi.c | 92 +++++++++++++++++++++++++++-----------------
17
2 files changed, 58 insertions(+), 36 deletions(-)
18
19
diff --git a/include/block/qapi.h b/include/block/qapi.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/include/block/qapi.h
22
+++ b/include/block/qapi.h
23
@@ -XXX,XX +XXX,XX @@ void bdrv_query_block_node_info(BlockDriverState *bs,
24
Error **errp);
25
void bdrv_query_image_info(BlockDriverState *bs,
26
ImageInfo **p_info,
27
+ bool flat,
28
+ bool skip_implicit_filters,
29
Error **errp);
30
31
void bdrv_snapshot_dump(QEMUSnapshotInfo *sn);
32
diff --git a/block/qapi.c b/block/qapi.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/block/qapi.c
35
+++ b/block/qapi.c
36
@@ -XXX,XX +XXX,XX @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
37
Error **errp)
38
{
39
ImageInfo **p_image_info;
40
+ ImageInfo *backing_info;
41
BlockDriverState *bs0, *backing;
42
BlockDeviceInfo *info;
43
+ ERRP_GUARD();
44
45
if (!bs->drv) {
46
error_setg(errp, "Block device %s is ejected", bs->node_name);
47
@@ -XXX,XX +XXX,XX @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
48
bs0 = bs;
49
p_image_info = &info->image;
50
info->backing_file_depth = 0;
51
- while (1) {
52
- Error *local_err = NULL;
53
- bdrv_query_image_info(bs0, p_image_info, &local_err);
54
- if (local_err) {
55
- error_propagate(errp, local_err);
56
- qapi_free_BlockDeviceInfo(info);
57
- return NULL;
58
- }
59
-
60
- /* stop gathering data for flat output */
61
- if (flat) {
62
- break;
63
- }
64
65
- if (bs0->drv && bdrv_filter_or_cow_child(bs0)) {
66
- /*
67
- * Put any filtered child here (for backwards compatibility to when
68
- * we put bs0->backing here, which might be any filtered child).
69
- */
70
- info->backing_file_depth++;
71
- bs0 = bdrv_filter_or_cow_bs(bs0);
72
- p_image_info = &((*p_image_info)->backing_image);
73
- } else {
74
- break;
75
- }
76
+ /*
77
+ * Skip automatically inserted nodes that the user isn't aware of for
78
+ * query-block (blk != NULL), but not for query-named-block-nodes
79
+ */
80
+ bdrv_query_image_info(bs0, p_image_info, flat, blk != NULL, errp);
81
+ if (*errp) {
82
+ qapi_free_BlockDeviceInfo(info);
83
+ return NULL;
84
+ }
85
86
- /* Skip automatically inserted nodes that the user isn't aware of for
87
- * query-block (blk != NULL), but not for query-named-block-nodes */
88
- if (blk) {
89
- bs0 = bdrv_skip_implicit_filters(bs0);
90
- }
91
+ backing_info = info->image->backing_image;
92
+ while (backing_info) {
93
+ info->backing_file_depth++;
94
+ backing_info = backing_info->backing_image;
95
}
96
97
return info;
98
@@ -XXX,XX +XXX,XX @@ void bdrv_query_block_node_info(BlockDriverState *bs,
99
* bdrv_query_image_info:
100
* @bs: block node to examine
101
* @p_info: location to store image information
102
+ * @flat: skip backing node information
103
+ * @skip_implicit_filters: skip implicit filters in the backing chain
104
* @errp: location to store error information
105
*
106
- * Store "flat" image information in @p_info.
107
+ * Store image information in @p_info, potentially recursively covering the
108
+ * backing chain.
109
*
110
- * "Flat" means it does *not* query backing image information,
111
- * i.e. (*pinfo)->has_backing_image will be set to false and
112
- * (*pinfo)->backing_image to NULL even when the image does in fact have
113
- * a backing image.
114
+ * If @flat is true, do not query backing image information, i.e.
115
+ * (*p_info)->has_backing_image will be set to false and
116
+ * (*p_info)->backing_image to NULL even when the image does in fact have a
117
+ * backing image.
118
+ *
119
+ * If @skip_implicit_filters is true, implicit filter nodes in the backing chain
120
+ * will be skipped when querying backing image information.
121
+ * (@skip_implicit_filters is ignored when @flat is true.)
122
*
123
* @p_info will be set only on success. On error, store error in @errp.
124
*/
125
void bdrv_query_image_info(BlockDriverState *bs,
126
ImageInfo **p_info,
127
+ bool flat,
128
+ bool skip_implicit_filters,
129
Error **errp)
130
{
131
ImageInfo *info;
132
@@ -XXX,XX +XXX,XX @@ void bdrv_query_image_info(BlockDriverState *bs,
133
info = g_new0(ImageInfo, 1);
134
bdrv_do_query_node_info(bs, qapi_ImageInfo_base(info), errp);
135
if (*errp) {
136
- qapi_free_ImageInfo(info);
137
- return;
138
+ goto fail;
139
+ }
140
+
141
+ if (!flat) {
142
+ BlockDriverState *backing;
143
+
144
+ /*
145
+ * Use any filtered child here (for backwards compatibility to when
146
+ * we always took bs->backing, which might be any filtered child).
147
+ */
148
+ backing = bdrv_filter_or_cow_bs(bs);
149
+ if (skip_implicit_filters) {
150
+ backing = bdrv_skip_implicit_filters(backing);
151
+ }
152
+
153
+ if (backing) {
154
+ bdrv_query_image_info(backing, &info->backing_image, false,
155
+ skip_implicit_filters, errp);
156
+ if (*errp) {
157
+ goto fail;
158
+ }
159
+ }
160
}
161
162
*p_info = info;
163
+ return;
164
+
165
+fail:
166
+ assert(*errp);
167
+ qapi_free_ImageInfo(info);
168
}
169
170
/* @p_info will be set only on success. */
171
--
172
2.38.1
diff view generated by jsdifflib
New patch
1
From: Hanna Reitz <hreitz@redhat.com>
1
2
3
Introduce a new QAPI type BlockGraphInfo and an associated
4
bdrv_query_block_graph_info() function that recursively gathers
5
BlockNodeInfo objects through a block graph.
6
7
A follow-up patch is going to make "qemu-img info" use this to print
8
information about all nodes that are (usually implicitly) opened for a
9
given image file.
10
11
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
12
Message-Id: <20220620162704.80987-8-hreitz@redhat.com>
13
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
---
16
qapi/block-core.json | 35 ++++++++++++++++++++++++++++++++
17
include/block/qapi.h | 3 +++
18
block/qapi.c | 48 ++++++++++++++++++++++++++++++++++++++++++++
19
3 files changed, 86 insertions(+)
20
21
diff --git a/qapi/block-core.json b/qapi/block-core.json
22
index XXXXXXX..XXXXXXX 100644
23
--- a/qapi/block-core.json
24
+++ b/qapi/block-core.json
25
@@ -XXX,XX +XXX,XX @@
26
'*backing-image': 'ImageInfo'
27
} }
28
29
+##
30
+# @BlockChildInfo:
31
+#
32
+# Information about all nodes in the block graph starting at some node,
33
+# annotated with information about that node in relation to its parent.
34
+#
35
+# @name: Child name of the root node in the BlockGraphInfo struct, in its role
36
+# as the child of some undescribed parent node
37
+#
38
+# @info: Block graph information starting at this node
39
+#
40
+# Since: 8.0
41
+##
42
+{ 'struct': 'BlockChildInfo',
43
+ 'data': {
44
+ 'name': 'str',
45
+ 'info': 'BlockGraphInfo'
46
+ } }
47
+
48
+##
49
+# @BlockGraphInfo:
50
+#
51
+# Information about all nodes in a block (sub)graph in the form of BlockNodeInfo
52
+# data.
53
+# The base BlockNodeInfo struct contains the information for the (sub)graph's
54
+# root node.
55
+#
56
+# @children: Array of links to this node's child nodes' information
57
+#
58
+# Since: 8.0
59
+##
60
+{ 'struct': 'BlockGraphInfo',
61
+ 'base': 'BlockNodeInfo',
62
+ 'data': { 'children': ['BlockChildInfo'] } }
63
+
64
##
65
# @ImageCheck:
66
#
67
diff --git a/include/block/qapi.h b/include/block/qapi.h
68
index XXXXXXX..XXXXXXX 100644
69
--- a/include/block/qapi.h
70
+++ b/include/block/qapi.h
71
@@ -XXX,XX +XXX,XX @@ void bdrv_query_image_info(BlockDriverState *bs,
72
bool flat,
73
bool skip_implicit_filters,
74
Error **errp);
75
+void bdrv_query_block_graph_info(BlockDriverState *bs,
76
+ BlockGraphInfo **p_info,
77
+ Error **errp);
78
79
void bdrv_snapshot_dump(QEMUSnapshotInfo *sn);
80
void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec,
81
diff --git a/block/qapi.c b/block/qapi.c
82
index XXXXXXX..XXXXXXX 100644
83
--- a/block/qapi.c
84
+++ b/block/qapi.c
85
@@ -XXX,XX +XXX,XX @@ fail:
86
qapi_free_ImageInfo(info);
87
}
88
89
+/**
90
+ * bdrv_query_block_graph_info:
91
+ * @bs: root node to start from
92
+ * @p_info: location to store image information
93
+ * @errp: location to store error information
94
+ *
95
+ * Store image information about the graph starting from @bs in @p_info.
96
+ *
97
+ * @p_info will be set only on success. On error, store error in @errp.
98
+ */
99
+void bdrv_query_block_graph_info(BlockDriverState *bs,
100
+ BlockGraphInfo **p_info,
101
+ Error **errp)
102
+{
103
+ BlockGraphInfo *info;
104
+ BlockChildInfoList **children_list_tail;
105
+ BdrvChild *c;
106
+ ERRP_GUARD();
107
+
108
+ info = g_new0(BlockGraphInfo, 1);
109
+ bdrv_do_query_node_info(bs, qapi_BlockGraphInfo_base(info), errp);
110
+ if (*errp) {
111
+ goto fail;
112
+ }
113
+
114
+ children_list_tail = &info->children;
115
+
116
+ QLIST_FOREACH(c, &bs->children, next) {
117
+ BlockChildInfo *c_info;
118
+
119
+ c_info = g_new0(BlockChildInfo, 1);
120
+ QAPI_LIST_APPEND(children_list_tail, c_info);
121
+
122
+ c_info->name = g_strdup(c->name);
123
+ bdrv_query_block_graph_info(c->bs, &c_info->info, errp);
124
+ if (*errp) {
125
+ goto fail;
126
+ }
127
+ }
128
+
129
+ *p_info = info;
130
+ return;
131
+
132
+fail:
133
+ assert(*errp != NULL);
134
+ qapi_free_BlockGraphInfo(info);
135
+}
136
+
137
/* @p_info will be set only on success. */
138
static void bdrv_query_info(BlockBackend *blk, BlockInfo **p_info,
139
Error **errp)
140
--
141
2.38.1
diff view generated by jsdifflib
New patch
1
From: Hanna Reitz <hreitz@redhat.com>
1
2
3
In order to let qemu-img info present a block graph, add a parameter to
4
bdrv_node_info_dump() and bdrv_image_info_specific_dump() so that the
5
information of nodes below the root level can be given an indentation.
6
7
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
8
Message-Id: <20220620162704.80987-9-hreitz@redhat.com>
9
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
12
include/block/qapi.h | 5 ++--
13
block/monitor/block-hmp-cmds.c | 2 +-
14
block/qapi.c | 47 +++++++++++++++++++---------------
15
qemu-img.c | 2 +-
16
qemu-io-cmds.c | 3 ++-
17
5 files changed, 34 insertions(+), 25 deletions(-)
18
19
diff --git a/include/block/qapi.h b/include/block/qapi.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/include/block/qapi.h
22
+++ b/include/block/qapi.h
23
@@ -XXX,XX +XXX,XX @@ void bdrv_query_block_graph_info(BlockDriverState *bs,
24
25
void bdrv_snapshot_dump(QEMUSnapshotInfo *sn);
26
void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec,
27
- const char *prefix);
28
-void bdrv_node_info_dump(BlockNodeInfo *info);
29
+ const char *prefix,
30
+ int indentation);
31
+void bdrv_node_info_dump(BlockNodeInfo *info, int indentation);
32
#endif
33
diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/block/monitor/block-hmp-cmds.c
36
+++ b/block/monitor/block-hmp-cmds.c
37
@@ -XXX,XX +XXX,XX @@ static void print_block_info(Monitor *mon, BlockInfo *info,
38
monitor_printf(mon, "\nImages:\n");
39
image_info = inserted->image;
40
while (1) {
41
- bdrv_node_info_dump(qapi_ImageInfo_base(image_info));
42
+ bdrv_node_info_dump(qapi_ImageInfo_base(image_info), 0);
43
if (image_info->backing_image) {
44
image_info = image_info->backing_image;
45
} else {
46
diff --git a/block/qapi.c b/block/qapi.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/block/qapi.c
49
+++ b/block/qapi.c
50
@@ -XXX,XX +XXX,XX @@ static bool qobject_is_empty_dump(const QObject *obj)
51
* prepending an optional prefix if the dump is not empty.
52
*/
53
void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec,
54
- const char *prefix)
55
+ const char *prefix,
56
+ int indentation)
57
{
58
QObject *obj, *data;
59
Visitor *v = qobject_output_visitor_new(&obj);
60
@@ -XXX,XX +XXX,XX @@ void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec,
61
data = qdict_get(qobject_to(QDict, obj), "data");
62
if (!qobject_is_empty_dump(data)) {
63
if (prefix) {
64
- qemu_printf("%s", prefix);
65
+ qemu_printf("%*s%s", indentation * 4, "", prefix);
66
}
67
- dump_qobject(1, data);
68
+ dump_qobject(indentation + 1, data);
69
}
70
qobject_unref(obj);
71
visit_free(v);
72
}
73
74
-void bdrv_node_info_dump(BlockNodeInfo *info)
75
+void bdrv_node_info_dump(BlockNodeInfo *info, int indentation)
76
{
77
char *size_buf, *dsize_buf;
78
+ g_autofree char *ind_s = g_strdup_printf("%*s", indentation * 4, "");
79
+
80
if (!info->has_actual_size) {
81
dsize_buf = g_strdup("unavailable");
82
} else {
83
dsize_buf = size_to_str(info->actual_size);
84
}
85
size_buf = size_to_str(info->virtual_size);
86
- qemu_printf("image: %s\n"
87
- "file format: %s\n"
88
- "virtual size: %s (%" PRId64 " bytes)\n"
89
- "disk size: %s\n",
90
- info->filename, info->format, size_buf,
91
- info->virtual_size,
92
- dsize_buf);
93
+ qemu_printf("%simage: %s\n"
94
+ "%sfile format: %s\n"
95
+ "%svirtual size: %s (%" PRId64 " bytes)\n"
96
+ "%sdisk size: %s\n",
97
+ ind_s, info->filename,
98
+ ind_s, info->format,
99
+ ind_s, size_buf, info->virtual_size,
100
+ ind_s, dsize_buf);
101
g_free(size_buf);
102
g_free(dsize_buf);
103
104
if (info->has_encrypted && info->encrypted) {
105
- qemu_printf("encrypted: yes\n");
106
+ qemu_printf("%sencrypted: yes\n", ind_s);
107
}
108
109
if (info->has_cluster_size) {
110
- qemu_printf("cluster_size: %" PRId64 "\n",
111
- info->cluster_size);
112
+ qemu_printf("%scluster_size: %" PRId64 "\n",
113
+ ind_s, info->cluster_size);
114
}
115
116
if (info->has_dirty_flag && info->dirty_flag) {
117
- qemu_printf("cleanly shut down: no\n");
118
+ qemu_printf("%scleanly shut down: no\n", ind_s);
119
}
120
121
if (info->backing_filename) {
122
- qemu_printf("backing file: %s", info->backing_filename);
123
+ qemu_printf("%sbacking file: %s", ind_s, info->backing_filename);
124
if (!info->full_backing_filename) {
125
qemu_printf(" (cannot determine actual path)");
126
} else if (strcmp(info->backing_filename,
127
@@ -XXX,XX +XXX,XX @@ void bdrv_node_info_dump(BlockNodeInfo *info)
128
}
129
qemu_printf("\n");
130
if (info->backing_filename_format) {
131
- qemu_printf("backing file format: %s\n",
132
- info->backing_filename_format);
133
+ qemu_printf("%sbacking file format: %s\n",
134
+ ind_s, info->backing_filename_format);
135
}
136
}
137
138
if (info->has_snapshots) {
139
SnapshotInfoList *elem;
140
141
- qemu_printf("Snapshot list:\n");
142
+ qemu_printf("%sSnapshot list:\n", ind_s);
143
+ qemu_printf("%s", ind_s);
144
bdrv_snapshot_dump(NULL);
145
qemu_printf("\n");
146
147
@@ -XXX,XX +XXX,XX @@ void bdrv_node_info_dump(BlockNodeInfo *info)
148
149
pstrcpy(sn.id_str, sizeof(sn.id_str), elem->value->id);
150
pstrcpy(sn.name, sizeof(sn.name), elem->value->name);
151
+ qemu_printf("%s", ind_s);
152
bdrv_snapshot_dump(&sn);
153
qemu_printf("\n");
154
}
155
@@ -XXX,XX +XXX,XX @@ void bdrv_node_info_dump(BlockNodeInfo *info)
156
157
if (info->format_specific) {
158
bdrv_image_info_specific_dump(info->format_specific,
159
- "Format specific information:\n");
160
+ "Format specific information:\n",
161
+ indentation);
162
}
163
}
164
diff --git a/qemu-img.c b/qemu-img.c
165
index XXXXXXX..XXXXXXX 100644
166
--- a/qemu-img.c
167
+++ b/qemu-img.c
168
@@ -XXX,XX +XXX,XX @@ static void dump_human_image_info_list(BlockNodeInfoList *list)
169
}
170
delim = true;
171
172
- bdrv_node_info_dump(elem->value);
173
+ bdrv_node_info_dump(elem->value, 0);
174
}
175
}
176
177
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
178
index XXXXXXX..XXXXXXX 100644
179
--- a/qemu-io-cmds.c
180
+++ b/qemu-io-cmds.c
181
@@ -XXX,XX +XXX,XX @@ static int info_f(BlockBackend *blk, int argc, char **argv)
182
}
183
if (spec_info) {
184
bdrv_image_info_specific_dump(spec_info,
185
- "Format specific information:\n");
186
+ "Format specific information:\n",
187
+ 0);
188
qapi_free_ImageInfoSpecific(spec_info);
189
}
190
191
--
192
2.38.1
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: Hanna Reitz <hreitz@redhat.com>
2
2
3
To disallow certain refcount_bits values, some _unsupported_imgopts
3
Before we let qemu-img info print child node information, have
4
invocations look like "refcount_bits=1[^0-9]", i.e. they match an
4
common.filter, common.rc, and iotests.py filter it from the test output
5
integer boundary with [^0-9]. This expression does not match the end of
5
so we get as few reference output changes as possible.
6
the string, though, so it breaks down when refcount_bits is the last
7
option (which it tends to be after the rewrite of the check script in
8
Python).
9
6
10
Those invocations could use \b or \> instead, but those are not
7
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
11
portable. They could use something like \([^0-9]\|$\), but that would
8
Message-Id: <20220620162704.80987-10-hreitz@redhat.com>
12
be cumbersome. To make it simple and keep the existing invocations
9
Tested-by: Kevin Wolf <kwolf@redhat.com>
13
working, just let _unsupported_imgopts match the regex against $IMGOPTS
14
plus a trailing space.
15
16
Suggested-by: Eric Blake <eblake@redhat.com>
17
Signed-off-by: Max Reitz <mreitz@redhat.com>
18
Message-Id: <20210210095128.22732-1-mreitz@redhat.com>
19
Reviewed-by: Eric Blake <eblake@redhat.com>
20
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
21
---
11
---
22
tests/qemu-iotests/common.rc | 4 +++-
12
tests/qemu-iotests/iotests.py | 18 +++++++++++++++---
23
1 file changed, 3 insertions(+), 1 deletion(-)
13
tests/qemu-iotests/common.filter | 22 ++++++++++++++--------
14
tests/qemu-iotests/common.rc | 22 ++++++++++++++--------
15
3 files changed, 43 insertions(+), 19 deletions(-)
24
16
17
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
18
index XXXXXXX..XXXXXXX 100644
19
--- a/tests/qemu-iotests/iotests.py
20
+++ b/tests/qemu-iotests/iotests.py
21
@@ -XXX,XX +XXX,XX @@ def qemu_img_log(*args: str, check: bool = True
22
23
def img_info_log(filename: str, filter_path: Optional[str] = None,
24
use_image_opts: bool = False, extra_args: Sequence[str] = (),
25
- check: bool = True,
26
+ check: bool = True, drop_child_info: bool = True,
27
) -> None:
28
args = ['info']
29
if use_image_opts:
30
@@ -XXX,XX +XXX,XX @@ def img_info_log(filename: str, filter_path: Optional[str] = None,
31
output = qemu_img(*args, check=check).stdout
32
if not filter_path:
33
filter_path = filename
34
- log(filter_img_info(output, filter_path))
35
+ log(filter_img_info(output, filter_path, drop_child_info))
36
37
def qemu_io_wrap_args(args: Sequence[str]) -> List[str]:
38
if '-f' in args or '--image-opts' in args:
39
@@ -XXX,XX +XXX,XX @@ def _filter(_key, value):
40
def filter_generated_node_ids(msg):
41
return re.sub("#block[0-9]+", "NODE_NAME", msg)
42
43
-def filter_img_info(output, filename):
44
+def filter_img_info(output: str, filename: str,
45
+ drop_child_info: bool = True) -> str:
46
lines = []
47
+ drop_indented = False
48
for line in output.split('\n'):
49
if 'disk size' in line or 'actual-size' in line:
50
continue
51
+
52
+ # Drop child node info
53
+ if drop_indented:
54
+ if line.startswith(' '):
55
+ continue
56
+ drop_indented = False
57
+ if drop_child_info and "Child node '/" in line:
58
+ drop_indented = True
59
+ continue
60
+
61
line = line.replace(filename, 'TEST_IMG')
62
line = filter_testfiles(line)
63
line = line.replace(imgfmt, 'IMGFMT')
64
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
65
index XXXXXXX..XXXXXXX 100644
66
--- a/tests/qemu-iotests/common.filter
67
+++ b/tests/qemu-iotests/common.filter
68
@@ -XXX,XX +XXX,XX @@ _filter_img_info()
69
70
discard=0
71
regex_json_spec_start='^ *"format-specific": \{'
72
+ regex_json_child_start='^ *"children": \['
73
gsed -e "s#$REMOTE_TEST_DIR#TEST_DIR#g" \
74
-e "s#$IMGPROTO:$TEST_DIR#TEST_DIR#g" \
75
-e "s#$TEST_DIR#TEST_DIR#g" \
76
@@ -XXX,XX +XXX,XX @@ _filter_img_info()
77
-e 's/\(compression type: \)\(zlib\|zstd\)/\1COMPRESSION_TYPE/' \
78
-e "s/uuid: [-a-f0-9]\\+/uuid: 00000000-0000-0000-0000-000000000000/" | \
79
while IFS='' read -r line; do
80
- if [[ $format_specific == 1 ]]; then
81
- discard=0
82
- elif [[ $line == "Format specific information:" ]]; then
83
- discard=1
84
- elif [[ $line =~ $regex_json_spec_start ]]; then
85
- discard=2
86
- regex_json_spec_end="^${line%%[^ ]*}\\},? *$"
87
+ if [[ $discard == 0 ]]; then
88
+ if [[ $format_specific == 0 && $line == "Format specific information:" ]]; then
89
+ discard=1
90
+ elif [[ $line =~ "Child node '/" ]]; then
91
+ discard=1
92
+ elif [[ $line =~ $regex_json_spec_start ]]; then
93
+ discard=2
94
+ regex_json_end="^${line%%[^ ]*}\\},? *$"
95
+ elif [[ $line =~ $regex_json_child_start ]]; then
96
+ discard=2
97
+ regex_json_end="^${line%%[^ ]*}\\],? *$"
98
+ fi
99
fi
100
if [[ $discard == 0 ]]; then
101
echo "$line"
102
elif [[ $discard == 1 && ! $line ]]; then
103
echo
104
discard=0
105
- elif [[ $discard == 2 && $line =~ $regex_json_spec_end ]]; then
106
+ elif [[ $discard == 2 && $line =~ $regex_json_end ]]; then
107
discard=0
108
fi
109
done
25
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
110
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
26
index XXXXXXX..XXXXXXX 100644
111
index XXXXXXX..XXXXXXX 100644
27
--- a/tests/qemu-iotests/common.rc
112
--- a/tests/qemu-iotests/common.rc
28
+++ b/tests/qemu-iotests/common.rc
113
+++ b/tests/qemu-iotests/common.rc
29
@@ -XXX,XX +XXX,XX @@ _unsupported_imgopts()
114
@@ -XXX,XX +XXX,XX @@ _img_info()
30
{
115
31
for bad_opt
116
discard=0
32
do
117
regex_json_spec_start='^ *"format-specific": \{'
33
- if echo "$IMGOPTS" | grep -q 2>/dev/null "$bad_opt"
118
+ regex_json_child_start='^ *"children": \['
34
+ # Add a space so tests can match for whitespace that marks the
119
$QEMU_IMG info $QEMU_IMG_EXTRA_ARGS "$@" "$TEST_IMG" 2>&1 | \
35
+ # end of an option (\b or \> are not portable)
120
sed -e "s#$REMOTE_TEST_DIR#TEST_DIR#g" \
36
+ if echo "$IMGOPTS " | grep -q 2>/dev/null "$bad_opt"
121
-e "s#$IMGPROTO:$TEST_DIR#TEST_DIR#g" \
37
then
122
@@ -XXX,XX +XXX,XX @@ _img_info()
38
_notrun "not suitable for image option: $bad_opt"
123
-e "/^disk size:/ D" \
39
fi
124
-e "/actual-size/ D" | \
125
while IFS='' read -r line; do
126
- if [[ $format_specific == 1 ]]; then
127
- discard=0
128
- elif [[ $line == "Format specific information:" ]]; then
129
- discard=1
130
- elif [[ $line =~ $regex_json_spec_start ]]; then
131
- discard=2
132
- regex_json_spec_end="^${line%%[^ ]*}\\},? *$"
133
+ if [[ $discard == 0 ]]; then
134
+ if [[ $format_specific == 0 && $line == "Format specific information:" ]]; then
135
+ discard=1
136
+ elif [[ $line =~ "Child node '/" ]]; then
137
+ discard=1
138
+ elif [[ $format_specific == 0 && $line =~ $regex_json_spec_start ]]; then
139
+ discard=2
140
+ regex_json_end="^${line%%[^ ]*}\\},? *$"
141
+ elif [[ $line =~ $regex_json_child_start ]]; then
142
+ discard=2
143
+ regex_json_end="^${line%%[^ ]*}\\],? *$"
144
+ fi
145
fi
146
if [[ $discard == 0 ]]; then
147
echo "$line"
148
elif [[ $discard == 1 && ! $line ]]; then
149
echo
150
discard=0
151
- elif [[ $discard == 2 && $line =~ $regex_json_spec_end ]]; then
152
+ elif [[ $discard == 2 && $line =~ $regex_json_end ]]; then
153
discard=0
154
fi
155
done
40
--
156
--
41
2.29.2
157
2.38.1
42
43
diff view generated by jsdifflib
New patch
1
From: Hanna Reitz <hreitz@redhat.com>
1
2
3
These tests read size information (sometimes disk size, sometimes
4
virtual size) from qemu-img info's output. Once qemu-img starts
5
printing info about child nodes, we are going to see multiple instances
6
of that per image, but these tests are only interested in the first one,
7
so use "head -n 1" to get it.
8
9
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
10
Message-Id: <20220620162704.80987-11-hreitz@redhat.com>
11
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
14
tests/qemu-iotests/106 | 4 ++--
15
tests/qemu-iotests/214 | 6 ++++--
16
tests/qemu-iotests/308 | 4 ++--
17
3 files changed, 8 insertions(+), 6 deletions(-)
18
19
diff --git a/tests/qemu-iotests/106 b/tests/qemu-iotests/106
20
index XXXXXXX..XXXXXXX 100755
21
--- a/tests/qemu-iotests/106
22
+++ b/tests/qemu-iotests/106
23
@@ -XXX,XX +XXX,XX @@ for create_mode in off falloc full; do
24
expected_size=$((expected_size + $GROWTH_SIZE))
25
fi
26
27
- actual_size=$($QEMU_IMG info -f "$IMGFMT" "$TEST_IMG" | grep 'disk size')
28
+ actual_size=$($QEMU_IMG info -f "$IMGFMT" "$TEST_IMG" | grep 'disk size' | head -n 1)
29
actual_size=$(echo "$actual_size" | sed -e 's/^[^0-9]*\([0-9]\+\).*$/\1/')
30
31
# The actual size may exceed the expected size, depending on the file
32
@@ -XXX,XX +XXX,XX @@ for growth_mode in falloc full; do
33
_make_test_img -o "extent_size_hint=0" 2G
34
$QEMU_IMG resize -f "$IMGFMT" --preallocation=$growth_mode "$TEST_IMG" +${GROWTH_SIZE}K
35
36
- actual_size=$($QEMU_IMG info -f "$IMGFMT" "$TEST_IMG" | grep 'disk size')
37
+ actual_size=$($QEMU_IMG info -f "$IMGFMT" "$TEST_IMG" | grep 'disk size' | head -n 1)
38
actual_size=$(echo "$actual_size" | sed -e 's/^[^0-9]*\([0-9]\+\).*$/\1/')
39
40
if [ $actual_size -lt $GROWTH_SIZE ]; then
41
diff --git a/tests/qemu-iotests/214 b/tests/qemu-iotests/214
42
index XXXXXXX..XXXXXXX 100755
43
--- a/tests/qemu-iotests/214
44
+++ b/tests/qemu-iotests/214
45
@@ -XXX,XX +XXX,XX @@ let data_size="8 * $cluster_size"
46
$QEMU_IO -c "write -P 0xaa 0 $data_size" "$TEST_IMG" \
47
2>&1 | _filter_qemu_io | _filter_testdir
48
sizeA=$($QEMU_IMG info --output=json "$TEST_IMG" |
49
- sed -n '/"actual-size":/ s/[^0-9]//gp')
50
+ sed -n '/"actual-size":/ s/[^0-9]//gp' |
51
+ head -n 1)
52
53
_make_test_img 2M -o cluster_size=$cluster_size
54
echo "Write compressed data:"
55
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c "write -P 0xcc $offset $data_size" "json:{\
56
_filter_qemu_io | _filter_testdir
57
58
sizeB=$($QEMU_IMG info --output=json "$TEST_IMG" |
59
- sed -n '/"actual-size":/ s/[^0-9]//gp')
60
+ sed -n '/"actual-size":/ s/[^0-9]//gp' |
61
+ head -n 1)
62
63
if [ $sizeA -lt $sizeB ]
64
then
65
diff --git a/tests/qemu-iotests/308 b/tests/qemu-iotests/308
66
index XXXXXXX..XXXXXXX 100755
67
--- a/tests/qemu-iotests/308
68
+++ b/tests/qemu-iotests/308
69
@@ -XXX,XX +XXX,XX @@ echo
70
echo '=== Remove export ==='
71
72
# Double-check that $EXT_MP appears as a non-empty file (the raw image)
73
-$QEMU_IMG info -f raw "$EXT_MP" | grep 'virtual size'
74
+$QEMU_IMG info -f raw "$EXT_MP" | grep 'virtual size' | head -n 1
75
76
fuse_export_del 'export-mp'
77
78
# See that the file appears empty again
79
-$QEMU_IMG info -f raw "$EXT_MP" | grep 'virtual size'
80
+$QEMU_IMG info -f raw "$EXT_MP" | grep 'virtual size' | head -n 1
81
82
echo
83
echo '=== Writable export ==='
84
--
85
2.38.1
diff view generated by jsdifflib
New patch
1
1
From: Hanna Reitz <hreitz@redhat.com>
2
3
For every node in the backing chain, collect its BlockGraphInfo struct
4
using bdrv_query_block_graph_info(). Print all nodes' information,
5
indenting child nodes and labelling them with a path constructed from
6
the child names leading to the node from the root (e.g. /file/file).
7
8
Note that we open each image with BDRV_O_NO_BACKING, so its backing
9
child is omitted from this graph, and thus presented in the previous
10
manner: By simply concatenating all images' information, separated with
11
blank lines.
12
13
This affects two iotests:
14
- 065: Here we try to get the format node's format specific information.
15
The pre-patch code does so by taking all lines from "Format specific
16
information:" until an empty line. This format specific information
17
is no longer followed by an empty line, though, but by child node
18
information, so limit the range by "Child node '/file':".
19
- 302: Calls qemu_img() for qemu-img info directly, which does not
20
filter the output, so the child node information ends up in the
21
output.
22
23
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
24
Message-Id: <20220620162704.80987-12-hreitz@redhat.com>
25
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
26
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
27
---
28
qapi/block-core.json | 4 +--
29
qemu-img.c | 69 ++++++++++++++++++++++++++------------
30
tests/qemu-iotests/065 | 2 +-
31
tests/qemu-iotests/302.out | 5 +++
32
4 files changed, 56 insertions(+), 24 deletions(-)
33
34
diff --git a/qapi/block-core.json b/qapi/block-core.json
35
index XXXXXXX..XXXXXXX 100644
36
--- a/qapi/block-core.json
37
+++ b/qapi/block-core.json
38
@@ -XXX,XX +XXX,XX @@
39
##
40
# @DummyBlockCoreForceArrays:
41
#
42
-# Not used by QMP; hack to let us use BlockNodeInfoList internally
43
+# Not used by QMP; hack to let us use BlockGraphInfoList internally
44
#
45
# Since: 8.0
46
##
47
{ 'struct': 'DummyBlockCoreForceArrays',
48
- 'data': { 'unused-block-node-info': ['BlockNodeInfo'] } }
49
+ 'data': { 'unused-block-graph-info': ['BlockGraphInfo'] } }
50
diff --git a/qemu-img.c b/qemu-img.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/qemu-img.c
53
+++ b/qemu-img.c
54
@@ -XXX,XX +XXX,XX @@ static void dump_snapshots(BlockDriverState *bs)
55
g_free(sn_tab);
56
}
57
58
-static void dump_json_block_node_info_list(BlockNodeInfoList *list)
59
+static void dump_json_block_graph_info_list(BlockGraphInfoList *list)
60
{
61
GString *str;
62
QObject *obj;
63
Visitor *v = qobject_output_visitor_new(&obj);
64
65
- visit_type_BlockNodeInfoList(v, NULL, &list, &error_abort);
66
+ visit_type_BlockGraphInfoList(v, NULL, &list, &error_abort);
67
visit_complete(v, &obj);
68
str = qobject_to_json_pretty(obj, true);
69
assert(str != NULL);
70
@@ -XXX,XX +XXX,XX @@ static void dump_json_block_node_info_list(BlockNodeInfoList *list)
71
g_string_free(str, true);
72
}
73
74
-static void dump_json_block_node_info(BlockNodeInfo *info)
75
+static void dump_json_block_graph_info(BlockGraphInfo *info)
76
{
77
GString *str;
78
QObject *obj;
79
Visitor *v = qobject_output_visitor_new(&obj);
80
81
- visit_type_BlockNodeInfo(v, NULL, &info, &error_abort);
82
+ visit_type_BlockGraphInfo(v, NULL, &info, &error_abort);
83
visit_complete(v, &obj);
84
str = qobject_to_json_pretty(obj, true);
85
assert(str != NULL);
86
@@ -XXX,XX +XXX,XX @@ static void dump_json_block_node_info(BlockNodeInfo *info)
87
g_string_free(str, true);
88
}
89
90
-static void dump_human_image_info_list(BlockNodeInfoList *list)
91
+static void dump_human_image_info(BlockGraphInfo *info, int indentation,
92
+ const char *path)
93
{
94
- BlockNodeInfoList *elem;
95
+ BlockChildInfoList *children_list;
96
+
97
+ bdrv_node_info_dump(qapi_BlockGraphInfo_base(info), indentation);
98
+
99
+ for (children_list = info->children; children_list;
100
+ children_list = children_list->next)
101
+ {
102
+ BlockChildInfo *child = children_list->value;
103
+ g_autofree char *child_path;
104
+
105
+ printf("%*sChild node '%s%s':\n",
106
+ indentation * 4, "", path, child->name);
107
+ child_path = g_strdup_printf("%s%s/", path, child->name);
108
+ dump_human_image_info(child->info, indentation + 1, child_path);
109
+ }
110
+}
111
+
112
+static void dump_human_image_info_list(BlockGraphInfoList *list)
113
+{
114
+ BlockGraphInfoList *elem;
115
bool delim = false;
116
117
for (elem = list; elem; elem = elem->next) {
118
@@ -XXX,XX +XXX,XX @@ static void dump_human_image_info_list(BlockNodeInfoList *list)
119
}
120
delim = true;
121
122
- bdrv_node_info_dump(elem->value, 0);
123
+ dump_human_image_info(elem->value, 0, "/");
124
}
125
}
126
127
@@ -XXX,XX +XXX,XX @@ static gboolean str_equal_func(gconstpointer a, gconstpointer b)
128
}
129
130
/**
131
- * Open an image file chain and return an BlockNodeInfoList
132
+ * Open an image file chain and return an BlockGraphInfoList
133
*
134
* @filename: topmost image filename
135
* @fmt: topmost image format (may be NULL to autodetect)
136
@@ -XXX,XX +XXX,XX @@ static gboolean str_equal_func(gconstpointer a, gconstpointer b)
137
* opening an image file. If there was an error a message will have been
138
* printed to stderr.
139
*/
140
-static BlockNodeInfoList *collect_image_info_list(bool image_opts,
141
- const char *filename,
142
- const char *fmt,
143
- bool chain, bool force_share)
144
+static BlockGraphInfoList *collect_image_info_list(bool image_opts,
145
+ const char *filename,
146
+ const char *fmt,
147
+ bool chain, bool force_share)
148
{
149
- BlockNodeInfoList *head = NULL;
150
- BlockNodeInfoList **tail = &head;
151
+ BlockGraphInfoList *head = NULL;
152
+ BlockGraphInfoList **tail = &head;
153
GHashTable *filenames;
154
Error *err = NULL;
155
156
@@ -XXX,XX +XXX,XX @@ static BlockNodeInfoList *collect_image_info_list(bool image_opts,
157
while (filename) {
158
BlockBackend *blk;
159
BlockDriverState *bs;
160
- BlockNodeInfo *info;
161
+ BlockGraphInfo *info;
162
163
if (g_hash_table_lookup_extended(filenames, filename, NULL, NULL)) {
164
error_report("Backing file '%s' creates an infinite loop.",
165
@@ -XXX,XX +XXX,XX @@ static BlockNodeInfoList *collect_image_info_list(bool image_opts,
166
}
167
bs = blk_bs(blk);
168
169
- bdrv_query_block_node_info(bs, &info, &err);
170
+ /*
171
+ * Note that the returned BlockGraphInfo object will not have
172
+ * information about this image's backing node, because we have opened
173
+ * it with BDRV_O_NO_BACKING. Printing this object will therefore not
174
+ * duplicate the backing chain information that we obtain by walking
175
+ * the chain manually here.
176
+ */
177
+ bdrv_query_block_graph_info(bs, &info, &err);
178
if (err) {
179
error_report_err(err);
180
blk_unref(blk);
181
@@ -XXX,XX +XXX,XX @@ static BlockNodeInfoList *collect_image_info_list(bool image_opts,
182
return head;
183
184
err:
185
- qapi_free_BlockNodeInfoList(head);
186
+ qapi_free_BlockGraphInfoList(head);
187
g_hash_table_destroy(filenames);
188
return NULL;
189
}
190
@@ -XXX,XX +XXX,XX @@ static int img_info(int argc, char **argv)
191
OutputFormat output_format = OFORMAT_HUMAN;
192
bool chain = false;
193
const char *filename, *fmt, *output;
194
- BlockNodeInfoList *list;
195
+ BlockGraphInfoList *list;
196
bool image_opts = false;
197
bool force_share = false;
198
199
@@ -XXX,XX +XXX,XX @@ static int img_info(int argc, char **argv)
200
break;
201
case OFORMAT_JSON:
202
if (chain) {
203
- dump_json_block_node_info_list(list);
204
+ dump_json_block_graph_info_list(list);
205
} else {
206
- dump_json_block_node_info(list->value);
207
+ dump_json_block_graph_info(list->value);
208
}
209
break;
210
}
211
212
- qapi_free_BlockNodeInfoList(list);
213
+ qapi_free_BlockGraphInfoList(list);
214
return 0;
215
}
216
217
diff --git a/tests/qemu-iotests/065 b/tests/qemu-iotests/065
218
index XXXXXXX..XXXXXXX 100755
219
--- a/tests/qemu-iotests/065
220
+++ b/tests/qemu-iotests/065
221
@@ -XXX,XX +XXX,XX @@ class TestQemuImgInfo(TestImageInfoSpecific):
222
def test_human(self):
223
data = qemu_img('info', '--output=human', test_img).stdout.split('\n')
224
data = data[(data.index('Format specific information:') + 1)
225
- :data.index('')]
226
+ :data.index("Child node '/file':")]
227
for field in data:
228
self.assertTrue(re.match('^ {4}[^ ]', field) is not None)
229
data = [line.strip() for line in data]
230
diff --git a/tests/qemu-iotests/302.out b/tests/qemu-iotests/302.out
231
index XXXXXXX..XXXXXXX 100644
232
--- a/tests/qemu-iotests/302.out
233
+++ b/tests/qemu-iotests/302.out
234
@@ -XXX,XX +XXX,XX @@ image: nbd+unix:///exp?socket=SOCK_DIR/PID-nbd-sock
235
file format: raw
236
virtual size: 448 KiB (458752 bytes)
237
disk size: unavailable
238
+Child node '/file':
239
+ image: nbd+unix:///exp?socket=SOCK_DIR/PID-nbd-sock
240
+ file format: nbd
241
+ virtual size: 448 KiB (458752 bytes)
242
+ disk size: unavailable
243
244
=== Converted image info ===
245
image: TEST_IMG
246
--
247
2.38.1
diff view generated by jsdifflib
New patch
1
From: Hanna Reitz <hreitz@redhat.com>
1
2
3
Currently, when querying a qcow2 image, qemu-img info reports something
4
like this:
5
6
image: test.qcow2
7
file format: qcow2
8
virtual size: 64 MiB (67108864 bytes)
9
disk size: 196 KiB
10
cluster_size: 65536
11
Format specific information:
12
compat: 1.1
13
compression type: zlib
14
lazy refcounts: false
15
refcount bits: 16
16
corrupt: false
17
extended l2: false
18
Child node '/file':
19
image: test.qcow2
20
file format: file
21
virtual size: 192 KiB (197120 bytes)
22
disk size: 196 KiB
23
Format specific information:
24
extent size hint: 1048576
25
26
Notably, the way the keys are named is specific for image files: The
27
filename is shown under "image", the BDS driver under "file format", and
28
the BDS length under "virtual size". This does not make much sense for
29
nodes that are not actually supposed to be guest images, like the /file
30
child node shown above.
31
32
Give bdrv_node_info_dump() a @protocol parameter that gives a hint that
33
the respective node is probably just used for data storage and does not
34
necessarily present the data for a VM guest disk. This renames the keys
35
so that with this patch, the output becomes:
36
37
image: test.qcow2
38
[...]
39
Child node '/file':
40
filename: test.qcow2
41
protocol type: file
42
file length: 192 KiB (197120 bytes)
43
disk size: 196 KiB
44
Format specific information:
45
extent size hint: 1048576
46
47
(Perhaps we should also rename "Format specific information", but I
48
could not come up with anything better that will not become problematic
49
if we guess wrong with the protocol "heuristic".)
50
51
This change affects iotest 302, which has protocol node information in
52
its reference output.
53
54
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
55
Message-Id: <20220620162704.80987-13-hreitz@redhat.com>
56
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
57
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
58
---
59
include/block/qapi.h | 2 +-
60
block/monitor/block-hmp-cmds.c | 2 +-
61
block/qapi.c | 39 ++++++++++++++++++++++++++++------
62
qemu-img.c | 3 ++-
63
tests/qemu-iotests/302.out | 6 +++---
64
5 files changed, 39 insertions(+), 13 deletions(-)
65
66
diff --git a/include/block/qapi.h b/include/block/qapi.h
67
index XXXXXXX..XXXXXXX 100644
68
--- a/include/block/qapi.h
69
+++ b/include/block/qapi.h
70
@@ -XXX,XX +XXX,XX @@ void bdrv_snapshot_dump(QEMUSnapshotInfo *sn);
71
void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec,
72
const char *prefix,
73
int indentation);
74
-void bdrv_node_info_dump(BlockNodeInfo *info, int indentation);
75
+void bdrv_node_info_dump(BlockNodeInfo *info, int indentation, bool protocol);
76
#endif
77
diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/block/monitor/block-hmp-cmds.c
80
+++ b/block/monitor/block-hmp-cmds.c
81
@@ -XXX,XX +XXX,XX @@ static void print_block_info(Monitor *mon, BlockInfo *info,
82
monitor_printf(mon, "\nImages:\n");
83
image_info = inserted->image;
84
while (1) {
85
- bdrv_node_info_dump(qapi_ImageInfo_base(image_info), 0);
86
+ bdrv_node_info_dump(qapi_ImageInfo_base(image_info), 0, false);
87
if (image_info->backing_image) {
88
image_info = image_info->backing_image;
89
} else {
90
diff --git a/block/qapi.c b/block/qapi.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/block/qapi.c
93
+++ b/block/qapi.c
94
@@ -XXX,XX +XXX,XX @@ void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec,
95
visit_free(v);
96
}
97
98
-void bdrv_node_info_dump(BlockNodeInfo *info, int indentation)
99
+/**
100
+ * Print the given @info object in human-readable form. Every field is indented
101
+ * using the given @indentation (four spaces per indentation level).
102
+ *
103
+ * When using this to print a whole block graph, @protocol can be set to true to
104
+ * signify that the given information is associated with a protocol node, i.e.
105
+ * just data storage for an image, such that the data it presents is not really
106
+ * a full VM disk. If so, several fields change name: For example, "virtual
107
+ * size" is printed as "file length".
108
+ * (Consider a qcow2 image, which is represented by a qcow2 node and a file
109
+ * node. Printing a "virtual size" for the file node does not make sense,
110
+ * because without the qcow2 node, it is not really a guest disk, so it does not
111
+ * have a "virtual size". Therefore, we call it "file length" instead.)
112
+ *
113
+ * @protocol is ignored when @indentation is 0, because we take that to mean
114
+ * that the associated node is the root node in the queried block graph, and
115
+ * thus is always to be interpreted as a standalone guest disk.
116
+ */
117
+void bdrv_node_info_dump(BlockNodeInfo *info, int indentation, bool protocol)
118
{
119
char *size_buf, *dsize_buf;
120
g_autofree char *ind_s = g_strdup_printf("%*s", indentation * 4, "");
121
122
+ if (indentation == 0) {
123
+ /* Top level, consider this a normal image */
124
+ protocol = false;
125
+ }
126
+
127
if (!info->has_actual_size) {
128
dsize_buf = g_strdup("unavailable");
129
} else {
130
dsize_buf = size_to_str(info->actual_size);
131
}
132
size_buf = size_to_str(info->virtual_size);
133
- qemu_printf("%simage: %s\n"
134
- "%sfile format: %s\n"
135
- "%svirtual size: %s (%" PRId64 " bytes)\n"
136
+ qemu_printf("%s%s: %s\n"
137
+ "%s%s: %s\n"
138
+ "%s%s: %s (%" PRId64 " bytes)\n"
139
"%sdisk size: %s\n",
140
- ind_s, info->filename,
141
- ind_s, info->format,
142
- ind_s, size_buf, info->virtual_size,
143
+ ind_s, protocol ? "filename" : "image", info->filename,
144
+ ind_s, protocol ? "protocol type" : "file format",
145
+ info->format,
146
+ ind_s, protocol ? "file length" : "virtual size",
147
+ size_buf, info->virtual_size,
148
ind_s, dsize_buf);
149
g_free(size_buf);
150
g_free(dsize_buf);
151
diff --git a/qemu-img.c b/qemu-img.c
152
index XXXXXXX..XXXXXXX 100644
153
--- a/qemu-img.c
154
+++ b/qemu-img.c
155
@@ -XXX,XX +XXX,XX @@ static void dump_human_image_info(BlockGraphInfo *info, int indentation,
156
{
157
BlockChildInfoList *children_list;
158
159
- bdrv_node_info_dump(qapi_BlockGraphInfo_base(info), indentation);
160
+ bdrv_node_info_dump(qapi_BlockGraphInfo_base(info), indentation,
161
+ info->children == NULL);
162
163
for (children_list = info->children; children_list;
164
children_list = children_list->next)
165
diff --git a/tests/qemu-iotests/302.out b/tests/qemu-iotests/302.out
166
index XXXXXXX..XXXXXXX 100644
167
--- a/tests/qemu-iotests/302.out
168
+++ b/tests/qemu-iotests/302.out
169
@@ -XXX,XX +XXX,XX @@ file format: raw
170
virtual size: 448 KiB (458752 bytes)
171
disk size: unavailable
172
Child node '/file':
173
- image: nbd+unix:///exp?socket=SOCK_DIR/PID-nbd-sock
174
- file format: nbd
175
- virtual size: 448 KiB (458752 bytes)
176
+ filename: nbd+unix:///exp?socket=SOCK_DIR/PID-nbd-sock
177
+ protocol type: nbd
178
+ file length: 448 KiB (458752 bytes)
179
disk size: unavailable
180
181
=== Converted image info ===
182
--
183
2.38.1
diff view generated by jsdifflib