1
The following changes since commit 0a301624c2f4ced3331ffd5bce85b4274fe132af:
1
The following changes since commit 344744e148e6e865f5a57e745b02a87e5ea534ad:
2
2
3
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20220208' into staging (2022-02-08 11:40:08 +0000)
3
Merge tag 'dump-pull-request' of https://gitlab.com/marcandre.lureau/qemu into staging (2022-10-26 10:53:49 -0400)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
https://gitlab.com/kmwolf/qemu.git tags/for-upstream
7
git://repo.or.cz/qemu/kevin.git tags/for-upstream
8
8
9
for you to fetch changes up to fdb8541b2e4f6ff60f435fbb5a5e1df20c275a86:
9
for you to fetch changes up to be8da05b5ed8fb546731b9edb997f303f272bad8:
10
10
11
hw/block/fdc-isa: Respect QOM properties when building AML (2022-02-11 17:37:26 +0100)
11
block/block-backend: blk_set_enable_write_cache is IO_CODE (2022-10-27 20:27:37 +0200)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block layer patches
14
Block layer patches
15
15
16
- Fix crash in blockdev-reopen with iothreads
16
- Cleanup bs->backing and bs->file handling
17
- fdc-isa: Respect QOM properties when building AML
17
- Refactor bdrv_try_set_aio_context using transactions
18
- Changes for improved coroutine_fn consistency
19
- vhost-user-blk: fix the resize crash
20
- io_uring: Use of io_uring_register_ring_fd() led to breakage, revert
21
- vvfat: Fix some problems with r/w mode
22
- Code cleanup
23
- MAINTAINERS: Fold "Block QAPI, monitor, ..." into "Block layer core"
18
24
19
----------------------------------------------------------------
25
----------------------------------------------------------------
20
Bernhard Beschow (1):
26
Alberto Faria (20):
21
hw/block/fdc-isa: Respect QOM properties when building AML
27
backup: remove incorrect coroutine_fn annotation
28
block: remove incorrect coroutine_fn annotation
29
monitor: add missing coroutine_fn annotation
30
ssh: add missing coroutine_fn annotation
31
block: add missing coroutine_fn annotation to prototypes
32
coroutine-lock: add missing coroutine_fn annotation to prototypes
33
coroutine-io: add missing coroutine_fn annotation to prototypes
34
block: add missing coroutine_fn annotation to BlockDriverState callbacks
35
qcow2: add coroutine_fn annotation for indirect-called functions
36
commit: switch to *_co_* functions
37
block: switch to *_co_* functions
38
mirror: switch to *_co_* functions
39
parallels: switch to *_co_* functions
40
qcow: switch to *_co_* functions
41
qcow2: switch to *_co_* functions
42
qed: switch to *_co_* functions
43
vdi: switch to *_co_* functions
44
vhdx: switch to *_co_* functions
45
vmdk: switch to *_co_* functions
46
monitor: switch to *_co_* functions
22
47
23
Kevin Wolf (2):
48
Bin Meng (3):
24
block: Lock AioContext for drain_end in blockdev-reopen
49
block: Ignore close() failure in get_tmp_filename()
25
iotests: Test blockdev-reopen with iothreads and throttling
50
block: Refactor get_tmp_filename()
51
block/nfs: Fix 32-bit Windows build
26
52
27
blockdev.c | 11 ++++++++++-
53
Emanuele Giuseppe Esposito (11):
28
hw/block/fdc-isa.c | 11 +++++++----
54
block.c: assert bs->aio_context is written under BQL and drains
29
tests/qemu-iotests/245 | 36 +++++++++++++++++++++++++++++++++---
55
block: use transactions as a replacement of ->{can_}set_aio_context()
30
tests/qemu-iotests/245.out | 4 ++--
56
bdrv_change_aio_context: use hash table instead of list of visited nodes
31
4 files changed, 52 insertions(+), 10 deletions(-)
57
blockjob: implement .change_aio_ctx in child_job
58
block: implement .change_aio_ctx in child_of_bds
59
block-backend: implement .change_aio_ctx in child_root
60
block: use the new _change_ API instead of _can_set_ and _set_
61
block: remove all unused ->can_set_aio_ctx and ->set_aio_ctx callbacks
62
block: rename bdrv_child_try_change_aio_context in bdrv_try_change_aio_context
63
block: remove bdrv_try_set_aio_context and replace it with bdrv_try_change_aio_context
64
block/block-backend: blk_set_enable_write_cache is IO_CODE
65
66
Hervé Poussineau (2):
67
vvfat: allow some writes to bootsector
68
vvfat: allow spaces in file names
69
70
Li Feng (1):
71
vhost-user-blk: fix the resize crash
72
73
Markus Armbruster (1):
74
MAINTAINERS: Fold "Block QAPI, monitor, ..." into "Block layer core"
75
76
Paolo Bonzini (4):
77
blkdebug: add missing coroutine_fn annotation for indirect-called functions
78
qcow: manually add more coroutine_fn annotations
79
qcow2: manually add more coroutine_fn annotations
80
vmdk: manually add more coroutine_fn annotations
81
82
Sam Li (1):
83
block/io_uring: revert "Use io_uring_register_ring_fd() to skip fd operations"
84
85
Vladimir Sementsov-Ogievskiy (15):
86
block: BlockDriver: add .filtered_child_is_backing field
87
block: introduce bdrv_open_file_child() helper
88
block/blklogwrites: don't care to remove bs->file child on failure
89
test-bdrv-graph-mod: update test_parallel_perm_update test case
90
tests-bdrv-drain: bdrv_replace_test driver: declare supports_backing
91
test-bdrv-graph-mod: fix filters to be filters
92
block: document connection between child roles and bs->backing/bs->file
93
block/snapshot: stress that we fallback to primary child
94
Revert "block: Let replace_child_noperm free children"
95
Revert "block: Let replace_child_tran keep indirect pointer"
96
Revert "block: Restructure remove_file_or_backing_child()"
97
Revert "block: Pass BdrvChild ** to replace_child_noperm"
98
block: Manipulate bs->file / bs->backing pointers in .attach/.detach
99
block/snapshot: drop indirection around bdrv_snapshot_fallback_ptr
100
block: refactor bdrv_remove_file_or_backing_child to bdrv_remove_child
101
102
docs/devel/multiple-iothreads.txt | 4 +-
103
block/qcow2.h | 32 +-
104
include/block/block-common.h | 39 ++
105
include/block/block-global-state.h | 18 +-
106
include/block/block-hmp-cmds.h | 2 +-
107
include/block/block-io.h | 5 +-
108
include/block/block_int-common.h | 49 ++-
109
include/monitor/hmp.h | 3 +-
110
include/qemu/coroutine.h | 18 +-
111
block.c | 855 +++++++++++++++++--------------------
112
block/backup.c | 2 +-
113
block/blkdebug.c | 11 +-
114
block/blklogwrites.c | 11 +-
115
block/blkreplay.c | 7 +-
116
block/blkverify.c | 9 +-
117
block/block-backend.c | 76 ++--
118
block/bochs.c | 7 +-
119
block/cloop.c | 7 +-
120
block/commit.c | 3 +-
121
block/copy-before-write.c | 9 +-
122
block/copy-on-read.c | 9 +-
123
block/crypto.c | 11 +-
124
block/dmg.c | 7 +-
125
block/export/export.c | 2 +-
126
block/filter-compress.c | 8 +-
127
block/io.c | 8 +-
128
block/io_uring.c | 13 +-
129
block/mirror.c | 5 +-
130
block/monitor/block-hmp-cmds.c | 2 +-
131
block/nfs.c | 8 +
132
block/parallels.c | 35 +-
133
block/preallocate.c | 9 +-
134
block/qcow.c | 66 +--
135
block/qcow2-bitmap.c | 4 +-
136
block/qcow2-cluster.c | 29 +-
137
block/qcow2-refcount.c | 18 +-
138
block/qcow2-snapshot.c | 6 +-
139
block/qcow2.c | 40 +-
140
block/qed-table.c | 2 +-
141
block/qed.c | 20 +-
142
block/raw-format.c | 4 +-
143
block/replication.c | 8 +-
144
block/snapshot-access.c | 6 +-
145
block/snapshot.c | 59 +--
146
block/ssh.c | 6 +-
147
block/throttle.c | 8 +-
148
block/vdi.c | 24 +-
149
block/vhdx.c | 15 +-
150
block/vmdk.c | 95 ++---
151
block/vpc.c | 7 +-
152
block/vvfat.c | 35 +-
153
blockdev.c | 24 +-
154
blockjob.c | 50 ++-
155
hw/block/vhost-user-blk.c | 4 +
156
job.c | 2 +-
157
tests/unit/test-bdrv-drain.c | 17 +-
158
tests/unit/test-bdrv-graph-mod.c | 104 +++--
159
tests/unit/test-block-iothread.c | 10 +-
160
MAINTAINERS | 12 +-
161
meson.build | 1 -
162
tests/qemu-iotests/051 | 3 +-
163
tests/qemu-iotests/051.out | 2 +-
164
tests/qemu-iotests/051.pc.out | 2 +-
165
63 files changed, 984 insertions(+), 983 deletions(-)
32
166
33
167
diff view generated by jsdifflib
New patch
1
From: Markus Armbruster <armbru@redhat.com>
1
2
3
Section "Block QAPI, monitor, command line" is about the external
4
interfaces we provide for block devices. It covers the relevant QAPI
5
schema parts, monitor and command line code, more or less.
6
7
The section's files are also covered by section "Block layer core",
8
except for the QAPI schema files.
9
10
I haven't acted as maintainer in this area for a long time. Make it
11
official: add the QAPI schema files to section "Block layer core", and
12
delete section "Block QAPI, monitor, command line".
13
14
Cc: Kevin Wolf <kwolf@redhat.com>
15
Cc: Hanna Reitz <hreitz@redhat.com>
16
Signed-off-by: Markus Armbruster <armbru@redhat.com>
17
Message-Id: <20221020120541.80757-1-armbru@redhat.com>
18
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
19
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
20
---
21
MAINTAINERS | 12 ++----------
22
1 file changed, 2 insertions(+), 10 deletions(-)
23
24
diff --git a/MAINTAINERS b/MAINTAINERS
25
index XXXXXXX..XXXXXXX 100644
26
--- a/MAINTAINERS
27
+++ b/MAINTAINERS
28
@@ -XXX,XX +XXX,XX @@ S: Supported
29
F: block*
30
F: block/
31
F: hw/block/
32
+F: qapi/block*.json
33
+F: qapi/transaction.json
34
F: include/block/
35
F: qemu-img*
36
F: docs/tools/qemu-img.rst
37
@@ -XXX,XX +XXX,XX @@ F: include/qemu/co-shared-resource.h
38
T: git https://gitlab.com/jsnow/qemu.git jobs
39
T: git https://gitlab.com/vsementsov/qemu.git block
40
41
-Block QAPI, monitor, command line
42
-M: Markus Armbruster <armbru@redhat.com>
43
-S: Supported
44
-F: blockdev.c
45
-F: blockdev-hmp-cmds.c
46
-F: block/qapi.c
47
-F: qapi/block*.json
48
-F: qapi/transaction.json
49
-T: git https://repo.or.cz/qemu/armbru.git block-next
50
-
51
Compute Express Link
52
M: Ben Widawsky <ben.widawsky@intel.com>
53
M: Jonathan Cameron <jonathan.cameron@huawei.com>
54
--
55
2.37.3
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bin.meng@windriver.com>
1
2
3
The temporary file has been created and is ready for use. Checking
4
return value of close() does not seem useful. The file descriptor
5
is almost certainly closed; see close(2) under "Dealing with error
6
returns from close()".
7
8
Let's simply ignore close() failure here.
9
10
Suggested-by: Markus Armbruster <armbru@redhat.com>
11
Signed-off-by: Bin Meng <bin.meng@windriver.com>
12
Reviewed-by: Markus Armbruster <armbru@redhat.com>
13
Message-Id: <20221010040432.3380478-1-bin.meng@windriver.com>
14
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
15
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
---
17
block.c | 5 +----
18
1 file changed, 1 insertion(+), 4 deletions(-)
19
20
diff --git a/block.c b/block.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/block.c
23
+++ b/block.c
24
@@ -XXX,XX +XXX,XX @@ int get_tmp_filename(char *filename, int size)
25
if (fd < 0) {
26
return -errno;
27
}
28
- if (close(fd) != 0) {
29
- unlink(filename);
30
- return -errno;
31
- }
32
+ close(fd);
33
return 0;
34
#endif
35
}
36
--
37
2.37.3
diff view generated by jsdifflib
New patch
1
1
From: Bin Meng <bin.meng@windriver.com>
2
3
At present there are two callers of get_tmp_filename() and they are
4
inconsistent.
5
6
One does:
7
8
/* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */
9
char *tmp_filename = g_malloc0(PATH_MAX + 1);
10
...
11
ret = get_tmp_filename(tmp_filename, PATH_MAX + 1);
12
13
while the other does:
14
15
s->qcow_filename = g_malloc(PATH_MAX);
16
ret = get_tmp_filename(s->qcow_filename, PATH_MAX);
17
18
As we can see different 'size' arguments are passed. There are also
19
platform specific implementations inside the function, and the use
20
of snprintf is really undesirable.
21
22
The function name is also misleading. It creates a temporary file,
23
not just a filename.
24
25
Refactor this routine by changing its name and signature to:
26
27
char *create_tmp_file(Error **errp)
28
29
and use g_get_tmp_dir() / g_mkstemp() for a consistent implementation.
30
31
While we are here, add some comments to mention that /var/tmp is
32
preferred over /tmp on non-win32 hosts.
33
34
Signed-off-by: Bin Meng <bin.meng@windriver.com>
35
Message-Id: <20221010040432.3380478-2-bin.meng@windriver.com>
36
[kwolf: Fixed incorrect errno negation and iotest 051]
37
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
38
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
39
---
40
include/block/block_int-common.h | 2 +-
41
block.c | 56 +++++++++++++++++---------------
42
block/vvfat.c | 7 ++--
43
tests/qemu-iotests/051 | 3 +-
44
tests/qemu-iotests/051.out | 2 +-
45
tests/qemu-iotests/051.pc.out | 2 +-
46
6 files changed, 38 insertions(+), 34 deletions(-)
47
48
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
49
index XXXXXXX..XXXXXXX 100644
50
--- a/include/block/block_int-common.h
51
+++ b/include/block/block_int-common.h
52
@@ -XXX,XX +XXX,XX @@ static inline BlockDriverState *child_bs(BdrvChild *child)
53
}
54
55
int bdrv_check_request(int64_t offset, int64_t bytes, Error **errp);
56
-int get_tmp_filename(char *filename, int size);
57
+char *create_tmp_file(Error **errp);
58
void bdrv_parse_filename_strip_prefix(const char *filename, const char *prefix,
59
QDict *options);
60
61
diff --git a/block.c b/block.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/block.c
64
+++ b/block.c
65
@@ -XXX,XX +XXX,XX @@ int bdrv_probe_geometry(BlockDriverState *bs, HDGeometry *geo)
66
67
/*
68
* Create a uniquely-named empty temporary file.
69
- * Return 0 upon success, otherwise a negative errno value.
70
+ * Return the actual file name used upon success, otherwise NULL.
71
+ * This string should be freed with g_free() when not needed any longer.
72
+ *
73
+ * Note: creating a temporary file for the caller to (re)open is
74
+ * inherently racy. Use g_file_open_tmp() instead whenever practical.
75
*/
76
-int get_tmp_filename(char *filename, int size)
77
+char *create_tmp_file(Error **errp)
78
{
79
-#ifdef _WIN32
80
- char temp_dir[MAX_PATH];
81
- /* GetTempFileName requires that its output buffer (4th param)
82
- have length MAX_PATH or greater. */
83
- assert(size >= MAX_PATH);
84
- return (GetTempPath(MAX_PATH, temp_dir)
85
- && GetTempFileName(temp_dir, "qem", 0, filename)
86
- ? 0 : -GetLastError());
87
-#else
88
int fd;
89
const char *tmpdir;
90
- tmpdir = getenv("TMPDIR");
91
- if (!tmpdir) {
92
+ g_autofree char *filename = NULL;
93
+
94
+ tmpdir = g_get_tmp_dir();
95
+#ifndef _WIN32
96
+ /*
97
+ * See commit 69bef79 ("block: use /var/tmp instead of /tmp for -snapshot")
98
+ *
99
+ * This function is used to create temporary disk images (like -snapshot),
100
+ * so the files can become very large. /tmp is often a tmpfs where as
101
+ * /var/tmp is usually on a disk, so more appropriate for disk images.
102
+ */
103
+ if (!g_strcmp0(tmpdir, "/tmp")) {
104
tmpdir = "/var/tmp";
105
}
106
- if (snprintf(filename, size, "%s/vl.XXXXXX", tmpdir) >= size) {
107
- return -EOVERFLOW;
108
- }
109
- fd = mkstemp(filename);
110
+#endif
111
+
112
+ filename = g_strdup_printf("%s/vl.XXXXXX", tmpdir);
113
+ fd = g_mkstemp(filename);
114
if (fd < 0) {
115
- return -errno;
116
+ error_setg_errno(errp, errno, "Could not open temporary file '%s'",
117
+ filename);
118
+ return NULL;
119
}
120
close(fd);
121
- return 0;
122
-#endif
123
+
124
+ return g_steal_pointer(&filename);
125
}
126
127
/*
128
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_append_temp_snapshot(BlockDriverState *bs,
129
QDict *snapshot_options,
130
Error **errp)
131
{
132
- /* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */
133
- char *tmp_filename = g_malloc0(PATH_MAX + 1);
134
+ g_autofree char *tmp_filename = NULL;
135
int64_t total_size;
136
QemuOpts *opts = NULL;
137
BlockDriverState *bs_snapshot = NULL;
138
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_append_temp_snapshot(BlockDriverState *bs,
139
}
140
141
/* Create the temporary image */
142
- ret = get_tmp_filename(tmp_filename, PATH_MAX + 1);
143
- if (ret < 0) {
144
- error_setg_errno(errp, -ret, "Could not get temporary filename");
145
+ tmp_filename = create_tmp_file(errp);
146
+ if (!tmp_filename) {
147
goto out;
148
}
149
150
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_append_temp_snapshot(BlockDriverState *bs,
151
152
out:
153
qobject_unref(snapshot_options);
154
- g_free(tmp_filename);
155
return bs_snapshot;
156
}
157
158
diff --git a/block/vvfat.c b/block/vvfat.c
159
index XXXXXXX..XXXXXXX 100644
160
--- a/block/vvfat.c
161
+++ b/block/vvfat.c
162
@@ -XXX,XX +XXX,XX @@ static int enable_write_target(BlockDriverState *bs, Error **errp)
163
164
array_init(&(s->commits), sizeof(commit_t));
165
166
- s->qcow_filename = g_malloc(PATH_MAX);
167
- ret = get_tmp_filename(s->qcow_filename, PATH_MAX);
168
- if (ret < 0) {
169
- error_setg_errno(errp, -ret, "can't create temporary file");
170
+ s->qcow_filename = create_tmp_file(errp);
171
+ if (!s->qcow_filename) {
172
+ ret = -ENOENT;
173
goto err;
174
}
175
176
diff --git a/tests/qemu-iotests/051 b/tests/qemu-iotests/051
177
index XXXXXXX..XXXXXXX 100755
178
--- a/tests/qemu-iotests/051
179
+++ b/tests/qemu-iotests/051
180
@@ -XXX,XX +XXX,XX @@ if [ "${VALGRIND_QEMU_VM}" == "y" ]; then
181
_casenotrun "Valgrind needs a valid TMPDIR for itself"
182
fi
183
VALGRIND_QEMU_VM= \
184
-TMPDIR=/nonexistent run_qemu -drive driver=null-co,snapshot=on
185
+TMPDIR=/nonexistent run_qemu -drive driver=null-co,snapshot=on |
186
+ sed -e "s#'[^']*/vl\.[A-Za-z0-9]\{6\}'#SNAPSHOT_PATH#g"
187
188
# Using snapshot=on together with read-only=on
189
echo "info block" |
190
diff --git a/tests/qemu-iotests/051.out b/tests/qemu-iotests/051.out
191
index XXXXXXX..XXXXXXX 100644
192
--- a/tests/qemu-iotests/051.out
193
+++ b/tests/qemu-iotests/051.out
194
@@ -XXX,XX +XXX,XX @@ wrote 4096/4096 bytes at offset 0
195
read 4096/4096 bytes at offset 0
196
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
197
Testing: -drive driver=null-co,snapshot=on
198
-QEMU_PROG: -drive driver=null-co,snapshot=on: Could not get temporary filename: No such file or directory
199
+QEMU_PROG: -drive driver=null-co,snapshot=on: Could not open temporary file SNAPSHOT_PATH: No such file or directory
200
201
Testing: -drive file=TEST_DIR/t.qcow2,snapshot=on,read-only=on,if=none,id=drive0
202
QEMU X.Y.Z monitor - type 'help' for more information
203
diff --git a/tests/qemu-iotests/051.pc.out b/tests/qemu-iotests/051.pc.out
204
index XXXXXXX..XXXXXXX 100644
205
--- a/tests/qemu-iotests/051.pc.out
206
+++ b/tests/qemu-iotests/051.pc.out
207
@@ -XXX,XX +XXX,XX @@ wrote 4096/4096 bytes at offset 0
208
read 4096/4096 bytes at offset 0
209
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
210
Testing: -drive driver=null-co,snapshot=on
211
-QEMU_PROG: -drive driver=null-co,snapshot=on: Could not get temporary filename: No such file or directory
212
+QEMU_PROG: -drive driver=null-co,snapshot=on: Could not open temporary file SNAPSHOT_PATH: No such file or directory
213
214
Testing: -drive file=TEST_DIR/t.qcow2,snapshot=on,read-only=on,if=none,id=drive0
215
QEMU X.Y.Z monitor - type 'help' for more information
216
--
217
2.37.3
diff view generated by jsdifflib
New patch
1
From: Hervé Poussineau <hpoussin@reactos.org>
1
2
3
'reserved1' field in bootsector is used to mark volume dirty, or need to verify.
4
Allow writes to bootsector which only changes the 'reserved1' field.
5
6
This fixes I/O errors on Windows guests.
7
8
Resolves: https://bugs.launchpad.net/qemu/+bug/1889421
9
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
10
Message-Id: <20221010175511.3414357-2-hpoussin@reactos.org>
11
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
14
block/vvfat.c | 26 +++++++++++++++++++++++++-
15
1 file changed, 25 insertions(+), 1 deletion(-)
16
17
diff --git a/block/vvfat.c b/block/vvfat.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/block/vvfat.c
20
+++ b/block/vvfat.c
21
@@ -XXX,XX +XXX,XX @@ DLOG(checkpoint());
22
23
vvfat_close_current_file(s);
24
25
+ if (sector_num == s->offset_to_bootsector && nb_sectors == 1) {
26
+ /*
27
+ * Write on bootsector. Allow only changing the reserved1 field,
28
+ * used to mark volume dirtiness
29
+ */
30
+ unsigned char *bootsector = s->first_sectors
31
+ + s->offset_to_bootsector * 0x200;
32
+ /*
33
+ * LATER TODO: if FAT32, this is wrong (see init_directories(),
34
+ * which always creates a FAT16 bootsector)
35
+ */
36
+ const int reserved1_offset = offsetof(bootsector_t, u.fat16.reserved1);
37
+
38
+ for (i = 0; i < 0x200; i++) {
39
+ if (i != reserved1_offset && bootsector[i] != buf[i]) {
40
+ fprintf(stderr, "Tried to write to protected bootsector\n");
41
+ return -1;
42
+ }
43
+ }
44
+
45
+ /* Update bootsector with the only updatable byte, and return success */
46
+ bootsector[reserved1_offset] = buf[reserved1_offset];
47
+ return 0;
48
+ }
49
+
50
/*
51
* Some sanity checks:
52
* - do not allow writing to the boot sector
53
*/
54
-
55
if (sector_num < s->offset_to_fat)
56
return -1;
57
58
--
59
2.37.3
60
61
diff view generated by jsdifflib
New patch
1
From: Hervé Poussineau <hpoussin@reactos.org>
1
2
3
In R/W mode, files with spaces were never created on host side.
4
5
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1176
6
Fixes: c79e243ed67683d6d06692bd7040f7394da178b0
7
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
10
Message-Id: <20221010175511.3414357-3-hpoussin@reactos.org>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
13
block/vvfat.c | 2 +-
14
1 file changed, 1 insertion(+), 1 deletion(-)
15
16
diff --git a/block/vvfat.c b/block/vvfat.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/block/vvfat.c
19
+++ b/block/vvfat.c
20
@@ -XXX,XX +XXX,XX @@ static bool valid_filename(const unsigned char *name)
21
(c >= 'A' && c <= 'Z') ||
22
(c >= 'a' && c <= 'z') ||
23
c > 127 ||
24
- strchr("$%'-_@~`!(){}^#&.+,;=[]", c) != NULL))
25
+ strchr(" $%'-_@~`!(){}^#&.+,;=[]", c) != NULL))
26
{
27
return false;
28
}
29
--
30
2.37.3
31
32
diff view generated by jsdifflib
New patch
1
From: Sam Li <faithilikerun@gmail.com>
1
2
3
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1193
4
5
The commit "Use io_uring_register_ring_fd() to skip fd operations" broke
6
when booting a guest with iothread and io_uring. That is because the
7
io_uring_register_ring_fd() call is made from the main thread instead of
8
IOThread where io_uring_submit() is called. It can not be guaranteed
9
to register the ring fd in the correct thread or unregister the same ring
10
fd if the IOThread is disabled. This optimization is not critical so we
11
will revert previous commit.
12
13
This reverts commit e2848bc574fe2715c694bf8fe9a1ba7f78a1125a
14
and 77e3f038af1764983087e3551a0fde9951952c4d.
15
16
Cc: qemu-stable@nongnu.org
17
Signed-off-by: Sam Li <faithilikerun@gmail.com>
18
Message-Id: <20220924144815.5591-1-faithilikerun@gmail.com>
19
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
20
Tested-by: Dario Faggioli <dfaggioli@suse.com>
21
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
22
---
23
block/io_uring.c | 13 +------------
24
meson.build | 1 -
25
2 files changed, 1 insertion(+), 13 deletions(-)
26
27
diff --git a/block/io_uring.c b/block/io_uring.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/block/io_uring.c
30
+++ b/block/io_uring.c
31
@@ -XXX,XX +XXX,XX @@
32
#include "qemu/osdep.h"
33
#include <liburing.h>
34
#include "block/aio.h"
35
-#include "qemu/error-report.h"
36
#include "qemu/queue.h"
37
#include "block/block.h"
38
#include "block/raw-aio.h"
39
@@ -XXX,XX +XXX,XX @@
40
#include "qapi/error.h"
41
#include "trace.h"
42
43
-
44
/* io_uring ring size */
45
#define MAX_ENTRIES 128
46
47
@@ -XXX,XX +XXX,XX @@ LuringState *luring_init(Error **errp)
48
}
49
50
ioq_init(&s->io_q);
51
-#ifdef CONFIG_LIBURING_REGISTER_RING_FD
52
- if (io_uring_register_ring_fd(&s->ring) < 0) {
53
- /*
54
- * Only warn about this error: we will fallback to the non-optimized
55
- * io_uring operations.
56
- */
57
- warn_report("failed to register linux io_uring ring file descriptor");
58
- }
59
-#endif
60
-
61
return s;
62
+
63
}
64
65
void luring_cleanup(LuringState *s)
66
diff --git a/meson.build b/meson.build
67
index XXXXXXX..XXXXXXX 100644
68
--- a/meson.build
69
+++ b/meson.build
70
@@ -XXX,XX +XXX,XX @@ config_host_data.set('CONFIG_LIBNFS', libnfs.found())
71
config_host_data.set('CONFIG_LIBSSH', libssh.found())
72
config_host_data.set('CONFIG_LINUX_AIO', libaio.found())
73
config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
74
-config_host_data.set('CONFIG_LIBURING_REGISTER_RING_FD', cc.has_function('io_uring_register_ring_fd', prefix: '#include <liburing.h>', dependencies:linux_io_uring))
75
config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
76
config_host_data.set('CONFIG_NUMA', numa.found())
77
config_host_data.set('CONFIG_OPENGL', opengl.found())
78
--
79
2.37.3
diff view generated by jsdifflib
New patch
1
From: Li Feng <fengli@smartx.com>
1
2
3
If the os is not installed and doesn't have the virtio guest driver,
4
the vhost dev isn't started, so the dev->vdev is NULL.
5
6
Reproduce: mount a Win 2019 iso, go into the install ui, then resize
7
the virtio-blk device, qemu crash.
8
9
Signed-off-by: Li Feng <fengli@smartx.com>
10
Message-Id: <20220919121816.3252223-1-fengli@smartx.com>
11
Reviewed-by: Raphael Norwitz <raphael.norwitz@nutanix.com>
12
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
15
hw/block/vhost-user-blk.c | 4 ++++
16
1 file changed, 4 insertions(+)
17
18
diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/block/vhost-user-blk.c
21
+++ b/hw/block/vhost-user-blk.c
22
@@ -XXX,XX +XXX,XX @@ static int vhost_user_blk_handle_config_change(struct vhost_dev *dev)
23
VHostUserBlk *s = VHOST_USER_BLK(dev->vdev);
24
Error *local_err = NULL;
25
26
+ if (!dev->started) {
27
+ return 0;
28
+ }
29
+
30
ret = vhost_dev_get_config(dev, (uint8_t *)&blkcfg,
31
vdev->config_len, &local_err);
32
if (ret < 0) {
33
--
34
2.37.3
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
1
2
3
Unfortunately not all filters use .file child as filtered child. Two
4
exclusions are mirror_top and commit_top. Happily they both are private
5
filters. Bad thing is that this inconsistency is observable through qmp
6
commands query-block / query-named-block-nodes. So, could we just
7
change mirror_top and commit_top to use file child as all other filter
8
driver is an open question. Probably, we could do that with some kind
9
of deprecation period, but how to warn users during it?
10
11
For now, let's just add a field so we can distinguish them in generic
12
code, it will be used in further commits.
13
14
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
15
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
16
Message-Id: <20220726201134.924743-2-vsementsov@yandex-team.ru>
17
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
18
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
19
---
20
include/block/block_int-common.h | 13 +++++++++++++
21
block/commit.c | 1 +
22
block/mirror.c | 1 +
23
3 files changed, 15 insertions(+)
24
25
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
26
index XXXXXXX..XXXXXXX 100644
27
--- a/include/block/block_int-common.h
28
+++ b/include/block/block_int-common.h
29
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
30
* (And this filtered child must then be bs->file or bs->backing.)
31
*/
32
bool is_filter;
33
+ /*
34
+ * Only make sense for filter drivers, for others must be false.
35
+ * If true, filtered child is bs->backing. Otherwise it's bs->file.
36
+ * Only two internal filters use bs->backing as filtered child and has this
37
+ * field set to true: mirror_top and commit_top.
38
+ *
39
+ * Never create any more such filters!
40
+ *
41
+ * TODO: imagine how to deprecate this behavior and make all filters work
42
+ * similarly using bs->file as filtered child.
43
+ */
44
+ bool filtered_child_is_backing;
45
+
46
/*
47
* Set to true if the BlockDriver is a format driver. Format nodes
48
* generally do not expect their children to be other format nodes
49
diff --git a/block/commit.c b/block/commit.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/block/commit.c
52
+++ b/block/commit.c
53
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_commit_top = {
54
.bdrv_child_perm = bdrv_commit_top_child_perm,
55
56
.is_filter = true,
57
+ .filtered_child_is_backing = true,
58
};
59
60
void commit_start(const char *job_id, BlockDriverState *bs,
61
diff --git a/block/mirror.c b/block/mirror.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/block/mirror.c
64
+++ b/block/mirror.c
65
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_mirror_top = {
66
.bdrv_child_perm = bdrv_mirror_top_child_perm,
67
68
.is_filter = true,
69
+ .filtered_child_is_backing = true,
70
};
71
72
static BlockJob *mirror_start_job(
73
--
74
2.37.3
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
1
2
3
Almost all drivers call bdrv_open_child() similarly. Let's create a
4
helper for this.
5
6
The only not updated drivers that call bdrv_open_child() to set
7
bs->file are raw-format and snapshot-access:
8
raw-format sometimes want to have filtered child but
9
don't set drv->is_filter to true.
10
snapshot-access wants only DATA | PRIMARY
11
12
Possibly we should implement drv->is_filter_func() handler, to consider
13
raw-format as filter when it works as filter.. But it's another story.
14
15
Note also, that we decrease assignments to bs->file in code: it helps
16
us restrict modifying this field in further commit.
17
18
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
19
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
20
Message-Id: <20220726201134.924743-3-vsementsov@yandex-team.ru>
21
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
22
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
23
---
24
include/block/block-global-state.h | 3 +++
25
block.c | 21 +++++++++++++++++++++
26
block/blkdebug.c | 9 +++------
27
block/blklogwrites.c | 7 ++-----
28
block/blkreplay.c | 7 ++-----
29
block/blkverify.c | 9 +++------
30
block/bochs.c | 7 +++----
31
block/cloop.c | 7 +++----
32
block/copy-before-write.c | 9 ++++-----
33
block/copy-on-read.c | 9 ++++-----
34
block/crypto.c | 11 ++++++-----
35
block/dmg.c | 7 +++----
36
block/filter-compress.c | 8 +++-----
37
block/parallels.c | 7 +++----
38
block/preallocate.c | 9 ++++-----
39
block/qcow.c | 6 ++----
40
block/qcow2.c | 8 ++++----
41
block/qed.c | 8 ++++----
42
block/replication.c | 8 +++-----
43
block/throttle.c | 8 +++-----
44
block/vdi.c | 7 +++----
45
block/vhdx.c | 7 +++----
46
block/vmdk.c | 7 +++----
47
block/vpc.c | 7 +++----
48
24 files changed, 95 insertions(+), 101 deletions(-)
49
50
diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h
51
index XXXXXXX..XXXXXXX 100644
52
--- a/include/block/block-global-state.h
53
+++ b/include/block/block-global-state.h
54
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_open_child(const char *filename,
55
const BdrvChildClass *child_class,
56
BdrvChildRole child_role,
57
bool allow_none, Error **errp);
58
+int bdrv_open_file_child(const char *filename,
59
+ QDict *options, const char *bdref_key,
60
+ BlockDriverState *parent, Error **errp);
61
BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp);
62
int bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd,
63
Error **errp);
64
diff --git a/block.c b/block.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/block.c
67
+++ b/block.c
68
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_open_child(const char *filename,
69
errp);
70
}
71
72
+/*
73
+ * Wrapper on bdrv_open_child() for most popular case: open primary child of bs.
74
+ */
75
+int bdrv_open_file_child(const char *filename,
76
+ QDict *options, const char *bdref_key,
77
+ BlockDriverState *parent, Error **errp)
78
+{
79
+ BdrvChildRole role;
80
+
81
+ /* commit_top and mirror_top don't use this function */
82
+ assert(!parent->drv->filtered_child_is_backing);
83
+
84
+ role = parent->drv->is_filter ?
85
+ (BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY) : BDRV_CHILD_IMAGE;
86
+
87
+ parent->file = bdrv_open_child(filename, options, bdref_key, parent,
88
+ &child_of_bds, role, false, errp);
89
+
90
+ return parent->file ? 0 : -EINVAL;
91
+}
92
+
93
/*
94
* TODO Future callers may need to specify parent/child_class in order for
95
* option inheritance to work. Existing callers use it for the root node.
96
diff --git a/block/blkdebug.c b/block/blkdebug.c
97
index XXXXXXX..XXXXXXX 100644
98
--- a/block/blkdebug.c
99
+++ b/block/blkdebug.c
100
@@ -XXX,XX +XXX,XX @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
101
}
102
103
/* Open the image file */
104
- bs->file = bdrv_open_child(qemu_opt_get(opts, "x-image"), options, "image",
105
- bs, &child_of_bds,
106
- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
107
- false, errp);
108
- if (!bs->file) {
109
- ret = -EINVAL;
110
+ ret = bdrv_open_file_child(qemu_opt_get(opts, "x-image"), options, "image",
111
+ bs, errp);
112
+ if (ret < 0) {
113
goto out;
114
}
115
116
diff --git a/block/blklogwrites.c b/block/blklogwrites.c
117
index XXXXXXX..XXXXXXX 100644
118
--- a/block/blklogwrites.c
119
+++ b/block/blklogwrites.c
120
@@ -XXX,XX +XXX,XX @@ static int blk_log_writes_open(BlockDriverState *bs, QDict *options, int flags,
121
}
122
123
/* Open the file */
124
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
125
- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, false,
126
- errp);
127
- if (!bs->file) {
128
- ret = -EINVAL;
129
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
130
+ if (ret < 0) {
131
goto fail;
132
}
133
134
diff --git a/block/blkreplay.c b/block/blkreplay.c
135
index XXXXXXX..XXXXXXX 100644
136
--- a/block/blkreplay.c
137
+++ b/block/blkreplay.c
138
@@ -XXX,XX +XXX,XX @@ static int blkreplay_open(BlockDriverState *bs, QDict *options, int flags,
139
int ret;
140
141
/* Open the image file */
142
- bs->file = bdrv_open_child(NULL, options, "image", bs, &child_of_bds,
143
- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
144
- false, errp);
145
- if (!bs->file) {
146
- ret = -EINVAL;
147
+ ret = bdrv_open_file_child(NULL, options, "image", bs, errp);
148
+ if (ret < 0) {
149
goto fail;
150
}
151
152
diff --git a/block/blkverify.c b/block/blkverify.c
153
index XXXXXXX..XXXXXXX 100644
154
--- a/block/blkverify.c
155
+++ b/block/blkverify.c
156
@@ -XXX,XX +XXX,XX @@ static int blkverify_open(BlockDriverState *bs, QDict *options, int flags,
157
}
158
159
/* Open the raw file */
160
- bs->file = bdrv_open_child(qemu_opt_get(opts, "x-raw"), options, "raw",
161
- bs, &child_of_bds,
162
- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
163
- false, errp);
164
- if (!bs->file) {
165
- ret = -EINVAL;
166
+ ret = bdrv_open_file_child(qemu_opt_get(opts, "x-raw"), options, "raw",
167
+ bs, errp);
168
+ if (ret < 0) {
169
goto fail;
170
}
171
172
diff --git a/block/bochs.c b/block/bochs.c
173
index XXXXXXX..XXXXXXX 100644
174
--- a/block/bochs.c
175
+++ b/block/bochs.c
176
@@ -XXX,XX +XXX,XX @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
177
return ret;
178
}
179
180
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
181
- BDRV_CHILD_IMAGE, false, errp);
182
- if (!bs->file) {
183
- return -EINVAL;
184
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
185
+ if (ret < 0) {
186
+ return ret;
187
}
188
189
ret = bdrv_pread(bs->file, 0, sizeof(bochs), &bochs, 0);
190
diff --git a/block/cloop.c b/block/cloop.c
191
index XXXXXXX..XXXXXXX 100644
192
--- a/block/cloop.c
193
+++ b/block/cloop.c
194
@@ -XXX,XX +XXX,XX @@ static int cloop_open(BlockDriverState *bs, QDict *options, int flags,
195
return ret;
196
}
197
198
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
199
- BDRV_CHILD_IMAGE, false, errp);
200
- if (!bs->file) {
201
- return -EINVAL;
202
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
203
+ if (ret < 0) {
204
+ return ret;
205
}
206
207
/* read header */
208
diff --git a/block/copy-before-write.c b/block/copy-before-write.c
209
index XXXXXXX..XXXXXXX 100644
210
--- a/block/copy-before-write.c
211
+++ b/block/copy-before-write.c
212
@@ -XXX,XX +XXX,XX @@ static int cbw_open(BlockDriverState *bs, QDict *options, int flags,
213
int64_t cluster_size;
214
g_autoptr(BlockdevOptions) full_opts = NULL;
215
BlockdevOptionsCbw *opts;
216
+ int ret;
217
218
full_opts = cbw_parse_options(options, errp);
219
if (!full_opts) {
220
@@ -XXX,XX +XXX,XX @@ static int cbw_open(BlockDriverState *bs, QDict *options, int flags,
221
assert(full_opts->driver == BLOCKDEV_DRIVER_COPY_BEFORE_WRITE);
222
opts = &full_opts->u.copy_before_write;
223
224
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
225
- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
226
- false, errp);
227
- if (!bs->file) {
228
- return -EINVAL;
229
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
230
+ if (ret < 0) {
231
+ return ret;
232
}
233
234
s->target = bdrv_open_child(NULL, options, "target", bs, &child_of_bds,
235
diff --git a/block/copy-on-read.c b/block/copy-on-read.c
236
index XXXXXXX..XXXXXXX 100644
237
--- a/block/copy-on-read.c
238
+++ b/block/copy-on-read.c
239
@@ -XXX,XX +XXX,XX @@ static int cor_open(BlockDriverState *bs, QDict *options, int flags,
240
BDRVStateCOR *state = bs->opaque;
241
/* Find a bottom node name, if any */
242
const char *bottom_node = qdict_get_try_str(options, "bottom");
243
+ int ret;
244
245
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
246
- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
247
- false, errp);
248
- if (!bs->file) {
249
- return -EINVAL;
250
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
251
+ if (ret < 0) {
252
+ return ret;
253
}
254
255
bs->supported_read_flags = BDRV_REQ_PREFETCH;
256
diff --git a/block/crypto.c b/block/crypto.c
257
index XXXXXXX..XXXXXXX 100644
258
--- a/block/crypto.c
259
+++ b/block/crypto.c
260
@@ -XXX,XX +XXX,XX @@ static int block_crypto_open_generic(QCryptoBlockFormat format,
261
{
262
BlockCrypto *crypto = bs->opaque;
263
QemuOpts *opts = NULL;
264
- int ret = -EINVAL;
265
+ int ret;
266
QCryptoBlockOpenOptions *open_opts = NULL;
267
unsigned int cflags = 0;
268
QDict *cryptoopts = NULL;
269
270
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
271
- BDRV_CHILD_IMAGE, false, errp);
272
- if (!bs->file) {
273
- return -EINVAL;
274
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
275
+ if (ret < 0) {
276
+ return ret;
277
}
278
279
bs->supported_write_flags = BDRV_REQ_FUA &
280
@@ -XXX,XX +XXX,XX @@ static int block_crypto_open_generic(QCryptoBlockFormat format,
281
282
opts = qemu_opts_create(opts_spec, NULL, 0, &error_abort);
283
if (!qemu_opts_absorb_qdict(opts, options, errp)) {
284
+ ret = -EINVAL;
285
goto cleanup;
286
}
287
288
@@ -XXX,XX +XXX,XX @@ static int block_crypto_open_generic(QCryptoBlockFormat format,
289
290
open_opts = block_crypto_open_opts_init(cryptoopts, errp);
291
if (!open_opts) {
292
+ ret = -EINVAL;
293
goto cleanup;
294
}
295
296
diff --git a/block/dmg.c b/block/dmg.c
297
index XXXXXXX..XXXXXXX 100644
298
--- a/block/dmg.c
299
+++ b/block/dmg.c
300
@@ -XXX,XX +XXX,XX @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
301
return ret;
302
}
303
304
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
305
- BDRV_CHILD_IMAGE, false, errp);
306
- if (!bs->file) {
307
- return -EINVAL;
308
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
309
+ if (ret < 0) {
310
+ return ret;
311
}
312
313
block_module_load_one("dmg-bz2");
314
diff --git a/block/filter-compress.c b/block/filter-compress.c
315
index XXXXXXX..XXXXXXX 100644
316
--- a/block/filter-compress.c
317
+++ b/block/filter-compress.c
318
@@ -XXX,XX +XXX,XX @@
319
static int compress_open(BlockDriverState *bs, QDict *options, int flags,
320
Error **errp)
321
{
322
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
323
- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
324
- false, errp);
325
- if (!bs->file) {
326
- return -EINVAL;
327
+ int ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
328
+ if (ret < 0) {
329
+ return ret;
330
}
331
332
if (!bs->file->bs->drv || !block_driver_can_compress(bs->file->bs->drv)) {
333
diff --git a/block/parallels.c b/block/parallels.c
334
index XXXXXXX..XXXXXXX 100644
335
--- a/block/parallels.c
336
+++ b/block/parallels.c
337
@@ -XXX,XX +XXX,XX @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
338
Error *local_err = NULL;
339
char *buf;
340
341
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
342
- BDRV_CHILD_IMAGE, false, errp);
343
- if (!bs->file) {
344
- return -EINVAL;
345
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
346
+ if (ret < 0) {
347
+ return ret;
348
}
349
350
ret = bdrv_pread(bs->file, 0, sizeof(ph), &ph, 0);
351
diff --git a/block/preallocate.c b/block/preallocate.c
352
index XXXXXXX..XXXXXXX 100644
353
--- a/block/preallocate.c
354
+++ b/block/preallocate.c
355
@@ -XXX,XX +XXX,XX @@ static int preallocate_open(BlockDriverState *bs, QDict *options, int flags,
356
Error **errp)
357
{
358
BDRVPreallocateState *s = bs->opaque;
359
+ int ret;
360
361
/*
362
* s->data_end and friends should be initialized on permission update.
363
@@ -XXX,XX +XXX,XX @@ static int preallocate_open(BlockDriverState *bs, QDict *options, int flags,
364
*/
365
s->file_end = s->zero_start = s->data_end = -EINVAL;
366
367
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
368
- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
369
- false, errp);
370
- if (!bs->file) {
371
- return -EINVAL;
372
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
373
+ if (ret < 0) {
374
+ return ret;
375
}
376
377
if (!preallocate_absorb_opts(&s->opts, options, bs->file->bs, errp)) {
378
diff --git a/block/qcow.c b/block/qcow.c
379
index XXXXXXX..XXXXXXX 100644
380
--- a/block/qcow.c
381
+++ b/block/qcow.c
382
@@ -XXX,XX +XXX,XX @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
383
qdict_extract_subqdict(options, &encryptopts, "encrypt.");
384
encryptfmt = qdict_get_try_str(encryptopts, "format");
385
386
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
387
- BDRV_CHILD_IMAGE, false, errp);
388
- if (!bs->file) {
389
- ret = -EINVAL;
390
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
391
+ if (ret < 0) {
392
goto fail;
393
}
394
395
diff --git a/block/qcow2.c b/block/qcow2.c
396
index XXXXXXX..XXXXXXX 100644
397
--- a/block/qcow2.c
398
+++ b/block/qcow2.c
399
@@ -XXX,XX +XXX,XX @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
400
.errp = errp,
401
.ret = -EINPROGRESS
402
};
403
+ int ret;
404
405
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
406
- BDRV_CHILD_IMAGE, false, errp);
407
- if (!bs->file) {
408
- return -EINVAL;
409
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
410
+ if (ret < 0) {
411
+ return ret;
412
}
413
414
/* Initialise locks */
415
diff --git a/block/qed.c b/block/qed.c
416
index XXXXXXX..XXXXXXX 100644
417
--- a/block/qed.c
418
+++ b/block/qed.c
419
@@ -XXX,XX +XXX,XX @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
420
.errp = errp,
421
.ret = -EINPROGRESS
422
};
423
+ int ret;
424
425
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
426
- BDRV_CHILD_IMAGE, false, errp);
427
- if (!bs->file) {
428
- return -EINVAL;
429
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
430
+ if (ret < 0) {
431
+ return ret;
432
}
433
434
bdrv_qed_init_state(bs);
435
diff --git a/block/replication.c b/block/replication.c
436
index XXXXXXX..XXXXXXX 100644
437
--- a/block/replication.c
438
+++ b/block/replication.c
439
@@ -XXX,XX +XXX,XX @@ static int replication_open(BlockDriverState *bs, QDict *options,
440
const char *mode;
441
const char *top_id;
442
443
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
444
- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
445
- false, errp);
446
- if (!bs->file) {
447
- return -EINVAL;
448
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
449
+ if (ret < 0) {
450
+ return ret;
451
}
452
453
ret = -EINVAL;
454
diff --git a/block/throttle.c b/block/throttle.c
455
index XXXXXXX..XXXXXXX 100644
456
--- a/block/throttle.c
457
+++ b/block/throttle.c
458
@@ -XXX,XX +XXX,XX @@ static int throttle_open(BlockDriverState *bs, QDict *options,
459
char *group;
460
int ret;
461
462
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
463
- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
464
- false, errp);
465
- if (!bs->file) {
466
- return -EINVAL;
467
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
468
+ if (ret < 0) {
469
+ return ret;
470
}
471
bs->supported_write_flags = bs->file->bs->supported_write_flags |
472
BDRV_REQ_WRITE_UNCHANGED;
473
diff --git a/block/vdi.c b/block/vdi.c
474
index XXXXXXX..XXXXXXX 100644
475
--- a/block/vdi.c
476
+++ b/block/vdi.c
477
@@ -XXX,XX +XXX,XX @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
478
int ret;
479
QemuUUID uuid_link, uuid_parent;
480
481
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
482
- BDRV_CHILD_IMAGE, false, errp);
483
- if (!bs->file) {
484
- return -EINVAL;
485
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
486
+ if (ret < 0) {
487
+ return ret;
488
}
489
490
logout("\n");
491
diff --git a/block/vhdx.c b/block/vhdx.c
492
index XXXXXXX..XXXXXXX 100644
493
--- a/block/vhdx.c
494
+++ b/block/vhdx.c
495
@@ -XXX,XX +XXX,XX @@ static int vhdx_open(BlockDriverState *bs, QDict *options, int flags,
496
uint64_t signature;
497
Error *local_err = NULL;
498
499
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
500
- BDRV_CHILD_IMAGE, false, errp);
501
- if (!bs->file) {
502
- return -EINVAL;
503
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
504
+ if (ret < 0) {
505
+ return ret;
506
}
507
508
s->bat = NULL;
509
diff --git a/block/vmdk.c b/block/vmdk.c
510
index XXXXXXX..XXXXXXX 100644
511
--- a/block/vmdk.c
512
+++ b/block/vmdk.c
513
@@ -XXX,XX +XXX,XX @@ static int vmdk_open(BlockDriverState *bs, QDict *options, int flags,
514
BDRVVmdkState *s = bs->opaque;
515
uint32_t magic;
516
517
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
518
- BDRV_CHILD_IMAGE, false, errp);
519
- if (!bs->file) {
520
- return -EINVAL;
521
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
522
+ if (ret < 0) {
523
+ return ret;
524
}
525
526
buf = vmdk_read_desc(bs->file, 0, errp);
527
diff --git a/block/vpc.c b/block/vpc.c
528
index XXXXXXX..XXXXXXX 100644
529
--- a/block/vpc.c
530
+++ b/block/vpc.c
531
@@ -XXX,XX +XXX,XX @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
532
int ret;
533
int64_t bs_size;
534
535
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
536
- BDRV_CHILD_IMAGE, false, errp);
537
- if (!bs->file) {
538
- return -EINVAL;
539
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
540
+ if (ret < 0) {
541
+ return ret;
542
}
543
544
opts = qemu_opts_create(&vpc_runtime_opts, NULL, 0, &error_abort);
545
--
546
2.37.3
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
1
2
3
We don't need to remove bs->file, generic layer takes care of it. No
4
other driver cares to remove bs->file on failure by hand.
5
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
7
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
8
Message-Id: <20220726201134.924743-4-vsementsov@yandex-team.ru>
9
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
12
block/blklogwrites.c | 4 ----
13
1 file changed, 4 deletions(-)
14
15
diff --git a/block/blklogwrites.c b/block/blklogwrites.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/block/blklogwrites.c
18
+++ b/block/blklogwrites.c
19
@@ -XXX,XX +XXX,XX @@ fail_log:
20
s->log_file = NULL;
21
}
22
fail:
23
- if (ret < 0) {
24
- bdrv_unref_child(bs, bs->file);
25
- bs->file = NULL;
26
- }
27
qemu_opts_del(opts);
28
return ret;
29
}
30
--
31
2.37.3
diff view generated by jsdifflib
1
From: Bernhard Beschow <shentey@gmail.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
2
2
3
Other ISA devices such as serial-isa use the properties in their
3
test_parallel_perm_update() does two things that we are going to
4
build_aml functions. fdc-isa not using them is probably an oversight.
4
restrict in the near future:
5
5
6
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
6
1. It updates bs->file field by hand. bs->file will be managed
7
Message-Id: <20220209191558.30393-1-shentey@gmail.com>
7
automatically by generic code (together with bs->children list).
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
9
Let's better refactor our "tricky" bds to have own state where one
10
of children is linked as "selected".
11
This also looks less "tricky", so avoid using this word.
12
13
2. It create FILTERED children that are not PRIMARY. Except for tests
14
all FILTERED children in the Qemu block layer are always PRIMARY as
15
well. We are going to formalize this rule, so let's better use DATA
16
children here.
17
18
3. It creates more than one FILTERED child, which is already abandoned
19
in BDRV_CHILD_FILTERED's description.
20
21
While being here, update the picture to better correspond to the test
22
code.
23
24
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
25
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
26
Message-Id: <20220726201134.924743-5-vsementsov@yandex-team.ru>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
27
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
28
---
11
hw/block/fdc-isa.c | 11 +++++++----
29
tests/unit/test-bdrv-graph-mod.c | 80 +++++++++++++++++++-------------
12
1 file changed, 7 insertions(+), 4 deletions(-)
30
1 file changed, 49 insertions(+), 31 deletions(-)
13
31
14
diff --git a/hw/block/fdc-isa.c b/hw/block/fdc-isa.c
32
diff --git a/tests/unit/test-bdrv-graph-mod.c b/tests/unit/test-bdrv-graph-mod.c
15
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/block/fdc-isa.c
34
--- a/tests/unit/test-bdrv-graph-mod.c
17
+++ b/hw/block/fdc-isa.c
35
+++ b/tests/unit/test-bdrv-graph-mod.c
18
@@ -XXX,XX +XXX,XX @@ int cmos_get_fd_drive_type(FloppyDriveType fd0)
36
@@ -XXX,XX +XXX,XX @@ static void test_parallel_exclusive_write(void)
19
37
bdrv_unref(top);
20
static void fdc_isa_build_aml(ISADevice *isadev, Aml *scope)
38
}
39
40
-static void write_to_file_perms(BlockDriverState *bs, BdrvChild *c,
41
- BdrvChildRole role,
42
- BlockReopenQueue *reopen_queue,
43
- uint64_t perm, uint64_t shared,
44
- uint64_t *nperm, uint64_t *nshared)
45
+/*
46
+ * write-to-selected node may have several DATA children, one of them may be
47
+ * "selected". Exclusive write permission is taken on selected child.
48
+ *
49
+ * We don't realize write handler itself, as we need only to test how permission
50
+ * update works.
51
+ */
52
+typedef struct BDRVWriteToSelectedState {
53
+ BdrvChild *selected;
54
+} BDRVWriteToSelectedState;
55
+
56
+static void write_to_selected_perms(BlockDriverState *bs, BdrvChild *c,
57
+ BdrvChildRole role,
58
+ BlockReopenQueue *reopen_queue,
59
+ uint64_t perm, uint64_t shared,
60
+ uint64_t *nperm, uint64_t *nshared)
21
{
61
{
22
+ FDCtrlISABus *isa = ISA_FDC(isadev);
62
- if (bs->file && c == bs->file) {
23
Aml *dev;
63
+ BDRVWriteToSelectedState *s = bs->opaque;
24
Aml *crs;
64
+
25
int i;
65
+ if (s->selected && c == s->selected) {
26
@@ -XXX,XX +XXX,XX @@ static void fdc_isa_build_aml(ISADevice *isadev, Aml *scope)
66
*nperm = BLK_PERM_WRITE;
27
};
67
*nshared = BLK_PERM_ALL & ~BLK_PERM_WRITE;
28
68
} else {
29
crs = aml_resource_template();
69
@@ -XXX,XX +XXX,XX @@ static void write_to_file_perms(BlockDriverState *bs, BdrvChild *c,
30
- aml_append(crs, aml_io(AML_DECODE16, 0x03F2, 0x03F2, 0x00, 0x04));
70
}
31
- aml_append(crs, aml_io(AML_DECODE16, 0x03F7, 0x03F7, 0x00, 0x01));
71
}
32
- aml_append(crs, aml_irq_no_flags(6));
72
33
aml_append(crs,
73
-static BlockDriver bdrv_write_to_file = {
34
- aml_dma(AML_COMPATIBILITY, AML_NOTBUSMASTER, AML_TRANSFER8, 2));
74
- .format_name = "tricky-perm",
35
+ aml_io(AML_DECODE16, isa->iobase + 2, isa->iobase + 2, 0x00, 0x04));
75
- .bdrv_child_perm = write_to_file_perms,
36
+ aml_append(crs,
76
+static BlockDriver bdrv_write_to_selected = {
37
+ aml_io(AML_DECODE16, isa->iobase + 7, isa->iobase + 7, 0x00, 0x01));
77
+ .format_name = "write-to-selected",
38
+ aml_append(crs, aml_irq_no_flags(isa->irq));
78
+ .instance_size = sizeof(BDRVWriteToSelectedState),
39
+ aml_append(crs,
79
+ .bdrv_child_perm = write_to_selected_perms,
40
+ aml_dma(AML_COMPATIBILITY, AML_NOTBUSMASTER, AML_TRANSFER8, isa->dma));
80
};
41
81
42
dev = aml_device("FDC0");
82
43
aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0700")));
83
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_write_to_file = {
84
* The following test shows that topological-sort order is required for
85
* permission update, simple DFS is not enough.
86
*
87
- * Consider the block driver which has two filter children: one active
88
- * with exclusive write access and one inactive with no specific
89
- * permissions.
90
+ * Consider the block driver (write-to-selected) which has two children: one is
91
+ * selected so we have exclusive write access to it and for the other one we
92
+ * don't need any specific permissions.
93
*
94
* And, these two children has a common base child, like this:
95
+ * (additional "top" on top is used in test just because the only public
96
+ * function to update permission should get a specific child to update.
97
+ * Making bdrv_refresh_perms() public just for this test isn't worth it)
98
*
99
- * ┌─────┐ ┌──────┐
100
- * │ fl2 │ ◀── │ top │
101
- * └─────┘ └──────┘
102
+ * ┌─────┐ ┌───────────────────┐ ┌─────┐
103
+ * │ fl2 │ ◀── │ write-to-selected │ ◀── │ top │
104
+ * └─────┘ └───────────────────┘ └─────┘
105
* │ │
106
* │ │ w
107
* │ ▼
108
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_write_to_file = {
109
*
110
* So, exclusive write is propagated.
111
*
112
- * Assume, we want to make fl2 active instead of fl1.
113
- * So, we set some option for top driver and do permission update.
114
+ * Assume, we want to select fl2 instead of fl1.
115
+ * So, we set some option for write-to-selected driver and do permission update.
116
*
117
* With simple DFS, if permission update goes first through
118
- * top->fl1->base branch it will succeed: it firstly drop exclusive write
119
- * permissions and than apply them for another BdrvChildren.
120
- * But if permission update goes first through top->fl2->base branch it
121
- * will fail, as when we try to update fl2->base child, old not yet
122
+ * write-to-selected -> fl1 -> base branch it will succeed: it firstly drop
123
+ * exclusive write permissions and than apply them for another BdrvChildren.
124
+ * But if permission update goes first through write-to-selected -> fl2 -> base
125
+ * branch it will fail, as when we try to update fl2->base child, old not yet
126
* updated fl1->base child will be in conflict.
127
*
128
* With topological-sort order we always update parents before children, so fl1
129
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_write_to_file = {
130
static void test_parallel_perm_update(void)
131
{
132
BlockDriverState *top = no_perm_node("top");
133
- BlockDriverState *tricky =
134
- bdrv_new_open_driver(&bdrv_write_to_file, "tricky", BDRV_O_RDWR,
135
+ BlockDriverState *ws =
136
+ bdrv_new_open_driver(&bdrv_write_to_selected, "ws", BDRV_O_RDWR,
137
&error_abort);
138
+ BDRVWriteToSelectedState *s = ws->opaque;
139
BlockDriverState *base = no_perm_node("base");
140
BlockDriverState *fl1 = pass_through_node("fl1");
141
BlockDriverState *fl2 = pass_through_node("fl2");
142
@@ -XXX,XX +XXX,XX @@ static void test_parallel_perm_update(void)
143
*/
144
bdrv_ref(base);
145
146
- bdrv_attach_child(top, tricky, "file", &child_of_bds, BDRV_CHILD_DATA,
147
+ bdrv_attach_child(top, ws, "file", &child_of_bds, BDRV_CHILD_DATA,
148
&error_abort);
149
- c_fl1 = bdrv_attach_child(tricky, fl1, "first", &child_of_bds,
150
- BDRV_CHILD_FILTERED, &error_abort);
151
- c_fl2 = bdrv_attach_child(tricky, fl2, "second", &child_of_bds,
152
- BDRV_CHILD_FILTERED, &error_abort);
153
+ c_fl1 = bdrv_attach_child(ws, fl1, "first", &child_of_bds,
154
+ BDRV_CHILD_DATA, &error_abort);
155
+ c_fl2 = bdrv_attach_child(ws, fl2, "second", &child_of_bds,
156
+ BDRV_CHILD_DATA, &error_abort);
157
bdrv_attach_child(fl1, base, "backing", &child_of_bds, BDRV_CHILD_FILTERED,
158
&error_abort);
159
bdrv_attach_child(fl2, base, "backing", &child_of_bds, BDRV_CHILD_FILTERED,
160
&error_abort);
161
162
/* Select fl1 as first child to be active */
163
- tricky->file = c_fl1;
164
+ s->selected = c_fl1;
165
bdrv_child_refresh_perms(top, top->children.lh_first, &error_abort);
166
167
assert(c_fl1->perm & BLK_PERM_WRITE);
168
assert(!(c_fl2->perm & BLK_PERM_WRITE));
169
170
/* Now, try to switch active child and update permissions */
171
- tricky->file = c_fl2;
172
+ s->selected = c_fl2;
173
bdrv_child_refresh_perms(top, top->children.lh_first, &error_abort);
174
175
assert(c_fl2->perm & BLK_PERM_WRITE);
176
assert(!(c_fl1->perm & BLK_PERM_WRITE));
177
178
/* Switch once more, to not care about real child order in the list */
179
- tricky->file = c_fl1;
180
+ s->selected = c_fl1;
181
bdrv_child_refresh_perms(top, top->children.lh_first, &error_abort);
182
183
assert(c_fl1->perm & BLK_PERM_WRITE);
44
--
184
--
45
2.34.1
185
2.37.3
46
186
47
187
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
1
2
3
We do add COW child to the node. In future we are going to forbid
4
adding COW child to the node that doesn't support backing. So, fix it
5
here now.
6
7
Don't worry about setting bs->backing itself: in further commit we'll
8
update the block-layer to automatically set/unset this field in generic
9
code.
10
11
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
12
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
13
Message-Id: <20220726201134.924743-6-vsementsov@yandex-team.ru>
14
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
15
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
---
17
tests/unit/test-bdrv-drain.c | 1 +
18
1 file changed, 1 insertion(+)
19
20
diff --git a/tests/unit/test-bdrv-drain.c b/tests/unit/test-bdrv-drain.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/tests/unit/test-bdrv-drain.c
23
+++ b/tests/unit/test-bdrv-drain.c
24
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn bdrv_replace_test_co_drain_end(BlockDriverState *bs)
25
static BlockDriver bdrv_replace_test = {
26
.format_name = "replace_test",
27
.instance_size = sizeof(BDRVReplaceTestState),
28
+ .supports_backing = true,
29
30
.bdrv_close = bdrv_replace_test_close,
31
.bdrv_co_preadv = bdrv_replace_test_co_preadv,
32
--
33
2.37.3
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
1
2
3
bdrv_pass_through is used as filter, even all node variables has
4
corresponding names. We want to append it, so it should be
5
backing-child-based filter like mirror_top.
6
So, in test_update_perm_tree, first child should be DATA, as we don't
7
want filters with two filtered children.
8
9
bdrv_exclusive_writer is used as a filter once. So it should be filter
10
anyway. We want to append it, so it should be backing-child-based
11
fitler too.
12
13
Make all FILTERED children to be PRIMARY as well. We are going to force
14
this rule by assertion soon.
15
16
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
17
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
18
Message-Id: <20220726201134.924743-7-vsementsov@yandex-team.ru>
19
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
20
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
21
---
22
include/block/block_int-common.h | 5 +++--
23
tests/unit/test-bdrv-graph-mod.c | 24 +++++++++++++++++-------
24
2 files changed, 20 insertions(+), 9 deletions(-)
25
26
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/include/block/block_int-common.h
29
+++ b/include/block/block_int-common.h
30
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
31
/*
32
* Only make sense for filter drivers, for others must be false.
33
* If true, filtered child is bs->backing. Otherwise it's bs->file.
34
- * Only two internal filters use bs->backing as filtered child and has this
35
- * field set to true: mirror_top and commit_top.
36
+ * Two internal filters use bs->backing as filtered child and has this
37
+ * field set to true: mirror_top and commit_top. There also two such test
38
+ * filters in tests/unit/test-bdrv-graph-mod.c.
39
*
40
* Never create any more such filters!
41
*
42
diff --git a/tests/unit/test-bdrv-graph-mod.c b/tests/unit/test-bdrv-graph-mod.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/tests/unit/test-bdrv-graph-mod.c
45
+++ b/tests/unit/test-bdrv-graph-mod.c
46
@@ -XXX,XX +XXX,XX @@
47
48
static BlockDriver bdrv_pass_through = {
49
.format_name = "pass-through",
50
+ .is_filter = true,
51
+ .filtered_child_is_backing = true,
52
.bdrv_child_perm = bdrv_default_perms,
53
};
54
55
@@ -XXX,XX +XXX,XX @@ static void exclusive_write_perms(BlockDriverState *bs, BdrvChild *c,
56
57
static BlockDriver bdrv_exclusive_writer = {
58
.format_name = "exclusive-writer",
59
+ .is_filter = true,
60
+ .filtered_child_is_backing = true,
61
.bdrv_child_perm = exclusive_write_perms,
62
};
63
64
@@ -XXX,XX +XXX,XX @@ static void test_update_perm_tree(void)
65
blk_insert_bs(root, bs, &error_abort);
66
67
bdrv_attach_child(filter, bs, "child", &child_of_bds,
68
- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, &error_abort);
69
+ BDRV_CHILD_DATA, &error_abort);
70
71
ret = bdrv_append(filter, bs, NULL);
72
g_assert_cmpint(ret, <, 0);
73
@@ -XXX,XX +XXX,XX @@ static void test_parallel_exclusive_write(void)
74
*/
75
bdrv_ref(base);
76
77
- bdrv_attach_child(top, fl1, "backing", &child_of_bds, BDRV_CHILD_DATA,
78
+ bdrv_attach_child(top, fl1, "backing", &child_of_bds,
79
+ BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
80
&error_abort);
81
- bdrv_attach_child(fl1, base, "backing", &child_of_bds, BDRV_CHILD_FILTERED,
82
+ bdrv_attach_child(fl1, base, "backing", &child_of_bds,
83
+ BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
84
&error_abort);
85
- bdrv_attach_child(fl2, base, "backing", &child_of_bds, BDRV_CHILD_FILTERED,
86
+ bdrv_attach_child(fl2, base, "backing", &child_of_bds,
87
+ BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
88
&error_abort);
89
90
bdrv_replace_node(fl1, fl2, &error_abort);
91
@@ -XXX,XX +XXX,XX @@ static void test_parallel_perm_update(void)
92
BDRV_CHILD_DATA, &error_abort);
93
c_fl2 = bdrv_attach_child(ws, fl2, "second", &child_of_bds,
94
BDRV_CHILD_DATA, &error_abort);
95
- bdrv_attach_child(fl1, base, "backing", &child_of_bds, BDRV_CHILD_FILTERED,
96
+ bdrv_attach_child(fl1, base, "backing", &child_of_bds,
97
+ BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
98
&error_abort);
99
- bdrv_attach_child(fl2, base, "backing", &child_of_bds, BDRV_CHILD_FILTERED,
100
+ bdrv_attach_child(fl2, base, "backing", &child_of_bds,
101
+ BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
102
&error_abort);
103
104
/* Select fl1 as first child to be active */
105
@@ -XXX,XX +XXX,XX @@ static void test_append_greedy_filter(void)
106
BlockDriverState *base = no_perm_node("base");
107
BlockDriverState *fl = exclusive_writer_node("fl1");
108
109
- bdrv_attach_child(top, base, "backing", &child_of_bds, BDRV_CHILD_COW,
110
+ bdrv_attach_child(top, base, "backing", &child_of_bds,
111
+ BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
112
&error_abort);
113
114
bdrv_append(fl, base, &error_abort);
115
--
116
2.37.3
diff view generated by jsdifflib
1
The 'throttle' block driver implements .bdrv_co_drain_end, so
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
2
blockdev-reopen will have to wait for it to complete in the polling
3
loop at the end of qmp_blockdev_reopen(). This makes AIO_WAIT_WHILE()
4
release the AioContext lock, which causes a crash if the lock hasn't
5
correctly been taken.
6
2
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
3
Make the informal rules formal. In further commit we'll add
8
Message-Id: <20220203140534.36522-3-kwolf@redhat.com>
4
corresponding assertions.
5
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
9
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
7
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
8
Message-Id: <20220726201134.924743-8-vsementsov@yandex-team.ru>
9
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
11
---
12
tests/qemu-iotests/245 | 36 +++++++++++++++++++++++++++++++++---
12
include/block/block-common.h | 39 ++++++++++++++++++++++++++++++++++++
13
tests/qemu-iotests/245.out | 4 ++--
13
1 file changed, 39 insertions(+)
14
2 files changed, 35 insertions(+), 5 deletions(-)
15
14
16
diff --git a/tests/qemu-iotests/245 b/tests/qemu-iotests/245
15
diff --git a/include/block/block-common.h b/include/block/block-common.h
17
index XXXXXXX..XXXXXXX 100755
18
--- a/tests/qemu-iotests/245
19
+++ b/tests/qemu-iotests/245
20
@@ -XXX,XX +XXX,XX @@ class TestBlockdevReopen(iotests.QMPTestCase):
21
self.assertEqual(self.get_node('hd1'), None)
22
self.assert_qmp(self.get_node('hd2'), 'ro', True)
23
24
- def run_test_iothreads(self, iothread_a, iothread_b, errmsg = None):
25
- opts = hd_opts(0)
26
+ def run_test_iothreads(self, iothread_a, iothread_b, errmsg = None,
27
+ opts_a = None, opts_b = None):
28
+ opts = opts_a or hd_opts(0)
29
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts)
30
self.assert_qmp(result, 'return', {})
31
32
- opts2 = hd_opts(2)
33
+ opts2 = opts_b or hd_opts(2)
34
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts2)
35
self.assert_qmp(result, 'return', {})
36
37
@@ -XXX,XX +XXX,XX @@ class TestBlockdevReopen(iotests.QMPTestCase):
38
def test_iothreads_switch_overlay(self):
39
self.run_test_iothreads('', 'iothread0')
40
41
+ def test_iothreads_with_throttling(self):
42
+ # Create a throttle-group object
43
+ opts = { 'qom-type': 'throttle-group', 'id': 'group0',
44
+ 'limits': { 'iops-total': 1000 } }
45
+ result = self.vm.qmp('object-add', conv_keys = False, **opts)
46
+ self.assert_qmp(result, 'return', {})
47
+
48
+ # Options with a throttle filter between format and protocol
49
+ opts = [
50
+ {
51
+ 'driver': iotests.imgfmt,
52
+ 'node-name': f'hd{idx}',
53
+ 'file' : {
54
+ 'node-name': f'hd{idx}-throttle',
55
+ 'driver': 'throttle',
56
+ 'throttle-group': 'group0',
57
+ 'file': {
58
+ 'driver': 'file',
59
+ 'node-name': f'hd{idx}-file',
60
+ 'filename': hd_path[idx],
61
+ },
62
+ },
63
+ }
64
+ for idx in (0, 2)
65
+ ]
66
+
67
+ self.run_test_iothreads('iothread0', 'iothread0', None,
68
+ opts[0], opts[1])
69
+
70
if __name__ == '__main__':
71
iotests.activate_logging()
72
iotests.main(supported_fmts=["qcow2"],
73
diff --git a/tests/qemu-iotests/245.out b/tests/qemu-iotests/245.out
74
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
75
--- a/tests/qemu-iotests/245.out
17
--- a/include/block/block-common.h
76
+++ b/tests/qemu-iotests/245.out
18
+++ b/include/block/block-common.h
77
@@ -XXX,XX +XXX,XX @@ read 1/1 bytes at offset 262152
19
@@ -XXX,XX +XXX,XX @@ enum {
78
read 1/1 bytes at offset 262160
20
*
79
1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
21
* At least one of DATA, METADATA, FILTERED, or COW must be set for
80
22
* every child.
81
-...............
23
+ *
82
+................
24
+ *
83
----------------------------------------------------------------------
25
+ * = Connection with bs->children, bs->file and bs->backing fields =
84
-Ran 25 tests
26
+ *
85
+Ran 26 tests
27
+ * 1. Filters
86
28
+ *
87
OK
29
+ * Filter drivers have drv->is_filter = true.
30
+ *
31
+ * Filter node has exactly one FILTERED|PRIMARY child, and may have other
32
+ * children which must not have these bits (one example is the
33
+ * copy-before-write filter, which also has its target DATA child).
34
+ *
35
+ * Filter nodes never have COW children.
36
+ *
37
+ * For most filters, the filtered child is linked in bs->file, bs->backing is
38
+ * NULL. For some filters (as an exception), it is the other way around; those
39
+ * drivers will have drv->filtered_child_is_backing set to true (see that
40
+ * field’s documentation for what drivers this concerns)
41
+ *
42
+ * 2. "raw" driver (block/raw-format.c)
43
+ *
44
+ * Formally it's not a filter (drv->is_filter = false)
45
+ *
46
+ * bs->backing is always NULL
47
+ *
48
+ * Only has one child, linked in bs->file. Its role is either FILTERED|PRIMARY
49
+ * (like filter) or DATA|PRIMARY depending on options.
50
+ *
51
+ * 3. Other drivers
52
+ *
53
+ * Don't have any FILTERED children.
54
+ *
55
+ * May have at most one COW child. In this case it's linked in bs->backing.
56
+ * Otherwise bs->backing is NULL. COW child is never PRIMARY.
57
+ *
58
+ * May have at most one PRIMARY child. In this case it's linked in bs->file.
59
+ * Otherwise bs->file is NULL.
60
+ *
61
+ * May also have some other children that don't have the PRIMARY or COW bit set.
62
*/
63
enum BdrvChildRoleBits {
64
/*
88
--
65
--
89
2.34.1
66
2.37.3
90
67
91
68
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
1
2
3
Actually what we chose is a primary child. Let's stress it in the code.
4
5
We are going to drop indirect pointer logic here in future. Actually
6
this commit simplifies the future work: we drop use of indirection in
7
the assertion now.
8
9
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
10
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
11
Message-Id: <20220726201134.924743-9-vsementsov@yandex-team.ru>
12
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
15
block/snapshot.c | 30 ++++++++++--------------------
16
1 file changed, 10 insertions(+), 20 deletions(-)
17
18
diff --git a/block/snapshot.c b/block/snapshot.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/block/snapshot.c
21
+++ b/block/snapshot.c
22
@@ -XXX,XX +XXX,XX @@ bool bdrv_snapshot_find_by_id_and_name(BlockDriverState *bs,
23
static BdrvChild **bdrv_snapshot_fallback_ptr(BlockDriverState *bs)
24
{
25
BdrvChild **fallback;
26
- BdrvChild *child;
27
+ BdrvChild *child = bdrv_primary_child(bs);
28
29
- /*
30
- * The only BdrvChild pointers that are safe to modify (and which
31
- * we can thus return a reference to) are bs->file and
32
- * bs->backing.
33
- */
34
- fallback = &bs->file;
35
- if (!*fallback && bs->drv && bs->drv->is_filter) {
36
- fallback = &bs->backing;
37
- }
38
-
39
- if (!*fallback) {
40
+ /* We allow fallback only to primary child */
41
+ if (!child) {
42
return NULL;
43
}
44
+ fallback = (child == bs->file ? &bs->file : &bs->backing);
45
+ assert(*fallback == child);
46
47
/*
48
* Check that there are no other children that would need to be
49
@@ -XXX,XX +XXX,XX @@ int bdrv_snapshot_goto(BlockDriverState *bs,
50
}
51
52
/*
53
- * fallback_ptr is &bs->file or &bs->backing. *fallback_ptr
54
- * was closed above and set to NULL, but the .bdrv_open() call
55
- * has opened it again, because we set the respective option
56
- * (with the qdict_put_str() call above).
57
- * Assert that .bdrv_open() has attached some child on
58
- * *fallback_ptr, and that it has attached the one we wanted
59
- * it to (i.e., fallback_bs).
60
+ * fallback was a primary child. It was closed above and set to NULL,
61
+ * but the .bdrv_open() call has opened it again, because we set the
62
+ * respective option (with the qdict_put_str() call above).
63
+ * Assert that .bdrv_open() has attached the right BDS as primary child.
64
*/
65
- assert(*fallback_ptr && fallback_bs == (*fallback_ptr)->bs);
66
+ assert(bdrv_primary_bs(bs) == fallback_bs);
67
bdrv_unref(fallback_bs);
68
return ret;
69
}
70
--
71
2.37.3
diff view generated by jsdifflib
New patch
1
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
2
3
We are going to reimplement this behavior (clear bs->file / bs->backing
4
pointers automatically when child->bs is cleared) in a nicer way, see
5
further commit
6
"block: Manipulate bs->file / bs->backing pointers in .attach/.detach".
7
8
With this revert we bring back a problem that was fixed by b0a9f6fed3d8.
9
Still the problem was mostly theoretical, we don't have concrete bugs
10
fixed by b0a9f6fed3d8, we don't have a specific test. Probably some
11
accidental failures of iotests are related.
12
13
Alternatively, we may merge this and following three reverts into final
14
"block: Manipulate ..." to avoid any kind of regression. But seems that
15
in this case having separate clear revert commits is better.
16
17
This reverts commit b0a9f6fed3d80de610dcd04a7e66f9f30a04174f.
18
19
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
20
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
21
Message-Id: <20220726201134.924743-10-vsementsov@yandex-team.ru>
22
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
23
---
24
block.c | 102 +++++++++++++-------------------------------------------
25
1 file changed, 23 insertions(+), 79 deletions(-)
26
27
diff --git a/block.c b/block.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/block.c
30
+++ b/block.c
31
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
32
static bool bdrv_recurse_has_child(BlockDriverState *bs,
33
BlockDriverState *child);
34
35
-static void bdrv_child_free(BdrvChild *child);
36
static void bdrv_replace_child_noperm(BdrvChild **child,
37
- BlockDriverState *new_bs,
38
- bool free_empty_child);
39
+ BlockDriverState *new_bs);
40
static void bdrv_remove_file_or_backing_child(BlockDriverState *bs,
41
BdrvChild *child,
42
Transaction *tran);
43
@@ -XXX,XX +XXX,XX @@ typedef struct BdrvReplaceChildState {
44
BdrvChild *child;
45
BdrvChild **childp;
46
BlockDriverState *old_bs;
47
- bool free_empty_child;
48
} BdrvReplaceChildState;
49
50
static void bdrv_replace_child_commit(void *opaque)
51
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child_commit(void *opaque)
52
BdrvReplaceChildState *s = opaque;
53
GLOBAL_STATE_CODE();
54
55
- if (s->free_empty_child && !s->child->bs) {
56
- bdrv_child_free(s->child);
57
- }
58
bdrv_unref(s->old_bs);
59
}
60
61
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child_abort(void *opaque)
62
* modify the BdrvChild * pointer we indirectly pass to it, i.e. it
63
* will not modify s->child. From that perspective, it does not matter
64
* whether we pass s->childp or &s->child.
65
+ * (TODO: Right now, bdrv_replace_child_noperm() never modifies that
66
+ * pointer anyway (though it will in the future), so at this point it
67
+ * absolutely does not matter whether we pass s->childp or &s->child.)
68
* (2) If new_bs is not NULL, s->childp will be NULL. We then cannot use
69
* it here.
70
* (3) If new_bs is NULL, *s->childp will have been NULLed by
71
* bdrv_replace_child_tran()'s bdrv_replace_child_noperm() call, and we
72
* must not pass a NULL *s->childp here.
73
+ * (TODO: In its current state, bdrv_replace_child_noperm() will not
74
+ * have NULLed *s->childp, so this does not apply yet. It will in the
75
+ * future.)
76
*
77
* So whether new_bs was NULL or not, we cannot pass s->childp here; and in
78
* any case, there is no reason to pass it anyway.
79
*/
80
- bdrv_replace_child_noperm(&s->child, s->old_bs, true);
81
- /*
82
- * The child was pre-existing, so s->old_bs must be non-NULL, and
83
- * s->child thus must not have been freed
84
- */
85
- assert(s->child != NULL);
86
- if (!new_bs) {
87
- /* As described above, *s->childp was cleared, so restore it */
88
- assert(s->childp != NULL);
89
- *s->childp = s->child;
90
- }
91
+ bdrv_replace_child_noperm(&s->child, s->old_bs);
92
bdrv_unref(new_bs);
93
}
94
95
@@ -XXX,XX +XXX,XX @@ static TransactionActionDrv bdrv_replace_child_drv = {
96
*
97
* The function doesn't update permissions, caller is responsible for this.
98
*
99
- * (*childp)->bs must not be NULL.
100
- *
101
* Note that if new_bs == NULL, @childp is stored in a state object attached
102
* to @tran, so that the old child can be reinstated in the abort handler.
103
* Therefore, if @new_bs can be NULL, @childp must stay valid until the
104
* transaction is committed or aborted.
105
*
106
- * If @free_empty_child is true and @new_bs is NULL, the BdrvChild is
107
- * freed (on commit). @free_empty_child should only be false if the
108
- * caller will free the BDrvChild themselves (which may be important
109
- * if this is in turn called in another transactional context).
110
+ * (TODO: The reinstating does not happen yet, but it will once
111
+ * bdrv_replace_child_noperm() NULLs *childp when new_bs is NULL.)
112
*/
113
static void bdrv_replace_child_tran(BdrvChild **childp,
114
BlockDriverState *new_bs,
115
- Transaction *tran,
116
- bool free_empty_child)
117
+ Transaction *tran)
118
{
119
BdrvReplaceChildState *s = g_new(BdrvReplaceChildState, 1);
120
*s = (BdrvReplaceChildState) {
121
.child = *childp,
122
.childp = new_bs == NULL ? childp : NULL,
123
.old_bs = (*childp)->bs,
124
- .free_empty_child = free_empty_child,
125
};
126
tran_add(tran, &bdrv_replace_child_drv, s);
127
128
- /* The abort handler relies on this */
129
- assert(s->old_bs != NULL);
130
-
131
if (new_bs) {
132
bdrv_ref(new_bs);
133
}
134
- /*
135
- * Pass free_empty_child=false, we will free the child (if
136
- * necessary) in bdrv_replace_child_commit() (if our
137
- * @free_empty_child parameter was true).
138
- */
139
- bdrv_replace_child_noperm(childp, new_bs, false);
140
+ bdrv_replace_child_noperm(childp, new_bs);
141
/* old_bs reference is transparently moved from *childp to @s */
142
}
143
144
@@ -XXX,XX +XXX,XX @@ uint64_t bdrv_qapi_perm_to_blk_perm(BlockPermission qapi_perm)
145
return permissions[qapi_perm];
146
}
147
148
-/**
149
- * Replace (*childp)->bs by @new_bs.
150
- *
151
- * If @new_bs is NULL, *childp will be set to NULL, too: BDS parents
152
- * generally cannot handle a BdrvChild with .bs == NULL, so clearing
153
- * BdrvChild.bs should generally immediately be followed by the
154
- * BdrvChild pointer being cleared as well.
155
- *
156
- * If @free_empty_child is true and @new_bs is NULL, the BdrvChild is
157
- * freed. @free_empty_child should only be false if the caller will
158
- * free the BdrvChild themselves (this may be important in a
159
- * transactional context, where it may only be freed on commit).
160
- */
161
static void bdrv_replace_child_noperm(BdrvChild **childp,
162
- BlockDriverState *new_bs,
163
- bool free_empty_child)
164
+ BlockDriverState *new_bs)
165
{
166
BdrvChild *child = *childp;
167
BlockDriverState *old_bs = child->bs;
168
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child_noperm(BdrvChild **childp,
169
}
170
171
child->bs = new_bs;
172
- if (!new_bs) {
173
- *childp = NULL;
174
- }
175
176
if (new_bs) {
177
assert_bdrv_graph_writable(new_bs);
178
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child_noperm(BdrvChild **childp,
179
bdrv_parent_drained_end_single(child);
180
drain_saldo++;
181
}
182
-
183
- if (free_empty_child && !child->bs) {
184
- bdrv_child_free(child);
185
- }
186
}
187
188
/**
189
@@ -XXX,XX +XXX,XX @@ static void bdrv_attach_child_common_abort(void *opaque)
190
BlockDriverState *bs = child->bs;
191
192
GLOBAL_STATE_CODE();
193
- /*
194
- * Pass free_empty_child=false, because we still need the child
195
- * for the AioContext operations on the parent below; those
196
- * BdrvChildClass methods all work on a BdrvChild object, so we
197
- * need to keep it as an empty shell (after this function, it will
198
- * not be attached to any parent, and it will not have a .bs).
199
- */
200
- bdrv_replace_child_noperm(s->child, NULL, false);
201
+ bdrv_replace_child_noperm(s->child, NULL);
202
203
if (bdrv_get_aio_context(bs) != s->old_child_ctx) {
204
bdrv_try_set_aio_context(bs, s->old_child_ctx, &error_abort);
205
@@ -XXX,XX +XXX,XX @@ static void bdrv_attach_child_common_abort(void *opaque)
206
207
bdrv_unref(bs);
208
bdrv_child_free(child);
209
+ *s->child = NULL;
210
}
211
212
static TransactionActionDrv bdrv_attach_child_common_drv = {
213
@@ -XXX,XX +XXX,XX @@ static int bdrv_attach_child_common(BlockDriverState *child_bs,
214
}
215
216
bdrv_ref(child_bs);
217
- bdrv_replace_child_noperm(&new_child, child_bs, true);
218
- /* child_bs was non-NULL, so new_child must not have been freed */
219
- assert(new_child != NULL);
220
+ bdrv_replace_child_noperm(&new_child, child_bs);
221
222
*child = new_child;
223
224
@@ -XXX,XX +XXX,XX @@ static void bdrv_detach_child(BdrvChild **childp)
225
BlockDriverState *old_bs = (*childp)->bs;
226
227
GLOBAL_STATE_CODE();
228
- bdrv_replace_child_noperm(childp, NULL, true);
229
+ bdrv_replace_child_noperm(childp, NULL);
230
+ bdrv_child_free(*childp);
231
232
if (old_bs) {
233
/*
234
@@ -XXX,XX +XXX,XX @@ static void bdrv_remove_file_or_backing_child(BlockDriverState *bs,
235
}
236
237
if (child->bs) {
238
- /*
239
- * Pass free_empty_child=false, we will free the child in
240
- * bdrv_remove_filter_or_cow_child_commit()
241
- */
242
- bdrv_replace_child_tran(childp, NULL, tran, false);
243
+ bdrv_replace_child_tran(childp, NULL, tran);
244
}
245
246
s = g_new(BdrvRemoveFilterOrCowChild, 1);
247
@@ -XXX,XX +XXX,XX @@ static void bdrv_remove_file_or_backing_child(BlockDriverState *bs,
248
.is_backing = (childp == &bs->backing),
249
};
250
tran_add(tran, &bdrv_remove_filter_or_cow_child_drv, s);
251
+
252
+ *childp = NULL;
253
}
254
255
/*
256
@@ -XXX,XX +XXX,XX @@ static int bdrv_replace_node_noperm(BlockDriverState *from,
257
* Passing a pointer to the local variable @c is fine here, because
258
* @to is not NULL, and so &c will not be attached to the transaction.
259
*/
260
- bdrv_replace_child_tran(&c, to, tran, true);
261
+ bdrv_replace_child_tran(&c, to, tran);
262
}
263
264
return 0;
265
@@ -XXX,XX +XXX,XX @@ int bdrv_replace_child_bs(BdrvChild *child, BlockDriverState *new_bs,
266
bdrv_drained_begin(old_bs);
267
bdrv_drained_begin(new_bs);
268
269
- bdrv_replace_child_tran(&child, new_bs, tran, true);
270
- /* @new_bs must have been non-NULL, so @child must not have been freed */
271
- assert(child != NULL);
272
+ bdrv_replace_child_tran(&child, new_bs, tran);
273
274
found = g_hash_table_new(NULL, NULL);
275
refresh_list = bdrv_topological_dfs(refresh_list, found, old_bs);
276
--
277
2.37.3
diff view generated by jsdifflib
New patch
1
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
2
3
That's a preparation to previously reverted
4
"block: Let replace_child_noperm free children". Drop it too, we don't
5
need it for a new approach.
6
7
This reverts commit 82b54cf51656bf3cd5ed1ac549e8a1085a0e3290.
8
9
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
10
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
11
Message-Id: <20220726201134.924743-11-vsementsov@yandex-team.ru>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
14
block.c | 81 +++++++--------------------------------------------------
15
1 file changed, 10 insertions(+), 71 deletions(-)
16
17
diff --git a/block.c b/block.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/block.c
20
+++ b/block.c
21
@@ -XXX,XX +XXX,XX @@ static int bdrv_drv_set_perm(BlockDriverState *bs, uint64_t perm,
22
23
typedef struct BdrvReplaceChildState {
24
BdrvChild *child;
25
- BdrvChild **childp;
26
BlockDriverState *old_bs;
27
} BdrvReplaceChildState;
28
29
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child_abort(void *opaque)
30
BlockDriverState *new_bs = s->child->bs;
31
32
GLOBAL_STATE_CODE();
33
- /*
34
- * old_bs reference is transparently moved from @s to s->child.
35
- *
36
- * Pass &s->child here instead of s->childp, because:
37
- * (1) s->old_bs must be non-NULL, so bdrv_replace_child_noperm() will not
38
- * modify the BdrvChild * pointer we indirectly pass to it, i.e. it
39
- * will not modify s->child. From that perspective, it does not matter
40
- * whether we pass s->childp or &s->child.
41
- * (TODO: Right now, bdrv_replace_child_noperm() never modifies that
42
- * pointer anyway (though it will in the future), so at this point it
43
- * absolutely does not matter whether we pass s->childp or &s->child.)
44
- * (2) If new_bs is not NULL, s->childp will be NULL. We then cannot use
45
- * it here.
46
- * (3) If new_bs is NULL, *s->childp will have been NULLed by
47
- * bdrv_replace_child_tran()'s bdrv_replace_child_noperm() call, and we
48
- * must not pass a NULL *s->childp here.
49
- * (TODO: In its current state, bdrv_replace_child_noperm() will not
50
- * have NULLed *s->childp, so this does not apply yet. It will in the
51
- * future.)
52
- *
53
- * So whether new_bs was NULL or not, we cannot pass s->childp here; and in
54
- * any case, there is no reason to pass it anyway.
55
- */
56
+ /* old_bs reference is transparently moved from @s to @s->child */
57
bdrv_replace_child_noperm(&s->child, s->old_bs);
58
bdrv_unref(new_bs);
59
}
60
@@ -XXX,XX +XXX,XX @@ static TransactionActionDrv bdrv_replace_child_drv = {
61
* Note: real unref of old_bs is done only on commit.
62
*
63
* The function doesn't update permissions, caller is responsible for this.
64
- *
65
- * Note that if new_bs == NULL, @childp is stored in a state object attached
66
- * to @tran, so that the old child can be reinstated in the abort handler.
67
- * Therefore, if @new_bs can be NULL, @childp must stay valid until the
68
- * transaction is committed or aborted.
69
- *
70
- * (TODO: The reinstating does not happen yet, but it will once
71
- * bdrv_replace_child_noperm() NULLs *childp when new_bs is NULL.)
72
*/
73
-static void bdrv_replace_child_tran(BdrvChild **childp,
74
- BlockDriverState *new_bs,
75
+static void bdrv_replace_child_tran(BdrvChild *child, BlockDriverState *new_bs,
76
Transaction *tran)
77
{
78
BdrvReplaceChildState *s = g_new(BdrvReplaceChildState, 1);
79
*s = (BdrvReplaceChildState) {
80
- .child = *childp,
81
- .childp = new_bs == NULL ? childp : NULL,
82
- .old_bs = (*childp)->bs,
83
+ .child = child,
84
+ .old_bs = child->bs,
85
};
86
tran_add(tran, &bdrv_replace_child_drv, s);
87
88
if (new_bs) {
89
bdrv_ref(new_bs);
90
}
91
- bdrv_replace_child_noperm(childp, new_bs);
92
- /* old_bs reference is transparently moved from *childp to @s */
93
+ bdrv_replace_child_noperm(&child, new_bs);
94
+ /* old_bs reference is transparently moved from @child to @s */
95
}
96
97
/*
98
@@ -XXX,XX +XXX,XX @@ static bool should_update_child(BdrvChild *c, BlockDriverState *to)
99
100
typedef struct BdrvRemoveFilterOrCowChild {
101
BdrvChild *child;
102
- BlockDriverState *bs;
103
bool is_backing;
104
} BdrvRemoveFilterOrCowChild;
105
106
@@ -XXX,XX +XXX,XX @@ static void bdrv_remove_filter_or_cow_child_commit(void *opaque)
107
bdrv_child_free(s->child);
108
}
109
110
-static void bdrv_remove_filter_or_cow_child_clean(void *opaque)
111
-{
112
- BdrvRemoveFilterOrCowChild *s = opaque;
113
-
114
- /* Drop the bs reference after the transaction is done */
115
- bdrv_unref(s->bs);
116
- g_free(s);
117
-}
118
-
119
static TransactionActionDrv bdrv_remove_filter_or_cow_child_drv = {
120
.abort = bdrv_remove_filter_or_cow_child_abort,
121
.commit = bdrv_remove_filter_or_cow_child_commit,
122
- .clean = bdrv_remove_filter_or_cow_child_clean,
123
+ .clean = g_free,
124
};
125
126
/*
127
@@ -XXX,XX +XXX,XX @@ static void bdrv_remove_file_or_backing_child(BlockDriverState *bs,
128
return;
129
}
130
131
- /*
132
- * Keep a reference to @bs so @childp will stay valid throughout the
133
- * transaction (required by bdrv_replace_child_tran())
134
- */
135
- bdrv_ref(bs);
136
if (child == bs->backing) {
137
childp = &bs->backing;
138
} else if (child == bs->file) {
139
@@ -XXX,XX +XXX,XX @@ static void bdrv_remove_file_or_backing_child(BlockDriverState *bs,
140
}
141
142
if (child->bs) {
143
- bdrv_replace_child_tran(childp, NULL, tran);
144
+ bdrv_replace_child_tran(*childp, NULL, tran);
145
}
146
147
s = g_new(BdrvRemoveFilterOrCowChild, 1);
148
*s = (BdrvRemoveFilterOrCowChild) {
149
.child = child,
150
- .bs = bs,
151
.is_backing = (childp == &bs->backing),
152
};
153
tran_add(tran, &bdrv_remove_filter_or_cow_child_drv, s);
154
@@ -XXX,XX +XXX,XX @@ static int bdrv_replace_node_noperm(BlockDriverState *from,
155
{
156
BdrvChild *c, *next;
157
158
- assert(to != NULL);
159
GLOBAL_STATE_CODE();
160
161
QLIST_FOREACH_SAFE(c, &from->parents, next_parent, next) {
162
@@ -XXX,XX +XXX,XX @@ static int bdrv_replace_node_noperm(BlockDriverState *from,
163
c->name, from->node_name);
164
return -EPERM;
165
}
166
-
167
- /*
168
- * Passing a pointer to the local variable @c is fine here, because
169
- * @to is not NULL, and so &c will not be attached to the transaction.
170
- */
171
- bdrv_replace_child_tran(&c, to, tran);
172
+ bdrv_replace_child_tran(c, to, tran);
173
}
174
175
return 0;
176
@@ -XXX,XX +XXX,XX @@ static int bdrv_replace_node_noperm(BlockDriverState *from,
177
*
178
* With @detach_subchain=true @to must be in a backing chain of @from. In this
179
* case backing link of the cow-parent of @to is removed.
180
- *
181
- * @to must not be NULL.
182
*/
183
static int bdrv_replace_node_common(BlockDriverState *from,
184
BlockDriverState *to,
185
@@ -XXX,XX +XXX,XX @@ static int bdrv_replace_node_common(BlockDriverState *from,
186
int ret;
187
188
GLOBAL_STATE_CODE();
189
- assert(to != NULL);
190
191
if (detach_subchain) {
192
assert(bdrv_chain_contains(from, to));
193
@@ -XXX,XX +XXX,XX @@ out:
194
return ret;
195
}
196
197
-/**
198
- * Replace node @from by @to (where neither may be NULL).
199
- */
200
int bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
201
Error **errp)
202
{
203
@@ -XXX,XX +XXX,XX @@ int bdrv_replace_child_bs(BdrvChild *child, BlockDriverState *new_bs,
204
bdrv_drained_begin(old_bs);
205
bdrv_drained_begin(new_bs);
206
207
- bdrv_replace_child_tran(&child, new_bs, tran);
208
+ bdrv_replace_child_tran(child, new_bs, tran);
209
210
found = g_hash_table_new(NULL, NULL);
211
refresh_list = bdrv_topological_dfs(refresh_list, found, old_bs);
212
--
213
2.37.3
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
1
2
3
That's a preparation to previously reverted
4
"block: Let replace_child_noperm free children". Drop it too, we don't
5
need it for a new approach.
6
7
This reverts commit 562bda8bb41879eeda0bd484dd3d55134579b28e.
8
9
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
10
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
11
Message-Id: <20220726201134.924743-12-vsementsov@yandex-team.ru>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
14
block.c | 21 +++++++++------------
15
1 file changed, 9 insertions(+), 12 deletions(-)
16
17
diff --git a/block.c b/block.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/block.c
20
+++ b/block.c
21
@@ -XXX,XX +XXX,XX @@ static void bdrv_remove_file_or_backing_child(BlockDriverState *bs,
22
BdrvChild *child,
23
Transaction *tran)
24
{
25
- BdrvChild **childp;
26
BdrvRemoveFilterOrCowChild *s;
27
28
+ assert(child == bs->backing || child == bs->file);
29
+
30
if (!child) {
31
return;
32
}
33
34
- if (child == bs->backing) {
35
- childp = &bs->backing;
36
- } else if (child == bs->file) {
37
- childp = &bs->file;
38
- } else {
39
- g_assert_not_reached();
40
- }
41
-
42
if (child->bs) {
43
- bdrv_replace_child_tran(*childp, NULL, tran);
44
+ bdrv_replace_child_tran(child, NULL, tran);
45
}
46
47
s = g_new(BdrvRemoveFilterOrCowChild, 1);
48
*s = (BdrvRemoveFilterOrCowChild) {
49
.child = child,
50
- .is_backing = (childp == &bs->backing),
51
+ .is_backing = (child == bs->backing),
52
};
53
tran_add(tran, &bdrv_remove_filter_or_cow_child_drv, s);
54
55
- *childp = NULL;
56
+ if (s->is_backing) {
57
+ bs->backing = NULL;
58
+ } else {
59
+ bs->file = NULL;
60
+ }
61
}
62
63
/*
64
--
65
2.37.3
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
1
2
3
That's a preparation to previously reverted
4
"block: Let replace_child_noperm free children". Drop it too, we don't
5
need it for a new approach.
6
7
This reverts commit be64bbb0149748f3999c49b13976aafb8330ea86.
8
9
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
10
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
11
Message-Id: <20220726201134.924743-13-vsementsov@yandex-team.ru>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
14
block.c | 23 +++++++++++------------
15
1 file changed, 11 insertions(+), 12 deletions(-)
16
17
diff --git a/block.c b/block.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/block.c
20
+++ b/block.c
21
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
22
static bool bdrv_recurse_has_child(BlockDriverState *bs,
23
BlockDriverState *child);
24
25
-static void bdrv_replace_child_noperm(BdrvChild **child,
26
+static void bdrv_replace_child_noperm(BdrvChild *child,
27
BlockDriverState *new_bs);
28
static void bdrv_remove_file_or_backing_child(BlockDriverState *bs,
29
BdrvChild *child,
30
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child_abort(void *opaque)
31
32
GLOBAL_STATE_CODE();
33
/* old_bs reference is transparently moved from @s to @s->child */
34
- bdrv_replace_child_noperm(&s->child, s->old_bs);
35
+ bdrv_replace_child_noperm(s->child, s->old_bs);
36
bdrv_unref(new_bs);
37
}
38
39
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child_tran(BdrvChild *child, BlockDriverState *new_bs,
40
if (new_bs) {
41
bdrv_ref(new_bs);
42
}
43
- bdrv_replace_child_noperm(&child, new_bs);
44
+ bdrv_replace_child_noperm(child, new_bs);
45
/* old_bs reference is transparently moved from @child to @s */
46
}
47
48
@@ -XXX,XX +XXX,XX @@ uint64_t bdrv_qapi_perm_to_blk_perm(BlockPermission qapi_perm)
49
return permissions[qapi_perm];
50
}
51
52
-static void bdrv_replace_child_noperm(BdrvChild **childp,
53
+static void bdrv_replace_child_noperm(BdrvChild *child,
54
BlockDriverState *new_bs)
55
{
56
- BdrvChild *child = *childp;
57
BlockDriverState *old_bs = child->bs;
58
int new_bs_quiesce_counter;
59
int drain_saldo;
60
@@ -XXX,XX +XXX,XX @@ static void bdrv_attach_child_common_abort(void *opaque)
61
BlockDriverState *bs = child->bs;
62
63
GLOBAL_STATE_CODE();
64
- bdrv_replace_child_noperm(s->child, NULL);
65
+ bdrv_replace_child_noperm(child, NULL);
66
67
if (bdrv_get_aio_context(bs) != s->old_child_ctx) {
68
bdrv_try_set_aio_context(bs, s->old_child_ctx, &error_abort);
69
@@ -XXX,XX +XXX,XX @@ static int bdrv_attach_child_common(BlockDriverState *child_bs,
70
}
71
72
bdrv_ref(child_bs);
73
- bdrv_replace_child_noperm(&new_child, child_bs);
74
+ bdrv_replace_child_noperm(new_child, child_bs);
75
76
*child = new_child;
77
78
@@ -XXX,XX +XXX,XX @@ static int bdrv_attach_child_noperm(BlockDriverState *parent_bs,
79
return 0;
80
}
81
82
-static void bdrv_detach_child(BdrvChild **childp)
83
+static void bdrv_detach_child(BdrvChild *child)
84
{
85
- BlockDriverState *old_bs = (*childp)->bs;
86
+ BlockDriverState *old_bs = child->bs;
87
88
GLOBAL_STATE_CODE();
89
- bdrv_replace_child_noperm(childp, NULL);
90
- bdrv_child_free(*childp);
91
+ bdrv_replace_child_noperm(child, NULL);
92
+ bdrv_child_free(child);
93
94
if (old_bs) {
95
/*
96
@@ -XXX,XX +XXX,XX @@ void bdrv_root_unref_child(BdrvChild *child)
97
GLOBAL_STATE_CODE();
98
99
child_bs = child->bs;
100
- bdrv_detach_child(&child);
101
+ bdrv_detach_child(child);
102
bdrv_unref(child_bs);
103
}
104
105
--
106
2.37.3
diff view generated by jsdifflib
New patch
1
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
2
3
bs->file and bs->backing are a kind of duplication of part of
4
bs->children. But very useful diplication, so let's not drop them at
5
all:)
6
7
We should manage bs->file and bs->backing in same place, where we
8
manage bs->children, to keep them in sync.
9
10
Moreover, generic io paths are unprepared to BdrvChild without a bs, so
11
it's double good to clear bs->file / bs->backing when we detach the
12
child.
13
14
Detach is simple: if we detach bs->file or bs->backing child, just
15
set corresponding field to NULL.
16
17
Attach is a bit more complicated. But we still can precisely detect
18
should we set one of bs->file / bs->backing or not:
19
20
- if role is BDRV_CHILD_COW, we definitely deal with bs->backing
21
- else, if role is BDRV_CHILD_FILTERED (it must be also
22
BDRV_CHILD_PRIMARY), it's a filtered child. Use
23
bs->drv->filtered_child_is_backing to chose the pointer field to
24
modify.
25
- else, if role is BDRV_CHILD_PRIMARY, we deal with bs->file
26
- in all other cases, it's neither bs->backing nor bs->file. It's some
27
other child and we shouldn't care
28
29
OK. This change brings one more good thing: we can (and should) get rid
30
of all indirect pointers in the block-graph-change transactions:
31
32
bdrv_attach_child_common() stores BdrvChild** into transaction to clear
33
it on abort.
34
35
bdrv_attach_child_common() has two callers: bdrv_attach_child_noperm()
36
just pass-through this feature, bdrv_root_attach_child() doesn't need
37
the feature.
38
39
Look at bdrv_attach_child_noperm() callers:
40
- bdrv_attach_child() doesn't need the feature
41
- bdrv_set_file_or_backing_noperm() uses the feature to manage
42
bs->file and bs->backing, we don't want it anymore
43
- bdrv_append() uses the feature to manage bs->backing, again we
44
don't want it anymore
45
46
So, we should drop this stuff! Great!
47
48
We could probably keep BdrvChild** argument to keep the int return
49
value, but it seems not worth the complexity.
50
51
Finally, we now set .file / .backing automatically in generic code and
52
want to restring setting them by hand outside of .attach/.detach.
53
So, this patch cleanups all remaining places where they were set.
54
To find such places I use:
55
56
git grep '\->file ='
57
git grep '\->backing ='
58
git grep '&.*\<backing\>'
59
git grep '&.*\<file\>'
60
61
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
62
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
63
Message-Id: <20220726201134.924743-14-vsementsov@yandex-team.ru>
64
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
65
---
66
include/block/block_int-common.h | 15 +-
67
block.c | 234 ++++++++++++++-----------------
68
block/raw-format.c | 4 +-
69
block/snapshot-access.c | 6 +-
70
block/snapshot.c | 1 -
71
tests/unit/test-bdrv-drain.c | 10 +-
72
6 files changed, 126 insertions(+), 144 deletions(-)
73
74
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
75
index XXXXXXX..XXXXXXX 100644
76
--- a/include/block/block_int-common.h
77
+++ b/include/block/block_int-common.h
78
@@ -XXX,XX +XXX,XX @@ struct BlockDriverState {
79
QDict *full_open_options;
80
char exact_filename[PATH_MAX];
81
82
- BdrvChild *backing;
83
- BdrvChild *file;
84
-
85
/* I/O Limits */
86
BlockLimits bl;
87
88
@@ -XXX,XX +XXX,XX @@ struct BlockDriverState {
89
* parent node of this node.
90
*/
91
BlockDriverState *inherits_from;
92
+
93
+ /*
94
+ * @backing and @file are some of @children or NULL. All these three fields
95
+ * (@file, @backing and @children) are modified only in
96
+ * bdrv_child_cb_attach() and bdrv_child_cb_detach().
97
+ *
98
+ * See also comment in include/block/block.h, to learn how backing and file
99
+ * are connected with BdrvChildRole.
100
+ */
101
QLIST_HEAD(, BdrvChild) children;
102
+ BdrvChild *backing;
103
+ BdrvChild *file;
104
+
105
QLIST_HEAD(, BdrvChild) parents;
106
107
QDict *options;
108
diff --git a/block.c b/block.c
109
index XXXXXXX..XXXXXXX 100644
110
--- a/block.c
111
+++ b/block.c
112
@@ -XXX,XX +XXX,XX @@ static void bdrv_child_cb_attach(BdrvChild *child)
113
114
assert_bdrv_graph_writable(bs);
115
QLIST_INSERT_HEAD(&bs->children, child, next);
116
-
117
- if (child->role & BDRV_CHILD_COW) {
118
+ if (bs->drv->is_filter || (child->role & BDRV_CHILD_FILTERED)) {
119
+ /*
120
+ * Here we handle filters and block/raw-format.c when it behave like
121
+ * filter. They generally have a single PRIMARY child, which is also the
122
+ * FILTERED child, and that they may have multiple more children, which
123
+ * are neither PRIMARY nor FILTERED. And never we have a COW child here.
124
+ * So bs->file will be the PRIMARY child, unless the PRIMARY child goes
125
+ * into bs->backing on exceptional cases; and bs->backing will be
126
+ * nothing else.
127
+ */
128
+ assert(!(child->role & BDRV_CHILD_COW));
129
+ if (child->role & BDRV_CHILD_PRIMARY) {
130
+ assert(child->role & BDRV_CHILD_FILTERED);
131
+ assert(!bs->backing);
132
+ assert(!bs->file);
133
+
134
+ if (bs->drv->filtered_child_is_backing) {
135
+ bs->backing = child;
136
+ } else {
137
+ bs->file = child;
138
+ }
139
+ } else {
140
+ assert(!(child->role & BDRV_CHILD_FILTERED));
141
+ }
142
+ } else if (child->role & BDRV_CHILD_COW) {
143
+ assert(bs->drv->supports_backing);
144
+ assert(!(child->role & BDRV_CHILD_PRIMARY));
145
+ assert(!bs->backing);
146
+ bs->backing = child;
147
bdrv_backing_attach(child);
148
+ } else if (child->role & BDRV_CHILD_PRIMARY) {
149
+ assert(!bs->file);
150
+ bs->file = child;
151
}
152
153
bdrv_apply_subtree_drain(child, bs);
154
@@ -XXX,XX +XXX,XX @@ static void bdrv_child_cb_detach(BdrvChild *child)
155
156
assert_bdrv_graph_writable(bs);
157
QLIST_REMOVE(child, next);
158
+ if (child == bs->backing) {
159
+ assert(child != bs->file);
160
+ bs->backing = NULL;
161
+ } else if (child == bs->file) {
162
+ bs->file = NULL;
163
+ }
164
}
165
166
static int bdrv_child_cb_update_filename(BdrvChild *c, BlockDriverState *base,
167
@@ -XXX,XX +XXX,XX @@ open_failed:
168
bs->drv = NULL;
169
if (bs->file != NULL) {
170
bdrv_unref_child(bs, bs->file);
171
- bs->file = NULL;
172
+ assert(!bs->file);
173
}
174
g_free(bs->opaque);
175
bs->opaque = NULL;
176
@@ -XXX,XX +XXX,XX @@ static void bdrv_child_free(BdrvChild *child)
177
}
178
179
typedef struct BdrvAttachChildCommonState {
180
- BdrvChild **child;
181
+ BdrvChild *child;
182
AioContext *old_parent_ctx;
183
AioContext *old_child_ctx;
184
} BdrvAttachChildCommonState;
185
@@ -XXX,XX +XXX,XX @@ typedef struct BdrvAttachChildCommonState {
186
static void bdrv_attach_child_common_abort(void *opaque)
187
{
188
BdrvAttachChildCommonState *s = opaque;
189
- BdrvChild *child = *s->child;
190
- BlockDriverState *bs = child->bs;
191
+ BlockDriverState *bs = s->child->bs;
192
193
GLOBAL_STATE_CODE();
194
- bdrv_replace_child_noperm(child, NULL);
195
+ bdrv_replace_child_noperm(s->child, NULL);
196
197
if (bdrv_get_aio_context(bs) != s->old_child_ctx) {
198
bdrv_try_set_aio_context(bs, s->old_child_ctx, &error_abort);
199
}
200
201
- if (bdrv_child_get_parent_aio_context(child) != s->old_parent_ctx) {
202
+ if (bdrv_child_get_parent_aio_context(s->child) != s->old_parent_ctx) {
203
GSList *ignore;
204
205
/* No need to ignore `child`, because it has been detached already */
206
ignore = NULL;
207
- child->klass->can_set_aio_ctx(child, s->old_parent_ctx, &ignore,
208
- &error_abort);
209
+ s->child->klass->can_set_aio_ctx(s->child, s->old_parent_ctx, &ignore,
210
+ &error_abort);
211
g_slist_free(ignore);
212
213
ignore = NULL;
214
- child->klass->set_aio_ctx(child, s->old_parent_ctx, &ignore);
215
+ s->child->klass->set_aio_ctx(s->child, s->old_parent_ctx, &ignore);
216
g_slist_free(ignore);
217
}
218
219
bdrv_unref(bs);
220
- bdrv_child_free(child);
221
- *s->child = NULL;
222
+ bdrv_child_free(s->child);
223
}
224
225
static TransactionActionDrv bdrv_attach_child_common_drv = {
226
@@ -XXX,XX +XXX,XX @@ static TransactionActionDrv bdrv_attach_child_common_drv = {
227
/*
228
* Common part of attaching bdrv child to bs or to blk or to job
229
*
230
- * Resulting new child is returned through @child.
231
- * At start *@child must be NULL.
232
- * @child is saved to a new entry of @tran, so that *@child could be reverted to
233
- * NULL on abort(). So referenced variable must live at least until transaction
234
- * end.
235
- *
236
* Function doesn't update permissions, caller is responsible for this.
237
+ *
238
+ * Returns new created child.
239
*/
240
-static int bdrv_attach_child_common(BlockDriverState *child_bs,
241
- const char *child_name,
242
- const BdrvChildClass *child_class,
243
- BdrvChildRole child_role,
244
- uint64_t perm, uint64_t shared_perm,
245
- void *opaque, BdrvChild **child,
246
- Transaction *tran, Error **errp)
247
+static BdrvChild *bdrv_attach_child_common(BlockDriverState *child_bs,
248
+ const char *child_name,
249
+ const BdrvChildClass *child_class,
250
+ BdrvChildRole child_role,
251
+ uint64_t perm, uint64_t shared_perm,
252
+ void *opaque,
253
+ Transaction *tran, Error **errp)
254
{
255
BdrvChild *new_child;
256
AioContext *parent_ctx;
257
AioContext *child_ctx = bdrv_get_aio_context(child_bs);
258
259
- assert(child);
260
- assert(*child == NULL);
261
assert(child_class->get_parent_desc);
262
GLOBAL_STATE_CODE();
263
264
@@ -XXX,XX +XXX,XX @@ static int bdrv_attach_child_common(BlockDriverState *child_bs,
265
if (ret < 0) {
266
error_propagate(errp, local_err);
267
bdrv_child_free(new_child);
268
- return ret;
269
+ return NULL;
270
}
271
}
272
273
bdrv_ref(child_bs);
274
bdrv_replace_child_noperm(new_child, child_bs);
275
276
- *child = new_child;
277
-
278
BdrvAttachChildCommonState *s = g_new(BdrvAttachChildCommonState, 1);
279
*s = (BdrvAttachChildCommonState) {
280
- .child = child,
281
+ .child = new_child,
282
.old_parent_ctx = parent_ctx,
283
.old_child_ctx = child_ctx,
284
};
285
tran_add(tran, &bdrv_attach_child_common_drv, s);
286
287
- return 0;
288
+ return new_child;
289
}
290
291
/*
292
- * Variable referenced by @child must live at least until transaction end.
293
- * (see bdrv_attach_child_common() doc for details)
294
- *
295
* Function doesn't update permissions, caller is responsible for this.
296
*/
297
-static int bdrv_attach_child_noperm(BlockDriverState *parent_bs,
298
- BlockDriverState *child_bs,
299
- const char *child_name,
300
- const BdrvChildClass *child_class,
301
- BdrvChildRole child_role,
302
- BdrvChild **child,
303
- Transaction *tran,
304
- Error **errp)
305
+static BdrvChild *bdrv_attach_child_noperm(BlockDriverState *parent_bs,
306
+ BlockDriverState *child_bs,
307
+ const char *child_name,
308
+ const BdrvChildClass *child_class,
309
+ BdrvChildRole child_role,
310
+ Transaction *tran,
311
+ Error **errp)
312
{
313
- int ret;
314
uint64_t perm, shared_perm;
315
316
assert(parent_bs->drv);
317
@@ -XXX,XX +XXX,XX @@ static int bdrv_attach_child_noperm(BlockDriverState *parent_bs,
318
if (bdrv_recurse_has_child(child_bs, parent_bs)) {
319
error_setg(errp, "Making '%s' a %s child of '%s' would create a cycle",
320
child_bs->node_name, child_name, parent_bs->node_name);
321
- return -EINVAL;
322
+ return NULL;
323
}
324
325
bdrv_get_cumulative_perm(parent_bs, &perm, &shared_perm);
326
bdrv_child_perm(parent_bs, child_bs, NULL, child_role, NULL,
327
perm, shared_perm, &perm, &shared_perm);
328
329
- ret = bdrv_attach_child_common(child_bs, child_name, child_class,
330
- child_role, perm, shared_perm, parent_bs,
331
- child, tran, errp);
332
- if (ret < 0) {
333
- return ret;
334
- }
335
-
336
- return 0;
337
+ return bdrv_attach_child_common(child_bs, child_name, child_class,
338
+ child_role, perm, shared_perm, parent_bs,
339
+ tran, errp);
340
}
341
342
static void bdrv_detach_child(BdrvChild *child)
343
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
344
void *opaque, Error **errp)
345
{
346
int ret;
347
- BdrvChild *child = NULL;
348
+ BdrvChild *child;
349
Transaction *tran = tran_new();
350
351
GLOBAL_STATE_CODE();
352
353
- ret = bdrv_attach_child_common(child_bs, child_name, child_class,
354
+ child = bdrv_attach_child_common(child_bs, child_name, child_class,
355
child_role, perm, shared_perm, opaque,
356
- &child, tran, errp);
357
- if (ret < 0) {
358
+ tran, errp);
359
+ if (!child) {
360
+ ret = -EINVAL;
361
goto out;
362
}
363
364
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
365
366
out:
367
tran_finalize(tran, ret);
368
- /* child is unset on failure by bdrv_attach_child_common_abort() */
369
- assert((ret < 0) == !child);
370
371
bdrv_unref(child_bs);
372
- return child;
373
+
374
+ return ret < 0 ? NULL : child;
375
}
376
377
/*
378
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
379
Error **errp)
380
{
381
int ret;
382
- BdrvChild *child = NULL;
383
+ BdrvChild *child;
384
Transaction *tran = tran_new();
385
386
GLOBAL_STATE_CODE();
387
388
- ret = bdrv_attach_child_noperm(parent_bs, child_bs, child_name, child_class,
389
- child_role, &child, tran, errp);
390
- if (ret < 0) {
391
+ child = bdrv_attach_child_noperm(parent_bs, child_bs, child_name,
392
+ child_class, child_role, tran, errp);
393
+ if (!child) {
394
+ ret = -EINVAL;
395
goto out;
396
}
397
398
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
399
400
out:
401
tran_finalize(tran, ret);
402
- /* child is unset on failure by bdrv_attach_child_common_abort() */
403
- assert((ret < 0) == !child);
404
405
bdrv_unref(child_bs);
406
407
- return child;
408
+ return ret < 0 ? NULL : child;
409
}
410
411
/* Callers must ensure that child->frozen is false. */
412
@@ -XXX,XX +XXX,XX @@ static int bdrv_set_file_or_backing_noperm(BlockDriverState *parent_bs,
413
bool is_backing,
414
Transaction *tran, Error **errp)
415
{
416
- int ret = 0;
417
bool update_inherits_from =
418
bdrv_inherits_from_recursive(child_bs, parent_bs);
419
BdrvChild *child = is_backing ? parent_bs->backing : parent_bs->file;
420
@@ -XXX,XX +XXX,XX @@ static int bdrv_set_file_or_backing_noperm(BlockDriverState *parent_bs,
421
goto out;
422
}
423
424
- ret = bdrv_attach_child_noperm(parent_bs, child_bs,
425
- is_backing ? "backing" : "file",
426
- &child_of_bds, role,
427
- is_backing ? &parent_bs->backing :
428
- &parent_bs->file,
429
- tran, errp);
430
- if (ret < 0) {
431
- return ret;
432
+ child = bdrv_attach_child_noperm(parent_bs, child_bs,
433
+ is_backing ? "backing" : "file",
434
+ &child_of_bds, role,
435
+ tran, errp);
436
+ if (!child) {
437
+ return -EINVAL;
438
}
439
440
441
@@ -XXX,XX +XXX,XX @@ int bdrv_open_file_child(const char *filename,
442
443
/* commit_top and mirror_top don't use this function */
444
assert(!parent->drv->filtered_child_is_backing);
445
-
446
role = parent->drv->is_filter ?
447
(BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY) : BDRV_CHILD_IMAGE;
448
449
- parent->file = bdrv_open_child(filename, options, bdref_key, parent,
450
- &child_of_bds, role, false, errp);
451
+ if (!bdrv_open_child(filename, options, bdref_key, parent,
452
+ &child_of_bds, role, false, errp))
453
+ {
454
+ return -EINVAL;
455
+ }
456
457
- return parent->file ? 0 : -EINVAL;
458
+ return 0;
459
}
460
461
/*
462
@@ -XXX,XX +XXX,XX @@ static void bdrv_close(BlockDriverState *bs)
463
bdrv_unref_child(bs, child);
464
}
465
466
- bs->backing = NULL;
467
- bs->file = NULL;
468
+ assert(!bs->backing);
469
+ assert(!bs->file);
470
g_free(bs->opaque);
471
bs->opaque = NULL;
472
qatomic_set(&bs->copy_on_read, 0);
473
@@ -XXX,XX +XXX,XX @@ static bool should_update_child(BdrvChild *c, BlockDriverState *to)
474
return ret;
475
}
476
477
-typedef struct BdrvRemoveFilterOrCowChild {
478
- BdrvChild *child;
479
- bool is_backing;
480
-} BdrvRemoveFilterOrCowChild;
481
-
482
-static void bdrv_remove_filter_or_cow_child_abort(void *opaque)
483
-{
484
- BdrvRemoveFilterOrCowChild *s = opaque;
485
- BlockDriverState *parent_bs = s->child->opaque;
486
-
487
- if (s->is_backing) {
488
- parent_bs->backing = s->child;
489
- } else {
490
- parent_bs->file = s->child;
491
- }
492
-
493
- /*
494
- * We don't have to restore child->bs here to undo bdrv_replace_child_tran()
495
- * because that function is transactionable and it registered own completion
496
- * entries in @tran, so .abort() for bdrv_replace_child_safe() will be
497
- * called automatically.
498
- */
499
-}
500
-
501
static void bdrv_remove_filter_or_cow_child_commit(void *opaque)
502
{
503
- BdrvRemoveFilterOrCowChild *s = opaque;
504
GLOBAL_STATE_CODE();
505
- bdrv_child_free(s->child);
506
+ bdrv_child_free(opaque);
507
}
508
509
static TransactionActionDrv bdrv_remove_filter_or_cow_child_drv = {
510
- .abort = bdrv_remove_filter_or_cow_child_abort,
511
.commit = bdrv_remove_filter_or_cow_child_commit,
512
- .clean = g_free,
513
};
514
515
/*
516
@@ -XXX,XX +XXX,XX @@ static void bdrv_remove_file_or_backing_child(BlockDriverState *bs,
517
BdrvChild *child,
518
Transaction *tran)
519
{
520
- BdrvRemoveFilterOrCowChild *s;
521
-
522
assert(child == bs->backing || child == bs->file);
523
524
if (!child) {
525
@@ -XXX,XX +XXX,XX @@ static void bdrv_remove_file_or_backing_child(BlockDriverState *bs,
526
bdrv_replace_child_tran(child, NULL, tran);
527
}
528
529
- s = g_new(BdrvRemoveFilterOrCowChild, 1);
530
- *s = (BdrvRemoveFilterOrCowChild) {
531
- .child = child,
532
- .is_backing = (child == bs->backing),
533
- };
534
- tran_add(tran, &bdrv_remove_filter_or_cow_child_drv, s);
535
-
536
- if (s->is_backing) {
537
- bs->backing = NULL;
538
- } else {
539
- bs->file = NULL;
540
- }
541
+ tran_add(tran, &bdrv_remove_filter_or_cow_child_drv, child);
542
}
543
544
/*
545
@@ -XXX,XX +XXX,XX @@ int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top,
546
Error **errp)
547
{
548
int ret;
549
+ BdrvChild *child;
550
Transaction *tran = tran_new();
551
552
GLOBAL_STATE_CODE();
553
554
assert(!bs_new->backing);
555
556
- ret = bdrv_attach_child_noperm(bs_new, bs_top, "backing",
557
- &child_of_bds, bdrv_backing_role(bs_new),
558
- &bs_new->backing, tran, errp);
559
- if (ret < 0) {
560
+ child = bdrv_attach_child_noperm(bs_new, bs_top, "backing",
561
+ &child_of_bds, bdrv_backing_role(bs_new),
562
+ tran, errp);
563
+ if (!child) {
564
+ ret = -EINVAL;
565
goto out;
566
}
567
568
diff --git a/block/raw-format.c b/block/raw-format.c
569
index XXXXXXX..XXXXXXX 100644
570
--- a/block/raw-format.c
571
+++ b/block/raw-format.c
572
@@ -XXX,XX +XXX,XX @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
573
file_role = BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY;
574
}
575
576
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
577
- file_role, false, errp);
578
+ bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
579
+ file_role, false, errp);
580
if (!bs->file) {
581
return -EINVAL;
582
}
583
diff --git a/block/snapshot-access.c b/block/snapshot-access.c
584
index XXXXXXX..XXXXXXX 100644
585
--- a/block/snapshot-access.c
586
+++ b/block/snapshot-access.c
587
@@ -XXX,XX +XXX,XX @@ static void snapshot_access_refresh_filename(BlockDriverState *bs)
588
static int snapshot_access_open(BlockDriverState *bs, QDict *options, int flags,
589
Error **errp)
590
{
591
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
592
- BDRV_CHILD_DATA | BDRV_CHILD_PRIMARY,
593
- false, errp);
594
+ bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
595
+ BDRV_CHILD_DATA | BDRV_CHILD_PRIMARY,
596
+ false, errp);
597
if (!bs->file) {
598
return -EINVAL;
599
}
600
diff --git a/block/snapshot.c b/block/snapshot.c
601
index XXXXXXX..XXXXXXX 100644
602
--- a/block/snapshot.c
603
+++ b/block/snapshot.c
604
@@ -XXX,XX +XXX,XX @@ int bdrv_snapshot_goto(BlockDriverState *bs,
605
606
/* .bdrv_open() will re-attach it */
607
bdrv_unref_child(bs, *fallback_ptr);
608
- *fallback_ptr = NULL;
609
610
ret = bdrv_snapshot_goto(fallback_bs, snapshot_id, errp);
611
open_ret = drv->bdrv_open(bs, options, bs->open_flags, &local_err);
612
diff --git a/tests/unit/test-bdrv-drain.c b/tests/unit/test-bdrv-drain.c
613
index XXXXXXX..XXXXXXX 100644
614
--- a/tests/unit/test-bdrv-drain.c
615
+++ b/tests/unit/test-bdrv-drain.c
616
@@ -XXX,XX +XXX,XX @@ static void test_drop_intermediate_poll(void)
617
for (i = 0; i < 3; i++) {
618
if (i) {
619
/* Takes the reference to chain[i - 1] */
620
- chain[i]->backing = bdrv_attach_child(chain[i], chain[i - 1],
621
- "chain", &chain_child_class,
622
- BDRV_CHILD_COW, &error_abort);
623
+ bdrv_attach_child(chain[i], chain[i - 1], "chain",
624
+ &chain_child_class, BDRV_CHILD_COW, &error_abort);
625
}
626
}
627
628
@@ -XXX,XX +XXX,XX @@ static void do_test_replace_child_mid_drain(int old_drain_count,
629
new_child_bs->total_sectors = 1;
630
631
bdrv_ref(old_child_bs);
632
- parent_bs->backing = bdrv_attach_child(parent_bs, old_child_bs, "child",
633
- &child_of_bds, BDRV_CHILD_COW,
634
- &error_abort);
635
+ bdrv_attach_child(parent_bs, old_child_bs, "child", &child_of_bds,
636
+ BDRV_CHILD_COW, &error_abort);
637
638
for (i = 0; i < old_drain_count; i++) {
639
bdrv_drained_begin(old_child_bs);
640
--
641
2.37.3
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
1
2
3
Now the indirection is not actually used, we can safely reduce it to
4
simple pointer. For consistency do a bit of refactoring to get rid of
5
_ptr suffixes that become meaningless.
6
7
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
8
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
9
Message-Id: <20220726201134.924743-15-vsementsov@yandex-team.ru>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
12
block/snapshot.c | 38 ++++++++++++++++----------------------
13
1 file changed, 16 insertions(+), 22 deletions(-)
14
15
diff --git a/block/snapshot.c b/block/snapshot.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/block/snapshot.c
18
+++ b/block/snapshot.c
19
@@ -XXX,XX +XXX,XX @@ bool bdrv_snapshot_find_by_id_and_name(BlockDriverState *bs,
20
}
21
22
/**
23
- * Return a pointer to the child BDS pointer to which we can fall
24
+ * Return a pointer to child of given BDS to which we can fall
25
* back if the given BDS does not support snapshots.
26
* Return NULL if there is no BDS to (safely) fall back to.
27
- *
28
- * We need to return an indirect pointer because bdrv_snapshot_goto()
29
- * has to modify the BdrvChild pointer.
30
*/
31
-static BdrvChild **bdrv_snapshot_fallback_ptr(BlockDriverState *bs)
32
+static BdrvChild *bdrv_snapshot_fallback_child(BlockDriverState *bs)
33
{
34
- BdrvChild **fallback;
35
- BdrvChild *child = bdrv_primary_child(bs);
36
+ BdrvChild *fallback = bdrv_primary_child(bs);
37
+ BdrvChild *child;
38
39
/* We allow fallback only to primary child */
40
- if (!child) {
41
+ if (!fallback) {
42
return NULL;
43
}
44
- fallback = (child == bs->file ? &bs->file : &bs->backing);
45
- assert(*fallback == child);
46
47
/*
48
* Check that there are no other children that would need to be
49
* snapshotted. If there are, it is not safe to fall back to
50
- * *fallback.
51
+ * fallback.
52
*/
53
QLIST_FOREACH(child, &bs->children, next) {
54
if (child->role & (BDRV_CHILD_DATA | BDRV_CHILD_METADATA |
55
BDRV_CHILD_FILTERED) &&
56
- child != *fallback)
57
+ child != fallback)
58
{
59
return NULL;
60
}
61
@@ -XXX,XX +XXX,XX @@ static BdrvChild **bdrv_snapshot_fallback_ptr(BlockDriverState *bs)
62
63
static BlockDriverState *bdrv_snapshot_fallback(BlockDriverState *bs)
64
{
65
- BdrvChild **child_ptr = bdrv_snapshot_fallback_ptr(bs);
66
- return child_ptr ? (*child_ptr)->bs : NULL;
67
+ return child_bs(bdrv_snapshot_fallback_child(bs));
68
}
69
70
int bdrv_can_snapshot(BlockDriverState *bs)
71
@@ -XXX,XX +XXX,XX @@ int bdrv_snapshot_goto(BlockDriverState *bs,
72
Error **errp)
73
{
74
BlockDriver *drv = bs->drv;
75
- BdrvChild **fallback_ptr;
76
+ BdrvChild *fallback;
77
int ret, open_ret;
78
79
GLOBAL_STATE_CODE();
80
@@ -XXX,XX +XXX,XX @@ int bdrv_snapshot_goto(BlockDriverState *bs,
81
return ret;
82
}
83
84
- fallback_ptr = bdrv_snapshot_fallback_ptr(bs);
85
- if (fallback_ptr) {
86
+ fallback = bdrv_snapshot_fallback_child(bs);
87
+ if (fallback) {
88
QDict *options;
89
QDict *file_options;
90
Error *local_err = NULL;
91
- BlockDriverState *fallback_bs = (*fallback_ptr)->bs;
92
- char *subqdict_prefix = g_strdup_printf("%s.", (*fallback_ptr)->name);
93
+ BlockDriverState *fallback_bs = fallback->bs;
94
+ char *subqdict_prefix = g_strdup_printf("%s.", fallback->name);
95
96
options = qdict_clone_shallow(bs->options);
97
98
@@ -XXX,XX +XXX,XX @@ int bdrv_snapshot_goto(BlockDriverState *bs,
99
qobject_unref(file_options);
100
g_free(subqdict_prefix);
101
102
- /* Force .bdrv_open() below to re-attach fallback_bs on *fallback_ptr */
103
- qdict_put_str(options, (*fallback_ptr)->name,
104
+ /* Force .bdrv_open() below to re-attach fallback_bs on fallback */
105
+ qdict_put_str(options, fallback->name,
106
bdrv_get_node_name(fallback_bs));
107
108
/* Now close bs, apply the snapshot on fallback_bs, and re-open bs */
109
@@ -XXX,XX +XXX,XX @@ int bdrv_snapshot_goto(BlockDriverState *bs,
110
}
111
112
/* .bdrv_open() will re-attach it */
113
- bdrv_unref_child(bs, *fallback_ptr);
114
+ bdrv_unref_child(bs, fallback);
115
116
ret = bdrv_snapshot_goto(fallback_bs, snapshot_id, errp);
117
open_ret = drv->bdrv_open(bs, options, bs->open_flags, &local_err);
118
--
119
2.37.3
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
1
2
3
Now the function can remove any child, so give it more common name.
4
Drop assertions and drop bs argument which becomes unused. Function
5
would be reused in a further commit.
6
7
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
8
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
9
Message-Id: <20220726201134.924743-16-vsementsov@yandex-team.ru>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
12
block.c | 27 +++++++++------------------
13
1 file changed, 9 insertions(+), 18 deletions(-)
14
15
diff --git a/block.c b/block.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/block.c
18
+++ b/block.c
19
@@ -XXX,XX +XXX,XX @@ static bool bdrv_recurse_has_child(BlockDriverState *bs,
20
21
static void bdrv_replace_child_noperm(BdrvChild *child,
22
BlockDriverState *new_bs);
23
-static void bdrv_remove_file_or_backing_child(BlockDriverState *bs,
24
- BdrvChild *child,
25
- Transaction *tran);
26
+static void bdrv_remove_child(BdrvChild *child, Transaction *tran);
27
static void bdrv_remove_filter_or_cow_child(BlockDriverState *bs,
28
Transaction *tran);
29
30
@@ -XXX,XX +XXX,XX @@ static int bdrv_set_file_or_backing_noperm(BlockDriverState *parent_bs,
31
32
if (child) {
33
bdrv_unset_inherits_from(parent_bs, child, tran);
34
- bdrv_remove_file_or_backing_child(parent_bs, child, tran);
35
+ bdrv_remove_child(child, tran);
36
}
37
38
if (!child_bs) {
39
@@ -XXX,XX +XXX,XX @@ static bool should_update_child(BdrvChild *c, BlockDriverState *to)
40
return ret;
41
}
42
43
-static void bdrv_remove_filter_or_cow_child_commit(void *opaque)
44
+static void bdrv_remove_child_commit(void *opaque)
45
{
46
GLOBAL_STATE_CODE();
47
bdrv_child_free(opaque);
48
}
49
50
-static TransactionActionDrv bdrv_remove_filter_or_cow_child_drv = {
51
- .commit = bdrv_remove_filter_or_cow_child_commit,
52
+static TransactionActionDrv bdrv_remove_child_drv = {
53
+ .commit = bdrv_remove_child_commit,
54
};
55
56
-/*
57
- * A function to remove backing or file child of @bs.
58
- * Function doesn't update permissions, caller is responsible for this.
59
- */
60
-static void bdrv_remove_file_or_backing_child(BlockDriverState *bs,
61
- BdrvChild *child,
62
- Transaction *tran)
63
+/* Function doesn't update permissions, caller is responsible for this. */
64
+static void bdrv_remove_child(BdrvChild *child, Transaction *tran)
65
{
66
- assert(child == bs->backing || child == bs->file);
67
-
68
if (!child) {
69
return;
70
}
71
@@ -XXX,XX +XXX,XX @@ static void bdrv_remove_file_or_backing_child(BlockDriverState *bs,
72
bdrv_replace_child_tran(child, NULL, tran);
73
}
74
75
- tran_add(tran, &bdrv_remove_filter_or_cow_child_drv, child);
76
+ tran_add(tran, &bdrv_remove_child_drv, child);
77
}
78
79
/*
80
@@ -XXX,XX +XXX,XX @@ static void bdrv_remove_file_or_backing_child(BlockDriverState *bs,
81
static void bdrv_remove_filter_or_cow_child(BlockDriverState *bs,
82
Transaction *tran)
83
{
84
- bdrv_remove_file_or_backing_child(bs, bdrv_filter_or_cow_child(bs), tran);
85
+ bdrv_remove_child(bdrv_filter_or_cow_child(bs), tran);
86
}
87
88
static int bdrv_replace_node_noperm(BlockDriverState *from,
89
--
90
2.37.3
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
Also here ->aio_context is read by I/O threads and written
4
under BQL.
5
6
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
7
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
8
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
9
Message-Id: <20221025084952.2139888-2-eesposit@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
12
block.c | 2 ++
13
1 file changed, 2 insertions(+)
14
15
diff --git a/block.c b/block.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/block.c
18
+++ b/block.c
19
@@ -XXX,XX +XXX,XX @@ static void bdrv_detach_aio_context(BlockDriverState *bs)
20
if (bs->quiesce_counter) {
21
aio_enable_external(bs->aio_context);
22
}
23
+ assert_bdrv_graph_writable(bs);
24
bs->aio_context = NULL;
25
}
26
27
@@ -XXX,XX +XXX,XX @@ static void bdrv_attach_aio_context(BlockDriverState *bs,
28
aio_disable_external(new_context);
29
}
30
31
+ assert_bdrv_graph_writable(bs);
32
bs->aio_context = new_context;
33
34
if (bs->drv && bs->drv->bdrv_attach_aio_context) {
35
--
36
2.37.3
diff view generated by jsdifflib
New patch
1
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
2
3
Simplify the way the aiocontext can be changed in a BDS graph.
4
There are currently two problems in bdrv_try_set_aio_context:
5
- There is a confusion of AioContext locks taken and released, because
6
we assume that old aiocontext is always taken and new one is
7
taken inside.
8
9
- It doesn't look very safe to call bdrv_drained_begin while some
10
nodes have already switched to the new aiocontext and others haven't.
11
This could be especially dangerous because bdrv_drained_begin polls, so
12
something else could be executed while graph is in an inconsistent
13
state.
14
15
Additional minor nitpick: can_set and set_ callbacks both traverse the
16
graph, both using the ignored list of visited nodes in a different way.
17
18
Therefore, get rid of all of this and introduce a new callback,
19
change_aio_context, that uses transactions to efficiently, cleanly
20
and most importantly safely change the aiocontext of a graph.
21
22
This new callback is a "merge" of the two previous ones:
23
- Just like can_set_aio_context, recursively traverses the graph.
24
Marks all nodes that are visited using a GList, and checks if
25
they *could* change the aio_context.
26
- For each node that passes the above check, drain it and add a new transaction
27
that implements a callback that effectively changes the aiocontext.
28
- Once done, the recursive function returns if *all* nodes can change
29
the AioContext. If so, commit the above transactions.
30
Regardless of the outcome, call transaction.clean() to undo all drains
31
done in the recursion.
32
- The transaction list is scanned only after all nodes are being drained, so
33
we are sure that they all are in the same context, and then
34
we switch their AioContext, concluding the drain only after all nodes
35
switched to the new AioContext. In this way we make sure that
36
bdrv_drained_begin() is always called under the old AioContext, and
37
bdrv_drained_end() under the new one.
38
- Because of the above, we don't need to release and re-acquire the
39
old AioContext every time, as everything is done once (and not
40
per-node drain and aiocontext change).
41
42
Note that the "change" API is not yet invoked anywhere.
43
44
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
45
Message-Id: <20221025084952.2139888-3-eesposit@redhat.com>
46
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
47
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
48
---
49
include/block/block-global-state.h | 6 +
50
include/block/block_int-common.h | 3 +
51
block.c | 220 ++++++++++++++++++++++++++++-
52
3 files changed, 228 insertions(+), 1 deletion(-)
53
54
diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h
55
index XXXXXXX..XXXXXXX 100644
56
--- a/include/block/block-global-state.h
57
+++ b/include/block/block-global-state.h
58
@@ -XXX,XX +XXX,XX @@ bool bdrv_can_set_aio_context(BlockDriverState *bs, AioContext *ctx,
59
GSList **ignore, Error **errp);
60
AioContext *bdrv_child_get_parent_aio_context(BdrvChild *c);
61
62
+bool bdrv_child_change_aio_context(BdrvChild *c, AioContext *ctx,
63
+ GSList **visited, Transaction *tran,
64
+ Error **errp);
65
+int bdrv_child_try_change_aio_context(BlockDriverState *bs, AioContext *ctx,
66
+ BdrvChild *ignore_child, Error **errp);
67
+
68
int bdrv_probe_blocksizes(BlockDriverState *bs, BlockSizes *bsz);
69
int bdrv_probe_geometry(BlockDriverState *bs, HDGeometry *geo);
70
71
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
72
index XXXXXXX..XXXXXXX 100644
73
--- a/include/block/block_int-common.h
74
+++ b/include/block/block_int-common.h
75
@@ -XXX,XX +XXX,XX @@ struct BdrvChildClass {
76
GSList **ignore, Error **errp);
77
void (*set_aio_ctx)(BdrvChild *child, AioContext *ctx, GSList **ignore);
78
79
+ bool (*change_aio_ctx)(BdrvChild *child, AioContext *ctx,
80
+ GSList **visited, Transaction *tran, Error **errp);
81
+
82
AioContext *(*get_parent_aio_context)(BdrvChild *child);
83
84
/*
85
diff --git a/block.c b/block.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/block.c
88
+++ b/block.c
89
@@ -XXX,XX +XXX,XX @@ static void bdrv_reopen_abort(BDRVReopenState *reopen_state);
90
91
static bool bdrv_backing_overridden(BlockDriverState *bs);
92
93
+static bool bdrv_change_aio_context(BlockDriverState *bs, AioContext *ctx,
94
+ GSList **visited, Transaction *tran,
95
+ Error **errp);
96
+
97
/* If non-zero, use only whitelisted block drivers */
98
static int use_bdrv_whitelist;
99
100
@@ -XXX,XX +XXX,XX @@ static void bdrv_attach_aio_context(BlockDriverState *bs,
101
* must not own the AioContext lock for new_context (unless new_context is the
102
* same as the current context of bs).
103
*
104
- * @ignore will accumulate all visited BdrvChild object. The caller is
105
+ * @ignore will accumulate all visited BdrvChild objects. The caller is
106
* responsible for freeing the list afterwards.
107
*/
108
void bdrv_set_aio_context_ignore(BlockDriverState *bs,
109
@@ -XXX,XX +XXX,XX @@ static bool bdrv_parent_can_set_aio_context(BdrvChild *c, AioContext *ctx,
110
return true;
111
}
112
113
+typedef struct BdrvStateSetAioContext {
114
+ AioContext *new_ctx;
115
+ BlockDriverState *bs;
116
+} BdrvStateSetAioContext;
117
+
118
+static bool bdrv_parent_change_aio_context(BdrvChild *c, AioContext *ctx,
119
+ GSList **visited, Transaction *tran,
120
+ Error **errp)
121
+{
122
+ GLOBAL_STATE_CODE();
123
+ if (g_slist_find(*visited, c)) {
124
+ return true;
125
+ }
126
+ *visited = g_slist_prepend(*visited, c);
127
+
128
+ /*
129
+ * A BdrvChildClass that doesn't handle AioContext changes cannot
130
+ * tolerate any AioContext changes
131
+ */
132
+ if (!c->klass->change_aio_ctx) {
133
+ char *user = bdrv_child_user_desc(c);
134
+ error_setg(errp, "Changing iothreads is not supported by %s", user);
135
+ g_free(user);
136
+ return false;
137
+ }
138
+ if (!c->klass->change_aio_ctx(c, ctx, visited, tran, errp)) {
139
+ assert(!errp || *errp);
140
+ return false;
141
+ }
142
+ return true;
143
+}
144
+
145
bool bdrv_child_can_set_aio_context(BdrvChild *c, AioContext *ctx,
146
GSList **ignore, Error **errp)
147
{
148
@@ -XXX,XX +XXX,XX @@ bool bdrv_child_can_set_aio_context(BdrvChild *c, AioContext *ctx,
149
return bdrv_can_set_aio_context(c->bs, ctx, ignore, errp);
150
}
151
152
+bool bdrv_child_change_aio_context(BdrvChild *c, AioContext *ctx,
153
+ GSList **visited, Transaction *tran,
154
+ Error **errp)
155
+{
156
+ GLOBAL_STATE_CODE();
157
+ if (g_slist_find(*visited, c)) {
158
+ return true;
159
+ }
160
+ *visited = g_slist_prepend(*visited, c);
161
+ return bdrv_change_aio_context(c->bs, ctx, visited, tran, errp);
162
+}
163
+
164
/* @ignore will accumulate all visited BdrvChild object. The caller is
165
* responsible for freeing the list afterwards. */
166
bool bdrv_can_set_aio_context(BlockDriverState *bs, AioContext *ctx,
167
@@ -XXX,XX +XXX,XX @@ bool bdrv_can_set_aio_context(BlockDriverState *bs, AioContext *ctx,
168
return true;
169
}
170
171
+static void bdrv_set_aio_context_clean(void *opaque)
172
+{
173
+ BdrvStateSetAioContext *state = (BdrvStateSetAioContext *) opaque;
174
+ BlockDriverState *bs = (BlockDriverState *) state->bs;
175
+
176
+ /* Paired with bdrv_drained_begin in bdrv_change_aio_context() */
177
+ bdrv_drained_end(bs);
178
+
179
+ g_free(state);
180
+}
181
+
182
+static void bdrv_set_aio_context_commit(void *opaque)
183
+{
184
+ BdrvStateSetAioContext *state = (BdrvStateSetAioContext *) opaque;
185
+ BlockDriverState *bs = (BlockDriverState *) state->bs;
186
+ AioContext *new_context = state->new_ctx;
187
+ AioContext *old_context = bdrv_get_aio_context(bs);
188
+ assert_bdrv_graph_writable(bs);
189
+
190
+ /*
191
+ * Take the old AioContex when detaching it from bs.
192
+ * At this point, new_context lock is already acquired, and we are now
193
+ * also taking old_context. This is safe as long as bdrv_detach_aio_context
194
+ * does not call AIO_POLL_WHILE().
195
+ */
196
+ if (old_context != qemu_get_aio_context()) {
197
+ aio_context_acquire(old_context);
198
+ }
199
+ bdrv_detach_aio_context(bs);
200
+ if (old_context != qemu_get_aio_context()) {
201
+ aio_context_release(old_context);
202
+ }
203
+ bdrv_attach_aio_context(bs, new_context);
204
+}
205
+
206
+static TransactionActionDrv set_aio_context = {
207
+ .commit = bdrv_set_aio_context_commit,
208
+ .clean = bdrv_set_aio_context_clean,
209
+};
210
+
211
+/*
212
+ * Changes the AioContext used for fd handlers, timers, and BHs by this
213
+ * BlockDriverState and all its children and parents.
214
+ *
215
+ * Must be called from the main AioContext.
216
+ *
217
+ * The caller must own the AioContext lock for the old AioContext of bs, but it
218
+ * must not own the AioContext lock for new_context (unless new_context is the
219
+ * same as the current context of bs).
220
+ *
221
+ * @visited will accumulate all visited BdrvChild objects. The caller is
222
+ * responsible for freeing the list afterwards.
223
+ */
224
+static bool bdrv_change_aio_context(BlockDriverState *bs, AioContext *ctx,
225
+ GSList **visited, Transaction *tran,
226
+ Error **errp)
227
+{
228
+ BdrvChild *c;
229
+ BdrvStateSetAioContext *state;
230
+
231
+ GLOBAL_STATE_CODE();
232
+
233
+ if (bdrv_get_aio_context(bs) == ctx) {
234
+ return true;
235
+ }
236
+
237
+ QLIST_FOREACH(c, &bs->parents, next_parent) {
238
+ if (!bdrv_parent_change_aio_context(c, ctx, visited, tran, errp)) {
239
+ return false;
240
+ }
241
+ }
242
+
243
+ QLIST_FOREACH(c, &bs->children, next) {
244
+ if (!bdrv_child_change_aio_context(c, ctx, visited, tran, errp)) {
245
+ return false;
246
+ }
247
+ }
248
+
249
+ state = g_new(BdrvStateSetAioContext, 1);
250
+ *state = (BdrvStateSetAioContext) {
251
+ .new_ctx = ctx,
252
+ .bs = bs,
253
+ };
254
+
255
+ /* Paired with bdrv_drained_end in bdrv_set_aio_context_clean() */
256
+ bdrv_drained_begin(bs);
257
+
258
+ tran_add(tran, &set_aio_context, state);
259
+
260
+ return true;
261
+}
262
+
263
int bdrv_child_try_set_aio_context(BlockDriverState *bs, AioContext *ctx,
264
BdrvChild *ignore_child, Error **errp)
265
{
266
@@ -XXX,XX +XXX,XX @@ int bdrv_child_try_set_aio_context(BlockDriverState *bs, AioContext *ctx,
267
return 0;
268
}
269
270
+/*
271
+ * Change bs's and recursively all of its parents' and children's AioContext
272
+ * to the given new context, returning an error if that isn't possible.
273
+ *
274
+ * If ignore_child is not NULL, that child (and its subgraph) will not
275
+ * be touched.
276
+ *
277
+ * This function still requires the caller to take the bs current
278
+ * AioContext lock, otherwise draining will fail since AIO_WAIT_WHILE
279
+ * assumes the lock is always held if bs is in another AioContext.
280
+ * For the same reason, it temporarily also holds the new AioContext, since
281
+ * bdrv_drained_end calls BDRV_POLL_WHILE that assumes the lock is taken too.
282
+ * Therefore the new AioContext lock must not be taken by the caller.
283
+ */
284
+int bdrv_child_try_change_aio_context(BlockDriverState *bs, AioContext *ctx,
285
+ BdrvChild *ignore_child, Error **errp)
286
+{
287
+ Transaction *tran;
288
+ GSList *visited;
289
+ int ret;
290
+ AioContext *old_context = bdrv_get_aio_context(bs);
291
+ GLOBAL_STATE_CODE();
292
+
293
+ /*
294
+ * Recursion phase: go through all nodes of the graph.
295
+ * Take care of checking that all nodes support changing AioContext
296
+ * and drain them, builing a linear list of callbacks to run if everything
297
+ * is successful (the transaction itself).
298
+ */
299
+ tran = tran_new();
300
+ visited = ignore_child ? g_slist_prepend(NULL, ignore_child) : NULL;
301
+ ret = bdrv_change_aio_context(bs, ctx, &visited, tran, errp);
302
+ g_slist_free(visited);
303
+
304
+ /*
305
+ * Linear phase: go through all callbacks collected in the transaction.
306
+ * Run all callbacks collected in the recursion to switch all nodes
307
+ * AioContext lock (transaction commit), or undo all changes done in the
308
+ * recursion (transaction abort).
309
+ */
310
+
311
+ if (!ret) {
312
+ /* Just run clean() callbacks. No AioContext changed. */
313
+ tran_abort(tran);
314
+ return -EPERM;
315
+ }
316
+
317
+ /*
318
+ * Release old AioContext, it won't be needed anymore, as all
319
+ * bdrv_drained_begin() have been called already.
320
+ */
321
+ if (qemu_get_aio_context() != old_context) {
322
+ aio_context_release(old_context);
323
+ }
324
+
325
+ /*
326
+ * Acquire new AioContext since bdrv_drained_end() is going to be called
327
+ * after we switched all nodes in the new AioContext, and the function
328
+ * assumes that the lock of the bs is always taken.
329
+ */
330
+ if (qemu_get_aio_context() != ctx) {
331
+ aio_context_acquire(ctx);
332
+ }
333
+
334
+ tran_commit(tran);
335
+
336
+ if (qemu_get_aio_context() != ctx) {
337
+ aio_context_release(ctx);
338
+ }
339
+
340
+ /* Re-acquire the old AioContext, since the caller takes and releases it. */
341
+ if (qemu_get_aio_context() != old_context) {
342
+ aio_context_acquire(old_context);
343
+ }
344
+
345
+ return 0;
346
+}
347
+
348
int bdrv_try_set_aio_context(BlockDriverState *bs, AioContext *ctx,
349
Error **errp)
350
{
351
--
352
2.37.3
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
Minor performance improvement, but given that we have hash tables
4
available, avoid iterating in the visited nodes list every time just
5
to check if a node has been already visited.
6
7
The data structure is not actually a proper hash map, but an hash set,
8
as we are just adding nodes and not key,value pairs.
9
10
Suggested-by: Hanna Reitz <hreitz@redhat.com>
11
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
12
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
13
Message-Id: <20221025084952.2139888-4-eesposit@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
---
16
include/block/block-global-state.h | 2 +-
17
include/block/block_int-common.h | 3 ++-
18
block.c | 28 ++++++++++++++++------------
19
3 files changed, 19 insertions(+), 14 deletions(-)
20
21
diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/include/block/block-global-state.h
24
+++ b/include/block/block-global-state.h
25
@@ -XXX,XX +XXX,XX @@ bool bdrv_can_set_aio_context(BlockDriverState *bs, AioContext *ctx,
26
AioContext *bdrv_child_get_parent_aio_context(BdrvChild *c);
27
28
bool bdrv_child_change_aio_context(BdrvChild *c, AioContext *ctx,
29
- GSList **visited, Transaction *tran,
30
+ GHashTable *visited, Transaction *tran,
31
Error **errp);
32
int bdrv_child_try_change_aio_context(BlockDriverState *bs, AioContext *ctx,
33
BdrvChild *ignore_child, Error **errp);
34
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/include/block/block_int-common.h
37
+++ b/include/block/block_int-common.h
38
@@ -XXX,XX +XXX,XX @@ struct BdrvChildClass {
39
void (*set_aio_ctx)(BdrvChild *child, AioContext *ctx, GSList **ignore);
40
41
bool (*change_aio_ctx)(BdrvChild *child, AioContext *ctx,
42
- GSList **visited, Transaction *tran, Error **errp);
43
+ GHashTable *visited, Transaction *tran,
44
+ Error **errp);
45
46
AioContext *(*get_parent_aio_context)(BdrvChild *child);
47
48
diff --git a/block.c b/block.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/block.c
51
+++ b/block.c
52
@@ -XXX,XX +XXX,XX @@ static void bdrv_reopen_abort(BDRVReopenState *reopen_state);
53
static bool bdrv_backing_overridden(BlockDriverState *bs);
54
55
static bool bdrv_change_aio_context(BlockDriverState *bs, AioContext *ctx,
56
- GSList **visited, Transaction *tran,
57
+ GHashTable *visited, Transaction *tran,
58
Error **errp);
59
60
/* If non-zero, use only whitelisted block drivers */
61
@@ -XXX,XX +XXX,XX @@ typedef struct BdrvStateSetAioContext {
62
} BdrvStateSetAioContext;
63
64
static bool bdrv_parent_change_aio_context(BdrvChild *c, AioContext *ctx,
65
- GSList **visited, Transaction *tran,
66
+ GHashTable *visited,
67
+ Transaction *tran,
68
Error **errp)
69
{
70
GLOBAL_STATE_CODE();
71
- if (g_slist_find(*visited, c)) {
72
+ if (g_hash_table_contains(visited, c)) {
73
return true;
74
}
75
- *visited = g_slist_prepend(*visited, c);
76
+ g_hash_table_add(visited, c);
77
78
/*
79
* A BdrvChildClass that doesn't handle AioContext changes cannot
80
@@ -XXX,XX +XXX,XX @@ bool bdrv_child_can_set_aio_context(BdrvChild *c, AioContext *ctx,
81
}
82
83
bool bdrv_child_change_aio_context(BdrvChild *c, AioContext *ctx,
84
- GSList **visited, Transaction *tran,
85
+ GHashTable *visited, Transaction *tran,
86
Error **errp)
87
{
88
GLOBAL_STATE_CODE();
89
- if (g_slist_find(*visited, c)) {
90
+ if (g_hash_table_contains(visited, c)) {
91
return true;
92
}
93
- *visited = g_slist_prepend(*visited, c);
94
+ g_hash_table_add(visited, c);
95
return bdrv_change_aio_context(c->bs, ctx, visited, tran, errp);
96
}
97
98
@@ -XXX,XX +XXX,XX @@ static TransactionActionDrv set_aio_context = {
99
* responsible for freeing the list afterwards.
100
*/
101
static bool bdrv_change_aio_context(BlockDriverState *bs, AioContext *ctx,
102
- GSList **visited, Transaction *tran,
103
+ GHashTable *visited, Transaction *tran,
104
Error **errp)
105
{
106
BdrvChild *c;
107
@@ -XXX,XX +XXX,XX @@ int bdrv_child_try_change_aio_context(BlockDriverState *bs, AioContext *ctx,
108
BdrvChild *ignore_child, Error **errp)
109
{
110
Transaction *tran;
111
- GSList *visited;
112
+ GHashTable *visited;
113
int ret;
114
AioContext *old_context = bdrv_get_aio_context(bs);
115
GLOBAL_STATE_CODE();
116
@@ -XXX,XX +XXX,XX @@ int bdrv_child_try_change_aio_context(BlockDriverState *bs, AioContext *ctx,
117
* is successful (the transaction itself).
118
*/
119
tran = tran_new();
120
- visited = ignore_child ? g_slist_prepend(NULL, ignore_child) : NULL;
121
- ret = bdrv_change_aio_context(bs, ctx, &visited, tran, errp);
122
- g_slist_free(visited);
123
+ visited = g_hash_table_new(NULL, NULL);
124
+ if (ignore_child) {
125
+ g_hash_table_add(visited, ignore_child);
126
+ }
127
+ ret = bdrv_change_aio_context(bs, ctx, visited, tran, errp);
128
+ g_hash_table_destroy(visited);
129
130
/*
131
* Linear phase: go through all callbacks collected in the transaction.
132
--
133
2.37.3
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
child_job_change_aio_ctx() is very similar to
4
child_job_can_set_aio_ctx(), but it implements a new transaction
5
so that if all check pass, the new transaction's .commit()
6
will take care of changin the BlockJob AioContext.
7
child_job_set_aio_ctx_commit() is similar to child_job_set_aio_ctx(),
8
but it doesn't need to invoke the recursion, as this is already
9
taken care by child_job_change_aio_ctx().
10
11
Note: bdrv_child_try_change_aio_context() is not called by
12
anyone at this point.
13
14
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
15
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
16
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
17
Message-Id: <20221025084952.2139888-5-eesposit@redhat.com>
18
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
19
---
20
blockjob.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
21
1 file changed, 45 insertions(+)
22
23
diff --git a/blockjob.c b/blockjob.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/blockjob.c
26
+++ b/blockjob.c
27
@@ -XXX,XX +XXX,XX @@ static void child_job_drained_end(BdrvChild *c, int *drained_end_counter)
28
job_resume(&job->job);
29
}
30
31
+typedef struct BdrvStateChildJobContext {
32
+ AioContext *new_ctx;
33
+ BlockJob *job;
34
+} BdrvStateChildJobContext;
35
+
36
+static void child_job_set_aio_ctx_commit(void *opaque)
37
+{
38
+ BdrvStateChildJobContext *s = opaque;
39
+ BlockJob *job = s->job;
40
+
41
+ job_set_aio_context(&job->job, s->new_ctx);
42
+}
43
+
44
+static TransactionActionDrv change_child_job_context = {
45
+ .commit = child_job_set_aio_ctx_commit,
46
+ .clean = g_free,
47
+};
48
+
49
+static bool child_job_change_aio_ctx(BdrvChild *c, AioContext *ctx,
50
+ GHashTable *visited, Transaction *tran,
51
+ Error **errp)
52
+{
53
+ BlockJob *job = c->opaque;
54
+ BdrvStateChildJobContext *s;
55
+ GSList *l;
56
+
57
+ for (l = job->nodes; l; l = l->next) {
58
+ BdrvChild *sibling = l->data;
59
+ if (!bdrv_child_change_aio_context(sibling, ctx, visited,
60
+ tran, errp)) {
61
+ return false;
62
+ }
63
+ }
64
+
65
+ s = g_new(BdrvStateChildJobContext, 1);
66
+ *s = (BdrvStateChildJobContext) {
67
+ .new_ctx = ctx,
68
+ .job = job,
69
+ };
70
+
71
+ tran_add(tran, &change_child_job_context, s);
72
+ return true;
73
+}
74
+
75
static bool child_job_can_set_aio_ctx(BdrvChild *c, AioContext *ctx,
76
GSList **ignore, Error **errp)
77
{
78
@@ -XXX,XX +XXX,XX @@ static const BdrvChildClass child_job = {
79
.drained_end = child_job_drained_end,
80
.can_set_aio_ctx = child_job_can_set_aio_ctx,
81
.set_aio_ctx = child_job_set_aio_ctx,
82
+ .change_aio_ctx = child_job_change_aio_ctx,
83
.stay_at_node = true,
84
.get_parent_aio_context = child_job_get_parent_aio_context,
85
};
86
--
87
2.37.3
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
bdrv_child_cb_change_aio_ctx() is identical to
4
bdrv_child_cb_can_set_aio_ctx(), as we only need
5
to recursively go on the parent bs.
6
7
Note: bdrv_child_try_change_aio_context() is not called by
8
anyone at this point.
9
10
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
11
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
12
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
13
Message-Id: <20221025084952.2139888-6-eesposit@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
---
16
block.c | 9 +++++++++
17
1 file changed, 9 insertions(+)
18
19
diff --git a/block.c b/block.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/block.c
22
+++ b/block.c
23
@@ -XXX,XX +XXX,XX @@ static int bdrv_child_cb_inactivate(BdrvChild *child)
24
return 0;
25
}
26
27
+static bool bdrv_child_cb_change_aio_ctx(BdrvChild *child, AioContext *ctx,
28
+ GHashTable *visited, Transaction *tran,
29
+ Error **errp)
30
+{
31
+ BlockDriverState *bs = child->opaque;
32
+ return bdrv_change_aio_context(bs, ctx, visited, tran, errp);
33
+}
34
+
35
static bool bdrv_child_cb_can_set_aio_ctx(BdrvChild *child, AioContext *ctx,
36
GSList **ignore, Error **errp)
37
{
38
@@ -XXX,XX +XXX,XX @@ const BdrvChildClass child_of_bds = {
39
.inactivate = bdrv_child_cb_inactivate,
40
.can_set_aio_ctx = bdrv_child_cb_can_set_aio_ctx,
41
.set_aio_ctx = bdrv_child_cb_set_aio_ctx,
42
+ .change_aio_ctx = bdrv_child_cb_change_aio_ctx,
43
.update_filename = bdrv_child_cb_update_filename,
44
.get_parent_aio_context = child_of_bds_get_parent_aio_context,
45
};
46
--
47
2.37.3
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
blk_root_change_aio_ctx() is very similar to blk_root_can_set_aio_ctx(),
4
but implements a new transaction so that if all check pass, the new
5
transaction's .commit will take care of changing the BlockBackend
6
AioContext. blk_root_set_aio_ctx_commit() is the same as
7
blk_root_set_aio_ctx().
8
9
Note: bdrv_child_try_change_aio_context() is not called by
10
anyone at this point.
11
12
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
13
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
14
Message-Id: <20221025084952.2139888-7-eesposit@redhat.com>
15
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
---
17
block/block-backend.c | 52 +++++++++++++++++++++++++++++++++++++++++++
18
1 file changed, 52 insertions(+)
19
20
diff --git a/block/block-backend.c b/block/block-backend.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/block/block-backend.c
23
+++ b/block/block-backend.c
24
@@ -XXX,XX +XXX,XX @@ static bool blk_root_can_set_aio_ctx(BdrvChild *child, AioContext *ctx,
25
GSList **ignore, Error **errp);
26
static void blk_root_set_aio_ctx(BdrvChild *child, AioContext *ctx,
27
GSList **ignore);
28
+static bool blk_root_change_aio_ctx(BdrvChild *child, AioContext *ctx,
29
+ GHashTable *visited, Transaction *tran,
30
+ Error **errp);
31
32
static char *blk_root_get_parent_desc(BdrvChild *child)
33
{
34
@@ -XXX,XX +XXX,XX @@ static const BdrvChildClass child_root = {
35
36
.can_set_aio_ctx = blk_root_can_set_aio_ctx,
37
.set_aio_ctx = blk_root_set_aio_ctx,
38
+ .change_aio_ctx = blk_root_change_aio_ctx,
39
40
.get_parent_aio_context = blk_root_get_parent_aio_context,
41
};
42
@@ -XXX,XX +XXX,XX @@ int blk_set_aio_context(BlockBackend *blk, AioContext *new_context,
43
return blk_do_set_aio_context(blk, new_context, true, errp);
44
}
45
46
+typedef struct BdrvStateBlkRootContext {
47
+ AioContext *new_ctx;
48
+ BlockBackend *blk;
49
+} BdrvStateBlkRootContext;
50
+
51
+static void blk_root_set_aio_ctx_commit(void *opaque)
52
+{
53
+ BdrvStateBlkRootContext *s = opaque;
54
+ BlockBackend *blk = s->blk;
55
+
56
+ blk_do_set_aio_context(blk, s->new_ctx, false, &error_abort);
57
+}
58
+
59
+static TransactionActionDrv set_blk_root_context = {
60
+ .commit = blk_root_set_aio_ctx_commit,
61
+ .clean = g_free,
62
+};
63
+
64
+static bool blk_root_change_aio_ctx(BdrvChild *child, AioContext *ctx,
65
+ GHashTable *visited, Transaction *tran,
66
+ Error **errp)
67
+{
68
+ BlockBackend *blk = child->opaque;
69
+ BdrvStateBlkRootContext *s;
70
+
71
+ if (!blk->allow_aio_context_change) {
72
+ /*
73
+ * Manually created BlockBackends (those with a name) that are not
74
+ * attached to anything can change their AioContext without updating
75
+ * their user; return an error for others.
76
+ */
77
+ if (!blk->name || blk->dev) {
78
+ /* TODO Add BB name/QOM path */
79
+ error_setg(errp, "Cannot change iothread of active block backend");
80
+ return false;
81
+ }
82
+ }
83
+
84
+ s = g_new(BdrvStateBlkRootContext, 1);
85
+ *s = (BdrvStateBlkRootContext) {
86
+ .new_ctx = ctx,
87
+ .blk = blk,
88
+ };
89
+
90
+ tran_add(tran, &set_blk_root_context, s);
91
+ return true;
92
+}
93
+
94
static bool blk_root_can_set_aio_ctx(BdrvChild *child, AioContext *ctx,
95
GSList **ignore, Error **errp)
96
{
97
--
98
2.37.3
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
Replace all direct usage of ->can_set_aio_ctx and ->set_aio_ctx,
4
and call bdrv_child_try_change_aio_context() in
5
bdrv_try_set_aio_context(), the main function called through
6
the whole block layer.
7
8
From this point onwards, ->can_set_aio_ctx and ->set_aio_ctx
9
won't be used anymore.
10
11
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
12
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
13
Message-Id: <20221025084952.2139888-8-eesposit@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
---
16
block.c | 44 ++++++++++++++++++++++++-------------------
17
block/block-backend.c | 8 ++++++--
18
2 files changed, 31 insertions(+), 21 deletions(-)
19
20
diff --git a/block.c b/block.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/block.c
23
+++ b/block.c
24
@@ -XXX,XX +XXX,XX @@ static void bdrv_attach_child_common_abort(void *opaque)
25
}
26
27
if (bdrv_child_get_parent_aio_context(s->child) != s->old_parent_ctx) {
28
- GSList *ignore;
29
+ Transaction *tran;
30
+ GHashTable *visited;
31
+ bool ret;
32
33
- /* No need to ignore `child`, because it has been detached already */
34
- ignore = NULL;
35
- s->child->klass->can_set_aio_ctx(s->child, s->old_parent_ctx, &ignore,
36
- &error_abort);
37
- g_slist_free(ignore);
38
+ tran = tran_new();
39
40
- ignore = NULL;
41
- s->child->klass->set_aio_ctx(s->child, s->old_parent_ctx, &ignore);
42
- g_slist_free(ignore);
43
+ /* No need to visit `child`, because it has been detached already */
44
+ visited = g_hash_table_new(NULL, NULL);
45
+ ret = s->child->klass->change_aio_ctx(s->child, s->old_parent_ctx,
46
+ visited, tran, &error_abort);
47
+ g_hash_table_destroy(visited);
48
+
49
+ /* transaction is supposed to always succeed */
50
+ assert(ret == true);
51
+ tran_commit(tran);
52
}
53
54
bdrv_unref(bs);
55
@@ -XXX,XX +XXX,XX @@ static BdrvChild *bdrv_attach_child_common(BlockDriverState *child_bs,
56
Error *local_err = NULL;
57
int ret = bdrv_try_set_aio_context(child_bs, parent_ctx, &local_err);
58
59
- if (ret < 0 && child_class->can_set_aio_ctx) {
60
- GSList *ignore = g_slist_prepend(NULL, new_child);
61
- if (child_class->can_set_aio_ctx(new_child, child_ctx, &ignore,
62
- NULL))
63
- {
64
+ if (ret < 0 && child_class->change_aio_ctx) {
65
+ Transaction *tran = tran_new();
66
+ GHashTable *visited = g_hash_table_new(NULL, NULL);
67
+ bool ret_child;
68
+
69
+ g_hash_table_add(visited, new_child);
70
+ ret_child = child_class->change_aio_ctx(new_child, child_ctx,
71
+ visited, tran, NULL);
72
+ if (ret_child == true) {
73
error_free(local_err);
74
ret = 0;
75
- g_slist_free(ignore);
76
- ignore = g_slist_prepend(NULL, new_child);
77
- child_class->set_aio_ctx(new_child, child_ctx, &ignore);
78
}
79
- g_slist_free(ignore);
80
+ tran_finalize(tran, ret_child == true ? 0 : -1);
81
+ g_hash_table_destroy(visited);
82
}
83
84
if (ret < 0) {
85
@@ -XXX,XX +XXX,XX @@ int bdrv_try_set_aio_context(BlockDriverState *bs, AioContext *ctx,
86
Error **errp)
87
{
88
GLOBAL_STATE_CODE();
89
- return bdrv_child_try_set_aio_context(bs, ctx, NULL, errp);
90
+ return bdrv_child_try_change_aio_context(bs, ctx, NULL, errp);
91
}
92
93
void bdrv_add_aio_context_notifier(BlockDriverState *bs,
94
diff --git a/block/block-backend.c b/block/block-backend.c
95
index XXXXXXX..XXXXXXX 100644
96
--- a/block/block-backend.c
97
+++ b/block/block-backend.c
98
@@ -XXX,XX +XXX,XX @@ static int blk_do_set_aio_context(BlockBackend *blk, AioContext *new_context,
99
bdrv_ref(bs);
100
101
if (update_root_node) {
102
- ret = bdrv_child_try_set_aio_context(bs, new_context, blk->root,
103
- errp);
104
+ /*
105
+ * update_root_node MUST be false for blk_root_set_aio_ctx_commit(),
106
+ * as we are already in the commit function of a transaction.
107
+ */
108
+ ret = bdrv_child_try_change_aio_context(bs, new_context, blk->root,
109
+ errp);
110
if (ret < 0) {
111
bdrv_unref(bs);
112
return ret;
113
--
114
2.37.3
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
Together with all _can_set_ and _set_ APIs, as they are not needed
4
anymore.
5
6
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
7
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
8
Message-Id: <20221025084952.2139888-9-eesposit@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
include/block/block-global-state.h | 9 --
12
include/block/block_int-common.h | 4 -
13
block.c | 196 -----------------------------
14
block/block-backend.c | 33 -----
15
blockjob.c | 35 ------
16
5 files changed, 277 deletions(-)
17
18
diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/block/block-global-state.h
21
+++ b/include/block/block-global-state.h
22
@@ -XXX,XX +XXX,XX @@ void coroutine_fn bdrv_co_lock(BlockDriverState *bs);
23
*/
24
void coroutine_fn bdrv_co_unlock(BlockDriverState *bs);
25
26
-void bdrv_set_aio_context_ignore(BlockDriverState *bs,
27
- AioContext *new_context, GSList **ignore);
28
int bdrv_try_set_aio_context(BlockDriverState *bs, AioContext *ctx,
29
Error **errp);
30
-int bdrv_child_try_set_aio_context(BlockDriverState *bs, AioContext *ctx,
31
- BdrvChild *ignore_child, Error **errp);
32
-bool bdrv_child_can_set_aio_context(BdrvChild *c, AioContext *ctx,
33
- GSList **ignore, Error **errp);
34
-bool bdrv_can_set_aio_context(BlockDriverState *bs, AioContext *ctx,
35
- GSList **ignore, Error **errp);
36
AioContext *bdrv_child_get_parent_aio_context(BdrvChild *c);
37
-
38
bool bdrv_child_change_aio_context(BdrvChild *c, AioContext *ctx,
39
GHashTable *visited, Transaction *tran,
40
Error **errp);
41
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
42
index XXXXXXX..XXXXXXX 100644
43
--- a/include/block/block_int-common.h
44
+++ b/include/block/block_int-common.h
45
@@ -XXX,XX +XXX,XX @@ struct BdrvChildClass {
46
int (*update_filename)(BdrvChild *child, BlockDriverState *new_base,
47
const char *filename, Error **errp);
48
49
- bool (*can_set_aio_ctx)(BdrvChild *child, AioContext *ctx,
50
- GSList **ignore, Error **errp);
51
- void (*set_aio_ctx)(BdrvChild *child, AioContext *ctx, GSList **ignore);
52
-
53
bool (*change_aio_ctx)(BdrvChild *child, AioContext *ctx,
54
GHashTable *visited, Transaction *tran,
55
Error **errp);
56
diff --git a/block.c b/block.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/block.c
59
+++ b/block.c
60
@@ -XXX,XX +XXX,XX @@ static bool bdrv_child_cb_change_aio_ctx(BdrvChild *child, AioContext *ctx,
61
return bdrv_change_aio_context(bs, ctx, visited, tran, errp);
62
}
63
64
-static bool bdrv_child_cb_can_set_aio_ctx(BdrvChild *child, AioContext *ctx,
65
- GSList **ignore, Error **errp)
66
-{
67
- BlockDriverState *bs = child->opaque;
68
- return bdrv_can_set_aio_context(bs, ctx, ignore, errp);
69
-}
70
-
71
-static void bdrv_child_cb_set_aio_ctx(BdrvChild *child, AioContext *ctx,
72
- GSList **ignore)
73
-{
74
- BlockDriverState *bs = child->opaque;
75
- return bdrv_set_aio_context_ignore(bs, ctx, ignore);
76
-}
77
-
78
/*
79
* Returns the options and flags that a temporary snapshot should get, based on
80
* the originally requested flags (the originally requested image will have
81
@@ -XXX,XX +XXX,XX @@ const BdrvChildClass child_of_bds = {
82
.attach = bdrv_child_cb_attach,
83
.detach = bdrv_child_cb_detach,
84
.inactivate = bdrv_child_cb_inactivate,
85
- .can_set_aio_ctx = bdrv_child_cb_can_set_aio_ctx,
86
- .set_aio_ctx = bdrv_child_cb_set_aio_ctx,
87
.change_aio_ctx = bdrv_child_cb_change_aio_ctx,
88
.update_filename = bdrv_child_cb_update_filename,
89
.get_parent_aio_context = child_of_bds_get_parent_aio_context,
90
@@ -XXX,XX +XXX,XX @@ static void bdrv_attach_aio_context(BlockDriverState *bs,
91
bs->walking_aio_notifiers = false;
92
}
93
94
-/*
95
- * Changes the AioContext used for fd handlers, timers, and BHs by this
96
- * BlockDriverState and all its children and parents.
97
- *
98
- * Must be called from the main AioContext.
99
- *
100
- * The caller must own the AioContext lock for the old AioContext of bs, but it
101
- * must not own the AioContext lock for new_context (unless new_context is the
102
- * same as the current context of bs).
103
- *
104
- * @ignore will accumulate all visited BdrvChild objects. The caller is
105
- * responsible for freeing the list afterwards.
106
- */
107
-void bdrv_set_aio_context_ignore(BlockDriverState *bs,
108
- AioContext *new_context, GSList **ignore)
109
-{
110
- AioContext *old_context = bdrv_get_aio_context(bs);
111
- GSList *children_to_process = NULL;
112
- GSList *parents_to_process = NULL;
113
- GSList *entry;
114
- BdrvChild *child, *parent;
115
-
116
- g_assert(qemu_get_current_aio_context() == qemu_get_aio_context());
117
- GLOBAL_STATE_CODE();
118
-
119
- if (old_context == new_context) {
120
- return;
121
- }
122
-
123
- bdrv_drained_begin(bs);
124
-
125
- QLIST_FOREACH(child, &bs->children, next) {
126
- if (g_slist_find(*ignore, child)) {
127
- continue;
128
- }
129
- *ignore = g_slist_prepend(*ignore, child);
130
- children_to_process = g_slist_prepend(children_to_process, child);
131
- }
132
-
133
- QLIST_FOREACH(parent, &bs->parents, next_parent) {
134
- if (g_slist_find(*ignore, parent)) {
135
- continue;
136
- }
137
- *ignore = g_slist_prepend(*ignore, parent);
138
- parents_to_process = g_slist_prepend(parents_to_process, parent);
139
- }
140
-
141
- for (entry = children_to_process;
142
- entry != NULL;
143
- entry = g_slist_next(entry)) {
144
- child = entry->data;
145
- bdrv_set_aio_context_ignore(child->bs, new_context, ignore);
146
- }
147
- g_slist_free(children_to_process);
148
-
149
- for (entry = parents_to_process;
150
- entry != NULL;
151
- entry = g_slist_next(entry)) {
152
- parent = entry->data;
153
- assert(parent->klass->set_aio_ctx);
154
- parent->klass->set_aio_ctx(parent, new_context, ignore);
155
- }
156
- g_slist_free(parents_to_process);
157
-
158
- bdrv_detach_aio_context(bs);
159
-
160
- /* Acquire the new context, if necessary */
161
- if (qemu_get_aio_context() != new_context) {
162
- aio_context_acquire(new_context);
163
- }
164
-
165
- bdrv_attach_aio_context(bs, new_context);
166
-
167
- /*
168
- * If this function was recursively called from
169
- * bdrv_set_aio_context_ignore(), there may be nodes in the
170
- * subtree that have not yet been moved to the new AioContext.
171
- * Release the old one so bdrv_drained_end() can poll them.
172
- */
173
- if (qemu_get_aio_context() != old_context) {
174
- aio_context_release(old_context);
175
- }
176
-
177
- bdrv_drained_end(bs);
178
-
179
- if (qemu_get_aio_context() != old_context) {
180
- aio_context_acquire(old_context);
181
- }
182
- if (qemu_get_aio_context() != new_context) {
183
- aio_context_release(new_context);
184
- }
185
-}
186
-
187
-static bool bdrv_parent_can_set_aio_context(BdrvChild *c, AioContext *ctx,
188
- GSList **ignore, Error **errp)
189
-{
190
- GLOBAL_STATE_CODE();
191
- if (g_slist_find(*ignore, c)) {
192
- return true;
193
- }
194
- *ignore = g_slist_prepend(*ignore, c);
195
-
196
- /*
197
- * A BdrvChildClass that doesn't handle AioContext changes cannot
198
- * tolerate any AioContext changes
199
- */
200
- if (!c->klass->can_set_aio_ctx) {
201
- char *user = bdrv_child_user_desc(c);
202
- error_setg(errp, "Changing iothreads is not supported by %s", user);
203
- g_free(user);
204
- return false;
205
- }
206
- if (!c->klass->can_set_aio_ctx(c, ctx, ignore, errp)) {
207
- assert(!errp || *errp);
208
- return false;
209
- }
210
- return true;
211
-}
212
-
213
typedef struct BdrvStateSetAioContext {
214
AioContext *new_ctx;
215
BlockDriverState *bs;
216
@@ -XXX,XX +XXX,XX @@ static bool bdrv_parent_change_aio_context(BdrvChild *c, AioContext *ctx,
217
return true;
218
}
219
220
-bool bdrv_child_can_set_aio_context(BdrvChild *c, AioContext *ctx,
221
- GSList **ignore, Error **errp)
222
-{
223
- GLOBAL_STATE_CODE();
224
- if (g_slist_find(*ignore, c)) {
225
- return true;
226
- }
227
- *ignore = g_slist_prepend(*ignore, c);
228
- return bdrv_can_set_aio_context(c->bs, ctx, ignore, errp);
229
-}
230
-
231
bool bdrv_child_change_aio_context(BdrvChild *c, AioContext *ctx,
232
GHashTable *visited, Transaction *tran,
233
Error **errp)
234
@@ -XXX,XX +XXX,XX @@ bool bdrv_child_change_aio_context(BdrvChild *c, AioContext *ctx,
235
return bdrv_change_aio_context(c->bs, ctx, visited, tran, errp);
236
}
237
238
-/* @ignore will accumulate all visited BdrvChild object. The caller is
239
- * responsible for freeing the list afterwards. */
240
-bool bdrv_can_set_aio_context(BlockDriverState *bs, AioContext *ctx,
241
- GSList **ignore, Error **errp)
242
-{
243
- BdrvChild *c;
244
-
245
- if (bdrv_get_aio_context(bs) == ctx) {
246
- return true;
247
- }
248
-
249
- GLOBAL_STATE_CODE();
250
-
251
- QLIST_FOREACH(c, &bs->parents, next_parent) {
252
- if (!bdrv_parent_can_set_aio_context(c, ctx, ignore, errp)) {
253
- return false;
254
- }
255
- }
256
- QLIST_FOREACH(c, &bs->children, next) {
257
- if (!bdrv_child_can_set_aio_context(c, ctx, ignore, errp)) {
258
- return false;
259
- }
260
- }
261
-
262
- return true;
263
-}
264
-
265
static void bdrv_set_aio_context_clean(void *opaque)
266
{
267
BdrvStateSetAioContext *state = (BdrvStateSetAioContext *) opaque;
268
@@ -XXX,XX +XXX,XX @@ static bool bdrv_change_aio_context(BlockDriverState *bs, AioContext *ctx,
269
return true;
270
}
271
272
-int bdrv_child_try_set_aio_context(BlockDriverState *bs, AioContext *ctx,
273
- BdrvChild *ignore_child, Error **errp)
274
-{
275
- GSList *ignore;
276
- bool ret;
277
-
278
- GLOBAL_STATE_CODE();
279
-
280
- ignore = ignore_child ? g_slist_prepend(NULL, ignore_child) : NULL;
281
- ret = bdrv_can_set_aio_context(bs, ctx, &ignore, errp);
282
- g_slist_free(ignore);
283
-
284
- if (!ret) {
285
- return -EPERM;
286
- }
287
-
288
- ignore = ignore_child ? g_slist_prepend(NULL, ignore_child) : NULL;
289
- bdrv_set_aio_context_ignore(bs, ctx, &ignore);
290
- g_slist_free(ignore);
291
-
292
- return 0;
293
-}
294
-
295
/*
296
* Change bs's and recursively all of its parents' and children's AioContext
297
* to the given new context, returning an error if that isn't possible.
298
diff --git a/block/block-backend.c b/block/block-backend.c
299
index XXXXXXX..XXXXXXX 100644
300
--- a/block/block-backend.c
301
+++ b/block/block-backend.c
302
@@ -XXX,XX +XXX,XX @@ static void blk_root_drained_end(BdrvChild *child, int *drained_end_counter);
303
static void blk_root_change_media(BdrvChild *child, bool load);
304
static void blk_root_resize(BdrvChild *child);
305
306
-static bool blk_root_can_set_aio_ctx(BdrvChild *child, AioContext *ctx,
307
- GSList **ignore, Error **errp);
308
-static void blk_root_set_aio_ctx(BdrvChild *child, AioContext *ctx,
309
- GSList **ignore);
310
static bool blk_root_change_aio_ctx(BdrvChild *child, AioContext *ctx,
311
GHashTable *visited, Transaction *tran,
312
Error **errp);
313
@@ -XXX,XX +XXX,XX @@ static const BdrvChildClass child_root = {
314
.attach = blk_root_attach,
315
.detach = blk_root_detach,
316
317
- .can_set_aio_ctx = blk_root_can_set_aio_ctx,
318
- .set_aio_ctx = blk_root_set_aio_ctx,
319
.change_aio_ctx = blk_root_change_aio_ctx,
320
321
.get_parent_aio_context = blk_root_get_parent_aio_context,
322
@@ -XXX,XX +XXX,XX @@ static bool blk_root_change_aio_ctx(BdrvChild *child, AioContext *ctx,
323
return true;
324
}
325
326
-static bool blk_root_can_set_aio_ctx(BdrvChild *child, AioContext *ctx,
327
- GSList **ignore, Error **errp)
328
-{
329
- BlockBackend *blk = child->opaque;
330
-
331
- if (blk->allow_aio_context_change) {
332
- return true;
333
- }
334
-
335
- /* Only manually created BlockBackends that are not attached to anything
336
- * can change their AioContext without updating their user. */
337
- if (!blk->name || blk->dev) {
338
- /* TODO Add BB name/QOM path */
339
- error_setg(errp, "Cannot change iothread of active block backend");
340
- return false;
341
- }
342
-
343
- return true;
344
-}
345
-
346
-static void blk_root_set_aio_ctx(BdrvChild *child, AioContext *ctx,
347
- GSList **ignore)
348
-{
349
- BlockBackend *blk = child->opaque;
350
- blk_do_set_aio_context(blk, ctx, false, &error_abort);
351
-}
352
-
353
void blk_add_aio_context_notifier(BlockBackend *blk,
354
void (*attached_aio_context)(AioContext *new_context, void *opaque),
355
void (*detach_aio_context)(void *opaque), void *opaque)
356
diff --git a/blockjob.c b/blockjob.c
357
index XXXXXXX..XXXXXXX 100644
358
--- a/blockjob.c
359
+++ b/blockjob.c
360
@@ -XXX,XX +XXX,XX @@ static bool child_job_change_aio_ctx(BdrvChild *c, AioContext *ctx,
361
return true;
362
}
363
364
-static bool child_job_can_set_aio_ctx(BdrvChild *c, AioContext *ctx,
365
- GSList **ignore, Error **errp)
366
-{
367
- BlockJob *job = c->opaque;
368
- GSList *l;
369
-
370
- for (l = job->nodes; l; l = l->next) {
371
- BdrvChild *sibling = l->data;
372
- if (!bdrv_child_can_set_aio_context(sibling, ctx, ignore, errp)) {
373
- return false;
374
- }
375
- }
376
- return true;
377
-}
378
-
379
-static void child_job_set_aio_ctx(BdrvChild *c, AioContext *ctx,
380
- GSList **ignore)
381
-{
382
- BlockJob *job = c->opaque;
383
- GSList *l;
384
-
385
- for (l = job->nodes; l; l = l->next) {
386
- BdrvChild *sibling = l->data;
387
- if (g_slist_find(*ignore, sibling)) {
388
- continue;
389
- }
390
- *ignore = g_slist_prepend(*ignore, sibling);
391
- bdrv_set_aio_context_ignore(sibling->bs, ctx, ignore);
392
- }
393
-
394
- job_set_aio_context(&job->job, ctx);
395
-}
396
-
397
static AioContext *child_job_get_parent_aio_context(BdrvChild *c)
398
{
399
BlockJob *job = c->opaque;
400
@@ -XXX,XX +XXX,XX @@ static const BdrvChildClass child_job = {
401
.drained_begin = child_job_drained_begin,
402
.drained_poll = child_job_drained_poll,
403
.drained_end = child_job_drained_end,
404
- .can_set_aio_ctx = child_job_can_set_aio_ctx,
405
- .set_aio_ctx = child_job_set_aio_ctx,
406
.change_aio_ctx = child_job_change_aio_ctx,
407
.stay_at_node = true,
408
.get_parent_aio_context = child_job_get_parent_aio_context,
409
--
410
2.37.3
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
No functional changes intended.
4
5
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
6
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
7
Message-Id: <20221025084952.2139888-10-eesposit@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
10
include/block/block-global-state.h | 4 ++--
11
block.c | 6 +++---
12
block/block-backend.c | 3 +--
13
3 files changed, 6 insertions(+), 7 deletions(-)
14
15
diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/block/block-global-state.h
18
+++ b/include/block/block-global-state.h
19
@@ -XXX,XX +XXX,XX @@ AioContext *bdrv_child_get_parent_aio_context(BdrvChild *c);
20
bool bdrv_child_change_aio_context(BdrvChild *c, AioContext *ctx,
21
GHashTable *visited, Transaction *tran,
22
Error **errp);
23
-int bdrv_child_try_change_aio_context(BlockDriverState *bs, AioContext *ctx,
24
- BdrvChild *ignore_child, Error **errp);
25
+int bdrv_try_change_aio_context(BlockDriverState *bs, AioContext *ctx,
26
+ BdrvChild *ignore_child, Error **errp);
27
28
int bdrv_probe_blocksizes(BlockDriverState *bs, BlockSizes *bsz);
29
int bdrv_probe_geometry(BlockDriverState *bs, HDGeometry *geo);
30
diff --git a/block.c b/block.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/block.c
33
+++ b/block.c
34
@@ -XXX,XX +XXX,XX @@ static bool bdrv_change_aio_context(BlockDriverState *bs, AioContext *ctx,
35
* bdrv_drained_end calls BDRV_POLL_WHILE that assumes the lock is taken too.
36
* Therefore the new AioContext lock must not be taken by the caller.
37
*/
38
-int bdrv_child_try_change_aio_context(BlockDriverState *bs, AioContext *ctx,
39
- BdrvChild *ignore_child, Error **errp)
40
+int bdrv_try_change_aio_context(BlockDriverState *bs, AioContext *ctx,
41
+ BdrvChild *ignore_child, Error **errp)
42
{
43
Transaction *tran;
44
GHashTable *visited;
45
@@ -XXX,XX +XXX,XX @@ int bdrv_try_set_aio_context(BlockDriverState *bs, AioContext *ctx,
46
Error **errp)
47
{
48
GLOBAL_STATE_CODE();
49
- return bdrv_child_try_change_aio_context(bs, ctx, NULL, errp);
50
+ return bdrv_try_change_aio_context(bs, ctx, NULL, errp);
51
}
52
53
void bdrv_add_aio_context_notifier(BlockDriverState *bs,
54
diff --git a/block/block-backend.c b/block/block-backend.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/block/block-backend.c
57
+++ b/block/block-backend.c
58
@@ -XXX,XX +XXX,XX @@ static int blk_do_set_aio_context(BlockBackend *blk, AioContext *new_context,
59
* update_root_node MUST be false for blk_root_set_aio_ctx_commit(),
60
* as we are already in the commit function of a transaction.
61
*/
62
- ret = bdrv_child_try_change_aio_context(bs, new_context, blk->root,
63
- errp);
64
+ ret = bdrv_try_change_aio_context(bs, new_context, blk->root, errp);
65
if (ret < 0) {
66
bdrv_unref(bs);
67
return ret;
68
--
69
2.37.3
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
No functional change intended.
4
5
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
6
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
7
Message-Id: <20221025084952.2139888-11-eesposit@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
10
docs/devel/multiple-iothreads.txt | 4 ++--
11
include/block/block-global-state.h | 2 --
12
block.c | 14 ++++----------
13
block/export/export.c | 2 +-
14
blockdev.c | 22 +++++++++++-----------
15
job.c | 2 +-
16
tests/unit/test-bdrv-drain.c | 6 +++---
17
tests/unit/test-block-iothread.c | 10 +++++-----
18
8 files changed, 27 insertions(+), 35 deletions(-)
19
20
diff --git a/docs/devel/multiple-iothreads.txt b/docs/devel/multiple-iothreads.txt
21
index XXXXXXX..XXXXXXX 100644
22
--- a/docs/devel/multiple-iothreads.txt
23
+++ b/docs/devel/multiple-iothreads.txt
24
@@ -XXX,XX +XXX,XX @@ The AioContext originates from the QEMU block layer, even though nowadays
25
AioContext is a generic event loop that can be used by any QEMU subsystem.
26
27
The block layer has support for AioContext integrated. Each BlockDriverState
28
-is associated with an AioContext using bdrv_try_set_aio_context() and
29
+is associated with an AioContext using bdrv_try_change_aio_context() and
30
bdrv_get_aio_context(). This allows block layer code to process I/O inside the
31
right AioContext. Other subsystems may wish to follow a similar approach.
32
33
@@ -XXX,XX +XXX,XX @@ Long-running jobs (usually in the form of coroutines) are best scheduled in
34
the BlockDriverState's AioContext to avoid the need to acquire/release around
35
each bdrv_*() call. The functions bdrv_add/remove_aio_context_notifier,
36
or alternatively blk_add/remove_aio_context_notifier if you use BlockBackends,
37
-can be used to get a notification whenever bdrv_try_set_aio_context() moves a
38
+can be used to get a notification whenever bdrv_try_change_aio_context() moves a
39
BlockDriverState to a different AioContext.
40
diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h
41
index XXXXXXX..XXXXXXX 100644
42
--- a/include/block/block-global-state.h
43
+++ b/include/block/block-global-state.h
44
@@ -XXX,XX +XXX,XX @@ void coroutine_fn bdrv_co_lock(BlockDriverState *bs);
45
*/
46
void coroutine_fn bdrv_co_unlock(BlockDriverState *bs);
47
48
-int bdrv_try_set_aio_context(BlockDriverState *bs, AioContext *ctx,
49
- Error **errp);
50
AioContext *bdrv_child_get_parent_aio_context(BdrvChild *c);
51
bool bdrv_child_change_aio_context(BdrvChild *c, AioContext *ctx,
52
GHashTable *visited, Transaction *tran,
53
diff --git a/block.c b/block.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/block.c
56
+++ b/block.c
57
@@ -XXX,XX +XXX,XX @@ static void bdrv_attach_child_common_abort(void *opaque)
58
bdrv_replace_child_noperm(s->child, NULL);
59
60
if (bdrv_get_aio_context(bs) != s->old_child_ctx) {
61
- bdrv_try_set_aio_context(bs, s->old_child_ctx, &error_abort);
62
+ bdrv_try_change_aio_context(bs, s->old_child_ctx, NULL, &error_abort);
63
}
64
65
if (bdrv_child_get_parent_aio_context(s->child) != s->old_parent_ctx) {
66
@@ -XXX,XX +XXX,XX @@ static BdrvChild *bdrv_attach_child_common(BlockDriverState *child_bs,
67
parent_ctx = bdrv_child_get_parent_aio_context(new_child);
68
if (child_ctx != parent_ctx) {
69
Error *local_err = NULL;
70
- int ret = bdrv_try_set_aio_context(child_bs, parent_ctx, &local_err);
71
+ int ret = bdrv_try_change_aio_context(child_bs, parent_ctx, NULL,
72
+ &local_err);
73
74
if (ret < 0 && child_class->change_aio_ctx) {
75
Transaction *tran = tran_new();
76
@@ -XXX,XX +XXX,XX @@ static void bdrv_detach_child(BdrvChild *child)
77
* When the parent requiring a non-default AioContext is removed, the
78
* node moves back to the main AioContext
79
*/
80
- bdrv_try_set_aio_context(old_bs, qemu_get_aio_context(), NULL);
81
+ bdrv_try_change_aio_context(old_bs, qemu_get_aio_context(), NULL, NULL);
82
}
83
}
84
85
@@ -XXX,XX +XXX,XX @@ int bdrv_try_change_aio_context(BlockDriverState *bs, AioContext *ctx,
86
return 0;
87
}
88
89
-int bdrv_try_set_aio_context(BlockDriverState *bs, AioContext *ctx,
90
- Error **errp)
91
-{
92
- GLOBAL_STATE_CODE();
93
- return bdrv_try_change_aio_context(bs, ctx, NULL, errp);
94
-}
95
-
96
void bdrv_add_aio_context_notifier(BlockDriverState *bs,
97
void (*attached_aio_context)(AioContext *new_context, void *opaque),
98
void (*detach_aio_context)(void *opaque), void *opaque)
99
diff --git a/block/export/export.c b/block/export/export.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/block/export/export.c
102
+++ b/block/export/export.c
103
@@ -XXX,XX +XXX,XX @@ BlockExport *blk_exp_add(BlockExportOptions *export, Error **errp)
104
105
/* Ignore errors with fixed-iothread=false */
106
set_context_errp = fixed_iothread ? errp : NULL;
107
- ret = bdrv_try_set_aio_context(bs, new_ctx, set_context_errp);
108
+ ret = bdrv_try_change_aio_context(bs, new_ctx, NULL, set_context_errp);
109
if (ret == 0) {
110
aio_context_release(ctx);
111
aio_context_acquire(new_ctx);
112
diff --git a/blockdev.c b/blockdev.c
113
index XXXXXXX..XXXXXXX 100644
114
--- a/blockdev.c
115
+++ b/blockdev.c
116
@@ -XXX,XX +XXX,XX @@ static void external_snapshot_abort(BlkActionState *common)
117
aio_context_release(aio_context);
118
aio_context_acquire(tmp_context);
119
120
- ret = bdrv_try_set_aio_context(state->old_bs,
121
- aio_context, NULL);
122
+ ret = bdrv_try_change_aio_context(state->old_bs,
123
+ aio_context, NULL, NULL);
124
assert(ret == 0);
125
126
aio_context_release(tmp_context);
127
@@ -XXX,XX +XXX,XX @@ static void drive_backup_prepare(BlkActionState *common, Error **errp)
128
goto out;
129
}
130
131
- /* Honor bdrv_try_set_aio_context() context acquisition requirements. */
132
+ /* Honor bdrv_try_change_aio_context() context acquisition requirements. */
133
old_context = bdrv_get_aio_context(target_bs);
134
aio_context_release(aio_context);
135
aio_context_acquire(old_context);
136
137
- ret = bdrv_try_set_aio_context(target_bs, aio_context, errp);
138
+ ret = bdrv_try_change_aio_context(target_bs, aio_context, NULL, errp);
139
if (ret < 0) {
140
bdrv_unref(target_bs);
141
aio_context_release(old_context);
142
@@ -XXX,XX +XXX,XX @@ static void blockdev_backup_prepare(BlkActionState *common, Error **errp)
143
return;
144
}
145
146
- /* Honor bdrv_try_set_aio_context() context acquisition requirements. */
147
+ /* Honor bdrv_try_change_aio_context() context acquisition requirements. */
148
aio_context = bdrv_get_aio_context(bs);
149
old_context = bdrv_get_aio_context(target_bs);
150
aio_context_acquire(old_context);
151
152
- ret = bdrv_try_set_aio_context(target_bs, aio_context, errp);
153
+ ret = bdrv_try_change_aio_context(target_bs, aio_context, NULL, errp);
154
if (ret < 0) {
155
aio_context_release(old_context);
156
return;
157
@@ -XXX,XX +XXX,XX @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
158
!bdrv_has_zero_init(target_bs)));
159
160
161
- /* Honor bdrv_try_set_aio_context() context acquisition requirements. */
162
+ /* Honor bdrv_try_change_aio_context() context acquisition requirements. */
163
old_context = bdrv_get_aio_context(target_bs);
164
aio_context_release(aio_context);
165
aio_context_acquire(old_context);
166
167
- ret = bdrv_try_set_aio_context(target_bs, aio_context, errp);
168
+ ret = bdrv_try_change_aio_context(target_bs, aio_context, NULL, errp);
169
if (ret < 0) {
170
bdrv_unref(target_bs);
171
aio_context_release(old_context);
172
@@ -XXX,XX +XXX,XX @@ void qmp_blockdev_mirror(bool has_job_id, const char *job_id,
173
174
zero_target = (sync == MIRROR_SYNC_MODE_FULL);
175
176
- /* Honor bdrv_try_set_aio_context() context acquisition requirements. */
177
+ /* Honor bdrv_try_change_aio_context() context acquisition requirements. */
178
old_context = bdrv_get_aio_context(target_bs);
179
aio_context = bdrv_get_aio_context(bs);
180
aio_context_acquire(old_context);
181
182
- ret = bdrv_try_set_aio_context(target_bs, aio_context, errp);
183
+ ret = bdrv_try_change_aio_context(target_bs, aio_context, NULL, errp);
184
185
aio_context_release(old_context);
186
aio_context_acquire(aio_context);
187
@@ -XXX,XX +XXX,XX @@ void qmp_x_blockdev_set_iothread(const char *node_name, StrOrNull *iothread,
188
old_context = bdrv_get_aio_context(bs);
189
aio_context_acquire(old_context);
190
191
- bdrv_try_set_aio_context(bs, new_context, errp);
192
+ bdrv_try_change_aio_context(bs, new_context, NULL, errp);
193
194
aio_context_release(old_context);
195
}
196
diff --git a/job.c b/job.c
197
index XXXXXXX..XXXXXXX 100644
198
--- a/job.c
199
+++ b/job.c
200
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn job_do_yield_locked(Job *job, uint64_t ns)
201
next_aio_context = job->aio_context;
202
/*
203
* Coroutine has resumed, but in the meanwhile the job AioContext
204
- * might have changed via bdrv_try_set_aio_context(), so we need to move
205
+ * might have changed via bdrv_try_change_aio_context(), so we need to move
206
* the coroutine too in the new aiocontext.
207
*/
208
while (qemu_get_current_aio_context() != next_aio_context) {
209
diff --git a/tests/unit/test-bdrv-drain.c b/tests/unit/test-bdrv-drain.c
210
index XXXXXXX..XXXXXXX 100644
211
--- a/tests/unit/test-bdrv-drain.c
212
+++ b/tests/unit/test-bdrv-drain.c
213
@@ -XXX,XX +XXX,XX @@ static void test_set_aio_context(void)
214
&error_abort);
215
216
bdrv_drained_begin(bs);
217
- bdrv_try_set_aio_context(bs, ctx_a, &error_abort);
218
+ bdrv_try_change_aio_context(bs, ctx_a, NULL, &error_abort);
219
220
aio_context_acquire(ctx_a);
221
bdrv_drained_end(bs);
222
223
bdrv_drained_begin(bs);
224
- bdrv_try_set_aio_context(bs, ctx_b, &error_abort);
225
+ bdrv_try_change_aio_context(bs, ctx_b, NULL, &error_abort);
226
aio_context_release(ctx_a);
227
aio_context_acquire(ctx_b);
228
- bdrv_try_set_aio_context(bs, qemu_get_aio_context(), &error_abort);
229
+ bdrv_try_change_aio_context(bs, qemu_get_aio_context(), NULL, &error_abort);
230
aio_context_release(ctx_b);
231
bdrv_drained_end(bs);
232
233
diff --git a/tests/unit/test-block-iothread.c b/tests/unit/test-block-iothread.c
234
index XXXXXXX..XXXXXXX 100644
235
--- a/tests/unit/test-block-iothread.c
236
+++ b/tests/unit/test-block-iothread.c
237
@@ -XXX,XX +XXX,XX @@ static void test_propagate_mirror(void)
238
filter = bdrv_find_node("filter_node");
239
240
/* Change the AioContext of src */
241
- bdrv_try_set_aio_context(src, ctx, &error_abort);
242
+ bdrv_try_change_aio_context(src, ctx, NULL, &error_abort);
243
g_assert(bdrv_get_aio_context(src) == ctx);
244
g_assert(bdrv_get_aio_context(target) == ctx);
245
g_assert(bdrv_get_aio_context(filter) == ctx);
246
@@ -XXX,XX +XXX,XX @@ static void test_propagate_mirror(void)
247
248
/* Change the AioContext of target */
249
aio_context_acquire(ctx);
250
- bdrv_try_set_aio_context(target, main_ctx, &error_abort);
251
+ bdrv_try_change_aio_context(target, main_ctx, NULL, &error_abort);
252
aio_context_release(ctx);
253
g_assert(bdrv_get_aio_context(src) == main_ctx);
254
g_assert(bdrv_get_aio_context(target) == main_ctx);
255
@@ -XXX,XX +XXX,XX @@ static void test_propagate_mirror(void)
256
blk = blk_new(qemu_get_aio_context(), 0, BLK_PERM_ALL);
257
blk_insert_bs(blk, src, &error_abort);
258
259
- bdrv_try_set_aio_context(target, ctx, &local_err);
260
+ bdrv_try_change_aio_context(target, ctx, NULL, &local_err);
261
error_free_or_abort(&local_err);
262
263
g_assert(blk_get_aio_context(blk) == main_ctx);
264
@@ -XXX,XX +XXX,XX @@ static void test_propagate_mirror(void)
265
/* ...unless we explicitly allow it */
266
aio_context_acquire(ctx);
267
blk_set_allow_aio_context_change(blk, true);
268
- bdrv_try_set_aio_context(target, ctx, &error_abort);
269
+ bdrv_try_change_aio_context(target, ctx, NULL, &error_abort);
270
aio_context_release(ctx);
271
272
g_assert(blk_get_aio_context(blk) == ctx);
273
@@ -XXX,XX +XXX,XX @@ static void test_propagate_mirror(void)
274
275
aio_context_acquire(ctx);
276
blk_set_aio_context(blk, main_ctx, &error_abort);
277
- bdrv_try_set_aio_context(target, main_ctx, &error_abort);
278
+ bdrv_try_change_aio_context(target, main_ctx, NULL, &error_abort);
279
aio_context_release(ctx);
280
281
blk_unref(blk);
282
--
283
2.37.3
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bin.meng@windriver.com>
1
2
3
libnfs.h declares nfs_fstat() as the following for win32:
4
5
int nfs_fstat(struct nfs_context *nfs, struct nfsfh *nfsfh,
6
struct __stat64 *st);
7
8
The 'st' parameter should be of type 'struct __stat64'. The
9
codes happen to build successfully for 64-bit Windows, but it
10
does not build for 32-bit Windows.
11
12
Fixes: 6542aa9c75bc ("block: add native support for NFS")
13
Fixes: 18a8056e0bc7 ("block/nfs: cache allocated filesize for read-only files")
14
Signed-off-by: Bin Meng <bin.meng@windriver.com>
15
Message-Id: <20220908132817.1831008-6-bmeng.cn@gmail.com>
16
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
---
19
block/nfs.c | 8 ++++++++
20
1 file changed, 8 insertions(+)
21
22
diff --git a/block/nfs.c b/block/nfs.c
23
index XXXXXXX..XXXXXXX 100644
24
--- a/block/nfs.c
25
+++ b/block/nfs.c
26
@@ -XXX,XX +XXX,XX @@ static int64_t nfs_client_open(NFSClient *client, BlockdevOptionsNfs *opts,
27
int flags, int open_flags, Error **errp)
28
{
29
int64_t ret = -EINVAL;
30
+#ifdef _WIN32
31
+ struct __stat64 st;
32
+#else
33
struct stat st;
34
+#endif
35
char *file = NULL, *strp = NULL;
36
37
qemu_mutex_init(&client->mutex);
38
@@ -XXX,XX +XXX,XX @@ static int nfs_reopen_prepare(BDRVReopenState *state,
39
BlockReopenQueue *queue, Error **errp)
40
{
41
NFSClient *client = state->bs->opaque;
42
+#ifdef _WIN32
43
+ struct __stat64 st;
44
+#else
45
struct stat st;
46
+#endif
47
int ret = 0;
48
49
if (state->flags & BDRV_O_RDWR && bdrv_is_read_only(state->bs)) {
50
--
51
2.37.3
diff view generated by jsdifflib
New patch
1
From: Alberto Faria <afaria@redhat.com>
1
2
3
The .set_speed callback is not called from coroutine.
4
5
Signed-off-by: Alberto Faria <afaria@redhat.com>
6
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
7
Message-Id: <20221013123711.620631-2-pbonzini@redhat.com>
8
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
block/backup.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
14
diff --git a/block/backup.c b/block/backup.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/block/backup.c
17
+++ b/block/backup.c
18
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn backup_pause(Job *job)
19
}
20
}
21
22
-static void coroutine_fn backup_set_speed(BlockJob *job, int64_t speed)
23
+static void backup_set_speed(BlockJob *job, int64_t speed)
24
{
25
BackupBlockJob *s = container_of(job, BackupBlockJob, common);
26
27
--
28
2.37.3
diff view generated by jsdifflib
New patch
1
From: Alberto Faria <afaria@redhat.com>
1
2
3
Signed-off-by: Alberto Faria <afaria@redhat.com>
4
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
5
Message-Id: <20221013123711.620631-3-pbonzini@redhat.com>
6
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
9
block/io.c | 4 ++--
10
1 file changed, 2 insertions(+), 2 deletions(-)
11
12
diff --git a/block/io.c b/block/io.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/block/io.c
15
+++ b/block/io.c
16
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_is_zero_fast(BlockDriverState *bs, int64_t offset,
17
return (pnum == bytes) && (ret & BDRV_BLOCK_ZERO);
18
}
19
20
-int coroutine_fn bdrv_is_allocated(BlockDriverState *bs, int64_t offset,
21
- int64_t bytes, int64_t *pnum)
22
+int bdrv_is_allocated(BlockDriverState *bs, int64_t offset, int64_t bytes,
23
+ int64_t *pnum)
24
{
25
int ret;
26
int64_t dummy;
27
--
28
2.37.3
diff view generated by jsdifflib
New patch
1
From: Alberto Faria <afaria@redhat.com>
1
2
3
hmp_block_resize and hmp_screendump are defined as a ".coroutine = true" command,
4
so they must be coroutine_fn.
5
6
Signed-off-by: Alberto Faria <afaria@redhat.com>
7
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
8
Message-Id: <20221013123711.620631-4-pbonzini@redhat.com>
9
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
12
include/block/block-hmp-cmds.h | 2 +-
13
include/monitor/hmp.h | 3 ++-
14
block/monitor/block-hmp-cmds.c | 2 +-
15
3 files changed, 4 insertions(+), 3 deletions(-)
16
17
diff --git a/include/block/block-hmp-cmds.h b/include/block/block-hmp-cmds.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/block/block-hmp-cmds.h
20
+++ b/include/block/block-hmp-cmds.h
21
@@ -XXX,XX +XXX,XX @@ void hmp_nbd_server_add(Monitor *mon, const QDict *qdict);
22
void hmp_nbd_server_remove(Monitor *mon, const QDict *qdict);
23
void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict);
24
25
-void hmp_block_resize(Monitor *mon, const QDict *qdict);
26
+void coroutine_fn hmp_block_resize(Monitor *mon, const QDict *qdict);
27
void hmp_block_stream(Monitor *mon, const QDict *qdict);
28
void hmp_block_passwd(Monitor *mon, const QDict *qdict);
29
void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict);
30
diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
31
index XXXXXXX..XXXXXXX 100644
32
--- a/include/monitor/hmp.h
33
+++ b/include/monitor/hmp.h
34
@@ -XXX,XX +XXX,XX @@
35
#define HMP_H
36
37
#include "qemu/readline.h"
38
+#include "qemu/coroutine.h"
39
#include "qapi/qapi-types-common.h"
40
41
bool hmp_handle_error(Monitor *mon, Error *err);
42
@@ -XXX,XX +XXX,XX @@ void hmp_netdev_del(Monitor *mon, const QDict *qdict);
43
void hmp_getfd(Monitor *mon, const QDict *qdict);
44
void hmp_closefd(Monitor *mon, const QDict *qdict);
45
void hmp_sendkey(Monitor *mon, const QDict *qdict);
46
-void hmp_screendump(Monitor *mon, const QDict *qdict);
47
+void coroutine_fn hmp_screendump(Monitor *mon, const QDict *qdict);
48
void hmp_chardev_add(Monitor *mon, const QDict *qdict);
49
void hmp_chardev_change(Monitor *mon, const QDict *qdict);
50
void hmp_chardev_remove(Monitor *mon, const QDict *qdict);
51
diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/block/monitor/block-hmp-cmds.c
54
+++ b/block/monitor/block-hmp-cmds.c
55
@@ -XXX,XX +XXX,XX @@ void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict)
56
hmp_handle_error(mon, err);
57
}
58
59
-void hmp_block_resize(Monitor *mon, const QDict *qdict)
60
+void coroutine_fn hmp_block_resize(Monitor *mon, const QDict *qdict)
61
{
62
const char *device = qdict_get_str(qdict, "device");
63
int64_t size = qdict_get_int(qdict, "size");
64
--
65
2.37.3
diff view generated by jsdifflib
New patch
1
From: Alberto Faria <afaria@redhat.com>
1
2
3
ssh_write is only called from ssh_co_writev.
4
5
Signed-off-by: Alberto Faria <afaria@redhat.com>
6
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
7
Message-Id: <20221013123711.620631-5-pbonzini@redhat.com>
8
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
block/ssh.c | 6 +++---
12
1 file changed, 3 insertions(+), 3 deletions(-)
13
14
diff --git a/block/ssh.c b/block/ssh.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/block/ssh.c
17
+++ b/block/ssh.c
18
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int ssh_co_readv(BlockDriverState *bs,
19
return ret;
20
}
21
22
-static int ssh_write(BDRVSSHState *s, BlockDriverState *bs,
23
- int64_t offset, size_t size,
24
- QEMUIOVector *qiov)
25
+static coroutine_fn int ssh_write(BDRVSSHState *s, BlockDriverState *bs,
26
+ int64_t offset, size_t size,
27
+ QEMUIOVector *qiov)
28
{
29
ssize_t r;
30
size_t written;
31
--
32
2.37.3
diff view generated by jsdifflib
New patch
1
From: Alberto Faria <afaria@redhat.com>
1
2
3
The functions are marked coroutine_fn in the definition.
4
5
Signed-off-by: Alberto Faria <afaria@redhat.com>
6
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
7
Message-Id: <20221013123711.620631-6-pbonzini@redhat.com>
8
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
include/block/block-io.h | 5 +++--
12
1 file changed, 3 insertions(+), 2 deletions(-)
13
14
diff --git a/include/block/block-io.h b/include/block/block-io.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/block/block-io.h
17
+++ b/include/block/block-io.h
18
@@ -XXX,XX +XXX,XX @@ void bdrv_aio_cancel(BlockAIOCB *acb);
19
void bdrv_aio_cancel_async(BlockAIOCB *acb);
20
21
/* sg packet commands */
22
-int bdrv_co_ioctl(BlockDriverState *bs, int req, void *buf);
23
+int coroutine_fn bdrv_co_ioctl(BlockDriverState *bs, int req, void *buf);
24
25
/* Ensure contents are flushed to disk. */
26
int coroutine_fn bdrv_co_flush(BlockDriverState *bs);
27
28
-int bdrv_co_pdiscard(BdrvChild *child, int64_t offset, int64_t bytes);
29
+int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset,
30
+ int64_t bytes);
31
bool bdrv_can_write_zeroes_with_unmap(BlockDriverState *bs);
32
int bdrv_block_status(BlockDriverState *bs, int64_t offset,
33
int64_t bytes, int64_t *pnum, int64_t *map,
34
--
35
2.37.3
diff view generated by jsdifflib
New patch
1
From: Alberto Faria <afaria@redhat.com>
1
2
3
The functions are marked coroutine_fn in the definition.
4
5
Signed-off-by: Alberto Faria <afaria@redhat.com>
6
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
7
Message-Id: <20221013123711.620631-7-pbonzini@redhat.com>
8
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
include/qemu/coroutine.h | 10 +++++-----
12
1 file changed, 5 insertions(+), 5 deletions(-)
13
14
diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/qemu/coroutine.h
17
+++ b/include/qemu/coroutine.h
18
@@ -XXX,XX +XXX,XX @@ void qemu_co_rwlock_init(CoRwlock *lock);
19
* of a parallel writer, control is transferred to the caller of the current
20
* coroutine.
21
*/
22
-void qemu_co_rwlock_rdlock(CoRwlock *lock);
23
+void coroutine_fn qemu_co_rwlock_rdlock(CoRwlock *lock);
24
25
/**
26
* Write Locks the CoRwlock from a reader. This is a bit more efficient than
27
@@ -XXX,XX +XXX,XX @@ void qemu_co_rwlock_rdlock(CoRwlock *lock);
28
* to the caller of the current coroutine; another writer might run while
29
* @qemu_co_rwlock_upgrade blocks.
30
*/
31
-void qemu_co_rwlock_upgrade(CoRwlock *lock);
32
+void coroutine_fn qemu_co_rwlock_upgrade(CoRwlock *lock);
33
34
/**
35
* Downgrades a write-side critical section to a reader. Downgrading with
36
@@ -XXX,XX +XXX,XX @@ void qemu_co_rwlock_upgrade(CoRwlock *lock);
37
* followed by @qemu_co_rwlock_rdlock. This makes it more efficient, but
38
* may also sometimes be necessary for correctness.
39
*/
40
-void qemu_co_rwlock_downgrade(CoRwlock *lock);
41
+void coroutine_fn qemu_co_rwlock_downgrade(CoRwlock *lock);
42
43
/**
44
* Write Locks the mutex. If the lock cannot be taken immediately because
45
* of a parallel reader, control is transferred to the caller of the current
46
* coroutine.
47
*/
48
-void qemu_co_rwlock_wrlock(CoRwlock *lock);
49
+void coroutine_fn qemu_co_rwlock_wrlock(CoRwlock *lock);
50
51
/**
52
* Unlocks the read/write lock and schedules the next coroutine that was
53
* waiting for this lock to be run.
54
*/
55
-void qemu_co_rwlock_unlock(CoRwlock *lock);
56
+void coroutine_fn qemu_co_rwlock_unlock(CoRwlock *lock);
57
58
typedef struct QemuCoSleep {
59
Coroutine *to_wake;
60
--
61
2.37.3
diff view generated by jsdifflib
New patch
1
From: Alberto Faria <afaria@redhat.com>
1
2
3
Signed-off-by: Alberto Faria <afaria@redhat.com>
4
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
5
Message-Id: <20221013123711.620631-8-pbonzini@redhat.com>
6
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
9
include/qemu/coroutine.h | 8 +++++---
10
1 file changed, 5 insertions(+), 3 deletions(-)
11
12
diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/include/qemu/coroutine.h
15
+++ b/include/qemu/coroutine.h
16
@@ -XXX,XX +XXX,XX @@ void qemu_coroutine_dec_pool_size(unsigned int additional_pool_size);
17
* The same interface as qemu_sendv_recvv(), with added yielding.
18
* XXX should mark these as coroutine_fn
19
*/
20
-ssize_t qemu_co_sendv_recvv(int sockfd, struct iovec *iov, unsigned iov_cnt,
21
- size_t offset, size_t bytes, bool do_send);
22
+ssize_t coroutine_fn qemu_co_sendv_recvv(int sockfd, struct iovec *iov,
23
+ unsigned iov_cnt, size_t offset,
24
+ size_t bytes, bool do_send);
25
#define qemu_co_recvv(sockfd, iov, iov_cnt, offset, bytes) \
26
qemu_co_sendv_recvv(sockfd, iov, iov_cnt, offset, bytes, false)
27
#define qemu_co_sendv(sockfd, iov, iov_cnt, offset, bytes) \
28
@@ -XXX,XX +XXX,XX @@ ssize_t qemu_co_sendv_recvv(int sockfd, struct iovec *iov, unsigned iov_cnt,
29
/**
30
* The same as above, but with just a single buffer
31
*/
32
-ssize_t qemu_co_send_recv(int sockfd, void *buf, size_t bytes, bool do_send);
33
+ssize_t coroutine_fn qemu_co_send_recv(int sockfd, void *buf, size_t bytes,
34
+ bool do_send);
35
#define qemu_co_recv(sockfd, buf, bytes) \
36
qemu_co_send_recv(sockfd, buf, bytes, false)
37
#define qemu_co_send(sockfd, buf, bytes) \
38
--
39
2.37.3
diff view generated by jsdifflib
New patch
1
From: Alberto Faria <afaria@redhat.com>
1
2
3
Signed-off-by: Alberto Faria <afaria@redhat.com>
4
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
5
Message-Id: <20221013123711.620631-9-pbonzini@redhat.com>
6
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
9
block/qcow2.h | 14 +++++++-------
10
include/block/block_int-common.h | 12 +++++-------
11
2 files changed, 12 insertions(+), 14 deletions(-)
12
13
diff --git a/block/qcow2.h b/block/qcow2.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/block/qcow2.h
16
+++ b/block/qcow2.h
17
@@ -XXX,XX +XXX,XX @@ int qcow2_truncate_bitmaps_check(BlockDriverState *bs, Error **errp);
18
bool qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs,
19
bool release_stored, Error **errp);
20
int qcow2_reopen_bitmaps_ro(BlockDriverState *bs, Error **errp);
21
-bool qcow2_co_can_store_new_dirty_bitmap(BlockDriverState *bs,
22
- const char *name,
23
- uint32_t granularity,
24
- Error **errp);
25
-int qcow2_co_remove_persistent_dirty_bitmap(BlockDriverState *bs,
26
- const char *name,
27
- Error **errp);
28
+bool coroutine_fn qcow2_co_can_store_new_dirty_bitmap(BlockDriverState *bs,
29
+ const char *name,
30
+ uint32_t granularity,
31
+ Error **errp);
32
+int coroutine_fn qcow2_co_remove_persistent_dirty_bitmap(BlockDriverState *bs,
33
+ const char *name,
34
+ Error **errp);
35
bool qcow2_supports_persistent_dirty_bitmap(BlockDriverState *bs);
36
uint64_t qcow2_get_persistent_dirty_bitmap_size(BlockDriverState *bs,
37
uint32_t cluster_size);
38
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
39
index XXXXXXX..XXXXXXX 100644
40
--- a/include/block/block_int-common.h
41
+++ b/include/block/block_int-common.h
42
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
43
void coroutine_fn (*bdrv_co_drain_end)(BlockDriverState *bs);
44
45
bool (*bdrv_supports_persistent_dirty_bitmap)(BlockDriverState *bs);
46
- bool (*bdrv_co_can_store_new_dirty_bitmap)(BlockDriverState *bs,
47
- const char *name,
48
- uint32_t granularity,
49
- Error **errp);
50
- int (*bdrv_co_remove_persistent_dirty_bitmap)(BlockDriverState *bs,
51
- const char *name,
52
- Error **errp);
53
+ bool coroutine_fn (*bdrv_co_can_store_new_dirty_bitmap)(
54
+ BlockDriverState *bs, const char *name, uint32_t granularity,
55
+ Error **errp);
56
+ int coroutine_fn (*bdrv_co_remove_persistent_dirty_bitmap)(
57
+ BlockDriverState *bs, const char *name, Error **errp);
58
};
59
60
static inline bool block_driver_can_compress(BlockDriver *drv)
61
--
62
2.37.3
diff view generated by jsdifflib
New patch
1
From: Alberto Faria <afaria@redhat.com>
1
2
3
Signed-off-by: Alberto Faria <afaria@redhat.com>
4
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
5
Message-Id: <20221013123711.620631-10-pbonzini@redhat.com>
6
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
9
block/qcow2.c | 8 ++++----
10
1 file changed, 4 insertions(+), 4 deletions(-)
11
12
diff --git a/block/qcow2.c b/block/qcow2.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/block/qcow2.c
15
+++ b/block/qcow2.c
16
@@ -XXX,XX +XXX,XX @@ static int64_t qcow2_check_vmstate_request(BlockDriverState *bs,
17
return pos;
18
}
19
20
-static int qcow2_save_vmstate(BlockDriverState *bs, QEMUIOVector *qiov,
21
- int64_t pos)
22
+static coroutine_fn int qcow2_save_vmstate(BlockDriverState *bs,
23
+ QEMUIOVector *qiov, int64_t pos)
24
{
25
int64_t offset = qcow2_check_vmstate_request(bs, qiov, pos);
26
if (offset < 0) {
27
@@ -XXX,XX +XXX,XX @@ static int qcow2_save_vmstate(BlockDriverState *bs, QEMUIOVector *qiov,
28
return bs->drv->bdrv_co_pwritev_part(bs, offset, qiov->size, qiov, 0, 0);
29
}
30
31
-static int qcow2_load_vmstate(BlockDriverState *bs, QEMUIOVector *qiov,
32
- int64_t pos)
33
+static coroutine_fn int qcow2_load_vmstate(BlockDriverState *bs,
34
+ QEMUIOVector *qiov, int64_t pos)
35
{
36
int64_t offset = qcow2_check_vmstate_request(bs, qiov, pos);
37
if (offset < 0) {
38
--
39
2.37.3
diff view generated by jsdifflib
New patch
1
From: Paolo Bonzini <pbonzini@redhat.com>
1
2
3
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
4
Message-Id: <20221013123711.620631-11-pbonzini@redhat.com>
5
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
8
block/blkdebug.c | 2 +-
9
1 file changed, 1 insertion(+), 1 deletion(-)
10
11
diff --git a/block/blkdebug.c b/block/blkdebug.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/block/blkdebug.c
14
+++ b/block/blkdebug.c
15
@@ -XXX,XX +XXX,XX @@ blkdebug_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
16
return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
17
}
18
19
-static int blkdebug_co_flush(BlockDriverState *bs)
20
+static int coroutine_fn blkdebug_co_flush(BlockDriverState *bs)
21
{
22
int err = rule_check(bs, 0, 0, BLKDEBUG_IO_TYPE_FLUSH);
23
24
--
25
2.37.3
diff view generated by jsdifflib
New patch
1
From: Paolo Bonzini <pbonzini@redhat.com>
1
2
3
get_cluster_offset() and decompress_cluster() are only called from
4
the read and write paths.
5
6
The validity of these was double-checked with Alberto Faria's static analyzer.
7
8
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
9
Message-Id: <20221013123711.620631-12-pbonzini@redhat.com>
10
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
13
block/qcow.c | 15 +++++++++------
14
1 file changed, 9 insertions(+), 6 deletions(-)
15
16
diff --git a/block/qcow.c b/block/qcow.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/block/qcow.c
19
+++ b/block/qcow.c
20
@@ -XXX,XX +XXX,XX @@ typedef struct BDRVQcowState {
21
22
static QemuOptsList qcow_create_opts;
23
24
-static int decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset);
25
+static int coroutine_fn decompress_cluster(BlockDriverState *bs,
26
+ uint64_t cluster_offset);
27
28
static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename)
29
{
30
@@ -XXX,XX +XXX,XX @@ static int qcow_reopen_prepare(BDRVReopenState *state,
31
* return 0 if not allocated, 1 if *result is assigned, and negative
32
* errno on failure.
33
*/
34
-static int get_cluster_offset(BlockDriverState *bs,
35
- uint64_t offset, int allocate,
36
- int compressed_size,
37
- int n_start, int n_end, uint64_t *result)
38
+static int coroutine_fn get_cluster_offset(BlockDriverState *bs,
39
+ uint64_t offset, int allocate,
40
+ int compressed_size,
41
+ int n_start, int n_end,
42
+ uint64_t *result)
43
{
44
BDRVQcowState *s = bs->opaque;
45
int min_index, i, j, l1_index, l2_index, ret;
46
@@ -XXX,XX +XXX,XX @@ static int decompress_buffer(uint8_t *out_buf, int out_buf_size,
47
return 0;
48
}
49
50
-static int decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset)
51
+static int coroutine_fn decompress_cluster(BlockDriverState *bs,
52
+ uint64_t cluster_offset)
53
{
54
BDRVQcowState *s = bs->opaque;
55
int ret, csize;
56
--
57
2.37.3
diff view generated by jsdifflib
New patch
1
From: Paolo Bonzini <pbonzini@redhat.com>
1
2
3
The validity of these was double-checked with Alberto Faria's static
4
analyzer.
5
6
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
7
Message-Id: <20221013123711.620631-13-pbonzini@redhat.com>
8
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
block/qcow2.h | 18 +++++++++---------
12
block/qcow2-bitmap.c | 4 ++--
13
block/qcow2-cluster.c | 21 ++++++++++++---------
14
block/qcow2-refcount.c | 8 ++++----
15
4 files changed, 27 insertions(+), 24 deletions(-)
16
17
diff --git a/block/qcow2.h b/block/qcow2.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/block/qcow2.h
20
+++ b/block/qcow2.h
21
@@ -XXX,XX +XXX,XX @@ int qcow2_validate_table(BlockDriverState *bs, uint64_t offset,
22
Error **errp);
23
24
/* qcow2-refcount.c functions */
25
-int qcow2_refcount_init(BlockDriverState *bs);
26
+int coroutine_fn qcow2_refcount_init(BlockDriverState *bs);
27
void qcow2_refcount_close(BlockDriverState *bs);
28
29
int qcow2_get_refcount(BlockDriverState *bs, int64_t cluster_index,
30
@@ -XXX,XX +XXX,XX @@ int qcow2_inc_refcounts_imrt(BlockDriverState *bs, BdrvCheckResult *res,
31
int qcow2_change_refcount_order(BlockDriverState *bs, int refcount_order,
32
BlockDriverAmendStatusCB *status_cb,
33
void *cb_opaque, Error **errp);
34
-int qcow2_shrink_reftable(BlockDriverState *bs);
35
+int coroutine_fn qcow2_shrink_reftable(BlockDriverState *bs);
36
int64_t qcow2_get_last_cluster(BlockDriverState *bs, int64_t size);
37
int coroutine_fn qcow2_detect_metadata_preallocation(BlockDriverState *bs);
38
39
/* qcow2-cluster.c functions */
40
int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
41
bool exact_size);
42
-int qcow2_shrink_l1_table(BlockDriverState *bs, uint64_t max_size);
43
+int coroutine_fn qcow2_shrink_l1_table(BlockDriverState *bs, uint64_t max_size);
44
int qcow2_write_l1_entry(BlockDriverState *bs, int l1_index);
45
int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num,
46
uint8_t *buf, int nb_sectors, bool enc, Error **errp);
47
@@ -XXX,XX +XXX,XX @@ int qcow2_get_host_offset(BlockDriverState *bs, uint64_t offset,
48
int coroutine_fn qcow2_alloc_host_offset(BlockDriverState *bs, uint64_t offset,
49
unsigned int *bytes,
50
uint64_t *host_offset, QCowL2Meta **m);
51
-int qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
52
- uint64_t offset,
53
- int compressed_size,
54
- uint64_t *host_offset);
55
+int coroutine_fn qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
56
+ uint64_t offset,
57
+ int compressed_size,
58
+ uint64_t *host_offset);
59
void qcow2_parse_compressed_l2_entry(BlockDriverState *bs, uint64_t l2_entry,
60
uint64_t *coffset, int *csize);
61
62
@@ -XXX,XX +XXX,XX @@ void qcow2_cache_discard(Qcow2Cache *c, void *table);
63
int qcow2_check_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
64
void **refcount_table,
65
int64_t *refcount_table_size);
66
-bool qcow2_load_dirty_bitmaps(BlockDriverState *bs, bool *header_updated,
67
- Error **errp);
68
+bool coroutine_fn qcow2_load_dirty_bitmaps(BlockDriverState *bs,
69
+ bool *header_updated, Error **errp);
70
bool qcow2_get_bitmap_info_list(BlockDriverState *bs,
71
Qcow2BitmapInfoList **info_list, Error **errp);
72
int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp);
73
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/block/qcow2-bitmap.c
76
+++ b/block/qcow2-bitmap.c
77
@@ -XXX,XX +XXX,XX @@ static void set_readonly_helper(gpointer bitmap, gpointer value)
78
* If header_updated is not NULL then it is set appropriately regardless of
79
* the return value.
80
*/
81
-bool qcow2_load_dirty_bitmaps(BlockDriverState *bs, bool *header_updated,
82
- Error **errp)
83
+bool coroutine_fn qcow2_load_dirty_bitmaps(BlockDriverState *bs,
84
+ bool *header_updated, Error **errp)
85
{
86
BDRVQcow2State *s = bs->opaque;
87
Qcow2BitmapList *bm_list;
88
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/block/qcow2-cluster.c
91
+++ b/block/qcow2-cluster.c
92
@@ -XXX,XX +XXX,XX @@
93
#include "qemu/memalign.h"
94
#include "trace.h"
95
96
-int qcow2_shrink_l1_table(BlockDriverState *bs, uint64_t exact_size)
97
+int coroutine_fn qcow2_shrink_l1_table(BlockDriverState *bs,
98
+ uint64_t exact_size)
99
{
100
BDRVQcow2State *s = bs->opaque;
101
int new_l1_size, i, ret;
102
@@ -XXX,XX +XXX,XX @@ static int get_cluster_table(BlockDriverState *bs, uint64_t offset,
103
*
104
* Return 0 on success and -errno in error cases
105
*/
106
-int qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
107
- uint64_t offset,
108
- int compressed_size,
109
- uint64_t *host_offset)
110
+int coroutine_fn qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
111
+ uint64_t offset,
112
+ int compressed_size,
113
+ uint64_t *host_offset)
114
{
115
BDRVQcow2State *s = bs->opaque;
116
int l2_index, ret;
117
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn handle_dependencies(BlockDriverState *bs,
118
*
119
* -errno: in error cases
120
*/
121
-static int handle_copied(BlockDriverState *bs, uint64_t guest_offset,
122
- uint64_t *host_offset, uint64_t *bytes, QCowL2Meta **m)
123
+static int coroutine_fn handle_copied(BlockDriverState *bs,
124
+ uint64_t guest_offset, uint64_t *host_offset, uint64_t *bytes,
125
+ QCowL2Meta **m)
126
{
127
BDRVQcow2State *s = bs->opaque;
128
int l2_index;
129
@@ -XXX,XX +XXX,XX @@ static int do_alloc_cluster_offset(BlockDriverState *bs, uint64_t guest_offset,
130
*
131
* -errno: in error cases
132
*/
133
-static int handle_alloc(BlockDriverState *bs, uint64_t guest_offset,
134
- uint64_t *host_offset, uint64_t *bytes, QCowL2Meta **m)
135
+static int coroutine_fn handle_alloc(BlockDriverState *bs,
136
+ uint64_t guest_offset, uint64_t *host_offset, uint64_t *bytes,
137
+ QCowL2Meta **m)
138
{
139
BDRVQcow2State *s = bs->opaque;
140
int l2_index;
141
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
142
index XXXXXXX..XXXXXXX 100644
143
--- a/block/qcow2-refcount.c
144
+++ b/block/qcow2-refcount.c
145
@@ -XXX,XX +XXX,XX @@ static void update_max_refcount_table_index(BDRVQcow2State *s)
146
s->max_refcount_table_index = i;
147
}
148
149
-int qcow2_refcount_init(BlockDriverState *bs)
150
+int coroutine_fn qcow2_refcount_init(BlockDriverState *bs)
151
{
152
BDRVQcow2State *s = bs->opaque;
153
unsigned int refcount_table_size2, i;
154
@@ -XXX,XX +XXX,XX @@ static int64_t get_refblock_offset(BlockDriverState *bs, uint64_t offset)
155
return covering_refblock_offset;
156
}
157
158
-static int qcow2_discard_refcount_block(BlockDriverState *bs,
159
- uint64_t discard_block_offs)
160
+static int coroutine_fn
161
+qcow2_discard_refcount_block(BlockDriverState *bs, uint64_t discard_block_offs)
162
{
163
BDRVQcow2State *s = bs->opaque;
164
int64_t refblock_offs;
165
@@ -XXX,XX +XXX,XX @@ static int qcow2_discard_refcount_block(BlockDriverState *bs,
166
return 0;
167
}
168
169
-int qcow2_shrink_reftable(BlockDriverState *bs)
170
+int coroutine_fn qcow2_shrink_reftable(BlockDriverState *bs)
171
{
172
BDRVQcow2State *s = bs->opaque;
173
uint64_t *reftable_tmp =
174
--
175
2.37.3
diff view generated by jsdifflib
New patch
1
From: Paolo Bonzini <pbonzini@redhat.com>
1
2
3
The validity of these was double-checked with Alberto Faria's static analyzer.
4
5
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
6
Message-Id: <20221013123711.620631-14-pbonzini@redhat.com>
7
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
10
block/vmdk.c | 34 +++++++++++++++++-----------------
11
1 file changed, 17 insertions(+), 17 deletions(-)
12
13
diff --git a/block/vmdk.c b/block/vmdk.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/block/vmdk.c
16
+++ b/block/vmdk.c
17
@@ -XXX,XX +XXX,XX @@ static void vmdk_refresh_limits(BlockDriverState *bs, Error **errp)
18
* [@skip_start_sector, @skip_end_sector) is not copied or written, and leave
19
* it for call to write user data in the request.
20
*/
21
-static int get_whole_cluster(BlockDriverState *bs,
22
- VmdkExtent *extent,
23
- uint64_t cluster_offset,
24
- uint64_t offset,
25
- uint64_t skip_start_bytes,
26
- uint64_t skip_end_bytes,
27
- bool zeroed)
28
+static int coroutine_fn get_whole_cluster(BlockDriverState *bs,
29
+ VmdkExtent *extent,
30
+ uint64_t cluster_offset,
31
+ uint64_t offset,
32
+ uint64_t skip_start_bytes,
33
+ uint64_t skip_end_bytes,
34
+ bool zeroed)
35
{
36
int ret = VMDK_OK;
37
int64_t cluster_bytes;
38
@@ -XXX,XX +XXX,XX @@ exit:
39
return ret;
40
}
41
42
-static int vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data,
43
- uint32_t offset)
44
+static int coroutine_fn vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data,
45
+ uint32_t offset)
46
{
47
offset = cpu_to_le32(offset);
48
/* update L2 table */
49
@@ -XXX,XX +XXX,XX @@ static int vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data,
50
* VMDK_UNALLOC if cluster is not mapped and @allocate is false.
51
* VMDK_ERROR if failed.
52
*/
53
-static int get_cluster_offset(BlockDriverState *bs,
54
- VmdkExtent *extent,
55
- VmdkMetaData *m_data,
56
- uint64_t offset,
57
- bool allocate,
58
- uint64_t *cluster_offset,
59
- uint64_t skip_start_bytes,
60
- uint64_t skip_end_bytes)
61
+static int coroutine_fn get_cluster_offset(BlockDriverState *bs,
62
+ VmdkExtent *extent,
63
+ VmdkMetaData *m_data,
64
+ uint64_t offset,
65
+ bool allocate,
66
+ uint64_t *cluster_offset,
67
+ uint64_t skip_start_bytes,
68
+ uint64_t skip_end_bytes)
69
{
70
unsigned int l1_index, l2_offset, l2_index;
71
int min_index, i, j;
72
--
73
2.37.3
diff view generated by jsdifflib
New patch
1
From: Alberto Faria <afaria@redhat.com>
1
2
3
Signed-off-by: Alberto Faria <afaria@redhat.com>
4
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
5
Message-Id: <20221013123711.620631-15-pbonzini@redhat.com>
6
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
9
block/commit.c | 2 +-
10
1 file changed, 1 insertion(+), 1 deletion(-)
11
12
diff --git a/block/commit.c b/block/commit.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/block/commit.c
15
+++ b/block/commit.c
16
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn commit_run(Job *job, Error **errp)
17
}
18
19
if (base_len < len) {
20
- ret = blk_truncate(s->base, len, false, PREALLOC_MODE_OFF, 0, NULL);
21
+ ret = blk_co_truncate(s->base, len, false, PREALLOC_MODE_OFF, 0, NULL);
22
if (ret) {
23
return ret;
24
}
25
--
26
2.37.3
diff view generated by jsdifflib
New patch
1
From: Alberto Faria <afaria@redhat.com>
1
2
3
Signed-off-by: Alberto Faria <afaria@redhat.com>
4
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
5
Message-Id: <20221013123711.620631-16-pbonzini@redhat.com>
6
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
9
block.c | 2 +-
10
block/io.c | 4 ++--
11
2 files changed, 3 insertions(+), 3 deletions(-)
12
13
diff --git a/block.c b/block.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/block.c
16
+++ b/block.c
17
@@ -XXX,XX +XXX,XX @@ create_file_fallback_zero_first_sector(BlockBackend *blk,
18
19
bytes_to_clear = MIN(current_size, BDRV_SECTOR_SIZE);
20
if (bytes_to_clear) {
21
- ret = blk_pwrite_zeroes(blk, 0, bytes_to_clear, BDRV_REQ_MAY_UNMAP);
22
+ ret = blk_co_pwrite_zeroes(blk, 0, bytes_to_clear, BDRV_REQ_MAY_UNMAP);
23
if (ret < 0) {
24
error_setg_errno(errp, -ret,
25
"Failed to clear the new image's first sector");
26
diff --git a/block/io.c b/block/io.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/block/io.c
29
+++ b/block/io.c
30
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_is_zero_fast(BlockDriverState *bs, int64_t offset,
31
return 1;
32
}
33
34
- ret = bdrv_common_block_status_above(bs, NULL, false, false, offset,
35
- bytes, &pnum, NULL, NULL, NULL);
36
+ ret = bdrv_co_common_block_status_above(bs, NULL, false, false, offset,
37
+ bytes, &pnum, NULL, NULL, NULL);
38
39
if (ret < 0) {
40
return ret;
41
--
42
2.37.3
diff view generated by jsdifflib
New patch
1
From: Alberto Faria <afaria@redhat.com>
1
2
3
Signed-off-by: Alberto Faria <afaria@redhat.com>
4
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
5
Message-Id: <20221013123711.620631-17-pbonzini@redhat.com>
6
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
9
block/mirror.c | 4 ++--
10
1 file changed, 2 insertions(+), 2 deletions(-)
11
12
diff --git a/block/mirror.c b/block/mirror.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/block/mirror.c
15
+++ b/block/mirror.c
16
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
17
* active layer. */
18
if (s->base == blk_bs(s->target)) {
19
if (s->bdev_length > target_length) {
20
- ret = blk_truncate(s->target, s->bdev_length, false,
21
- PREALLOC_MODE_OFF, 0, NULL);
22
+ ret = blk_co_truncate(s->target, s->bdev_length, false,
23
+ PREALLOC_MODE_OFF, 0, NULL);
24
if (ret < 0) {
25
goto immediate_exit;
26
}
27
--
28
2.37.3
diff view generated by jsdifflib
New patch
1
From: Alberto Faria <afaria@redhat.com>
1
2
3
Signed-off-by: Alberto Faria <afaria@redhat.com>
4
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
5
Message-Id: <20221013123711.620631-18-pbonzini@redhat.com>
6
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
9
block/parallels.c | 28 ++++++++++++++--------------
10
1 file changed, 14 insertions(+), 14 deletions(-)
11
12
diff --git a/block/parallels.c b/block/parallels.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/block/parallels.c
15
+++ b/block/parallels.c
16
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int64_t allocate_clusters(BlockDriverState *bs,
17
* force the safer-but-slower fallocate.
18
*/
19
if (s->prealloc_mode == PRL_PREALLOC_MODE_TRUNCATE) {
20
- ret = bdrv_truncate(bs->file,
21
- (s->data_end + space) << BDRV_SECTOR_BITS,
22
- false, PREALLOC_MODE_OFF, BDRV_REQ_ZERO_WRITE,
23
- NULL);
24
+ ret = bdrv_co_truncate(bs->file,
25
+ (s->data_end + space) << BDRV_SECTOR_BITS,
26
+ false, PREALLOC_MODE_OFF,
27
+ BDRV_REQ_ZERO_WRITE, NULL);
28
if (ret == -ENOTSUP) {
29
s->prealloc_mode = PRL_PREALLOC_MODE_FALLOCATE;
30
}
31
}
32
if (s->prealloc_mode == PRL_PREALLOC_MODE_FALLOCATE) {
33
- ret = bdrv_pwrite_zeroes(bs->file,
34
- s->data_end << BDRV_SECTOR_BITS,
35
- space << BDRV_SECTOR_BITS, 0);
36
+ ret = bdrv_co_pwrite_zeroes(bs->file,
37
+ s->data_end << BDRV_SECTOR_BITS,
38
+ space << BDRV_SECTOR_BITS, 0);
39
}
40
if (ret < 0) {
41
return ret;
42
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int parallels_co_flush_to_os(BlockDriverState *bs)
43
if (off + to_write > s->header_size) {
44
to_write = s->header_size - off;
45
}
46
- ret = bdrv_pwrite(bs->file, off, to_write, (uint8_t *)s->header + off,
47
- 0);
48
+ ret = bdrv_co_pwrite(bs->file, off, to_write,
49
+ (uint8_t *)s->header + off, 0);
50
if (ret < 0) {
51
qemu_co_mutex_unlock(&s->lock);
52
return ret;
53
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn parallels_co_check(BlockDriverState *bs,
54
* In order to really repair the image, we must shrink it.
55
* That means we have to pass exact=true.
56
*/
57
- ret = bdrv_truncate(bs->file, res->image_end_offset, true,
58
- PREALLOC_MODE_OFF, 0, &local_err);
59
+ ret = bdrv_co_truncate(bs->file, res->image_end_offset, true,
60
+ PREALLOC_MODE_OFF, 0, &local_err);
61
if (ret < 0) {
62
error_report_err(local_err);
63
res->check_errors++;
64
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn parallels_co_create(BlockdevCreateOptions* opts,
65
memset(tmp, 0, sizeof(tmp));
66
memcpy(tmp, &header, sizeof(header));
67
68
- ret = blk_pwrite(blk, 0, BDRV_SECTOR_SIZE, tmp, 0);
69
+ ret = blk_co_pwrite(blk, 0, BDRV_SECTOR_SIZE, tmp, 0);
70
if (ret < 0) {
71
goto exit;
72
}
73
- ret = blk_pwrite_zeroes(blk, BDRV_SECTOR_SIZE,
74
- (bat_sectors - 1) << BDRV_SECTOR_BITS, 0);
75
+ ret = blk_co_pwrite_zeroes(blk, BDRV_SECTOR_SIZE,
76
+ (bat_sectors - 1) << BDRV_SECTOR_BITS, 0);
77
if (ret < 0) {
78
goto exit;
79
}
80
--
81
2.37.3
diff view generated by jsdifflib
New patch
1
From: Alberto Faria <afaria@redhat.com>
1
2
3
Signed-off-by: Alberto Faria <afaria@redhat.com>
4
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
5
Message-Id: <20221013123711.620631-19-pbonzini@redhat.com>
6
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
9
block/qcow.c | 45 +++++++++++++++++++++++----------------------
10
1 file changed, 23 insertions(+), 22 deletions(-)
11
12
diff --git a/block/qcow.c b/block/qcow.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/block/qcow.c
15
+++ b/block/qcow.c
16
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn get_cluster_offset(BlockDriverState *bs,
17
s->l1_table[l1_index] = l2_offset;
18
tmp = cpu_to_be64(l2_offset);
19
BLKDBG_EVENT(bs->file, BLKDBG_L1_UPDATE);
20
- ret = bdrv_pwrite_sync(bs->file,
21
- s->l1_table_offset + l1_index * sizeof(tmp),
22
- sizeof(tmp), &tmp, 0);
23
+ ret = bdrv_co_pwrite_sync(bs->file,
24
+ s->l1_table_offset + l1_index * sizeof(tmp),
25
+ sizeof(tmp), &tmp, 0);
26
if (ret < 0) {
27
return ret;
28
}
29
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn get_cluster_offset(BlockDriverState *bs,
30
BLKDBG_EVENT(bs->file, BLKDBG_L2_LOAD);
31
if (new_l2_table) {
32
memset(l2_table, 0, s->l2_size * sizeof(uint64_t));
33
- ret = bdrv_pwrite_sync(bs->file, l2_offset,
34
- s->l2_size * sizeof(uint64_t), l2_table, 0);
35
+ ret = bdrv_co_pwrite_sync(bs->file, l2_offset,
36
+ s->l2_size * sizeof(uint64_t), l2_table, 0);
37
if (ret < 0) {
38
return ret;
39
}
40
} else {
41
- ret = bdrv_pread(bs->file, l2_offset, s->l2_size * sizeof(uint64_t),
42
- l2_table, 0);
43
+ ret = bdrv_co_pread(bs->file, l2_offset,
44
+ s->l2_size * sizeof(uint64_t), l2_table, 0);
45
if (ret < 0) {
46
return ret;
47
}
48
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn get_cluster_offset(BlockDriverState *bs,
49
cluster_offset = QEMU_ALIGN_UP(cluster_offset, s->cluster_size);
50
/* write the cluster content */
51
BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
52
- ret = bdrv_pwrite(bs->file, cluster_offset, s->cluster_size,
53
- s->cluster_cache, 0);
54
+ ret = bdrv_co_pwrite(bs->file, cluster_offset, s->cluster_size,
55
+ s->cluster_cache, 0);
56
if (ret < 0) {
57
return ret;
58
}
59
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn get_cluster_offset(BlockDriverState *bs,
60
if (cluster_offset + s->cluster_size > INT64_MAX) {
61
return -E2BIG;
62
}
63
- ret = bdrv_truncate(bs->file, cluster_offset + s->cluster_size,
64
- false, PREALLOC_MODE_OFF, 0, NULL);
65
+ ret = bdrv_co_truncate(bs->file,
66
+ cluster_offset + s->cluster_size,
67
+ false, PREALLOC_MODE_OFF, 0, NULL);
68
if (ret < 0) {
69
return ret;
70
}
71
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn get_cluster_offset(BlockDriverState *bs,
72
return -EIO;
73
}
74
BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
75
- ret = bdrv_pwrite(bs->file, cluster_offset + i,
76
- BDRV_SECTOR_SIZE,
77
- s->cluster_data, 0);
78
+ ret = bdrv_co_pwrite(bs->file, cluster_offset + i,
79
+ BDRV_SECTOR_SIZE,
80
+ s->cluster_data, 0);
81
if (ret < 0) {
82
return ret;
83
}
84
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn get_cluster_offset(BlockDriverState *bs,
85
} else {
86
BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE);
87
}
88
- ret = bdrv_pwrite_sync(bs->file, l2_offset + l2_index * sizeof(tmp),
89
- sizeof(tmp), &tmp, 0);
90
+ ret = bdrv_co_pwrite_sync(bs->file, l2_offset + l2_index * sizeof(tmp),
91
+ sizeof(tmp), &tmp, 0);
92
if (ret < 0) {
93
return ret;
94
}
95
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn decompress_cluster(BlockDriverState *bs,
96
csize = cluster_offset >> (63 - s->cluster_bits);
97
csize &= (s->cluster_size - 1);
98
BLKDBG_EVENT(bs->file, BLKDBG_READ_COMPRESSED);
99
- ret = bdrv_pread(bs->file, coffset, csize, s->cluster_data, 0);
100
+ ret = bdrv_co_pread(bs->file, coffset, csize, s->cluster_data, 0);
101
if (ret < 0)
102
return -1;
103
if (decompress_buffer(s->cluster_cache, s->cluster_size,
104
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow_co_create(BlockdevCreateOptions *opts,
105
}
106
107
/* write all the data */
108
- ret = blk_pwrite(qcow_blk, 0, sizeof(header), &header, 0);
109
+ ret = blk_co_pwrite(qcow_blk, 0, sizeof(header), &header, 0);
110
if (ret < 0) {
111
goto exit;
112
}
113
114
if (qcow_opts->has_backing_file) {
115
- ret = blk_pwrite(qcow_blk, sizeof(header), backing_filename_len,
116
- qcow_opts->backing_file, 0);
117
+ ret = blk_co_pwrite(qcow_blk, sizeof(header), backing_filename_len,
118
+ qcow_opts->backing_file, 0);
119
if (ret < 0) {
120
goto exit;
121
}
122
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow_co_create(BlockdevCreateOptions *opts,
123
tmp = g_malloc0(BDRV_SECTOR_SIZE);
124
for (i = 0; i < DIV_ROUND_UP(sizeof(uint64_t) * l1_size, BDRV_SECTOR_SIZE);
125
i++) {
126
- ret = blk_pwrite(qcow_blk, header_size + BDRV_SECTOR_SIZE * i,
127
- BDRV_SECTOR_SIZE, tmp, 0);
128
+ ret = blk_co_pwrite(qcow_blk, header_size + BDRV_SECTOR_SIZE * i,
129
+ BDRV_SECTOR_SIZE, tmp, 0);
130
if (ret < 0) {
131
g_free(tmp);
132
goto exit;
133
--
134
2.37.3
diff view generated by jsdifflib
New patch
1
From: Alberto Faria <afaria@redhat.com>
1
2
3
Signed-off-by: Alberto Faria <afaria@redhat.com>
4
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
5
Message-Id: <20221013123711.620631-20-pbonzini@redhat.com>
6
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
9
block/qcow2-cluster.c | 8 ++++----
10
block/qcow2-refcount.c | 10 +++++-----
11
block/qcow2-snapshot.c | 6 +++---
12
block/qcow2.c | 24 ++++++++++++------------
13
4 files changed, 24 insertions(+), 24 deletions(-)
14
15
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/block/qcow2-cluster.c
18
+++ b/block/qcow2-cluster.c
19
@@ -XXX,XX +XXX,XX @@ int coroutine_fn qcow2_shrink_l1_table(BlockDriverState *bs,
20
#endif
21
22
BLKDBG_EVENT(bs->file, BLKDBG_L1_SHRINK_WRITE_TABLE);
23
- ret = bdrv_pwrite_zeroes(bs->file, s->l1_table_offset +
24
- new_l1_size * L1E_SIZE,
25
- (s->l1_size - new_l1_size) * L1E_SIZE, 0);
26
+ ret = bdrv_co_pwrite_zeroes(bs->file,
27
+ s->l1_table_offset + new_l1_size * L1E_SIZE,
28
+ (s->l1_size - new_l1_size) * L1E_SIZE, 0);
29
if (ret < 0) {
30
goto fail;
31
}
32
33
- ret = bdrv_flush(bs->file->bs);
34
+ ret = bdrv_co_flush(bs->file->bs);
35
if (ret < 0) {
36
goto fail;
37
}
38
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/block/qcow2-refcount.c
41
+++ b/block/qcow2-refcount.c
42
@@ -XXX,XX +XXX,XX @@ int coroutine_fn qcow2_refcount_init(BlockDriverState *bs)
43
goto fail;
44
}
45
BLKDBG_EVENT(bs->file, BLKDBG_REFTABLE_LOAD);
46
- ret = bdrv_pread(bs->file, s->refcount_table_offset,
47
- refcount_table_size2, s->refcount_table, 0);
48
+ ret = bdrv_co_pread(bs->file, s->refcount_table_offset,
49
+ refcount_table_size2, s->refcount_table, 0);
50
if (ret < 0) {
51
goto fail;
52
}
53
@@ -XXX,XX +XXX,XX @@ int coroutine_fn qcow2_shrink_reftable(BlockDriverState *bs)
54
reftable_tmp[i] = unused_block ? 0 : cpu_to_be64(s->refcount_table[i]);
55
}
56
57
- ret = bdrv_pwrite_sync(bs->file, s->refcount_table_offset,
58
- s->refcount_table_size * REFTABLE_ENTRY_SIZE,
59
- reftable_tmp, 0);
60
+ ret = bdrv_co_pwrite_sync(bs->file, s->refcount_table_offset,
61
+ s->refcount_table_size * REFTABLE_ENTRY_SIZE,
62
+ reftable_tmp, 0);
63
/*
64
* If the write in the reftable failed the image may contain a partially
65
* overwritten reftable. In this case it would be better to clear the
66
diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/block/qcow2-snapshot.c
69
+++ b/block/qcow2-snapshot.c
70
@@ -XXX,XX +XXX,XX @@ int coroutine_fn qcow2_check_read_snapshot_table(BlockDriverState *bs,
71
} QEMU_PACKED snapshot_table_pointer;
72
73
/* qcow2_do_open() discards this information in check mode */
74
- ret = bdrv_pread(bs->file, offsetof(QCowHeader, nb_snapshots),
75
- sizeof(snapshot_table_pointer), &snapshot_table_pointer,
76
- 0);
77
+ ret = bdrv_co_pread(bs->file, offsetof(QCowHeader, nb_snapshots),
78
+ sizeof(snapshot_table_pointer), &snapshot_table_pointer,
79
+ 0);
80
if (ret < 0) {
81
result->check_errors++;
82
fprintf(stderr, "ERROR failed to read the snapshot table pointer from "
83
diff --git a/block/qcow2.c b/block/qcow2.c
84
index XXXXXXX..XXXXXXX 100644
85
--- a/block/qcow2.c
86
+++ b/block/qcow2.c
87
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
88
uint64_t l1_vm_state_index;
89
bool update_header = false;
90
91
- ret = bdrv_pread(bs->file, 0, sizeof(header), &header, 0);
92
+ ret = bdrv_co_pread(bs->file, 0, sizeof(header), &header, 0);
93
if (ret < 0) {
94
error_setg_errno(errp, -ret, "Could not read qcow2 header");
95
goto fail;
96
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
97
if (header.header_length > sizeof(header)) {
98
s->unknown_header_fields_size = header.header_length - sizeof(header);
99
s->unknown_header_fields = g_malloc(s->unknown_header_fields_size);
100
- ret = bdrv_pread(bs->file, sizeof(header),
101
- s->unknown_header_fields_size,
102
- s->unknown_header_fields, 0);
103
+ ret = bdrv_co_pread(bs->file, sizeof(header),
104
+ s->unknown_header_fields_size,
105
+ s->unknown_header_fields, 0);
106
if (ret < 0) {
107
error_setg_errno(errp, -ret, "Could not read unknown qcow2 header "
108
"fields");
109
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
110
ret = -ENOMEM;
111
goto fail;
112
}
113
- ret = bdrv_pread(bs->file, s->l1_table_offset, s->l1_size * L1E_SIZE,
114
- s->l1_table, 0);
115
+ ret = bdrv_co_pread(bs->file, s->l1_table_offset, s->l1_size * L1E_SIZE,
116
+ s->l1_table, 0);
117
if (ret < 0) {
118
error_setg_errno(errp, -ret, "Could not read L1 table");
119
goto fail;
120
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
121
}
122
123
s->image_backing_file = g_malloc(len + 1);
124
- ret = bdrv_pread(bs->file, header.backing_file_offset, len,
125
- s->image_backing_file, 0);
126
+ ret = bdrv_co_pread(bs->file, header.backing_file_offset, len,
127
+ s->image_backing_file, 0);
128
if (ret < 0) {
129
error_setg_errno(errp, -ret, "Could not read backing file name");
130
goto fail;
131
@@ -XXX,XX +XXX,XX @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
132
cpu_to_be64(QCOW2_INCOMPAT_EXTL2);
133
}
134
135
- ret = blk_pwrite(blk, 0, cluster_size, header, 0);
136
+ ret = blk_co_pwrite(blk, 0, cluster_size, header, 0);
137
g_free(header);
138
if (ret < 0) {
139
error_setg_errno(errp, -ret, "Could not write qcow2 header");
140
@@ -XXX,XX +XXX,XX @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
141
/* Write a refcount table with one refcount block */
142
refcount_table = g_malloc0(2 * cluster_size);
143
refcount_table[0] = cpu_to_be64(2 * cluster_size);
144
- ret = blk_pwrite(blk, cluster_size, 2 * cluster_size, refcount_table, 0);
145
+ ret = blk_co_pwrite(blk, cluster_size, 2 * cluster_size, refcount_table, 0);
146
g_free(refcount_table);
147
148
if (ret < 0) {
149
@@ -XXX,XX +XXX,XX @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
150
}
151
152
/* Okay, now that we have a valid image, let's give it the right size */
153
- ret = blk_truncate(blk, qcow2_opts->size, false, qcow2_opts->preallocation,
154
- 0, errp);
155
+ ret = blk_co_truncate(blk, qcow2_opts->size, false,
156
+ qcow2_opts->preallocation, 0, errp);
157
if (ret < 0) {
158
error_prepend(errp, "Could not resize image: ");
159
goto out;
160
--
161
2.37.3
diff view generated by jsdifflib
New patch
1
From: Alberto Faria <afaria@redhat.com>
1
2
3
Signed-off-by: Alberto Faria <afaria@redhat.com>
4
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
5
Message-Id: <20221013123711.620631-21-pbonzini@redhat.com>
6
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
9
block/qed-table.c | 2 +-
10
block/qed.c | 12 ++++++------
11
2 files changed, 7 insertions(+), 7 deletions(-)
12
13
diff --git a/block/qed-table.c b/block/qed-table.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/block/qed-table.c
16
+++ b/block/qed-table.c
17
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qed_write_table(BDRVQEDState *s, uint64_t offset,
18
}
19
20
if (flush) {
21
- ret = bdrv_flush(s->bs);
22
+ ret = bdrv_co_flush(s->bs);
23
if (ret < 0) {
24
goto out;
25
}
26
diff --git a/block/qed.c b/block/qed.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/block/qed.c
29
+++ b/block/qed.c
30
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_do_open(BlockDriverState *bs, QDict *options,
31
int64_t file_size;
32
int ret;
33
34
- ret = bdrv_pread(bs->file, 0, sizeof(le_header), &le_header, 0);
35
+ ret = bdrv_co_pread(bs->file, 0, sizeof(le_header), &le_header, 0);
36
if (ret < 0) {
37
error_setg(errp, "Failed to read QED header");
38
return ret;
39
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_do_open(BlockDriverState *bs, QDict *options,
40
}
41
42
/* From here on only known autoclear feature bits are valid */
43
- bdrv_flush(bs->file->bs);
44
+ bdrv_co_flush(bs->file->bs);
45
}
46
47
s->l1_table = qed_alloc_table(s);
48
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_co_create(BlockdevCreateOptions *opts,
49
* The QED format associates file length with allocation status,
50
* so a new file (which is empty) must have a length of 0.
51
*/
52
- ret = blk_truncate(blk, 0, true, PREALLOC_MODE_OFF, 0, errp);
53
+ ret = blk_co_truncate(blk, 0, true, PREALLOC_MODE_OFF, 0, errp);
54
if (ret < 0) {
55
goto out;
56
}
57
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_co_create(BlockdevCreateOptions *opts,
58
}
59
60
qed_header_cpu_to_le(&header, &le_header);
61
- ret = blk_pwrite(blk, 0, sizeof(le_header), &le_header, 0);
62
+ ret = blk_co_pwrite(blk, 0, sizeof(le_header), &le_header, 0);
63
if (ret < 0) {
64
goto out;
65
}
66
- ret = blk_pwrite(blk, sizeof(le_header), header.backing_filename_size,
67
+ ret = blk_co_pwrite(blk, sizeof(le_header), header.backing_filename_size,
68
qed_opts->backing_file, 0);
69
if (ret < 0) {
70
goto out;
71
}
72
73
l1_table = g_malloc0(l1_size);
74
- ret = blk_pwrite(blk, header.l1_table_offset, l1_size, l1_table, 0);
75
+ ret = blk_co_pwrite(blk, header.l1_table_offset, l1_size, l1_table, 0);
76
if (ret < 0) {
77
goto out;
78
}
79
--
80
2.37.3
diff view generated by jsdifflib
New patch
1
From: Alberto Faria <afaria@redhat.com>
1
2
3
Signed-off-by: Alberto Faria <afaria@redhat.com>
4
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
5
Message-Id: <20221013123711.620631-22-pbonzini@redhat.com>
6
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
9
block/vdi.c | 17 +++++++++--------
10
1 file changed, 9 insertions(+), 8 deletions(-)
11
12
diff --git a/block/vdi.c b/block/vdi.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/block/vdi.c
15
+++ b/block/vdi.c
16
@@ -XXX,XX +XXX,XX @@ vdi_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
17
* so this full-cluster write does not overlap a partial write
18
* of the same cluster, issued from the "else" branch.
19
*/
20
- ret = bdrv_pwrite(bs->file, data_offset, s->block_size, block, 0);
21
+ ret = bdrv_co_pwrite(bs->file, data_offset, s->block_size, block,
22
+ 0);
23
qemu_co_rwlock_unlock(&s->bmap_lock);
24
} else {
25
nonallocating_write:
26
@@ -XXX,XX +XXX,XX @@ nonallocating_write:
27
assert(VDI_IS_ALLOCATED(bmap_first));
28
*header = s->header;
29
vdi_header_to_le(header);
30
- ret = bdrv_pwrite(bs->file, 0, sizeof(*header), header, 0);
31
+ ret = bdrv_co_pwrite(bs->file, 0, sizeof(*header), header, 0);
32
g_free(header);
33
34
if (ret < 0) {
35
@@ -XXX,XX +XXX,XX @@ nonallocating_write:
36
base = ((uint8_t *)&s->bmap[0]) + bmap_first * SECTOR_SIZE;
37
logout("will write %u block map sectors starting from entry %u\n",
38
n_sectors, bmap_first);
39
- ret = bdrv_pwrite(bs->file, offset * SECTOR_SIZE,
40
- n_sectors * SECTOR_SIZE, base, 0);
41
+ ret = bdrv_co_pwrite(bs->file, offset * SECTOR_SIZE,
42
+ n_sectors * SECTOR_SIZE, base, 0);
43
}
44
45
return ret;
46
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options,
47
vdi_header_print(&header);
48
}
49
vdi_header_to_le(&header);
50
- ret = blk_pwrite(blk, offset, sizeof(header), &header, 0);
51
+ ret = blk_co_pwrite(blk, offset, sizeof(header), &header, 0);
52
if (ret < 0) {
53
error_setg(errp, "Error writing header");
54
goto exit;
55
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options,
56
bmap[i] = VDI_UNALLOCATED;
57
}
58
}
59
- ret = blk_pwrite(blk, offset, bmap_size, bmap, 0);
60
+ ret = blk_co_pwrite(blk, offset, bmap_size, bmap, 0);
61
if (ret < 0) {
62
error_setg(errp, "Error writing bmap");
63
goto exit;
64
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options,
65
}
66
67
if (image_type == VDI_TYPE_STATIC) {
68
- ret = blk_truncate(blk, offset + blocks * block_size, false,
69
- PREALLOC_MODE_OFF, 0, errp);
70
+ ret = blk_co_truncate(blk, offset + blocks * block_size, false,
71
+ PREALLOC_MODE_OFF, 0, errp);
72
if (ret < 0) {
73
error_prepend(errp, "Failed to statically allocate file");
74
goto exit;
75
--
76
2.37.3
diff view generated by jsdifflib
New patch
1
From: Alberto Faria <afaria@redhat.com>
1
2
3
Signed-off-by: Alberto Faria <afaria@redhat.com>
4
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
5
Message-Id: <20221013123711.620631-23-pbonzini@redhat.com>
6
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
9
block/vhdx.c | 8 ++++----
10
1 file changed, 4 insertions(+), 4 deletions(-)
11
12
diff --git a/block/vhdx.c b/block/vhdx.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/block/vhdx.c
15
+++ b/block/vhdx.c
16
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vhdx_co_create(BlockdevCreateOptions *opts,
17
creator = g_utf8_to_utf16("QEMU v" QEMU_VERSION, -1, NULL,
18
&creator_items, NULL);
19
signature = cpu_to_le64(VHDX_FILE_SIGNATURE);
20
- ret = blk_pwrite(blk, VHDX_FILE_ID_OFFSET, sizeof(signature), &signature,
21
- 0);
22
+ ret = blk_co_pwrite(blk, VHDX_FILE_ID_OFFSET, sizeof(signature), &signature,
23
+ 0);
24
if (ret < 0) {
25
error_setg_errno(errp, -ret, "Failed to write file signature");
26
goto delete_and_exit;
27
}
28
if (creator) {
29
- ret = blk_pwrite(blk, VHDX_FILE_ID_OFFSET + sizeof(signature),
30
- creator_items * sizeof(gunichar2), creator, 0);
31
+ ret = blk_co_pwrite(blk, VHDX_FILE_ID_OFFSET + sizeof(signature),
32
+ creator_items * sizeof(gunichar2), creator, 0);
33
if (ret < 0) {
34
error_setg_errno(errp, -ret, "Failed to write creator field");
35
goto delete_and_exit;
36
--
37
2.37.3
diff view generated by jsdifflib
New patch
1
From: Alberto Faria <afaria@redhat.com>
1
2
3
Signed-off-by: Alberto Faria <afaria@redhat.com>
4
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
5
Message-Id: <20221013123711.620631-24-pbonzini@redhat.com>
6
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
9
block/vmdk.c | 54 ++++++++++++++++++++++++++--------------------------
10
1 file changed, 27 insertions(+), 27 deletions(-)
11
12
diff --git a/block/vmdk.c b/block/vmdk.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/block/vmdk.c
15
+++ b/block/vmdk.c
16
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn get_whole_cluster(BlockDriverState *bs,
17
if (copy_from_backing) {
18
/* qcow2 emits this on bs->file instead of bs->backing */
19
BLKDBG_EVENT(extent->file, BLKDBG_COW_READ);
20
- ret = bdrv_pread(bs->backing, offset, skip_start_bytes,
21
- whole_grain, 0);
22
+ ret = bdrv_co_pread(bs->backing, offset, skip_start_bytes,
23
+ whole_grain, 0);
24
if (ret < 0) {
25
ret = VMDK_ERROR;
26
goto exit;
27
}
28
}
29
BLKDBG_EVENT(extent->file, BLKDBG_COW_WRITE);
30
- ret = bdrv_pwrite(extent->file, cluster_offset, skip_start_bytes,
31
- whole_grain, 0);
32
+ ret = bdrv_co_pwrite(extent->file, cluster_offset, skip_start_bytes,
33
+ whole_grain, 0);
34
if (ret < 0) {
35
ret = VMDK_ERROR;
36
goto exit;
37
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn get_whole_cluster(BlockDriverState *bs,
38
if (copy_from_backing) {
39
/* qcow2 emits this on bs->file instead of bs->backing */
40
BLKDBG_EVENT(extent->file, BLKDBG_COW_READ);
41
- ret = bdrv_pread(bs->backing, offset + skip_end_bytes,
42
- cluster_bytes - skip_end_bytes,
43
- whole_grain + skip_end_bytes, 0);
44
+ ret = bdrv_co_pread(bs->backing, offset + skip_end_bytes,
45
+ cluster_bytes - skip_end_bytes,
46
+ whole_grain + skip_end_bytes, 0);
47
if (ret < 0) {
48
ret = VMDK_ERROR;
49
goto exit;
50
}
51
}
52
BLKDBG_EVENT(extent->file, BLKDBG_COW_WRITE);
53
- ret = bdrv_pwrite(extent->file, cluster_offset + skip_end_bytes,
54
- cluster_bytes - skip_end_bytes,
55
- whole_grain + skip_end_bytes, 0);
56
+ ret = bdrv_co_pwrite(extent->file, cluster_offset + skip_end_bytes,
57
+ cluster_bytes - skip_end_bytes,
58
+ whole_grain + skip_end_bytes, 0);
59
if (ret < 0) {
60
ret = VMDK_ERROR;
61
goto exit;
62
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data,
63
offset = cpu_to_le32(offset);
64
/* update L2 table */
65
BLKDBG_EVENT(extent->file, BLKDBG_L2_UPDATE);
66
- if (bdrv_pwrite(extent->file,
67
- ((int64_t)m_data->l2_offset * 512)
68
- + (m_data->l2_index * sizeof(offset)),
69
- sizeof(offset), &offset, 0) < 0) {
70
+ if (bdrv_co_pwrite(extent->file,
71
+ ((int64_t)m_data->l2_offset * 512)
72
+ + (m_data->l2_index * sizeof(offset)),
73
+ sizeof(offset), &offset, 0) < 0) {
74
return VMDK_ERROR;
75
}
76
/* update backup L2 table */
77
if (extent->l1_backup_table_offset != 0) {
78
m_data->l2_offset = extent->l1_backup_table[m_data->l1_index];
79
- if (bdrv_pwrite(extent->file,
80
- ((int64_t)m_data->l2_offset * 512)
81
- + (m_data->l2_index * sizeof(offset)),
82
- sizeof(offset), &offset, 0) < 0) {
83
+ if (bdrv_co_pwrite(extent->file,
84
+ ((int64_t)m_data->l2_offset * 512)
85
+ + (m_data->l2_index * sizeof(offset)),
86
+ sizeof(offset), &offset, 0) < 0) {
87
return VMDK_ERROR;
88
}
89
}
90
- if (bdrv_flush(extent->file->bs) < 0) {
91
+ if (bdrv_co_flush(extent->file->bs) < 0) {
92
return VMDK_ERROR;
93
}
94
if (m_data->l2_cache_entry) {
95
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn get_cluster_offset(BlockDriverState *bs,
96
}
97
l2_table = (char *)extent->l2_cache + (min_index * l2_size_bytes);
98
BLKDBG_EVENT(extent->file, BLKDBG_L2_LOAD);
99
- if (bdrv_pread(extent->file,
100
+ if (bdrv_co_pread(extent->file,
101
(int64_t)l2_offset * 512,
102
l2_size_bytes,
103
- l2_table,
104
- 0
105
+ l2_table, 0
106
) < 0) {
107
return VMDK_ERROR;
108
}
109
@@ -XXX,XX +XXX,XX @@ vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset,
110
cluster_buf = g_malloc(buf_bytes);
111
uncomp_buf = g_malloc(cluster_bytes);
112
BLKDBG_EVENT(extent->file, BLKDBG_READ_COMPRESSED);
113
- ret = bdrv_pread(extent->file, cluster_offset, buf_bytes, cluster_buf, 0);
114
+ ret = bdrv_co_pread(extent->file, cluster_offset, buf_bytes, cluster_buf,
115
+ 0);
116
if (ret < 0) {
117
goto out;
118
}
119
@@ -XXX,XX +XXX,XX @@ vmdk_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes,
120
return length;
121
}
122
length = QEMU_ALIGN_UP(length, BDRV_SECTOR_SIZE);
123
- ret = bdrv_truncate(s->extents[i].file, length, false,
124
- PREALLOC_MODE_OFF, 0, NULL);
125
+ ret = bdrv_co_truncate(s->extents[i].file, length, false,
126
+ PREALLOC_MODE_OFF, 0, NULL);
127
if (ret < 0) {
128
return ret;
129
}
130
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vmdk_co_do_create(int64_t size,
131
desc_offset = 0x200;
132
}
133
134
- ret = blk_pwrite(blk, desc_offset, desc_len, desc, 0);
135
+ ret = blk_co_pwrite(blk, desc_offset, desc_len, desc, 0);
136
if (ret < 0) {
137
error_setg_errno(errp, -ret, "Could not write description");
138
goto exit;
139
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vmdk_co_do_create(int64_t size,
140
/* bdrv_pwrite write padding zeros to align to sector, we don't need that
141
* for description file */
142
if (desc_offset == 0) {
143
- ret = blk_truncate(blk, desc_len, false, PREALLOC_MODE_OFF, 0, errp);
144
+ ret = blk_co_truncate(blk, desc_len, false, PREALLOC_MODE_OFF, 0, errp);
145
if (ret < 0) {
146
goto exit;
147
}
148
--
149
2.37.3
diff view generated by jsdifflib
1
bdrv_subtree_drained_end() requires the caller to hold the AioContext
1
From: Alberto Faria <afaria@redhat.com>
2
lock for the drained node. Not doing this for nodes outside of the main
3
AioContext leads to crashes when AIO_WAIT_WHILE() needs to wait and
4
tries to temporarily release the lock.
5
2
6
Fixes: 3908b7a8994fa5ef7a89aa58cd5a02fc58141592
3
Signed-off-by: Alberto Faria <afaria@redhat.com>
7
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2046659
4
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
8
Reported-by: Qing Wang <qinwang@redhat.com>
5
Message-Id: <20221013123711.620631-25-pbonzini@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
10
Message-Id: <20220203140534.36522-2-kwolf@redhat.com>
11
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
8
---
14
blockdev.c | 11 ++++++++++-
9
blockdev.c | 2 +-
15
1 file changed, 10 insertions(+), 1 deletion(-)
10
1 file changed, 1 insertion(+), 1 deletion(-)
16
11
17
diff --git a/blockdev.c b/blockdev.c
12
diff --git a/blockdev.c b/blockdev.c
18
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
19
--- a/blockdev.c
14
--- a/blockdev.c
20
+++ b/blockdev.c
15
+++ b/blockdev.c
21
@@ -XXX,XX +XXX,XX @@ void qmp_blockdev_reopen(BlockdevOptionsList *reopen_list, Error **errp)
16
@@ -XXX,XX +XXX,XX @@ void coroutine_fn qmp_block_resize(bool has_device, const char *device,
22
{
17
bdrv_co_unlock(bs);
23
BlockReopenQueue *queue = NULL;
18
24
GSList *drained = NULL;
19
old_ctx = bdrv_co_enter(bs);
25
+ GSList *p;
20
- blk_truncate(blk, size, false, PREALLOC_MODE_OFF, 0, errp);
26
21
+ blk_co_truncate(blk, size, false, PREALLOC_MODE_OFF, 0, errp);
27
/* Add each one of the BDS that we want to reopen to the queue */
22
bdrv_co_leave(bs, old_ctx);
28
for (; reopen_list != NULL; reopen_list = reopen_list->next) {
23
29
@@ -XXX,XX +XXX,XX @@ void qmp_blockdev_reopen(BlockdevOptionsList *reopen_list, Error **errp)
24
bdrv_co_lock(bs);
30
31
fail:
32
bdrv_reopen_queue_free(queue);
33
- g_slist_free_full(drained, (GDestroyNotify) bdrv_subtree_drained_end);
34
+ for (p = drained; p; p = p->next) {
35
+ BlockDriverState *bs = p->data;
36
+ AioContext *ctx = bdrv_get_aio_context(bs);
37
+
38
+ aio_context_acquire(ctx);
39
+ bdrv_subtree_drained_end(bs);
40
+ aio_context_release(ctx);
41
+ }
42
+ g_slist_free(drained);
43
}
44
45
void qmp_blockdev_del(const char *node_name, Error **errp)
46
--
25
--
47
2.34.1
26
2.37.3
48
49
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
blk_set_enable_write_cache() is defined as GLOBAL_STATE_CODE
4
but can be invoked from iothreads when handling scsi requests.
5
This triggers an assertion failure:
6
7
0x00007fd6c3515ce1 in raise () from /lib/x86_64-linux-gnu/libc.so.6
8
0x00007fd6c34ff537 in abort () from /lib/x86_64-linux-gnu/libc.so.6
9
0x00007fd6c34ff40f in ?? () from /lib/x86_64-linux-gnu/libc.so.6
10
0x00007fd6c350e662 in __assert_fail () from /lib/x86_64-linux-gnu/libc.so.6
11
0x000056149e2cea03 in blk_set_enable_write_cache (wce=true, blk=0x5614a01c27f0)
12
at ../src/block/block-backend.c:1949
13
0x000056149e2d0a67 in blk_set_enable_write_cache (blk=0x5614a01c27f0,
14
wce=<optimized out>) at ../src/block/block-backend.c:1951
15
0x000056149dfe9c59 in scsi_disk_apply_mode_select (p=0x7fd6b400c00e "\004",
16
page=<optimized out>, s=<optimized out>) at ../src/hw/scsi/scsi-disk.c:1520
17
mode_select_pages (change=true, len=18, p=0x7fd6b400c00e "\004", r=0x7fd6b4001ff0)
18
at ../src/hw/scsi/scsi-disk.c:1570
19
scsi_disk_emulate_mode_select (inbuf=<optimized out>, r=0x7fd6b4001ff0) at
20
../src/hw/scsi/scsi-disk.c:1640
21
scsi_disk_emulate_write_data (req=0x7fd6b4001ff0) at ../src/hw/scsi/scsi-disk.c:1934
22
0x000056149e18ff16 in virtio_scsi_handle_cmd_req_submit (req=<optimized out>,
23
req=<optimized out>, s=0x5614a12f16b0) at ../src/hw/scsi/virtio-scsi.c:719
24
virtio_scsi_handle_cmd_vq (vq=0x7fd6bab92140, s=0x5614a12f16b0) at
25
../src/hw/scsi/virtio-scsi.c:761
26
virtio_scsi_handle_cmd (vq=<optimized out>, vdev=<optimized out>) at
27
../src/hw/scsi/virtio-scsi.c:775
28
virtio_scsi_handle_cmd (vdev=0x5614a12f16b0, vq=0x7fd6bab92140) at
29
../src/hw/scsi/virtio-scsi.c:765
30
0x000056149e1a8aa6 in virtio_queue_notify_vq (vq=0x7fd6bab92140) at
31
../src/hw/virtio/virtio.c:2365
32
0x000056149e3ccea5 in aio_dispatch_handler (ctx=ctx@entry=0x5614a01babe0,
33
node=<optimized out>) at ../src/util/aio-posix.c:369
34
0x000056149e3cd868 in aio_dispatch_ready_handlers (ready_list=0x7fd6c09b2680,
35
ctx=0x5614a01babe0) at ../src/util/aio-posix.c:399
36
aio_poll (ctx=0x5614a01babe0, blocking=blocking@entry=true) at
37
../src/util/aio-posix.c:713
38
0x000056149e2a7796 in iothread_run (opaque=opaque@entry=0x56149ffde500) at
39
../src/iothread.c:67
40
0x000056149e3d0859 in qemu_thread_start (args=0x7fd6c09b26f0) at
41
../src/util/qemu-thread-posix.c:504
42
0x00007fd6c36b9ea7 in start_thread () from /lib/x86_64-linux-gnu/libpthread.so.0
43
0x00007fd6c35d9aef in clone () from /lib/x86_64-linux-gnu/libc.so.6
44
45
Changing GLOBAL_STATE_CODE in IO_CODE is allowed, since GSC callers are
46
allowed to call IO_CODE.
47
48
Resolves: #1272
49
50
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
51
Message-Id: <20221027072726.2681500-1-eesposit@redhat.com>
52
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
53
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
54
Tested-by: Antoine Damhet <antoine.damhet@shadow.tech>
55
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
56
---
57
block/block-backend.c | 2 +-
58
1 file changed, 1 insertion(+), 1 deletion(-)
59
60
diff --git a/block/block-backend.c b/block/block-backend.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/block/block-backend.c
63
+++ b/block/block-backend.c
64
@@ -XXX,XX +XXX,XX @@ bool blk_enable_write_cache(BlockBackend *blk)
65
66
void blk_set_enable_write_cache(BlockBackend *blk, bool wce)
67
{
68
- GLOBAL_STATE_CODE();
69
+ IO_CODE();
70
blk->enable_write_cache = wce;
71
}
72
73
--
74
2.37.3
diff view generated by jsdifflib