1
The following changes since commit b34181056c04e05db6c632063012beaee7006a37:
1
The following changes since commit d8d5fefd8657d4f7b380b3a1533340434b5b9def:
2
2
3
Merge remote-tracking branch 'remotes/rth/tags/pull-sh4-20180709' into staging (2018-07-09 22:44:22 +0100)
3
Merge remote-tracking branch 'remotes/berrange/tags/qcrypto-next-pull-request' into staging (2018-12-13 18:45:18 +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
git://repo.or.cz/qemu/kevin.git tags/for-upstream
8
8
9
for you to fetch changes up to cd47d792d7a27a57f4b621e2ff1ed8f4e83de1e9:
9
for you to fetch changes up to 537c3d4f64297911a5b70a151926cd7851bbf752:
10
10
11
block: Use common write req handling in truncate (2018-07-10 16:46:22 +0200)
11
block/mirror: add missing coroutine_fn annotations (2018-12-14 11:55:02 +0100)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block layer patches:
14
Block layer patches:
15
15
16
- Copy offloading fixes for when the copy increases the image size
16
- qcow2: Decompression worker threads
17
- Temporary revert of the removal of deprecated -drive options
17
- dmg: lzfse compression support
18
- Fix request serialisation in the image fleecing scenario
18
- file-posix: Simplify delegation to worker thread
19
- Fix copy-on-read crash with unaligned image size
19
- Don't pass flags to bdrv_reopen_queue()
20
- Fix another drain crash
20
- iotests: make 235 work on s390 (and others)
21
21
22
----------------------------------------------------------------
22
----------------------------------------------------------------
23
Ari Sundholm (2):
23
Alberto Garcia (15):
24
qapi/block-core.json: Add missing documentation for blklogwrites log-append option
24
block: Add bdrv_reopen_set_read_only()
25
block/blklogwrites: Make sure the log sector size is not too small
25
block: Use bdrv_reopen_set_read_only() in bdrv_backing_update_filename()
26
block: Use bdrv_reopen_set_read_only() in commit_start/complete()
27
block: Use bdrv_reopen_set_read_only() in bdrv_commit()
28
block: Use bdrv_reopen_set_read_only() in stream_start/complete()
29
block: Use bdrv_reopen_set_read_only() in qmp_change_backing_file()
30
block: Use bdrv_reopen_set_read_only() in external_snapshot_commit()
31
block: Use bdrv_reopen_set_read_only() in the mirror driver
32
block: Drop bdrv_reopen()
33
qemu-io: Put flag changes in the options QDict in reopen_f()
34
block: Clean up reopen_backing_file() in block/replication.c
35
block: Remove flags parameter from bdrv_reopen_queue()
36
block: Stop passing flags to bdrv_reopen_queue_child()
37
block: Remove assertions from update_flags_from_options()
38
block: Assert that flags are up-to-date in bdrv_reopen_prepare()
26
39
27
Cornelia Huck (4):
40
Christian Borntraeger (1):
28
Revert "block: Remove dead deprecation warning code"
41
iotests: make 235 work on s390 (and others)
29
Revert "block: Remove deprecated -drive option serial"
30
Revert "block: Remove deprecated -drive option addr"
31
Revert "block: Remove deprecated -drive geometry options"
32
42
33
Fam Zheng (11):
43
Julio Faracco (4):
34
iotests: 222: Don't run with luks
44
block: adding lzfse decompressing support as a module.
35
block: Prefix file driver trace points with "file_"
45
configure: adding support to lzfse library.
36
block: Add copy offloading trace points
46
dmg: including dmg-lzfse module inside dmg block driver.
37
block: Use BdrvChild to discard
47
dmg: exchanging hardcoded dmg UDIF block types to enum.
38
block: Use uint64_t for BdrvTrackedRequest byte fields
39
block: Extract common write req handling
40
block: Fix handling of image enlarging write
41
block: Use common req handling for discard
42
block: Use common req handling in copy offloading
43
block: Fix bdrv_co_truncate overlap check
44
block: Use common write req handling in truncate
45
48
46
Kevin Wolf (3):
49
Kevin Wolf (12):
47
block: Poll after drain on attaching a node
50
file-posix: Reorganise RawPosixAIOData
48
test-bdrv-drain: Test bdrv_append() to drained node
51
file-posix: Factor out raw_thread_pool_submit()
49
block: Fix copy-on-read crash with partial final cluster
52
file-posix: Avoid aio_worker() for QEMU_AIO_TRUNCATE
53
file-posix: Avoid aio_worker() for QEMU_AIO_COPY_RANGE
54
file-posix: Avoid aio_worker() for QEMU_AIO_WRITE_ZEROES
55
file-posix: Avoid aio_worker() for QEMU_AIO_DISCARD
56
file-posix: Avoid aio_worker() for QEMU_AIO_FLUSH
57
file-posix: Move read/write operation logic out of aio_worker()
58
file-posix: Avoid aio_worker() for QEMU_AIO_READ/WRITE
59
file-posix: Remove paio_submit_co()
60
file-posix: Switch to .bdrv_co_ioctl
61
file-posix: Avoid aio_worker() for QEMU_AIO_IOCTL
50
62
51
Vladimir Sementsov-Ogievskiy (4):
63
Stefan Hajnoczi (1):
52
block/io: fix copy_range
64
block/mirror: add missing coroutine_fn annotations
53
block: split flags in copy_range
54
block: add BDRV_REQ_SERIALISING flag
55
block/backup: fix fleecing scheme: use serialized writes
56
65
57
qapi/block-core.json | 2 +
66
Vladimir Sementsov-Ogievskiy (9):
58
include/block/block.h | 41 +++++-
67
block/replication: drop extra synchronization
59
include/block/block_int.h | 21 ++-
68
block/backup: drop unused synchronization interface
60
include/hw/block/block.h | 1 +
69
qcow2: use Z_OK instead of 0 for deflateInit2 return code check
61
include/sysemu/block-backend.h | 3 +-
70
qcow2: make more generic interface for qcow2_compress
62
include/sysemu/blockdev.h | 3 +
71
qcow2: move decompression from qcow2-cluster.c to qcow2.c
63
block.c | 2 +-
72
qcow2: refactor decompress_buffer
64
block/backup.c | 20 ++-
73
qcow2: use byte-based read in qcow2_decompress_cluster
65
block/blkdebug.c | 2 +-
74
qcow2: aio support for compressed cluster read
66
block/blklogwrites.c | 7 +-
75
qcow2: do decompression in threads
67
block/blkreplay.c | 2 +-
68
block/block-backend.c | 8 +-
69
block/copy-on-read.c | 2 +-
70
block/file-posix.c | 25 ++--
71
block/file-win32.c | 2 +-
72
block/io.c | 318 ++++++++++++++++++++++++++++-------------
73
block/iscsi.c | 12 +-
74
block/mirror.c | 2 +-
75
block/qcow2-refcount.c | 2 +-
76
block/qcow2.c | 20 +--
77
block/raw-format.c | 26 ++--
78
block/throttle.c | 2 +-
79
blockdev.c | 110 ++++++++++++++
80
device-hotplug.c | 4 +
81
hw/block/block.c | 27 ++++
82
hw/block/nvme.c | 1 +
83
hw/block/virtio-blk.c | 1 +
84
hw/ide/qdev.c | 1 +
85
hw/scsi/scsi-disk.c | 1 +
86
hw/usb/dev-storage.c | 1 +
87
qemu-img.c | 2 +-
88
tests/ahci-test.c | 6 +-
89
tests/hd-geo-test.c | 37 ++++-
90
tests/ide-test.c | 8 +-
91
tests/test-bdrv-drain.c | 43 ++++++
92
block/trace-events | 10 +-
93
hmp-commands.hx | 1 +
94
qemu-doc.texi | 15 ++
95
qemu-options.hx | 14 +-
96
tests/qemu-iotests/197 | 9 ++
97
tests/qemu-iotests/197.out | 8 ++
98
tests/qemu-iotests/222 | 2 +
99
42 files changed, 647 insertions(+), 177 deletions(-)
100
76
77
configure | 31 ++++
78
block/dmg.h | 3 +
79
block/qcow2.h | 4 -
80
include/block/block.h | 6 +-
81
include/block/block_backup.h | 13 --
82
include/scsi/pr-manager.h | 8 +-
83
block.c | 89 +++++-----
84
block/backup.c | 38 +----
85
block/commit.c | 23 +--
86
block/dmg-lzfse.c | 49 ++++++
87
block/dmg.c | 65 ++++++--
88
block/file-posix.c | 382 ++++++++++++++++++++++---------------------
89
block/mirror.c | 38 +++--
90
block/qcow2-cluster.c | 70 --------
91
block/qcow2.c | 170 ++++++++++++++++---
92
block/replication.c | 67 +++-----
93
block/stream.c | 20 +--
94
blockdev.c | 11 +-
95
qemu-io-cmds.c | 29 +++-
96
scsi/pr-manager.c | 21 +--
97
block/Makefile.objs | 2 +
98
scsi/trace-events | 2 +-
99
tests/qemu-iotests/133 | 18 ++
100
tests/qemu-iotests/133.out | 15 ++
101
tests/qemu-iotests/235 | 4 +-
102
25 files changed, 671 insertions(+), 507 deletions(-)
103
create mode 100644 block/dmg-lzfse.c
104
diff view generated by jsdifflib
Deleted patch
1
Commit dcf94a23b1 ('block: Don't poll in parent drain callbacks')
2
removed polling in bdrv_child_cb_drained_begin() on the grounds that the
3
original bdrv_drain() already will poll and BdrvChildRole.drained_begin
4
calls must not cause graph changes (and therefore must not call
5
aio_poll() or the recursion through the graph will break.
6
1
7
This reasoning is correct for calls through bdrv_do_drained_begin().
8
However, BdrvChildRole.drained_begin is also called when a node that is
9
already in a drained section (i.e. bdrv_do_drained_begin() has already
10
returned and therefore can't poll any more) is attached to a new parent.
11
In this case, we must explicitly poll to have all requests completed
12
before the drained new child can be attached to the parent.
13
14
In bdrv_replace_child_noperm(), we know that we're not inside the
15
recursion of bdrv_do_drained_begin() because graph changes are not
16
allowed there, and bdrv_replace_child_noperm() is a graph change. The
17
call of BdrvChildRole.drained_begin() must therefore be followed by a
18
BDRV_POLL_WHILE() that waits for the completion of requests.
19
20
Reported-by: Max Reitz <mreitz@redhat.com>
21
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
22
---
23
include/block/block.h | 8 ++++++++
24
include/block/block_int.h | 3 +++
25
block.c | 2 +-
26
block/io.c | 26 ++++++++++++++++++++------
27
4 files changed, 32 insertions(+), 7 deletions(-)
28
29
diff --git a/include/block/block.h b/include/block/block.h
30
index XXXXXXX..XXXXXXX 100644
31
--- a/include/block/block.h
32
+++ b/include/block/block.h
33
@@ -XXX,XX +XXX,XX @@ void bdrv_parent_drained_begin(BlockDriverState *bs, BdrvChild *ignore,
34
bool ignore_bds_parents);
35
36
/**
37
+ * bdrv_parent_drained_begin_single:
38
+ *
39
+ * Begin a quiesced section for the parent of @c. If @poll is true, wait for
40
+ * any pending activity to cease.
41
+ */
42
+void bdrv_parent_drained_begin_single(BdrvChild *c, bool poll);
43
+
44
+/**
45
* bdrv_parent_drained_end:
46
*
47
* End a quiesced section of all users of @bs. This is part of
48
diff --git a/include/block/block_int.h b/include/block/block_int.h
49
index XXXXXXX..XXXXXXX 100644
50
--- a/include/block/block_int.h
51
+++ b/include/block/block_int.h
52
@@ -XXX,XX +XXX,XX @@ struct BdrvChildRole {
53
* requests after returning from .drained_begin() until .drained_end() is
54
* called.
55
*
56
+ * These functions must not change the graph (and therefore also must not
57
+ * call aio_poll(), which could change the graph indirectly).
58
+ *
59
* Note that this can be nested. If drained_begin() was called twice, new
60
* I/O is allowed only after drained_end() was called twice, too.
61
*/
62
diff --git a/block.c b/block.c
63
index XXXXXXX..XXXXXXX 100644
64
--- a/block.c
65
+++ b/block.c
66
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child_noperm(BdrvChild *child,
67
}
68
assert(num >= 0);
69
for (i = 0; i < num; i++) {
70
- child->role->drained_begin(child);
71
+ bdrv_parent_drained_begin_single(child, true);
72
}
73
}
74
75
diff --git a/block/io.c b/block/io.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/block/io.c
78
+++ b/block/io.c
79
@@ -XXX,XX +XXX,XX @@ void bdrv_parent_drained_begin(BlockDriverState *bs, BdrvChild *ignore,
80
if (c == ignore || (ignore_bds_parents && c->role->parent_is_bds)) {
81
continue;
82
}
83
- if (c->role->drained_begin) {
84
- c->role->drained_begin(c);
85
- }
86
+ bdrv_parent_drained_begin_single(c, false);
87
}
88
}
89
90
@@ -XXX,XX +XXX,XX @@ void bdrv_parent_drained_end(BlockDriverState *bs, BdrvChild *ignore,
91
}
92
}
93
94
+static bool bdrv_parent_drained_poll_single(BdrvChild *c)
95
+{
96
+ if (c->role->drained_poll) {
97
+ return c->role->drained_poll(c);
98
+ }
99
+ return false;
100
+}
101
+
102
static bool bdrv_parent_drained_poll(BlockDriverState *bs, BdrvChild *ignore,
103
bool ignore_bds_parents)
104
{
105
@@ -XXX,XX +XXX,XX @@ static bool bdrv_parent_drained_poll(BlockDriverState *bs, BdrvChild *ignore,
106
if (c == ignore || (ignore_bds_parents && c->role->parent_is_bds)) {
107
continue;
108
}
109
- if (c->role->drained_poll) {
110
- busy |= c->role->drained_poll(c);
111
- }
112
+ busy |= bdrv_parent_drained_poll_single(c);
113
}
114
115
return busy;
116
}
117
118
+void bdrv_parent_drained_begin_single(BdrvChild *c, bool poll)
119
+{
120
+ if (c->role->drained_begin) {
121
+ c->role->drained_begin(c);
122
+ }
123
+ if (poll) {
124
+ BDRV_POLL_WHILE(c->bs, bdrv_parent_drained_poll_single(c));
125
+ }
126
+}
127
+
128
static void bdrv_merge_limits(BlockLimits *dst, const BlockLimits *src)
129
{
130
dst->opt_transfer = MAX(dst->opt_transfer, src->opt_transfer);
131
--
132
2.13.6
133
134
diff view generated by jsdifflib
Deleted patch
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2
---
3
tests/test-bdrv-drain.c | 43 +++++++++++++++++++++++++++++++++++++++++++
4
1 file changed, 43 insertions(+)
5
1
6
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
7
index XXXXXXX..XXXXXXX 100644
8
--- a/tests/test-bdrv-drain.c
9
+++ b/tests/test-bdrv-drain.c
10
@@ -XXX,XX +XXX,XX @@ static void test_detach_by_driver_cb(void)
11
test_detach_indirect(false);
12
}
13
14
+static void test_append_to_drained(void)
15
+{
16
+ BlockBackend *blk;
17
+ BlockDriverState *base, *overlay;
18
+ BDRVTestState *base_s, *overlay_s;
19
+
20
+ blk = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
21
+ base = bdrv_new_open_driver(&bdrv_test, "base", BDRV_O_RDWR, &error_abort);
22
+ base_s = base->opaque;
23
+ blk_insert_bs(blk, base, &error_abort);
24
+
25
+ overlay = bdrv_new_open_driver(&bdrv_test, "overlay", BDRV_O_RDWR,
26
+ &error_abort);
27
+ overlay_s = overlay->opaque;
28
+
29
+ do_drain_begin(BDRV_DRAIN, base);
30
+ g_assert_cmpint(base->quiesce_counter, ==, 1);
31
+ g_assert_cmpint(base_s->drain_count, ==, 1);
32
+ g_assert_cmpint(base->in_flight, ==, 0);
33
+
34
+ /* Takes ownership of overlay, so we don't have to unref it later */
35
+ bdrv_append(overlay, base, &error_abort);
36
+ g_assert_cmpint(base->in_flight, ==, 0);
37
+ g_assert_cmpint(overlay->in_flight, ==, 0);
38
+
39
+ g_assert_cmpint(base->quiesce_counter, ==, 1);
40
+ g_assert_cmpint(base_s->drain_count, ==, 1);
41
+ g_assert_cmpint(overlay->quiesce_counter, ==, 1);
42
+ g_assert_cmpint(overlay_s->drain_count, ==, 1);
43
+
44
+ do_drain_end(BDRV_DRAIN, base);
45
+
46
+ g_assert_cmpint(base->quiesce_counter, ==, 0);
47
+ g_assert_cmpint(base_s->drain_count, ==, 0);
48
+ g_assert_cmpint(overlay->quiesce_counter, ==, 0);
49
+ g_assert_cmpint(overlay_s->drain_count, ==, 0);
50
+
51
+ bdrv_unref(base);
52
+ blk_unref(blk);
53
+}
54
+
55
int main(int argc, char **argv)
56
{
57
int ret;
58
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
59
g_test_add_func("/bdrv-drain/detach/parent_cb", test_detach_by_parent_cb);
60
g_test_add_func("/bdrv-drain/detach/driver_cb", test_detach_by_driver_cb);
61
62
+ g_test_add_func("/bdrv-drain/attach/drain", test_append_to_drained);
63
+
64
ret = g_test_run();
65
qemu_event_destroy(&done_event);
66
return ret;
67
--
68
2.13.6
69
70
diff view generated by jsdifflib
Deleted patch
1
If the virtual disk size isn't aligned to full clusters,
2
bdrv_co_do_copy_on_readv() may get pnum == 0 before having the full
3
cluster completed, which will let it run into an assertion failure:
4
1
5
qemu-io: block/io.c:1203: bdrv_co_do_copy_on_readv: Assertion `skip_bytes < pnum' failed.
6
7
Check for EOF, assert that we read at least as much as the read request
8
originally wanted to have (which is true at EOF because otherwise
9
bdrv_check_byte_request() would already have returned an error) and
10
return success early even though we couldn't copy the full cluster.
11
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
14
block/io.c | 6 ++++++
15
tests/qemu-iotests/197 | 9 +++++++++
16
tests/qemu-iotests/197.out | 8 ++++++++
17
3 files changed, 23 insertions(+)
18
19
diff --git a/block/io.c b/block/io.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/block/io.c
22
+++ b/block/io.c
23
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child,
24
pnum = MIN(cluster_bytes, max_transfer);
25
}
26
27
+ /* Stop at EOF if the image ends in the middle of the cluster */
28
+ if (ret == 0 && pnum == 0) {
29
+ assert(progress >= bytes);
30
+ break;
31
+ }
32
+
33
assert(skip_bytes < pnum);
34
35
if (ret <= 0) {
36
diff --git a/tests/qemu-iotests/197 b/tests/qemu-iotests/197
37
index XXXXXXX..XXXXXXX 100755
38
--- a/tests/qemu-iotests/197
39
+++ b/tests/qemu-iotests/197
40
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -f qcow2 -c map "$TEST_WRAP"
41
_check_test_img
42
$QEMU_IMG compare -f $IMGFMT -F qcow2 "$TEST_IMG" "$TEST_WRAP"
43
44
+echo
45
+echo '=== Partial final cluster ==='
46
+echo
47
+
48
+_make_test_img 1024
49
+$QEMU_IO -f $IMGFMT -C -c 'read 0 1024' "$TEST_IMG" | _filter_qemu_io
50
+$QEMU_IO -f $IMGFMT -c map "$TEST_IMG"
51
+_check_test_img
52
+
53
# success, all done
54
echo '*** done'
55
status=0
56
diff --git a/tests/qemu-iotests/197.out b/tests/qemu-iotests/197.out
57
index XXXXXXX..XXXXXXX 100644
58
--- a/tests/qemu-iotests/197.out
59
+++ b/tests/qemu-iotests/197.out
60
@@ -XXX,XX +XXX,XX @@ can't open device TEST_DIR/t.wrap.qcow2: Can't use copy-on-read on read-only dev
61
1023.938 MiB (0x3fff0000) bytes not allocated at offset 3 GiB (0xc0010000)
62
No errors were found on the image.
63
Images are identical.
64
+
65
+=== Partial final cluster ===
66
+
67
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1024
68
+read 1024/1024 bytes at offset 0
69
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
70
+1 KiB (0x400) bytes allocated at offset 0 bytes (0x0)
71
+No errors were found on the image.
72
*** done
73
--
74
2.13.6
75
76
diff view generated by jsdifflib
Deleted patch
1
From: Fam Zheng <famz@redhat.com>
2
1
3
Luks needs special parameters to operate the image. Since this test is
4
focusing on image fleecing, skip skip that format.
5
6
Signed-off-by: Fam Zheng <famz@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
9
tests/qemu-iotests/222 | 2 ++
10
1 file changed, 2 insertions(+)
11
12
diff --git a/tests/qemu-iotests/222 b/tests/qemu-iotests/222
13
index XXXXXXX..XXXXXXX 100644
14
--- a/tests/qemu-iotests/222
15
+++ b/tests/qemu-iotests/222
16
@@ -XXX,XX +XXX,XX @@ import iotests
17
from iotests import log, qemu_img, qemu_io, qemu_io_silent
18
19
iotests.verify_platform(['linux'])
20
+iotests.verify_image_format(supported_fmts=['qcow2', 'qcow', 'qed', 'vmdk',
21
+ 'vhdx', 'raw'])
22
23
patterns = [("0x5d", "0", "64k"),
24
("0xd5", "1M", "64k"),
25
--
26
2.13.6
27
28
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Here two things are fixed:
4
5
1. Architecture
6
7
On each recursion step, we go to the child of src or dst, only for one
8
of them. So, it's wrong to create tracked requests for both on each
9
step. It leads to tracked requests duplication.
10
11
2. Wait for serializing requests on write path independently of
12
BDRV_REQ_NO_SERIALISING
13
14
Before commit 9ded4a01149 "backup: Use copy offloading",
15
BDRV_REQ_NO_SERIALISING was used for only one case: read in
16
copy-on-write operation during backup. Also, the flag was handled only
17
on read path (in bdrv_co_preadv and bdrv_aligned_preadv).
18
19
After 9ded4a01149, flag is used for not waiting serializing operations
20
on backup target (in same case of copy-on-write operation). This
21
behavior change is unsubstantiated and potentially dangerous, let's
22
drop it and add additional asserts and documentation.
23
24
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
25
Reviewed-by: Fam Zheng <famz@redhat.com>
26
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
27
---
28
include/block/block.h | 12 ++++++++++++
29
block/io.c | 42 +++++++++++++++++++++++++++---------------
30
2 files changed, 39 insertions(+), 15 deletions(-)
31
32
diff --git a/include/block/block.h b/include/block/block.h
33
index XXXXXXX..XXXXXXX 100644
34
--- a/include/block/block.h
35
+++ b/include/block/block.h
36
@@ -XXX,XX +XXX,XX @@ typedef enum {
37
* opened with BDRV_O_UNMAP.
38
*/
39
BDRV_REQ_MAY_UNMAP = 0x4,
40
+
41
+ /*
42
+ * The BDRV_REQ_NO_SERIALISING flag is only valid for reads and means that
43
+ * we don't want wait_serialising_requests() during the read operation.
44
+ *
45
+ * This flag is used for backup copy-on-write operations, when we need to
46
+ * read old data before write (write notifier triggered). It is okay since
47
+ * we already waited for other serializing requests in the initiating write
48
+ * (see bdrv_aligned_pwritev), and it is necessary if the initiating write
49
+ * is already serializing (without the flag, the read would deadlock
50
+ * waiting for the serialising write to complete).
51
+ */
52
BDRV_REQ_NO_SERIALISING = 0x8,
53
BDRV_REQ_FUA = 0x10,
54
BDRV_REQ_WRITE_COMPRESSED = 0x20,
55
diff --git a/block/io.c b/block/io.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/block/io.c
58
+++ b/block/io.c
59
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child,
60
max_transfer = QEMU_ALIGN_DOWN(MIN_NON_ZERO(bs->bl.max_transfer, INT_MAX),
61
align);
62
63
+ /* BDRV_REQ_NO_SERIALISING is only for read operation */
64
+ assert(!(flags & BDRV_REQ_NO_SERIALISING));
65
waited = wait_serialising_requests(req);
66
assert(!waited || !req->serialising);
67
assert(req->overlap_offset <= offset);
68
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_copy_range_internal(BdrvChild *src,
69
BdrvRequestFlags flags,
70
bool recurse_src)
71
{
72
- BdrvTrackedRequest src_req, dst_req;
73
+ BdrvTrackedRequest req;
74
int ret;
75
76
if (!dst || !dst->bs) {
77
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_copy_range_internal(BdrvChild *src,
78
|| src->bs->encrypted || dst->bs->encrypted) {
79
return -ENOTSUP;
80
}
81
- bdrv_inc_in_flight(src->bs);
82
- bdrv_inc_in_flight(dst->bs);
83
- tracked_request_begin(&src_req, src->bs, src_offset,
84
- bytes, BDRV_TRACKED_READ);
85
- tracked_request_begin(&dst_req, dst->bs, dst_offset,
86
- bytes, BDRV_TRACKED_WRITE);
87
88
- if (!(flags & BDRV_REQ_NO_SERIALISING)) {
89
- wait_serialising_requests(&src_req);
90
- wait_serialising_requests(&dst_req);
91
- }
92
if (recurse_src) {
93
+ bdrv_inc_in_flight(src->bs);
94
+ tracked_request_begin(&req, src->bs, src_offset, bytes,
95
+ BDRV_TRACKED_READ);
96
+
97
+ if (!(flags & BDRV_REQ_NO_SERIALISING)) {
98
+ wait_serialising_requests(&req);
99
+ }
100
+
101
ret = src->bs->drv->bdrv_co_copy_range_from(src->bs,
102
src, src_offset,
103
dst, dst_offset,
104
bytes, flags);
105
+
106
+ tracked_request_end(&req);
107
+ bdrv_dec_in_flight(src->bs);
108
} else {
109
+ bdrv_inc_in_flight(dst->bs);
110
+ tracked_request_begin(&req, dst->bs, dst_offset, bytes,
111
+ BDRV_TRACKED_WRITE);
112
+
113
+ /* BDRV_REQ_NO_SERIALISING is only for read operation,
114
+ * so we ignore it in flags.
115
+ */
116
+ wait_serialising_requests(&req);
117
+
118
ret = dst->bs->drv->bdrv_co_copy_range_to(dst->bs,
119
src, src_offset,
120
dst, dst_offset,
121
bytes, flags);
122
+
123
+ tracked_request_end(&req);
124
+ bdrv_dec_in_flight(dst->bs);
125
}
126
- tracked_request_end(&src_req);
127
- tracked_request_end(&dst_req);
128
- bdrv_dec_in_flight(src->bs);
129
- bdrv_dec_in_flight(dst->bs);
130
+
131
return ret;
132
}
133
134
--
135
2.13.6
136
137
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Pass read flags and write flags separately. This is needed to handle
4
coming BDRV_REQ_NO_SERIALISING clearly in following patches.
5
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Reviewed-by: Fam Zheng <famz@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
10
include/block/block.h | 3 ++-
11
include/block/block_int.h | 14 +++++++++----
12
include/sysemu/block-backend.h | 3 ++-
13
block/backup.c | 2 +-
14
block/block-backend.c | 5 +++--
15
block/file-posix.c | 21 +++++++++++--------
16
block/io.c | 46 +++++++++++++++++++++++-------------------
17
block/iscsi.c | 9 ++++++---
18
block/qcow2.c | 20 +++++++++---------
19
block/raw-format.c | 24 ++++++++++++++--------
20
qemu-img.c | 2 +-
21
11 files changed, 90 insertions(+), 59 deletions(-)
22
23
diff --git a/include/block/block.h b/include/block/block.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/include/block/block.h
26
+++ b/include/block/block.h
27
@@ -XXX,XX +XXX,XX @@ void bdrv_unregister_buf(BlockDriverState *bs, void *host);
28
**/
29
int coroutine_fn bdrv_co_copy_range(BdrvChild *src, uint64_t src_offset,
30
BdrvChild *dst, uint64_t dst_offset,
31
- uint64_t bytes, BdrvRequestFlags flags);
32
+ uint64_t bytes, BdrvRequestFlags read_flags,
33
+ BdrvRequestFlags write_flags);
34
#endif
35
diff --git a/include/block/block_int.h b/include/block/block_int.h
36
index XXXXXXX..XXXXXXX 100644
37
--- a/include/block/block_int.h
38
+++ b/include/block/block_int.h
39
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
40
BdrvChild *dst,
41
uint64_t dst_offset,
42
uint64_t bytes,
43
- BdrvRequestFlags flags);
44
+ BdrvRequestFlags read_flags,
45
+ BdrvRequestFlags write_flags);
46
47
/* Map [offset, offset + nbytes) range onto a child of bs to copy data to,
48
* and invoke bdrv_co_copy_range_to(child, src, ...), or perform the copy
49
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
50
BdrvChild *dst,
51
uint64_t dst_offset,
52
uint64_t bytes,
53
- BdrvRequestFlags flags);
54
+ BdrvRequestFlags read_flags,
55
+ BdrvRequestFlags write_flags);
56
57
/*
58
* Building block for bdrv_block_status[_above] and
59
@@ -XXX,XX +XXX,XX @@ void blockdev_close_all_bdrv_states(void);
60
61
int coroutine_fn bdrv_co_copy_range_from(BdrvChild *src, uint64_t src_offset,
62
BdrvChild *dst, uint64_t dst_offset,
63
- uint64_t bytes, BdrvRequestFlags flags);
64
+ uint64_t bytes,
65
+ BdrvRequestFlags read_flags,
66
+ BdrvRequestFlags write_flags);
67
int coroutine_fn bdrv_co_copy_range_to(BdrvChild *src, uint64_t src_offset,
68
BdrvChild *dst, uint64_t dst_offset,
69
- uint64_t bytes, BdrvRequestFlags flags);
70
+ uint64_t bytes,
71
+ BdrvRequestFlags read_flags,
72
+ BdrvRequestFlags write_flags);
73
74
int refresh_total_sectors(BlockDriverState *bs, int64_t hint);
75
76
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
77
index XXXXXXX..XXXXXXX 100644
78
--- a/include/sysemu/block-backend.h
79
+++ b/include/sysemu/block-backend.h
80
@@ -XXX,XX +XXX,XX @@ void blk_unregister_buf(BlockBackend *blk, void *host);
81
82
int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in,
83
BlockBackend *blk_out, int64_t off_out,
84
- int bytes, BdrvRequestFlags flags);
85
+ int bytes, BdrvRequestFlags read_flags,
86
+ BdrvRequestFlags write_flags);
87
88
#endif
89
diff --git a/block/backup.c b/block/backup.c
90
index XXXXXXX..XXXXXXX 100644
91
--- a/block/backup.c
92
+++ b/block/backup.c
93
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_cow_with_offload(BackupBlockJob *job,
94
hbitmap_reset(job->copy_bitmap, start / job->cluster_size,
95
nr_clusters);
96
ret = blk_co_copy_range(blk, start, job->target, start, nbytes,
97
- is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0);
98
+ is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0, 0);
99
if (ret < 0) {
100
trace_backup_do_cow_copy_range_fail(job, start, ret);
101
hbitmap_set(job->copy_bitmap, start / job->cluster_size,
102
diff --git a/block/block-backend.c b/block/block-backend.c
103
index XXXXXXX..XXXXXXX 100644
104
--- a/block/block-backend.c
105
+++ b/block/block-backend.c
106
@@ -XXX,XX +XXX,XX @@ void blk_unregister_buf(BlockBackend *blk, void *host)
107
108
int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in,
109
BlockBackend *blk_out, int64_t off_out,
110
- int bytes, BdrvRequestFlags flags)
111
+ int bytes, BdrvRequestFlags read_flags,
112
+ BdrvRequestFlags write_flags)
113
{
114
int r;
115
r = blk_check_byte_request(blk_in, off_in, bytes);
116
@@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in,
117
}
118
return bdrv_co_copy_range(blk_in->root, off_in,
119
blk_out->root, off_out,
120
- bytes, flags);
121
+ bytes, read_flags, write_flags);
122
}
123
diff --git a/block/file-posix.c b/block/file-posix.c
124
index XXXXXXX..XXXXXXX 100644
125
--- a/block/file-posix.c
126
+++ b/block/file-posix.c
127
@@ -XXX,XX +XXX,XX @@ static void raw_abort_perm_update(BlockDriverState *bs)
128
raw_handle_perm_lock(bs, RAW_PL_ABORT, 0, 0, NULL);
129
}
130
131
-static int coroutine_fn raw_co_copy_range_from(BlockDriverState *bs,
132
- BdrvChild *src, uint64_t src_offset,
133
- BdrvChild *dst, uint64_t dst_offset,
134
- uint64_t bytes, BdrvRequestFlags flags)
135
+static int coroutine_fn raw_co_copy_range_from(
136
+ BlockDriverState *bs, BdrvChild *src, uint64_t src_offset,
137
+ BdrvChild *dst, uint64_t dst_offset, uint64_t bytes,
138
+ BdrvRequestFlags read_flags, BdrvRequestFlags write_flags)
139
{
140
- return bdrv_co_copy_range_to(src, src_offset, dst, dst_offset, bytes, flags);
141
+ return bdrv_co_copy_range_to(src, src_offset, dst, dst_offset, bytes,
142
+ read_flags, write_flags);
143
}
144
145
static int coroutine_fn raw_co_copy_range_to(BlockDriverState *bs,
146
- BdrvChild *src, uint64_t src_offset,
147
- BdrvChild *dst, uint64_t dst_offset,
148
- uint64_t bytes, BdrvRequestFlags flags)
149
+ BdrvChild *src,
150
+ uint64_t src_offset,
151
+ BdrvChild *dst,
152
+ uint64_t dst_offset,
153
+ uint64_t bytes,
154
+ BdrvRequestFlags read_flags,
155
+ BdrvRequestFlags write_flags)
156
{
157
BDRVRawState *s = bs->opaque;
158
BDRVRawState *src_s;
159
diff --git a/block/io.c b/block/io.c
160
index XXXXXXX..XXXXXXX 100644
161
--- a/block/io.c
162
+++ b/block/io.c
163
@@ -XXX,XX +XXX,XX @@ void bdrv_unregister_buf(BlockDriverState *bs, void *host)
164
}
165
}
166
167
-static int coroutine_fn bdrv_co_copy_range_internal(BdrvChild *src,
168
- uint64_t src_offset,
169
- BdrvChild *dst,
170
- uint64_t dst_offset,
171
- uint64_t bytes,
172
- BdrvRequestFlags flags,
173
- bool recurse_src)
174
+static int coroutine_fn bdrv_co_copy_range_internal(
175
+ BdrvChild *src, uint64_t src_offset, BdrvChild *dst,
176
+ uint64_t dst_offset, uint64_t bytes,
177
+ BdrvRequestFlags read_flags, BdrvRequestFlags write_flags,
178
+ bool recurse_src)
179
{
180
BdrvTrackedRequest req;
181
int ret;
182
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_copy_range_internal(BdrvChild *src,
183
if (ret) {
184
return ret;
185
}
186
- if (flags & BDRV_REQ_ZERO_WRITE) {
187
- return bdrv_co_pwrite_zeroes(dst, dst_offset, bytes, flags);
188
+ if (write_flags & BDRV_REQ_ZERO_WRITE) {
189
+ return bdrv_co_pwrite_zeroes(dst, dst_offset, bytes, write_flags);
190
}
191
192
if (!src || !src->bs) {
193
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_copy_range_internal(BdrvChild *src,
194
tracked_request_begin(&req, src->bs, src_offset, bytes,
195
BDRV_TRACKED_READ);
196
197
- if (!(flags & BDRV_REQ_NO_SERIALISING)) {
198
+ if (!(read_flags & BDRV_REQ_NO_SERIALISING)) {
199
wait_serialising_requests(&req);
200
}
201
202
ret = src->bs->drv->bdrv_co_copy_range_from(src->bs,
203
src, src_offset,
204
dst, dst_offset,
205
- bytes, flags);
206
+ bytes,
207
+ read_flags, write_flags);
208
209
tracked_request_end(&req);
210
bdrv_dec_in_flight(src->bs);
211
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_copy_range_internal(BdrvChild *src,
212
tracked_request_begin(&req, dst->bs, dst_offset, bytes,
213
BDRV_TRACKED_WRITE);
214
215
- /* BDRV_REQ_NO_SERIALISING is only for read operation,
216
- * so we ignore it in flags.
217
- */
218
+ /* BDRV_REQ_NO_SERIALISING is only for read operation */
219
+ assert(!(write_flags & BDRV_REQ_NO_SERIALISING));
220
wait_serialising_requests(&req);
221
222
ret = dst->bs->drv->bdrv_co_copy_range_to(dst->bs,
223
src, src_offset,
224
dst, dst_offset,
225
- bytes, flags);
226
+ bytes,
227
+ read_flags, write_flags);
228
229
tracked_request_end(&req);
230
bdrv_dec_in_flight(dst->bs);
231
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_copy_range_internal(BdrvChild *src,
232
* semantics. */
233
int coroutine_fn bdrv_co_copy_range_from(BdrvChild *src, uint64_t src_offset,
234
BdrvChild *dst, uint64_t dst_offset,
235
- uint64_t bytes, BdrvRequestFlags flags)
236
+ uint64_t bytes,
237
+ BdrvRequestFlags read_flags,
238
+ BdrvRequestFlags write_flags)
239
{
240
return bdrv_co_copy_range_internal(src, src_offset, dst, dst_offset,
241
- bytes, flags, true);
242
+ bytes, read_flags, write_flags, true);
243
}
244
245
/* Copy range from @src to @dst.
246
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_copy_range_from(BdrvChild *src, uint64_t src_offset,
247
* semantics. */
248
int coroutine_fn bdrv_co_copy_range_to(BdrvChild *src, uint64_t src_offset,
249
BdrvChild *dst, uint64_t dst_offset,
250
- uint64_t bytes, BdrvRequestFlags flags)
251
+ uint64_t bytes,
252
+ BdrvRequestFlags read_flags,
253
+ BdrvRequestFlags write_flags)
254
{
255
return bdrv_co_copy_range_internal(src, src_offset, dst, dst_offset,
256
- bytes, flags, false);
257
+ bytes, read_flags, write_flags, false);
258
}
259
260
int coroutine_fn bdrv_co_copy_range(BdrvChild *src, uint64_t src_offset,
261
BdrvChild *dst, uint64_t dst_offset,
262
- uint64_t bytes, BdrvRequestFlags flags)
263
+ uint64_t bytes, BdrvRequestFlags read_flags,
264
+ BdrvRequestFlags write_flags)
265
{
266
return bdrv_co_copy_range_from(src, src_offset,
267
dst, dst_offset,
268
- bytes, flags);
269
+ bytes, read_flags, write_flags);
270
}
271
272
static void bdrv_parent_cb_resize(BlockDriverState *bs)
273
diff --git a/block/iscsi.c b/block/iscsi.c
274
index XXXXXXX..XXXXXXX 100644
275
--- a/block/iscsi.c
276
+++ b/block/iscsi.c
277
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn iscsi_co_copy_range_from(BlockDriverState *bs,
278
BdrvChild *dst,
279
uint64_t dst_offset,
280
uint64_t bytes,
281
- BdrvRequestFlags flags)
282
+ BdrvRequestFlags read_flags,
283
+ BdrvRequestFlags write_flags)
284
{
285
- return bdrv_co_copy_range_to(src, src_offset, dst, dst_offset, bytes, flags);
286
+ return bdrv_co_copy_range_to(src, src_offset, dst, dst_offset, bytes,
287
+ read_flags, write_flags);
288
}
289
290
static struct scsi_task *iscsi_xcopy_task(int param_len)
291
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn iscsi_co_copy_range_to(BlockDriverState *bs,
292
BdrvChild *dst,
293
uint64_t dst_offset,
294
uint64_t bytes,
295
- BdrvRequestFlags flags)
296
+ BdrvRequestFlags read_flags,
297
+ BdrvRequestFlags write_flags)
298
{
299
IscsiLun *dst_lun = dst->bs->opaque;
300
IscsiLun *src_lun;
301
diff --git a/block/qcow2.c b/block/qcow2.c
302
index XXXXXXX..XXXXXXX 100644
303
--- a/block/qcow2.c
304
+++ b/block/qcow2.c
305
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn
306
qcow2_co_copy_range_from(BlockDriverState *bs,
307
BdrvChild *src, uint64_t src_offset,
308
BdrvChild *dst, uint64_t dst_offset,
309
- uint64_t bytes, BdrvRequestFlags flags)
310
+ uint64_t bytes, BdrvRequestFlags read_flags,
311
+ BdrvRequestFlags write_flags)
312
{
313
BDRVQcow2State *s = bs->opaque;
314
int ret;
315
unsigned int cur_bytes; /* number of bytes in current iteration */
316
BdrvChild *child = NULL;
317
- BdrvRequestFlags cur_flags;
318
+ BdrvRequestFlags cur_write_flags;
319
320
assert(!bs->encrypted);
321
qemu_co_mutex_lock(&s->lock);
322
@@ -XXX,XX +XXX,XX @@ qcow2_co_copy_range_from(BlockDriverState *bs,
323
uint64_t copy_offset = 0;
324
/* prepare next request */
325
cur_bytes = MIN(bytes, INT_MAX);
326
- cur_flags = flags;
327
+ cur_write_flags = write_flags;
328
329
ret = qcow2_get_cluster_offset(bs, src_offset, &cur_bytes, &copy_offset);
330
if (ret < 0) {
331
@@ -XXX,XX +XXX,XX @@ qcow2_co_copy_range_from(BlockDriverState *bs,
332
if (bs->backing && bs->backing->bs) {
333
int64_t backing_length = bdrv_getlength(bs->backing->bs);
334
if (src_offset >= backing_length) {
335
- cur_flags |= BDRV_REQ_ZERO_WRITE;
336
+ cur_write_flags |= BDRV_REQ_ZERO_WRITE;
337
} else {
338
child = bs->backing;
339
cur_bytes = MIN(cur_bytes, backing_length - src_offset);
340
copy_offset = src_offset;
341
}
342
} else {
343
- cur_flags |= BDRV_REQ_ZERO_WRITE;
344
+ cur_write_flags |= BDRV_REQ_ZERO_WRITE;
345
}
346
break;
347
348
case QCOW2_CLUSTER_ZERO_PLAIN:
349
case QCOW2_CLUSTER_ZERO_ALLOC:
350
- cur_flags |= BDRV_REQ_ZERO_WRITE;
351
+ cur_write_flags |= BDRV_REQ_ZERO_WRITE;
352
break;
353
354
case QCOW2_CLUSTER_COMPRESSED:
355
@@ -XXX,XX +XXX,XX @@ qcow2_co_copy_range_from(BlockDriverState *bs,
356
ret = bdrv_co_copy_range_from(child,
357
copy_offset,
358
dst, dst_offset,
359
- cur_bytes, cur_flags);
360
+ cur_bytes, read_flags, cur_write_flags);
361
qemu_co_mutex_lock(&s->lock);
362
if (ret < 0) {
363
goto out;
364
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn
365
qcow2_co_copy_range_to(BlockDriverState *bs,
366
BdrvChild *src, uint64_t src_offset,
367
BdrvChild *dst, uint64_t dst_offset,
368
- uint64_t bytes, BdrvRequestFlags flags)
369
+ uint64_t bytes, BdrvRequestFlags read_flags,
370
+ BdrvRequestFlags write_flags)
371
{
372
BDRVQcow2State *s = bs->opaque;
373
int offset_in_cluster;
374
@@ -XXX,XX +XXX,XX @@ qcow2_co_copy_range_to(BlockDriverState *bs,
375
ret = bdrv_co_copy_range_to(src, src_offset,
376
bs->file,
377
cluster_offset + offset_in_cluster,
378
- cur_bytes, flags);
379
+ cur_bytes, read_flags, write_flags);
380
qemu_co_mutex_lock(&s->lock);
381
if (ret < 0) {
382
goto fail;
383
diff --git a/block/raw-format.c b/block/raw-format.c
384
index XXXXXXX..XXXXXXX 100644
385
--- a/block/raw-format.c
386
+++ b/block/raw-format.c
387
@@ -XXX,XX +XXX,XX @@ static int raw_probe_geometry(BlockDriverState *bs, HDGeometry *geo)
388
}
389
390
static int coroutine_fn raw_co_copy_range_from(BlockDriverState *bs,
391
- BdrvChild *src, uint64_t src_offset,
392
- BdrvChild *dst, uint64_t dst_offset,
393
- uint64_t bytes, BdrvRequestFlags flags)
394
+ BdrvChild *src,
395
+ uint64_t src_offset,
396
+ BdrvChild *dst,
397
+ uint64_t dst_offset,
398
+ uint64_t bytes,
399
+ BdrvRequestFlags read_flags,
400
+ BdrvRequestFlags write_flags)
401
{
402
int ret;
403
404
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_copy_range_from(BlockDriverState *bs,
405
return ret;
406
}
407
return bdrv_co_copy_range_from(bs->file, src_offset, dst, dst_offset,
408
- bytes, flags);
409
+ bytes, read_flags, write_flags);
410
}
411
412
static int coroutine_fn raw_co_copy_range_to(BlockDriverState *bs,
413
- BdrvChild *src, uint64_t src_offset,
414
- BdrvChild *dst, uint64_t dst_offset,
415
- uint64_t bytes, BdrvRequestFlags flags)
416
+ BdrvChild *src,
417
+ uint64_t src_offset,
418
+ BdrvChild *dst,
419
+ uint64_t dst_offset,
420
+ uint64_t bytes,
421
+ BdrvRequestFlags read_flags,
422
+ BdrvRequestFlags write_flags)
423
{
424
int ret;
425
426
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_copy_range_to(BlockDriverState *bs,
427
return ret;
428
}
429
return bdrv_co_copy_range_to(src, src_offset, bs->file, dst_offset, bytes,
430
- flags);
431
+ read_flags, write_flags);
432
}
433
434
BlockDriver bdrv_raw = {
435
diff --git a/qemu-img.c b/qemu-img.c
436
index XXXXXXX..XXXXXXX 100644
437
--- a/qemu-img.c
438
+++ b/qemu-img.c
439
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn convert_co_copy_range(ImgConvertState *s, int64_t sector
440
441
ret = blk_co_copy_range(blk, offset, s->target,
442
sector_num << BDRV_SECTOR_BITS,
443
- n << BDRV_SECTOR_BITS, 0);
444
+ n << BDRV_SECTOR_BITS, 0, 0);
445
if (ret < 0) {
446
return ret;
447
}
448
--
449
2.13.6
450
451
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Serialized writes should be used in copy-on-write of backup(sync=none)
4
for image fleecing scheme.
5
6
We need to change an assert in bdrv_aligned_pwritev, added in
7
28de2dcd88de. The assert may fail now, because call to
8
wait_serialising_requests here may become first call to it for this
9
request with serializing flag set. It occurs if the request is aligned
10
(otherwise, we should already set serializing flag before calling
11
bdrv_aligned_pwritev and correspondingly waited for all intersecting
12
requests). However, for aligned requests, we should not care about
13
outdating of previously read data, as there no such data. Therefore,
14
let's just update an assert to not care about aligned requests.
15
16
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
17
Reviewed-by: Fam Zheng <famz@redhat.com>
18
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
19
---
20
include/block/block.h | 14 +++++++++++++-
21
block/io.c | 28 +++++++++++++++++++++++++++-
22
2 files changed, 40 insertions(+), 2 deletions(-)
23
24
diff --git a/include/block/block.h b/include/block/block.h
25
index XXXXXXX..XXXXXXX 100644
26
--- a/include/block/block.h
27
+++ b/include/block/block.h
28
@@ -XXX,XX +XXX,XX @@ typedef enum {
29
* content. */
30
BDRV_REQ_WRITE_UNCHANGED = 0x40,
31
32
+ /*
33
+ * BDRV_REQ_SERIALISING forces request serialisation for writes.
34
+ * It is used to ensure that writes to the backing file of a backup process
35
+ * target cannot race with a read of the backup target that defers to the
36
+ * backing file.
37
+ *
38
+ * Note, that BDRV_REQ_SERIALISING is _not_ opposite in meaning to
39
+ * BDRV_REQ_NO_SERIALISING. A more descriptive name for the latter might be
40
+ * _DO_NOT_WAIT_FOR_SERIALISING, except that is too long.
41
+ */
42
+ BDRV_REQ_SERIALISING = 0x80,
43
+
44
/* Mask of valid flags */
45
- BDRV_REQ_MASK = 0x7f,
46
+ BDRV_REQ_MASK = 0xff,
47
} BdrvRequestFlags;
48
49
typedef struct BlockSizes {
50
diff --git a/block/io.c b/block/io.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/block/io.c
53
+++ b/block/io.c
54
@@ -XXX,XX +XXX,XX @@ static void mark_request_serialising(BdrvTrackedRequest *req, uint64_t align)
55
req->overlap_bytes = MAX(req->overlap_bytes, overlap_bytes);
56
}
57
58
+static bool is_request_serialising_and_aligned(BdrvTrackedRequest *req)
59
+{
60
+ /*
61
+ * If the request is serialising, overlap_offset and overlap_bytes are set,
62
+ * so we can check if the request is aligned. Otherwise, don't care and
63
+ * return false.
64
+ */
65
+
66
+ return req->serialising && (req->offset == req->overlap_offset) &&
67
+ (req->bytes == req->overlap_bytes);
68
+}
69
+
70
/**
71
* Round a region to cluster boundaries
72
*/
73
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_aligned_preadv(BdrvChild *child,
74
mark_request_serialising(req, bdrv_get_cluster_size(bs));
75
}
76
77
+ /* BDRV_REQ_SERIALISING is only for write operation */
78
+ assert(!(flags & BDRV_REQ_SERIALISING));
79
+
80
if (!(flags & BDRV_REQ_NO_SERIALISING)) {
81
wait_serialising_requests(req);
82
}
83
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child,
84
85
/* BDRV_REQ_NO_SERIALISING is only for read operation */
86
assert(!(flags & BDRV_REQ_NO_SERIALISING));
87
+
88
+ if (flags & BDRV_REQ_SERIALISING) {
89
+ mark_request_serialising(req, bdrv_get_cluster_size(bs));
90
+ }
91
+
92
waited = wait_serialising_requests(req);
93
- assert(!waited || !req->serialising);
94
+ assert(!waited || !req->serialising ||
95
+ is_request_serialising_and_aligned(req));
96
assert(req->overlap_offset <= offset);
97
assert(offset + bytes <= req->overlap_offset + req->overlap_bytes);
98
if (flags & BDRV_REQ_WRITE_UNCHANGED) {
99
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_copy_range_internal(
100
tracked_request_begin(&req, src->bs, src_offset, bytes,
101
BDRV_TRACKED_READ);
102
103
+ /* BDRV_REQ_SERIALISING is only for write operation */
104
+ assert(!(read_flags & BDRV_REQ_SERIALISING));
105
if (!(read_flags & BDRV_REQ_NO_SERIALISING)) {
106
wait_serialising_requests(&req);
107
}
108
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_copy_range_internal(
109
110
/* BDRV_REQ_NO_SERIALISING is only for read operation */
111
assert(!(write_flags & BDRV_REQ_NO_SERIALISING));
112
+ if (write_flags & BDRV_REQ_SERIALISING) {
113
+ mark_request_serialising(&req, bdrv_get_cluster_size(dst->bs));
114
+ }
115
wait_serialising_requests(&req);
116
117
ret = dst->bs->drv->bdrv_co_copy_range_to(dst->bs,
118
--
119
2.13.6
120
121
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Fleecing scheme works as follows: we want a kind of temporary snapshot
4
of active drive A. We create temporary image B, with B->backing = A.
5
Then we start backup(sync=none) from A to B. From this point, B reads
6
as point-in-time snapshot of A (A continues to be active drive,
7
accepting guest IO).
8
9
This scheme needs some additional synchronization between reads from B
10
and backup COW operations, otherwise, the following situation is
11
theoretically possible:
12
13
(assume B is qcow2, client is NBD client, reading from B)
14
15
1. client starts reading and take qcow2 mutex in qcow2_co_preadv, and
16
goes up to l2 table loading (assume cache miss)
17
18
2) guest write => backup COW => qcow2 write =>
19
try to take qcow2 mutex => waiting
20
21
3. l2 table loaded, we see that cluster is UNALLOCATED, go to
22
"case QCOW2_CLUSTER_UNALLOCATED" and unlock mutex before
23
bdrv_co_preadv(bs->backing, ...)
24
25
4) aha, mutex unlocked, backup COW continues, and we finally finish
26
guest write and change cluster in our active disk A
27
28
5. actually, do bdrv_co_preadv(bs->backing, ...) and read
29
_new updated_ data.
30
31
To avoid this, let's make backup writes serializing, to not intersect
32
with reads from B.
33
34
Note: we expand range of handled cases from (sync=none and
35
B->backing = A) to just (A in backing chain of B), to finally allow
36
safe reading from B during backup for all cases when A in backing chain
37
of B, i.e. B formally looks like point-in-time snapshot of A.
38
39
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
40
Reviewed-by: Fam Zheng <famz@redhat.com>
41
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
42
---
43
block/backup.c | 20 ++++++++++++++------
44
1 file changed, 14 insertions(+), 6 deletions(-)
45
46
diff --git a/block/backup.c b/block/backup.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/block/backup.c
49
+++ b/block/backup.c
50
@@ -XXX,XX +XXX,XX @@ typedef struct BackupBlockJob {
51
HBitmap *copy_bitmap;
52
bool use_copy_range;
53
int64_t copy_range_size;
54
+
55
+ bool serialize_target_writes;
56
} BackupBlockJob;
57
58
static const BlockJobDriver backup_job_driver;
59
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_cow_with_bounce_buffer(BackupBlockJob *job,
60
QEMUIOVector qiov;
61
BlockBackend *blk = job->common.blk;
62
int nbytes;
63
+ int read_flags = is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0;
64
+ int write_flags = job->serialize_target_writes ? BDRV_REQ_SERIALISING : 0;
65
66
hbitmap_reset(job->copy_bitmap, start / job->cluster_size, 1);
67
nbytes = MIN(job->cluster_size, job->len - start);
68
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_cow_with_bounce_buffer(BackupBlockJob *job,
69
iov.iov_len = nbytes;
70
qemu_iovec_init_external(&qiov, &iov, 1);
71
72
- ret = blk_co_preadv(blk, start, qiov.size, &qiov,
73
- is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0);
74
+ ret = blk_co_preadv(blk, start, qiov.size, &qiov, read_flags);
75
if (ret < 0) {
76
trace_backup_do_cow_read_fail(job, start, ret);
77
if (error_is_read) {
78
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_cow_with_bounce_buffer(BackupBlockJob *job,
79
80
if (qemu_iovec_is_zero(&qiov)) {
81
ret = blk_co_pwrite_zeroes(job->target, start,
82
- qiov.size, BDRV_REQ_MAY_UNMAP);
83
+ qiov.size, write_flags | BDRV_REQ_MAY_UNMAP);
84
} else {
85
ret = blk_co_pwritev(job->target, start,
86
- qiov.size, &qiov,
87
- job->compress ? BDRV_REQ_WRITE_COMPRESSED : 0);
88
+ qiov.size, &qiov, write_flags |
89
+ (job->compress ? BDRV_REQ_WRITE_COMPRESSED : 0));
90
}
91
if (ret < 0) {
92
trace_backup_do_cow_write_fail(job, start, ret);
93
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_cow_with_offload(BackupBlockJob *job,
94
int nr_clusters;
95
BlockBackend *blk = job->common.blk;
96
int nbytes;
97
+ int read_flags = is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0;
98
+ int write_flags = job->serialize_target_writes ? BDRV_REQ_SERIALISING : 0;
99
100
assert(QEMU_IS_ALIGNED(job->copy_range_size, job->cluster_size));
101
nbytes = MIN(job->copy_range_size, end - start);
102
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_cow_with_offload(BackupBlockJob *job,
103
hbitmap_reset(job->copy_bitmap, start / job->cluster_size,
104
nr_clusters);
105
ret = blk_co_copy_range(blk, start, job->target, start, nbytes,
106
- is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0, 0);
107
+ read_flags, write_flags);
108
if (ret < 0) {
109
trace_backup_do_cow_copy_range_fail(job, start, ret);
110
hbitmap_set(job->copy_bitmap, start / job->cluster_size,
111
@@ -XXX,XX +XXX,XX @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
112
sync_bitmap : NULL;
113
job->compress = compress;
114
115
+ /* Detect image-fleecing (and similar) schemes */
116
+ job->serialize_target_writes = bdrv_chain_contains(target, bs);
117
+
118
/* If there is no backing file on the target, we cannot rely on COW if our
119
* backup cluster size is smaller than the target cluster size. Even for
120
* targets with a backing file, try to avoid COW if possible. */
121
--
122
2.13.6
123
124
diff view generated by jsdifflib
Deleted patch
1
From: Ari Sundholm <ari@tuxera.com>
2
1
3
This was accidentally omitted. Thanks to Eric Blake for spotting this.
4
5
Signed-off-by: Ari Sundholm <ari@tuxera.com>
6
Reviewed-by: Eric Blake <eblake@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
9
qapi/block-core.json | 2 ++
10
1 file changed, 2 insertions(+)
11
12
diff --git a/qapi/block-core.json b/qapi/block-core.json
13
index XXXXXXX..XXXXXXX 100644
14
--- a/qapi/block-core.json
15
+++ b/qapi/block-core.json
16
@@ -XXX,XX +XXX,XX @@
17
# @log-sector-size: sector size used in logging writes to @file, determines
18
# granularity of offsets and sizes of writes (default: 512)
19
#
20
+# @log-append: append to an existing log (default: false)
21
+#
22
# @log-super-update-interval: interval of write requests after which the log
23
# super block is updated to disk (default: 4096)
24
#
25
--
26
2.13.6
27
28
diff view generated by jsdifflib
Deleted patch
1
From: Ari Sundholm <ari@tuxera.com>
2
1
3
The sector size needs to be large enough to accommodate the data
4
structures for the log super block and log write entries. This was
5
previously not properly checked, which made it possible to cause
6
QEMU to badly misbehave.
7
8
Signed-off-by: Ari Sundholm <ari@tuxera.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
block/blklogwrites.c | 5 ++++-
12
1 file changed, 4 insertions(+), 1 deletion(-)
13
14
diff --git a/block/blklogwrites.c b/block/blklogwrites.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/block/blklogwrites.c
17
+++ b/block/blklogwrites.c
18
@@ -XXX,XX +XXX,XX @@ static inline uint32_t blk_log_writes_log2(uint32_t value)
19
20
static inline bool blk_log_writes_sector_size_valid(uint32_t sector_size)
21
{
22
- return sector_size < (1ull << 24) && is_power_of_2(sector_size);
23
+ return is_power_of_2(sector_size) &&
24
+ sector_size >= sizeof(struct log_write_super) &&
25
+ sector_size >= sizeof(struct log_write_entry) &&
26
+ sector_size < (1ull << 24);
27
}
28
29
static uint64_t blk_log_writes_find_cur_log_sector(BdrvChild *log,
30
--
31
2.13.6
32
33
diff view generated by jsdifflib
Deleted patch
1
From: Cornelia Huck <cohuck@redhat.com>
2
1
3
This reverts commit 6266e900b8083945cb766b45c124fb3c42932cb3.
4
5
Some deprecated -drive options were still in use by libvirt, only
6
fixed with libvirt commit b340c6c614 ("qemu: format serial and geometry
7
on frontend disk device"), which is not yet in any released version
8
of libvirt.
9
10
So let's hold off removing the deprecated options for one more QEMU
11
release.
12
13
Reported-by: Christian Borntraeger <borntraeger@de.ibm.com>
14
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
15
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
---
17
blockdev.c | 12 ++++++++++++
18
1 file changed, 12 insertions(+)
19
20
diff --git a/blockdev.c b/blockdev.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/blockdev.c
23
+++ b/blockdev.c
24
@@ -XXX,XX +XXX,XX @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
25
const char *filename;
26
Error *local_err = NULL;
27
int i;
28
+ const char *deprecated[] = {
29
+ };
30
31
/* Change legacy command line options into QMP ones */
32
static const struct {
33
@@ -XXX,XX +XXX,XX @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
34
goto fail;
35
}
36
37
+ /* Other deprecated options */
38
+ if (!qtest_enabled()) {
39
+ for (i = 0; i < ARRAY_SIZE(deprecated); i++) {
40
+ if (qemu_opt_get(legacy_opts, deprecated[i]) != NULL) {
41
+ error_report("'%s' is deprecated, please use the corresponding "
42
+ "option of '-device' instead", deprecated[i]);
43
+ }
44
+ }
45
+ }
46
+
47
/* Media type */
48
value = qemu_opt_get(legacy_opts, "media");
49
if (value) {
50
--
51
2.13.6
52
53
diff view generated by jsdifflib
Deleted patch
1
From: Cornelia Huck <cohuck@redhat.com>
2
1
3
This reverts commit b0083267444a5e0f28391f6c2831a539f878d424.
4
5
Hold off removing this for one more QEMU release (current libvirt
6
release still uses it.)
7
8
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
include/hw/block/block.h | 1 +
12
include/sysemu/blockdev.h | 1 +
13
block/block-backend.c | 1 +
14
blockdev.c | 10 ++++++++++
15
hw/block/block.c | 13 +++++++++++++
16
hw/block/nvme.c | 1 +
17
hw/block/virtio-blk.c | 1 +
18
hw/ide/qdev.c | 1 +
19
hw/scsi/scsi-disk.c | 1 +
20
hw/usb/dev-storage.c | 1 +
21
tests/ahci-test.c | 6 +++---
22
tests/ide-test.c | 8 ++++----
23
qemu-doc.texi | 5 +++++
24
qemu-options.hx | 6 +++++-
25
14 files changed, 48 insertions(+), 8 deletions(-)
26
27
diff --git a/include/hw/block/block.h b/include/hw/block/block.h
28
index XXXXXXX..XXXXXXX 100644
29
--- a/include/hw/block/block.h
30
+++ b/include/hw/block/block.h
31
@@ -XXX,XX +XXX,XX @@ static inline unsigned int get_physical_block_exp(BlockConf *conf)
32
33
/* Configuration helpers */
34
35
+void blkconf_serial(BlockConf *conf, char **serial);
36
bool blkconf_geometry(BlockConf *conf, int *trans,
37
unsigned cyls_max, unsigned heads_max, unsigned secs_max,
38
Error **errp);
39
diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
40
index XXXXXXX..XXXXXXX 100644
41
--- a/include/sysemu/blockdev.h
42
+++ b/include/sysemu/blockdev.h
43
@@ -XXX,XX +XXX,XX @@ struct DriveInfo {
44
bool is_default; /* Added by default_drive() ? */
45
int media_cd;
46
QemuOpts *opts;
47
+ char *serial;
48
QTAILQ_ENTRY(DriveInfo) next;
49
};
50
51
diff --git a/block/block-backend.c b/block/block-backend.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/block/block-backend.c
54
+++ b/block/block-backend.c
55
@@ -XXX,XX +XXX,XX @@ static void drive_info_del(DriveInfo *dinfo)
56
return;
57
}
58
qemu_opts_del(dinfo->opts);
59
+ g_free(dinfo->serial);
60
g_free(dinfo);
61
}
62
63
diff --git a/blockdev.c b/blockdev.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/blockdev.c
66
+++ b/blockdev.c
67
@@ -XXX,XX +XXX,XX @@ QemuOptsList qemu_legacy_drive_opts = {
68
.type = QEMU_OPT_STRING,
69
.help = "interface (ide, scsi, sd, mtd, floppy, pflash, virtio)",
70
},{
71
+ .name = "serial",
72
+ .type = QEMU_OPT_STRING,
73
+ .help = "disk serial number",
74
+ },{
75
.name = "file",
76
.type = QEMU_OPT_STRING,
77
.help = "file name",
78
@@ -XXX,XX +XXX,XX @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
79
const char *werror, *rerror;
80
bool read_only = false;
81
bool copy_on_read;
82
+ const char *serial;
83
const char *filename;
84
Error *local_err = NULL;
85
int i;
86
const char *deprecated[] = {
87
+ "serial"
88
};
89
90
/* Change legacy command line options into QMP ones */
91
@@ -XXX,XX +XXX,XX @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
92
goto fail;
93
}
94
95
+ /* Serial number */
96
+ serial = qemu_opt_get(legacy_opts, "serial");
97
+
98
/* no id supplied -> create one */
99
if (qemu_opts_id(all_opts) == NULL) {
100
char *new_id;
101
@@ -XXX,XX +XXX,XX @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
102
dinfo->type = type;
103
dinfo->bus = bus_id;
104
dinfo->unit = unit_id;
105
+ dinfo->serial = g_strdup(serial);
106
107
blk_set_legacy_dinfo(blk, dinfo);
108
109
diff --git a/hw/block/block.c b/hw/block/block.c
110
index XXXXXXX..XXXXXXX 100644
111
--- a/hw/block/block.c
112
+++ b/hw/block/block.c
113
@@ -XXX,XX +XXX,XX @@
114
#include "qapi/qapi-types-block.h"
115
#include "qemu/error-report.h"
116
117
+void blkconf_serial(BlockConf *conf, char **serial)
118
+{
119
+ DriveInfo *dinfo;
120
+
121
+ if (!*serial) {
122
+ /* try to fall back to value set with legacy -drive serial=... */
123
+ dinfo = blk_legacy_dinfo(conf->blk);
124
+ if (dinfo) {
125
+ *serial = g_strdup(dinfo->serial);
126
+ }
127
+ }
128
+}
129
+
130
void blkconf_blocksizes(BlockConf *conf)
131
{
132
BlockBackend *blk = conf->blk;
133
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
134
index XXXXXXX..XXXXXXX 100644
135
--- a/hw/block/nvme.c
136
+++ b/hw/block/nvme.c
137
@@ -XXX,XX +XXX,XX @@ static void nvme_realize(PCIDevice *pci_dev, Error **errp)
138
return;
139
}
140
141
+ blkconf_serial(&n->conf, &n->serial);
142
if (!n->serial) {
143
error_setg(errp, "serial property not set");
144
return;
145
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
146
index XXXXXXX..XXXXXXX 100644
147
--- a/hw/block/virtio-blk.c
148
+++ b/hw/block/virtio-blk.c
149
@@ -XXX,XX +XXX,XX @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
150
return;
151
}
152
153
+ blkconf_serial(&conf->conf, &conf->serial);
154
if (!blkconf_apply_backend_options(&conf->conf,
155
blk_is_read_only(conf->conf.blk), true,
156
errp)) {
157
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
158
index XXXXXXX..XXXXXXX 100644
159
--- a/hw/ide/qdev.c
160
+++ b/hw/ide/qdev.c
161
@@ -XXX,XX +XXX,XX @@ static void ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind, Error **errp)
162
return;
163
}
164
165
+ blkconf_serial(&dev->conf, &dev->serial);
166
if (kind != IDE_CD) {
167
if (!blkconf_geometry(&dev->conf, &dev->chs_trans, 65535, 16, 255,
168
errp)) {
169
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
170
index XXXXXXX..XXXXXXX 100644
171
--- a/hw/scsi/scsi-disk.c
172
+++ b/hw/scsi/scsi-disk.c
173
@@ -XXX,XX +XXX,XX @@ static void scsi_realize(SCSIDevice *dev, Error **errp)
174
return;
175
}
176
177
+ blkconf_serial(&s->qdev.conf, &s->serial);
178
blkconf_blocksizes(&s->qdev.conf);
179
180
if (s->qdev.conf.logical_block_size >
181
diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c
182
index XXXXXXX..XXXXXXX 100644
183
--- a/hw/usb/dev-storage.c
184
+++ b/hw/usb/dev-storage.c
185
@@ -XXX,XX +XXX,XX @@ static void usb_msd_storage_realize(USBDevice *dev, Error **errp)
186
return;
187
}
188
189
+ blkconf_serial(&s->conf, &dev->serial);
190
blkconf_blocksizes(&s->conf);
191
if (!blkconf_apply_backend_options(&s->conf, blk_is_read_only(blk), true,
192
errp)) {
193
diff --git a/tests/ahci-test.c b/tests/ahci-test.c
194
index XXXXXXX..XXXXXXX 100644
195
--- a/tests/ahci-test.c
196
+++ b/tests/ahci-test.c
197
@@ -XXX,XX +XXX,XX @@ static AHCIQState *ahci_boot(const char *cli, ...)
198
s = ahci_vboot(cli, ap);
199
va_end(ap);
200
} else {
201
- cli = "-drive if=none,id=drive0,file=%s,cache=writeback,format=%s"
202
+ cli = "-drive if=none,id=drive0,file=%s,cache=writeback,serial=%s"
203
+ ",format=%s"
204
" -M q35 "
205
"-device ide-hd,drive=drive0 "
206
- "-global ide-hd.serial=%s "
207
"-global ide-hd.ver=%s";
208
- s = ahci_boot(cli, tmp_path, imgfmt, "testdisk", "version");
209
+ s = ahci_boot(cli, tmp_path, "testdisk", imgfmt, "version");
210
}
211
212
return s;
213
diff --git a/tests/ide-test.c b/tests/ide-test.c
214
index XXXXXXX..XXXXXXX 100644
215
--- a/tests/ide-test.c
216
+++ b/tests/ide-test.c
217
@@ -XXX,XX +XXX,XX @@ static void test_bmdma_no_busmaster(void)
218
static void test_bmdma_setup(void)
219
{
220
ide_test_start(
221
- "-drive file=%s,if=ide,cache=writeback,format=raw "
222
- "-global ide-hd.serial=%s -global ide-hd.ver=%s",
223
+ "-drive file=%s,if=ide,serial=%s,cache=writeback,format=raw "
224
+ "-global ide-hd.ver=%s",
225
tmp_path, "testdisk", "version");
226
qtest_irq_intercept_in(global_qtest, "ioapic");
227
}
228
@@ -XXX,XX +XXX,XX @@ static void test_identify(void)
229
int ret;
230
231
ide_test_start(
232
- "-drive file=%s,if=ide,cache=writeback,format=raw "
233
- "-global ide-hd.serial=%s -global ide-hd.ver=%s",
234
+ "-drive file=%s,if=ide,serial=%s,cache=writeback,format=raw "
235
+ "-global ide-hd.ver=%s",
236
tmp_path, "testdisk", "version");
237
238
dev = get_pci_device(&bmdma_bar, &ide_bar);
239
diff --git a/qemu-doc.texi b/qemu-doc.texi
240
index XXXXXXX..XXXXXXX 100644
241
--- a/qemu-doc.texi
242
+++ b/qemu-doc.texi
243
@@ -XXX,XX +XXX,XX @@ with ``-device ...,netdev=x''), or ``-nic user,smb=/some/dir''
244
(for embedded NICs). The new syntax allows different settings to be
245
provided per NIC.
246
247
+@subsection -drive serial=... (since 2.10.0)
248
+
249
+The drive serial argument is replaced by the the serial argument
250
+that can be specified with the ``-device'' parameter.
251
+
252
@subsection -usbdevice (since 2.10.0)
253
254
The ``-usbdevice DEV'' argument is now a synonym for setting
255
diff --git a/qemu-options.hx b/qemu-options.hx
256
index XXXXXXX..XXXXXXX 100644
257
--- a/qemu-options.hx
258
+++ b/qemu-options.hx
259
@@ -XXX,XX +XXX,XX @@ ETEXI
260
DEF("drive", HAS_ARG, QEMU_OPTION_drive,
261
"-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][,index=i]\n"
262
" [,cache=writethrough|writeback|none|directsync|unsafe][,format=f]\n"
263
- " [,snapshot=on|off][,rerror=ignore|stop|report]\n"
264
+ " [,snapshot=on|off][,serial=s][,rerror=ignore|stop|report]\n"
265
" [,werror=ignore|stop|report|enospc][,id=name][,aio=threads|native]\n"
266
" [,readonly=on|off][,copy-on-read=on|off]\n"
267
" [,discard=ignore|unmap][,detect-zeroes=on|off|unmap]\n"
268
@@ -XXX,XX +XXX,XX @@ The default mode is @option{cache=writeback}.
269
Specify which disk @var{format} will be used rather than detecting
270
the format. Can be used to specify format=raw to avoid interpreting
271
an untrusted format header.
272
+@item serial=@var{serial}
273
+This option specifies the serial number to assign to the device. This
274
+parameter is deprecated, use the corresponding parameter of @code{-device}
275
+instead.
276
@item werror=@var{action},rerror=@var{action}
277
Specify which @var{action} to take on write and read errors. Valid actions are:
278
"ignore" (ignore the error and try to continue), "stop" (pause QEMU),
279
--
280
2.13.6
281
282
diff view generated by jsdifflib
Deleted patch
1
From: Cornelia Huck <cohuck@redhat.com>
2
1
3
This reverts commit eae3bd1eb7c6b105d30ec06008b3bc3dfc5f45bb.
4
5
Reverted to avoid conflicts for geometry options revert.
6
7
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
10
include/sysemu/blockdev.h | 1 +
11
blockdev.c | 17 ++++++++++++++++-
12
device-hotplug.c | 4 ++++
13
qemu-doc.texi | 5 +++++
14
qemu-options.hx | 5 ++++-
15
5 files changed, 30 insertions(+), 2 deletions(-)
16
17
diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/sysemu/blockdev.h
20
+++ b/include/sysemu/blockdev.h
21
@@ -XXX,XX +XXX,XX @@ typedef enum {
22
} BlockInterfaceType;
23
24
struct DriveInfo {
25
+ const char *devaddr;
26
BlockInterfaceType type;
27
int bus;
28
int unit;
29
diff --git a/blockdev.c b/blockdev.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/blockdev.c
32
+++ b/blockdev.c
33
@@ -XXX,XX +XXX,XX @@ QemuOptsList qemu_legacy_drive_opts = {
34
.type = QEMU_OPT_STRING,
35
.help = "interface (ide, scsi, sd, mtd, floppy, pflash, virtio)",
36
},{
37
+ .name = "addr",
38
+ .type = QEMU_OPT_STRING,
39
+ .help = "pci address (virtio only)",
40
+ },{
41
.name = "serial",
42
.type = QEMU_OPT_STRING,
43
.help = "disk serial number",
44
@@ -XXX,XX +XXX,XX @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
45
DriveMediaType media = MEDIA_DISK;
46
BlockInterfaceType type;
47
int max_devs, bus_id, unit_id, index;
48
+ const char *devaddr;
49
const char *werror, *rerror;
50
bool read_only = false;
51
bool copy_on_read;
52
@@ -XXX,XX +XXX,XX @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
53
Error *local_err = NULL;
54
int i;
55
const char *deprecated[] = {
56
- "serial"
57
+ "serial", "addr"
58
};
59
60
/* Change legacy command line options into QMP ones */
61
@@ -XXX,XX +XXX,XX @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
62
}
63
64
/* Add virtio block device */
65
+ devaddr = qemu_opt_get(legacy_opts, "addr");
66
+ if (devaddr && type != IF_VIRTIO) {
67
+ error_report("addr is not supported by this bus type");
68
+ goto fail;
69
+ }
70
+
71
if (type == IF_VIRTIO) {
72
QemuOpts *devopts;
73
devopts = qemu_opts_create(qemu_find_opts("device"), NULL, 0,
74
@@ -XXX,XX +XXX,XX @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
75
}
76
qemu_opt_set(devopts, "drive", qdict_get_str(bs_opts, "id"),
77
&error_abort);
78
+ if (devaddr) {
79
+ qemu_opt_set(devopts, "addr", devaddr, &error_abort);
80
+ }
81
}
82
83
filename = qemu_opt_get(legacy_opts, "file");
84
@@ -XXX,XX +XXX,XX @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
85
dinfo->type = type;
86
dinfo->bus = bus_id;
87
dinfo->unit = unit_id;
88
+ dinfo->devaddr = devaddr;
89
dinfo->serial = g_strdup(serial);
90
91
blk_set_legacy_dinfo(blk, dinfo);
92
diff --git a/device-hotplug.c b/device-hotplug.c
93
index XXXXXXX..XXXXXXX 100644
94
--- a/device-hotplug.c
95
+++ b/device-hotplug.c
96
@@ -XXX,XX +XXX,XX @@ void hmp_drive_add(Monitor *mon, const QDict *qdict)
97
if (!dinfo) {
98
goto err;
99
}
100
+ if (dinfo->devaddr) {
101
+ monitor_printf(mon, "Parameter addr not supported\n");
102
+ goto err;
103
+ }
104
105
switch (dinfo->type) {
106
case IF_NONE:
107
diff --git a/qemu-doc.texi b/qemu-doc.texi
108
index XXXXXXX..XXXXXXX 100644
109
--- a/qemu-doc.texi
110
+++ b/qemu-doc.texi
111
@@ -XXX,XX +XXX,XX @@ provided per NIC.
112
The drive serial argument is replaced by the the serial argument
113
that can be specified with the ``-device'' parameter.
114
115
+@subsection -drive addr=... (since 2.10.0)
116
+
117
+The drive addr argument is replaced by the the addr argument
118
+that can be specified with the ``-device'' parameter.
119
+
120
@subsection -usbdevice (since 2.10.0)
121
122
The ``-usbdevice DEV'' argument is now a synonym for setting
123
diff --git a/qemu-options.hx b/qemu-options.hx
124
index XXXXXXX..XXXXXXX 100644
125
--- a/qemu-options.hx
126
+++ b/qemu-options.hx
127
@@ -XXX,XX +XXX,XX @@ ETEXI
128
DEF("drive", HAS_ARG, QEMU_OPTION_drive,
129
"-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][,index=i]\n"
130
" [,cache=writethrough|writeback|none|directsync|unsafe][,format=f]\n"
131
- " [,snapshot=on|off][,serial=s][,rerror=ignore|stop|report]\n"
132
+ " [,snapshot=on|off][,serial=s][,addr=A][,rerror=ignore|stop|report]\n"
133
" [,werror=ignore|stop|report|enospc][,id=name][,aio=threads|native]\n"
134
" [,readonly=on|off][,copy-on-read=on|off]\n"
135
" [,discard=ignore|unmap][,detect-zeroes=on|off|unmap]\n"
136
@@ -XXX,XX +XXX,XX @@ an untrusted format header.
137
This option specifies the serial number to assign to the device. This
138
parameter is deprecated, use the corresponding parameter of @code{-device}
139
instead.
140
+@item addr=@var{addr}
141
+Specify the controller's PCI address (if=virtio only). This parameter is
142
+deprecated, use the corresponding parameter of @code{-device} instead.
143
@item werror=@var{action},rerror=@var{action}
144
Specify which @var{action} to take on write and read errors. Valid actions are:
145
"ignore" (ignore the error and try to continue), "stop" (pause QEMU),
146
--
147
2.13.6
148
149
diff view generated by jsdifflib
Deleted patch
1
From: Cornelia Huck <cohuck@redhat.com>
2
1
3
This reverts commit a7aff6dd10b16b67e8b142d0c94c5d92c3fe88f6.
4
5
Hold off removing this for one more QEMU release (current libvirt
6
release still uses it.)
7
8
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
include/sysemu/blockdev.h | 1 +
12
blockdev.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++-
13
hw/block/block.c | 14 +++++++++
14
tests/hd-geo-test.c | 37 ++++++++++++++++++-----
15
hmp-commands.hx | 1 +
16
qemu-doc.texi | 5 ++++
17
qemu-options.hx | 7 ++++-
18
7 files changed, 131 insertions(+), 9 deletions(-)
19
20
diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/include/sysemu/blockdev.h
23
+++ b/include/sysemu/blockdev.h
24
@@ -XXX,XX +XXX,XX @@ struct DriveInfo {
25
int auto_del; /* see blockdev_mark_auto_del() */
26
bool is_default; /* Added by default_drive() ? */
27
int media_cd;
28
+ int cyls, heads, secs, trans;
29
QemuOpts *opts;
30
char *serial;
31
QTAILQ_ENTRY(DriveInfo) next;
32
diff --git a/blockdev.c b/blockdev.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/blockdev.c
35
+++ b/blockdev.c
36
@@ -XXX,XX +XXX,XX @@ QemuOptsList qemu_legacy_drive_opts = {
37
.type = QEMU_OPT_STRING,
38
.help = "interface (ide, scsi, sd, mtd, floppy, pflash, virtio)",
39
},{
40
+ .name = "cyls",
41
+ .type = QEMU_OPT_NUMBER,
42
+ .help = "number of cylinders (ide disk geometry)",
43
+ },{
44
+ .name = "heads",
45
+ .type = QEMU_OPT_NUMBER,
46
+ .help = "number of heads (ide disk geometry)",
47
+ },{
48
+ .name = "secs",
49
+ .type = QEMU_OPT_NUMBER,
50
+ .help = "number of sectors (ide disk geometry)",
51
+ },{
52
+ .name = "trans",
53
+ .type = QEMU_OPT_STRING,
54
+ .help = "chs translation (auto, lba, none)",
55
+ },{
56
.name = "addr",
57
.type = QEMU_OPT_STRING,
58
.help = "pci address (virtio only)",
59
@@ -XXX,XX +XXX,XX @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
60
QemuOpts *legacy_opts;
61
DriveMediaType media = MEDIA_DISK;
62
BlockInterfaceType type;
63
+ int cyls, heads, secs, translation;
64
int max_devs, bus_id, unit_id, index;
65
const char *devaddr;
66
const char *werror, *rerror;
67
@@ -XXX,XX +XXX,XX @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
68
Error *local_err = NULL;
69
int i;
70
const char *deprecated[] = {
71
- "serial", "addr"
72
+ "serial", "trans", "secs", "heads", "cyls", "addr"
73
};
74
75
/* Change legacy command line options into QMP ones */
76
@@ -XXX,XX +XXX,XX @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
77
type = block_default_type;
78
}
79
80
+ /* Geometry */
81
+ cyls = qemu_opt_get_number(legacy_opts, "cyls", 0);
82
+ heads = qemu_opt_get_number(legacy_opts, "heads", 0);
83
+ secs = qemu_opt_get_number(legacy_opts, "secs", 0);
84
+
85
+ if (cyls || heads || secs) {
86
+ if (cyls < 1) {
87
+ error_report("invalid physical cyls number");
88
+ goto fail;
89
+ }
90
+ if (heads < 1) {
91
+ error_report("invalid physical heads number");
92
+ goto fail;
93
+ }
94
+ if (secs < 1) {
95
+ error_report("invalid physical secs number");
96
+ goto fail;
97
+ }
98
+ }
99
+
100
+ translation = BIOS_ATA_TRANSLATION_AUTO;
101
+ value = qemu_opt_get(legacy_opts, "trans");
102
+ if (value != NULL) {
103
+ if (!cyls) {
104
+ error_report("'%s' trans must be used with cyls, heads and secs",
105
+ value);
106
+ goto fail;
107
+ }
108
+ if (!strcmp(value, "none")) {
109
+ translation = BIOS_ATA_TRANSLATION_NONE;
110
+ } else if (!strcmp(value, "lba")) {
111
+ translation = BIOS_ATA_TRANSLATION_LBA;
112
+ } else if (!strcmp(value, "large")) {
113
+ translation = BIOS_ATA_TRANSLATION_LARGE;
114
+ } else if (!strcmp(value, "rechs")) {
115
+ translation = BIOS_ATA_TRANSLATION_RECHS;
116
+ } else if (!strcmp(value, "auto")) {
117
+ translation = BIOS_ATA_TRANSLATION_AUTO;
118
+ } else {
119
+ error_report("'%s' invalid translation type", value);
120
+ goto fail;
121
+ }
122
+ }
123
+
124
+ if (media == MEDIA_CDROM) {
125
+ if (cyls || secs || heads) {
126
+ error_report("CHS can't be set with media=cdrom");
127
+ goto fail;
128
+ }
129
+ }
130
+
131
/* Device address specified by bus/unit or index.
132
* If none was specified, try to find the first free one. */
133
bus_id = qemu_opt_get_number(legacy_opts, "bus", 0);
134
@@ -XXX,XX +XXX,XX @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
135
dinfo = g_malloc0(sizeof(*dinfo));
136
dinfo->opts = all_opts;
137
138
+ dinfo->cyls = cyls;
139
+ dinfo->heads = heads;
140
+ dinfo->secs = secs;
141
+ dinfo->trans = translation;
142
+
143
dinfo->type = type;
144
dinfo->bus = bus_id;
145
dinfo->unit = unit_id;
146
diff --git a/hw/block/block.c b/hw/block/block.c
147
index XXXXXXX..XXXXXXX 100644
148
--- a/hw/block/block.c
149
+++ b/hw/block/block.c
150
@@ -XXX,XX +XXX,XX @@ bool blkconf_geometry(BlockConf *conf, int *ptrans,
151
unsigned cyls_max, unsigned heads_max, unsigned secs_max,
152
Error **errp)
153
{
154
+ DriveInfo *dinfo;
155
+
156
+ if (!conf->cyls && !conf->heads && !conf->secs) {
157
+ /* try to fall back to value set with legacy -drive cyls=... */
158
+ dinfo = blk_legacy_dinfo(conf->blk);
159
+ if (dinfo) {
160
+ conf->cyls = dinfo->cyls;
161
+ conf->heads = dinfo->heads;
162
+ conf->secs = dinfo->secs;
163
+ if (ptrans) {
164
+ *ptrans = dinfo->trans;
165
+ }
166
+ }
167
+ }
168
if (!conf->cyls && !conf->heads && !conf->secs) {
169
hd_geometry_guess(conf->blk,
170
&conf->cyls, &conf->heads, &conf->secs,
171
diff --git a/tests/hd-geo-test.c b/tests/hd-geo-test.c
172
index XXXXXXX..XXXXXXX 100644
173
--- a/tests/hd-geo-test.c
174
+++ b/tests/hd-geo-test.c
175
@@ -XXX,XX +XXX,XX @@ static void setup_mbr(int img_idx, MBRcontents mbr)
176
177
static int setup_ide(int argc, char *argv[], int argv_sz,
178
int ide_idx, const char *dev, int img_idx,
179
- MBRcontents mbr)
180
+ MBRcontents mbr, const char *opts)
181
{
182
char *s1, *s2, *s3;
183
184
@@ -XXX,XX +XXX,XX @@ static int setup_ide(int argc, char *argv[], int argv_sz,
185
s3 = g_strdup(",media=cdrom");
186
}
187
argc = append_arg(argc, argv, argv_sz,
188
- g_strdup_printf("%s%s%s", s1, s2, s3));
189
+ g_strdup_printf("%s%s%s%s", s1, s2, s3, opts));
190
g_free(s1);
191
g_free(s2);
192
g_free(s3);
193
@@ -XXX,XX +XXX,XX @@ static void test_ide_mbr(bool use_device, MBRcontents mbr)
194
for (i = 0; i < backend_last; i++) {
195
cur_ide[i] = &hd_chst[i][mbr];
196
dev = use_device ? (is_hd(cur_ide[i]) ? "ide-hd" : "ide-cd") : NULL;
197
- argc = setup_ide(argc, argv, ARGV_SIZE, i, dev, i, mbr);
198
+ argc = setup_ide(argc, argv, ARGV_SIZE, i, dev, i, mbr, "");
199
}
200
args = g_strjoinv(" ", argv);
201
qtest_start(args);
202
@@ -XXX,XX +XXX,XX @@ static void test_ide_drive_user(const char *dev, bool trans)
203
const CHST expected_chst = { secs / (4 * 32) , 4, 32, trans };
204
205
argc = setup_common(argv, ARGV_SIZE);
206
- opts = g_strdup_printf("%s,%scyls=%d,heads=%d,secs=%d",
207
- dev, trans ? "bios-chs-trans=lba," : "",
208
+ opts = g_strdup_printf("%s,%s%scyls=%d,heads=%d,secs=%d",
209
+ dev ?: "",
210
+ trans && dev ? "bios-chs-" : "",
211
+ trans ? "trans=lba," : "",
212
expected_chst.cyls, expected_chst.heads,
213
expected_chst.secs);
214
cur_ide[0] = &expected_chst;
215
- argc = setup_ide(argc, argv, ARGV_SIZE, 0, opts, backend_small, mbr_chs);
216
+ argc = setup_ide(argc, argv, ARGV_SIZE,
217
+ 0, dev ? opts : NULL, backend_small, mbr_chs,
218
+ dev ? "" : opts);
219
g_free(opts);
220
args = g_strjoinv(" ", argv);
221
qtest_start(args);
222
@@ -XXX,XX +XXX,XX @@ static void test_ide_drive_user(const char *dev, bool trans)
223
}
224
225
/*
226
+ * Test case: IDE device (if=ide) with explicit CHS
227
+ */
228
+static void test_ide_drive_user_chs(void)
229
+{
230
+ test_ide_drive_user(NULL, false);
231
+}
232
+
233
+/*
234
+ * Test case: IDE device (if=ide) with explicit CHS and translation
235
+ */
236
+static void test_ide_drive_user_chst(void)
237
+{
238
+ test_ide_drive_user(NULL, true);
239
+}
240
+
241
+/*
242
* Test case: IDE device (if=none) with explicit CHS
243
*/
244
static void test_ide_device_user_chs(void)
245
@@ -XXX,XX +XXX,XX @@ static void test_ide_drive_cd_0(void)
246
for (i = 0; i <= backend_empty; i++) {
247
ide_idx = backend_empty - i;
248
cur_ide[ide_idx] = &hd_chst[i][mbr_blank];
249
- argc = setup_ide(argc, argv, ARGV_SIZE, ide_idx, NULL, i, mbr_blank);
250
+ argc = setup_ide(argc, argv, ARGV_SIZE,
251
+ ide_idx, NULL, i, mbr_blank, "");
252
}
253
args = g_strjoinv(" ", argv);
254
qtest_start(args);
255
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
256
qtest_add_func("hd-geo/ide/drive/mbr/blank", test_ide_drive_mbr_blank);
257
qtest_add_func("hd-geo/ide/drive/mbr/lba", test_ide_drive_mbr_lba);
258
qtest_add_func("hd-geo/ide/drive/mbr/chs", test_ide_drive_mbr_chs);
259
+ qtest_add_func("hd-geo/ide/drive/user/chs", test_ide_drive_user_chs);
260
+ qtest_add_func("hd-geo/ide/drive/user/chst", test_ide_drive_user_chst);
261
qtest_add_func("hd-geo/ide/drive/cd_0", test_ide_drive_cd_0);
262
qtest_add_func("hd-geo/ide/device/mbr/blank", test_ide_device_mbr_blank);
263
qtest_add_func("hd-geo/ide/device/mbr/lba", test_ide_device_mbr_lba);
264
diff --git a/hmp-commands.hx b/hmp-commands.hx
265
index XXXXXXX..XXXXXXX 100644
266
--- a/hmp-commands.hx
267
+++ b/hmp-commands.hx
268
@@ -XXX,XX +XXX,XX @@ ETEXI
269
.params = "[-n] [[<domain>:]<bus>:]<slot>\n"
270
"[file=file][,if=type][,bus=n]\n"
271
"[,unit=m][,media=d][,index=i]\n"
272
+ "[,cyls=c,heads=h,secs=s[,trans=t]]\n"
273
"[,snapshot=on|off][,cache=on|off]\n"
274
"[,readonly=on|off][,copy-on-read=on|off]",
275
.help = "add drive to PCI storage controller",
276
diff --git a/qemu-doc.texi b/qemu-doc.texi
277
index XXXXXXX..XXXXXXX 100644
278
--- a/qemu-doc.texi
279
+++ b/qemu-doc.texi
280
@@ -XXX,XX +XXX,XX @@ with ``-device ...,netdev=x''), or ``-nic user,smb=/some/dir''
281
(for embedded NICs). The new syntax allows different settings to be
282
provided per NIC.
283
284
+@subsection -drive cyls=...,heads=...,secs=...,trans=... (since 2.10.0)
285
+
286
+The drive geometry arguments are replaced by the the geometry arguments
287
+that can be specified with the ``-device'' parameter.
288
+
289
@subsection -drive serial=... (since 2.10.0)
290
291
The drive serial argument is replaced by the the serial argument
292
diff --git a/qemu-options.hx b/qemu-options.hx
293
index XXXXXXX..XXXXXXX 100644
294
--- a/qemu-options.hx
295
+++ b/qemu-options.hx
296
@@ -XXX,XX +XXX,XX @@ ETEXI
297
298
DEF("drive", HAS_ARG, QEMU_OPTION_drive,
299
"-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][,index=i]\n"
300
+ " [,cyls=c,heads=h,secs=s[,trans=t]][,snapshot=on|off]\n"
301
" [,cache=writethrough|writeback|none|directsync|unsafe][,format=f]\n"
302
- " [,snapshot=on|off][,serial=s][,addr=A][,rerror=ignore|stop|report]\n"
303
+ " [,serial=s][,addr=A][,rerror=ignore|stop|report]\n"
304
" [,werror=ignore|stop|report|enospc][,id=name][,aio=threads|native]\n"
305
" [,readonly=on|off][,copy-on-read=on|off]\n"
306
" [,discard=ignore|unmap][,detect-zeroes=on|off|unmap]\n"
307
@@ -XXX,XX +XXX,XX @@ This option defines where is connected the drive by using an index in the list
308
of available connectors of a given interface type.
309
@item media=@var{media}
310
This option defines the type of the media: disk or cdrom.
311
+@item cyls=@var{c},heads=@var{h},secs=@var{s}[,trans=@var{t}]
312
+Force disk physical geometry and the optional BIOS translation (trans=none or
313
+lba). These parameters are deprecated, use the corresponding parameters
314
+of @code{-device} instead.
315
@item snapshot=@var{snapshot}
316
@var{snapshot} is "on" or "off" and controls snapshot mode for the given drive
317
(see @option{-snapshot}).
318
--
319
2.13.6
320
321
diff view generated by jsdifflib
Deleted patch
1
From: Fam Zheng <famz@redhat.com>
2
1
3
With in one module, trace points usually have a common prefix named
4
after the module name. paio_submit and paio_submit_co are the only two
5
trace points so far in the two file protocol drivers. As we are adding
6
more, having a common prefix here is better so that trace points can be
7
enabled with a glob. Rename them.
8
9
Suggested-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Fam Zheng <famz@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
13
block/file-posix.c | 2 +-
14
block/file-win32.c | 2 +-
15
block/trace-events | 4 ++--
16
3 files changed, 4 insertions(+), 4 deletions(-)
17
18
diff --git a/block/file-posix.c b/block/file-posix.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/block/file-posix.c
21
+++ b/block/file-posix.c
22
@@ -XXX,XX +XXX,XX @@ static int paio_submit_co_full(BlockDriverState *bs, int fd,
23
assert(qiov->size == bytes);
24
}
25
26
- trace_paio_submit_co(offset, bytes, type);
27
+ trace_file_paio_submit_co(offset, bytes, type);
28
pool = aio_get_thread_pool(bdrv_get_aio_context(bs));
29
return thread_pool_submit_co(pool, aio_worker, acb);
30
}
31
diff --git a/block/file-win32.c b/block/file-win32.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/block/file-win32.c
34
+++ b/block/file-win32.c
35
@@ -XXX,XX +XXX,XX @@ static BlockAIOCB *paio_submit(BlockDriverState *bs, HANDLE hfile,
36
acb->aio_nbytes = count;
37
acb->aio_offset = offset;
38
39
- trace_paio_submit(acb, opaque, offset, count, type);
40
+ trace_file_paio_submit(acb, opaque, offset, count, type);
41
pool = aio_get_thread_pool(bdrv_get_aio_context(bs));
42
return thread_pool_submit_aio(pool, aio_worker, acb, cb, opaque);
43
}
44
diff --git a/block/trace-events b/block/trace-events
45
index XXXXXXX..XXXXXXX 100644
46
--- a/block/trace-events
47
+++ b/block/trace-events
48
@@ -XXX,XX +XXX,XX @@ qmp_block_stream(void *bs, void *job) "bs %p job %p"
49
50
# block/file-win32.c
51
# block/file-posix.c
52
-paio_submit_co(int64_t offset, int count, int type) "offset %"PRId64" count %d type %d"
53
-paio_submit(void *acb, void *opaque, int64_t offset, int count, int type) "acb %p opaque %p offset %"PRId64" count %d type %d"
54
+file_paio_submit_co(int64_t offset, int count, int type) "offset %"PRId64" count %d type %d"
55
+file_paio_submit(void *acb, void *opaque, int64_t offset, int count, int type) "acb %p opaque %p offset %"PRId64" count %d type %d"
56
57
# block/qcow2.c
58
qcow2_writev_start_req(void *co, int64_t offset, int bytes) "co %p offset 0x%" PRIx64 " bytes %d"
59
--
60
2.13.6
61
62
diff view generated by jsdifflib
Deleted patch
1
From: Fam Zheng <famz@redhat.com>
2
1
3
A few trace points that can help reveal what is happening in a copy
4
offloading I/O path.
5
6
Signed-off-by: Fam Zheng <famz@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
9
block/file-posix.c | 2 ++
10
block/io.c | 4 ++++
11
block/iscsi.c | 3 +++
12
block/trace-events | 6 ++++++
13
4 files changed, 15 insertions(+)
14
15
diff --git a/block/file-posix.c b/block/file-posix.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/block/file-posix.c
18
+++ b/block/file-posix.c
19
@@ -XXX,XX +XXX,XX @@ static ssize_t handle_aiocb_copy_range(RawPosixAIOData *aiocb)
20
ssize_t ret = copy_file_range(aiocb->aio_fildes, &in_off,
21
aiocb->aio_fd2, &out_off,
22
bytes, 0);
23
+ trace_file_copy_file_range(aiocb->bs, aiocb->aio_fildes, in_off,
24
+ aiocb->aio_fd2, out_off, bytes, 0, ret);
25
if (ret == 0) {
26
/* No progress (e.g. when beyond EOF), let the caller fall back to
27
* buffer I/O. */
28
diff --git a/block/io.c b/block/io.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/block/io.c
31
+++ b/block/io.c
32
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_copy_range_from(BdrvChild *src, uint64_t src_offset,
33
BdrvRequestFlags read_flags,
34
BdrvRequestFlags write_flags)
35
{
36
+ trace_bdrv_co_copy_range_from(src, src_offset, dst, dst_offset, bytes,
37
+ read_flags, write_flags);
38
return bdrv_co_copy_range_internal(src, src_offset, dst, dst_offset,
39
bytes, read_flags, write_flags, true);
40
}
41
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_copy_range_to(BdrvChild *src, uint64_t src_offset,
42
BdrvRequestFlags read_flags,
43
BdrvRequestFlags write_flags)
44
{
45
+ trace_bdrv_co_copy_range_to(src, src_offset, dst, dst_offset, bytes,
46
+ read_flags, write_flags);
47
return bdrv_co_copy_range_internal(src, src_offset, dst, dst_offset,
48
bytes, read_flags, write_flags, false);
49
}
50
diff --git a/block/iscsi.c b/block/iscsi.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/block/iscsi.c
53
+++ b/block/iscsi.c
54
@@ -XXX,XX +XXX,XX @@
55
#include "qapi/qmp/qstring.h"
56
#include "crypto/secret.h"
57
#include "scsi/utils.h"
58
+#include "trace.h"
59
60
/* Conflict between scsi/utils.h and libiscsi! :( */
61
#define SCSI_XFER_NONE ISCSI_XFER_NONE
62
@@ -XXX,XX +XXX,XX @@ retry:
63
}
64
65
out_unlock:
66
+
67
+ trace_iscsi_xcopy(src_lun, src_offset, dst_lun, dst_offset, bytes, r);
68
g_free(iscsi_task.task);
69
qemu_mutex_unlock(&dst_lun->mutex);
70
g_free(iscsi_task.err_str);
71
diff --git a/block/trace-events b/block/trace-events
72
index XXXXXXX..XXXXXXX 100644
73
--- a/block/trace-events
74
+++ b/block/trace-events
75
@@ -XXX,XX +XXX,XX @@ bdrv_co_preadv(void *bs, int64_t offset, int64_t nbytes, unsigned int flags) "bs
76
bdrv_co_pwritev(void *bs, int64_t offset, int64_t nbytes, unsigned int flags) "bs %p offset %"PRId64" nbytes %"PRId64" flags 0x%x"
77
bdrv_co_pwrite_zeroes(void *bs, int64_t offset, int count, int flags) "bs %p offset %"PRId64" count %d flags 0x%x"
78
bdrv_co_do_copy_on_readv(void *bs, int64_t offset, unsigned int bytes, int64_t cluster_offset, int64_t cluster_bytes) "bs %p offset %"PRId64" bytes %u cluster_offset %"PRId64" cluster_bytes %"PRId64
79
+bdrv_co_copy_range_from(void *src, uint64_t src_offset, void *dst, uint64_t dst_offset, uint64_t bytes, int read_flags, int write_flags) "src %p offset %"PRIu64" dst %p offset %"PRIu64" bytes %"PRIu64" rw flags 0x%x 0x%x"
80
+bdrv_co_copy_range_to(void *src, uint64_t src_offset, void *dst, uint64_t dst_offset, uint64_t bytes, int read_flags, int write_flags) "src %p offset %"PRIu64" dst %p offset %"PRIu64" bytes %"PRIu64" rw flags 0x%x 0x%x"
81
82
# block/stream.c
83
stream_one_iteration(void *s, int64_t offset, uint64_t bytes, int is_allocated) "s %p offset %" PRId64 " bytes %" PRIu64 " is_allocated %d"
84
@@ -XXX,XX +XXX,XX @@ qmp_block_stream(void *bs, void *job) "bs %p job %p"
85
# block/file-posix.c
86
file_paio_submit_co(int64_t offset, int count, int type) "offset %"PRId64" count %d type %d"
87
file_paio_submit(void *acb, void *opaque, int64_t offset, int count, int type) "acb %p opaque %p offset %"PRId64" count %d type %d"
88
+file_copy_file_range(void *bs, int src, int64_t src_off, int dst, int64_t dst_off, int64_t bytes, int flags, int64_t ret) "bs %p src_fd %d offset %"PRIu64" dst_fd %d offset %"PRIu64" bytes %"PRIu64" flags %d ret %"PRId64
89
90
# block/qcow2.c
91
qcow2_writev_start_req(void *co, int64_t offset, int bytes) "co %p offset 0x%" PRIx64 " bytes %d"
92
@@ -XXX,XX +XXX,XX @@ nvme_free_req_queue_wait(void *q) "q %p"
93
nvme_cmd_map_qiov(void *s, void *cmd, void *req, void *qiov, int entries) "s %p cmd %p req %p qiov %p entries %d"
94
nvme_cmd_map_qiov_pages(void *s, int i, uint64_t page) "s %p page[%d] 0x%"PRIx64
95
nvme_cmd_map_qiov_iov(void *s, int i, void *page, int pages) "s %p iov[%d] %p pages %d"
96
+
97
+# block/iscsi.c
98
+iscsi_xcopy(void *src_lun, uint64_t src_off, void *dst_lun, uint64_t dst_off, uint64_t bytes, int ret) "src_lun %p offset %"PRIu64" dst_lun %p offset %"PRIu64" bytes %"PRIu64" ret %d"
99
--
100
2.13.6
101
102
diff view generated by jsdifflib
Deleted patch
1
From: Fam Zheng <famz@redhat.com>
2
1
3
Other I/O functions are already using a BdrvChild pointer in the API, so
4
make discard do the same. It makes it possible to initiate the same
5
permission checks before doing I/O, and much easier to share the
6
helper functions for this, which will be added and used by write,
7
truncate and copy range paths.
8
9
Signed-off-by: Fam Zheng <famz@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
12
include/block/block.h | 4 ++--
13
block/blkdebug.c | 2 +-
14
block/blklogwrites.c | 2 +-
15
block/blkreplay.c | 2 +-
16
block/block-backend.c | 2 +-
17
block/copy-on-read.c | 2 +-
18
block/io.c | 18 +++++++++---------
19
block/mirror.c | 2 +-
20
block/qcow2-refcount.c | 2 +-
21
block/raw-format.c | 2 +-
22
block/throttle.c | 2 +-
23
11 files changed, 20 insertions(+), 20 deletions(-)
24
25
diff --git a/include/block/block.h b/include/block/block.h
26
index XXXXXXX..XXXXXXX 100644
27
--- a/include/block/block.h
28
+++ b/include/block/block.h
29
@@ -XXX,XX +XXX,XX @@ AioWait *bdrv_get_aio_wait(BlockDriverState *bs);
30
bdrv_get_aio_context(bs_), \
31
cond); })
32
33
-int bdrv_pdiscard(BlockDriverState *bs, int64_t offset, int bytes);
34
-int bdrv_co_pdiscard(BlockDriverState *bs, int64_t offset, int bytes);
35
+int bdrv_pdiscard(BdrvChild *child, int64_t offset, int bytes);
36
+int bdrv_co_pdiscard(BdrvChild *child, int64_t offset, int bytes);
37
int bdrv_has_zero_init_1(BlockDriverState *bs);
38
int bdrv_has_zero_init(BlockDriverState *bs);
39
bool bdrv_unallocated_blocks_are_zero(BlockDriverState *bs);
40
diff --git a/block/blkdebug.c b/block/blkdebug.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/block/blkdebug.c
43
+++ b/block/blkdebug.c
44
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn blkdebug_co_pdiscard(BlockDriverState *bs,
45
return err;
46
}
47
48
- return bdrv_co_pdiscard(bs->file->bs, offset, bytes);
49
+ return bdrv_co_pdiscard(bs->file, offset, bytes);
50
}
51
52
static int coroutine_fn blkdebug_co_block_status(BlockDriverState *bs,
53
diff --git a/block/blklogwrites.c b/block/blklogwrites.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/block/blklogwrites.c
56
+++ b/block/blklogwrites.c
57
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn blk_log_writes_co_do_file_flush(BlkLogWritesFileReq *fr)
58
static int coroutine_fn
59
blk_log_writes_co_do_file_pdiscard(BlkLogWritesFileReq *fr)
60
{
61
- return bdrv_co_pdiscard(fr->bs->file->bs, fr->offset, fr->bytes);
62
+ return bdrv_co_pdiscard(fr->bs->file, fr->offset, fr->bytes);
63
}
64
65
static int coroutine_fn
66
diff --git a/block/blkreplay.c b/block/blkreplay.c
67
index XXXXXXX..XXXXXXX 100755
68
--- a/block/blkreplay.c
69
+++ b/block/blkreplay.c
70
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn blkreplay_co_pdiscard(BlockDriverState *bs,
71
int64_t offset, int bytes)
72
{
73
uint64_t reqid = blkreplay_next_id();
74
- int ret = bdrv_co_pdiscard(bs->file->bs, offset, bytes);
75
+ int ret = bdrv_co_pdiscard(bs->file, offset, bytes);
76
block_request_create(reqid, bs, qemu_coroutine_self());
77
qemu_coroutine_yield();
78
79
diff --git a/block/block-backend.c b/block/block-backend.c
80
index XXXXXXX..XXXXXXX 100644
81
--- a/block/block-backend.c
82
+++ b/block/block-backend.c
83
@@ -XXX,XX +XXX,XX @@ int blk_co_pdiscard(BlockBackend *blk, int64_t offset, int bytes)
84
return ret;
85
}
86
87
- return bdrv_co_pdiscard(blk_bs(blk), offset, bytes);
88
+ return bdrv_co_pdiscard(blk->root, offset, bytes);
89
}
90
91
int blk_co_flush(BlockBackend *blk)
92
diff --git a/block/copy-on-read.c b/block/copy-on-read.c
93
index XXXXXXX..XXXXXXX 100644
94
--- a/block/copy-on-read.c
95
+++ b/block/copy-on-read.c
96
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn cor_co_pwrite_zeroes(BlockDriverState *bs,
97
static int coroutine_fn cor_co_pdiscard(BlockDriverState *bs,
98
int64_t offset, int bytes)
99
{
100
- return bdrv_co_pdiscard(bs->file->bs, offset, bytes);
101
+ return bdrv_co_pdiscard(bs->file, offset, bytes);
102
}
103
104
105
diff --git a/block/io.c b/block/io.c
106
index XXXXXXX..XXXXXXX 100644
107
--- a/block/io.c
108
+++ b/block/io.c
109
@@ -XXX,XX +XXX,XX @@ int bdrv_flush(BlockDriverState *bs)
110
}
111
112
typedef struct DiscardCo {
113
- BlockDriverState *bs;
114
+ BdrvChild *child;
115
int64_t offset;
116
int bytes;
117
int ret;
118
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn bdrv_pdiscard_co_entry(void *opaque)
119
{
120
DiscardCo *rwco = opaque;
121
122
- rwco->ret = bdrv_co_pdiscard(rwco->bs, rwco->offset, rwco->bytes);
123
+ rwco->ret = bdrv_co_pdiscard(rwco->child, rwco->offset, rwco->bytes);
124
}
125
126
-int coroutine_fn bdrv_co_pdiscard(BlockDriverState *bs, int64_t offset,
127
- int bytes)
128
+int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset, int bytes)
129
{
130
BdrvTrackedRequest req;
131
int max_pdiscard, ret;
132
int head, tail, align;
133
+ BlockDriverState *bs = child->bs;
134
135
- if (!bs->drv) {
136
+ if (!bs || !bs->drv) {
137
return -ENOMEDIUM;
138
}
139
140
@@ -XXX,XX +XXX,XX @@ out:
141
return ret;
142
}
143
144
-int bdrv_pdiscard(BlockDriverState *bs, int64_t offset, int bytes)
145
+int bdrv_pdiscard(BdrvChild *child, int64_t offset, int bytes)
146
{
147
Coroutine *co;
148
DiscardCo rwco = {
149
- .bs = bs,
150
+ .child = child,
151
.offset = offset,
152
.bytes = bytes,
153
.ret = NOT_DONE,
154
@@ -XXX,XX +XXX,XX @@ int bdrv_pdiscard(BlockDriverState *bs, int64_t offset, int bytes)
155
bdrv_pdiscard_co_entry(&rwco);
156
} else {
157
co = qemu_coroutine_create(bdrv_pdiscard_co_entry, &rwco);
158
- bdrv_coroutine_enter(bs, co);
159
- BDRV_POLL_WHILE(bs, rwco.ret == NOT_DONE);
160
+ bdrv_coroutine_enter(child->bs, co);
161
+ BDRV_POLL_WHILE(child->bs, rwco.ret == NOT_DONE);
162
}
163
164
return rwco.ret;
165
diff --git a/block/mirror.c b/block/mirror.c
166
index XXXXXXX..XXXXXXX 100644
167
--- a/block/mirror.c
168
+++ b/block/mirror.c
169
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_mirror_top_do_write(BlockDriverState *bs,
170
break;
171
172
case MIRROR_METHOD_DISCARD:
173
- ret = bdrv_co_pdiscard(bs->backing->bs, offset, bytes);
174
+ ret = bdrv_co_pdiscard(bs->backing, offset, bytes);
175
break;
176
177
default:
178
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
179
index XXXXXXX..XXXXXXX 100644
180
--- a/block/qcow2-refcount.c
181
+++ b/block/qcow2-refcount.c
182
@@ -XXX,XX +XXX,XX @@ void qcow2_process_discards(BlockDriverState *bs, int ret)
183
184
/* Discard is optional, ignore the return value */
185
if (ret >= 0) {
186
- bdrv_pdiscard(bs->file->bs, d->offset, d->bytes);
187
+ bdrv_pdiscard(bs->file, d->offset, d->bytes);
188
}
189
190
g_free(d);
191
diff --git a/block/raw-format.c b/block/raw-format.c
192
index XXXXXXX..XXXXXXX 100644
193
--- a/block/raw-format.c
194
+++ b/block/raw-format.c
195
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_pdiscard(BlockDriverState *bs,
196
if (ret) {
197
return ret;
198
}
199
- return bdrv_co_pdiscard(bs->file->bs, offset, bytes);
200
+ return bdrv_co_pdiscard(bs->file, offset, bytes);
201
}
202
203
static int64_t raw_getlength(BlockDriverState *bs)
204
diff --git a/block/throttle.c b/block/throttle.c
205
index XXXXXXX..XXXXXXX 100644
206
--- a/block/throttle.c
207
+++ b/block/throttle.c
208
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn throttle_co_pdiscard(BlockDriverState *bs,
209
ThrottleGroupMember *tgm = bs->opaque;
210
throttle_group_co_io_limits_intercept(tgm, bytes, true);
211
212
- return bdrv_co_pdiscard(bs->file->bs, offset, bytes);
213
+ return bdrv_co_pdiscard(bs->file, offset, bytes);
214
}
215
216
static int throttle_co_flush(BlockDriverState *bs)
217
--
218
2.13.6
219
220
diff view generated by jsdifflib
Deleted patch
1
From: Fam Zheng <famz@redhat.com>
2
1
3
This matches the types used for bytes in the rest parts of block layer.
4
In the case of bdrv_co_truncate, new_bytes can be the image size which
5
probably doesn't fit in a 32 bit int.
6
7
Signed-off-by: Fam Zheng <famz@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
10
include/block/block_int.h | 4 ++--
11
block/io.c | 8 +++++---
12
2 files changed, 7 insertions(+), 5 deletions(-)
13
14
diff --git a/include/block/block_int.h b/include/block/block_int.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/block/block_int.h
17
+++ b/include/block/block_int.h
18
@@ -XXX,XX +XXX,XX @@ enum BdrvTrackedRequestType {
19
typedef struct BdrvTrackedRequest {
20
BlockDriverState *bs;
21
int64_t offset;
22
- unsigned int bytes;
23
+ uint64_t bytes;
24
enum BdrvTrackedRequestType type;
25
26
bool serialising;
27
int64_t overlap_offset;
28
- unsigned int overlap_bytes;
29
+ uint64_t overlap_bytes;
30
31
QLIST_ENTRY(BdrvTrackedRequest) list;
32
Coroutine *co; /* owner, used for deadlock detection */
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 void tracked_request_end(BdrvTrackedRequest *req)
38
static void tracked_request_begin(BdrvTrackedRequest *req,
39
BlockDriverState *bs,
40
int64_t offset,
41
- unsigned int bytes,
42
+ uint64_t bytes,
43
enum BdrvTrackedRequestType type)
44
{
45
+ assert(bytes <= INT64_MAX && offset <= INT64_MAX - bytes);
46
+
47
*req = (BdrvTrackedRequest){
48
.bs = bs,
49
.offset = offset,
50
@@ -XXX,XX +XXX,XX @@ static void tracked_request_begin(BdrvTrackedRequest *req,
51
static void mark_request_serialising(BdrvTrackedRequest *req, uint64_t align)
52
{
53
int64_t overlap_offset = req->offset & ~(align - 1);
54
- unsigned int overlap_bytes = ROUND_UP(req->offset + req->bytes, align)
55
+ uint64_t overlap_bytes = ROUND_UP(req->offset + req->bytes, align)
56
- overlap_offset;
57
58
if (!req->serialising) {
59
@@ -XXX,XX +XXX,XX @@ static int bdrv_get_cluster_size(BlockDriverState *bs)
60
}
61
62
static bool tracked_request_overlaps(BdrvTrackedRequest *req,
63
- int64_t offset, unsigned int bytes)
64
+ int64_t offset, uint64_t bytes)
65
{
66
/* aaaa bbbb */
67
if (offset >= req->overlap_offset + req->overlap_bytes) {
68
--
69
2.13.6
70
71
diff view generated by jsdifflib
Deleted patch
1
From: Fam Zheng <famz@redhat.com>
2
1
3
As a mechanical refactoring patch, this is the first step towards
4
unified and more correct write code paths. This is helpful because
5
multiple BlockDriverState fields need to be updated after modifying
6
image data, and it's hard to maintain in multiple places such as copy
7
offload, discard and truncate.
8
9
Suggested-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Fam Zheng <famz@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
13
block/io.c | 91 +++++++++++++++++++++++++++++++++++++++-----------------------
14
1 file changed, 57 insertions(+), 34 deletions(-)
15
16
diff --git a/block/io.c b/block/io.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/block/io.c
19
+++ b/block/io.c
20
@@ -XXX,XX +XXX,XX @@ fail:
21
return ret;
22
}
23
24
+static inline int coroutine_fn
25
+bdrv_co_write_req_prepare(BdrvChild *child, int64_t offset, uint64_t bytes,
26
+ BdrvTrackedRequest *req, int flags)
27
+{
28
+ BlockDriverState *bs = child->bs;
29
+ bool waited;
30
+ int64_t end_sector = DIV_ROUND_UP(offset + bytes, BDRV_SECTOR_SIZE);
31
+
32
+ if (bs->read_only) {
33
+ return -EPERM;
34
+ }
35
+
36
+ /* BDRV_REQ_NO_SERIALISING is only for read operation */
37
+ assert(!(flags & BDRV_REQ_NO_SERIALISING));
38
+ assert(!(bs->open_flags & BDRV_O_INACTIVE));
39
+ assert((bs->open_flags & BDRV_O_NO_IO) == 0);
40
+ assert(!(flags & ~BDRV_REQ_MASK));
41
+
42
+ if (flags & BDRV_REQ_SERIALISING) {
43
+ mark_request_serialising(req, bdrv_get_cluster_size(bs));
44
+ }
45
+
46
+ waited = wait_serialising_requests(req);
47
+
48
+ assert(!waited || !req->serialising ||
49
+ is_request_serialising_and_aligned(req));
50
+ assert(req->overlap_offset <= offset);
51
+ assert(offset + bytes <= req->overlap_offset + req->overlap_bytes);
52
+
53
+ if (flags & BDRV_REQ_WRITE_UNCHANGED) {
54
+ assert(child->perm & (BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE));
55
+ } else {
56
+ assert(child->perm & BLK_PERM_WRITE);
57
+ }
58
+ assert(end_sector <= bs->total_sectors || child->perm & BLK_PERM_RESIZE);
59
+ return notifier_with_return_list_notify(&bs->before_write_notifiers, req);
60
+}
61
+
62
+static inline void coroutine_fn
63
+bdrv_co_write_req_finish(BdrvChild *child, int64_t offset, uint64_t bytes,
64
+ BdrvTrackedRequest *req, int ret)
65
+{
66
+ int64_t end_sector = DIV_ROUND_UP(offset + bytes, BDRV_SECTOR_SIZE);
67
+ BlockDriverState *bs = child->bs;
68
+
69
+ atomic_inc(&bs->write_gen);
70
+ bdrv_set_dirty(bs, offset, bytes);
71
+
72
+ stat64_max(&bs->wr_highest_offset, offset + bytes);
73
+
74
+ if (ret == 0) {
75
+ bs->total_sectors = MAX(bs->total_sectors, end_sector);
76
+ }
77
+}
78
+
79
/*
80
* Forwards an already correctly aligned write request to the BlockDriver,
81
* after possibly fragmenting it.
82
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child,
83
{
84
BlockDriverState *bs = child->bs;
85
BlockDriver *drv = bs->drv;
86
- bool waited;
87
int ret;
88
89
- int64_t end_sector = DIV_ROUND_UP(offset + bytes, BDRV_SECTOR_SIZE);
90
uint64_t bytes_remaining = bytes;
91
int max_transfer;
92
93
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child,
94
assert((offset & (align - 1)) == 0);
95
assert((bytes & (align - 1)) == 0);
96
assert(!qiov || bytes == qiov->size);
97
- assert((bs->open_flags & BDRV_O_NO_IO) == 0);
98
- assert(!(flags & ~BDRV_REQ_MASK));
99
max_transfer = QEMU_ALIGN_DOWN(MIN_NON_ZERO(bs->bl.max_transfer, INT_MAX),
100
align);
101
102
- /* BDRV_REQ_NO_SERIALISING is only for read operation */
103
- assert(!(flags & BDRV_REQ_NO_SERIALISING));
104
-
105
- if (flags & BDRV_REQ_SERIALISING) {
106
- mark_request_serialising(req, bdrv_get_cluster_size(bs));
107
- }
108
-
109
- waited = wait_serialising_requests(req);
110
- assert(!waited || !req->serialising ||
111
- is_request_serialising_and_aligned(req));
112
- assert(req->overlap_offset <= offset);
113
- assert(offset + bytes <= req->overlap_offset + req->overlap_bytes);
114
- if (flags & BDRV_REQ_WRITE_UNCHANGED) {
115
- assert(child->perm & (BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE));
116
- } else {
117
- assert(child->perm & BLK_PERM_WRITE);
118
- }
119
- assert(end_sector <= bs->total_sectors || child->perm & BLK_PERM_RESIZE);
120
-
121
- ret = notifier_with_return_list_notify(&bs->before_write_notifiers, req);
122
+ ret = bdrv_co_write_req_prepare(child, offset, bytes, req, flags);
123
124
if (!ret && bs->detect_zeroes != BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF &&
125
!(flags & BDRV_REQ_ZERO_WRITE) && drv->bdrv_co_pwrite_zeroes &&
126
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child,
127
}
128
bdrv_debug_event(bs, BLKDBG_PWRITEV_DONE);
129
130
- atomic_inc(&bs->write_gen);
131
- bdrv_set_dirty(bs, offset, bytes);
132
-
133
- stat64_max(&bs->wr_highest_offset, offset + bytes);
134
-
135
if (ret >= 0) {
136
- bs->total_sectors = MAX(bs->total_sectors, end_sector);
137
ret = 0;
138
}
139
+ bdrv_co_write_req_finish(child, offset, bytes, req, ret);
140
141
return ret;
142
}
143
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pwritev(BdrvChild *child,
144
if (!bs->drv) {
145
return -ENOMEDIUM;
146
}
147
- if (bs->read_only) {
148
- return -EPERM;
149
- }
150
- assert(!(bs->open_flags & BDRV_O_INACTIVE));
151
152
ret = bdrv_check_byte_request(bs, offset, bytes);
153
if (ret < 0) {
154
--
155
2.13.6
156
157
diff view generated by jsdifflib
Deleted patch
1
From: Fam Zheng <famz@redhat.com>
2
1
3
Two problems exist when a write request that enlarges the image (i.e.
4
write beyond EOF) finishes:
5
6
1) parent is not notified about size change;
7
2) dirty bitmap is not resized although we try to set the dirty bits;
8
9
Fix them just like how bdrv_co_truncate works.
10
11
Reported-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Fam Zheng <famz@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
15
block/io.c | 10 +++++++---
16
1 file changed, 7 insertions(+), 3 deletions(-)
17
18
diff --git a/block/io.c b/block/io.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/block/io.c
21
+++ b/block/io.c
22
@@ -XXX,XX +XXX,XX @@
23
24
static AioWait drain_all_aio_wait;
25
26
+static void bdrv_parent_cb_resize(BlockDriverState *bs);
27
static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
28
int64_t offset, int bytes, BdrvRequestFlags flags);
29
30
@@ -XXX,XX +XXX,XX @@ bdrv_co_write_req_finish(BdrvChild *child, int64_t offset, uint64_t bytes,
31
BlockDriverState *bs = child->bs;
32
33
atomic_inc(&bs->write_gen);
34
- bdrv_set_dirty(bs, offset, bytes);
35
36
stat64_max(&bs->wr_highest_offset, offset + bytes);
37
38
- if (ret == 0) {
39
- bs->total_sectors = MAX(bs->total_sectors, end_sector);
40
+ if (ret == 0 &&
41
+ end_sector > bs->total_sectors) {
42
+ bs->total_sectors = end_sector;
43
+ bdrv_parent_cb_resize(bs);
44
+ bdrv_dirty_bitmap_truncate(bs, end_sector << BDRV_SECTOR_BITS);
45
}
46
+ bdrv_set_dirty(bs, offset, bytes);
47
}
48
49
/*
50
--
51
2.13.6
52
53
diff view generated by jsdifflib
Deleted patch
1
From: Fam Zheng <famz@redhat.com>
2
1
3
Reuse the new bdrv_co_write_req_prepare/finish helpers. The variation
4
here is that discard requests don't affect bs->wr_highest_offset, and it
5
cannot extend the image.
6
7
Signed-off-by: Fam Zheng <famz@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
10
block/io.c | 33 +++++++++++++++++++++++----------
11
1 file changed, 23 insertions(+), 10 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 @@ bdrv_co_write_req_finish(BdrvChild *child, int64_t offset, uint64_t bytes,
18
19
atomic_inc(&bs->write_gen);
20
21
- stat64_max(&bs->wr_highest_offset, offset + bytes);
22
-
23
+ /*
24
+ * Discard cannot extend the image, but in error handling cases, such as
25
+ * when reverting a qcow2 cluster allocation, the discarded range can pass
26
+ * the end of image file, so we cannot assert about BDRV_TRACKED_DISCARD
27
+ * here. Instead, just skip it, since semantically a discard request
28
+ * beyond EOF cannot expand the image anyway.
29
+ */
30
if (ret == 0 &&
31
- end_sector > bs->total_sectors) {
32
+ end_sector > bs->total_sectors &&
33
+ req->type != BDRV_TRACKED_DISCARD) {
34
bs->total_sectors = end_sector;
35
bdrv_parent_cb_resize(bs);
36
bdrv_dirty_bitmap_truncate(bs, end_sector << BDRV_SECTOR_BITS);
37
}
38
- bdrv_set_dirty(bs, offset, bytes);
39
+ if (req->bytes) {
40
+ switch (req->type) {
41
+ case BDRV_TRACKED_WRITE:
42
+ stat64_max(&bs->wr_highest_offset, offset + bytes);
43
+ /* fall through, to set dirty bits */
44
+ case BDRV_TRACKED_DISCARD:
45
+ bdrv_set_dirty(bs, offset, bytes);
46
+ break;
47
+ default:
48
+ break;
49
+ }
50
+ }
51
}
52
53
/*
54
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset, int bytes)
55
ret = bdrv_check_byte_request(bs, offset, bytes);
56
if (ret < 0) {
57
return ret;
58
- } else if (bs->read_only) {
59
- return -EPERM;
60
}
61
- assert(!(bs->open_flags & BDRV_O_INACTIVE));
62
63
/* Do nothing if disabled. */
64
if (!(bs->open_flags & BDRV_O_UNMAP)) {
65
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset, int bytes)
66
bdrv_inc_in_flight(bs);
67
tracked_request_begin(&req, bs, offset, bytes, BDRV_TRACKED_DISCARD);
68
69
- ret = notifier_with_return_list_notify(&bs->before_write_notifiers, &req);
70
+ ret = bdrv_co_write_req_prepare(child, offset, bytes, &req, 0);
71
if (ret < 0) {
72
goto out;
73
}
74
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset, int bytes)
75
}
76
ret = 0;
77
out:
78
- atomic_inc(&bs->write_gen);
79
- bdrv_set_dirty(bs, req.offset, req.bytes);
80
+ bdrv_co_write_req_finish(child, req.offset, req.bytes, &req, ret);
81
tracked_request_end(&req);
82
bdrv_dec_in_flight(bs);
83
return ret;
84
--
85
2.13.6
86
87
diff view generated by jsdifflib
Deleted patch
1
From: Fam Zheng <famz@redhat.com>
2
1
3
This brings the request handling logic inline with write and discard,
4
fixing write_gen, resize_cb, dirty bitmaps and image size refreshing.
5
The last of these issues broke iotest case 222, which is now fixed.
6
7
Signed-off-by: Fam Zheng <famz@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
10
block/io.c | 24 ++++++++++--------------
11
1 file changed, 10 insertions(+), 14 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 @@ static int coroutine_fn bdrv_co_copy_range_internal(
18
bdrv_inc_in_flight(dst->bs);
19
tracked_request_begin(&req, dst->bs, dst_offset, bytes,
20
BDRV_TRACKED_WRITE);
21
-
22
- /* BDRV_REQ_NO_SERIALISING is only for read operation */
23
- assert(!(write_flags & BDRV_REQ_NO_SERIALISING));
24
- if (write_flags & BDRV_REQ_SERIALISING) {
25
- mark_request_serialising(&req, bdrv_get_cluster_size(dst->bs));
26
- }
27
- wait_serialising_requests(&req);
28
-
29
- ret = dst->bs->drv->bdrv_co_copy_range_to(dst->bs,
30
- src, src_offset,
31
- dst, dst_offset,
32
- bytes,
33
- read_flags, write_flags);
34
-
35
+ ret = bdrv_co_write_req_prepare(dst, dst_offset, bytes, &req,
36
+ write_flags);
37
+ if (!ret) {
38
+ ret = dst->bs->drv->bdrv_co_copy_range_to(dst->bs,
39
+ src, src_offset,
40
+ dst, dst_offset,
41
+ bytes,
42
+ read_flags, write_flags);
43
+ }
44
+ bdrv_co_write_req_finish(dst, dst_offset, bytes, &req, ret);
45
tracked_request_end(&req);
46
bdrv_dec_in_flight(dst->bs);
47
}
48
--
49
2.13.6
50
51
diff view generated by jsdifflib
Deleted patch
1
From: Fam Zheng <famz@redhat.com>
2
1
3
If we are growing the image and potentially using preallocation for the
4
new area, we need to make sure that no write requests are made to the
5
"preallocated" area which is [@old_size, @offset), not
6
[@offset, offset * 2 - @old_size).
7
8
Signed-off-by: Fam Zheng <famz@redhat.com>
9
Reviewed-by: Eric Blake <eblake@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
12
block/io.c | 3 ++-
13
1 file changed, 2 insertions(+), 1 deletion(-)
14
15
diff --git a/block/io.c b/block/io.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/block/io.c
18
+++ b/block/io.c
19
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset,
20
}
21
22
bdrv_inc_in_flight(bs);
23
- tracked_request_begin(&req, bs, offset, new_bytes, BDRV_TRACKED_TRUNCATE);
24
+ tracked_request_begin(&req, bs, offset - new_bytes, new_bytes,
25
+ BDRV_TRACKED_TRUNCATE);
26
27
/* If we are growing the image and potentially using preallocation for the
28
* new area, we need to make sure that no write requests are made to it
29
--
30
2.13.6
31
32
diff view generated by jsdifflib
Deleted patch
1
From: Fam Zheng <famz@redhat.com>
2
1
3
Truncation is the last to convert from open coded req handling to
4
reusing helpers. This time the permission check in prepare has to adapt
5
to the new caller: it checks a different permission bit, and doesn't
6
trigger the before write notifier.
7
8
Also, truncation should always trigger a bs->total_sectors update and in
9
turn call parent resize_cb. Update the condition in finish helper, too.
10
11
It's intended to do a duplicated bs->read_only check before calling
12
bdrv_co_write_req_prepare() so that we can be more informative with the
13
error message, as bdrv_co_write_req_prepare() doesn't have Error
14
parameter.
15
16
Signed-off-by: Fam Zheng <famz@redhat.com>
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
---
19
block/io.c | 55 +++++++++++++++++++++++++++++++++++--------------------
20
1 file changed, 35 insertions(+), 20 deletions(-)
21
22
diff --git a/block/io.c b/block/io.c
23
index XXXXXXX..XXXXXXX 100644
24
--- a/block/io.c
25
+++ b/block/io.c
26
@@ -XXX,XX +XXX,XX @@ bdrv_co_write_req_prepare(BdrvChild *child, int64_t offset, uint64_t bytes,
27
is_request_serialising_and_aligned(req));
28
assert(req->overlap_offset <= offset);
29
assert(offset + bytes <= req->overlap_offset + req->overlap_bytes);
30
+ assert(end_sector <= bs->total_sectors || child->perm & BLK_PERM_RESIZE);
31
32
- if (flags & BDRV_REQ_WRITE_UNCHANGED) {
33
- assert(child->perm & (BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE));
34
- } else {
35
- assert(child->perm & BLK_PERM_WRITE);
36
+ switch (req->type) {
37
+ case BDRV_TRACKED_WRITE:
38
+ case BDRV_TRACKED_DISCARD:
39
+ if (flags & BDRV_REQ_WRITE_UNCHANGED) {
40
+ assert(child->perm & (BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE));
41
+ } else {
42
+ assert(child->perm & BLK_PERM_WRITE);
43
+ }
44
+ return notifier_with_return_list_notify(&bs->before_write_notifiers,
45
+ req);
46
+ case BDRV_TRACKED_TRUNCATE:
47
+ assert(child->perm & BLK_PERM_RESIZE);
48
+ return 0;
49
+ default:
50
+ abort();
51
}
52
- assert(end_sector <= bs->total_sectors || child->perm & BLK_PERM_RESIZE);
53
- return notifier_with_return_list_notify(&bs->before_write_notifiers, req);
54
}
55
56
static inline void coroutine_fn
57
@@ -XXX,XX +XXX,XX @@ bdrv_co_write_req_finish(BdrvChild *child, int64_t offset, uint64_t bytes,
58
* beyond EOF cannot expand the image anyway.
59
*/
60
if (ret == 0 &&
61
- end_sector > bs->total_sectors &&
62
- req->type != BDRV_TRACKED_DISCARD) {
63
+ (req->type == BDRV_TRACKED_TRUNCATE ||
64
+ end_sector > bs->total_sectors) &&
65
+ req->type != BDRV_TRACKED_DISCARD) {
66
bs->total_sectors = end_sector;
67
bdrv_parent_cb_resize(bs);
68
bdrv_dirty_bitmap_truncate(bs, end_sector << BDRV_SECTOR_BITS);
69
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset,
70
int64_t old_size, new_bytes;
71
int ret;
72
73
- assert(child->perm & BLK_PERM_RESIZE);
74
75
/* if bs->drv == NULL, bs is closed, so there's nothing to do here */
76
if (!drv) {
77
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset,
78
* concurrently or they might be overwritten by preallocation. */
79
if (new_bytes) {
80
mark_request_serialising(&req, 1);
81
- wait_serialising_requests(&req);
82
+ }
83
+ if (bs->read_only) {
84
+ error_setg(errp, "Image is read-only");
85
+ ret = -EACCES;
86
+ goto out;
87
+ }
88
+ ret = bdrv_co_write_req_prepare(child, offset - new_bytes, new_bytes, &req,
89
+ 0);
90
+ if (ret < 0) {
91
+ error_setg_errno(errp, -ret,
92
+ "Failed to prepare request for truncation");
93
+ goto out;
94
}
95
96
if (!drv->bdrv_co_truncate) {
97
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset,
98
ret = -ENOTSUP;
99
goto out;
100
}
101
- if (bs->read_only) {
102
- error_setg(errp, "Image is read-only");
103
- ret = -EACCES;
104
- goto out;
105
- }
106
-
107
- assert(!(bs->open_flags & BDRV_O_INACTIVE));
108
109
ret = drv->bdrv_co_truncate(bs, offset, prealloc, errp);
110
if (ret < 0) {
111
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset,
112
} else {
113
offset = bs->total_sectors * BDRV_SECTOR_SIZE;
114
}
115
- bdrv_dirty_bitmap_truncate(bs, offset);
116
- bdrv_parent_cb_resize(bs);
117
- atomic_inc(&bs->write_gen);
118
+ /* It's possible that truncation succeeded but refresh_total_sectors
119
+ * failed, but the latter doesn't affect how we should finish the request.
120
+ * Pass 0 as the last parameter so that dirty bitmaps etc. are handled. */
121
+ bdrv_co_write_req_finish(child, offset - new_bytes, new_bytes, &req, 0);
122
123
out:
124
tracked_request_end(&req);
125
--
126
2.13.6
127
128
diff view generated by jsdifflib