1
The following changes since commit b34181056c04e05db6c632063012beaee7006a37:
1
The following changes since commit 47c1cc30e440860aa695358f7c2dd0b9d7b53d16:
2
2
3
Merge remote-tracking branch 'remotes/rth/tags/pull-sh4-20180709' into staging (2018-07-09 22:44:22 +0100)
3
Update version for v3.1.0-rc2 release (2018-11-20 18:10:26 +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 924956b1efc50af7cc334b7a14f56aa213ca27ef:
10
10
11
block: Use common write req handling in truncate (2018-07-10 16:46:22 +0200)
11
iotests: Enhance 223 to cover multiple bitmap granularities (2018-11-22 16:43:52 +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
- block: Fix update of BDRV_O_AUTO_RDONLY in update_flags_from_options()
17
- Temporary revert of the removal of deprecated -drive options
17
- qemu-img: Fix memory leak and typo in error message
18
- Fix request serialisation in the image fleecing scenario
18
- nvme: Fixes for lockups and crashes
19
- Fix copy-on-read crash with unaligned image size
19
- scsi-disk: Fix crash if underlying host file or disk returns error
20
- Fix another drain crash
20
- Several qemu-iotests fixes and improvements
21
21
22
----------------------------------------------------------------
22
----------------------------------------------------------------
23
Ari Sundholm (2):
23
Alberto Garcia (1):
24
qapi/block-core.json: Add missing documentation for blklogwrites log-append option
24
block: Fix update of BDRV_O_AUTO_RDONLY in update_flags_from_options()
25
block/blklogwrites: Make sure the log sector size is not too small
26
25
27
Cornelia Huck (4):
26
Daniel P. Berrangé (1):
28
Revert "block: Remove dead deprecation warning code"
27
iotests: fix nbd test 233 to work correctly with raw images
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
28
33
Fam Zheng (11):
29
Eric Blake (2):
34
iotests: 222: Don't run with luks
30
iotests: Skip 233 if certtool not installed
35
block: Prefix file driver trace points with "file_"
31
iotests: Enhance 223 to cover multiple bitmap granularities
36
block: Add copy offloading trace points
32
37
block: Use BdrvChild to discard
33
Igor Druzhinin (1):
38
block: Use uint64_t for BdrvTrackedRequest byte fields
34
nvme: call blk_drain in NVMe reset code to avoid lockups
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
35
46
Kevin Wolf (3):
36
Kevin Wolf (3):
47
block: Poll after drain on attaching a node
37
iotests: Replace time.clock() with Timeout
48
test-bdrv-drain: Test bdrv_append() to drained node
38
iotests: Replace assertEquals() with assertEqual()
49
block: Fix copy-on-read crash with partial final cluster
39
Revert "nvme: fix oob access issue(CVE-2018-16847)"
50
40
51
Vladimir Sementsov-Ogievskiy (4):
41
Logan Gunthorpe (1):
52
block/io: fix copy_range
42
nvme: fix bug with PCI IRQ pins on teardown
53
block: split flags in copy_range
54
block: add BDRV_REQ_SERIALISING flag
55
block/backup: fix fleecing scheme: use serialized writes
56
43
57
qapi/block-core.json | 2 +
44
Max Reitz (2):
58
include/block/block.h | 41 +++++-
45
qemu-img: Fix typo
59
include/block/block_int.h | 21 ++-
46
qemu-img: Fix leak
60
include/hw/block/block.h | 1 +
61
include/sysemu/block-backend.h | 3 +-
62
include/sysemu/blockdev.h | 3 +
63
block.c | 2 +-
64
block/backup.c | 20 ++-
65
block/blkdebug.c | 2 +-
66
block/blklogwrites.c | 7 +-
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
47
48
Paolo Bonzini (1):
49
nvme: fix out-of-bounds access to the CMB
50
51
Richard W.M. Jones (1):
52
scsi-disk: Fix crash if underlying host file or disk returns error
53
54
block.c | 4 +--
55
hw/block/nvme.c | 12 +++-----
56
hw/scsi/scsi-disk.c | 2 +-
57
qemu-img.c | 3 +-
58
tests/nvme-test.c | 68 ++++++++++++++++++++++++++++++++++++-------
59
tests/Makefile.include | 2 +-
60
tests/qemu-iotests/041 | 6 ++--
61
tests/qemu-iotests/118 | 20 +++++--------
62
tests/qemu-iotests/223 | 43 ++++++++++++++++++++++-----
63
tests/qemu-iotests/223.out | 32 +++++++++++++++-----
64
tests/qemu-iotests/233 | 9 ++++--
65
tests/qemu-iotests/common.tls | 3 ++
66
tests/qemu-iotests/iotests.py | 2 +-
67
13 files changed, 148 insertions(+), 58 deletions(-)
68
diff view generated by jsdifflib
1
From: Fam Zheng <famz@redhat.com>
1
time.clock() is deprecated since Python 3.3. Current Python versions
2
warn that the function will be removed in Python 3.8, and those warnings
3
make the test case 118 fail.
2
4
3
Truncation is the last to convert from open coded req handling to
5
Replace it with the Timeout mechanism that is compatible with both
4
reusing helpers. This time the permission check in prepare has to adapt
6
Python 2 and 3, and makes the code even a little nicer.
5
to the new caller: it checks a different permission bit, and doesn't
6
trigger the before write notifier.
7
7
8
Also, truncation should always trigger a bs->total_sectors update and in
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
turn call parent resize_cb. Update the condition in finish helper, too.
9
Reviewed-by: John Snow <jsnow@redhat.com>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
---
12
tests/qemu-iotests/118 | 16 ++++++----------
13
1 file changed, 6 insertions(+), 10 deletions(-)
10
14
11
It's intended to do a duplicated bs->read_only check before calling
15
diff --git a/tests/qemu-iotests/118 b/tests/qemu-iotests/118
12
bdrv_co_write_req_prepare() so that we can be more informative with the
16
index XXXXXXX..XXXXXXX 100755
13
error message, as bdrv_co_write_req_prepare() doesn't have Error
17
--- a/tests/qemu-iotests/118
14
parameter.
18
+++ b/tests/qemu-iotests/118
15
19
@@ -XXX,XX +XXX,XX @@ class ChangeBaseClass(iotests.QMPTestCase):
16
Signed-off-by: Fam Zheng <famz@redhat.com>
20
if not self.has_real_tray:
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
21
return
18
---
22
19
block/io.c | 55 +++++++++++++++++++++++++++++++++++--------------------
23
- timeout = time.clock() + 3
20
1 file changed, 35 insertions(+), 20 deletions(-)
24
- while not self.has_opened and time.clock() < timeout:
21
25
- self.process_events()
22
diff --git a/block/io.c b/block/io.c
26
- if not self.has_opened:
23
index XXXXXXX..XXXXXXX 100644
27
- self.fail('Timeout while waiting for the tray to open')
24
--- a/block/io.c
28
+ with iotests.Timeout(3, 'Timeout while waiting for the tray to open'):
25
+++ b/block/io.c
29
+ while not self.has_opened:
26
@@ -XXX,XX +XXX,XX @@ bdrv_co_write_req_prepare(BdrvChild *child, int64_t offset, uint64_t bytes,
30
+ self.process_events()
27
is_request_serialising_and_aligned(req));
31
28
assert(req->overlap_offset <= offset);
32
def wait_for_close(self):
29
assert(offset + bytes <= req->overlap_offset + req->overlap_bytes);
33
if not self.has_real_tray:
30
+ assert(end_sector <= bs->total_sectors || child->perm & BLK_PERM_RESIZE);
34
return
31
35
32
- if (flags & BDRV_REQ_WRITE_UNCHANGED) {
36
- timeout = time.clock() + 3
33
- assert(child->perm & (BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE));
37
- while not self.has_closed and time.clock() < timeout:
34
- } else {
38
- self.process_events()
35
- assert(child->perm & BLK_PERM_WRITE);
39
- if not self.has_opened:
36
+ switch (req->type) {
40
- self.fail('Timeout while waiting for the tray to close')
37
+ case BDRV_TRACKED_WRITE:
41
+ with iotests.Timeout(3, 'Timeout while waiting for the tray to close'):
38
+ case BDRV_TRACKED_DISCARD:
42
+ while not self.has_closed:
39
+ if (flags & BDRV_REQ_WRITE_UNCHANGED) {
43
+ self.process_events()
40
+ assert(child->perm & (BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE));
44
41
+ } else {
45
class GeneralChangeTestsBaseClass(ChangeBaseClass):
42
+ assert(child->perm & BLK_PERM_WRITE);
46
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
--
47
--
126
2.13.6
48
2.19.1
127
49
128
50
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
TestCase.assertEquals() is deprecated since Python 2.7. Recent Python
2
versions print a warning when the function is called, which makes test
3
cases fail.
2
4
3
Here two things are fixed:
5
Replace it with the preferred spelling assertEqual().
4
6
5
1. Architecture
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Reviewed-by: John Snow <jsnow@redhat.com>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
---
11
tests/qemu-iotests/041 | 6 +++---
12
tests/qemu-iotests/118 | 4 ++--
13
tests/qemu-iotests/iotests.py | 2 +-
14
3 files changed, 6 insertions(+), 6 deletions(-)
6
15
7
On each recursion step, we go to the child of src or dst, only for one
16
diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041
8
of them. So, it's wrong to create tracked requests for both on each
17
index XXXXXXX..XXXXXXX 100755
9
step. It leads to tracked requests duplication.
18
--- a/tests/qemu-iotests/041
10
19
+++ b/tests/qemu-iotests/041
11
2. Wait for serializing requests on write path independently of
20
@@ -XXX,XX +XXX,XX @@ new_state = "1"
12
BDRV_REQ_NO_SERIALISING
21
self.assert_qmp(event, 'data/id', 'drive0')
13
22
event = self.vm.get_qmp_event(wait=True)
14
Before commit 9ded4a01149 "backup: Use copy offloading",
23
15
BDRV_REQ_NO_SERIALISING was used for only one case: read in
24
- self.assertEquals(event['event'], 'BLOCK_JOB_ERROR')
16
copy-on-write operation during backup. Also, the flag was handled only
25
+ self.assertEqual(event['event'], 'BLOCK_JOB_ERROR')
17
on read path (in bdrv_co_preadv and bdrv_aligned_preadv).
26
self.assert_qmp(event, 'data/device', 'drive0')
18
27
self.assert_qmp(event, 'data/operation', 'read')
19
After 9ded4a01149, flag is used for not waiting serializing operations
28
result = self.vm.qmp('query-block-jobs')
20
on backup target (in same case of copy-on-write operation). This
29
@@ -XXX,XX +XXX,XX @@ new_state = "1"
21
behavior change is unsubstantiated and potentially dangerous, let's
30
self.assert_qmp(event, 'data/id', 'drive0')
22
drop it and add additional asserts and documentation.
31
event = self.vm.get_qmp_event(wait=True)
23
32
24
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
33
- self.assertEquals(event['event'], 'BLOCK_JOB_ERROR')
25
Reviewed-by: Fam Zheng <famz@redhat.com>
34
+ self.assertEqual(event['event'], 'BLOCK_JOB_ERROR')
26
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
35
self.assert_qmp(event, 'data/device', 'drive0')
27
---
36
self.assert_qmp(event, 'data/operation', 'read')
28
include/block/block.h | 12 ++++++++++++
37
result = self.vm.qmp('query-block-jobs')
29
block/io.c | 42 +++++++++++++++++++++++++++---------------
38
@@ -XXX,XX +XXX,XX @@ new_state = "1"
30
2 files changed, 39 insertions(+), 15 deletions(-)
39
self.assert_qmp(result, 'return', {})
31
40
32
diff --git a/include/block/block.h b/include/block/block.h
41
event = self.vm.event_wait(name='BLOCK_JOB_ERROR')
42
- self.assertEquals(event['event'], 'BLOCK_JOB_ERROR')
43
+ self.assertEqual(event['event'], 'BLOCK_JOB_ERROR')
44
self.assert_qmp(event, 'data/device', 'drive0')
45
self.assert_qmp(event, 'data/operation', 'write')
46
result = self.vm.qmp('query-block-jobs')
47
diff --git a/tests/qemu-iotests/118 b/tests/qemu-iotests/118
48
index XXXXXXX..XXXXXXX 100755
49
--- a/tests/qemu-iotests/118
50
+++ b/tests/qemu-iotests/118
51
@@ -XXX,XX +XXX,XX @@ class GeneralChangeTestsBaseClass(ChangeBaseClass):
52
result = self.vm.qmp('blockdev-close-tray', id=self.device_name)
53
# Should be a no-op
54
self.assert_qmp(result, 'return', {})
55
- self.assertEquals(self.vm.get_qmp_events(wait=False), [])
56
+ self.assertEqual(self.vm.get_qmp_events(wait=False), [])
57
58
def test_remove_on_closed(self):
59
if not self.has_real_tray:
60
@@ -XXX,XX +XXX,XX @@ class TestChangeReadOnly(ChangeBaseClass):
61
read_only_mode='retain')
62
self.assert_qmp(result, 'error/class', 'GenericError')
63
64
- self.assertEquals(self.vm.get_qmp_events(wait=False), [])
65
+ self.assertEqual(self.vm.get_qmp_events(wait=False), [])
66
67
result = self.vm.qmp('query-block')
68
self.assert_qmp(result, 'return[0]/inserted/ro', False)
69
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
33
index XXXXXXX..XXXXXXX 100644
70
index XXXXXXX..XXXXXXX 100644
34
--- a/include/block/block.h
71
--- a/tests/qemu-iotests/iotests.py
35
+++ b/include/block/block.h
72
+++ b/tests/qemu-iotests/iotests.py
36
@@ -XXX,XX +XXX,XX @@ typedef enum {
73
@@ -XXX,XX +XXX,XX @@ class QMPTestCase(unittest.TestCase):
37
* opened with BDRV_O_UNMAP.
74
def wait_ready_and_cancel(self, drive='drive0'):
38
*/
75
self.wait_ready(drive=drive)
39
BDRV_REQ_MAY_UNMAP = 0x4,
76
event = self.cancel_and_wait(drive=drive)
40
+
77
- self.assertEquals(event['event'], 'BLOCK_JOB_COMPLETED')
41
+ /*
78
+ self.assertEqual(event['event'], 'BLOCK_JOB_COMPLETED')
42
+ * The BDRV_REQ_NO_SERIALISING flag is only valid for reads and means that
79
self.assert_qmp(event, 'data/type', 'mirror')
43
+ * we don't want wait_serialising_requests() during the read operation.
80
self.assert_qmp(event, 'data/offset', event['data']['len'])
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
81
134
--
82
--
135
2.13.6
83
2.19.1
136
84
137
85
diff view generated by jsdifflib
1
From: Fam Zheng <famz@redhat.com>
1
From: Eric Blake <eblake@redhat.com>
2
2
3
Two problems exist when a write request that enlarges the image (i.e.
3
The use of TLS while building qemu is optional. While the
4
write beyond EOF) finishes:
4
'certtool' binary should be available on every platform that
5
5
supports building against TLS, that does not imply that the
6
1) parent is not notified about size change;
6
developer has installed it. Make the test gracefully skip
7
2) dirty bitmap is not resized although we try to set the dirty bits;
7
in that case.
8
9
Fix them just like how bdrv_co_truncate works.
10
8
11
Reported-by: Kevin Wolf <kwolf@redhat.com>
9
Reported-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Fam Zheng <famz@redhat.com>
10
Signed-off-by: Eric Blake <eblake@redhat.com>
11
Reviewed-by: John Snow <jsnow@redhat.com>
12
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
13
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
15
---
15
block/io.c | 10 +++++++---
16
tests/qemu-iotests/common.tls | 3 +++
16
1 file changed, 7 insertions(+), 3 deletions(-)
17
1 file changed, 3 insertions(+)
17
18
18
diff --git a/block/io.c b/block/io.c
19
diff --git a/tests/qemu-iotests/common.tls b/tests/qemu-iotests/common.tls
19
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
20
--- a/block/io.c
21
--- a/tests/qemu-iotests/common.tls
21
+++ b/block/io.c
22
+++ b/tests/qemu-iotests/common.tls
22
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@ tls_x509_cleanup()
23
24
24
static AioWait drain_all_aio_wait;
25
tls_x509_init()
25
26
{
26
+static void bdrv_parent_cb_resize(BlockDriverState *bs);
27
+ (certtool --help) >/dev/null 2>&1 || \
27
static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
28
+    _notrun "certtool utility not found, skipping test"
28
int64_t offset, int bytes, BdrvRequestFlags flags);
29
+
29
30
mkdir -p "${tls_dir}"
30
@@ -XXX,XX +XXX,XX @@ bdrv_co_write_req_finish(BdrvChild *child, int64_t offset, uint64_t bytes,
31
31
BlockDriverState *bs = child->bs;
32
# use a fixed key so we don't waste system entropy on
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
--
33
--
51
2.13.6
34
2.19.1
52
35
53
36
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
Pass read flags and write flags separately. This is needed to handle
3
Fixes: d402b6a21a825a5c07aac9251990860723d49f5d
4
coming BDRV_REQ_NO_SERIALISING clearly in following patches.
4
Reported-by: Kevin Wolf <kwolf@redhat.com>
5
5
Cc: qemu-stable@nongnu.org
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Reviewed-by: Fam Zheng <famz@redhat.com>
7
Reviewed-by: John Snow <jsnow@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
9
---
10
include/block/block.h | 3 ++-
10
qemu-img.c | 2 +-
11
include/block/block_int.h | 14 +++++++++----
11
1 file changed, 1 insertion(+), 1 deletion(-)
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
12
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
13
diff --git a/qemu-img.c b/qemu-img.c
436
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
437
--- a/qemu-img.c
15
--- a/qemu-img.c
438
+++ b/qemu-img.c
16
+++ b/qemu-img.c
439
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn convert_co_copy_range(ImgConvertState *s, int64_t sector
17
@@ -XXX,XX +XXX,XX @@ static int print_block_option_help(const char *filename, const char *fmt)
440
18
return 1;
441
ret = blk_co_copy_range(blk, offset, s->target,
19
}
442
sector_num << BDRV_SECTOR_BITS,
20
if (!proto_drv->create_opts) {
443
- n << BDRV_SECTOR_BITS, 0);
21
- error_report("Protocal driver '%s' does not support image creation",
444
+ n << BDRV_SECTOR_BITS, 0, 0);
22
+ error_report("Protocol driver '%s' does not support image creation",
445
if (ret < 0) {
23
proto_drv->format_name);
446
return ret;
24
return 1;
447
}
25
}
448
--
26
--
449
2.13.6
27
2.19.1
450
28
451
29
diff view generated by jsdifflib
1
From: Fam Zheng <famz@redhat.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
If we are growing the image and potentially using preallocation for the
3
create_opts was leaked here. This is not too bad since the process is
4
new area, we need to make sure that no write requests are made to the
4
about to exit anyway, but relying on that does not make the code nicer
5
"preallocated" area which is [@old_size, @offset), not
5
to read.
6
[@offset, offset * 2 - @old_size).
7
6
8
Signed-off-by: Fam Zheng <famz@redhat.com>
7
Fixes: d402b6a21a825a5c07aac9251990860723d49f5d
9
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Reported-by: Kevin Wolf <kwolf@redhat.com>
9
Cc: qemu-stable@nongnu.org
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
Reviewed-by: John Snow <jsnow@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
13
---
12
block/io.c | 3 ++-
14
qemu-img.c | 1 +
13
1 file changed, 2 insertions(+), 1 deletion(-)
15
1 file changed, 1 insertion(+)
14
16
15
diff --git a/block/io.c b/block/io.c
17
diff --git a/qemu-img.c b/qemu-img.c
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/block/io.c
19
--- a/qemu-img.c
18
+++ b/block/io.c
20
+++ b/qemu-img.c
19
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset,
21
@@ -XXX,XX +XXX,XX @@ static int print_block_option_help(const char *filename, const char *fmt)
20
}
22
if (!proto_drv->create_opts) {
21
23
error_report("Protocol driver '%s' does not support image creation",
22
bdrv_inc_in_flight(bs);
24
proto_drv->format_name);
23
- tracked_request_begin(&req, bs, offset, new_bytes, BDRV_TRACKED_TRUNCATE);
25
+ qemu_opts_free(create_opts);
24
+ tracked_request_begin(&req, bs, offset - new_bytes, new_bytes,
26
return 1;
25
+ BDRV_TRACKED_TRUNCATE);
27
}
26
28
create_opts = qemu_opts_append(create_opts, proto_drv->create_opts);
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
--
29
--
30
2.13.6
30
2.19.1
31
31
32
32
diff view generated by jsdifflib
1
From: Fam Zheng <famz@redhat.com>
1
From: "Richard W.M. Jones" <rjones@redhat.com>
2
2
3
Reuse the new bdrv_co_write_req_prepare/finish helpers. The variation
3
Commit 40dce4ee6 "scsi-disk: fix rerror/werror=ignore" introduced a
4
here is that discard requests don't affect bs->wr_highest_offset, and it
4
bug which causes qemu to crash with the assertion error below if the
5
cannot extend the image.
5
host file or disk returns an error:
6
6
7
Signed-off-by: Fam Zheng <famz@redhat.com>
7
qemu-system-x86_64: hw/scsi/scsi-bus.c:1374: scsi_req_complete:
8
Assertion `req->status == -1' failed.
9
10
Kevin Wolf suggested this fix:
11
12
< kwolf> Hm, should the final return false; in that patch
13
actually be a return true?
14
< kwolf> Because I think he didn't intend to change anything
15
except BLOCK_ERROR_ACTION_IGNORE
16
17
Buglink: https://bugs.launchpad.net/qemu/+bug/1804323
18
Fixes: 40dce4ee61c68395f6d463fae792f61b7c003bce
19
Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
20
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
21
---
10
block/io.c | 33 +++++++++++++++++++++++----------
22
hw/scsi/scsi-disk.c | 2 +-
11
1 file changed, 23 insertions(+), 10 deletions(-)
23
1 file changed, 1 insertion(+), 1 deletion(-)
12
24
13
diff --git a/block/io.c b/block/io.c
25
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
14
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
15
--- a/block/io.c
27
--- a/hw/scsi/scsi-disk.c
16
+++ b/block/io.c
28
+++ b/hw/scsi/scsi-disk.c
17
@@ -XXX,XX +XXX,XX @@ bdrv_co_write_req_finish(BdrvChild *child, int64_t offset, uint64_t bytes,
29
@@ -XXX,XX +XXX,XX @@ static bool scsi_handle_rw_error(SCSIDiskReq *r, int error, bool acct_failed)
18
30
if (action == BLOCK_ERROR_ACTION_STOP) {
19
atomic_inc(&bs->write_gen);
31
scsi_req_retry(&r->req);
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
}
32
}
38
- bdrv_set_dirty(bs, offset, bytes);
33
- return false;
39
+ if (req->bytes) {
34
+ return true;
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
}
35
}
52
36
53
/*
37
static void scsi_write_complete_noio(SCSIDiskReq *r, int ret)
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
--
38
--
85
2.13.6
39
2.19.1
86
40
87
41
diff view generated by jsdifflib
1
Commit dcf94a23b1 ('block: Don't poll in parent drain callbacks')
1
From: Alberto Garcia <berto@igalia.com>
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
2
7
This reasoning is correct for calls through bdrv_do_drained_begin().
3
Commit e35bdc123a4ace9f4d3fcca added the auto-read-only option and the
8
However, BdrvChildRole.drained_begin is also called when a node that is
4
code to update its corresponding flag in update_flags_from_options(),
9
already in a drained section (i.e. bdrv_do_drained_begin() has already
5
but forgot to clear the flag if auto-read-only is false.
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
6
14
In bdrv_replace_child_noperm(), we know that we're not inside the
7
Signed-off-by: Alberto Garcia <berto@igalia.com>
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>
8
Reported-by: Max Reitz <mreitz@redhat.com>
21
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
22
---
10
---
23
include/block/block.h | 8 ++++++++
11
block.c | 4 +---
24
include/block/block_int.h | 3 +++
12
1 file changed, 1 insertion(+), 3 deletions(-)
25
block.c | 2 +-
26
block/io.c | 26 ++++++++++++++++++++------
27
4 files changed, 32 insertions(+), 7 deletions(-)
28
13
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
14
diff --git a/block.c b/block.c
63
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
64
--- a/block.c
16
--- a/block.c
65
+++ b/block.c
17
+++ b/block.c
66
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child_noperm(BdrvChild *child,
18
@@ -XXX,XX +XXX,XX @@ static int bdrv_open_flags(BlockDriverState *bs, int flags)
67
}
19
68
assert(num >= 0);
20
static void update_flags_from_options(int *flags, QemuOpts *opts)
69
for (i = 0; i < num; i++) {
21
{
70
- child->role->drained_begin(child);
22
- *flags &= ~BDRV_O_CACHE_MASK;
71
+ bdrv_parent_drained_begin_single(child, true);
23
+ *flags &= ~(BDRV_O_CACHE_MASK | BDRV_O_RDWR | BDRV_O_AUTO_RDONLY);
72
}
24
73
}
25
assert(qemu_opt_find(opts, BDRV_OPT_CACHE_NO_FLUSH));
74
26
if (qemu_opt_get_bool_del(opts, BDRV_OPT_CACHE_NO_FLUSH, false)) {
75
diff --git a/block/io.c b/block/io.c
27
@@ -XXX,XX +XXX,XX @@ static void update_flags_from_options(int *flags, QemuOpts *opts)
76
index XXXXXXX..XXXXXXX 100644
28
*flags |= BDRV_O_NOCACHE;
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
}
29
}
88
}
30
89
31
- *flags &= ~BDRV_O_RDWR;
90
@@ -XXX,XX +XXX,XX @@ void bdrv_parent_drained_end(BlockDriverState *bs, BdrvChild *ignore,
32
-
91
}
33
assert(qemu_opt_find(opts, BDRV_OPT_READ_ONLY));
92
}
34
if (!qemu_opt_get_bool_del(opts, BDRV_OPT_READ_ONLY, false)) {
93
35
*flags |= BDRV_O_RDWR;
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
--
36
--
132
2.13.6
37
2.19.1
133
38
134
39
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
1
From: Ari Sundholm <ari@tuxera.com>
1
From: Daniel P. Berrangé <berrange@redhat.com>
2
2
3
This was accidentally omitted. Thanks to Eric Blake for spotting this.
3
The first qemu-io command must honour the $IMGFMT that is set rather
4
than hardcoding qcow2. The qemu-nbd commands should also set $IMGFMT
5
to avoid the insecure format probe warning.
4
6
5
Signed-off-by: Ari Sundholm <ari@tuxera.com>
7
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
6
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Reviewed-by: Eric Blake <eblake@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
10
---
9
qapi/block-core.json | 2 ++
11
tests/qemu-iotests/233 | 9 ++++++---
10
1 file changed, 2 insertions(+)
12
1 file changed, 6 insertions(+), 3 deletions(-)
11
13
12
diff --git a/qapi/block-core.json b/qapi/block-core.json
14
diff --git a/tests/qemu-iotests/233 b/tests/qemu-iotests/233
13
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100755
14
--- a/qapi/block-core.json
16
--- a/tests/qemu-iotests/233
15
+++ b/qapi/block-core.json
17
+++ b/tests/qemu-iotests/233
16
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c 'w -P 0x11 1m 1m' "$TEST_IMG" | _filter_qemu_io
17
# @log-sector-size: sector size used in logging writes to @file, determines
19
18
# granularity of offsets and sizes of writes (default: 512)
20
echo
19
#
21
echo "== check TLS client to plain server fails =="
20
+# @log-append: append to an existing log (default: false)
22
-nbd_server_start_tcp_socket "$TEST_IMG"
21
+#
23
+nbd_server_start_tcp_socket -f $IMGFMT "$TEST_IMG"
22
# @log-super-update-interval: interval of write requests after which the log
24
23
# super block is updated to disk (default: 4096)
25
$QEMU_IMG info --image-opts \
24
#
26
--object tls-creds-x509,dir=${tls_dir}/client1,endpoint=client,id=tls0 \
27
@@ -XXX,XX +XXX,XX @@ nbd_server_stop
28
echo
29
echo "== check plain client to TLS server fails =="
30
31
-nbd_server_start_tcp_socket --object tls-creds-x509,dir=${tls_dir}/server1,endpoint=server,id=tls0,verify-peer=yes --tls-creds tls0 "$TEST_IMG"
32
+nbd_server_start_tcp_socket \
33
+ --object tls-creds-x509,dir=${tls_dir}/server1,endpoint=server,id=tls0,verify-peer=yes \
34
+ --tls-creds tls0 \
35
+ -f $IMGFMT "$TEST_IMG"
36
37
$QEMU_IMG info nbd://localhost:$nbd_tcp_port 2>&1 | sed "s/$nbd_tcp_port/PORT/g"
38
39
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c 'r -P 0x11 1m 1m' -c 'w -P 0x22 1m 1m' --image-opts \
40
driver=nbd,host=$nbd_tcp_addr,port=$nbd_tcp_port,tls-creds=tls0 \
41
2>&1 | _filter_qemu_io
42
43
-$QEMU_IO -f qcow2 -r -U -c 'r -P 0x22 1m 1m' "$TEST_IMG" | _filter_qemu_io
44
+$QEMU_IO -f $IMGFMT -r -U -c 'r -P 0x22 1m 1m' "$TEST_IMG" | _filter_qemu_io
45
46
# success, all done
47
echo "*** done"
25
--
48
--
26
2.13.6
49
2.19.1
27
50
28
51
diff view generated by jsdifflib
1
From: Fam Zheng <famz@redhat.com>
1
From: Igor Druzhinin <igor.druzhinin@citrix.com>
2
2
3
Luks needs special parameters to operate the image. Since this test is
3
When blk_flush called in NVMe reset path S/C queues are already freed
4
focusing on image fleecing, skip skip that format.
4
which means that re-entering AIO handling loop having some IO requests
5
unfinished will lockup or crash as their SG structures being potentially
6
reused. Call blk_drain before freeing the queues to avoid this nasty
7
scenario.
5
8
6
Signed-off-by: Fam Zheng <famz@redhat.com>
9
Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>
10
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
12
---
9
tests/qemu-iotests/222 | 2 ++
13
hw/block/nvme.c | 2 ++
10
1 file changed, 2 insertions(+)
14
1 file changed, 2 insertions(+)
11
15
12
diff --git a/tests/qemu-iotests/222 b/tests/qemu-iotests/222
16
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
13
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
14
--- a/tests/qemu-iotests/222
18
--- a/hw/block/nvme.c
15
+++ b/tests/qemu-iotests/222
19
+++ b/hw/block/nvme.c
16
@@ -XXX,XX +XXX,XX @@ import iotests
20
@@ -XXX,XX +XXX,XX @@ static void nvme_clear_ctrl(NvmeCtrl *n)
17
from iotests import log, qemu_img, qemu_io, qemu_io_silent
21
{
18
22
int i;
19
iotests.verify_platform(['linux'])
23
20
+iotests.verify_image_format(supported_fmts=['qcow2', 'qcow', 'qed', 'vmdk',
24
+ blk_drain(n->conf.blk);
21
+ 'vhdx', 'raw'])
25
+
22
26
for (i = 0; i < n->num_queues; i++) {
23
patterns = [("0x5d", "0", "64k"),
27
if (n->sq[i] != NULL) {
24
("0xd5", "1M", "64k"),
28
nvme_free_sq(n->sq[i], n);
25
--
29
--
26
2.13.6
30
2.19.1
27
31
28
32
diff view generated by jsdifflib
1
From: Cornelia Huck <cohuck@redhat.com>
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
2
3
This reverts commit a7aff6dd10b16b67e8b142d0c94c5d92c3fe88f6.
3
Because the CMB BAR has a min_access_size of 2, if you read the last
4
byte it will try to memcpy *2* bytes from n->cmbuf, causing an off-by-one
5
error. This is CVE-2018-16847.
4
6
5
Hold off removing this for one more QEMU release (current libvirt
7
Another way to fix this might be to register the CMB as a RAM memory
6
release still uses it.)
8
region, which would also be more efficient. However, that might be a
9
change for big-endian machines; I didn't think this through and I don't
10
know how real hardware works. Add a basic testcase for the CMB in case
11
somebody does this change later on.
7
12
8
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
13
Cc: Keith Busch <keith.busch@intel.com>
14
Cc: qemu-block@nongnu.org
15
Reported-by: Li Qiang <liq3ea@gmail.com>
16
Reviewed-by: Li Qiang <liq3ea@gmail.com>
17
Tested-by: Li Qiang <liq3ea@gmail.com>
18
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
19
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
20
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
21
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
22
---
11
include/sysemu/blockdev.h | 1 +
23
hw/block/nvme.c | 2 +-
12
blockdev.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++-
24
tests/nvme-test.c | 68 +++++++++++++++++++++++++++++++++++-------
13
hw/block/block.c | 14 +++++++++
25
tests/Makefile.include | 2 +-
14
tests/hd-geo-test.c | 37 ++++++++++++++++++-----
26
3 files changed, 60 insertions(+), 12 deletions(-)
15
hmp-commands.hx | 1 +
16
qemu-doc.texi | 5 ++++
17
qemu-options.hx | 7 ++++-
18
7 files changed, 131 insertions(+), 9 deletions(-)
19
27
20
diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
28
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
21
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
22
--- a/include/sysemu/blockdev.h
30
--- a/hw/block/nvme.c
23
+++ b/include/sysemu/blockdev.h
31
+++ b/hw/block/nvme.c
24
@@ -XXX,XX +XXX,XX @@ struct DriveInfo {
32
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps nvme_cmb_ops = {
25
int auto_del; /* see blockdev_mark_auto_del() */
33
.write = nvme_cmb_write,
26
bool is_default; /* Added by default_drive() ? */
34
.endianness = DEVICE_LITTLE_ENDIAN,
27
int media_cd;
35
.impl = {
28
+ int cyls, heads, secs, trans;
36
- .min_access_size = 2,
29
QemuOpts *opts;
37
+ .min_access_size = 1,
30
char *serial;
38
.max_access_size = 8,
31
QTAILQ_ENTRY(DriveInfo) next;
39
},
32
diff --git a/blockdev.c b/blockdev.c
40
};
41
diff --git a/tests/nvme-test.c b/tests/nvme-test.c
33
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
34
--- a/blockdev.c
43
--- a/tests/nvme-test.c
35
+++ b/blockdev.c
44
+++ b/tests/nvme-test.c
36
@@ -XXX,XX +XXX,XX @@ QemuOptsList qemu_legacy_drive_opts = {
45
@@ -XXX,XX +XXX,XX @@
37
.type = QEMU_OPT_STRING,
46
*/
38
.help = "interface (ide, scsi, sd, mtd, floppy, pflash, virtio)",
47
39
},{
48
#include "qemu/osdep.h"
40
+ .name = "cyls",
49
+#include "qemu/units.h"
41
+ .type = QEMU_OPT_NUMBER,
50
#include "libqtest.h"
42
+ .help = "number of cylinders (ide disk geometry)",
51
+#include "libqos/libqos-pc.h"
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
+
52
+
85
+ if (cyls || heads || secs) {
53
+static QOSState *qnvme_start(const char *extra_opts)
86
+ if (cyls < 1) {
54
+{
87
+ error_report("invalid physical cyls number");
55
+ QOSState *qs;
88
+ goto fail;
56
+ const char *arch = qtest_get_arch();
89
+ }
57
+ const char *cmd = "-drive id=drv0,if=none,file=null-co://,format=raw "
90
+ if (heads < 1) {
58
+ "-device nvme,addr=0x4.0,serial=foo,drive=drv0 %s";
91
+ error_report("invalid physical heads number");
59
+
92
+ goto fail;
60
+ if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
93
+ }
61
+ qs = qtest_pc_boot(cmd, extra_opts ? : "");
94
+ if (secs < 1) {
62
+ global_qtest = qs->qts;
95
+ error_report("invalid physical secs number");
63
+ return qs;
96
+ goto fail;
97
+ }
98
+ }
64
+ }
99
+
65
+
100
+ translation = BIOS_ATA_TRANSLATION_AUTO;
66
+ g_printerr("nvme tests are only available on x86\n");
101
+ value = qemu_opt_get(legacy_opts, "trans");
67
+ exit(EXIT_FAILURE);
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
+}
68
+}
232
+
69
+
233
+/*
70
+static void qnvme_stop(QOSState *qs)
234
+ * Test case: IDE device (if=ide) with explicit CHS and translation
235
+ */
236
+static void test_ide_drive_user_chst(void)
237
+{
71
+{
238
+ test_ide_drive_user(NULL, true);
72
+ qtest_shutdown(qs);
239
+}
73
+}
74
75
-/* Tests only initialization so far. TODO: Replace with functional tests */
76
static void nop(void)
77
{
78
+ QOSState *qs;
240
+
79
+
241
+/*
80
+ qs = qnvme_start(NULL);
242
* Test case: IDE device (if=none) with explicit CHS
81
+ qnvme_stop(qs);
243
*/
82
}
244
static void test_ide_device_user_chs(void)
83
245
@@ -XXX,XX +XXX,XX @@ static void test_ide_drive_cd_0(void)
84
-int main(int argc, char **argv)
246
for (i = 0; i <= backend_empty; i++) {
85
+static void nvmetest_cmb_test(void)
247
ide_idx = backend_empty - i;
86
{
248
cur_ide[ide_idx] = &hd_chst[i][mbr_blank];
87
- int ret;
249
- argc = setup_ide(argc, argv, ARGV_SIZE, ide_idx, NULL, i, mbr_blank);
88
+ const int cmb_bar_size = 2 * MiB;
250
+ argc = setup_ide(argc, argv, ARGV_SIZE,
89
+ QOSState *qs;
251
+ ide_idx, NULL, i, mbr_blank, "");
90
+ QPCIDevice *pdev;
252
}
91
+ QPCIBar bar;
253
args = g_strjoinv(" ", argv);
92
254
qtest_start(args);
93
- g_test_init(&argc, &argv, NULL);
255
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
94
- qtest_add_func("/nvme/nop", nop);
256
qtest_add_func("hd-geo/ide/drive/mbr/blank", test_ide_drive_mbr_blank);
95
+ qs = qnvme_start("-global nvme.cmb_size_mb=2");
257
qtest_add_func("hd-geo/ide/drive/mbr/lba", test_ide_drive_mbr_lba);
96
+ pdev = qpci_device_find(qs->pcibus, QPCI_DEVFN(4,0));
258
qtest_add_func("hd-geo/ide/drive/mbr/chs", test_ide_drive_mbr_chs);
97
+ g_assert(pdev != NULL);
259
+ qtest_add_func("hd-geo/ide/drive/user/chs", test_ide_drive_user_chs);
98
+
260
+ qtest_add_func("hd-geo/ide/drive/user/chst", test_ide_drive_user_chst);
99
+ qpci_device_enable(pdev);
261
qtest_add_func("hd-geo/ide/drive/cd_0", test_ide_drive_cd_0);
100
+ bar = qpci_iomap(pdev, 2, NULL);
262
qtest_add_func("hd-geo/ide/device/mbr/blank", test_ide_device_mbr_blank);
101
+
263
qtest_add_func("hd-geo/ide/device/mbr/lba", test_ide_device_mbr_lba);
102
+ qpci_io_writel(pdev, bar, 0, 0xccbbaa99);
264
diff --git a/hmp-commands.hx b/hmp-commands.hx
103
+ g_assert_cmpint(qpci_io_readb(pdev, bar, 0), ==, 0x99);
104
+ g_assert_cmpint(qpci_io_readw(pdev, bar, 0), ==, 0xaa99);
105
+
106
+ /* Test partially out-of-bounds accesses. */
107
+ qpci_io_writel(pdev, bar, cmb_bar_size - 1, 0x44332211);
108
+ g_assert_cmpint(qpci_io_readb(pdev, bar, cmb_bar_size - 1), ==, 0x11);
109
+ g_assert_cmpint(qpci_io_readw(pdev, bar, cmb_bar_size - 1), !=, 0x2211);
110
+ g_assert_cmpint(qpci_io_readl(pdev, bar, cmb_bar_size - 1), !=, 0x44332211);
111
+ g_free(pdev);
112
113
- qtest_start("-drive id=drv0,if=none,file=null-co://,format=raw "
114
- "-device nvme,drive=drv0,serial=foo");
115
- ret = g_test_run();
116
+ qnvme_stop(qs);
117
+}
118
119
- qtest_end();
120
+int main(int argc, char **argv)
121
+{
122
+ g_test_init(&argc, &argv, NULL);
123
+ qtest_add_func("/nvme/nop", nop);
124
+ qtest_add_func("/nvme/cmb_test", nvmetest_cmb_test);
125
126
- return ret;
127
+ return g_test_run();
128
}
129
diff --git a/tests/Makefile.include b/tests/Makefile.include
265
index XXXXXXX..XXXXXXX 100644
130
index XXXXXXX..XXXXXXX 100644
266
--- a/hmp-commands.hx
131
--- a/tests/Makefile.include
267
+++ b/hmp-commands.hx
132
+++ b/tests/Makefile.include
268
@@ -XXX,XX +XXX,XX @@ ETEXI
133
@@ -XXX,XX +XXX,XX @@ tests/test-hmp$(EXESUF): tests/test-hmp.o
269
.params = "[-n] [[<domain>:]<bus>:]<slot>\n"
134
tests/machine-none-test$(EXESUF): tests/machine-none-test.o
270
"[file=file][,if=type][,bus=n]\n"
135
tests/drive_del-test$(EXESUF): tests/drive_del-test.o $(libqos-virtio-obj-y)
271
"[,unit=m][,media=d][,index=i]\n"
136
tests/qdev-monitor-test$(EXESUF): tests/qdev-monitor-test.o $(libqos-pc-obj-y)
272
+ "[,cyls=c,heads=h,secs=s[,trans=t]]\n"
137
-tests/nvme-test$(EXESUF): tests/nvme-test.o
273
"[,snapshot=on|off][,cache=on|off]\n"
138
+tests/nvme-test$(EXESUF): tests/nvme-test.o $(libqos-pc-obj-y)
274
"[,readonly=on|off][,copy-on-read=on|off]",
139
tests/pvpanic-test$(EXESUF): tests/pvpanic-test.o
275
.help = "add drive to PCI storage controller",
140
tests/i82801b11-test$(EXESUF): tests/i82801b11-test.o
276
diff --git a/qemu-doc.texi b/qemu-doc.texi
141
tests/ac97-test$(EXESUF): tests/ac97-test.o
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
--
142
--
319
2.13.6
143
2.19.1
320
144
321
145
diff view generated by jsdifflib
1
From: Fam Zheng <famz@redhat.com>
1
This reverts commit 5e3c0220d7e4f0361c4d36c697a8842f2b583402.
2
We have a better fix commited for this now.
2
3
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>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
5
---
13
block/io.c | 91 +++++++++++++++++++++++++++++++++++++++-----------------------
6
hw/block/nvme.c | 7 -------
14
1 file changed, 57 insertions(+), 34 deletions(-)
7
1 file changed, 7 deletions(-)
15
8
16
diff --git a/block/io.c b/block/io.c
9
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
17
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
18
--- a/block/io.c
11
--- a/hw/block/nvme.c
19
+++ b/block/io.c
12
+++ b/hw/block/nvme.c
20
@@ -XXX,XX +XXX,XX @@ fail:
13
@@ -XXX,XX +XXX,XX @@ static void nvme_cmb_write(void *opaque, hwaddr addr, uint64_t data,
21
return ret;
14
unsigned size)
15
{
16
NvmeCtrl *n = (NvmeCtrl *)opaque;
17
-
18
- if (addr + size > NVME_CMBSZ_GETSIZE(n->bar.cmbsz)) {
19
- return;
20
- }
21
memcpy(&n->cmbuf[addr], &data, size);
22
}
22
}
23
23
24
+static inline int coroutine_fn
24
@@ -XXX,XX +XXX,XX @@ static uint64_t nvme_cmb_read(void *opaque, hwaddr addr, unsigned size)
25
+bdrv_co_write_req_prepare(BdrvChild *child, int64_t offset, uint64_t bytes,
25
uint64_t val;
26
+ BdrvTrackedRequest *req, int flags)
26
NvmeCtrl *n = (NvmeCtrl *)opaque;
27
+{
27
28
+ BlockDriverState *bs = child->bs;
28
- if (addr + size > NVME_CMBSZ_GETSIZE(n->bar.cmbsz)) {
29
+ bool waited;
29
- return 0;
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
- }
30
- }
108
-
31
memcpy(&val, &n->cmbuf[addr], size);
109
- waited = wait_serialising_requests(req);
32
return val;
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
}
33
}
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
--
34
--
155
2.13.6
35
2.19.1
156
36
157
37
diff view generated by jsdifflib
1
From: Cornelia Huck <cohuck@redhat.com>
1
From: Logan Gunthorpe <logang@deltatee.com>
2
2
3
This reverts commit b0083267444a5e0f28391f6c2831a539f878d424.
3
When the submission and completion queues are being torn down
4
the IRQ will be asserted for the completion queue when the
5
submsission queue is deleted. Then when the completion queue
6
is deleted it stays asserted. Thus, on systems that do
7
not use MSI, no further interrupts can be triggered on the host.
4
8
5
Hold off removing this for one more QEMU release (current libvirt
9
Linux sees this as a long delay when unbinding the nvme device.
6
release still uses it.)
10
Eventually the interrupt timeout occurs and it continues.
7
11
8
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
12
To fix this we ensure we deassert the IRQ for a CQ when it is
13
deleted.
14
15
Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
17
---
11
include/hw/block/block.h | 1 +
18
hw/block/nvme.c | 1 +
12
include/sysemu/blockdev.h | 1 +
19
1 file changed, 1 insertion(+)
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
20
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
21
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
134
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
135
--- a/hw/block/nvme.c
23
--- a/hw/block/nvme.c
136
+++ b/hw/block/nvme.c
24
+++ b/hw/block/nvme.c
137
@@ -XXX,XX +XXX,XX @@ static void nvme_realize(PCIDevice *pci_dev, Error **errp)
25
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_del_cq(NvmeCtrl *n, NvmeCmd *cmd)
138
return;
26
trace_nvme_err_invalid_del_cq_notempty(qid);
27
return NVME_INVALID_QUEUE_DEL;
139
}
28
}
140
29
+ nvme_irq_deassert(n, cq);
141
+ blkconf_serial(&n->conf, &n->serial);
30
trace_nvme_del_cq(qid);
142
if (!n->serial) {
31
nvme_free_cq(cq, n);
143
error_setg(errp, "serial property not set");
32
return NVME_SUCCESS;
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
--
33
--
280
2.13.6
34
2.19.1
281
35
282
36
diff view generated by jsdifflib
1
If the virtual disk size isn't aligned to full clusters,
1
From: Eric Blake <eblake@redhat.com>
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
2
5
qemu-io: block/io.c:1203: bdrv_co_do_copy_on_readv: Assertion `skip_bytes < pnum' failed.
3
Testing granularity at the same size as the cluster isn't quite
4
as fun as what happens when it is larger or smaller. This
5
enhancement also shows that qemu's nbd server can serve the
6
same disk over multiple exports simultaneously.
6
7
7
Check for EOF, assert that we read at least as much as the read request
8
Signed-off-by: Eric Blake <eblake@redhat.com>
8
originally wanted to have (which is true at EOF because otherwise
9
Tested-by: John Snow <jsnow@redhat.com>
9
bdrv_check_byte_request() would already have returned an error) and
10
Reviewed-by: John Snow <jsnow@redhat.com>
10
return success early even though we couldn't copy the full cluster.
11
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
12
---
14
block/io.c | 6 ++++++
13
tests/qemu-iotests/223 | 43 +++++++++++++++++++++++++++++++-------
15
tests/qemu-iotests/197 | 9 +++++++++
14
tests/qemu-iotests/223.out | 32 +++++++++++++++++++++-------
16
tests/qemu-iotests/197.out | 8 ++++++++
15
2 files changed, 60 insertions(+), 15 deletions(-)
17
3 files changed, 23 insertions(+)
18
16
19
diff --git a/block/io.c b/block/io.c
17
diff --git a/tests/qemu-iotests/223 b/tests/qemu-iotests/223
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
18
index XXXXXXX..XXXXXXX 100755
38
--- a/tests/qemu-iotests/197
19
--- a/tests/qemu-iotests/223
39
+++ b/tests/qemu-iotests/197
20
+++ b/tests/qemu-iotests/223
40
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -f qcow2 -c map "$TEST_WRAP"
21
@@ -XXX,XX +XXX,XX @@ run_qemu()
41
_check_test_img
22
}
42
$QEMU_IMG compare -f $IMGFMT -F qcow2 "$TEST_IMG" "$TEST_WRAP"
23
24
echo
25
-echo "=== Create partially sparse image, then add dirty bitmap ==="
26
+echo "=== Create partially sparse image, then add dirty bitmaps ==="
27
echo
28
29
-_make_test_img 4M
30
+# Two bitmaps, to contrast granularity issues
31
+_make_test_img -o cluster_size=4k 4M
32
$QEMU_IO -c 'w -P 0x11 1M 2M' "$TEST_IMG" | _filter_qemu_io
33
run_qemu <<EOF
34
{ "execute": "qmp_capabilities" }
35
@@ -XXX,XX +XXX,XX @@ run_qemu <<EOF
36
"arguments": {
37
"node": "n",
38
"name": "b",
39
- "persistent": true
40
+ "persistent": true,
41
+ "granularity": 65536
42
+ }
43
+}
44
+{ "execute": "block-dirty-bitmap-add",
45
+ "arguments": {
46
+ "node": "n",
47
+ "name": "b2",
48
+ "persistent": true,
49
+ "granularity": 512
50
}
51
}
52
{ "execute": "quit" }
53
@@ -XXX,XX +XXX,XX @@ echo
54
echo "=== Write part of the file under active bitmap ==="
55
echo
56
57
-$QEMU_IO -c 'w -P 0x22 2M 2M' "$TEST_IMG" | _filter_qemu_io
58
+$QEMU_IO -c 'w -P 0x22 512 512' -c 'w -P 0x33 2M 2M' "$TEST_IMG" \
59
+ | _filter_qemu_io
60
61
echo
62
-echo "=== End dirty bitmap, and start serving image over NBD ==="
63
+echo "=== End dirty bitmaps, and start serving image over NBD ==="
64
echo
65
66
_launch_qemu 2> >(_filter_nbd)
67
@@ -XXX,XX +XXX,XX @@ _send_qemu_cmd $QEMU_HANDLE '{"execute":"blockdev-add",
68
"file":{"driver":"file", "filename":"'"$TEST_IMG"'"}}}' "return"
69
_send_qemu_cmd $QEMU_HANDLE '{"execute":"x-block-dirty-bitmap-disable",
70
"arguments":{"node":"n", "name":"b"}}' "return"
71
+_send_qemu_cmd $QEMU_HANDLE '{"execute":"x-block-dirty-bitmap-disable",
72
+ "arguments":{"node":"n", "name":"b2"}}' "return"
73
_send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-start",
74
"arguments":{"addr":{"type":"unix",
75
"data":{"path":"'"$TEST_DIR/nbd"'"}}}}' "return"
76
@@ -XXX,XX +XXX,XX @@ _send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-add",
77
"arguments":{"device":"n"}}' "return"
78
_send_qemu_cmd $QEMU_HANDLE '{"execute":"x-nbd-server-add-bitmap",
79
"arguments":{"name":"n", "bitmap":"b"}}' "return"
80
+_send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-add",
81
+ "arguments":{"device":"n", "name":"n2"}}' "return"
82
+_send_qemu_cmd $QEMU_HANDLE '{"execute":"x-nbd-server-add-bitmap",
83
+ "arguments":{"name":"n2", "bitmap":"b2"}}' "return"
84
85
echo
86
-echo "=== Contrast normal status with dirty-bitmap status ==="
87
+echo "=== Contrast normal status to large granularity dirty-bitmap ==="
88
echo
89
90
QEMU_IO_OPTIONS=$QEMU_IO_OPTIONS_NO_FMT
91
IMG="driver=nbd,export=n,server.type=unix,server.path=$TEST_DIR/nbd"
92
-$QEMU_IO -r -c 'r -P 0 0 1m' -c 'r -P 0x11 1m 1m' \
93
- -c 'r -P 0x22 2m 2m' --image-opts "$IMG" | _filter_qemu_io
94
+$QEMU_IO -r -c 'r -P 0x22 512 512' -c 'r -P 0 512k 512k' -c 'r -P 0x11 1m 1m' \
95
+ -c 'r -P 0x33 2m 2m' --image-opts "$IMG" | _filter_qemu_io
96
$QEMU_IMG map --output=json --image-opts \
97
"$IMG" | _filter_qemu_img_map
98
$QEMU_IMG map --output=json --image-opts \
99
"$IMG,x-dirty-bitmap=qemu:dirty-bitmap:b" | _filter_qemu_img_map
43
100
44
+echo
101
+echo
45
+echo '=== Partial final cluster ==='
102
+echo "=== Contrast to small granularity dirty-bitmap ==="
46
+echo
103
+echo
47
+
104
+
48
+_make_test_img 1024
105
+IMG="driver=nbd,export=n2,server.type=unix,server.path=$TEST_DIR/nbd"
49
+$QEMU_IO -f $IMGFMT -C -c 'read 0 1024' "$TEST_IMG" | _filter_qemu_io
106
+$QEMU_IMG map --output=json --image-opts \
50
+$QEMU_IO -f $IMGFMT -c map "$TEST_IMG"
107
+ "$IMG,x-dirty-bitmap=qemu:dirty-bitmap:b2" | _filter_qemu_img_map
51
+_check_test_img
52
+
108
+
53
# success, all done
109
echo
54
echo '*** done'
110
echo "=== End NBD server ==="
55
status=0
111
echo
56
diff --git a/tests/qemu-iotests/197.out b/tests/qemu-iotests/197.out
112
113
_send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-remove",
114
"arguments":{"name":"n"}}' "return"
115
+_send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-remove",
116
+ "arguments":{"name":"n2"}}' "return"
117
_send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-stop"}' "return"
118
_send_qemu_cmd $QEMU_HANDLE '{"execute":"quit"}' "return"
119
120
diff --git a/tests/qemu-iotests/223.out b/tests/qemu-iotests/223.out
57
index XXXXXXX..XXXXXXX 100644
121
index XXXXXXX..XXXXXXX 100644
58
--- a/tests/qemu-iotests/197.out
122
--- a/tests/qemu-iotests/223.out
59
+++ b/tests/qemu-iotests/197.out
123
+++ b/tests/qemu-iotests/223.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
124
@@ -XXX,XX +XXX,XX @@
61
1023.938 MiB (0x3fff0000) bytes not allocated at offset 3 GiB (0xc0010000)
125
QA output created by 223
62
No errors were found on the image.
126
63
Images are identical.
127
-=== Create partially sparse image, then add dirty bitmap ===
128
+=== Create partially sparse image, then add dirty bitmaps ===
129
130
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4194304
131
wrote 2097152/2097152 bytes at offset 1048576
132
@@ -XXX,XX +XXX,XX @@ QMP_VERSION
133
{"return": {}}
134
{"return": {}}
135
{"return": {}}
136
+{"return": {}}
137
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
138
139
140
=== Write part of the file under active bitmap ===
141
142
+wrote 512/512 bytes at offset 512
143
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
144
wrote 2097152/2097152 bytes at offset 2097152
145
2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
146
147
-=== End dirty bitmap, and start serving image over NBD ===
148
+=== End dirty bitmaps, and start serving image over NBD ===
149
150
{"return": {}}
151
{"return": {}}
152
@@ -XXX,XX +XXX,XX @@ wrote 2097152/2097152 bytes at offset 2097152
153
{"return": {}}
154
{"return": {}}
155
{"return": {}}
156
+{"return": {}}
157
+{"return": {}}
158
+{"return": {}}
159
160
-=== Contrast normal status with dirty-bitmap status ===
161
+=== Contrast normal status to large granularity dirty-bitmap ===
162
163
-read 1048576/1048576 bytes at offset 0
164
-1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
165
+read 512/512 bytes at offset 512
166
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
167
+read 524288/524288 bytes at offset 524288
168
+512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
169
read 1048576/1048576 bytes at offset 1048576
170
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
171
read 2097152/2097152 bytes at offset 2097152
172
2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
173
-[{ "start": 0, "length": 1048576, "depth": 0, "zero": true, "data": false},
174
+[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true},
175
+{ "start": 4096, "length": 1044480, "depth": 0, "zero": true, "data": false},
176
{ "start": 1048576, "length": 3145728, "depth": 0, "zero": false, "data": true}]
177
-[{ "start": 0, "length": 2097152, "depth": 0, "zero": false, "data": true},
178
+[{ "start": 0, "length": 65536, "depth": 0, "zero": false, "data": false},
179
+{ "start": 65536, "length": 2031616, "depth": 0, "zero": false, "data": true},
180
+{ "start": 2097152, "length": 2097152, "depth": 0, "zero": false, "data": false}]
64
+
181
+
65
+=== Partial final cluster ===
182
+=== Contrast to small granularity dirty-bitmap ===
66
+
183
+
67
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1024
184
+[{ "start": 0, "length": 512, "depth": 0, "zero": false, "data": true},
68
+read 1024/1024 bytes at offset 0
185
+{ "start": 512, "length": 512, "depth": 0, "zero": false, "data": false},
69
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
186
+{ "start": 1024, "length": 2096128, "depth": 0, "zero": false, "data": true},
70
+1 KiB (0x400) bytes allocated at offset 0 bytes (0x0)
187
{ "start": 2097152, "length": 2097152, "depth": 0, "zero": false, "data": false}]
71
+No errors were found on the image.
188
189
=== End NBD server ===
190
@@ -XXX,XX +XXX,XX @@ read 2097152/2097152 bytes at offset 2097152
191
{"return": {}}
192
{"return": {}}
193
{"return": {}}
194
+{"return": {}}
72
*** done
195
*** done
73
--
196
--
74
2.13.6
197
2.19.1
75
198
76
199
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
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 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: 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
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