1
The following changes since commit 527266f324def9f7f392fe3b0dd940cb8dc699d9:
1
The following changes since commit ee59483267de29056b5b2ee2421ef3844e5c9932:
2
2
3
Merge remote-tracking branch 'remotes/armbru/tags/pull-pflash-2019-03-26' into staging (2019-03-26 09:57:07 +0000)
3
Merge tag 'qemu-openbios-20230307' of https://github.com/mcayland/qemu into staging (2023-03-09 16:55:03 +0000)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
git://repo.or.cz/qemu/kevin.git tags/for-upstream
7
https://repo.or.cz/qemu/kevin.git tags/for-upstream
8
8
9
for you to fetch changes up to c6e3f520c802c5cb2de80576aba7f9f1fe985d8b:
9
for you to fetch changes up to ecf8191314798391b1df80bcb829c0ead4f8acc9:
10
10
11
qemu-io: Add write -n for BDRV_REQ_NO_FALLBACK (2019-03-26 11:37:51 +0100)
11
qed: remove spurious BDRV_POLL_WHILE() (2023-03-10 15:14:46 +0100)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block layer patches:
14
Block layer patches
15
15
16
- Fix slow pre-zeroing in qemu-img convert
16
- fuse: Fix fallocate(PUNCH_HOLE) to zero out the range
17
- Test case for block job pausing on I/O errors
17
- qed: remove spurious BDRV_POLL_WHILE()
18
18
19
----------------------------------------------------------------
19
----------------------------------------------------------------
20
Kevin Wolf (6):
20
Hanna Czenczek (2):
21
block: Remove error messages in bdrv_make_zero()
21
block/fuse: Let PUNCH_HOLE write zeroes
22
block: Add BDRV_REQ_NO_FALLBACK
22
iotests/308: Add test for 'write -zu'
23
block: Advertise BDRV_REQ_NO_FALLBACK in filter drivers
24
file-posix: Support BDRV_REQ_NO_FALLBACK for zero writes
25
qemu-img: Use BDRV_REQ_NO_FALLBACK for pre-zeroing
26
qemu-io: Add write -n for BDRV_REQ_NO_FALLBACK
27
23
28
Vladimir Sementsov-Ogievskiy (1):
24
Stefan Hajnoczi (1):
29
iotests: add 248: test resume mirror after auto pause on ENOSPC
25
qed: remove spurious BDRV_POLL_WHILE()
30
26
31
include/block/block.h | 7 ++++-
27
block/export/fuse.c | 11 ++++++++++-
32
include/block/raw-aio.h | 1 +
28
block/qed.c | 1 -
33
block/blkdebug.c | 2 +-
29
tests/qemu-iotests/308 | 43 +++++++++++++++++++++++++++++++++++++++++++
34
block/copy-on-read.c | 7 ++---
30
tests/qemu-iotests/308.out | 35 +++++++++++++++++++++++++++++++++++
35
block/file-posix.c | 24 ++++++++++------
31
4 files changed, 88 insertions(+), 2 deletions(-)
36
block/io.c | 16 +++++++----
37
block/mirror.c | 3 +-
38
block/raw-format.c | 2 +-
39
qemu-img.c | 2 +-
40
qemu-io-cmds.c | 13 +++++++--
41
tests/qemu-iotests/248 | 71 ++++++++++++++++++++++++++++++++++++++++++++++
42
tests/qemu-iotests/248.out | 8 ++++++
43
tests/qemu-iotests/group | 1 +
44
13 files changed, 133 insertions(+), 24 deletions(-)
45
create mode 100755 tests/qemu-iotests/248
46
create mode 100644 tests/qemu-iotests/248.out
47
diff view generated by jsdifflib
1
This makes the new BDRV_REQ_NO_FALLBACK flag available in the qemu-io
1
From: Hanna Czenczek <hreitz@redhat.com>
2
write command.
3
2
3
fallocate(2) says about PUNCH_HOLE: "After a successful call, subsequent
4
reads from this range will return zeros." As it is, PUNCH_HOLE is
5
implemented as a call to blk_pdiscard(), which does not guarantee this.
6
7
We must call blk_pwrite_zeroes() instead. The difference to ZERO_RANGE
8
is that we pass the `BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK` flags to
9
the call -- the storage is supposed to be unmapped, and a slow fallback
10
by actually writing zeroes as data is not allowed.
11
12
Closes: https://gitlab.com/qemu-project/qemu/-/issues/1507
13
Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
14
Message-Id: <20230227104725.33511-2-hreitz@redhat.com>
15
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Acked-by: Eric Blake <eblake@redhat.com>
6
---
17
---
7
qemu-io-cmds.c | 13 +++++++++++--
18
block/export/fuse.c | 11 ++++++++++-
8
1 file changed, 11 insertions(+), 2 deletions(-)
19
1 file changed, 10 insertions(+), 1 deletion(-)
9
20
10
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
21
diff --git a/block/export/fuse.c b/block/export/fuse.c
11
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
12
--- a/qemu-io-cmds.c
23
--- a/block/export/fuse.c
13
+++ b/qemu-io-cmds.c
24
+++ b/block/export/fuse.c
14
@@ -XXX,XX +XXX,XX @@ static void write_help(void)
25
@@ -XXX,XX +XXX,XX @@ static void fuse_fallocate(fuse_req_t req, fuse_ino_t inode, int mode,
15
" -b, -- write to the VM state rather than the virtual disk\n"
26
do {
16
" -c, -- write compressed data with blk_write_compressed\n"
27
int size = MIN(length, BDRV_REQUEST_MAX_BYTES);
17
" -f, -- use Force Unit Access semantics\n"
28
18
+" -n, -- with -z, don't allow slow fallback\n"
29
- ret = blk_pdiscard(exp->common.blk, offset, size);
19
" -p, -- ignored for backwards compatibility\n"
30
+ ret = blk_pwrite_zeroes(exp->common.blk, offset, size,
20
" -P, -- use different pattern to fill file\n"
31
+ BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK);
21
" -C, -- report statistics in a machine parsable format\n"
32
+ if (ret == -ENOTSUP) {
22
@@ -XXX,XX +XXX,XX @@ static const cmdinfo_t write_cmd = {
33
+ /*
23
.perm = BLK_PERM_WRITE,
34
+ * fallocate() specifies to return EOPNOTSUPP for unsupported
24
.argmin = 2,
35
+ * operations
25
.argmax = -1,
36
+ */
26
- .args = "[-bcCfquz] [-P pattern] off len",
37
+ ret = -EOPNOTSUPP;
27
+ .args = "[-bcCfnquz] [-P pattern] off len",
38
+ }
28
.oneline = "writes a number of bytes at a specified offset",
29
.help = write_help,
30
};
31
@@ -XXX,XX +XXX,XX @@ static int write_f(BlockBackend *blk, int argc, char **argv)
32
int64_t total = 0;
33
int pattern = 0xcd;
34
35
- while ((c = getopt(argc, argv, "bcCfpP:quz")) != -1) {
36
+ while ((c = getopt(argc, argv, "bcCfnpP:quz")) != -1) {
37
switch (c) {
38
case 'b':
39
bflag = true;
40
@@ -XXX,XX +XXX,XX @@ static int write_f(BlockBackend *blk, int argc, char **argv)
41
case 'f':
42
flags |= BDRV_REQ_FUA;
43
break;
44
+ case 'n':
45
+ flags |= BDRV_REQ_NO_FALLBACK;
46
+ break;
47
case 'p':
48
/* Ignored for backwards compatibility */
49
break;
50
@@ -XXX,XX +XXX,XX @@ static int write_f(BlockBackend *blk, int argc, char **argv)
51
return -EINVAL;
52
}
53
54
+ if ((flags & BDRV_REQ_NO_FALLBACK) && !zflag) {
55
+ printf("-n requires -z to be specified\n");
56
+ return -EINVAL;
57
+ }
58
+
39
+
59
if ((flags & BDRV_REQ_MAY_UNMAP) && !zflag) {
40
offset += size;
60
printf("-u requires -z to be specified\n");
41
length -= size;
61
return -EINVAL;
42
} while (ret == 0 && length > 0);
62
--
43
--
63
2.20.1
44
2.39.2
64
65
diff view generated by jsdifflib
1
If qemu-img convert sees that the target image isn't zero-initialised
1
From: Hanna Czenczek <hreitz@redhat.com>
2
yet, it tries to do an efficient zero write for the whole image first
3
to save the overhead of repeated explicit zero writes during the
4
conversion. Obviously, this provides only an advantage if the
5
pre-zeroing is actually efficient. Otherwise, we can end up writing
6
zeroes slowly while zeroing out the whole image, and then overwrite the
7
same blocks again with real data, potentially doubling the written data.
8
2
9
Pass BDRV_REQ_NO_FALLBACK to blk_make_zero() to avoid this case. If we
3
Try writing zeroes to a FUSE export while allowing the area to be
10
can't efficiently zero out, we'll instead write explicit zeroes only if
4
unmapped; block/file-posix.c generally implements writing zeroes with
11
there is no data to be written to a block.
5
BDRV_REQ_MAY_UNMAP ('write -zu') by calling fallocate(PUNCH_HOLE). This
6
used to lead to a blk_pdiscard() in the FUSE export, which may or may
7
not lead to the area being zeroed. HEAD^ fixed this to use
8
blk_pwrite_zeroes() instead (again with BDRV_REQ_MAY_UNMAP), so verify
9
that running `qemu-io 'write -zu'` on a FUSE exports always results in
10
zeroes being written.
12
11
12
Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
13
Message-Id: <20230227104725.33511-3-hreitz@redhat.com>
14
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
Acked-by: Eric Blake <eblake@redhat.com>
15
---
16
---
16
qemu-img.c | 2 +-
17
tests/qemu-iotests/308 | 43 ++++++++++++++++++++++++++++++++++++++
17
1 file changed, 1 insertion(+), 1 deletion(-)
18
tests/qemu-iotests/308.out | 35 +++++++++++++++++++++++++++++++
19
2 files changed, 78 insertions(+)
18
20
19
diff --git a/qemu-img.c b/qemu-img.c
21
diff --git a/tests/qemu-iotests/308 b/tests/qemu-iotests/308
22
index XXXXXXX..XXXXXXX 100755
23
--- a/tests/qemu-iotests/308
24
+++ b/tests/qemu-iotests/308
25
@@ -XXX,XX +XXX,XX @@ echo
26
echo '=== Compare copy with original ==='
27
28
$QEMU_IMG compare -f raw -F $IMGFMT "$COPIED_IMG" "$TEST_IMG"
29
+_cleanup_test_img
30
+
31
+echo
32
+echo '=== Writing zeroes while unmapping ==='
33
+# Regression test for https://gitlab.com/qemu-project/qemu/-/issues/1507
34
+_make_test_img 64M
35
+$QEMU_IO -c 'write -s /dev/urandom 0 64M' "$TEST_IMG" | _filter_qemu_io
36
+
37
+_launch_qemu
38
+_send_qemu_cmd $QEMU_HANDLE \
39
+ "{'execute': 'qmp_capabilities'}" \
40
+ 'return'
41
+
42
+_send_qemu_cmd $QEMU_HANDLE \
43
+ "{'execute': 'blockdev-add',
44
+ 'arguments': {
45
+ 'driver': '$IMGFMT',
46
+ 'node-name': 'node-format',
47
+ 'file': {
48
+ 'driver': 'file',
49
+ 'filename': '$TEST_IMG'
50
+ }
51
+ } }" \
52
+ 'return'
53
+
54
+fuse_export_add 'export' "'mountpoint': '$EXT_MP', 'writable': true"
55
+
56
+# Try writing zeroes by unmapping
57
+$QEMU_IO -f raw -c 'write -zu 0 64M' "$EXT_MP" | _filter_qemu_io
58
+
59
+# Check the result
60
+$QEMU_IO -f raw -c 'read -P 0 0 64M' "$EXT_MP" | _filter_qemu_io
61
+
62
+_send_qemu_cmd $QEMU_HANDLE \
63
+ "{'execute': 'quit'}" \
64
+ 'return'
65
+
66
+wait=yes _cleanup_qemu
67
+
68
+# Check the original image
69
+$QEMU_IO -c 'read -P 0 0 64M' "$TEST_IMG" | _filter_qemu_io
70
+
71
+_cleanup_test_img
72
73
# success, all done
74
echo "*** done"
75
diff --git a/tests/qemu-iotests/308.out b/tests/qemu-iotests/308.out
20
index XXXXXXX..XXXXXXX 100644
76
index XXXXXXX..XXXXXXX 100644
21
--- a/qemu-img.c
77
--- a/tests/qemu-iotests/308.out
22
+++ b/qemu-img.c
78
+++ b/tests/qemu-iotests/308.out
23
@@ -XXX,XX +XXX,XX @@ static int convert_do_copy(ImgConvertState *s)
79
@@ -XXX,XX +XXX,XX @@ OK: Post-truncate image size is as expected
24
if (!s->has_zero_init && !s->target_has_backing &&
80
25
bdrv_can_write_zeroes_with_unmap(blk_bs(s->target)))
81
=== Compare copy with original ===
26
{
82
Images are identical.
27
- ret = blk_make_zero(s->target, BDRV_REQ_MAY_UNMAP);
83
+
28
+ ret = blk_make_zero(s->target, BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK);
84
+=== Writing zeroes while unmapping ===
29
if (ret == 0) {
85
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
30
s->has_zero_init = true;
86
+wrote 67108864/67108864 bytes at offset 0
31
}
87
+64 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
88
+{'execute': 'qmp_capabilities'}
89
+{"return": {}}
90
+{'execute': 'blockdev-add',
91
+ 'arguments': {
92
+ 'driver': 'IMGFMT',
93
+ 'node-name': 'node-format',
94
+ 'file': {
95
+ 'driver': 'file',
96
+ 'filename': 'TEST_DIR/t.IMGFMT'
97
+ }
98
+ } }
99
+{"return": {}}
100
+{'execute': 'block-export-add',
101
+ 'arguments': {
102
+ 'type': 'fuse',
103
+ 'id': 'export',
104
+ 'node-name': 'node-format',
105
+ 'mountpoint': 'TEST_DIR/t.IMGFMT.fuse', 'writable': true
106
+ } }
107
+{"return": {}}
108
+wrote 67108864/67108864 bytes at offset 0
109
+64 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
110
+read 67108864/67108864 bytes at offset 0
111
+64 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
112
+{'execute': 'quit'}
113
+{"return": {}}
114
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
115
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "export"}}
116
+read 67108864/67108864 bytes at offset 0
117
+64 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
118
*** done
32
--
119
--
33
2.20.1
120
2.39.2
34
35
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
From: Stefan Hajnoczi <stefanha@redhat.com>
2
2
3
Test that mirror job actually resume on resume command after being
3
This looks like a copy-paste or merge error. BDRV_POLL_WHILE() is
4
automatically paused on ENOSPC error.
4
already called above. It's not needed in the qemu_in_coroutine() case.
5
5
6
It's a follow-up test for 8d9648cbf3e
6
Fixes: 9fb4dfc570ce ("qed: make bdrv_qed_do_open a coroutine_fn")
7
"blockjob: fix user pause in block_job_error_action"
7
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
8
8
Message-Id: <20230309163134.398707-1-stefanha@redhat.com>
9
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
10
Tested-by: John Snow <jsnow@redhat.com>
11
Reviewed-by: John Snow <jsnow@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
11
---
14
tests/qemu-iotests/248 | 71 ++++++++++++++++++++++++++++++++++++++
12
block/qed.c | 1 -
15
tests/qemu-iotests/248.out | 8 +++++
13
1 file changed, 1 deletion(-)
16
tests/qemu-iotests/group | 1 +
17
3 files changed, 80 insertions(+)
18
create mode 100755 tests/qemu-iotests/248
19
create mode 100644 tests/qemu-iotests/248.out
20
14
21
diff --git a/tests/qemu-iotests/248 b/tests/qemu-iotests/248
15
diff --git a/block/qed.c b/block/qed.c
22
new file mode 100755
23
index XXXXXXX..XXXXXXX
24
--- /dev/null
25
+++ b/tests/qemu-iotests/248
26
@@ -XXX,XX +XXX,XX @@
27
+#!/usr/bin/env python
28
+#
29
+# Test resume mirror after auto pause on ENOSPC
30
+#
31
+# Copyright (c) 2019 Virtuozzo International GmbH. All rights reserved.
32
+#
33
+# This program is free software; you can redistribute it and/or modify
34
+# it under the terms of the GNU General Public License as published by
35
+# the Free Software Foundation; either version 2 of the License, or
36
+# (at your option) any later version.
37
+#
38
+# This program is distributed in the hope that it will be useful,
39
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
40
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
41
+# GNU General Public License for more details.
42
+#
43
+# You should have received a copy of the GNU General Public License
44
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
45
+#
46
+
47
+import iotests
48
+from iotests import qemu_img_create, qemu_io, file_path, filter_qmp_testfiles
49
+
50
+iotests.verify_image_format(supported_fmts=['qcow2'])
51
+
52
+source, target = file_path('source', 'target')
53
+size = 5 * 1024 * 1024
54
+limit = 2 * 1024 * 1024
55
+
56
+qemu_img_create('-f', iotests.imgfmt, source, str(size))
57
+qemu_img_create('-f', iotests.imgfmt, target, str(size))
58
+qemu_io('-c', 'write 0 {}'.format(size), source)
59
+
60
+# raw format don't like empty files
61
+qemu_io('-c', 'write 0 {}'.format(size), target)
62
+
63
+vm = iotests.VM().add_drive(source)
64
+vm.launch()
65
+
66
+blockdev_opts = {
67
+ 'driver': iotests.imgfmt,
68
+ 'node-name': 'target',
69
+ 'file': {
70
+ 'driver': 'raw',
71
+ 'size': limit,
72
+ 'file': {
73
+ 'driver': 'file',
74
+ 'filename': target
75
+ }
76
+ }
77
+}
78
+vm.qmp_log('blockdev-add', filters=[filter_qmp_testfiles], **blockdev_opts)
79
+
80
+vm.qmp_log('blockdev-mirror', device='drive0', sync='full', target='target',
81
+ on_target_error='enospc')
82
+
83
+vm.event_wait('JOB_STATUS_CHANGE', timeout=3.0,
84
+ match={'data': {'status': 'paused'}})
85
+
86
+# drop other cached events, to not interfere with further wait for 'running'
87
+vm.get_qmp_events()
88
+
89
+del blockdev_opts['file']['size']
90
+vm.qmp_log('x-blockdev-reopen', filters=[filter_qmp_testfiles],
91
+ **blockdev_opts)
92
+
93
+vm.qmp_log('block-job-resume', device='drive0')
94
+vm.event_wait('JOB_STATUS_CHANGE', timeout=1.0,
95
+ match={'data': {'status': 'running'}})
96
+
97
+vm.shutdown()
98
diff --git a/tests/qemu-iotests/248.out b/tests/qemu-iotests/248.out
99
new file mode 100644
100
index XXXXXXX..XXXXXXX
101
--- /dev/null
102
+++ b/tests/qemu-iotests/248.out
103
@@ -XXX,XX +XXX,XX @@
104
+{"execute": "blockdev-add", "arguments": {"driver": "qcow2", "file": {"driver": "raw", "file": {"driver": "file", "filename": "TEST_DIR/PID-target"}, "size": 2097152}, "node-name": "target"}}
105
+{"return": {}}
106
+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "on-target-error": "enospc", "sync": "full", "target": "target"}}
107
+{"return": {}}
108
+{"execute": "x-blockdev-reopen", "arguments": {"driver": "qcow2", "file": {"driver": "raw", "file": {"driver": "file", "filename": "TEST_DIR/PID-target"}}, "node-name": "target"}}
109
+{"return": {}}
110
+{"execute": "block-job-resume", "arguments": {"device": "drive0"}}
111
+{"return": {}}
112
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
113
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
114
--- a/tests/qemu-iotests/group
17
--- a/block/qed.c
115
+++ b/tests/qemu-iotests/group
18
+++ b/block/qed.c
116
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
117
245 rw auto
20
qemu_coroutine_enter(qemu_coroutine_create(bdrv_qed_open_entry, &qoc));
118
246 rw auto quick
21
BDRV_POLL_WHILE(bs, qoc.ret == -EINPROGRESS);
119
247 rw auto quick
22
}
120
+248 rw auto quick
23
- BDRV_POLL_WHILE(bs, qoc.ret == -EINPROGRESS);
24
return qoc.ret;
25
}
26
121
--
27
--
122
2.20.1
28
2.39.2
123
124
diff view generated by jsdifflib
Deleted patch
1
There is only a single caller of bdrv_make_zero(), which is qemu-img
2
convert. If the function fails, we just fall back to a different method
3
of zeroing out blocks on the target image. There is no good reason to
4
print error messages on stderr when the higher level operation will
5
actually succeed.
6
1
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Acked-by: Eric Blake <eblake@redhat.com>
9
---
10
block/io.c | 4 ----
11
1 file changed, 4 deletions(-)
12
13
diff --git a/block/io.c b/block/io.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/block/io.c
16
+++ b/block/io.c
17
@@ -XXX,XX +XXX,XX @@ int bdrv_make_zero(BdrvChild *child, BdrvRequestFlags flags)
18
}
19
ret = bdrv_block_status(bs, offset, bytes, &bytes, NULL, NULL);
20
if (ret < 0) {
21
- error_report("error getting block status at offset %" PRId64 ": %s",
22
- offset, strerror(-ret));
23
return ret;
24
}
25
if (ret & BDRV_BLOCK_ZERO) {
26
@@ -XXX,XX +XXX,XX @@ int bdrv_make_zero(BdrvChild *child, BdrvRequestFlags flags)
27
}
28
ret = bdrv_pwrite_zeroes(child, offset, bytes, flags);
29
if (ret < 0) {
30
- error_report("error writing zeroes at offset %" PRId64 ": %s",
31
- offset, strerror(-ret));
32
return ret;
33
}
34
offset += bytes;
35
--
36
2.20.1
37
38
diff view generated by jsdifflib
Deleted patch
1
For qemu-img convert, we want an operation that zeroes out the whole
2
image if this can be done efficiently, but that returns an error
3
otherwise so we don't write explicit zeroes and immediately overwrite
4
them with the real data, potentially doubling the amount of data to be
5
written.
6
1
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Acked-by: Eric Blake <eblake@redhat.com>
9
---
10
include/block/block.h | 7 ++++++-
11
block/io.c | 12 +++++++++++-
12
2 files changed, 17 insertions(+), 2 deletions(-)
13
14
diff --git a/include/block/block.h b/include/block/block.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/block/block.h
17
+++ b/include/block/block.h
18
@@ -XXX,XX +XXX,XX @@ typedef enum {
19
*/
20
BDRV_REQ_SERIALISING = 0x80,
21
22
+ /* Execute the request only if the operation can be offloaded or otherwise
23
+ * be executed efficiently, but return an error instead of using a slow
24
+ * fallback. */
25
+ BDRV_REQ_NO_FALLBACK = 0x100,
26
+
27
/* Mask of valid flags */
28
- BDRV_REQ_MASK = 0xff,
29
+ BDRV_REQ_MASK = 0x1ff,
30
} BdrvRequestFlags;
31
32
typedef struct BlockSizes {
33
diff --git a/block/io.c b/block/io.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/block/io.c
36
+++ b/block/io.c
37
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_driver_preadv(BlockDriverState *bs,
38
unsigned int nb_sectors;
39
40
assert(!(flags & ~BDRV_REQ_MASK));
41
+ assert(!(flags & BDRV_REQ_NO_FALLBACK));
42
43
if (!drv) {
44
return -ENOMEDIUM;
45
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_driver_pwritev(BlockDriverState *bs,
46
int ret;
47
48
assert(!(flags & ~BDRV_REQ_MASK));
49
+ assert(!(flags & BDRV_REQ_NO_FALLBACK));
50
51
if (!drv) {
52
return -ENOMEDIUM;
53
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
54
return -ENOMEDIUM;
55
}
56
57
+ if ((flags & ~bs->supported_zero_flags) & BDRV_REQ_NO_FALLBACK) {
58
+ return -ENOTSUP;
59
+ }
60
+
61
assert(alignment % bs->bl.request_alignment == 0);
62
head = offset % alignment;
63
tail = (offset + bytes) % alignment;
64
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
65
assert(!bs->supported_zero_flags);
66
}
67
68
- if (ret == -ENOTSUP) {
69
+ if (ret == -ENOTSUP && !(flags & BDRV_REQ_NO_FALLBACK)) {
70
/* Fall back to bounce buffer if write zeroes is unsupported */
71
BdrvRequestFlags write_flags = flags & ~BDRV_REQ_ZERO_WRITE;
72
73
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_copy_range_internal(
74
BdrvTrackedRequest req;
75
int ret;
76
77
+ /* TODO We can support BDRV_REQ_NO_FALLBACK here */
78
+ assert(!(read_flags & BDRV_REQ_NO_FALLBACK));
79
+ assert(!(write_flags & BDRV_REQ_NO_FALLBACK));
80
+
81
if (!dst || !dst->bs) {
82
return -ENOMEDIUM;
83
}
84
--
85
2.20.1
86
87
diff view generated by jsdifflib
Deleted patch
1
Filter drivers that support .bdrv_co_pwrite_zeroes can safely advertise
2
BDRV_REQ_NO_FALLBACK because they just forward the request flags to
3
their child node.
4
1
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Acked-by: Eric Blake <eblake@redhat.com>
7
---
8
block/blkdebug.c | 2 +-
9
block/copy-on-read.c | 7 +++----
10
block/mirror.c | 3 ++-
11
block/raw-format.c | 2 +-
12
4 files changed, 7 insertions(+), 7 deletions(-)
13
14
diff --git a/block/blkdebug.c b/block/blkdebug.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/block/blkdebug.c
17
+++ b/block/blkdebug.c
18
@@ -XXX,XX +XXX,XX @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
19
bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED |
20
(BDRV_REQ_FUA & bs->file->bs->supported_write_flags);
21
bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
22
- ((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP) &
23
+ ((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) &
24
bs->file->bs->supported_zero_flags);
25
ret = -EINVAL;
26
27
diff --git a/block/copy-on-read.c b/block/copy-on-read.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/block/copy-on-read.c
30
+++ b/block/copy-on-read.c
31
@@ -XXX,XX +XXX,XX @@ static int cor_open(BlockDriverState *bs, QDict *options, int flags,
32
}
33
34
bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED |
35
- (BDRV_REQ_FUA &
36
- bs->file->bs->supported_write_flags);
37
+ (BDRV_REQ_FUA & bs->file->bs->supported_write_flags);
38
39
bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
40
- ((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP) &
41
- bs->file->bs->supported_zero_flags);
42
+ ((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) &
43
+ bs->file->bs->supported_zero_flags);
44
45
return 0;
46
}
47
diff --git a/block/mirror.c b/block/mirror.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/block/mirror.c
50
+++ b/block/mirror.c
51
@@ -XXX,XX +XXX,XX @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
52
}
53
mirror_top_bs->total_sectors = bs->total_sectors;
54
mirror_top_bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED;
55
- mirror_top_bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED;
56
+ mirror_top_bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
57
+ BDRV_REQ_NO_FALLBACK;
58
bs_opaque = g_new0(MirrorBDSOpaque, 1);
59
mirror_top_bs->opaque = bs_opaque;
60
bdrv_set_aio_context(mirror_top_bs, bdrv_get_aio_context(bs));
61
diff --git a/block/raw-format.c b/block/raw-format.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/block/raw-format.c
64
+++ b/block/raw-format.c
65
@@ -XXX,XX +XXX,XX @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
66
bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED |
67
(BDRV_REQ_FUA & bs->file->bs->supported_write_flags);
68
bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
69
- ((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP) &
70
+ ((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) &
71
bs->file->bs->supported_zero_flags);
72
73
if (bs->probed && !bdrv_is_read_only(bs)) {
74
--
75
2.20.1
76
77
diff view generated by jsdifflib
Deleted patch
1
We know that the kernel implements a slow fallback code path for
2
BLKZEROOUT, so if BDRV_REQ_NO_FALLBACK is given, we shouldn't call it.
3
The other operations we call in the context of .bdrv_co_pwrite_zeroes
4
should usually be quick, so no modification should be needed for them.
5
If we ever notice that there are additional problematic cases, we can
6
still make these conditional as well.
7
1
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Acked-by: Eric Blake <eblake@redhat.com>
10
---
11
include/block/raw-aio.h | 1 +
12
block/file-posix.c | 24 ++++++++++++++++--------
13
2 files changed, 17 insertions(+), 8 deletions(-)
14
15
diff --git a/include/block/raw-aio.h b/include/block/raw-aio.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/block/raw-aio.h
18
+++ b/include/block/raw-aio.h
19
@@ -XXX,XX +XXX,XX @@
20
/* AIO flags */
21
#define QEMU_AIO_MISALIGNED 0x1000
22
#define QEMU_AIO_BLKDEV 0x2000
23
+#define QEMU_AIO_NO_FALLBACK 0x4000
24
25
26
/* linux-aio.c - Linux native implementation */
27
diff --git a/block/file-posix.c b/block/file-posix.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/block/file-posix.c
30
+++ b/block/file-posix.c
31
@@ -XXX,XX +XXX,XX @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
32
}
33
#endif
34
35
- bs->supported_zero_flags = BDRV_REQ_MAY_UNMAP;
36
+ bs->supported_zero_flags = BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK;
37
ret = 0;
38
fail:
39
if (filename && (bdrv_flags & BDRV_O_TEMPORARY)) {
40
@@ -XXX,XX +XXX,XX @@ static ssize_t handle_aiocb_write_zeroes_block(RawPosixAIOData *aiocb)
41
}
42
43
#ifdef BLKZEROOUT
44
- do {
45
- uint64_t range[2] = { aiocb->aio_offset, aiocb->aio_nbytes };
46
- if (ioctl(aiocb->aio_fildes, BLKZEROOUT, range) == 0) {
47
- return 0;
48
- }
49
- } while (errno == EINTR);
50
+ /* The BLKZEROOUT implementation in the kernel doesn't set
51
+ * BLKDEV_ZERO_NOFALLBACK, so we can't call this if we have to avoid slow
52
+ * fallbacks. */
53
+ if (!(aiocb->aio_type & QEMU_AIO_NO_FALLBACK)) {
54
+ do {
55
+ uint64_t range[2] = { aiocb->aio_offset, aiocb->aio_nbytes };
56
+ if (ioctl(aiocb->aio_fildes, BLKZEROOUT, range) == 0) {
57
+ return 0;
58
+ }
59
+ } while (errno == EINTR);
60
61
- ret = translate_err(-errno);
62
+ ret = translate_err(-errno);
63
+ }
64
#endif
65
66
if (ret == -ENOTSUP) {
67
@@ -XXX,XX +XXX,XX @@ raw_do_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int bytes,
68
if (blkdev) {
69
acb.aio_type |= QEMU_AIO_BLKDEV;
70
}
71
+ if (flags & BDRV_REQ_NO_FALLBACK) {
72
+ acb.aio_type |= QEMU_AIO_NO_FALLBACK;
73
+ }
74
75
if (flags & BDRV_REQ_MAY_UNMAP) {
76
acb.aio_type |= QEMU_AIO_DISCARD;
77
--
78
2.20.1
79
80
diff view generated by jsdifflib