1
The following changes since commit 16aaacb307ed607b9780c12702c44f0fe52edc7e:
1
The following changes since commit 17780edd81d27fcfdb7a802efc870a99788bd2fc:
2
2
3
Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20200430' into staging (2020-04-30 14:00:36 +0100)
3
Merge tag 'quick-fix-pull-request' of https://gitlab.com/bsdimp/qemu into staging (2023-08-31 10:06:29 -0400)
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 eaae29ef89d498d0eac553c77b554f310a47f809:
9
for you to fetch changes up to bb86eb45297840c31dbc4df6bac02e50596f2376:
10
10
11
qemu-storage-daemon: Fix non-string --object properties (2020-04-30 17:51:07 +0200)
11
block: Remove unnecessary variable in bdrv_block_device_info (2023-09-04 11:03:28 +0200)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block layer patches:
14
Block layer patches
15
15
16
- Fix resize (extending) of short overlays
16
- Process I/O in the current AioContext (instead of the BB AioContext)
17
- nvme: introduce PMR support from NVMe 1.4 spec
17
- Optimise reqs_lock to make multiqueue actually scale
18
- qemu-storage-daemon: Fix non-string --object properties
18
- iotests: Fix reference output for some tests after recent changes
19
- vpc: Avoid dynamic stack allocation
20
- Code cleanup, improved documentation
19
21
20
----------------------------------------------------------------
22
----------------------------------------------------------------
21
Alberto Garcia (1):
23
Dmitry Frolov (1):
22
qcow2: Add incompatibility note between backing files and raw external data files
24
vmdk: Clean up bdrv_open_child() return value check
23
25
24
Andrzej Jakowski (1):
26
Fabiano Rosas (2):
25
nvme: introduce PMR support from NVMe 1.4 spec
27
block: Remove bdrv_query_block_node_info
28
block: Remove unnecessary variable in bdrv_block_device_info
26
29
27
Kevin Wolf (12):
30
Fiona Ebner (1):
28
block: Add flags to BlockDriver.bdrv_co_truncate()
31
iotests: adapt test output for new qemu_cleanup() behavior
29
block: Add flags to bdrv(_co)_truncate()
30
block-backend: Add flags to blk_truncate()
31
qcow2: Support BDRV_REQ_ZERO_WRITE for truncate
32
raw-format: Support BDRV_REQ_ZERO_WRITE for truncate
33
file-posix: Support BDRV_REQ_ZERO_WRITE for truncate
34
block: truncate: Don't make backing file data visible
35
iotests: Filter testfiles out in filter_img_info()
36
iotests: Test committing to short backing file
37
qcow2: Forward ZERO_WRITE flag for full preallocation
38
qom: Factor out user_creatable_add_dict()
39
qemu-storage-daemon: Fix non-string --object properties
40
32
41
Paolo Bonzini (1):
33
Hanna Czenczek (1):
42
qemu-iotests: allow qcow2 external discarded clusters to contain stale data
34
block: Be more verbose in create fallback
43
35
44
docs/interop/qcow2.txt | 3 +
36
Kevin Wolf (1):
45
hw/block/nvme.h | 2 +
37
qemu-img: Update documentation for compressed images
46
include/block/block.h | 5 +-
38
47
include/block/block_int.h | 10 +-
39
Michael Tokarev (1):
48
include/block/nvme.h | 172 ++++++++++++++++++++++++++
40
qemu-img: omit errno value in error message
49
include/qom/object_interfaces.h | 16 +++
41
50
include/sysemu/block-backend.h | 2 +-
42
Peter Maydell (1):
51
block.c | 3 +-
43
block/iscsi: Document why we use raw malloc()
52
block/block-backend.c | 4 +-
44
53
block/commit.c | 4 +-
45
Philippe Mathieu-Daudé (1):
54
block/crypto.c | 7 +-
46
block/vpc: Avoid dynamic stack allocation
55
block/file-posix.c | 6 +-
47
56
block/file-win32.c | 2 +-
48
Stefan Hajnoczi (5):
57
block/gluster.c | 1 +
49
block: minimize bs->reqs_lock section in tracked_request_end()
58
block/io.c | 43 ++++++-
50
block: change reqs_lock to QemuMutex
59
block/iscsi.c | 2 +-
51
block: remove AIOCBInfo->get_aio_context()
60
block/mirror.c | 2 +-
52
block-backend: process I/O in the current AioContext
61
block/nfs.c | 3 +-
53
block-backend: process zoned requests in the current AioContext
62
block/parallels.c | 6 +-
54
63
block/qcow.c | 4 +-
55
docs/tools/qemu-img.rst | 19 ++++++++++++--
64
block/qcow2-cluster.c | 2 +-
56
include/block/aio.h | 1 -
65
block/qcow2-refcount.c | 2 +-
57
include/block/block-global-state.h | 2 ++
66
block/qcow2.c | 73 +++++++++--
58
include/block/block-io.h | 1 -
67
block/qed.c | 3 +-
59
include/block/block_int-common.h | 2 +-
68
block/raw-format.c | 6 +-
60
include/block/qapi.h | 3 ---
69
block/rbd.c | 1 +
61
block.c | 10 ++++---
70
block/sheepdog.c | 4 +-
62
block/block-backend.c | 35 +++++++------------------
71
block/ssh.c | 2 +-
63
block/io.c | 53 +++++++++++++++++++-------------------
72
block/vdi.c | 2 +-
64
block/iscsi.c | 1 +
73
block/vhdx-log.c | 2 +-
65
block/qapi.c | 32 ++---------------------
74
block/vhdx.c | 6 +-
66
block/vmdk.c | 2 +-
75
block/vmdk.c | 8 +-
67
block/vpc.c | 4 +--
76
block/vpc.c | 2 +-
68
hw/nvme/ctrl.c | 7 -----
77
blockdev.c | 2 +-
69
qemu-img.c | 4 +--
78
hw/block/nvme.c | 109 ++++++++++++++++
70
softmmu/dma-helpers.c | 8 ------
79
qemu-img.c | 2 +-
71
util/thread-pool.c | 8 ------
80
qemu-io-cmds.c | 2 +-
72
tests/qemu-iotests/080.out | 6 ++---
81
qemu-storage-daemon.c | 4 +-
73
tests/qemu-iotests/109.out | 24 +++++++++++++++++
82
qom/object_interfaces.c | 31 +++++
74
tests/qemu-iotests/112.out | 6 ++---
83
qom/qom-qmp-cmds.c | 24 +---
75
tests/qemu-iotests/185 | 2 ++
84
tests/test-block-iothread.c | 9 +-
76
tests/qemu-iotests/185.out | 4 +++
85
tests/qemu-iotests/iotests.py | 5 +-
77
tests/qemu-iotests/244.out | 2 +-
86
hw/block/Makefile.objs | 2 +-
78
23 files changed, 107 insertions(+), 129 deletions(-)
87
hw/block/trace-events | 4 +
88
tests/qemu-iotests/244 | 10 +-
89
tests/qemu-iotests/244.out | 9 +-
90
tests/qemu-iotests/274 | 155 +++++++++++++++++++++++
91
tests/qemu-iotests/274.out | 268 ++++++++++++++++++++++++++++++++++++++++
92
tests/qemu-iotests/group | 1 +
93
49 files changed, 951 insertions(+), 96 deletions(-)
94
create mode 100755 tests/qemu-iotests/274
95
create mode 100644 tests/qemu-iotests/274.out
96
79
97
80
diff view generated by jsdifflib
Deleted patch
1
From: Alberto Garcia <berto@igalia.com>
2
1
3
Backing files and raw external data files are mutually exclusive.
4
The documentation of the raw external data bit (in autoclear_features)
5
already indicates that, but we should also mention it on the other
6
side.
7
8
Suggested-by: Eric Blake <eblake@redhat.com>
9
Signed-off-by: Alberto Garcia <berto@igalia.com>
10
Message-Id: <20200410121816.8334-1-berto@igalia.com>
11
Reviewed-by: Eric Blake <eblake@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
14
docs/interop/qcow2.txt | 3 +++
15
1 file changed, 3 insertions(+)
16
17
diff --git a/docs/interop/qcow2.txt b/docs/interop/qcow2.txt
18
index XXXXXXX..XXXXXXX 100644
19
--- a/docs/interop/qcow2.txt
20
+++ b/docs/interop/qcow2.txt
21
@@ -XXX,XX +XXX,XX @@ The first cluster of a qcow2 image contains the file header:
22
is stored (NB: The string is not null terminated). 0 if the
23
image doesn't have a backing file.
24
25
+ Note: backing files are incompatible with raw external data
26
+ files (auto-clear feature bit 1).
27
+
28
16 - 19: backing_file_size
29
Length of the backing file name in bytes. Must not be
30
longer than 1023 bytes. Undefined if the image doesn't have
31
--
32
2.25.3
33
34
diff view generated by jsdifflib
1
After processing the option string with the keyval parser, we get a
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
QDict that contains only strings. This QDict must be fed to a keyval
3
visitor which converts the strings into the right data types.
4
2
5
qmp_object_add(), however, uses the normal QObject input visitor, which
3
Use autofree heap allocation instead of variable-length array on the
6
expects a QDict where all properties already have the QType that matches
4
stack. Here we don't expect the bitmap size to be enormous, and
7
the data type required by the QOM object type.
5
since we're about to read/write it to disk the overhead of the
6
allocation should be fine.
8
7
9
Change the --object implementation in qemu-storage-daemon so that it
8
The codebase has very few VLAs, and if we can get rid of them all we
10
doesn't call qmp_object_add(), but calls user_creatable_add_dict()
9
can make the compiler error on new additions. This is a defensive
11
directly instead and pass it a new keyval boolean that decides which
10
measure against security bugs where an on-stack dynamic allocation
12
visitor must be used.
11
isn't correctly size-checked (e.g. CVE-2021-3527).
13
12
14
Reported-by: Coiby Xu <coiby.xu@gmail.com>
13
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
14
[PMM: expanded commit message]
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Message-ID: <20230811175229.808139-1-peter.maydell@linaro.org>
17
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
18
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
15
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
19
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
---
20
---
17
include/qom/object_interfaces.h | 6 +++++-
21
block/vpc.c | 4 ++--
18
qemu-storage-daemon.c | 4 +---
22
1 file changed, 2 insertions(+), 2 deletions(-)
19
qom/object_interfaces.c | 8 ++++++--
20
qom/qom-qmp-cmds.c | 2 +-
21
4 files changed, 13 insertions(+), 7 deletions(-)
22
23
23
diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h
24
diff --git a/block/vpc.c b/block/vpc.c
24
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
25
--- a/include/qom/object_interfaces.h
26
--- a/block/vpc.c
26
+++ b/include/qom/object_interfaces.h
27
+++ b/block/vpc.c
27
@@ -XXX,XX +XXX,XX @@ Object *user_creatable_add_type(const char *type, const char *id,
28
@@ -XXX,XX +XXX,XX @@ get_image_offset(BlockDriverState *bs, uint64_t offset, bool write, int *err)
28
/**
29
miss sparse read optimization, but it's not a problem in terms of
29
* user_creatable_add_dict:
30
correctness. */
30
* @qdict: the object definition
31
if (write && (s->last_bitmap_offset != bitmap_offset)) {
31
+ * @keyval: if true, use a keyval visitor for processing @qdict (i.e.
32
- uint8_t bitmap[s->bitmap_size];
32
+ * assume that all @qdict values are strings); otherwise, use
33
+ g_autofree uint8_t *bitmap = g_malloc(s->bitmap_size);
33
+ * the normal QObject visitor (i.e. assume all @qdict values
34
int r;
34
+ * have the QType expected by the QOM object type)
35
35
* @errp: if an error occurs, a pointer to an area to store the error
36
s->last_bitmap_offset = bitmap_offset;
36
*
37
@@ -XXX,XX +XXX,XX @@ alloc_block(BlockDriverState *bs, int64_t offset)
37
* Create an instance of the user creatable object that is defined by
38
int64_t bat_offset;
38
@@ -XXX,XX +XXX,XX @@ Object *user_creatable_add_type(const char *type, const char *id,
39
uint32_t index, bat_value;
39
* ID from the key 'id'. The remaining entries in @qdict are used to
40
int ret;
40
* initialize the object properties.
41
- uint8_t bitmap[s->bitmap_size];
41
*/
42
+ g_autofree uint8_t *bitmap = g_malloc(s->bitmap_size);
42
-void user_creatable_add_dict(QDict *qdict, Error **errp);
43
43
+void user_creatable_add_dict(QDict *qdict, bool keyval, Error **errp);
44
/* Check if sector_num is valid */
44
45
if ((offset < 0) || (offset > bs->total_sectors * BDRV_SECTOR_SIZE)) {
45
/**
46
* user_creatable_add_opts:
47
diff --git a/qemu-storage-daemon.c b/qemu-storage-daemon.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/qemu-storage-daemon.c
50
+++ b/qemu-storage-daemon.c
51
@@ -XXX,XX +XXX,XX @@ static void process_options(int argc, char *argv[])
52
QemuOpts *opts;
53
const char *type;
54
QDict *args;
55
- QObject *ret_data = NULL;
56
57
/* FIXME The keyval parser rejects 'help' arguments, so we must
58
* unconditionall try QemuOpts first. */
59
@@ -XXX,XX +XXX,XX @@ static void process_options(int argc, char *argv[])
60
qemu_opts_del(opts);
61
62
args = keyval_parse(optarg, "qom-type", &error_fatal);
63
- qmp_object_add(args, &ret_data, &error_fatal);
64
+ user_creatable_add_dict(args, true, &error_fatal);
65
qobject_unref(args);
66
- qobject_unref(ret_data);
67
break;
68
}
69
default:
70
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/qom/object_interfaces.c
73
+++ b/qom/object_interfaces.c
74
@@ -XXX,XX +XXX,XX @@ out:
75
return obj;
76
}
77
78
-void user_creatable_add_dict(QDict *qdict, Error **errp)
79
+void user_creatable_add_dict(QDict *qdict, bool keyval, Error **errp)
80
{
81
Visitor *v;
82
Object *obj;
83
@@ -XXX,XX +XXX,XX @@ void user_creatable_add_dict(QDict *qdict, Error **errp)
84
}
85
qdict_del(qdict, "id");
86
87
- v = qobject_input_visitor_new(QOBJECT(qdict));
88
+ if (keyval) {
89
+ v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
90
+ } else {
91
+ v = qobject_input_visitor_new(QOBJECT(qdict));
92
+ }
93
obj = user_creatable_add_type(type, id, qdict, v, errp);
94
visit_free(v);
95
object_unref(obj);
96
diff --git a/qom/qom-qmp-cmds.c b/qom/qom-qmp-cmds.c
97
index XXXXXXX..XXXXXXX 100644
98
--- a/qom/qom-qmp-cmds.c
99
+++ b/qom/qom-qmp-cmds.c
100
@@ -XXX,XX +XXX,XX @@ void qmp_object_add(QDict *qdict, QObject **ret_data, Error **errp)
101
qobject_unref(pdict);
102
}
103
104
- user_creatable_add_dict(qdict, errp);
105
+ user_creatable_add_dict(qdict, false, errp);
106
}
107
108
void qmp_object_del(const char *id, Error **errp)
109
--
46
--
110
2.25.3
47
2.41.0
111
48
112
49
diff view generated by jsdifflib
1
The BDRV_REQ_ZERO_WRITE is currently implemented in a way that first the
1
From: Fiona Ebner <f.ebner@proxmox.com>
2
image is possibly preallocated and then the zero flag is added to all
3
clusters. This means that a copy-on-write operation may be needed when
4
writing to these clusters, despite having used preallocation, negating
5
one of the major benefits of preallocation.
6
2
7
Instead, try to forward the BDRV_REQ_ZERO_WRITE to the protocol driver,
3
Since commit ca2a5e630d ("qemu_cleanup: begin drained section after
8
and if the protocol driver can ensure that the new area reads as zeros,
4
vm_shutdown()"), there will be an additional pause for jobs during
9
we can skip setting the zero flag in the qcow2 layer.
5
qemu_cleanup(). The reason is that the bdrv_drain_all() call in
6
do_vm_stop() is not inside the drained section used by qemu_cleanup()
7
anymore. I.e., there is a second drained section now that ends before
8
the final one in qemu_cleanup() starts. Thus, job_pause() is called
9
twice during cleanup (via child_job_drained_begin()).
10
10
11
Unfortunately, the same approach doesn't work for metadata
11
Test 185 needs to be adapted directly too, because it waits for a
12
preallocation, so we'll still set the zero flag there.
12
specific number of JOB_STATUS_CHANGE events before the
13
BLOCK_JOB_CANCELLED event.
13
14
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
Reported-by: Kevin Wolf <kwolf@redhat.com>
15
Reviewed-by: Max Reitz <mreitz@redhat.com>
16
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
16
Message-Id: <20200424142701.67053-1-kwolf@redhat.com>
17
Message-ID: <20230817112538.255111-1-f.ebner@proxmox.com>
17
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
18
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
18
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
19
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
19
---
20
---
20
block/qcow2.c | 22 +++++++++++++++++++---
21
tests/qemu-iotests/109.out | 24 ++++++++++++++++++++++++
21
tests/qemu-iotests/274.out | 4 ++--
22
tests/qemu-iotests/185 | 2 ++
22
2 files changed, 21 insertions(+), 5 deletions(-)
23
tests/qemu-iotests/185.out | 4 ++++
24
3 files changed, 30 insertions(+)
23
25
24
diff --git a/block/qcow2.c b/block/qcow2.c
26
diff --git a/tests/qemu-iotests/109.out b/tests/qemu-iotests/109.out
25
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
26
--- a/block/qcow2.c
28
--- a/tests/qemu-iotests/109.out
27
+++ b/block/qcow2.c
29
+++ b/tests/qemu-iotests/109.out
28
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
30
@@ -XXX,XX +XXX,XX @@ read 512/512 bytes at offset 0
29
/* Allocate the data area */
31
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
30
new_file_size = allocation_start +
32
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "src"}}
31
nb_new_data_clusters * s->cluster_size;
33
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}}
32
- /* Image file grows, so @exact does not matter */
34
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "src"}}
33
- ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc, 0,
35
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}}
34
- errp);
36
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "src"}}
35
+ /*
37
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "src", "len": 1024, "offset": 1024, "speed": 0, "type": "mirror"}}
36
+ * Image file grows, so @exact does not matter.
38
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}}
37
+ *
39
@@ -XXX,XX +XXX,XX @@ read 512/512 bytes at offset 0
38
+ * If we need to zero out the new area, try first whether the protocol
40
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
39
+ * driver can already take care of this.
41
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "src"}}
40
+ */
42
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}}
41
+ if (flags & BDRV_REQ_ZERO_WRITE) {
43
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "src"}}
42
+ ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc,
44
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}}
43
+ BDRV_REQ_ZERO_WRITE, NULL);
45
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "src"}}
44
+ if (ret >= 0) {
46
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "src", "len": 197120, "offset": 197120, "speed": 0, "type": "mirror"}}
45
+ flags &= ~BDRV_REQ_ZERO_WRITE;
47
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}}
46
+ }
48
@@ -XXX,XX +XXX,XX @@ read 512/512 bytes at offset 0
47
+ } else {
49
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
48
+ ret = -1;
50
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "src"}}
49
+ }
51
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}}
50
+ if (ret < 0) {
52
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "src"}}
51
+ ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc, 0,
53
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}}
52
+ errp);
54
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "src"}}
53
+ }
55
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "src", "len": 327680, "offset": 327680, "speed": 0, "type": "mirror"}}
54
if (ret < 0) {
56
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}}
55
error_prepend(errp, "Failed to resize underlying file: ");
57
@@ -XXX,XX +XXX,XX @@ read 512/512 bytes at offset 0
56
qcow2_free_clusters(bs, allocation_start,
58
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
57
diff --git a/tests/qemu-iotests/274.out b/tests/qemu-iotests/274.out
59
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "src"}}
60
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}}
61
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "src"}}
62
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}}
63
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "src"}}
64
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "src", "len": 1024, "offset": 1024, "speed": 0, "type": "mirror"}}
65
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}}
66
@@ -XXX,XX +XXX,XX @@ read 512/512 bytes at offset 0
67
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
68
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "src"}}
69
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}}
70
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "src"}}
71
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}}
72
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "src"}}
73
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "src", "len": 65536, "offset": 65536, "speed": 0, "type": "mirror"}}
74
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}}
75
@@ -XXX,XX +XXX,XX @@ read 512/512 bytes at offset 0
76
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
77
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "src"}}
78
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}}
79
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "src"}}
80
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}}
81
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "src"}}
82
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "src", "len": 2560, "offset": 2560, "speed": 0, "type": "mirror"}}
83
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}}
84
@@ -XXX,XX +XXX,XX @@ read 512/512 bytes at offset 0
85
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
86
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "src"}}
87
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}}
88
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "src"}}
89
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}}
90
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "src"}}
91
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "src", "len": 2560, "offset": 2560, "speed": 0, "type": "mirror"}}
92
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}}
93
@@ -XXX,XX +XXX,XX @@ read 512/512 bytes at offset 0
94
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
95
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "src"}}
96
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}}
97
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "src"}}
98
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}}
99
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "src"}}
100
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "src", "len": 31457280, "offset": 31457280, "speed": 0, "type": "mirror"}}
101
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}}
102
@@ -XXX,XX +XXX,XX @@ read 512/512 bytes at offset 0
103
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
104
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "src"}}
105
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}}
106
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "src"}}
107
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}}
108
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "src"}}
109
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "src", "len": 327680, "offset": 327680, "speed": 0, "type": "mirror"}}
110
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}}
111
@@ -XXX,XX +XXX,XX @@ read 512/512 bytes at offset 0
112
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
113
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "src"}}
114
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}}
115
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "src"}}
116
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}}
117
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "src"}}
118
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "src", "len": 2048, "offset": 2048, "speed": 0, "type": "mirror"}}
119
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}}
120
@@ -XXX,XX +XXX,XX @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed
121
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
122
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "src"}}
123
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}}
124
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "src"}}
125
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}}
126
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "src"}}
127
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "src", "len": 512, "offset": 512, "speed": 0, "type": "mirror"}}
128
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}}
129
@@ -XXX,XX +XXX,XX @@ Images are identical.
130
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
131
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "src"}}
132
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}}
133
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "src"}}
134
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}}
135
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "src"}}
136
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "src", "len": 512, "offset": 512, "speed": 0, "type": "mirror"}}
137
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}}
138
diff --git a/tests/qemu-iotests/185 b/tests/qemu-iotests/185
139
index XXXXXXX..XXXXXXX 100755
140
--- a/tests/qemu-iotests/185
141
+++ b/tests/qemu-iotests/185
142
@@ -XXX,XX +XXX,XX @@ wait_for_job_and_quit() {
143
QEMU_EVENTS= # Ignore all JOB_STATUS_CHANGE events that came before SHUTDOWN
144
_wait_event $h 'JOB_STATUS_CHANGE' # standby
145
_wait_event $h 'JOB_STATUS_CHANGE' # ready
146
+ _wait_event $h 'JOB_STATUS_CHANGE' # standby
147
+ _wait_event $h 'JOB_STATUS_CHANGE' # ready
148
_wait_event $h 'JOB_STATUS_CHANGE' # aborting
149
# Filter the offset (depends on when exactly `quit` was issued)
150
_wait_event $h 'BLOCK_JOB_CANCELLED' \
151
diff --git a/tests/qemu-iotests/185.out b/tests/qemu-iotests/185.out
58
index XXXXXXX..XXXXXXX 100644
152
index XXXXXXX..XXXXXXX 100644
59
--- a/tests/qemu-iotests/274.out
153
--- a/tests/qemu-iotests/185.out
60
+++ b/tests/qemu-iotests/274.out
154
+++ b/tests/qemu-iotests/185.out
61
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 9437184
155
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
62
10 MiB (0xa00000) bytes allocated at offset 5 MiB (0x500000)
156
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
63
157
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "mirror"}}
64
[{ "start": 0, "length": 5242880, "depth": 1, "zero": true, "data": false},
158
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "mirror"}}
65
-{ "start": 5242880, "length": 10485760, "depth": 0, "zero": true, "data": false, "offset": 327680}]
159
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "mirror"}}
66
+{ "start": 5242880, "length": 10485760, "depth": 0, "zero": false, "data": true, "offset": 327680}]
160
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "mirror"}}
67
161
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "mirror"}}
68
=== preallocation=full ===
162
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "mirror", "len": 33554432, "offset": (filtered), "speed": 0, "type": "mirror"}}
69
Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=16777216 cluster_size=65536 lazy_refcounts=off refcount_bits=16
163
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "mirror"}}
70
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 11534336
164
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
71
4 MiB (0x400000) bytes allocated at offset 8 MiB (0x800000)
165
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
72
166
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "commit"}}
73
[{ "start": 0, "length": 8388608, "depth": 1, "zero": true, "data": false},
167
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "commit"}}
74
-{ "start": 8388608, "length": 4194304, "depth": 0, "zero": true, "data": false, "offset": 327680}]
168
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "commit"}}
75
+{ "start": 8388608, "length": 4194304, "depth": 0, "zero": false, "data": true, "offset": 327680}]
169
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "commit"}}
76
170
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "commit"}}
77
=== preallocation=off ===
171
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "commit", "len": 33554432, "offset": (filtered), "speed": 0, "type": "commit"}}
78
Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=393216 cluster_size=65536 lazy_refcounts=off refcount_bits=16
172
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "commit"}}
79
--
173
--
80
2.25.3
174
2.41.0
81
82
diff view generated by jsdifflib
1
When extending the size of an image that has a backing file larger than
1
From: Stefan Hajnoczi <stefanha@redhat.com>
2
its old size, make sure that the backing file data doesn't become
3
visible in the guest, but the added area is properly zeroed out.
4
2
5
Consider the following scenario where the overlay is shorter than its
3
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
6
backing file:
4
Message-ID: <20230808155852.2745350-2-stefanha@redhat.com>
7
5
Reviewed-by: Eric Blake <eblake@redhat.com>
8
base.qcow2: AAAAAAAA
6
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
overlay.qcow2: BBBB
10
11
When resizing (extending) overlay.qcow2, the new blocks should not stay
12
unallocated and make the additional As from base.qcow2 visible like
13
before this patch, but zeros should be read.
14
15
A similar case happens with the various variants of a commit job when an
16
intermediate file is short (- for unallocated):
17
18
base.qcow2: A-A-AAAA
19
mid.qcow2: BB-B
20
top.qcow2: C--C--C-
21
22
After commit top.qcow2 to mid.qcow2, the following happens:
23
24
mid.qcow2: CB-C00C0 (correct result)
25
mid.qcow2: CB-C--C- (before this fix)
26
27
Without the fix, blocks that previously read as zeros on top.qcow2
28
suddenly turn into A.
29
30
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
31
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
32
Message-Id: <20200424125448.63318-8-kwolf@redhat.com>
33
Reviewed-by: Max Reitz <mreitz@redhat.com>
34
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
35
---
8
---
36
block/io.c | 25 +++++++++++++++++++++++++
9
block/io.c | 8 +++++++-
37
1 file changed, 25 insertions(+)
10
1 file changed, 7 insertions(+), 1 deletion(-)
38
11
39
diff --git a/block/io.c b/block/io.c
12
diff --git a/block/io.c b/block/io.c
40
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
41
--- a/block/io.c
14
--- a/block/io.c
42
+++ b/block/io.c
15
+++ b/block/io.c
43
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
16
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn tracked_request_end(BdrvTrackedRequest *req)
44
goto out;
17
45
}
18
qemu_co_mutex_lock(&req->bs->reqs_lock);
46
19
QLIST_REMOVE(req, list);
20
- qemu_co_queue_restart_all(&req->wait_queue);
21
qemu_co_mutex_unlock(&req->bs->reqs_lock);
22
+
47
+ /*
23
+ /*
48
+ * If the image has a backing file that is large enough that it would
24
+ * At this point qemu_co_queue_wait(&req->wait_queue, ...) won't be called
49
+ * provide data for the new area, we cannot leave it unallocated because
25
+ * anymore because the request has been removed from the list, so it's safe
50
+ * then the backing file content would become visible. Instead, zero-fill
26
+ * to restart the queue outside reqs_lock to minimize the critical section.
51
+ * the new area.
52
+ *
53
+ * Note that if the image has a backing file, but was opened without the
54
+ * backing file, taking care of keeping things consistent with that backing
55
+ * file is the user's responsibility.
56
+ */
27
+ */
57
+ if (new_bytes && bs->backing) {
28
+ qemu_co_queue_restart_all(&req->wait_queue);
58
+ int64_t backing_len;
29
}
59
+
30
60
+ backing_len = bdrv_getlength(backing_bs(bs));
31
/**
61
+ if (backing_len < 0) {
62
+ ret = backing_len;
63
+ error_setg_errno(errp, -ret, "Could not get backing file size");
64
+ goto out;
65
+ }
66
+
67
+ if (backing_len > old_size) {
68
+ flags |= BDRV_REQ_ZERO_WRITE;
69
+ }
70
+ }
71
+
72
if (drv->bdrv_co_truncate) {
73
if (flags & ~bs->supported_truncate_flags) {
74
error_setg(errp, "Block driver does not support requested flags");
75
--
32
--
76
2.25.3
33
2.41.0
77
78
diff view generated by jsdifflib
1
From: Andrzej Jakowski <andrzej.jakowski@linux.intel.com>
1
From: Stefan Hajnoczi <stefanha@redhat.com>
2
2
3
This patch introduces support for PMR that has been defined as part of NVMe 1.4
3
CoMutex has poor performance when lock contention is high. The tracked
4
spec. User can now specify a pmrdev option that should point to HostMemoryBackend.
4
requests list is accessed frequently and performance suffers in QEMU
5
pmrdev memory region will subsequently be exposed as PCI BAR 2 in emulated NVMe
5
multi-queue block layer scenarios.
6
device. Guest OS can perform mmio read and writes to the PMR region that will stay
7
persistent across system reboot.
8
6
9
Signed-off-by: Andrzej Jakowski <andrzej.jakowski@linux.intel.com>
7
It is not necessary to use CoMutex for the requests lock. The lock is
10
Reviewed-by: Klaus Jensen <k.jensen@samsung.com>
8
always released across coroutine yield operations. It is held for
11
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
9
relatively short periods of time and it is not beneficial to yield when
12
Message-Id: <20200330164656.9348-1-andrzej.jakowski@linux.intel.com>
10
the lock is held by another coroutine.
13
Reviewed-by: Keith Busch <kbusch@kernel.org>
11
12
Change the lock type from CoMutex to QemuMutex to improve multi-queue
13
block layer performance. fio randread bs=4k iodepth=64 with 4 IOThreads
14
handling a virtio-blk device with 8 virtqueues improves from 254k to
15
517k IOPS (+203%). Full benchmark results and configuration details are
16
available here:
17
https://gitlab.com/stefanha/virt-playbooks/-/commit/980c40845d540e3669add1528739503c2e817b57
18
19
In the future we may wish to introduce thread-local tracked requests
20
lists to avoid lock contention completely. That would be much more
21
involved though.
22
23
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
24
Message-ID: <20230808155852.2745350-3-stefanha@redhat.com>
25
Reviewed-by: Eric Blake <eblake@redhat.com>
26
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
27
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
---
28
---
16
hw/block/nvme.h | 2 +
29
include/block/block_int-common.h | 2 +-
17
include/block/nvme.h | 172 +++++++++++++++++++++++++++++++++++++++++
30
block.c | 4 +++-
18
hw/block/nvme.c | 109 ++++++++++++++++++++++++++
31
block/io.c | 24 ++++++++++++------------
19
hw/block/Makefile.objs | 2 +-
32
3 files changed, 16 insertions(+), 14 deletions(-)
20
hw/block/trace-events | 4 +
21
5 files changed, 288 insertions(+), 1 deletion(-)
22
33
23
diff --git a/hw/block/nvme.h b/hw/block/nvme.h
34
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
24
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/block/nvme.h
36
--- a/include/block/block_int-common.h
26
+++ b/hw/block/nvme.h
37
+++ b/include/block/block_int-common.h
27
@@ -XXX,XX +XXX,XX @@ typedef struct NvmeCtrl {
38
@@ -XXX,XX +XXX,XX @@ struct BlockDriverState {
28
uint64_t timestamp_set_qemu_clock_ms; /* QEMU clock time */
39
unsigned int write_gen; /* Current data generation */
29
40
30
char *serial;
41
/* Protected by reqs_lock. */
31
+ HostMemoryBackend *pmrdev;
42
- CoMutex reqs_lock;
43
+ QemuMutex reqs_lock;
44
QLIST_HEAD(, BdrvTrackedRequest) tracked_requests;
45
CoQueue flush_queue; /* Serializing flush queue */
46
bool active_flush_req; /* Flush request in flight? */
47
diff --git a/block.c b/block.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/block.c
50
+++ b/block.c
51
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_new(void)
52
for (i = 0; i < BLOCK_OP_TYPE_MAX; i++) {
53
QLIST_INIT(&bs->op_blockers[i]);
54
}
55
- qemu_co_mutex_init(&bs->reqs_lock);
56
+ qemu_mutex_init(&bs->reqs_lock);
57
qemu_mutex_init(&bs->dirty_bitmap_mutex);
58
bs->refcnt = 1;
59
bs->aio_context = qemu_get_aio_context();
60
@@ -XXX,XX +XXX,XX @@ static void bdrv_delete(BlockDriverState *bs)
61
62
bdrv_close(bs);
63
64
+ qemu_mutex_destroy(&bs->reqs_lock);
32
+
65
+
33
NvmeNamespace *namespaces;
66
g_free(bs);
34
NvmeSQueue **sq;
67
}
35
NvmeCQueue **cq;
68
36
diff --git a/include/block/nvme.h b/include/block/nvme.h
69
diff --git a/block/io.c b/block/io.c
37
index XXXXXXX..XXXXXXX 100644
70
index XXXXXXX..XXXXXXX 100644
38
--- a/include/block/nvme.h
71
--- a/block/io.c
39
+++ b/include/block/nvme.h
72
+++ b/block/io.c
40
@@ -XXX,XX +XXX,XX @@ typedef struct NvmeBar {
73
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn tracked_request_end(BdrvTrackedRequest *req)
41
uint64_t acq;
74
qatomic_dec(&req->bs->serialising_in_flight);
42
uint32_t cmbloc;
43
uint32_t cmbsz;
44
+ uint8_t padding[3520]; /* not used by QEMU */
45
+ uint32_t pmrcap;
46
+ uint32_t pmrctl;
47
+ uint32_t pmrsts;
48
+ uint32_t pmrebs;
49
+ uint32_t pmrswtp;
50
+ uint32_t pmrmsc;
51
} NvmeBar;
52
53
enum NvmeCapShift {
54
@@ -XXX,XX +XXX,XX @@ enum NvmeCapShift {
55
CAP_CSS_SHIFT = 37,
56
CAP_MPSMIN_SHIFT = 48,
57
CAP_MPSMAX_SHIFT = 52,
58
+ CAP_PMR_SHIFT = 56,
59
};
60
61
enum NvmeCapMask {
62
@@ -XXX,XX +XXX,XX @@ enum NvmeCapMask {
63
CAP_CSS_MASK = 0xff,
64
CAP_MPSMIN_MASK = 0xf,
65
CAP_MPSMAX_MASK = 0xf,
66
+ CAP_PMR_MASK = 0x1,
67
};
68
69
#define NVME_CAP_MQES(cap) (((cap) >> CAP_MQES_SHIFT) & CAP_MQES_MASK)
70
@@ -XXX,XX +XXX,XX @@ enum NvmeCapMask {
71
<< CAP_MPSMIN_SHIFT)
72
#define NVME_CAP_SET_MPSMAX(cap, val) (cap |= (uint64_t)(val & CAP_MPSMAX_MASK)\
73
<< CAP_MPSMAX_SHIFT)
74
+#define NVME_CAP_SET_PMRS(cap, val) (cap |= (uint64_t)(val & CAP_PMR_MASK)\
75
+ << CAP_PMR_SHIFT)
76
77
enum NvmeCcShift {
78
CC_EN_SHIFT = 0,
79
@@ -XXX,XX +XXX,XX @@ enum NvmeCmbszMask {
80
#define NVME_CMBSZ_GETSIZE(cmbsz) \
81
(NVME_CMBSZ_SZ(cmbsz) * (1 << (12 + 4 * NVME_CMBSZ_SZU(cmbsz))))
82
83
+enum NvmePmrcapShift {
84
+ PMRCAP_RDS_SHIFT = 3,
85
+ PMRCAP_WDS_SHIFT = 4,
86
+ PMRCAP_BIR_SHIFT = 5,
87
+ PMRCAP_PMRTU_SHIFT = 8,
88
+ PMRCAP_PMRWBM_SHIFT = 10,
89
+ PMRCAP_PMRTO_SHIFT = 16,
90
+ PMRCAP_CMSS_SHIFT = 24,
91
+};
92
+
93
+enum NvmePmrcapMask {
94
+ PMRCAP_RDS_MASK = 0x1,
95
+ PMRCAP_WDS_MASK = 0x1,
96
+ PMRCAP_BIR_MASK = 0x7,
97
+ PMRCAP_PMRTU_MASK = 0x3,
98
+ PMRCAP_PMRWBM_MASK = 0xf,
99
+ PMRCAP_PMRTO_MASK = 0xff,
100
+ PMRCAP_CMSS_MASK = 0x1,
101
+};
102
+
103
+#define NVME_PMRCAP_RDS(pmrcap) \
104
+ ((pmrcap >> PMRCAP_RDS_SHIFT) & PMRCAP_RDS_MASK)
105
+#define NVME_PMRCAP_WDS(pmrcap) \
106
+ ((pmrcap >> PMRCAP_WDS_SHIFT) & PMRCAP_WDS_MASK)
107
+#define NVME_PMRCAP_BIR(pmrcap) \
108
+ ((pmrcap >> PMRCAP_BIR_SHIFT) & PMRCAP_BIR_MASK)
109
+#define NVME_PMRCAP_PMRTU(pmrcap) \
110
+ ((pmrcap >> PMRCAP_PMRTU_SHIFT) & PMRCAP_PMRTU_MASK)
111
+#define NVME_PMRCAP_PMRWBM(pmrcap) \
112
+ ((pmrcap >> PMRCAP_PMRWBM_SHIFT) & PMRCAP_PMRWBM_MASK)
113
+#define NVME_PMRCAP_PMRTO(pmrcap) \
114
+ ((pmrcap >> PMRCAP_PMRTO_SHIFT) & PMRCAP_PMRTO_MASK)
115
+#define NVME_PMRCAP_CMSS(pmrcap) \
116
+ ((pmrcap >> PMRCAP_CMSS_SHIFT) & PMRCAP_CMSS_MASK)
117
+
118
+#define NVME_PMRCAP_SET_RDS(pmrcap, val) \
119
+ (pmrcap |= (uint64_t)(val & PMRCAP_RDS_MASK) << PMRCAP_RDS_SHIFT)
120
+#define NVME_PMRCAP_SET_WDS(pmrcap, val) \
121
+ (pmrcap |= (uint64_t)(val & PMRCAP_WDS_MASK) << PMRCAP_WDS_SHIFT)
122
+#define NVME_PMRCAP_SET_BIR(pmrcap, val) \
123
+ (pmrcap |= (uint64_t)(val & PMRCAP_BIR_MASK) << PMRCAP_BIR_SHIFT)
124
+#define NVME_PMRCAP_SET_PMRTU(pmrcap, val) \
125
+ (pmrcap |= (uint64_t)(val & PMRCAP_PMRTU_MASK) << PMRCAP_PMRTU_SHIFT)
126
+#define NVME_PMRCAP_SET_PMRWBM(pmrcap, val) \
127
+ (pmrcap |= (uint64_t)(val & PMRCAP_PMRWBM_MASK) << PMRCAP_PMRWBM_SHIFT)
128
+#define NVME_PMRCAP_SET_PMRTO(pmrcap, val) \
129
+ (pmrcap |= (uint64_t)(val & PMRCAP_PMRTO_MASK) << PMRCAP_PMRTO_SHIFT)
130
+#define NVME_PMRCAP_SET_CMSS(pmrcap, val) \
131
+ (pmrcap |= (uint64_t)(val & PMRCAP_CMSS_MASK) << PMRCAP_CMSS_SHIFT)
132
+
133
+enum NvmePmrctlShift {
134
+ PMRCTL_EN_SHIFT = 0,
135
+};
136
+
137
+enum NvmePmrctlMask {
138
+ PMRCTL_EN_MASK = 0x1,
139
+};
140
+
141
+#define NVME_PMRCTL_EN(pmrctl) ((pmrctl >> PMRCTL_EN_SHIFT) & PMRCTL_EN_MASK)
142
+
143
+#define NVME_PMRCTL_SET_EN(pmrctl, val) \
144
+ (pmrctl |= (uint64_t)(val & PMRCTL_EN_MASK) << PMRCTL_EN_SHIFT)
145
+
146
+enum NvmePmrstsShift {
147
+ PMRSTS_ERR_SHIFT = 0,
148
+ PMRSTS_NRDY_SHIFT = 8,
149
+ PMRSTS_HSTS_SHIFT = 9,
150
+ PMRSTS_CBAI_SHIFT = 12,
151
+};
152
+
153
+enum NvmePmrstsMask {
154
+ PMRSTS_ERR_MASK = 0xff,
155
+ PMRSTS_NRDY_MASK = 0x1,
156
+ PMRSTS_HSTS_MASK = 0x7,
157
+ PMRSTS_CBAI_MASK = 0x1,
158
+};
159
+
160
+#define NVME_PMRSTS_ERR(pmrsts) \
161
+ ((pmrsts >> PMRSTS_ERR_SHIFT) & PMRSTS_ERR_MASK)
162
+#define NVME_PMRSTS_NRDY(pmrsts) \
163
+ ((pmrsts >> PMRSTS_NRDY_SHIFT) & PMRSTS_NRDY_MASK)
164
+#define NVME_PMRSTS_HSTS(pmrsts) \
165
+ ((pmrsts >> PMRSTS_HSTS_SHIFT) & PMRSTS_HSTS_MASK)
166
+#define NVME_PMRSTS_CBAI(pmrsts) \
167
+ ((pmrsts >> PMRSTS_CBAI_SHIFT) & PMRSTS_CBAI_MASK)
168
+
169
+#define NVME_PMRSTS_SET_ERR(pmrsts, val) \
170
+ (pmrsts |= (uint64_t)(val & PMRSTS_ERR_MASK) << PMRSTS_ERR_SHIFT)
171
+#define NVME_PMRSTS_SET_NRDY(pmrsts, val) \
172
+ (pmrsts |= (uint64_t)(val & PMRSTS_NRDY_MASK) << PMRSTS_NRDY_SHIFT)
173
+#define NVME_PMRSTS_SET_HSTS(pmrsts, val) \
174
+ (pmrsts |= (uint64_t)(val & PMRSTS_HSTS_MASK) << PMRSTS_HSTS_SHIFT)
175
+#define NVME_PMRSTS_SET_CBAI(pmrsts, val) \
176
+ (pmrsts |= (uint64_t)(val & PMRSTS_CBAI_MASK) << PMRSTS_CBAI_SHIFT)
177
+
178
+enum NvmePmrebsShift {
179
+ PMREBS_PMRSZU_SHIFT = 0,
180
+ PMREBS_RBB_SHIFT = 4,
181
+ PMREBS_PMRWBZ_SHIFT = 8,
182
+};
183
+
184
+enum NvmePmrebsMask {
185
+ PMREBS_PMRSZU_MASK = 0xf,
186
+ PMREBS_RBB_MASK = 0x1,
187
+ PMREBS_PMRWBZ_MASK = 0xffffff,
188
+};
189
+
190
+#define NVME_PMREBS_PMRSZU(pmrebs) \
191
+ ((pmrebs >> PMREBS_PMRSZU_SHIFT) & PMREBS_PMRSZU_MASK)
192
+#define NVME_PMREBS_RBB(pmrebs) \
193
+ ((pmrebs >> PMREBS_RBB_SHIFT) & PMREBS_RBB_MASK)
194
+#define NVME_PMREBS_PMRWBZ(pmrebs) \
195
+ ((pmrebs >> PMREBS_PMRWBZ_SHIFT) & PMREBS_PMRWBZ_MASK)
196
+
197
+#define NVME_PMREBS_SET_PMRSZU(pmrebs, val) \
198
+ (pmrebs |= (uint64_t)(val & PMREBS_PMRSZU_MASK) << PMREBS_PMRSZU_SHIFT)
199
+#define NVME_PMREBS_SET_RBB(pmrebs, val) \
200
+ (pmrebs |= (uint64_t)(val & PMREBS_RBB_MASK) << PMREBS_RBB_SHIFT)
201
+#define NVME_PMREBS_SET_PMRWBZ(pmrebs, val) \
202
+ (pmrebs |= (uint64_t)(val & PMREBS_PMRWBZ_MASK) << PMREBS_PMRWBZ_SHIFT)
203
+
204
+enum NvmePmrswtpShift {
205
+ PMRSWTP_PMRSWTU_SHIFT = 0,
206
+ PMRSWTP_PMRSWTV_SHIFT = 8,
207
+};
208
+
209
+enum NvmePmrswtpMask {
210
+ PMRSWTP_PMRSWTU_MASK = 0xf,
211
+ PMRSWTP_PMRSWTV_MASK = 0xffffff,
212
+};
213
+
214
+#define NVME_PMRSWTP_PMRSWTU(pmrswtp) \
215
+ ((pmrswtp >> PMRSWTP_PMRSWTU_SHIFT) & PMRSWTP_PMRSWTU_MASK)
216
+#define NVME_PMRSWTP_PMRSWTV(pmrswtp) \
217
+ ((pmrswtp >> PMRSWTP_PMRSWTV_SHIFT) & PMRSWTP_PMRSWTV_MASK)
218
+
219
+#define NVME_PMRSWTP_SET_PMRSWTU(pmrswtp, val) \
220
+ (pmrswtp |= (uint64_t)(val & PMRSWTP_PMRSWTU_MASK) << PMRSWTP_PMRSWTU_SHIFT)
221
+#define NVME_PMRSWTP_SET_PMRSWTV(pmrswtp, val) \
222
+ (pmrswtp |= (uint64_t)(val & PMRSWTP_PMRSWTV_MASK) << PMRSWTP_PMRSWTV_SHIFT)
223
+
224
+enum NvmePmrmscShift {
225
+ PMRMSC_CMSE_SHIFT = 1,
226
+ PMRMSC_CBA_SHIFT = 12,
227
+};
228
+
229
+enum NvmePmrmscMask {
230
+ PMRMSC_CMSE_MASK = 0x1,
231
+ PMRMSC_CBA_MASK = 0xfffffffffffff,
232
+};
233
+
234
+#define NVME_PMRMSC_CMSE(pmrmsc) \
235
+ ((pmrmsc >> PMRMSC_CMSE_SHIFT) & PMRMSC_CMSE_MASK)
236
+#define NVME_PMRMSC_CBA(pmrmsc) \
237
+ ((pmrmsc >> PMRMSC_CBA_SHIFT) & PMRMSC_CBA_MASK)
238
+
239
+#define NVME_PMRMSC_SET_CMSE(pmrmsc, val) \
240
+ (pmrmsc |= (uint64_t)(val & PMRMSC_CMSE_MASK) << PMRMSC_CMSE_SHIFT)
241
+#define NVME_PMRMSC_SET_CBA(pmrmsc, val) \
242
+ (pmrmsc |= (uint64_t)(val & PMRMSC_CBA_MASK) << PMRMSC_CBA_SHIFT)
243
+
244
typedef struct NvmeCmd {
245
uint8_t opcode;
246
uint8_t fuse;
247
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
248
index XXXXXXX..XXXXXXX 100644
249
--- a/hw/block/nvme.c
250
+++ b/hw/block/nvme.c
251
@@ -XXX,XX +XXX,XX @@
252
* -drive file=<file>,if=none,id=<drive_id>
253
* -device nvme,drive=<drive_id>,serial=<serial>,id=<id[optional]>, \
254
* cmb_size_mb=<cmb_size_mb[optional]>, \
255
+ * [pmrdev=<mem_backend_file_id>,] \
256
* num_queues=<N[optional]>
257
*
258
* Note cmb_size_mb denotes size of CMB in MB. CMB is assumed to be at
259
* offset 0 in BAR2 and supports only WDS, RDS and SQS for now.
260
+ *
261
+ * cmb_size_mb= and pmrdev= options are mutually exclusive due to limitation
262
+ * in available BAR's. cmb_size_mb= will take precedence over pmrdev= when
263
+ * both provided.
264
+ * Enabling pmr emulation can be achieved by pointing to memory-backend-file.
265
+ * For example:
266
+ * -object memory-backend-file,id=<mem_id>,share=on,mem-path=<file_path>, \
267
+ * size=<size> .... -device nvme,...,pmrdev=<mem_id>
268
*/
269
270
#include "qemu/osdep.h"
271
@@ -XXX,XX +XXX,XX @@
272
#include "sysemu/sysemu.h"
273
#include "qapi/error.h"
274
#include "qapi/visitor.h"
275
+#include "sysemu/hostmem.h"
276
#include "sysemu/block-backend.h"
277
+#include "exec/ram_addr.h"
278
279
#include "qemu/log.h"
280
#include "qemu/module.h"
281
@@ -XXX,XX +XXX,XX @@ static void nvme_write_bar(NvmeCtrl *n, hwaddr offset, uint64_t data,
282
NVME_GUEST_ERR(nvme_ub_mmiowr_cmbsz_readonly,
283
"invalid write to read only CMBSZ, ignored");
284
return;
285
+ case 0xE00: /* PMRCAP */
286
+ NVME_GUEST_ERR(nvme_ub_mmiowr_pmrcap_readonly,
287
+ "invalid write to PMRCAP register, ignored");
288
+ return;
289
+ case 0xE04: /* TODO PMRCTL */
290
+ break;
291
+ case 0xE08: /* PMRSTS */
292
+ NVME_GUEST_ERR(nvme_ub_mmiowr_pmrsts_readonly,
293
+ "invalid write to PMRSTS register, ignored");
294
+ return;
295
+ case 0xE0C: /* PMREBS */
296
+ NVME_GUEST_ERR(nvme_ub_mmiowr_pmrebs_readonly,
297
+ "invalid write to PMREBS register, ignored");
298
+ return;
299
+ case 0xE10: /* PMRSWTP */
300
+ NVME_GUEST_ERR(nvme_ub_mmiowr_pmrswtp_readonly,
301
+ "invalid write to PMRSWTP register, ignored");
302
+ return;
303
+ case 0xE14: /* TODO PMRMSC */
304
+ break;
305
default:
306
NVME_GUEST_ERR(nvme_ub_mmiowr_invalid,
307
"invalid MMIO write,"
308
@@ -XXX,XX +XXX,XX @@ static uint64_t nvme_mmio_read(void *opaque, hwaddr addr, unsigned size)
309
}
75
}
310
76
311
if (addr < sizeof(n->bar)) {
77
- qemu_co_mutex_lock(&req->bs->reqs_lock);
312
+ /*
78
+ qemu_mutex_lock(&req->bs->reqs_lock);
313
+ * When PMRWBM bit 1 is set then read from
79
QLIST_REMOVE(req, list);
314
+ * from PMRSTS should ensure prior writes
80
- qemu_co_mutex_unlock(&req->bs->reqs_lock);
315
+ * made it to persistent media
81
+ qemu_mutex_unlock(&req->bs->reqs_lock);
316
+ */
82
317
+ if (addr == 0xE08 &&
83
/*
318
+ (NVME_PMRCAP_PMRWBM(n->bar.pmrcap) & 0x02)) {
84
* At this point qemu_co_queue_wait(&req->wait_queue, ...) won't be called
319
+ qemu_ram_writeback(n->pmrdev->mr.ram_block,
85
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn tracked_request_begin(BdrvTrackedRequest *req,
320
+ 0, n->pmrdev->size);
86
321
+ }
87
qemu_co_queue_init(&req->wait_queue);
322
memcpy(&val, ptr + addr, size);
88
323
} else {
89
- qemu_co_mutex_lock(&bs->reqs_lock);
324
NVME_GUEST_ERR(nvme_ub_mmiord_invalid_ofs,
90
+ qemu_mutex_lock(&bs->reqs_lock);
325
@@ -XXX,XX +XXX,XX @@ static void nvme_realize(PCIDevice *pci_dev, Error **errp)
91
QLIST_INSERT_HEAD(&bs->tracked_requests, req, list);
326
error_setg(errp, "serial property not set");
92
- qemu_co_mutex_unlock(&bs->reqs_lock);
93
+ qemu_mutex_unlock(&bs->reqs_lock);
94
}
95
96
static bool tracked_request_overlaps(BdrvTrackedRequest *req,
97
@@ -XXX,XX +XXX,XX @@ bdrv_wait_serialising_requests(BdrvTrackedRequest *self)
327
return;
98
return;
328
}
99
}
329
+
100
330
+ if (!n->cmb_size_mb && n->pmrdev) {
101
- qemu_co_mutex_lock(&bs->reqs_lock);
331
+ if (host_memory_backend_is_mapped(n->pmrdev)) {
102
+ qemu_mutex_lock(&bs->reqs_lock);
332
+ char *path = object_get_canonical_path_component(OBJECT(n->pmrdev));
103
bdrv_wait_serialising_requests_locked(self);
333
+ error_setg(errp, "can't use already busy memdev: %s", path);
104
- qemu_co_mutex_unlock(&bs->reqs_lock);
334
+ g_free(path);
105
+ qemu_mutex_unlock(&bs->reqs_lock);
335
+ return;
106
}
336
+ }
107
337
+
108
void coroutine_fn bdrv_make_request_serialising(BdrvTrackedRequest *req,
338
+ if (!is_power_of_2(n->pmrdev->size)) {
109
@@ -XXX,XX +XXX,XX @@ void coroutine_fn bdrv_make_request_serialising(BdrvTrackedRequest *req,
339
+ error_setg(errp, "pmr backend size needs to be power of 2 in size");
110
{
340
+ return;
111
IO_CODE();
341
+ }
112
342
+
113
- qemu_co_mutex_lock(&req->bs->reqs_lock);
343
+ host_memory_backend_set_mapped(n->pmrdev, true);
114
+ qemu_mutex_lock(&req->bs->reqs_lock);
344
+ }
115
345
+
116
tracked_request_set_serialising(req, align);
346
blkconf_blocksizes(&n->conf);
117
bdrv_wait_serialising_requests_locked(req);
347
if (!blkconf_apply_backend_options(&n->conf, blk_is_read_only(n->conf.blk),
118
348
false, errp)) {
119
- qemu_co_mutex_unlock(&req->bs->reqs_lock);
349
@@ -XXX,XX +XXX,XX @@ static void nvme_realize(PCIDevice *pci_dev, Error **errp)
120
+ qemu_mutex_unlock(&req->bs->reqs_lock);
350
PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64 |
121
}
351
PCI_BASE_ADDRESS_MEM_PREFETCH, &n->ctrl_mem);
122
352
123
int bdrv_check_qiov_request(int64_t offset, int64_t bytes,
353
+ } else if (n->pmrdev) {
124
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
354
+ /* Controller Capabilities register */
125
goto early_exit;
355
+ NVME_CAP_SET_PMRS(n->bar.cap, 1);
356
+
357
+ /* PMR Capabities register */
358
+ n->bar.pmrcap = 0;
359
+ NVME_PMRCAP_SET_RDS(n->bar.pmrcap, 0);
360
+ NVME_PMRCAP_SET_WDS(n->bar.pmrcap, 0);
361
+ NVME_PMRCAP_SET_BIR(n->bar.pmrcap, 2);
362
+ NVME_PMRCAP_SET_PMRTU(n->bar.pmrcap, 0);
363
+ /* Turn on bit 1 support */
364
+ NVME_PMRCAP_SET_PMRWBM(n->bar.pmrcap, 0x02);
365
+ NVME_PMRCAP_SET_PMRTO(n->bar.pmrcap, 0);
366
+ NVME_PMRCAP_SET_CMSS(n->bar.pmrcap, 0);
367
+
368
+ /* PMR Control register */
369
+ n->bar.pmrctl = 0;
370
+ NVME_PMRCTL_SET_EN(n->bar.pmrctl, 0);
371
+
372
+ /* PMR Status register */
373
+ n->bar.pmrsts = 0;
374
+ NVME_PMRSTS_SET_ERR(n->bar.pmrsts, 0);
375
+ NVME_PMRSTS_SET_NRDY(n->bar.pmrsts, 0);
376
+ NVME_PMRSTS_SET_HSTS(n->bar.pmrsts, 0);
377
+ NVME_PMRSTS_SET_CBAI(n->bar.pmrsts, 0);
378
+
379
+ /* PMR Elasticity Buffer Size register */
380
+ n->bar.pmrebs = 0;
381
+ NVME_PMREBS_SET_PMRSZU(n->bar.pmrebs, 0);
382
+ NVME_PMREBS_SET_RBB(n->bar.pmrebs, 0);
383
+ NVME_PMREBS_SET_PMRWBZ(n->bar.pmrebs, 0);
384
+
385
+ /* PMR Sustained Write Throughput register */
386
+ n->bar.pmrswtp = 0;
387
+ NVME_PMRSWTP_SET_PMRSWTU(n->bar.pmrswtp, 0);
388
+ NVME_PMRSWTP_SET_PMRSWTV(n->bar.pmrswtp, 0);
389
+
390
+ /* PMR Memory Space Control register */
391
+ n->bar.pmrmsc = 0;
392
+ NVME_PMRMSC_SET_CMSE(n->bar.pmrmsc, 0);
393
+ NVME_PMRMSC_SET_CBA(n->bar.pmrmsc, 0);
394
+
395
+ pci_register_bar(pci_dev, NVME_PMRCAP_BIR(n->bar.pmrcap),
396
+ PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64 |
397
+ PCI_BASE_ADDRESS_MEM_PREFETCH, &n->pmrdev->mr);
398
}
126
}
399
127
400
for (i = 0; i < n->num_namespaces; i++) {
128
- qemu_co_mutex_lock(&bs->reqs_lock);
401
@@ -XXX,XX +XXX,XX @@ static void nvme_exit(PCIDevice *pci_dev)
129
+ qemu_mutex_lock(&bs->reqs_lock);
402
if (n->cmb_size_mb) {
130
current_gen = qatomic_read(&bs->write_gen);
403
g_free(n->cmbuf);
131
132
/* Wait until any previous flushes are completed */
133
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
134
135
/* Flushes reach this point in nondecreasing current_gen order. */
136
bs->active_flush_req = true;
137
- qemu_co_mutex_unlock(&bs->reqs_lock);
138
+ qemu_mutex_unlock(&bs->reqs_lock);
139
140
/* Write back all layers by calling one driver function */
141
if (bs->drv->bdrv_co_flush) {
142
@@ -XXX,XX +XXX,XX @@ out:
143
bs->flushed_gen = current_gen;
404
}
144
}
405
+
145
406
+ if (n->pmrdev) {
146
- qemu_co_mutex_lock(&bs->reqs_lock);
407
+ host_memory_backend_set_mapped(n->pmrdev, false);
147
+ qemu_mutex_lock(&bs->reqs_lock);
408
+ }
148
bs->active_flush_req = false;
409
msix_uninit_exclusive_bar(pci_dev);
149
/* Return value is ignored - it's ok if wait queue is empty */
410
}
150
qemu_co_queue_next(&bs->flush_queue);
411
151
- qemu_co_mutex_unlock(&bs->reqs_lock);
412
static Property nvme_props[] = {
152
+ qemu_mutex_unlock(&bs->reqs_lock);
413
DEFINE_BLOCK_PROPERTIES(NvmeCtrl, conf),
153
414
+ DEFINE_PROP_LINK("pmrdev", NvmeCtrl, pmrdev, TYPE_MEMORY_BACKEND,
154
early_exit:
415
+ HostMemoryBackend *),
155
bdrv_dec_in_flight(bs);
416
DEFINE_PROP_STRING("serial", NvmeCtrl, serial),
417
DEFINE_PROP_UINT32("cmb_size_mb", NvmeCtrl, cmb_size_mb, 0),
418
DEFINE_PROP_UINT32("num_queues", NvmeCtrl, num_queues, 64),
419
diff --git a/hw/block/Makefile.objs b/hw/block/Makefile.objs
420
index XXXXXXX..XXXXXXX 100644
421
--- a/hw/block/Makefile.objs
422
+++ b/hw/block/Makefile.objs
423
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_PFLASH_CFI02) += pflash_cfi02.o
424
common-obj-$(CONFIG_XEN) += xen-block.o
425
common-obj-$(CONFIG_ECC) += ecc.o
426
common-obj-$(CONFIG_ONENAND) += onenand.o
427
-common-obj-$(CONFIG_NVME_PCI) += nvme.o
428
common-obj-$(CONFIG_SWIM) += swim.o
429
430
common-obj-$(CONFIG_SH4) += tc58128.o
431
432
obj-$(CONFIG_VIRTIO_BLK) += virtio-blk.o
433
obj-$(CONFIG_VHOST_USER_BLK) += vhost-user-blk.o
434
+obj-$(CONFIG_NVME_PCI) += nvme.o
435
436
obj-y += dataplane/
437
diff --git a/hw/block/trace-events b/hw/block/trace-events
438
index XXXXXXX..XXXXXXX 100644
439
--- a/hw/block/trace-events
440
+++ b/hw/block/trace-events
441
@@ -XXX,XX +XXX,XX @@ nvme_ub_mmiowr_ssreset_w1c_unsupported(void) "attempted to W1C CSTS.NSSRO but CA
442
nvme_ub_mmiowr_ssreset_unsupported(void) "attempted NVM subsystem reset but CAP.NSSRS is zero (not supported)"
443
nvme_ub_mmiowr_cmbloc_reserved(void) "invalid write to reserved CMBLOC when CMBSZ is zero, ignored"
444
nvme_ub_mmiowr_cmbsz_readonly(void) "invalid write to read only CMBSZ, ignored"
445
+nvme_ub_mmiowr_pmrcap_readonly(void) "invalid write to read only PMRCAP, ignored"
446
+nvme_ub_mmiowr_pmrsts_readonly(void) "invalid write to read only PMRSTS, ignored"
447
+nvme_ub_mmiowr_pmrebs_readonly(void) "invalid write to read only PMREBS, ignored"
448
+nvme_ub_mmiowr_pmrswtp_readonly(void) "invalid write to read only PMRSWTP, ignored"
449
nvme_ub_mmiowr_invalid(uint64_t offset, uint64_t data) "invalid MMIO write, offset=0x%"PRIx64", data=0x%"PRIx64""
450
nvme_ub_mmiord_misaligned32(uint64_t offset) "MMIO read not 32-bit aligned, offset=0x%"PRIx64""
451
nvme_ub_mmiord_toosmall(uint64_t offset) "MMIO read smaller than 32-bits, offset=0x%"PRIx64""
452
--
156
--
453
2.25.3
157
2.41.0
454
455
diff view generated by jsdifflib
1
From: Paolo Bonzini <pbonzini@redhat.com>
1
From: Michael Tokarev <mjt@tls.msk.ru>
2
2
3
Test 244 checks the expected behavior of qcow2 external data files
3
I'm getting io-qcow2-244 test failure on mips*
4
with respect to zero and discarded clusters. Filesystems however
4
due to output mismatch:
5
are free to ignore discard requests, and this seems to be the
6
case for overlayfs. Relax the tests to skip checks on the
7
external data file for discarded areas, which implies not using
8
qemu-img compare in the data_file_raw=on case.
9
5
10
This fixes docker tests on RHEL8.
6
Take an internal snapshot:
7
-qemu-img: Could not create snapshot 'test': -95 (Operation not supported)
8
+qemu-img: Could not create snapshot 'test': -122 (Operation not supported)
9
No errors were found on the image.
11
10
12
Cc: Kevin Wolf <kwolf@redhat.com>
11
This is because errno values might be different across
13
Cc: qemu-block@nongnu.org
12
different architectures.
14
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
13
15
Message-Id: <20200409191006.24429-1-pbonzini@redhat.com>
14
This error message in qemu-img.c is the only one which
15
prints errno directly, all the rest print strerror(errno)
16
only. Fix this error message and the expected output
17
of the 3 test cases too.
18
19
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
20
Message-ID: <20230811110946.2435067-1-mjt@tls.msk.ru>
21
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
22
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
---
23
---
18
tests/qemu-iotests/244 | 10 ++++++++--
24
qemu-img.c | 4 ++--
19
tests/qemu-iotests/244.out | 9 ++++++---
25
tests/qemu-iotests/080.out | 6 +++---
20
2 files changed, 14 insertions(+), 5 deletions(-)
26
tests/qemu-iotests/112.out | 6 +++---
27
tests/qemu-iotests/244.out | 2 +-
28
4 files changed, 9 insertions(+), 9 deletions(-)
21
29
22
diff --git a/tests/qemu-iotests/244 b/tests/qemu-iotests/244
30
diff --git a/qemu-img.c b/qemu-img.c
23
index XXXXXXX..XXXXXXX 100755
31
index XXXXXXX..XXXXXXX 100644
24
--- a/tests/qemu-iotests/244
32
--- a/qemu-img.c
25
+++ b/tests/qemu-iotests/244
33
+++ b/qemu-img.c
26
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c 'read -P 0 0 1M' \
34
@@ -XXX,XX +XXX,XX @@ static int img_snapshot(int argc, char **argv)
27
echo
35
28
$QEMU_IO -c 'read -P 0 0 1M' \
36
ret = bdrv_snapshot_create(bs, &sn);
29
-c 'read -P 0x11 1M 1M' \
37
if (ret) {
30
- -c 'read -P 0 2M 2M' \
38
- error_report("Could not create snapshot '%s': %d (%s)",
31
-c 'read -P 0x11 4M 1M' \
39
- snapshot_name, ret, strerror(-ret));
32
-c 'read -P 0 5M 1M' \
40
+ error_report("Could not create snapshot '%s': %s",
33
-f raw "$TEST_IMG.data" |
41
+ snapshot_name, strerror(-ret));
34
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c 'read -P 0 0 1M' \
42
}
35
-f $IMGFMT "$TEST_IMG" |
43
break;
36
_filter_qemu_io
44
37
45
diff --git a/tests/qemu-iotests/080.out b/tests/qemu-iotests/080.out
38
+# Discarded clusters are only marked as such in the qcow2 metadata, but
46
index XXXXXXX..XXXXXXX 100644
39
+# they can contain stale data in the external data file. Instead, zero
47
--- a/tests/qemu-iotests/080.out
40
+# clusters must be zeroed in the external data file too.
48
+++ b/tests/qemu-iotests/080.out
41
echo
49
@@ -XXX,XX +XXX,XX @@ qemu-io: can't open device TEST_DIR/t.qcow2: Snapshot table offset invalid
42
-$QEMU_IMG compare "$TEST_IMG" "$TEST_IMG.data"
50
43
+$QEMU_IO -c 'read -P 0 0 1M' \
51
== Hitting snapshot table size limit ==
44
+ -c 'read -P 0x11 1M 1M' \
52
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
45
+ -c 'read -P 0 3M 3M' \
53
-qemu-img: Could not create snapshot 'test': -27 (File too large)
46
+ -f raw "$TEST_IMG".data |
54
+qemu-img: Could not create snapshot 'test': File too large
47
+ _filter_qemu_io
55
read 512/512 bytes at offset 0
48
56
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
49
echo -n "qcow2 file size after I/O: "
57
50
du -b $TEST_IMG | cut -f1
58
@@ -XXX,XX +XXX,XX @@ qemu-io: can't open device TEST_DIR/t.qcow2: Backing file name too long
59
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
60
wrote 512/512 bytes at offset 0
61
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
62
-qemu-img: Could not create snapshot 'test': -27 (File too large)
63
-qemu-img: Could not create snapshot 'test': -11 (Resource temporarily unavailable)
64
+qemu-img: Could not create snapshot 'test': File too large
65
+qemu-img: Could not create snapshot 'test': Resource temporarily unavailable
66
67
== Invalid snapshot L1 table offset ==
68
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
69
diff --git a/tests/qemu-iotests/112.out b/tests/qemu-iotests/112.out
70
index XXXXXXX..XXXXXXX 100644
71
--- a/tests/qemu-iotests/112.out
72
+++ b/tests/qemu-iotests/112.out
73
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
74
refcount bits: 1
75
wrote 512/512 bytes at offset 0
76
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
77
-qemu-img: Could not create snapshot 'foo': -22 (Invalid argument)
78
+qemu-img: Could not create snapshot 'foo': Invalid argument
79
Leaked cluster 6 refcount=1 reference=0
80
81
1 leaked clusters were found on the image.
82
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
83
refcount bits: 2
84
wrote 512/512 bytes at offset 0
85
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
86
-qemu-img: Could not create snapshot 'baz': -22 (Invalid argument)
87
+qemu-img: Could not create snapshot 'baz': Invalid argument
88
Leaked cluster 7 refcount=1 reference=0
89
90
1 leaked clusters were found on the image.
91
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
92
refcount bits: 64
93
wrote 512/512 bytes at offset 0
94
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
95
-qemu-img: Could not create snapshot 'foo': -22 (Invalid argument)
96
+qemu-img: Could not create snapshot 'foo': Invalid argument
97
Leaked cluster 5 refcount=18446744073709551615 reference=1
98
Leaked cluster 6 refcount=1 reference=0
99
51
diff --git a/tests/qemu-iotests/244.out b/tests/qemu-iotests/244.out
100
diff --git a/tests/qemu-iotests/244.out b/tests/qemu-iotests/244.out
52
index XXXXXXX..XXXXXXX 100644
101
index XXXXXXX..XXXXXXX 100644
53
--- a/tests/qemu-iotests/244.out
102
--- a/tests/qemu-iotests/244.out
54
+++ b/tests/qemu-iotests/244.out
103
+++ b/tests/qemu-iotests/244.out
55
@@ -XXX,XX +XXX,XX @@ read 1048576/1048576 bytes at offset 0
104
@@ -XXX,XX +XXX,XX @@ write failed: Operation not supported
56
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
105
No errors were found on the image.
57
read 1048576/1048576 bytes at offset 1048576
106
58
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
107
Take an internal snapshot:
59
-read 2097152/2097152 bytes at offset 2097152
108
-qemu-img: Could not create snapshot 'test': -95 (Operation not supported)
60
-2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
109
+qemu-img: Could not create snapshot 'test': Operation not supported
61
read 1048576/1048576 bytes at offset 4194304
110
No errors were found on the image.
62
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
111
63
read 1048576/1048576 bytes at offset 5242880
112
=== Standalone image with external data file (efficient) ===
64
@@ -XXX,XX +XXX,XX @@ read 1048576/1048576 bytes at offset 1048576
65
read 4194304/4194304 bytes at offset 2097152
66
4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
67
68
-Images are identical.
69
+read 1048576/1048576 bytes at offset 0
70
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
71
+read 1048576/1048576 bytes at offset 1048576
72
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
73
+read 3145728/3145728 bytes at offset 3145728
74
+3 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
75
qcow2 file size after I/O: 327680
76
77
=== bdrv_co_block_status test for file and offset=0 ===
78
--
113
--
79
2.25.3
114
2.41.0
80
81
diff view generated by jsdifflib
1
This adds a new BdrvRequestFlags parameter to the .bdrv_co_truncate()
1
From: Peter Maydell <peter.maydell@linaro.org>
2
driver callbacks, and a supported_truncate_flags field in
3
BlockDriverState that allows drivers to advertise support for request
4
flags in the context of truncate.
5
2
6
For now, we always pass 0 and no drivers declare support for any flag.
3
In block/iscsi.c we use a raw malloc() call, which is unusual
4
given the project standard is to use the glib memory allocation
5
functions. Document why we do so, to avoid it being converted
6
to g_malloc() by mistake.
7
7
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
Message-ID: <20230727150705.2664464-1-peter.maydell@linaro.org>
10
Reviewed-by: Alberto Garcia <berto@igalia.com>
10
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
11
Reviewed-by: Max Reitz <mreitz@redhat.com>
12
Message-Id: <20200424125448.63318-2-kwolf@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
12
---
15
include/block/block_int.h | 10 +++++++++-
13
block/iscsi.c | 1 +
16
block/crypto.c | 3 ++-
14
1 file changed, 1 insertion(+)
17
block/file-posix.c | 2 +-
18
block/file-win32.c | 2 +-
19
block/gluster.c | 1 +
20
block/io.c | 8 +++++++-
21
block/iscsi.c | 2 +-
22
block/nfs.c | 3 ++-
23
block/qcow2.c | 2 +-
24
block/qed.c | 1 +
25
block/raw-format.c | 2 +-
26
block/rbd.c | 1 +
27
block/sheepdog.c | 4 ++--
28
block/ssh.c | 2 +-
29
tests/test-block-iothread.c | 3 ++-
30
15 files changed, 33 insertions(+), 13 deletions(-)
31
15
32
diff --git a/include/block/block_int.h b/include/block/block_int.h
33
index XXXXXXX..XXXXXXX 100644
34
--- a/include/block/block_int.h
35
+++ b/include/block/block_int.h
36
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
37
*/
38
int coroutine_fn (*bdrv_co_truncate)(BlockDriverState *bs, int64_t offset,
39
bool exact, PreallocMode prealloc,
40
- Error **errp);
41
+ BdrvRequestFlags flags, Error **errp);
42
43
int64_t (*bdrv_getlength)(BlockDriverState *bs);
44
bool has_variable_length;
45
@@ -XXX,XX +XXX,XX @@ struct BlockDriverState {
46
/* Flags honored during pwrite_zeroes (so far: BDRV_REQ_FUA,
47
* BDRV_REQ_MAY_UNMAP, BDRV_REQ_WRITE_UNCHANGED) */
48
unsigned int supported_zero_flags;
49
+ /*
50
+ * Flags honoured during truncate (so far: BDRV_REQ_ZERO_WRITE).
51
+ *
52
+ * If BDRV_REQ_ZERO_WRITE is given, the truncate operation must make sure
53
+ * that any added space reads as all zeros. If this can't be guaranteed,
54
+ * the operation must fail.
55
+ */
56
+ unsigned int supported_truncate_flags;
57
58
/* the following member gives a name to every node on the bs graph. */
59
char node_name[32];
60
diff --git a/block/crypto.c b/block/crypto.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/block/crypto.c
63
+++ b/block/crypto.c
64
@@ -XXX,XX +XXX,XX @@ static int block_crypto_co_create_generic(BlockDriverState *bs,
65
66
static int coroutine_fn
67
block_crypto_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
68
- PreallocMode prealloc, Error **errp)
69
+ PreallocMode prealloc, BdrvRequestFlags flags,
70
+ Error **errp)
71
{
72
BlockCrypto *crypto = bs->opaque;
73
uint64_t payload_offset =
74
diff --git a/block/file-posix.c b/block/file-posix.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/block/file-posix.c
77
+++ b/block/file-posix.c
78
@@ -XXX,XX +XXX,XX @@ raw_regular_truncate(BlockDriverState *bs, int fd, int64_t offset,
79
80
static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
81
bool exact, PreallocMode prealloc,
82
- Error **errp)
83
+ BdrvRequestFlags flags, Error **errp)
84
{
85
BDRVRawState *s = bs->opaque;
86
struct stat st;
87
diff --git a/block/file-win32.c b/block/file-win32.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/block/file-win32.c
90
+++ b/block/file-win32.c
91
@@ -XXX,XX +XXX,XX @@ static void raw_close(BlockDriverState *bs)
92
93
static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
94
bool exact, PreallocMode prealloc,
95
- Error **errp)
96
+ BdrvRequestFlags flags, Error **errp)
97
{
98
BDRVRawState *s = bs->opaque;
99
LONG low, high;
100
diff --git a/block/gluster.c b/block/gluster.c
101
index XXXXXXX..XXXXXXX 100644
102
--- a/block/gluster.c
103
+++ b/block/gluster.c
104
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qemu_gluster_co_truncate(BlockDriverState *bs,
105
int64_t offset,
106
bool exact,
107
PreallocMode prealloc,
108
+ BdrvRequestFlags flags,
109
Error **errp)
110
{
111
BDRVGlusterState *s = bs->opaque;
112
diff --git a/block/io.c b/block/io.c
113
index XXXXXXX..XXXXXXX 100644
114
--- a/block/io.c
115
+++ b/block/io.c
116
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
117
BlockDriverState *bs = child->bs;
118
BlockDriver *drv = bs->drv;
119
BdrvTrackedRequest req;
120
+ BdrvRequestFlags flags = 0;
121
int64_t old_size, new_bytes;
122
int ret;
123
124
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
125
}
126
127
if (drv->bdrv_co_truncate) {
128
- ret = drv->bdrv_co_truncate(bs, offset, exact, prealloc, errp);
129
+ if (flags & ~bs->supported_truncate_flags) {
130
+ error_setg(errp, "Block driver does not support requested flags");
131
+ ret = -ENOTSUP;
132
+ goto out;
133
+ }
134
+ ret = drv->bdrv_co_truncate(bs, offset, exact, prealloc, flags, errp);
135
} else if (bs->file && drv->is_filter) {
136
ret = bdrv_co_truncate(bs->file, offset, exact, prealloc, errp);
137
} else {
138
diff --git a/block/iscsi.c b/block/iscsi.c
16
diff --git a/block/iscsi.c b/block/iscsi.c
139
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
140
--- a/block/iscsi.c
18
--- a/block/iscsi.c
141
+++ b/block/iscsi.c
19
+++ b/block/iscsi.c
142
@@ -XXX,XX +XXX,XX @@ static void iscsi_reopen_commit(BDRVReopenState *reopen_state)
20
@@ -XXX,XX +XXX,XX @@ static BlockAIOCB *iscsi_aio_ioctl(BlockDriverState *bs,
143
21
return NULL;
144
static int coroutine_fn iscsi_co_truncate(BlockDriverState *bs, int64_t offset,
22
}
145
bool exact, PreallocMode prealloc,
23
146
- Error **errp)
24
+ /* Must use malloc(): this is freed via scsi_free_scsi_task() */
147
+ BdrvRequestFlags flags, Error **errp)
25
acb->task = malloc(sizeof(struct scsi_task));
148
{
26
if (acb->task == NULL) {
149
IscsiLun *iscsilun = bs->opaque;
27
error_report("iSCSI: Failed to allocate task for scsi command. %s",
150
int64_t cur_length;
151
diff --git a/block/nfs.c b/block/nfs.c
152
index XXXXXXX..XXXXXXX 100644
153
--- a/block/nfs.c
154
+++ b/block/nfs.c
155
@@ -XXX,XX +XXX,XX @@ static int64_t nfs_get_allocated_file_size(BlockDriverState *bs)
156
157
static int coroutine_fn
158
nfs_file_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
159
- PreallocMode prealloc, Error **errp)
160
+ PreallocMode prealloc, BdrvRequestFlags flags,
161
+ Error **errp)
162
{
163
NFSClient *client = bs->opaque;
164
int ret;
165
diff --git a/block/qcow2.c b/block/qcow2.c
166
index XXXXXXX..XXXXXXX 100644
167
--- a/block/qcow2.c
168
+++ b/block/qcow2.c
169
@@ -XXX,XX +XXX,XX @@ fail:
170
171
static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
172
bool exact, PreallocMode prealloc,
173
- Error **errp)
174
+ BdrvRequestFlags flags, Error **errp)
175
{
176
BDRVQcow2State *s = bs->opaque;
177
uint64_t old_length;
178
diff --git a/block/qed.c b/block/qed.c
179
index XXXXXXX..XXXXXXX 100644
180
--- a/block/qed.c
181
+++ b/block/qed.c
182
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_co_truncate(BlockDriverState *bs,
183
int64_t offset,
184
bool exact,
185
PreallocMode prealloc,
186
+ BdrvRequestFlags flags,
187
Error **errp)
188
{
189
BDRVQEDState *s = bs->opaque;
190
diff --git a/block/raw-format.c b/block/raw-format.c
191
index XXXXXXX..XXXXXXX 100644
192
--- a/block/raw-format.c
193
+++ b/block/raw-format.c
194
@@ -XXX,XX +XXX,XX @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
195
196
static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
197
bool exact, PreallocMode prealloc,
198
- Error **errp)
199
+ BdrvRequestFlags flags, Error **errp)
200
{
201
BDRVRawState *s = bs->opaque;
202
203
diff --git a/block/rbd.c b/block/rbd.c
204
index XXXXXXX..XXXXXXX 100644
205
--- a/block/rbd.c
206
+++ b/block/rbd.c
207
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qemu_rbd_co_truncate(BlockDriverState *bs,
208
int64_t offset,
209
bool exact,
210
PreallocMode prealloc,
211
+ BdrvRequestFlags flags,
212
Error **errp)
213
{
214
int r;
215
diff --git a/block/sheepdog.c b/block/sheepdog.c
216
index XXXXXXX..XXXXXXX 100644
217
--- a/block/sheepdog.c
218
+++ b/block/sheepdog.c
219
@@ -XXX,XX +XXX,XX @@ static int64_t sd_getlength(BlockDriverState *bs)
220
221
static int coroutine_fn sd_co_truncate(BlockDriverState *bs, int64_t offset,
222
bool exact, PreallocMode prealloc,
223
- Error **errp)
224
+ BdrvRequestFlags flags, Error **errp)
225
{
226
BDRVSheepdogState *s = bs->opaque;
227
int ret, fd;
228
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int sd_co_writev(BlockDriverState *bs, int64_t sector_num,
229
230
assert(!flags);
231
if (offset > s->inode.vdi_size) {
232
- ret = sd_co_truncate(bs, offset, false, PREALLOC_MODE_OFF, NULL);
233
+ ret = sd_co_truncate(bs, offset, false, PREALLOC_MODE_OFF, 0, NULL);
234
if (ret < 0) {
235
return ret;
236
}
237
diff --git a/block/ssh.c b/block/ssh.c
238
index XXXXXXX..XXXXXXX 100644
239
--- a/block/ssh.c
240
+++ b/block/ssh.c
241
@@ -XXX,XX +XXX,XX @@ static int64_t ssh_getlength(BlockDriverState *bs)
242
243
static int coroutine_fn ssh_co_truncate(BlockDriverState *bs, int64_t offset,
244
bool exact, PreallocMode prealloc,
245
- Error **errp)
246
+ BdrvRequestFlags flags, Error **errp)
247
{
248
BDRVSSHState *s = bs->opaque;
249
250
diff --git a/tests/test-block-iothread.c b/tests/test-block-iothread.c
251
index XXXXXXX..XXXXXXX 100644
252
--- a/tests/test-block-iothread.c
253
+++ b/tests/test-block-iothread.c
254
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_test_co_pdiscard(BlockDriverState *bs,
255
256
static int coroutine_fn
257
bdrv_test_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
258
- PreallocMode prealloc, Error **errp)
259
+ PreallocMode prealloc, BdrvRequestFlags flags,
260
+ Error **errp)
261
{
262
return 0;
263
}
264
--
28
--
265
2.25.3
29
2.41.0
266
267
diff view generated by jsdifflib
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
1
From: Hanna Czenczek <hreitz@redhat.com>
2
Message-Id: <20200424125448.63318-10-kwolf@redhat.com>
2
3
Reviewed-by: Max Reitz <mreitz@redhat.com>
3
For image creation code, we have central fallback code for protocols
4
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
4
that do not support creating new images (like NBD or iscsi). So for
5
them, you can only specify existing paths/exports that are overwritten
6
to make clean new images. In such a case, if the given path cannot be
7
opened (assuming a pre-existing image there), we print an error message
8
that tries to describe what is going on: That with this protocol, you
9
cannot create new images, but only overwrite existing ones; and the
10
given path could not be opened as a pre-existing image.
11
12
However, the current message is confusing, because it does not say that
13
the protocol in question does not support creating new images, but
14
instead that "image creation" is unsupported. This can be interpreted
15
to mean that `qemu-img create` will not work in principle, which is not
16
true. Be more verbose for clarity.
17
18
Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2217204
19
Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
20
Message-ID: <20230720140024.46836-1-hreitz@redhat.com>
21
Reviewed-by: Eric Blake <eblake@redhat.com>
22
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
23
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
---
24
---
7
tests/qemu-iotests/274 | 155 +++++++++++++++++++++
25
block.c | 6 ++++--
8
tests/qemu-iotests/274.out | 268 +++++++++++++++++++++++++++++++++++++
26
1 file changed, 4 insertions(+), 2 deletions(-)
9
tests/qemu-iotests/group | 1 +
10
3 files changed, 424 insertions(+)
11
create mode 100755 tests/qemu-iotests/274
12
create mode 100644 tests/qemu-iotests/274.out
13
27
14
diff --git a/tests/qemu-iotests/274 b/tests/qemu-iotests/274
28
diff --git a/block.c b/block.c
15
new file mode 100755
16
index XXXXXXX..XXXXXXX
17
--- /dev/null
18
+++ b/tests/qemu-iotests/274
19
@@ -XXX,XX +XXX,XX @@
20
+#!/usr/bin/env python3
21
+#
22
+# Copyright (C) 2019 Red Hat, Inc.
23
+#
24
+# This program is free software; you can redistribute it and/or modify
25
+# it under the terms of the GNU General Public License as published by
26
+# the Free Software Foundation; either version 2 of the License, or
27
+# (at your option) any later version.
28
+#
29
+# This program is distributed in the hope that it will be useful,
30
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
31
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32
+# GNU General Public License for more details.
33
+#
34
+# You should have received a copy of the GNU General Public License
35
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
36
+#
37
+# Creator/Owner: Kevin Wolf <kwolf@redhat.com>
38
+#
39
+# Some tests for short backing files and short overlays
40
+
41
+import iotests
42
+
43
+iotests.verify_image_format(supported_fmts=['qcow2'])
44
+iotests.verify_platform(['linux'])
45
+
46
+size_short = 1 * 1024 * 1024
47
+size_long = 2 * 1024 * 1024
48
+size_diff = size_long - size_short
49
+
50
+def create_chain() -> None:
51
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, base,
52
+ str(size_long))
53
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, '-b', base, mid,
54
+ str(size_short))
55
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, '-b', mid, top,
56
+ str(size_long))
57
+
58
+ iotests.qemu_io_log('-c', 'write -P 1 0 %d' % size_long, base)
59
+
60
+def create_vm() -> iotests.VM:
61
+ vm = iotests.VM()
62
+ vm.add_blockdev('file,filename=%s,node-name=base-file' % base)
63
+ vm.add_blockdev('%s,file=base-file,node-name=base' % iotests.imgfmt)
64
+ vm.add_blockdev('file,filename=%s,node-name=mid-file' % mid)
65
+ vm.add_blockdev('%s,file=mid-file,node-name=mid,backing=base'
66
+ % iotests.imgfmt)
67
+ vm.add_drive(top, 'backing=mid,node-name=top')
68
+ return vm
69
+
70
+with iotests.FilePath('base') as base, \
71
+ iotests.FilePath('mid') as mid, \
72
+ iotests.FilePath('top') as top:
73
+
74
+ iotests.log('== Commit tests ==')
75
+
76
+ create_chain()
77
+
78
+ iotests.log('=== Check visible data ===')
79
+
80
+ iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, top)
81
+ iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), top)
82
+
83
+ iotests.log('=== Checking allocation status ===')
84
+
85
+ iotests.qemu_io_log('-c', 'alloc 0 %d' % size_short,
86
+ '-c', 'alloc %d %d' % (size_short, size_diff),
87
+ base)
88
+
89
+ iotests.qemu_io_log('-c', 'alloc 0 %d' % size_short,
90
+ '-c', 'alloc %d %d' % (size_short, size_diff),
91
+ mid)
92
+
93
+ iotests.qemu_io_log('-c', 'alloc 0 %d' % size_short,
94
+ '-c', 'alloc %d %d' % (size_short, size_diff),
95
+ top)
96
+
97
+ iotests.log('=== Checking map ===')
98
+
99
+ iotests.qemu_img_log('map', '--output=json', base)
100
+ iotests.qemu_img_log('map', '--output=human', base)
101
+ iotests.qemu_img_log('map', '--output=json', mid)
102
+ iotests.qemu_img_log('map', '--output=human', mid)
103
+ iotests.qemu_img_log('map', '--output=json', top)
104
+ iotests.qemu_img_log('map', '--output=human', top)
105
+
106
+ iotests.log('=== Testing qemu-img commit (top -> mid) ===')
107
+
108
+ iotests.qemu_img_log('commit', top)
109
+ iotests.img_info_log(mid)
110
+ iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, mid)
111
+ iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), mid)
112
+
113
+ iotests.log('=== Testing HMP commit (top -> mid) ===')
114
+
115
+ create_chain()
116
+ with create_vm() as vm:
117
+ vm.launch()
118
+ vm.qmp_log('human-monitor-command', command_line='commit drive0')
119
+
120
+ iotests.img_info_log(mid)
121
+ iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, mid)
122
+ iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), mid)
123
+
124
+ iotests.log('=== Testing QMP active commit (top -> mid) ===')
125
+
126
+ create_chain()
127
+ with create_vm() as vm:
128
+ vm.launch()
129
+ vm.qmp_log('block-commit', device='top', base_node='mid',
130
+ job_id='job0', auto_dismiss=False)
131
+ vm.run_job('job0', wait=5)
132
+
133
+ iotests.img_info_log(mid)
134
+ iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, mid)
135
+ iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), mid)
136
+
137
+
138
+ iotests.log('== Resize tests ==')
139
+
140
+ # Use different sizes for different allocation modes:
141
+ #
142
+ # We want to have at least one test where 32 bit truncation in the size of
143
+ # the overlapping area becomes visible. This is covered by the
144
+ # prealloc='off' case (1G to 6G is an overlap of 5G).
145
+ #
146
+ # However, we can only do this for modes that don't preallocate data
147
+ # because otherwise we might run out of space on the test host.
148
+ #
149
+ # We also want to test some unaligned combinations.
150
+ for (prealloc, base_size, top_size_old, top_size_new, off) in [
151
+ ('off', '6G', '1G', '8G', '5G'),
152
+ ('metadata', '32G', '30G', '33G', '31G'),
153
+ ('falloc', '10M', '5M', '15M', '9M'),
154
+ ('full', '16M', '8M', '12M', '11M'),
155
+ ('off', '384k', '253k', '512k', '253k'),
156
+ ('off', '400k', '256k', '512k', '336k'),
157
+ ('off', '512k', '256k', '500k', '436k')]:
158
+
159
+ iotests.log('=== preallocation=%s ===' % prealloc)
160
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, base, base_size)
161
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, '-b', base, top,
162
+ top_size_old)
163
+ iotests.qemu_io_log('-c', 'write -P 1 %s 64k' % off, base)
164
+
165
+ # After this, top_size_old to base_size should be allocated/zeroed.
166
+ #
167
+ # In theory, leaving base_size to top_size_new unallocated would be
168
+ # correct, but in practice, if we zero out anything, we zero out
169
+ # everything up to top_size_new.
170
+ iotests.qemu_img_log('resize', '-f', iotests.imgfmt,
171
+ '--preallocation', prealloc, top, top_size_new)
172
+ iotests.qemu_io_log('-c', 'read -P 0 %s 64k' % off, top)
173
+ iotests.qemu_io_log('-c', 'map', top)
174
+ iotests.qemu_img_log('map', '--output=json', top)
175
diff --git a/tests/qemu-iotests/274.out b/tests/qemu-iotests/274.out
176
new file mode 100644
177
index XXXXXXX..XXXXXXX
178
--- /dev/null
179
+++ b/tests/qemu-iotests/274.out
180
@@ -XXX,XX +XXX,XX @@
181
+== Commit tests ==
182
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16
183
+
184
+Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
185
+
186
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off refcount_bits=16
187
+
188
+wrote 2097152/2097152 bytes at offset 0
189
+2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
190
+
191
+=== Check visible data ===
192
+read 1048576/1048576 bytes at offset 0
193
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
194
+
195
+read 1048576/1048576 bytes at offset 1048576
196
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
197
+
198
+=== Checking allocation status ===
199
+1048576/1048576 bytes allocated at offset 0 bytes
200
+1048576/1048576 bytes allocated at offset 1 MiB
201
+
202
+0/1048576 bytes allocated at offset 0 bytes
203
+0/0 bytes allocated at offset 1 MiB
204
+
205
+0/1048576 bytes allocated at offset 0 bytes
206
+0/1048576 bytes allocated at offset 1 MiB
207
+
208
+=== Checking map ===
209
+[{ "start": 0, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": 327680}]
210
+
211
+Offset Length Mapped to File
212
+0 0x200000 0x50000 TEST_DIR/PID-base
213
+
214
+[{ "start": 0, "length": 1048576, "depth": 1, "zero": false, "data": true, "offset": 327680}]
215
+
216
+Offset Length Mapped to File
217
+0 0x100000 0x50000 TEST_DIR/PID-base
218
+
219
+[{ "start": 0, "length": 1048576, "depth": 2, "zero": false, "data": true, "offset": 327680},
220
+{ "start": 1048576, "length": 1048576, "depth": 0, "zero": true, "data": false}]
221
+
222
+Offset Length Mapped to File
223
+0 0x100000 0x50000 TEST_DIR/PID-base
224
+
225
+=== Testing qemu-img commit (top -> mid) ===
226
+Image committed.
227
+
228
+image: TEST_IMG
229
+file format: IMGFMT
230
+virtual size: 2 MiB (2097152 bytes)
231
+cluster_size: 65536
232
+backing file: TEST_DIR/PID-base
233
+Format specific information:
234
+ compat: 1.1
235
+ lazy refcounts: false
236
+ refcount bits: 16
237
+ corrupt: false
238
+
239
+read 1048576/1048576 bytes at offset 0
240
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
241
+
242
+read 1048576/1048576 bytes at offset 1048576
243
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
244
+
245
+=== Testing HMP commit (top -> mid) ===
246
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16
247
+
248
+Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
249
+
250
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off refcount_bits=16
251
+
252
+wrote 2097152/2097152 bytes at offset 0
253
+2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
254
+
255
+{"execute": "human-monitor-command", "arguments": {"command-line": "commit drive0"}}
256
+{"return": ""}
257
+image: TEST_IMG
258
+file format: IMGFMT
259
+virtual size: 2 MiB (2097152 bytes)
260
+cluster_size: 65536
261
+backing file: TEST_DIR/PID-base
262
+Format specific information:
263
+ compat: 1.1
264
+ lazy refcounts: false
265
+ refcount bits: 16
266
+ corrupt: false
267
+
268
+read 1048576/1048576 bytes at offset 0
269
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
270
+
271
+read 1048576/1048576 bytes at offset 1048576
272
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
273
+
274
+=== Testing QMP active commit (top -> mid) ===
275
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16
276
+
277
+Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
278
+
279
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off refcount_bits=16
280
+
281
+wrote 2097152/2097152 bytes at offset 0
282
+2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
283
+
284
+{"execute": "block-commit", "arguments": {"auto-dismiss": false, "base-node": "mid", "device": "top", "job-id": "job0"}}
285
+{"return": {}}
286
+{"execute": "job-complete", "arguments": {"id": "job0"}}
287
+{"return": {}}
288
+{"data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
289
+{"data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
290
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
291
+{"return": {}}
292
+image: TEST_IMG
293
+file format: IMGFMT
294
+virtual size: 2 MiB (2097152 bytes)
295
+cluster_size: 65536
296
+backing file: TEST_DIR/PID-base
297
+Format specific information:
298
+ compat: 1.1
299
+ lazy refcounts: false
300
+ refcount bits: 16
301
+ corrupt: false
302
+
303
+read 1048576/1048576 bytes at offset 0
304
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
305
+
306
+read 1048576/1048576 bytes at offset 1048576
307
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
308
+
309
+== Resize tests ==
310
+=== preallocation=off ===
311
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=6442450944 cluster_size=65536 lazy_refcounts=off refcount_bits=16
312
+
313
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=1073741824 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
314
+
315
+wrote 65536/65536 bytes at offset 5368709120
316
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
317
+
318
+Image resized.
319
+
320
+read 65536/65536 bytes at offset 5368709120
321
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
322
+
323
+1 GiB (0x40000000) bytes not allocated at offset 0 bytes (0x0)
324
+7 GiB (0x1c0000000) bytes allocated at offset 1 GiB (0x40000000)
325
+
326
+[{ "start": 0, "length": 1073741824, "depth": 1, "zero": true, "data": false},
327
+{ "start": 1073741824, "length": 7516192768, "depth": 0, "zero": true, "data": false}]
328
+
329
+=== preallocation=metadata ===
330
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=34359738368 cluster_size=65536 lazy_refcounts=off refcount_bits=16
331
+
332
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=32212254720 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
333
+
334
+wrote 65536/65536 bytes at offset 33285996544
335
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
336
+
337
+Image resized.
338
+
339
+read 65536/65536 bytes at offset 33285996544
340
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
341
+
342
+30 GiB (0x780000000) bytes not allocated at offset 0 bytes (0x0)
343
+3 GiB (0xc0000000) bytes allocated at offset 30 GiB (0x780000000)
344
+
345
+[{ "start": 0, "length": 32212254720, "depth": 1, "zero": true, "data": false},
346
+{ "start": 32212254720, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 327680},
347
+{ "start": 32749125632, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 537264128},
348
+{ "start": 33285996544, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 1074200576},
349
+{ "start": 33822867456, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 1611137024},
350
+{ "start": 34359738368, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 2148139008},
351
+{ "start": 34896609280, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 2685075456}]
352
+
353
+=== preallocation=falloc ===
354
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=10485760 cluster_size=65536 lazy_refcounts=off refcount_bits=16
355
+
356
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=5242880 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
357
+
358
+wrote 65536/65536 bytes at offset 9437184
359
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
360
+
361
+Image resized.
362
+
363
+read 65536/65536 bytes at offset 9437184
364
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
365
+
366
+5 MiB (0x500000) bytes not allocated at offset 0 bytes (0x0)
367
+10 MiB (0xa00000) bytes allocated at offset 5 MiB (0x500000)
368
+
369
+[{ "start": 0, "length": 5242880, "depth": 1, "zero": true, "data": false},
370
+{ "start": 5242880, "length": 10485760, "depth": 0, "zero": true, "data": false, "offset": 327680}]
371
+
372
+=== preallocation=full ===
373
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=16777216 cluster_size=65536 lazy_refcounts=off refcount_bits=16
374
+
375
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=8388608 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
376
+
377
+wrote 65536/65536 bytes at offset 11534336
378
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
379
+
380
+Image resized.
381
+
382
+read 65536/65536 bytes at offset 11534336
383
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
384
+
385
+8 MiB (0x800000) bytes not allocated at offset 0 bytes (0x0)
386
+4 MiB (0x400000) bytes allocated at offset 8 MiB (0x800000)
387
+
388
+[{ "start": 0, "length": 8388608, "depth": 1, "zero": true, "data": false},
389
+{ "start": 8388608, "length": 4194304, "depth": 0, "zero": true, "data": false, "offset": 327680}]
390
+
391
+=== preallocation=off ===
392
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=393216 cluster_size=65536 lazy_refcounts=off refcount_bits=16
393
+
394
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=259072 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
395
+
396
+wrote 65536/65536 bytes at offset 259072
397
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
398
+
399
+Image resized.
400
+
401
+read 65536/65536 bytes at offset 259072
402
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
403
+
404
+192 KiB (0x30000) bytes not allocated at offset 0 bytes (0x0)
405
+320 KiB (0x50000) bytes allocated at offset 192 KiB (0x30000)
406
+
407
+[{ "start": 0, "length": 196608, "depth": 1, "zero": true, "data": false},
408
+{ "start": 196608, "length": 65536, "depth": 0, "zero": false, "data": true, "offset": 327680},
409
+{ "start": 262144, "length": 262144, "depth": 0, "zero": true, "data": false}]
410
+
411
+=== preallocation=off ===
412
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=409600 cluster_size=65536 lazy_refcounts=off refcount_bits=16
413
+
414
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=262144 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
415
+
416
+wrote 65536/65536 bytes at offset 344064
417
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
418
+
419
+Image resized.
420
+
421
+read 65536/65536 bytes at offset 344064
422
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
423
+
424
+256 KiB (0x40000) bytes not allocated at offset 0 bytes (0x0)
425
+256 KiB (0x40000) bytes allocated at offset 256 KiB (0x40000)
426
+
427
+[{ "start": 0, "length": 262144, "depth": 1, "zero": true, "data": false},
428
+{ "start": 262144, "length": 262144, "depth": 0, "zero": true, "data": false}]
429
+
430
+=== preallocation=off ===
431
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=524288 cluster_size=65536 lazy_refcounts=off refcount_bits=16
432
+
433
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=262144 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
434
+
435
+wrote 65536/65536 bytes at offset 446464
436
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
437
+
438
+Image resized.
439
+
440
+read 65536/65536 bytes at offset 446464
441
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
442
+
443
+256 KiB (0x40000) bytes not allocated at offset 0 bytes (0x0)
444
+244 KiB (0x3d000) bytes allocated at offset 256 KiB (0x40000)
445
+
446
+[{ "start": 0, "length": 262144, "depth": 1, "zero": true, "data": false},
447
+{ "start": 262144, "length": 249856, "depth": 0, "zero": true, "data": false}]
448
+
449
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
450
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
451
--- a/tests/qemu-iotests/group
30
--- a/block.c
452
+++ b/tests/qemu-iotests/group
31
+++ b/block.c
453
@@ -XXX,XX +XXX,XX @@
32
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_create_opts_simple(BlockDriver *drv,
454
270 rw backing quick
33
blk = blk_co_new_open(filename, NULL, options,
455
272 rw
34
BDRV_O_RDWR | BDRV_O_RESIZE, errp);
456
273 backing quick
35
if (!blk) {
457
+274 rw backing
36
- error_prepend(errp, "Protocol driver '%s' does not support image "
458
277 rw quick
37
- "creation, and opening the image failed: ",
459
279 rw backing quick
38
+ error_prepend(errp, "Protocol driver '%s' does not support creating "
460
280 rw migration quick
39
+ "new images, so an existing image must be selected as "
40
+ "the target; however, opening the given target as an "
41
+ "existing image failed: ",
42
drv->format_name);
43
return -EINVAL;
44
}
461
--
45
--
462
2.25.3
46
2.41.0
463
464
diff view generated by jsdifflib
1
We want to keep TEST_IMG for the full path of the main test image, but
1
Document the 'compression_type' option for qcow2, and mention that
2
filter_testfiles() must be called for other test images before replacing
2
streamOptimized vmdk supports compression, too.
3
other things like the image format because the test directory path could
4
contain the format as a substring.
5
3
6
Insert a filter_testfiles() call between both.
4
Reported-by: Richard W.M. Jones <rjones@redhat.com>
7
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Reviewed-by: Max Reitz <mreitz@redhat.com>
6
Message-ID: <20230901102430.23856-1-kwolf@redhat.com>
10
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
11
Message-Id: <20200424125448.63318-9-kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
9
---
14
tests/qemu-iotests/iotests.py | 5 +++--
10
docs/tools/qemu-img.rst | 19 +++++++++++++++++--
15
1 file changed, 3 insertions(+), 2 deletions(-)
11
1 file changed, 17 insertions(+), 2 deletions(-)
16
12
17
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
13
diff --git a/docs/tools/qemu-img.rst b/docs/tools/qemu-img.rst
18
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
19
--- a/tests/qemu-iotests/iotests.py
15
--- a/docs/tools/qemu-img.rst
20
+++ b/tests/qemu-iotests/iotests.py
16
+++ b/docs/tools/qemu-img.rst
21
@@ -XXX,XX +XXX,XX @@ def filter_img_info(output, filename):
17
@@ -XXX,XX +XXX,XX @@ by the used format or see the format descriptions below for details.
22
for line in output.split('\n'):
18
23
if 'disk size' in line or 'actual-size' in line:
19
.. option:: -c
24
continue
20
25
- line = line.replace(filename, 'TEST_IMG') \
21
- Indicates that target image must be compressed (qcow format only).
26
- .replace(imgfmt, 'IMGFMT')
22
+ Indicates that target image must be compressed (qcow/qcow2 and vmdk with
27
+ line = line.replace(filename, 'TEST_IMG')
23
+ streamOptimized subformat only).
28
+ line = filter_testfiles(line)
24
+
29
+ line = line.replace(imgfmt, 'IMGFMT')
25
+ For qcow2, the compression algorithm can be specified with the ``-o
30
line = re.sub('iters: [0-9]+', 'iters: XXX', line)
26
+ compression_type=...`` option (see below).
31
line = re.sub('uuid: [-a-f0-9]+', 'uuid: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX', line)
27
32
line = re.sub('cid: [0-9]+', 'cid: XXXXXXXXXX', line)
28
.. option:: -h
29
30
@@ -XXX,XX +XXX,XX @@ Supported image file formats:
31
32
QEMU image format, the most versatile format. Use it to have smaller
33
images (useful if your filesystem does not supports holes, for example
34
- on Windows), optional AES encryption, zlib based compression and
35
+ on Windows), optional AES encryption, zlib or zstd based compression and
36
support of multiple VM snapshots.
37
38
Supported options:
39
@@ -XXX,XX +XXX,XX @@ Supported image file formats:
40
``backing_fmt``
41
Image format of the base image
42
43
+ ``compression_type``
44
+ This option configures which compression algorithm will be used for
45
+ compressed clusters on the image. Note that setting this option doesn't yet
46
+ cause the image to actually receive compressed writes. It is most commonly
47
+ used with the ``-c`` option of ``qemu-img convert``, but can also be used
48
+ with the ``compress`` filter driver or backup block jobs with compression
49
+ enabled.
50
+
51
+ Valid values are ``zlib`` and ``zstd``. For images that use
52
+ ``compat=0.10``, only ``zlib`` compression is available.
53
+
54
``encryption``
55
If this option is set to ``on``, the image is encrypted with
56
128-bit AES-CBC.
33
--
57
--
34
2.25.3
58
2.41.0
35
36
diff view generated by jsdifflib
1
For regular files, we always get BDRV_REQ_ZERO_WRITE behaviour from the
1
From: Dmitry Frolov <frolov@swemel.ru>
2
OS, so we can advertise the flag and just ignore it.
3
2
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
3
bdrv_open_child() may return NULL.
5
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
4
Usually return value is checked for this function.
6
Reviewed-by: Alberto Garcia <berto@igalia.com>
5
Check for return value is more reliable.
7
Reviewed-by: Max Reitz <mreitz@redhat.com>
6
8
Message-Id: <20200424125448.63318-7-kwolf@redhat.com>
7
Fixes: 24bc15d1f6 ("vmdk: Use BdrvChild instead of BDS for references to extents")
8
9
Signed-off-by: Dmitry Frolov <frolov@swemel.ru>
10
Message-ID: <20230831125926.796205-1-frolov@swemel.ru>
11
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
13
---
11
block/file-posix.c | 4 ++++
14
block/vmdk.c | 2 +-
12
1 file changed, 4 insertions(+)
15
1 file changed, 1 insertion(+), 1 deletion(-)
13
16
14
diff --git a/block/file-posix.c b/block/file-posix.c
17
diff --git a/block/vmdk.c b/block/vmdk.c
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/block/file-posix.c
19
--- a/block/vmdk.c
17
+++ b/block/file-posix.c
20
+++ b/block/vmdk.c
18
@@ -XXX,XX +XXX,XX @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
21
@@ -XXX,XX +XXX,XX @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
19
#endif
22
bs, &child_of_bds, extent_role, false,
20
23
&local_err);
21
bs->supported_zero_flags = BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK;
24
g_free(extent_path);
22
+ if (S_ISREG(st.st_mode)) {
25
- if (local_err) {
23
+ /* When extending regular files, we get zeros from the OS */
26
+ if (!extent_file) {
24
+ bs->supported_truncate_flags = BDRV_REQ_ZERO_WRITE;
27
error_propagate(errp, local_err);
25
+ }
28
ret = -EINVAL;
26
ret = 0;
29
goto out;
27
fail:
28
if (filename && (bdrv_flags & BDRV_O_TEMPORARY)) {
29
--
30
--
30
2.25.3
31
2.41.0
31
32
diff view generated by jsdifflib
1
Now that block drivers can support flags for .bdrv_co_truncate, expose
1
From: Stefan Hajnoczi <stefanha@redhat.com>
2
the parameter in the node level interfaces bdrv_co_truncate() and
2
3
bdrv_truncate().
3
The synchronous bdrv_aio_cancel() function needs the acb's AioContext so
4
4
it can call aio_poll() to wait for cancellation.
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
6
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
6
It turns out that all users run under the BQL in the main AioContext, so
7
Reviewed-by: Alberto Garcia <berto@igalia.com>
7
this callback is not needed.
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
8
9
Message-Id: <20200424125448.63318-3-kwolf@redhat.com>
9
Remove the callback, mark bdrv_aio_cancel() GLOBAL_STATE_CODE just like
10
its blk_aio_cancel() caller, and poll the main loop AioContext.
11
12
The purpose of this cleanup is to identify bdrv_aio_cancel() as an API
13
that does not work with the multi-queue block layer.
14
15
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
16
Message-ID: <20230823235938.1398382-2-stefanha@redhat.com>
17
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
19
---
12
include/block/block.h | 5 +++--
20
include/block/aio.h | 1 -
13
block/block-backend.c | 2 +-
21
include/block/block-global-state.h | 2 ++
14
block/crypto.c | 2 +-
22
include/block/block-io.h | 1 -
15
block/io.c | 12 +++++++-----
23
block/block-backend.c | 17 -----------------
16
block/parallels.c | 6 +++---
24
block/io.c | 23 ++++++++---------------
17
block/qcow.c | 4 ++--
25
hw/nvme/ctrl.c | 7 -------
18
block/qcow2-refcount.c | 2 +-
26
softmmu/dma-helpers.c | 8 --------
19
block/qcow2.c | 15 +++++++++------
27
util/thread-pool.c | 8 --------
20
block/raw-format.c | 2 +-
28
8 files changed, 10 insertions(+), 57 deletions(-)
21
block/vhdx-log.c | 2 +-
29
22
block/vhdx.c | 2 +-
30
diff --git a/include/block/aio.h b/include/block/aio.h
23
block/vmdk.c | 2 +-
31
index XXXXXXX..XXXXXXX 100644
24
tests/test-block-iothread.c | 6 +++---
32
--- a/include/block/aio.h
25
13 files changed, 34 insertions(+), 28 deletions(-)
33
+++ b/include/block/aio.h
26
34
@@ -XXX,XX +XXX,XX @@ typedef void BlockCompletionFunc(void *opaque, int ret);
27
diff --git a/include/block/block.h b/include/block/block.h
35
28
index XXXXXXX..XXXXXXX 100644
36
typedef struct AIOCBInfo {
29
--- a/include/block/block.h
37
void (*cancel_async)(BlockAIOCB *acb);
30
+++ b/include/block/block.h
38
- AioContext *(*get_aio_context)(BlockAIOCB *acb);
31
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
39
size_t aiocb_size;
32
void bdrv_refresh_filename(BlockDriverState *bs);
40
} AIOCBInfo;
33
41
34
int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
42
diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h
35
- PreallocMode prealloc, Error **errp);
43
index XXXXXXX..XXXXXXX 100644
36
+ PreallocMode prealloc, BdrvRequestFlags flags,
44
--- a/include/block/block-global-state.h
37
+ Error **errp);
45
+++ b/include/block/block-global-state.h
38
int bdrv_truncate(BdrvChild *child, int64_t offset, bool exact,
46
@@ -XXX,XX +XXX,XX @@ void bdrv_drain_all_begin_nopoll(void);
39
- PreallocMode prealloc, Error **errp);
47
void bdrv_drain_all_end(void);
40
+ PreallocMode prealloc, BdrvRequestFlags flags, Error **errp);
48
void bdrv_drain_all(void);
41
49
42
int64_t bdrv_nb_sectors(BlockDriverState *bs);
50
+void bdrv_aio_cancel(BlockAIOCB *acb);
43
int64_t bdrv_getlength(BlockDriverState *bs);
51
+
52
int bdrv_has_zero_init_1(BlockDriverState *bs);
53
int bdrv_has_zero_init(BlockDriverState *bs);
54
BlockDriverState *bdrv_find_node(const char *node_name);
55
diff --git a/include/block/block-io.h b/include/block/block-io.h
56
index XXXXXXX..XXXXXXX 100644
57
--- a/include/block/block-io.h
58
+++ b/include/block/block-io.h
59
@@ -XXX,XX +XXX,XX @@ bdrv_co_delete_file_noerr(BlockDriverState *bs);
60
61
62
/* async block I/O */
63
-void bdrv_aio_cancel(BlockAIOCB *acb);
64
void bdrv_aio_cancel_async(BlockAIOCB *acb);
65
66
/* sg packet commands */
44
diff --git a/block/block-backend.c b/block/block-backend.c
67
diff --git a/block/block-backend.c b/block/block-backend.c
45
index XXXXXXX..XXXXXXX 100644
68
index XXXXXXX..XXXXXXX 100644
46
--- a/block/block-backend.c
69
--- a/block/block-backend.c
47
+++ b/block/block-backend.c
70
+++ b/block/block-backend.c
48
@@ -XXX,XX +XXX,XX @@ int blk_truncate(BlockBackend *blk, int64_t offset, bool exact,
71
@@ -XXX,XX +XXX,XX @@
49
return -ENOMEDIUM;
72
50
}
73
#define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */
51
74
52
- return bdrv_truncate(blk->root, offset, exact, prealloc, errp);
75
-static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb);
53
+ return bdrv_truncate(blk->root, offset, exact, prealloc, 0, errp);
76
-
54
}
77
typedef struct BlockBackendAioNotifier {
55
78
void (*attached_aio_context)(AioContext *new_context, void *opaque);
56
int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
79
void (*detach_aio_context)(void *opaque);
57
diff --git a/block/crypto.c b/block/crypto.c
80
@@ -XXX,XX +XXX,XX @@ typedef struct BlockBackendAIOCB {
58
index XXXXXXX..XXXXXXX 100644
81
} BlockBackendAIOCB;
59
--- a/block/crypto.c
82
60
+++ b/block/crypto.c
83
static const AIOCBInfo block_backend_aiocb_info = {
61
@@ -XXX,XX +XXX,XX @@ block_crypto_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
84
- .get_aio_context = blk_aiocb_get_aio_context,
62
85
.aiocb_size = sizeof(BlockBackendAIOCB),
63
offset += payload_offset;
86
};
64
87
65
- return bdrv_co_truncate(bs->file, offset, exact, prealloc, errp);
88
@@ -XXX,XX +XXX,XX @@ typedef struct BlkAioEmAIOCB {
66
+ return bdrv_co_truncate(bs->file, offset, exact, prealloc, 0, errp);
89
bool has_returned;
67
}
90
} BlkAioEmAIOCB;
68
91
69
static void block_crypto_close(BlockDriverState *bs)
92
-static AioContext *blk_aio_em_aiocb_get_aio_context(BlockAIOCB *acb_)
93
-{
94
- BlkAioEmAIOCB *acb = container_of(acb_, BlkAioEmAIOCB, common);
95
-
96
- return blk_get_aio_context(acb->rwco.blk);
97
-}
98
-
99
static const AIOCBInfo blk_aio_em_aiocb_info = {
100
.aiocb_size = sizeof(BlkAioEmAIOCB),
101
- .get_aio_context = blk_aio_em_aiocb_get_aio_context,
102
};
103
104
static void blk_aio_complete(BlkAioEmAIOCB *acb)
105
@@ -XXX,XX +XXX,XX @@ AioContext *blk_get_aio_context(BlockBackend *blk)
106
return blk->ctx;
107
}
108
109
-static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb)
110
-{
111
- BlockBackendAIOCB *blk_acb = DO_UPCAST(BlockBackendAIOCB, common, acb);
112
- return blk_get_aio_context(blk_acb->blk);
113
-}
114
-
115
int blk_set_aio_context(BlockBackend *blk, AioContext *new_context,
116
Error **errp)
117
{
70
diff --git a/block/io.c b/block/io.c
118
diff --git a/block/io.c b/block/io.c
71
index XXXXXXX..XXXXXXX 100644
119
index XXXXXXX..XXXXXXX 100644
72
--- a/block/io.c
120
--- a/block/io.c
73
+++ b/block/io.c
121
+++ b/block/io.c
74
@@ -XXX,XX +XXX,XX @@ static void bdrv_parent_cb_resize(BlockDriverState *bs)
122
@@ -XXX,XX +XXX,XX @@ int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
75
* 'offset' bytes in length.
123
/**************************************************************/
76
*/
124
/* async I/Os */
77
int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
125
78
- PreallocMode prealloc, Error **errp)
126
+/**
79
+ PreallocMode prealloc, BdrvRequestFlags flags,
127
+ * Synchronously cancels an acb. Must be called with the BQL held and the acb
80
+ Error **errp)
128
+ * must be processed with the BQL held too (IOThreads are not allowed).
129
+ *
130
+ * Use bdrv_aio_cancel_async() instead when possible.
131
+ */
132
void bdrv_aio_cancel(BlockAIOCB *acb)
81
{
133
{
82
BlockDriverState *bs = child->bs;
134
- IO_CODE();
83
BlockDriver *drv = bs->drv;
135
+ GLOBAL_STATE_CODE();
84
BdrvTrackedRequest req;
136
qemu_aio_ref(acb);
85
- BdrvRequestFlags flags = 0;
137
bdrv_aio_cancel_async(acb);
86
int64_t old_size, new_bytes;
138
- while (acb->refcnt > 1) {
87
int ret;
139
- if (acb->aiocb_info->get_aio_context) {
88
140
- aio_poll(acb->aiocb_info->get_aio_context(acb), true);
89
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
141
- } else if (acb->bs) {
90
}
142
- /* qemu_aio_ref and qemu_aio_unref are not thread-safe, so
91
ret = drv->bdrv_co_truncate(bs, offset, exact, prealloc, flags, errp);
143
- * assert that we're not using an I/O thread. Thread-safe
92
} else if (bs->file && drv->is_filter) {
144
- * code should use bdrv_aio_cancel_async exclusively.
93
- ret = bdrv_co_truncate(bs->file, offset, exact, prealloc, errp);
145
- */
94
+ ret = bdrv_co_truncate(bs->file, offset, exact, prealloc, flags, errp);
146
- assert(bdrv_get_aio_context(acb->bs) == qemu_get_aio_context());
95
} else {
147
- aio_poll(bdrv_get_aio_context(acb->bs), true);
96
error_setg(errp, "Image format driver does not support resize");
148
- } else {
97
ret = -ENOTSUP;
149
- abort();
98
@@ -XXX,XX +XXX,XX @@ typedef struct TruncateCo {
150
- }
99
int64_t offset;
151
- }
100
bool exact;
152
+ AIO_WAIT_WHILE_UNLOCKED(NULL, acb->refcnt > 1);
101
PreallocMode prealloc;
153
qemu_aio_unref(acb);
102
+ BdrvRequestFlags flags;
154
}
103
Error **errp;
155
104
int ret;
156
diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
105
} TruncateCo;
157
index XXXXXXX..XXXXXXX 100644
106
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn bdrv_truncate_co_entry(void *opaque)
158
--- a/hw/nvme/ctrl.c
159
+++ b/hw/nvme/ctrl.c
160
@@ -XXX,XX +XXX,XX @@ static inline bool nvme_is_write(NvmeRequest *req)
161
rw->opcode == NVME_CMD_WRITE_ZEROES;
162
}
163
164
-static AioContext *nvme_get_aio_context(BlockAIOCB *acb)
165
-{
166
- return qemu_get_aio_context();
167
-}
168
-
169
static void nvme_misc_cb(void *opaque, int ret)
107
{
170
{
108
TruncateCo *tco = opaque;
171
NvmeRequest *req = opaque;
109
tco->ret = bdrv_co_truncate(tco->child, tco->offset, tco->exact,
172
@@ -XXX,XX +XXX,XX @@ static void nvme_flush_cancel(BlockAIOCB *acb)
110
- tco->prealloc, tco->errp);
173
static const AIOCBInfo nvme_flush_aiocb_info = {
111
+ tco->prealloc, tco->flags, tco->errp);
174
.aiocb_size = sizeof(NvmeFlushAIOCB),
112
aio_wait_kick();
175
.cancel_async = nvme_flush_cancel,
113
}
176
- .get_aio_context = nvme_get_aio_context,
114
177
};
115
int bdrv_truncate(BdrvChild *child, int64_t offset, bool exact,
178
116
- PreallocMode prealloc, Error **errp)
179
static void nvme_do_flush(NvmeFlushAIOCB *iocb);
117
+ PreallocMode prealloc, BdrvRequestFlags flags, Error **errp)
180
@@ -XXX,XX +XXX,XX @@ static void nvme_format_cancel(BlockAIOCB *aiocb)
118
{
181
static const AIOCBInfo nvme_format_aiocb_info = {
119
Coroutine *co;
182
.aiocb_size = sizeof(NvmeFormatAIOCB),
120
TruncateCo tco = {
183
.cancel_async = nvme_format_cancel,
121
@@ -XXX,XX +XXX,XX @@ int bdrv_truncate(BdrvChild *child, int64_t offset, bool exact,
184
- .get_aio_context = nvme_get_aio_context,
122
.offset = offset,
185
};
123
.exact = exact,
186
124
.prealloc = prealloc,
187
static void nvme_format_set(NvmeNamespace *ns, uint8_t lbaf, uint8_t mset,
125
+ .flags = flags,
188
diff --git a/softmmu/dma-helpers.c b/softmmu/dma-helpers.c
126
.errp = errp,
189
index XXXXXXX..XXXXXXX 100644
127
.ret = NOT_DONE,
190
--- a/softmmu/dma-helpers.c
128
};
191
+++ b/softmmu/dma-helpers.c
129
diff --git a/block/parallels.c b/block/parallels.c
192
@@ -XXX,XX +XXX,XX @@ static void dma_aio_cancel(BlockAIOCB *acb)
130
index XXXXXXX..XXXXXXX 100644
131
--- a/block/parallels.c
132
+++ b/block/parallels.c
133
@@ -XXX,XX +XXX,XX @@ static int64_t allocate_clusters(BlockDriverState *bs, int64_t sector_num,
134
} else {
135
ret = bdrv_truncate(bs->file,
136
(s->data_end + space) << BDRV_SECTOR_BITS,
137
- false, PREALLOC_MODE_OFF, NULL);
138
+ false, PREALLOC_MODE_OFF, 0, NULL);
139
}
140
if (ret < 0) {
141
return ret;
142
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn parallels_co_check(BlockDriverState *bs,
143
* That means we have to pass exact=true.
144
*/
145
ret = bdrv_truncate(bs->file, res->image_end_offset, true,
146
- PREALLOC_MODE_OFF, &local_err);
147
+ PREALLOC_MODE_OFF, 0, &local_err);
148
if (ret < 0) {
149
error_report_err(local_err);
150
res->check_errors++;
151
@@ -XXX,XX +XXX,XX @@ static void parallels_close(BlockDriverState *bs)
152
153
/* errors are ignored, so we might as well pass exact=true */
154
bdrv_truncate(bs->file, s->data_end << BDRV_SECTOR_BITS, true,
155
- PREALLOC_MODE_OFF, NULL);
156
+ PREALLOC_MODE_OFF, 0, NULL);
157
}
193
}
158
194
}
159
g_free(s->bat_dirty_bmap);
195
160
diff --git a/block/qcow.c b/block/qcow.c
196
-static AioContext *dma_get_aio_context(BlockAIOCB *acb)
161
index XXXXXXX..XXXXXXX 100644
197
-{
162
--- a/block/qcow.c
198
- DMAAIOCB *dbs = container_of(acb, DMAAIOCB, common);
163
+++ b/block/qcow.c
199
-
164
@@ -XXX,XX +XXX,XX @@ static int get_cluster_offset(BlockDriverState *bs,
200
- return dbs->ctx;
165
return -E2BIG;
201
-}
166
}
202
-
167
ret = bdrv_truncate(bs->file, cluster_offset + s->cluster_size,
203
static const AIOCBInfo dma_aiocb_info = {
168
- false, PREALLOC_MODE_OFF, NULL);
204
.aiocb_size = sizeof(DMAAIOCB),
169
+ false, PREALLOC_MODE_OFF, 0, NULL);
205
.cancel_async = dma_aio_cancel,
170
if (ret < 0) {
206
- .get_aio_context = dma_get_aio_context,
171
return ret;
207
};
172
}
208
173
@@ -XXX,XX +XXX,XX @@ static int qcow_make_empty(BlockDriverState *bs)
209
BlockAIOCB *dma_blk_io(AioContext *ctx,
174
l1_length) < 0)
210
diff --git a/util/thread-pool.c b/util/thread-pool.c
175
return -1;
211
index XXXXXXX..XXXXXXX 100644
176
ret = bdrv_truncate(bs->file, s->l1_table_offset + l1_length, false,
212
--- a/util/thread-pool.c
177
- PREALLOC_MODE_OFF, NULL);
213
+++ b/util/thread-pool.c
178
+ PREALLOC_MODE_OFF, 0, NULL);
214
@@ -XXX,XX +XXX,XX @@ static void thread_pool_cancel(BlockAIOCB *acb)
179
if (ret < 0)
215
180
return ret;
216
}
181
217
182
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
218
-static AioContext *thread_pool_get_aio_context(BlockAIOCB *acb)
183
index XXXXXXX..XXXXXXX 100644
219
-{
184
--- a/block/qcow2-refcount.c
220
- ThreadPoolElement *elem = (ThreadPoolElement *)acb;
185
+++ b/block/qcow2-refcount.c
221
- ThreadPool *pool = elem->pool;
186
@@ -XXX,XX +XXX,XX @@ static int check_refblocks(BlockDriverState *bs, BdrvCheckResult *res,
222
- return pool->ctx;
187
}
223
-}
188
224
-
189
ret = bdrv_truncate(bs->file, offset + s->cluster_size, false,
225
static const AIOCBInfo thread_pool_aiocb_info = {
190
- PREALLOC_MODE_OFF, &local_err);
226
.aiocb_size = sizeof(ThreadPoolElement),
191
+ PREALLOC_MODE_OFF, 0, &local_err);
227
.cancel_async = thread_pool_cancel,
192
if (ret < 0) {
228
- .get_aio_context = thread_pool_get_aio_context,
193
error_report_err(local_err);
229
};
194
goto resize_fail;
230
195
diff --git a/block/qcow2.c b/block/qcow2.c
231
BlockAIOCB *thread_pool_submit_aio(ThreadPoolFunc *func, void *arg,
196
index XXXXXXX..XXXXXXX 100644
197
--- a/block/qcow2.c
198
+++ b/block/qcow2.c
199
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset,
200
mode = PREALLOC_MODE_OFF;
201
}
202
ret = bdrv_co_truncate(s->data_file, host_offset + cur_bytes, false,
203
- mode, errp);
204
+ mode, 0, errp);
205
if (ret < 0) {
206
return ret;
207
}
208
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
209
* always fulfilled, so there is no need to pass it on.)
210
*/
211
bdrv_co_truncate(bs->file, (last_cluster + 1) * s->cluster_size,
212
- false, PREALLOC_MODE_OFF, &local_err);
213
+ false, PREALLOC_MODE_OFF, 0, &local_err);
214
if (local_err) {
215
warn_reportf_err(local_err,
216
"Failed to truncate the tail of the image: ");
217
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
218
* file should be resized to the exact target size, too,
219
* so we pass @exact here.
220
*/
221
- ret = bdrv_co_truncate(s->data_file, offset, exact, prealloc, errp);
222
+ ret = bdrv_co_truncate(s->data_file, offset, exact, prealloc, 0,
223
+ errp);
224
if (ret < 0) {
225
goto fail;
226
}
227
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
228
new_file_size = allocation_start +
229
nb_new_data_clusters * s->cluster_size;
230
/* Image file grows, so @exact does not matter */
231
- ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc, errp);
232
+ ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc, 0,
233
+ errp);
234
if (ret < 0) {
235
error_prepend(errp, "Failed to resize underlying file: ");
236
qcow2_free_clusters(bs, allocation_start,
237
@@ -XXX,XX +XXX,XX @@ qcow2_co_pwritev_compressed_part(BlockDriverState *bs,
238
if (len < 0) {
239
return len;
240
}
241
- return bdrv_co_truncate(bs->file, len, false, PREALLOC_MODE_OFF, NULL);
242
+ return bdrv_co_truncate(bs->file, len, false, PREALLOC_MODE_OFF, 0,
243
+ NULL);
244
}
245
246
if (offset_into_cluster(s, offset)) {
247
@@ -XXX,XX +XXX,XX @@ static int make_completely_empty(BlockDriverState *bs)
248
}
249
250
ret = bdrv_truncate(bs->file, (3 + l1_clusters) * s->cluster_size, false,
251
- PREALLOC_MODE_OFF, &local_err);
252
+ PREALLOC_MODE_OFF, 0, &local_err);
253
if (ret < 0) {
254
error_report_err(local_err);
255
goto fail;
256
diff --git a/block/raw-format.c b/block/raw-format.c
257
index XXXXXXX..XXXXXXX 100644
258
--- a/block/raw-format.c
259
+++ b/block/raw-format.c
260
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
261
262
s->size = offset;
263
offset += s->offset;
264
- return bdrv_co_truncate(bs->file, offset, exact, prealloc, errp);
265
+ return bdrv_co_truncate(bs->file, offset, exact, prealloc, 0, errp);
266
}
267
268
static void raw_eject(BlockDriverState *bs, bool eject_flag)
269
diff --git a/block/vhdx-log.c b/block/vhdx-log.c
270
index XXXXXXX..XXXXXXX 100644
271
--- a/block/vhdx-log.c
272
+++ b/block/vhdx-log.c
273
@@ -XXX,XX +XXX,XX @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s,
274
goto exit;
275
}
276
ret = bdrv_truncate(bs->file, new_file_size, false,
277
- PREALLOC_MODE_OFF, NULL);
278
+ PREALLOC_MODE_OFF, 0, NULL);
279
if (ret < 0) {
280
goto exit;
281
}
282
diff --git a/block/vhdx.c b/block/vhdx.c
283
index XXXXXXX..XXXXXXX 100644
284
--- a/block/vhdx.c
285
+++ b/block/vhdx.c
286
@@ -XXX,XX +XXX,XX @@ static int vhdx_allocate_block(BlockDriverState *bs, BDRVVHDXState *s,
287
}
288
289
return bdrv_truncate(bs->file, *new_offset + s->block_size, false,
290
- PREALLOC_MODE_OFF, NULL);
291
+ PREALLOC_MODE_OFF, 0, NULL);
292
}
293
294
/*
295
diff --git a/block/vmdk.c b/block/vmdk.c
296
index XXXXXXX..XXXXXXX 100644
297
--- a/block/vmdk.c
298
+++ b/block/vmdk.c
299
@@ -XXX,XX +XXX,XX @@ vmdk_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
300
}
301
length = QEMU_ALIGN_UP(length, BDRV_SECTOR_SIZE);
302
ret = bdrv_truncate(s->extents[i].file, length, false,
303
- PREALLOC_MODE_OFF, NULL);
304
+ PREALLOC_MODE_OFF, 0, NULL);
305
if (ret < 0) {
306
return ret;
307
}
308
diff --git a/tests/test-block-iothread.c b/tests/test-block-iothread.c
309
index XXXXXXX..XXXXXXX 100644
310
--- a/tests/test-block-iothread.c
311
+++ b/tests/test-block-iothread.c
312
@@ -XXX,XX +XXX,XX @@ static void test_sync_op_truncate(BdrvChild *c)
313
int ret;
314
315
/* Normal success path */
316
- ret = bdrv_truncate(c, 65536, false, PREALLOC_MODE_OFF, NULL);
317
+ ret = bdrv_truncate(c, 65536, false, PREALLOC_MODE_OFF, 0, NULL);
318
g_assert_cmpint(ret, ==, 0);
319
320
/* Early error: Negative offset */
321
- ret = bdrv_truncate(c, -2, false, PREALLOC_MODE_OFF, NULL);
322
+ ret = bdrv_truncate(c, -2, false, PREALLOC_MODE_OFF, 0, NULL);
323
g_assert_cmpint(ret, ==, -EINVAL);
324
325
/* Error: Read-only image */
326
c->bs->read_only = true;
327
c->bs->open_flags &= ~BDRV_O_RDWR;
328
329
- ret = bdrv_truncate(c, 65536, false, PREALLOC_MODE_OFF, NULL);
330
+ ret = bdrv_truncate(c, 65536, false, PREALLOC_MODE_OFF, 0, NULL);
331
g_assert_cmpint(ret, ==, -EACCES);
332
333
c->bs->read_only = false;
334
--
232
--
335
2.25.3
233
2.41.0
336
337
diff view generated by jsdifflib
1
If BDRV_REQ_ZERO_WRITE is set and we're extending the image, calling
1
From: Stefan Hajnoczi <stefanha@redhat.com>
2
qcow2_cluster_zeroize() with flags=0 does the right thing: It doesn't
3
undo any previous preallocation, but just adds the zero flag to all
4
relevant L2 entries. If an external data file is in use, a write_zeroes
5
request to the data file is made instead.
6
2
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
3
Switch blk_aio_*() APIs over to multi-queue by using
8
Message-Id: <20200424125448.63318-5-kwolf@redhat.com>
4
qemu_get_current_aio_context() instead of blk_get_aio_context(). This
9
Reviewed-by: Eric Blake <eblake@redhat.com>
5
change will allow devices to process I/O in multiple IOThreads in the
10
Reviewed-by: Max Reitz <mreitz@redhat.com>
6
future.
7
8
I audited existing blk_aio_*() callers:
9
- migration/block.c: blk_mig_lock() protects the data accessed by the
10
completion callback.
11
- The remaining emulated devices and exports run with
12
qemu_get_aio_context() == blk_get_aio_context().
13
14
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
15
Message-ID: <20230823235938.1398382-3-stefanha@redhat.com>
16
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
18
---
13
block/qcow2-cluster.c | 2 +-
19
block/block-backend.c | 6 +++---
14
block/qcow2.c | 34 ++++++++++++++++++++++++++++++++++
20
1 file changed, 3 insertions(+), 3 deletions(-)
15
2 files changed, 35 insertions(+), 1 deletion(-)
16
21
17
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
22
diff --git a/block/block-backend.c b/block/block-backend.c
18
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
19
--- a/block/qcow2-cluster.c
24
--- a/block/block-backend.c
20
+++ b/block/qcow2-cluster.c
25
+++ b/block/block-backend.c
21
@@ -XXX,XX +XXX,XX @@ int qcow2_cluster_zeroize(BlockDriverState *bs, uint64_t offset,
26
@@ -XXX,XX +XXX,XX @@ BlockAIOCB *blk_abort_aio_request(BlockBackend *blk,
22
/* Caller must pass aligned values, except at image end */
27
acb->blk = blk;
23
assert(QEMU_IS_ALIGNED(offset, s->cluster_size));
28
acb->ret = ret;
24
assert(QEMU_IS_ALIGNED(end_offset, s->cluster_size) ||
29
25
- end_offset == bs->total_sectors << BDRV_SECTOR_BITS);
30
- replay_bh_schedule_oneshot_event(blk_get_aio_context(blk),
26
+ end_offset >= bs->total_sectors << BDRV_SECTOR_BITS);
31
+ replay_bh_schedule_oneshot_event(qemu_get_current_aio_context(),
27
32
error_callback_bh, acb);
28
/* The zero flag is only supported by version 3 and newer */
33
return &acb->common;
29
if (s->qcow_version < 3) {
34
}
30
diff --git a/block/qcow2.c b/block/qcow2.c
35
@@ -XXX,XX +XXX,XX @@ static BlockAIOCB *blk_aio_prwv(BlockBackend *blk, int64_t offset,
31
index XXXXXXX..XXXXXXX 100644
36
acb->has_returned = false;
32
--- a/block/qcow2.c
37
33
+++ b/block/qcow2.c
38
co = qemu_coroutine_create(co_entry, acb);
34
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
39
- aio_co_enter(blk_get_aio_context(blk), co);
35
40
+ aio_co_enter(qemu_get_current_aio_context(), co);
36
bs->supported_zero_flags = header.version >= 3 ?
41
37
BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK : 0;
42
acb->has_returned = true;
38
+ bs->supported_truncate_flags = BDRV_REQ_ZERO_WRITE;
43
if (acb->rwco.ret != NOT_DONE) {
39
44
- replay_bh_schedule_oneshot_event(blk_get_aio_context(blk),
40
/* Repair image if dirty */
45
+ replay_bh_schedule_oneshot_event(qemu_get_current_aio_context(),
41
if (!(flags & (BDRV_O_CHECK | BDRV_O_INACTIVE)) && !bs->read_only &&
46
blk_aio_complete_bh, acb);
42
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
43
g_assert_not_reached();
44
}
47
}
45
48
46
+ if ((flags & BDRV_REQ_ZERO_WRITE) && offset > old_length) {
47
+ uint64_t zero_start = QEMU_ALIGN_UP(old_length, s->cluster_size);
48
+
49
+ /*
50
+ * Use zero clusters as much as we can. qcow2_cluster_zeroize()
51
+ * requires a cluster-aligned start. The end may be unaligned if it is
52
+ * at the end of the image (which it is here).
53
+ */
54
+ ret = qcow2_cluster_zeroize(bs, zero_start, offset - zero_start, 0);
55
+ if (ret < 0) {
56
+ error_setg_errno(errp, -ret, "Failed to zero out new clusters");
57
+ goto fail;
58
+ }
59
+
60
+ /* Write explicit zeros for the unaligned head */
61
+ if (zero_start > old_length) {
62
+ uint64_t len = zero_start - old_length;
63
+ uint8_t *buf = qemu_blockalign0(bs, len);
64
+ QEMUIOVector qiov;
65
+ qemu_iovec_init_buf(&qiov, buf, len);
66
+
67
+ qemu_co_mutex_unlock(&s->lock);
68
+ ret = qcow2_co_pwritev_part(bs, old_length, len, &qiov, 0, 0);
69
+ qemu_co_mutex_lock(&s->lock);
70
+
71
+ qemu_vfree(buf);
72
+ if (ret < 0) {
73
+ error_setg_errno(errp, -ret, "Failed to zero out the new area");
74
+ goto fail;
75
+ }
76
+ }
77
+ }
78
+
79
if (prealloc != PREALLOC_MODE_OFF) {
80
/* Flush metadata before actually changing the image size */
81
ret = qcow2_write_caches(bs);
82
--
49
--
83
2.25.3
50
2.41.0
84
85
diff view generated by jsdifflib
1
Now that node level interface bdrv_truncate() supports passing request
1
From: Stefan Hajnoczi <stefanha@redhat.com>
2
flags to the block driver, expose this on the BlockBackend level, too.
3
2
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
3
Process zoned requests in the current thread's AioContext instead of in
5
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
4
the BlockBackend's AioContext.
6
Reviewed-by: Alberto Garcia <berto@igalia.com>
5
7
Reviewed-by: Max Reitz <mreitz@redhat.com>
6
There is no need to use the BlockBackend's AioContext thanks to CoMutex
8
Message-Id: <20200424125448.63318-4-kwolf@redhat.com>
7
bs->wps->colock, which protects zone metadata.
8
9
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
10
Message-ID: <20230823235938.1398382-4-stefanha@redhat.com>
11
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
13
---
11
include/sysemu/block-backend.h | 2 +-
14
block/block-backend.c | 12 ++++++------
12
block.c | 3 ++-
15
1 file changed, 6 insertions(+), 6 deletions(-)
13
block/block-backend.c | 4 ++--
14
block/commit.c | 4 ++--
15
block/crypto.c | 2 +-
16
block/mirror.c | 2 +-
17
block/qcow2.c | 4 ++--
18
block/qed.c | 2 +-
19
block/vdi.c | 2 +-
20
block/vhdx.c | 4 ++--
21
block/vmdk.c | 6 +++---
22
block/vpc.c | 2 +-
23
blockdev.c | 2 +-
24
qemu-img.c | 2 +-
25
qemu-io-cmds.c | 2 +-
26
15 files changed, 22 insertions(+), 21 deletions(-)
27
16
28
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
29
index XXXXXXX..XXXXXXX 100644
30
--- a/include/sysemu/block-backend.h
31
+++ b/include/sysemu/block-backend.h
32
@@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_pwrite_zeroes(BlockBackend *blk, int64_t offset,
33
int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf,
34
int bytes);
35
int blk_truncate(BlockBackend *blk, int64_t offset, bool exact,
36
- PreallocMode prealloc, Error **errp);
37
+ PreallocMode prealloc, BdrvRequestFlags flags, Error **errp);
38
int blk_pdiscard(BlockBackend *blk, int64_t offset, int bytes);
39
int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
40
int64_t pos, int size);
41
diff --git a/block.c b/block.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/block.c
44
+++ b/block.c
45
@@ -XXX,XX +XXX,XX @@ static int64_t create_file_fallback_truncate(BlockBackend *blk,
46
int64_t size;
47
int ret;
48
49
- ret = blk_truncate(blk, minimum_size, false, PREALLOC_MODE_OFF, &local_err);
50
+ ret = blk_truncate(blk, minimum_size, false, PREALLOC_MODE_OFF, 0,
51
+ &local_err);
52
if (ret < 0 && ret != -ENOTSUP) {
53
error_propagate(errp, local_err);
54
return ret;
55
diff --git a/block/block-backend.c b/block/block-backend.c
17
diff --git a/block/block-backend.c b/block/block-backend.c
56
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
57
--- a/block/block-backend.c
19
--- a/block/block-backend.c
58
+++ b/block/block-backend.c
20
+++ b/block/block-backend.c
59
@@ -XXX,XX +XXX,XX @@ int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf,
21
@@ -XXX,XX +XXX,XX @@ BlockAIOCB *blk_aio_zone_report(BlockBackend *blk, int64_t offset,
60
}
22
acb->has_returned = false;
61
23
62
int blk_truncate(BlockBackend *blk, int64_t offset, bool exact,
24
co = qemu_coroutine_create(blk_aio_zone_report_entry, acb);
63
- PreallocMode prealloc, Error **errp)
25
- aio_co_enter(blk_get_aio_context(blk), co);
64
+ PreallocMode prealloc, BdrvRequestFlags flags, Error **errp)
26
+ aio_co_enter(qemu_get_current_aio_context(), co);
65
{
27
66
if (!blk_is_available(blk)) {
28
acb->has_returned = true;
67
error_setg(errp, "No medium inserted");
29
if (acb->rwco.ret != NOT_DONE) {
68
return -ENOMEDIUM;
30
- replay_bh_schedule_oneshot_event(blk_get_aio_context(blk),
31
+ replay_bh_schedule_oneshot_event(qemu_get_current_aio_context(),
32
blk_aio_complete_bh, acb);
69
}
33
}
70
34
71
- return bdrv_truncate(blk->root, offset, exact, prealloc, 0, errp);
35
@@ -XXX,XX +XXX,XX @@ BlockAIOCB *blk_aio_zone_mgmt(BlockBackend *blk, BlockZoneOp op,
72
+ return bdrv_truncate(blk->root, offset, exact, prealloc, flags, errp);
36
acb->has_returned = false;
73
}
37
74
38
co = qemu_coroutine_create(blk_aio_zone_mgmt_entry, acb);
75
int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
39
- aio_co_enter(blk_get_aio_context(blk), co);
76
diff --git a/block/commit.c b/block/commit.c
40
+ aio_co_enter(qemu_get_current_aio_context(), co);
77
index XXXXXXX..XXXXXXX 100644
41
78
--- a/block/commit.c
42
acb->has_returned = true;
79
+++ b/block/commit.c
43
if (acb->rwco.ret != NOT_DONE) {
80
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn commit_run(Job *job, Error **errp)
44
- replay_bh_schedule_oneshot_event(blk_get_aio_context(blk),
45
+ replay_bh_schedule_oneshot_event(qemu_get_current_aio_context(),
46
blk_aio_complete_bh, acb);
81
}
47
}
82
48
83
if (base_len < len) {
49
@@ -XXX,XX +XXX,XX @@ BlockAIOCB *blk_aio_zone_append(BlockBackend *blk, int64_t *offset,
84
- ret = blk_truncate(s->base, len, false, PREALLOC_MODE_OFF, NULL);
50
acb->has_returned = false;
85
+ ret = blk_truncate(s->base, len, false, PREALLOC_MODE_OFF, 0, NULL);
51
86
if (ret) {
52
co = qemu_coroutine_create(blk_aio_zone_append_entry, acb);
87
goto out;
53
- aio_co_enter(blk_get_aio_context(blk), co);
88
}
54
+ aio_co_enter(qemu_get_current_aio_context(), co);
89
@@ -XXX,XX +XXX,XX @@ int bdrv_commit(BlockDriverState *bs)
55
acb->has_returned = true;
90
* grow the backing file image if possible. If not possible,
56
if (acb->rwco.ret != NOT_DONE) {
91
* we must return an error */
57
- replay_bh_schedule_oneshot_event(blk_get_aio_context(blk),
92
if (length > backing_length) {
58
+ replay_bh_schedule_oneshot_event(qemu_get_current_aio_context(),
93
- ret = blk_truncate(backing, length, false, PREALLOC_MODE_OFF,
59
blk_aio_complete_bh, acb);
94
+ ret = blk_truncate(backing, length, false, PREALLOC_MODE_OFF, 0,
95
&local_err);
96
if (ret < 0) {
97
error_report_err(local_err);
98
diff --git a/block/crypto.c b/block/crypto.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/block/crypto.c
101
+++ b/block/crypto.c
102
@@ -XXX,XX +XXX,XX @@ static ssize_t block_crypto_init_func(QCryptoBlock *block,
103
* which will be used by the crypto header
104
*/
105
return blk_truncate(data->blk, data->size + headerlen, false,
106
- data->prealloc, errp);
107
+ data->prealloc, 0, errp);
108
}
109
110
111
diff --git a/block/mirror.c b/block/mirror.c
112
index XXXXXXX..XXXXXXX 100644
113
--- a/block/mirror.c
114
+++ b/block/mirror.c
115
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
116
117
if (s->bdev_length > base_length) {
118
ret = blk_truncate(s->target, s->bdev_length, false,
119
- PREALLOC_MODE_OFF, NULL);
120
+ PREALLOC_MODE_OFF, 0, NULL);
121
if (ret < 0) {
122
goto immediate_exit;
123
}
124
diff --git a/block/qcow2.c b/block/qcow2.c
125
index XXXXXXX..XXXXXXX 100644
126
--- a/block/qcow2.c
127
+++ b/block/qcow2.c
128
@@ -XXX,XX +XXX,XX @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
129
130
/* Okay, now that we have a valid image, let's give it the right size */
131
ret = blk_truncate(blk, qcow2_opts->size, false, qcow2_opts->preallocation,
132
- errp);
133
+ 0, errp);
134
if (ret < 0) {
135
error_prepend(errp, "Could not resize image: ");
136
goto out;
137
@@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
138
* Amending image options should ensure that the image has
139
* exactly the given new values, so pass exact=true here.
140
*/
141
- ret = blk_truncate(blk, new_size, true, PREALLOC_MODE_OFF, errp);
142
+ ret = blk_truncate(blk, new_size, true, PREALLOC_MODE_OFF, 0, errp);
143
blk_unref(blk);
144
if (ret < 0) {
145
return ret;
146
diff --git a/block/qed.c b/block/qed.c
147
index XXXXXXX..XXXXXXX 100644
148
--- a/block/qed.c
149
+++ b/block/qed.c
150
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_co_create(BlockdevCreateOptions *opts,
151
* The QED format associates file length with allocation status,
152
* so a new file (which is empty) must have a length of 0.
153
*/
154
- ret = blk_truncate(blk, 0, true, PREALLOC_MODE_OFF, errp);
155
+ ret = blk_truncate(blk, 0, true, PREALLOC_MODE_OFF, 0, errp);
156
if (ret < 0) {
157
goto out;
158
}
60
}
159
diff --git a/block/vdi.c b/block/vdi.c
61
160
index XXXXXXX..XXXXXXX 100644
161
--- a/block/vdi.c
162
+++ b/block/vdi.c
163
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options,
164
165
if (image_type == VDI_TYPE_STATIC) {
166
ret = blk_truncate(blk, offset + blocks * block_size, false,
167
- PREALLOC_MODE_OFF, errp);
168
+ PREALLOC_MODE_OFF, 0, errp);
169
if (ret < 0) {
170
error_prepend(errp, "Failed to statically allocate file");
171
goto exit;
172
diff --git a/block/vhdx.c b/block/vhdx.c
173
index XXXXXXX..XXXXXXX 100644
174
--- a/block/vhdx.c
175
+++ b/block/vhdx.c
176
@@ -XXX,XX +XXX,XX @@ static int vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s,
177
/* All zeroes, so we can just extend the file - the end of the BAT
178
* is the furthest thing we have written yet */
179
ret = blk_truncate(blk, data_file_offset, false, PREALLOC_MODE_OFF,
180
- errp);
181
+ 0, errp);
182
if (ret < 0) {
183
goto exit;
184
}
185
} else if (type == VHDX_TYPE_FIXED) {
186
ret = blk_truncate(blk, data_file_offset + image_size, false,
187
- PREALLOC_MODE_OFF, errp);
188
+ PREALLOC_MODE_OFF, 0, errp);
189
if (ret < 0) {
190
goto exit;
191
}
192
diff --git a/block/vmdk.c b/block/vmdk.c
193
index XXXXXXX..XXXXXXX 100644
194
--- a/block/vmdk.c
195
+++ b/block/vmdk.c
196
@@ -XXX,XX +XXX,XX @@ static int vmdk_init_extent(BlockBackend *blk,
197
int gd_buf_size;
198
199
if (flat) {
200
- ret = blk_truncate(blk, filesize, false, PREALLOC_MODE_OFF, errp);
201
+ ret = blk_truncate(blk, filesize, false, PREALLOC_MODE_OFF, 0, errp);
202
goto exit;
203
}
204
magic = cpu_to_be32(VMDK4_MAGIC);
205
@@ -XXX,XX +XXX,XX @@ static int vmdk_init_extent(BlockBackend *blk,
206
}
207
208
ret = blk_truncate(blk, le64_to_cpu(header.grain_offset) << 9, false,
209
- PREALLOC_MODE_OFF, errp);
210
+ PREALLOC_MODE_OFF, 0, errp);
211
if (ret < 0) {
212
goto exit;
213
}
214
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vmdk_co_do_create(int64_t size,
215
/* bdrv_pwrite write padding zeros to align to sector, we don't need that
216
* for description file */
217
if (desc_offset == 0) {
218
- ret = blk_truncate(blk, desc_len, false, PREALLOC_MODE_OFF, errp);
219
+ ret = blk_truncate(blk, desc_len, false, PREALLOC_MODE_OFF, 0, errp);
220
if (ret < 0) {
221
goto exit;
222
}
223
diff --git a/block/vpc.c b/block/vpc.c
224
index XXXXXXX..XXXXXXX 100644
225
--- a/block/vpc.c
226
+++ b/block/vpc.c
227
@@ -XXX,XX +XXX,XX @@ static int create_fixed_disk(BlockBackend *blk, uint8_t *buf,
228
/* Add footer to total size */
229
total_size += HEADER_SIZE;
230
231
- ret = blk_truncate(blk, total_size, false, PREALLOC_MODE_OFF, errp);
232
+ ret = blk_truncate(blk, total_size, false, PREALLOC_MODE_OFF, 0, errp);
233
if (ret < 0) {
234
return ret;
235
}
236
diff --git a/blockdev.c b/blockdev.c
237
index XXXXXXX..XXXXXXX 100644
238
--- a/blockdev.c
239
+++ b/blockdev.c
240
@@ -XXX,XX +XXX,XX @@ void qmp_block_resize(bool has_device, const char *device,
241
}
242
243
bdrv_drained_begin(bs);
244
- ret = blk_truncate(blk, size, false, PREALLOC_MODE_OFF, errp);
245
+ ret = blk_truncate(blk, size, false, PREALLOC_MODE_OFF, 0, errp);
246
bdrv_drained_end(bs);
247
248
out:
249
diff --git a/qemu-img.c b/qemu-img.c
250
index XXXXXXX..XXXXXXX 100644
251
--- a/qemu-img.c
252
+++ b/qemu-img.c
253
@@ -XXX,XX +XXX,XX @@ static int img_resize(int argc, char **argv)
254
* resizing, so pass @exact=true. It is of no use to report
255
* success when the image has not actually been resized.
256
*/
257
- ret = blk_truncate(blk, total_size, true, prealloc, &err);
258
+ ret = blk_truncate(blk, total_size, true, prealloc, 0, &err);
259
if (!ret) {
260
qprintf(quiet, "Image resized.\n");
261
} else {
262
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
263
index XXXXXXX..XXXXXXX 100644
264
--- a/qemu-io-cmds.c
265
+++ b/qemu-io-cmds.c
266
@@ -XXX,XX +XXX,XX @@ static int truncate_f(BlockBackend *blk, int argc, char **argv)
267
* exact=true. It is better to err on the "emit more errors" side
268
* than to be overly permissive.
269
*/
270
- ret = blk_truncate(blk, offset, true, PREALLOC_MODE_OFF, &local_err);
271
+ ret = blk_truncate(blk, offset, true, PREALLOC_MODE_OFF, 0, &local_err);
272
if (ret < 0) {
273
error_report_err(local_err);
274
return ret;
275
--
62
--
276
2.25.3
63
2.41.0
277
278
diff view generated by jsdifflib
1
The QMP handler qmp_object_add() and the implementation of --object in
1
From: Fabiano Rosas <farosas@suse.de>
2
qemu-storage-daemon can share most of the code. Currently,
3
qemu-storage-daemon calls qmp_object_add(), but this is not correct
4
because different visitors need to be used.
5
2
6
As a first step towards a fix, make qmp_object_add() a wrapper around a
3
The last call site of this function has been removed by commit
7
new function user_creatable_add_dict() that can get an additional
4
c04d0ab026 ("qemu-img: Let info print block graph").
8
parameter. The handling of "props" is only required for compatibility
9
and not required for the qemu-storage-daemon command line, so it stays
10
in qmp_object_add().
11
5
6
Reviewed-by: Claudio Fontana <cfontana@suse.de>
7
Signed-off-by: Fabiano Rosas <farosas@suse.de>
8
Message-ID: <20230901184605.32260-2-farosas@suse.de>
9
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
11
---
14
include/qom/object_interfaces.h | 12 ++++++++++++
12
include/block/qapi.h | 3 ---
15
qom/object_interfaces.c | 27 +++++++++++++++++++++++++++
13
block/qapi.c | 27 ---------------------------
16
qom/qom-qmp-cmds.c | 24 +-----------------------
14
2 files changed, 30 deletions(-)
17
3 files changed, 40 insertions(+), 23 deletions(-)
18
15
19
diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h
16
diff --git a/include/block/qapi.h b/include/block/qapi.h
20
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
21
--- a/include/qom/object_interfaces.h
18
--- a/include/block/qapi.h
22
+++ b/include/qom/object_interfaces.h
19
+++ b/include/block/qapi.h
23
@@ -XXX,XX +XXX,XX @@ Object *user_creatable_add_type(const char *type, const char *id,
20
@@ -XXX,XX +XXX,XX @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
24
const QDict *qdict,
21
int bdrv_query_snapshot_info_list(BlockDriverState *bs,
25
Visitor *v, Error **errp);
22
SnapshotInfoList **p_list,
26
23
Error **errp);
27
+/**
24
-void bdrv_query_block_node_info(BlockDriverState *bs,
28
+ * user_creatable_add_dict:
25
- BlockNodeInfo **p_info,
29
+ * @qdict: the object definition
26
- Error **errp);
30
+ * @errp: if an error occurs, a pointer to an area to store the error
27
void bdrv_query_image_info(BlockDriverState *bs,
31
+ *
28
ImageInfo **p_info,
32
+ * Create an instance of the user creatable object that is defined by
29
bool flat,
33
+ * @qdict. The object type is taken from the QDict key 'qom-type', its
30
diff --git a/block/qapi.c b/block/qapi.c
34
+ * ID from the key 'id'. The remaining entries in @qdict are used to
35
+ * initialize the object properties.
36
+ */
37
+void user_creatable_add_dict(QDict *qdict, Error **errp);
38
+
39
/**
40
* user_creatable_add_opts:
41
* @opts: the object definition
42
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
43
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
44
--- a/qom/object_interfaces.c
32
--- a/block/qapi.c
45
+++ b/qom/object_interfaces.c
33
+++ b/block/qapi.c
46
@@ -XXX,XX +XXX,XX @@
47
#include "qapi/qmp/qerror.h"
48
#include "qapi/qmp/qjson.h"
49
#include "qapi/qmp/qstring.h"
50
+#include "qapi/qobject-input-visitor.h"
51
#include "qom/object_interfaces.h"
52
#include "qemu/help_option.h"
53
#include "qemu/module.h"
54
@@ -XXX,XX +XXX,XX @@ out:
34
@@ -XXX,XX +XXX,XX @@ out:
55
return obj;
35
aio_context_release(bdrv_get_aio_context(bs));
56
}
36
}
57
37
58
+void user_creatable_add_dict(QDict *qdict, Error **errp)
38
-/**
59
+{
39
- * bdrv_query_block_node_info:
60
+ Visitor *v;
40
- * @bs: block node to examine
61
+ Object *obj;
41
- * @p_info: location to store node information
62
+ g_autofree char *type = NULL;
42
- * @errp: location to store error information
63
+ g_autofree char *id = NULL;
43
- *
64
+
44
- * Store image information about @bs in @p_info.
65
+ type = g_strdup(qdict_get_try_str(qdict, "qom-type"));
45
- *
66
+ if (!type) {
46
- * @p_info will be set only on success. On error, store error in @errp.
67
+ error_setg(errp, QERR_MISSING_PARAMETER, "qom-type");
47
- */
68
+ return;
48
-void bdrv_query_block_node_info(BlockDriverState *bs,
69
+ }
49
- BlockNodeInfo **p_info,
70
+ qdict_del(qdict, "qom-type");
50
- Error **errp)
71
+
51
-{
72
+ id = g_strdup(qdict_get_try_str(qdict, "id"));
52
- BlockNodeInfo *info;
73
+ if (!id) {
53
- ERRP_GUARD();
74
+ error_setg(errp, QERR_MISSING_PARAMETER, "id");
75
+ return;
76
+ }
77
+ qdict_del(qdict, "id");
78
+
79
+ v = qobject_input_visitor_new(QOBJECT(qdict));
80
+ obj = user_creatable_add_type(type, id, qdict, v, errp);
81
+ visit_free(v);
82
+ object_unref(obj);
83
+}
84
85
Object *user_creatable_add_opts(QemuOpts *opts, Error **errp)
86
{
87
diff --git a/qom/qom-qmp-cmds.c b/qom/qom-qmp-cmds.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/qom/qom-qmp-cmds.c
90
+++ b/qom/qom-qmp-cmds.c
91
@@ -XXX,XX +XXX,XX @@
92
#include "qapi/qapi-commands-qom.h"
93
#include "qapi/qmp/qdict.h"
94
#include "qapi/qmp/qerror.h"
95
-#include "qapi/qobject-input-visitor.h"
96
#include "qemu/cutils.h"
97
#include "qom/object_interfaces.h"
98
#include "qom/qom-qobject.h"
99
@@ -XXX,XX +XXX,XX @@ void qmp_object_add(QDict *qdict, QObject **ret_data, Error **errp)
100
{
101
QObject *props;
102
QDict *pdict;
103
- Visitor *v;
104
- Object *obj;
105
- g_autofree char *type = NULL;
106
- g_autofree char *id = NULL;
107
-
54
-
108
- type = g_strdup(qdict_get_try_str(qdict, "qom-type"));
55
- info = g_new0(BlockNodeInfo, 1);
109
- if (!type) {
56
- bdrv_do_query_node_info(bs, info, errp);
110
- error_setg(errp, QERR_MISSING_PARAMETER, "qom-type");
57
- if (*errp) {
58
- qapi_free_BlockNodeInfo(info);
111
- return;
59
- return;
112
- }
60
- }
113
- qdict_del(qdict, "qom-type");
114
-
61
-
115
- id = g_strdup(qdict_get_try_str(qdict, "id"));
62
- *p_info = info;
116
- if (!id) {
63
-}
117
- error_setg(errp, QERR_MISSING_PARAMETER, "id");
64
-
118
- return;
65
/**
119
- }
66
* bdrv_query_image_info:
120
- qdict_del(qdict, "id");
67
* @bs: block node to examine
121
122
props = qdict_get(qdict, "props");
123
if (props) {
124
@@ -XXX,XX +XXX,XX @@ void qmp_object_add(QDict *qdict, QObject **ret_data, Error **errp)
125
qobject_unref(pdict);
126
}
127
128
- v = qobject_input_visitor_new(QOBJECT(qdict));
129
- obj = user_creatable_add_type(type, id, qdict, v, errp);
130
- visit_free(v);
131
- object_unref(obj);
132
+ user_creatable_add_dict(qdict, errp);
133
}
134
135
void qmp_object_del(const char *id, Error **errp)
136
--
68
--
137
2.25.3
69
2.41.0
138
139
diff view generated by jsdifflib
1
The raw format driver can simply forward the flag and let its bs->file
1
From: Fabiano Rosas <farosas@suse.de>
2
child take care of actually providing the zeros.
3
2
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
3
The commit 5d8813593f ("block/qapi: Let bdrv_query_image_info()
5
Reviewed-by: Max Reitz <mreitz@redhat.com>
4
recurse") removed the loop where we set the 'bs0' variable, so now it
6
Reviewed-by: Eric Blake <eblake@redhat.com>
5
is just the same as 'bs'.
7
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
6
8
Message-Id: <20200424125448.63318-6-kwolf@redhat.com>
7
Signed-off-by: Fabiano Rosas <farosas@suse.de>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Message-ID: <20230901184605.32260-3-farosas@suse.de>
10
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
12
---
11
block/raw-format.c | 4 +++-
13
block/qapi.c | 5 ++---
12
1 file changed, 3 insertions(+), 1 deletion(-)
14
1 file changed, 2 insertions(+), 3 deletions(-)
13
15
14
diff --git a/block/raw-format.c b/block/raw-format.c
16
diff --git a/block/qapi.c b/block/qapi.c
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/block/raw-format.c
18
--- a/block/qapi.c
17
+++ b/block/raw-format.c
19
+++ b/block/qapi.c
18
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
20
@@ -XXX,XX +XXX,XX @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
19
21
{
20
s->size = offset;
22
ImageInfo **p_image_info;
21
offset += s->offset;
23
ImageInfo *backing_info;
22
- return bdrv_co_truncate(bs->file, offset, exact, prealloc, 0, errp);
24
- BlockDriverState *bs0, *backing;
23
+ return bdrv_co_truncate(bs->file, offset, exact, prealloc, flags, errp);
25
+ BlockDriverState *backing;
24
}
26
BlockDeviceInfo *info;
25
27
ERRP_GUARD();
26
static void raw_eject(BlockDriverState *bs, bool eject_flag)
28
27
@@ -XXX,XX +XXX,XX @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
29
@@ -XXX,XX +XXX,XX @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
28
bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
30
29
((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) &
31
info->write_threshold = bdrv_write_threshold_get(bs);
30
bs->file->bs->supported_zero_flags);
32
31
+ bs->supported_truncate_flags = bs->file->bs->supported_truncate_flags &
33
- bs0 = bs;
32
+ BDRV_REQ_ZERO_WRITE;
34
p_image_info = &info->image;
33
35
info->backing_file_depth = 0;
34
if (bs->probed && !bdrv_is_read_only(bs)) {
36
35
bdrv_refresh_filename(bs->file->bs);
37
@@ -XXX,XX +XXX,XX @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
38
* Skip automatically inserted nodes that the user isn't aware of for
39
* query-block (blk != NULL), but not for query-named-block-nodes
40
*/
41
- bdrv_query_image_info(bs0, p_image_info, flat, blk != NULL, errp);
42
+ bdrv_query_image_info(bs, p_image_info, flat, blk != NULL, errp);
43
if (*errp) {
44
qapi_free_BlockDeviceInfo(info);
45
return NULL;
36
--
46
--
37
2.25.3
47
2.41.0
38
48
39
49
diff view generated by jsdifflib