1
The following changes since commit fc3dbb90f2eb069801bfb4cfe9cbc83cf9c5f4a9:
1
The following changes since commit a2376507f615495b1d16685449ce0ea78c2caf9d:
2
2
3
Merge remote-tracking branch 'remotes/jnsnow/tags/bitmaps-pull-request' into staging (2019-02-21 13:09:33 +0000)
3
Merge remote-tracking branch 'remotes/bonzini-gitlab/tags/for-upstream' into staging (2021-07-24 11:04:57 +0100)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
git://github.com/stefanha/qemu.git tags/block-pull-request
7
https://gitlab.com/stefanha/qemu.git tags/block-pull-request
8
8
9
for you to fetch changes up to 9a9f4b74fa547b68edb38fa414999836770a4735:
9
for you to fetch changes up to 15a730e7a3aaac180df72cd5730e0617bcf44a5a:
10
10
11
tests/virtio-blk: add test for DISCARD command (2019-02-22 09:42:17 +0000)
11
block/nvme: Fix VFIO_MAP_DMA failed: No space left on device (2021-07-26 09:38:12 +0100)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Pull request
14
Pull request
15
15
16
Phil's block/nvme.c ENOSPC fix for newer Linux kernels that return this errno.
17
16
----------------------------------------------------------------
18
----------------------------------------------------------------
17
19
18
Stefano Garzarella (10):
20
Philippe Mathieu-Daudé (1):
19
virtio-blk: add acct_failed param to virtio_blk_handle_rw_error()
21
block/nvme: Fix VFIO_MAP_DMA failed: No space left on device
20
virtio-blk: add host_features field in VirtIOBlock
21
virtio-blk: add "discard" and "write-zeroes" properties
22
virtio-net: make VirtIOFeature usable for other virtio devices
23
virtio-blk: set config size depending on the features enabled
24
virtio-blk: add DISCARD and WRITE_ZEROES features
25
tests/virtio-blk: change assert on data_size in virtio_blk_request()
26
tests/virtio-blk: add virtio_blk_fix_dwz_hdr() function
27
tests/virtio-blk: add test for WRITE_ZEROES command
28
tests/virtio-blk: add test for DISCARD command
29
22
30
Vladimir Sementsov-Ogievskiy (17):
23
block/nvme.c | 22 ++++++++++++++++++++++
31
block: enhance QEMUIOVector structure
24
1 file changed, 22 insertions(+)
32
block/io: use qemu_iovec_init_buf
33
block/block-backend: use QEMU_IOVEC_INIT_BUF
34
block/backup: use qemu_iovec_init_buf
35
block/commit: use QEMU_IOVEC_INIT_BUF
36
block/stream: use QEMU_IOVEC_INIT_BUF
37
block/parallels: use QEMU_IOVEC_INIT_BUF
38
block/qcow: use qemu_iovec_init_buf
39
block/qcow2: use qemu_iovec_init_buf
40
block/qed: use qemu_iovec_init_buf
41
block/vmdk: use qemu_iovec_init_buf
42
qemu-img: use qemu_iovec_init_buf
43
migration/block: use qemu_iovec_init_buf
44
tests/test-bdrv-drain: use QEMU_IOVEC_INIT_BUF
45
hw/ide: drop iov field from IDEState
46
hw/ide: drop iov field from IDEBufferedRequest
47
hw/ide: drop iov field from IDEDMA
48
49
include/hw/ide/internal.h | 3 -
50
include/hw/virtio/virtio-blk.h | 6 +-
51
include/hw/virtio/virtio.h | 15 ++
52
include/qemu/iov.h | 64 ++++++++-
53
block/backup.c | 5 +-
54
block/block-backend.c | 13 +-
55
block/commit.c | 7 +-
56
block/io.c | 89 +++---------
57
block/parallels.c | 13 +-
58
block/qcow.c | 21 +--
59
block/qcow2.c | 12 +-
60
block/qed-table.c | 16 +--
61
block/qed.c | 31 ++---
62
block/stream.c | 7 +-
63
block/vmdk.c | 7 +-
64
hw/block/virtio-blk.c | 245 ++++++++++++++++++++++++++++++---
65
hw/core/machine.c | 2 +
66
hw/ide/atapi.c | 14 +-
67
hw/ide/core.c | 19 ++-
68
hw/net/virtio-net.c | 31 +----
69
hw/virtio/virtio.c | 15 ++
70
migration/block.c | 10 +-
71
qemu-img.c | 10 +-
72
tests/test-bdrv-drain.c | 29 +---
73
tests/virtio-blk-test.c | 127 ++++++++++++++++-
74
25 files changed, 525 insertions(+), 286 deletions(-)
75
25
76
--
26
--
77
2.20.1
27
2.31.1
78
28
79
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Add a possibility of embedded iovec, for cases when we need only one
4
local iov.
5
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Message-id: 20190218140926.333779-2-vsementsov@virtuozzo.com
9
Message-Id: <20190218140926.333779-2-vsementsov@virtuozzo.com>
10
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
11
---
12
include/qemu/iov.h | 64 ++++++++++++++++++++++++++++++++++++++++++++--
13
1 file changed, 62 insertions(+), 2 deletions(-)
14
15
diff --git a/include/qemu/iov.h b/include/qemu/iov.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/qemu/iov.h
18
+++ b/include/qemu/iov.h
19
@@ -XXX,XX +XXX,XX @@ size_t iov_discard_back(struct iovec *iov, unsigned int *iov_cnt,
20
typedef struct QEMUIOVector {
21
struct iovec *iov;
22
int niov;
23
- int nalloc;
24
- size_t size;
25
+
26
+ /*
27
+ * For external @iov (qemu_iovec_init_external()) or allocated @iov
28
+ * (qemu_iovec_init()), @size is the cumulative size of iovecs and
29
+ * @local_iov is invalid and unused.
30
+ *
31
+ * For embedded @iov (QEMU_IOVEC_INIT_BUF() or qemu_iovec_init_buf()),
32
+ * @iov is equal to &@local_iov, and @size is valid, as it has same
33
+ * offset and type as @local_iov.iov_len, which is guaranteed by
34
+ * static assertion below.
35
+ *
36
+ * @nalloc is always valid and is -1 both for embedded and external
37
+ * cases. It is included in the union only to ensure the padding prior
38
+ * to the @size field will not result in a 0-length array.
39
+ */
40
+ union {
41
+ struct {
42
+ int nalloc;
43
+ struct iovec local_iov;
44
+ };
45
+ struct {
46
+ char __pad[sizeof(int) + offsetof(struct iovec, iov_len)];
47
+ size_t size;
48
+ };
49
+ };
50
} QEMUIOVector;
51
52
+QEMU_BUILD_BUG_ON(offsetof(QEMUIOVector, size) !=
53
+ offsetof(QEMUIOVector, local_iov.iov_len));
54
+
55
+#define QEMU_IOVEC_INIT_BUF(self, buf, len) \
56
+{ \
57
+ .iov = &(self).local_iov, \
58
+ .niov = 1, \
59
+ .nalloc = -1, \
60
+ .local_iov = { \
61
+ .iov_base = (void *)(buf), /* cast away const */ \
62
+ .iov_len = (len), \
63
+ }, \
64
+}
65
+
66
+/*
67
+ * qemu_iovec_init_buf
68
+ *
69
+ * Initialize embedded QEMUIOVector.
70
+ *
71
+ * Note: "const" is used over @buf pointer to make it simple to pass
72
+ * const pointers, appearing in read functions. Then this "const" is
73
+ * cast away by QEMU_IOVEC_INIT_BUF().
74
+ */
75
+static inline void qemu_iovec_init_buf(QEMUIOVector *qiov,
76
+ const void *buf, size_t len)
77
+{
78
+ *qiov = (QEMUIOVector) QEMU_IOVEC_INIT_BUF(*qiov, buf, len);
79
+}
80
+
81
+static inline void *qemu_iovec_buf(QEMUIOVector *qiov)
82
+{
83
+ /* Only supports embedded iov */
84
+ assert(qiov->nalloc == -1 && qiov->iov == &qiov->local_iov);
85
+
86
+ return qiov->local_iov.iov_base;
87
+}
88
+
89
void qemu_iovec_init(QEMUIOVector *qiov, int alloc_hint);
90
void qemu_iovec_init_external(QEMUIOVector *qiov, struct iovec *iov, int niov);
91
void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len);
92
--
93
2.20.1
94
95
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Use new qemu_iovec_init_buf() instead of
4
qemu_iovec_init_external( ... , 1), which simplifies the code.
5
6
While being here, use qemu_try_blockalign0 as well.
7
8
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
Reviewed-by: Eric Blake <eblake@redhat.com>
10
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
11
Message-id: 20190218140926.333779-3-vsementsov@virtuozzo.com
12
Message-Id: <20190218140926.333779-3-vsementsov@virtuozzo.com>
13
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
14
---
15
block/io.c | 89 ++++++++++++------------------------------------------
16
1 file changed, 20 insertions(+), 69 deletions(-)
17
18
diff --git a/block/io.c b/block/io.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/block/io.c
21
+++ b/block/io.c
22
@@ -XXX,XX +XXX,XX @@ static int bdrv_prwv_co(BdrvChild *child, int64_t offset,
23
static int bdrv_rw_co(BdrvChild *child, int64_t sector_num, uint8_t *buf,
24
int nb_sectors, bool is_write, BdrvRequestFlags flags)
25
{
26
- QEMUIOVector qiov;
27
- struct iovec iov = {
28
- .iov_base = (void *)buf,
29
- .iov_len = nb_sectors * BDRV_SECTOR_SIZE,
30
- };
31
+ QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf,
32
+ nb_sectors * BDRV_SECTOR_SIZE);
33
34
if (nb_sectors < 0 || nb_sectors > BDRV_REQUEST_MAX_SECTORS) {
35
return -EINVAL;
36
}
37
38
- qemu_iovec_init_external(&qiov, &iov, 1);
39
return bdrv_prwv_co(child, sector_num << BDRV_SECTOR_BITS,
40
&qiov, is_write, flags);
41
}
42
@@ -XXX,XX +XXX,XX @@ int bdrv_write(BdrvChild *child, int64_t sector_num,
43
int bdrv_pwrite_zeroes(BdrvChild *child, int64_t offset,
44
int bytes, BdrvRequestFlags flags)
45
{
46
- QEMUIOVector qiov;
47
- struct iovec iov = {
48
- .iov_base = NULL,
49
- .iov_len = bytes,
50
- };
51
+ QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, NULL, bytes);
52
53
- qemu_iovec_init_external(&qiov, &iov, 1);
54
return bdrv_prwv_co(child, offset, &qiov, true,
55
BDRV_REQ_ZERO_WRITE | flags);
56
}
57
@@ -XXX,XX +XXX,XX @@ int bdrv_preadv(BdrvChild *child, int64_t offset, QEMUIOVector *qiov)
58
59
int bdrv_pread(BdrvChild *child, int64_t offset, void *buf, int bytes)
60
{
61
- QEMUIOVector qiov;
62
- struct iovec iov = {
63
- .iov_base = (void *)buf,
64
- .iov_len = bytes,
65
- };
66
+ QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
67
68
if (bytes < 0) {
69
return -EINVAL;
70
}
71
72
- qemu_iovec_init_external(&qiov, &iov, 1);
73
return bdrv_preadv(child, offset, &qiov);
74
}
75
76
@@ -XXX,XX +XXX,XX @@ int bdrv_pwritev(BdrvChild *child, int64_t offset, QEMUIOVector *qiov)
77
78
int bdrv_pwrite(BdrvChild *child, int64_t offset, const void *buf, int bytes)
79
{
80
- QEMUIOVector qiov;
81
- struct iovec iov = {
82
- .iov_base = (void *) buf,
83
- .iov_len = bytes,
84
- };
85
+ QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
86
87
if (bytes < 0) {
88
return -EINVAL;
89
}
90
91
- qemu_iovec_init_external(&qiov, &iov, 1);
92
return bdrv_pwritev(child, offset, &qiov);
93
}
94
95
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child,
96
void *bounce_buffer;
97
98
BlockDriver *drv = bs->drv;
99
- struct iovec iov;
100
QEMUIOVector local_qiov;
101
int64_t cluster_offset;
102
int64_t cluster_bytes;
103
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child,
104
105
if (ret <= 0) {
106
/* Must copy-on-read; use the bounce buffer */
107
- iov.iov_base = bounce_buffer;
108
- iov.iov_len = pnum = MIN(pnum, MAX_BOUNCE_BUFFER);
109
- qemu_iovec_init_external(&local_qiov, &iov, 1);
110
+ pnum = MIN(pnum, MAX_BOUNCE_BUFFER);
111
+ qemu_iovec_init_buf(&local_qiov, bounce_buffer, pnum);
112
113
ret = bdrv_driver_preadv(bs, cluster_offset, pnum,
114
&local_qiov, 0);
115
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
116
{
117
BlockDriver *drv = bs->drv;
118
QEMUIOVector qiov;
119
- struct iovec iov = {0};
120
+ void *buf = NULL;
121
int ret = 0;
122
bool need_flush = false;
123
int head = 0;
124
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
125
need_flush = true;
126
}
127
num = MIN(num, max_transfer);
128
- iov.iov_len = num;
129
- if (iov.iov_base == NULL) {
130
- iov.iov_base = qemu_try_blockalign(bs, num);
131
- if (iov.iov_base == NULL) {
132
+ if (buf == NULL) {
133
+ buf = qemu_try_blockalign0(bs, num);
134
+ if (buf == NULL) {
135
ret = -ENOMEM;
136
goto fail;
137
}
138
- memset(iov.iov_base, 0, num);
139
}
140
- qemu_iovec_init_external(&qiov, &iov, 1);
141
+ qemu_iovec_init_buf(&qiov, buf, num);
142
143
ret = bdrv_driver_pwritev(bs, offset, num, &qiov, write_flags);
144
145
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
146
* all future requests.
147
*/
148
if (num < max_transfer) {
149
- qemu_vfree(iov.iov_base);
150
- iov.iov_base = NULL;
151
+ qemu_vfree(buf);
152
+ buf = NULL;
153
}
154
}
155
156
@@ -XXX,XX +XXX,XX @@ fail:
157
if (ret == 0 && need_flush) {
158
ret = bdrv_co_flush(bs);
159
}
160
- qemu_vfree(iov.iov_base);
161
+ qemu_vfree(buf);
162
return ret;
163
}
164
165
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_do_zero_pwritev(BdrvChild *child,
166
BlockDriverState *bs = child->bs;
167
uint8_t *buf = NULL;
168
QEMUIOVector local_qiov;
169
- struct iovec iov;
170
uint64_t align = bs->bl.request_alignment;
171
unsigned int head_padding_bytes, tail_padding_bytes;
172
int ret = 0;
173
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_do_zero_pwritev(BdrvChild *child,
174
assert(flags & BDRV_REQ_ZERO_WRITE);
175
if (head_padding_bytes || tail_padding_bytes) {
176
buf = qemu_blockalign(bs, align);
177
- iov = (struct iovec) {
178
- .iov_base = buf,
179
- .iov_len = align,
180
- };
181
- qemu_iovec_init_external(&local_qiov, &iov, 1);
182
+ qemu_iovec_init_buf(&local_qiov, buf, align);
183
}
184
if (head_padding_bytes) {
185
uint64_t zero_bytes = MIN(bytes, align - head_padding_bytes);
186
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pwritev(BdrvChild *child,
187
188
if (offset & (align - 1)) {
189
QEMUIOVector head_qiov;
190
- struct iovec head_iov;
191
192
mark_request_serialising(&req, align);
193
wait_serialising_requests(&req);
194
195
head_buf = qemu_blockalign(bs, align);
196
- head_iov = (struct iovec) {
197
- .iov_base = head_buf,
198
- .iov_len = align,
199
- };
200
- qemu_iovec_init_external(&head_qiov, &head_iov, 1);
201
+ qemu_iovec_init_buf(&head_qiov, head_buf, align);
202
203
bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_HEAD);
204
ret = bdrv_aligned_preadv(child, &req, offset & ~(align - 1), align,
205
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pwritev(BdrvChild *child,
206
207
if ((offset + bytes) & (align - 1)) {
208
QEMUIOVector tail_qiov;
209
- struct iovec tail_iov;
210
size_t tail_bytes;
211
bool waited;
212
213
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pwritev(BdrvChild *child,
214
assert(!waited || !use_local_qiov);
215
216
tail_buf = qemu_blockalign(bs, align);
217
- tail_iov = (struct iovec) {
218
- .iov_base = tail_buf,
219
- .iov_len = align,
220
- };
221
- qemu_iovec_init_external(&tail_qiov, &tail_iov, 1);
222
+ qemu_iovec_init_buf(&tail_qiov, tail_buf, align);
223
224
bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_TAIL);
225
ret = bdrv_aligned_preadv(child, &req, (offset + bytes) & ~(align - 1),
226
@@ -XXX,XX +XXX,XX @@ bdrv_rw_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos,
227
int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
228
int64_t pos, int size)
229
{
230
- QEMUIOVector qiov;
231
- struct iovec iov = {
232
- .iov_base = (void *) buf,
233
- .iov_len = size,
234
- };
235
+ QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, size);
236
int ret;
237
238
- qemu_iovec_init_external(&qiov, &iov, 1);
239
-
240
ret = bdrv_writev_vmstate(bs, &qiov, pos);
241
if (ret < 0) {
242
return ret;
243
@@ -XXX,XX +XXX,XX @@ int bdrv_writev_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos)
244
int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
245
int64_t pos, int size)
246
{
247
- QEMUIOVector qiov;
248
- struct iovec iov = {
249
- .iov_base = buf,
250
- .iov_len = size,
251
- };
252
+ QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, size);
253
int ret;
254
255
- qemu_iovec_init_external(&qiov, &iov, 1);
256
ret = bdrv_readv_vmstate(bs, &qiov, pos);
257
if (ret < 0) {
258
return ret;
259
--
260
2.20.1
261
262
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Use new QEMU_IOVEC_INIT_BUF() instead of
4
qemu_iovec_init_external( ... , 1), which simplifies the code.
5
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Message-id: 20190218140926.333779-4-vsementsov@virtuozzo.com
10
Message-Id: <20190218140926.333779-4-vsementsov@virtuozzo.com>
11
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
12
---
13
block/block-backend.c | 13 ++-----------
14
1 file changed, 2 insertions(+), 11 deletions(-)
15
16
diff --git a/block/block-backend.c b/block/block-backend.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/block/block-backend.c
19
+++ b/block/block-backend.c
20
@@ -XXX,XX +XXX,XX @@ static int blk_prw(BlockBackend *blk, int64_t offset, uint8_t *buf,
21
int64_t bytes, CoroutineEntry co_entry,
22
BdrvRequestFlags flags)
23
{
24
- QEMUIOVector qiov;
25
- struct iovec iov;
26
- BlkRwCo rwco;
27
-
28
- iov = (struct iovec) {
29
- .iov_base = buf,
30
- .iov_len = bytes,
31
- };
32
- qemu_iovec_init_external(&qiov, &iov, 1);
33
-
34
- rwco = (BlkRwCo) {
35
+ QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
36
+ BlkRwCo rwco = {
37
.blk = blk,
38
.offset = offset,
39
.iobuf = &qiov,
40
--
41
2.20.1
42
43
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Use new qemu_iovec_init_buf() instead of
4
qemu_iovec_init_external( ... , 1), which simplifies the code.
5
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Message-id: 20190218140926.333779-5-vsementsov@virtuozzo.com
10
Message-Id: <20190218140926.333779-5-vsementsov@virtuozzo.com>
11
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
12
---
13
block/backup.c | 5 +----
14
1 file changed, 1 insertion(+), 4 deletions(-)
15
16
diff --git a/block/backup.c b/block/backup.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/block/backup.c
19
+++ b/block/backup.c
20
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_cow_with_bounce_buffer(BackupBlockJob *job,
21
void **bounce_buffer)
22
{
23
int ret;
24
- struct iovec iov;
25
QEMUIOVector qiov;
26
BlockBackend *blk = job->common.blk;
27
int nbytes;
28
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_cow_with_bounce_buffer(BackupBlockJob *job,
29
if (!*bounce_buffer) {
30
*bounce_buffer = blk_blockalign(blk, job->cluster_size);
31
}
32
- iov.iov_base = *bounce_buffer;
33
- iov.iov_len = nbytes;
34
- qemu_iovec_init_external(&qiov, &iov, 1);
35
+ qemu_iovec_init_buf(&qiov, *bounce_buffer, nbytes);
36
37
ret = blk_co_preadv(blk, start, qiov.size, &qiov, read_flags);
38
if (ret < 0) {
39
--
40
2.20.1
41
42
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Use new QEMU_IOVEC_INIT_BUF() instead of
4
qemu_iovec_init_external( ... , 1), which simplifies the code.
5
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Message-id: 20190218140926.333779-6-vsementsov@virtuozzo.com
10
Message-Id: <20190218140926.333779-6-vsementsov@virtuozzo.com>
11
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
12
---
13
block/commit.c | 7 +------
14
1 file changed, 1 insertion(+), 6 deletions(-)
15
16
diff --git a/block/commit.c b/block/commit.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/block/commit.c
19
+++ b/block/commit.c
20
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn commit_populate(BlockBackend *bs, BlockBackend *base,
21
void *buf)
22
{
23
int ret = 0;
24
- QEMUIOVector qiov;
25
- struct iovec iov = {
26
- .iov_base = buf,
27
- .iov_len = bytes,
28
- };
29
+ QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
30
31
assert(bytes < SIZE_MAX);
32
- qemu_iovec_init_external(&qiov, &iov, 1);
33
34
ret = blk_co_preadv(bs, offset, qiov.size, &qiov, 0);
35
if (ret < 0) {
36
--
37
2.20.1
38
39
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Use new QEMU_IOVEC_INIT_BUF() instead of
4
qemu_iovec_init_external( ... , 1), which simplifies the code.
5
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Message-id: 20190218140926.333779-7-vsementsov@virtuozzo.com
10
Message-Id: <20190218140926.333779-7-vsementsov@virtuozzo.com>
11
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
12
---
13
block/stream.c | 7 +------
14
1 file changed, 1 insertion(+), 6 deletions(-)
15
16
diff --git a/block/stream.c b/block/stream.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/block/stream.c
19
+++ b/block/stream.c
20
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn stream_populate(BlockBackend *blk,
21
int64_t offset, uint64_t bytes,
22
void *buf)
23
{
24
- struct iovec iov = {
25
- .iov_base = buf,
26
- .iov_len = bytes,
27
- };
28
- QEMUIOVector qiov;
29
+ QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
30
31
assert(bytes < SIZE_MAX);
32
- qemu_iovec_init_external(&qiov, &iov, 1);
33
34
/* Copy-on-read the unallocated clusters */
35
return blk_co_preadv(blk, offset, qiov.size, &qiov, BDRV_REQ_COPY_ON_READ);
36
--
37
2.20.1
38
39
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Use new QEMU_IOVEC_INIT_BUF() instead of
4
qemu_iovec_init_external( ... , 1), which simplifies the code.
5
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Message-id: 20190218140926.333779-8-vsementsov@virtuozzo.com
10
Message-Id: <20190218140926.333779-8-vsementsov@virtuozzo.com>
11
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
12
---
13
block/parallels.c | 13 +++++--------
14
1 file changed, 5 insertions(+), 8 deletions(-)
15
16
diff --git a/block/parallels.c b/block/parallels.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/block/parallels.c
19
+++ b/block/parallels.c
20
@@ -XXX,XX +XXX,XX @@ static int64_t allocate_clusters(BlockDriverState *bs, int64_t sector_num,
21
if (bs->backing) {
22
int64_t nb_cow_sectors = to_allocate * s->tracks;
23
int64_t nb_cow_bytes = nb_cow_sectors << BDRV_SECTOR_BITS;
24
- QEMUIOVector qiov;
25
- struct iovec iov = {
26
- .iov_len = nb_cow_bytes,
27
- .iov_base = qemu_blockalign(bs, nb_cow_bytes)
28
- };
29
- qemu_iovec_init_external(&qiov, &iov, 1);
30
+ QEMUIOVector qiov =
31
+ QEMU_IOVEC_INIT_BUF(qiov, qemu_blockalign(bs, nb_cow_bytes),
32
+ nb_cow_bytes);
33
34
ret = bdrv_co_preadv(bs->backing, idx * s->tracks * BDRV_SECTOR_SIZE,
35
nb_cow_bytes, &qiov, 0);
36
if (ret < 0) {
37
- qemu_vfree(iov.iov_base);
38
+ qemu_vfree(qemu_iovec_buf(&qiov));
39
return ret;
40
}
41
42
ret = bdrv_co_pwritev(bs->file, s->data_end * BDRV_SECTOR_SIZE,
43
nb_cow_bytes, &qiov, 0);
44
- qemu_vfree(iov.iov_base);
45
+ qemu_vfree(qemu_iovec_buf(&qiov));
46
if (ret < 0) {
47
return ret;
48
}
49
--
50
2.20.1
51
52
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Use new qemu_iovec_init_buf() instead of
4
qemu_iovec_init_external( ... , 1), which simplifies the code.
5
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Message-id: 20190218140926.333779-9-vsementsov@virtuozzo.com
10
Message-Id: <20190218140926.333779-9-vsementsov@virtuozzo.com>
11
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
12
---
13
block/qcow.c | 21 ++++-----------------
14
1 file changed, 4 insertions(+), 17 deletions(-)
15
16
diff --git a/block/qcow.c b/block/qcow.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/block/qcow.c
19
+++ b/block/qcow.c
20
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow_co_preadv(BlockDriverState *bs, uint64_t offset,
21
int offset_in_cluster;
22
int ret = 0, n;
23
uint64_t cluster_offset;
24
- struct iovec hd_iov;
25
QEMUIOVector hd_qiov;
26
uint8_t *buf;
27
void *orig_buf;
28
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow_co_preadv(BlockDriverState *bs, uint64_t offset,
29
if (!cluster_offset) {
30
if (bs->backing) {
31
/* read from the base image */
32
- hd_iov.iov_base = (void *)buf;
33
- hd_iov.iov_len = n;
34
- qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
35
+ qemu_iovec_init_buf(&hd_qiov, buf, n);
36
qemu_co_mutex_unlock(&s->lock);
37
/* qcow2 emits this on bs->file instead of bs->backing */
38
BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
39
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow_co_preadv(BlockDriverState *bs, uint64_t offset,
40
ret = -EIO;
41
break;
42
}
43
- hd_iov.iov_base = (void *)buf;
44
- hd_iov.iov_len = n;
45
- qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
46
+ qemu_iovec_init_buf(&hd_qiov, buf, n);
47
qemu_co_mutex_unlock(&s->lock);
48
BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
49
ret = bdrv_co_preadv(bs->file, cluster_offset + offset_in_cluster,
50
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow_co_pwritev(BlockDriverState *bs, uint64_t offset,
51
int offset_in_cluster;
52
uint64_t cluster_offset;
53
int ret = 0, n;
54
- struct iovec hd_iov;
55
QEMUIOVector hd_qiov;
56
uint8_t *buf;
57
void *orig_buf;
58
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow_co_pwritev(BlockDriverState *bs, uint64_t offset,
59
}
60
}
61
62
- hd_iov.iov_base = (void *)buf;
63
- hd_iov.iov_len = n;
64
- qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
65
+ qemu_iovec_init_buf(&hd_qiov, buf, n);
66
qemu_co_mutex_unlock(&s->lock);
67
BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
68
ret = bdrv_co_pwritev(bs->file, cluster_offset + offset_in_cluster,
69
@@ -XXX,XX +XXX,XX @@ qcow_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
70
{
71
BDRVQcowState *s = bs->opaque;
72
QEMUIOVector hd_qiov;
73
- struct iovec iov;
74
z_stream strm;
75
int ret, out_len;
76
uint8_t *buf, *out_buf;
77
@@ -XXX,XX +XXX,XX @@ qcow_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
78
}
79
cluster_offset &= s->cluster_offset_mask;
80
81
- iov = (struct iovec) {
82
- .iov_base = out_buf,
83
- .iov_len = out_len,
84
- };
85
- qemu_iovec_init_external(&hd_qiov, &iov, 1);
86
+ qemu_iovec_init_buf(&hd_qiov, out_buf, out_len);
87
BLKDBG_EVENT(bs->file, BLKDBG_WRITE_COMPRESSED);
88
ret = bdrv_co_pwritev(bs->file, cluster_offset, out_len, &hd_qiov, 0);
89
if (ret < 0) {
90
--
91
2.20.1
92
93
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Use new qemu_iovec_init_buf() instead of
4
qemu_iovec_init_external( ... , 1), which simplifies the code.
5
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Message-id: 20190218140926.333779-10-vsementsov@virtuozzo.com
10
Message-Id: <20190218140926.333779-10-vsementsov@virtuozzo.com>
11
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
12
---
13
block/qcow2.c | 12 ++----------
14
1 file changed, 2 insertions(+), 10 deletions(-)
15
16
diff --git a/block/qcow2.c b/block/qcow2.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/block/qcow2.c
19
+++ b/block/qcow2.c
20
@@ -XXX,XX +XXX,XX @@ qcow2_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
21
{
22
BDRVQcow2State *s = bs->opaque;
23
QEMUIOVector hd_qiov;
24
- struct iovec iov;
25
int ret;
26
size_t out_len;
27
uint8_t *buf, *out_buf;
28
@@ -XXX,XX +XXX,XX @@ qcow2_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
29
goto fail;
30
}
31
32
- iov = (struct iovec) {
33
- .iov_base = out_buf,
34
- .iov_len = out_len,
35
- };
36
- qemu_iovec_init_external(&hd_qiov, &iov, 1);
37
+ qemu_iovec_init_buf(&hd_qiov, out_buf, out_len);
38
39
BLKDBG_EVENT(bs->file, BLKDBG_WRITE_COMPRESSED);
40
ret = bdrv_co_pwritev(bs->file, cluster_offset, out_len, &hd_qiov, 0);
41
@@ -XXX,XX +XXX,XX @@ qcow2_co_preadv_compressed(BlockDriverState *bs,
42
int ret = 0, csize, nb_csectors;
43
uint64_t coffset;
44
uint8_t *buf, *out_buf;
45
- struct iovec iov;
46
QEMUIOVector local_qiov;
47
int offset_in_cluster = offset_into_cluster(s, offset);
48
49
@@ -XXX,XX +XXX,XX @@ qcow2_co_preadv_compressed(BlockDriverState *bs,
50
if (!buf) {
51
return -ENOMEM;
52
}
53
- iov.iov_base = buf;
54
- iov.iov_len = csize;
55
- qemu_iovec_init_external(&local_qiov, &iov, 1);
56
+ qemu_iovec_init_buf(&local_qiov, buf, csize);
57
58
out_buf = qemu_blockalign(bs, s->cluster_size);
59
60
--
61
2.20.1
62
63
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Use new qemu_iovec_init_buf() instead of
4
qemu_iovec_init_external( ... , 1), which simplifies the code.
5
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Message-id: 20190218140926.333779-11-vsementsov@virtuozzo.com
10
Message-Id: <20190218140926.333779-11-vsementsov@virtuozzo.com>
11
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
12
---
13
block/qed-table.c | 16 +++-------------
14
block/qed.c | 31 +++++++++----------------------
15
2 files changed, 12 insertions(+), 35 deletions(-)
16
17
diff --git a/block/qed-table.c b/block/qed-table.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/block/qed-table.c
20
+++ b/block/qed-table.c
21
@@ -XXX,XX +XXX,XX @@
22
/* Called with table_lock held. */
23
static int qed_read_table(BDRVQEDState *s, uint64_t offset, QEDTable *table)
24
{
25
- QEMUIOVector qiov;
26
+ QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(
27
+ qiov, table->offsets, s->header.cluster_size * s->header.table_size);
28
int noffsets;
29
int i, ret;
30
31
- struct iovec iov = {
32
- .iov_base = table->offsets,
33
- .iov_len = s->header.cluster_size * s->header.table_size,
34
- };
35
- qemu_iovec_init_external(&qiov, &iov, 1);
36
-
37
trace_qed_read_table(s, offset, table);
38
39
qemu_co_mutex_unlock(&s->table_lock);
40
@@ -XXX,XX +XXX,XX @@ static int qed_write_table(BDRVQEDState *s, uint64_t offset, QEDTable *table,
41
unsigned int sector_mask = BDRV_SECTOR_SIZE / sizeof(uint64_t) - 1;
42
unsigned int start, end, i;
43
QEDTable *new_table;
44
- struct iovec iov;
45
QEMUIOVector qiov;
46
size_t len_bytes;
47
int ret;
48
@@ -XXX,XX +XXX,XX @@ static int qed_write_table(BDRVQEDState *s, uint64_t offset, QEDTable *table,
49
len_bytes = (end - start) * sizeof(uint64_t);
50
51
new_table = qemu_blockalign(s->bs, len_bytes);
52
- iov = (struct iovec) {
53
- .iov_base = new_table->offsets,
54
- .iov_len = len_bytes,
55
- };
56
- qemu_iovec_init_external(&qiov, &iov, 1);
57
+ qemu_iovec_init_buf(&qiov, new_table->offsets, len_bytes);
58
59
/* Byteswap table */
60
for (i = start; i < end; i++) {
61
diff --git a/block/qed.c b/block/qed.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/block/qed.c
64
+++ b/block/qed.c
65
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qed_write_header(BDRVQEDState *s)
66
int nsectors = DIV_ROUND_UP(sizeof(QEDHeader), BDRV_SECTOR_SIZE);
67
size_t len = nsectors * BDRV_SECTOR_SIZE;
68
uint8_t *buf;
69
- struct iovec iov;
70
QEMUIOVector qiov;
71
int ret;
72
73
assert(s->allocating_acb || s->allocating_write_reqs_plugged);
74
75
buf = qemu_blockalign(s->bs, len);
76
- iov = (struct iovec) {
77
- .iov_base = buf,
78
- .iov_len = len,
79
- };
80
- qemu_iovec_init_external(&qiov, &iov, 1);
81
+ qemu_iovec_init_buf(&qiov, buf, len);
82
83
ret = bdrv_co_preadv(s->bs->file, 0, qiov.size, &qiov, 0);
84
if (ret < 0) {
85
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qed_copy_from_backing_file(BDRVQEDState *s,
86
{
87
QEMUIOVector qiov;
88
QEMUIOVector *backing_qiov = NULL;
89
- struct iovec iov;
90
int ret;
91
92
/* Skip copy entirely if there is no work to do */
93
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qed_copy_from_backing_file(BDRVQEDState *s,
94
return 0;
95
}
96
97
- iov = (struct iovec) {
98
- .iov_base = qemu_blockalign(s->bs, len),
99
- .iov_len = len,
100
- };
101
- qemu_iovec_init_external(&qiov, &iov, 1);
102
+ qemu_iovec_init_buf(&qiov, qemu_blockalign(s->bs, len), len);
103
104
ret = qed_read_backing_file(s, pos, &qiov, &backing_qiov);
105
106
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qed_copy_from_backing_file(BDRVQEDState *s,
107
}
108
ret = 0;
109
out:
110
- qemu_vfree(iov.iov_base);
111
+ qemu_vfree(qemu_iovec_buf(&qiov));
112
return ret;
113
}
114
115
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_co_pwrite_zeroes(BlockDriverState *bs,
116
BdrvRequestFlags flags)
117
{
118
BDRVQEDState *s = bs->opaque;
119
- QEMUIOVector qiov;
120
- struct iovec iov;
121
+
122
+ /*
123
+ * Zero writes start without an I/O buffer. If a buffer becomes necessary
124
+ * then it will be allocated during request processing.
125
+ */
126
+ QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, NULL, bytes);
127
128
/* Fall back if the request is not aligned */
129
if (qed_offset_into_cluster(s, offset) ||
130
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_co_pwrite_zeroes(BlockDriverState *bs,
131
return -ENOTSUP;
132
}
133
134
- /* Zero writes start without an I/O buffer. If a buffer becomes necessary
135
- * then it will be allocated during request processing.
136
- */
137
- iov.iov_base = NULL;
138
- iov.iov_len = bytes;
139
-
140
- qemu_iovec_init_external(&qiov, &iov, 1);
141
return qed_co_request(bs, offset >> BDRV_SECTOR_BITS, &qiov,
142
bytes >> BDRV_SECTOR_BITS,
143
QED_AIOCB_WRITE | QED_AIOCB_ZERO);
144
--
145
2.20.1
146
147
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Use new qemu_iovec_init_buf() instead of
4
qemu_iovec_init_external( ... , 1), which simplifies the code.
5
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Message-id: 20190218140926.333779-12-vsementsov@virtuozzo.com
10
Message-Id: <20190218140926.333779-12-vsementsov@virtuozzo.com>
11
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
12
---
13
block/vmdk.c | 7 +------
14
1 file changed, 1 insertion(+), 6 deletions(-)
15
16
diff --git a/block/vmdk.c b/block/vmdk.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/block/vmdk.c
19
+++ b/block/vmdk.c
20
@@ -XXX,XX +XXX,XX @@ static int vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset,
21
VmdkGrainMarker *data = NULL;
22
uLongf buf_len;
23
QEMUIOVector local_qiov;
24
- struct iovec iov;
25
int64_t write_offset;
26
int64_t write_end_sector;
27
28
@@ -XXX,XX +XXX,XX @@ static int vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset,
29
data->size = cpu_to_le32(buf_len);
30
31
n_bytes = buf_len + sizeof(VmdkGrainMarker);
32
- iov = (struct iovec) {
33
- .iov_base = data,
34
- .iov_len = n_bytes,
35
- };
36
- qemu_iovec_init_external(&local_qiov, &iov, 1);
37
+ qemu_iovec_init_buf(&local_qiov, data, n_bytes);
38
39
BLKDBG_EVENT(extent->file, BLKDBG_WRITE_COMPRESSED);
40
} else {
41
--
42
2.20.1
43
44
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Use new qemu_iovec_init_buf() instead of
4
qemu_iovec_init_external( ... , 1), which simplifies the code.
5
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Message-id: 20190218140926.333779-13-vsementsov@virtuozzo.com
10
Message-Id: <20190218140926.333779-13-vsementsov@virtuozzo.com>
11
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
12
---
13
qemu-img.c | 10 ++--------
14
1 file changed, 2 insertions(+), 8 deletions(-)
15
16
diff --git a/qemu-img.c b/qemu-img.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/qemu-img.c
19
+++ b/qemu-img.c
20
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn convert_co_read(ImgConvertState *s, int64_t sector_num,
21
{
22
int n, ret;
23
QEMUIOVector qiov;
24
- struct iovec iov;
25
26
assert(nb_sectors <= s->buf_sectors);
27
while (nb_sectors > 0) {
28
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn convert_co_read(ImgConvertState *s, int64_t sector_num,
29
bs_sectors = s->src_sectors[src_cur];
30
31
n = MIN(nb_sectors, bs_sectors - (sector_num - src_cur_offset));
32
- iov.iov_base = buf;
33
- iov.iov_len = n << BDRV_SECTOR_BITS;
34
- qemu_iovec_init_external(&qiov, &iov, 1);
35
+ qemu_iovec_init_buf(&qiov, buf, n << BDRV_SECTOR_BITS);
36
37
ret = blk_co_preadv(
38
blk, (sector_num - src_cur_offset) << BDRV_SECTOR_BITS,
39
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn convert_co_write(ImgConvertState *s, int64_t sector_num,
40
{
41
int ret;
42
QEMUIOVector qiov;
43
- struct iovec iov;
44
45
while (nb_sectors > 0) {
46
int n = nb_sectors;
47
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn convert_co_write(ImgConvertState *s, int64_t sector_num,
48
(s->compressed &&
49
!buffer_is_zero(buf, n * BDRV_SECTOR_SIZE)))
50
{
51
- iov.iov_base = buf;
52
- iov.iov_len = n << BDRV_SECTOR_BITS;
53
- qemu_iovec_init_external(&qiov, &iov, 1);
54
+ qemu_iovec_init_buf(&qiov, buf, n << BDRV_SECTOR_BITS);
55
56
ret = blk_co_pwritev(s->target, sector_num << BDRV_SECTOR_BITS,
57
n << BDRV_SECTOR_BITS, &qiov, flags);
58
--
59
2.20.1
60
61
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Use new qemu_iovec_init_buf() instead of
4
qemu_iovec_init_external( ... , 1), which simplifies the code.
5
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Message-id: 20190218140926.333779-14-vsementsov@virtuozzo.com
10
Message-Id: <20190218140926.333779-14-vsementsov@virtuozzo.com>
11
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
12
---
13
migration/block.c | 10 +++-------
14
1 file changed, 3 insertions(+), 7 deletions(-)
15
16
diff --git a/migration/block.c b/migration/block.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/migration/block.c
19
+++ b/migration/block.c
20
@@ -XXX,XX +XXX,XX @@ typedef struct BlkMigBlock {
21
BlkMigDevState *bmds;
22
int64_t sector;
23
int nr_sectors;
24
- struct iovec iov;
25
QEMUIOVector qiov;
26
BlockAIOCB *aiocb;
27
28
@@ -XXX,XX +XXX,XX @@ static int mig_save_device_bulk(QEMUFile *f, BlkMigDevState *bmds)
29
blk->sector = cur_sector;
30
blk->nr_sectors = nr_sectors;
31
32
- blk->iov.iov_base = blk->buf;
33
- blk->iov.iov_len = nr_sectors * BDRV_SECTOR_SIZE;
34
- qemu_iovec_init_external(&blk->qiov, &blk->iov, 1);
35
+ qemu_iovec_init_buf(&blk->qiov, blk->buf, nr_sectors * BDRV_SECTOR_SIZE);
36
37
blk_mig_lock();
38
block_mig_state.submitted++;
39
@@ -XXX,XX +XXX,XX @@ static int mig_save_device_dirty(QEMUFile *f, BlkMigDevState *bmds,
40
blk->nr_sectors = nr_sectors;
41
42
if (is_async) {
43
- blk->iov.iov_base = blk->buf;
44
- blk->iov.iov_len = nr_sectors * BDRV_SECTOR_SIZE;
45
- qemu_iovec_init_external(&blk->qiov, &blk->iov, 1);
46
+ qemu_iovec_init_buf(&blk->qiov, blk->buf,
47
+ nr_sectors * BDRV_SECTOR_SIZE);
48
49
blk->aiocb = blk_aio_preadv(bmds->blk,
50
sector * BDRV_SECTOR_SIZE,
51
--
52
2.20.1
53
54
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Use new QEMU_IOVEC_INIT_BUF() instead of
4
qemu_iovec_init_external( ... , 1), which simplifies the code.
5
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Message-id: 20190218140926.333779-15-vsementsov@virtuozzo.com
10
Message-Id: <20190218140926.333779-15-vsementsov@virtuozzo.com>
11
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
12
---
13
tests/test-bdrv-drain.c | 29 ++++-------------------------
14
1 file changed, 4 insertions(+), 25 deletions(-)
15
16
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/tests/test-bdrv-drain.c
19
+++ b/tests/test-bdrv-drain.c
20
@@ -XXX,XX +XXX,XX @@ static void test_drv_cb_common(enum drain_type drain_type, bool recursive)
21
BlockAIOCB *acb;
22
int aio_ret;
23
24
- QEMUIOVector qiov;
25
- struct iovec iov = {
26
- .iov_base = NULL,
27
- .iov_len = 0,
28
- };
29
- qemu_iovec_init_external(&qiov, &iov, 1);
30
+ QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, NULL, 0);
31
32
blk = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
33
bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR,
34
@@ -XXX,XX +XXX,XX @@ static void test_iothread_common(enum drain_type drain_type, int drain_thread)
35
AioContext *ctx_a = iothread_get_aio_context(a);
36
AioContext *ctx_b = iothread_get_aio_context(b);
37
38
- QEMUIOVector qiov;
39
- struct iovec iov = {
40
- .iov_base = NULL,
41
- .iov_len = 0,
42
- };
43
- qemu_iovec_init_external(&qiov, &iov, 1);
44
+ QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, NULL, 0);
45
46
/* bdrv_drain_all() may only be called from the main loop thread */
47
if (drain_type == BDRV_DRAIN_ALL && drain_thread != 0) {
48
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn test_co_delete_by_drain(void *opaque)
49
BlockDriverState *bs = blk_bs(blk);
50
BDRVTestTopState *tts = bs->opaque;
51
void *buffer = g_malloc(65536);
52
- QEMUIOVector qiov;
53
- struct iovec iov = {
54
- .iov_base = buffer,
55
- .iov_len = 65536,
56
- };
57
-
58
- qemu_iovec_init_external(&qiov, &iov, 1);
59
+ QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buffer, 65536);
60
61
/* Pretend some internal write operation from parent to child.
62
* Important: We have to read from the child, not from the parent!
63
@@ -XXX,XX +XXX,XX @@ static void test_detach_indirect(bool by_parent_cb)
64
BdrvChild *child_a, *child_b;
65
BlockAIOCB *acb;
66
67
- QEMUIOVector qiov;
68
- struct iovec iov = {
69
- .iov_base = NULL,
70
- .iov_len = 0,
71
- };
72
- qemu_iovec_init_external(&qiov, &iov, 1);
73
+ QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, NULL, 0);
74
75
if (!by_parent_cb) {
76
detach_by_driver_cb_role = child_file;
77
--
78
2.20.1
79
80
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
@iov is used only to initialize @qiov. Let's use new
4
qemu_iovec_init_buf() instead, which simplifies the code.
5
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Message-id: 20190218140926.333779-16-vsementsov@virtuozzo.com
10
Message-Id: <20190218140926.333779-16-vsementsov@virtuozzo.com>
11
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
12
---
13
include/hw/ide/internal.h | 1 -
14
hw/ide/atapi.c | 9 ++++-----
15
hw/ide/core.c | 8 ++------
16
3 files changed, 6 insertions(+), 12 deletions(-)
17
18
diff --git a/include/hw/ide/internal.h b/include/hw/ide/internal.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/ide/internal.h
21
+++ b/include/hw/ide/internal.h
22
@@ -XXX,XX +XXX,XX @@ struct IDEState {
23
int atapi_dma; /* true if dma is requested for the packet cmd */
24
BlockAcctCookie acct;
25
BlockAIOCB *pio_aiocb;
26
- struct iovec iov;
27
QEMUIOVector qiov;
28
QLIST_HEAD(, IDEBufferedRequest) buffered_requests;
29
/* ATA DMA state */
30
diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/ide/atapi.c
33
+++ b/hw/ide/atapi.c
34
@@ -XXX,XX +XXX,XX @@ static void cd_read_sector_cb(void *opaque, int ret)
35
36
static int cd_read_sector(IDEState *s)
37
{
38
+ void *buf;
39
+
40
if (s->cd_sector_size != 2048 && s->cd_sector_size != 2352) {
41
block_acct_invalid(blk_get_stats(s->blk), BLOCK_ACCT_READ);
42
return -EINVAL;
43
}
44
45
- s->iov.iov_base = (s->cd_sector_size == 2352) ?
46
- s->io_buffer + 16 : s->io_buffer;
47
-
48
- s->iov.iov_len = ATAPI_SECTOR_SIZE;
49
- qemu_iovec_init_external(&s->qiov, &s->iov, 1);
50
+ buf = (s->cd_sector_size == 2352) ? s->io_buffer + 16 : s->io_buffer;
51
+ qemu_iovec_init_buf(&s->qiov, buf, ATAPI_SECTOR_SIZE);
52
53
trace_cd_read_sector(s->lba);
54
55
diff --git a/hw/ide/core.c b/hw/ide/core.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/hw/ide/core.c
58
+++ b/hw/ide/core.c
59
@@ -XXX,XX +XXX,XX @@ static void ide_sector_read(IDEState *s)
60
return;
61
}
62
63
- s->iov.iov_base = s->io_buffer;
64
- s->iov.iov_len = n * BDRV_SECTOR_SIZE;
65
- qemu_iovec_init_external(&s->qiov, &s->iov, 1);
66
+ qemu_iovec_init_buf(&s->qiov, s->io_buffer, n * BDRV_SECTOR_SIZE);
67
68
block_acct_start(blk_get_stats(s->blk), &s->acct,
69
n * BDRV_SECTOR_SIZE, BLOCK_ACCT_READ);
70
@@ -XXX,XX +XXX,XX @@ static void ide_sector_write(IDEState *s)
71
return;
72
}
73
74
- s->iov.iov_base = s->io_buffer;
75
- s->iov.iov_len = n * BDRV_SECTOR_SIZE;
76
- qemu_iovec_init_external(&s->qiov, &s->iov, 1);
77
+ qemu_iovec_init_buf(&s->qiov, s->io_buffer, n * BDRV_SECTOR_SIZE);
78
79
block_acct_start(blk_get_stats(s->blk), &s->acct,
80
n * BDRV_SECTOR_SIZE, BLOCK_ACCT_WRITE);
81
--
82
2.20.1
83
84
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
@iov is used only to initialize @qiov. Let's use new
4
qemu_iovec_init_buf() instead, which simplifies the code.
5
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Message-id: 20190218140926.333779-17-vsementsov@virtuozzo.com
10
Message-Id: <20190218140926.333779-17-vsementsov@virtuozzo.com>
11
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
12
---
13
include/hw/ide/internal.h | 1 -
14
hw/ide/core.c | 11 ++++++-----
15
2 files changed, 6 insertions(+), 6 deletions(-)
16
17
diff --git a/include/hw/ide/internal.h b/include/hw/ide/internal.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/ide/internal.h
20
+++ b/include/hw/ide/internal.h
21
@@ -XXX,XX +XXX,XX @@ extern const char *IDE_DMA_CMD_lookup[IDE_DMA__COUNT];
22
23
typedef struct IDEBufferedRequest {
24
QLIST_ENTRY(IDEBufferedRequest) list;
25
- struct iovec iov;
26
QEMUIOVector qiov;
27
QEMUIOVector *original_qiov;
28
BlockCompletionFunc *original_cb;
29
diff --git a/hw/ide/core.c b/hw/ide/core.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/ide/core.c
32
+++ b/hw/ide/core.c
33
@@ -XXX,XX +XXX,XX @@ static void ide_buffered_readv_cb(void *opaque, int ret)
34
IDEBufferedRequest *req = opaque;
35
if (!req->orphaned) {
36
if (!ret) {
37
- qemu_iovec_from_buf(req->original_qiov, 0, req->iov.iov_base,
38
+ assert(req->qiov.size == req->original_qiov->size);
39
+ qemu_iovec_from_buf(req->original_qiov, 0,
40
+ req->qiov.local_iov.iov_base,
41
req->original_qiov->size);
42
}
43
req->original_cb(req->original_opaque, ret);
44
}
45
QLIST_REMOVE(req, list);
46
- qemu_vfree(req->iov.iov_base);
47
+ qemu_vfree(qemu_iovec_buf(&req->qiov));
48
g_free(req);
49
}
50
51
@@ -XXX,XX +XXX,XX @@ BlockAIOCB *ide_buffered_readv(IDEState *s, int64_t sector_num,
52
req->original_qiov = iov;
53
req->original_cb = cb;
54
req->original_opaque = opaque;
55
- req->iov.iov_base = qemu_blockalign(blk_bs(s->blk), iov->size);
56
- req->iov.iov_len = iov->size;
57
- qemu_iovec_init_external(&req->qiov, &req->iov, 1);
58
+ qemu_iovec_init_buf(&req->qiov, blk_blockalign(s->blk, iov->size),
59
+ iov->size);
60
61
aioreq = blk_aio_preadv(s->blk, sector_num << BDRV_SECTOR_BITS,
62
&req->qiov, 0, ide_buffered_readv_cb, req);
63
--
64
2.20.1
65
66
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
@iov is used only to initialize @qiov. Let's use new
4
qemu_iovec_init_buf() instead, which simplifies the code.
5
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Message-id: 20190218140926.333779-18-vsementsov@virtuozzo.com
10
Message-Id: <20190218140926.333779-18-vsementsov@virtuozzo.com>
11
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
12
---
13
include/hw/ide/internal.h | 1 -
14
hw/ide/atapi.c | 5 ++---
15
2 files changed, 2 insertions(+), 4 deletions(-)
16
17
diff --git a/include/hw/ide/internal.h b/include/hw/ide/internal.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/ide/internal.h
20
+++ b/include/hw/ide/internal.h
21
@@ -XXX,XX +XXX,XX @@ struct IDEDMAOps {
22
23
struct IDEDMA {
24
const struct IDEDMAOps *ops;
25
- struct iovec iov;
26
QEMUIOVector qiov;
27
BlockAIOCB *aiocb;
28
};
29
diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/ide/atapi.c
32
+++ b/hw/ide/atapi.c
33
@@ -XXX,XX +XXX,XX @@ static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret)
34
data_offset = 0;
35
}
36
trace_ide_atapi_cmd_read_dma_cb_aio(s, s->lba, n);
37
- s->bus->dma->iov.iov_base = (void *)(s->io_buffer + data_offset);
38
- s->bus->dma->iov.iov_len = n * ATAPI_SECTOR_SIZE;
39
- qemu_iovec_init_external(&s->bus->dma->qiov, &s->bus->dma->iov, 1);
40
+ qemu_iovec_init_buf(&s->bus->dma->qiov, s->io_buffer + data_offset,
41
+ n * ATAPI_SECTOR_SIZE);
42
43
s->bus->dma->aiocb = ide_buffered_readv(s, (int64_t)s->lba << 2,
44
&s->bus->dma->qiov, n * 4,
45
--
46
2.20.1
47
48
diff view generated by jsdifflib
Deleted patch
1
From: Stefano Garzarella <sgarzare@redhat.com>
2
1
3
We add acct_failed param in order to use virtio_blk_handle_rw_error()
4
also when is not required to call block_acct_failed(). (eg. a discard
5
operation is failed)
6
7
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
10
Message-id: 20190221103314.58500-2-sgarzare@redhat.com
11
Message-Id: <20190221103314.58500-2-sgarzare@redhat.com>
12
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
13
---
14
hw/block/virtio-blk.c | 10 ++++++----
15
1 file changed, 6 insertions(+), 4 deletions(-)
16
17
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/block/virtio-blk.c
20
+++ b/hw/block/virtio-blk.c
21
@@ -XXX,XX +XXX,XX @@ static void virtio_blk_req_complete(VirtIOBlockReq *req, unsigned char status)
22
}
23
24
static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error,
25
- bool is_read)
26
+ bool is_read, bool acct_failed)
27
{
28
VirtIOBlock *s = req->dev;
29
BlockErrorAction action = blk_get_error_action(s->blk, is_read, error);
30
@@ -XXX,XX +XXX,XX @@ static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error,
31
s->rq = req;
32
} else if (action == BLOCK_ERROR_ACTION_REPORT) {
33
virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
34
- block_acct_failed(blk_get_stats(s->blk), &req->acct);
35
+ if (acct_failed) {
36
+ block_acct_failed(blk_get_stats(s->blk), &req->acct);
37
+ }
38
virtio_blk_free_request(req);
39
}
40
41
@@ -XXX,XX +XXX,XX @@ static void virtio_blk_rw_complete(void *opaque, int ret)
42
* the memory until the request is completed (which will
43
* happen on the other side of the migration).
44
*/
45
- if (virtio_blk_handle_rw_error(req, -ret, is_read)) {
46
+ if (virtio_blk_handle_rw_error(req, -ret, is_read, true)) {
47
continue;
48
}
49
}
50
@@ -XXX,XX +XXX,XX @@ static void virtio_blk_flush_complete(void *opaque, int ret)
51
52
aio_context_acquire(blk_get_aio_context(s->conf.conf.blk));
53
if (ret) {
54
- if (virtio_blk_handle_rw_error(req, -ret, 0)) {
55
+ if (virtio_blk_handle_rw_error(req, -ret, 0, true)) {
56
goto out;
57
}
58
}
59
--
60
2.20.1
61
62
diff view generated by jsdifflib
Deleted patch
1
From: Stefano Garzarella <sgarzare@redhat.com>
2
1
3
Since configurable features for virtio-blk are growing, this patch
4
adds host_features field in the struct VirtIOBlock. (as in virtio-net)
5
In this way, we can avoid to add new fields for new properties and
6
we can directly set VIRTIO_BLK_F* flags in the host_features.
7
8
We update "config-wce" and "scsi" property definition to use the new
9
host_features field without change the behaviour.
10
11
Suggested-by: Michael S. Tsirkin <mst@redhat.com>
12
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
13
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
14
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
15
Message-id: 20190221103314.58500-3-sgarzare@redhat.com
16
Message-Id: <20190221103314.58500-3-sgarzare@redhat.com>
17
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
18
---
19
include/hw/virtio/virtio-blk.h | 3 +--
20
hw/block/virtio-blk.c | 16 +++++++++-------
21
2 files changed, 10 insertions(+), 9 deletions(-)
22
23
diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/virtio/virtio-blk.h
26
+++ b/include/hw/virtio/virtio-blk.h
27
@@ -XXX,XX +XXX,XX @@ struct VirtIOBlkConf
28
BlockConf conf;
29
IOThread *iothread;
30
char *serial;
31
- uint32_t scsi;
32
- uint32_t config_wce;
33
uint32_t request_merging;
34
uint16_t num_queues;
35
uint16_t queue_size;
36
@@ -XXX,XX +XXX,XX @@ typedef struct VirtIOBlock {
37
bool dataplane_disabled;
38
bool dataplane_started;
39
struct VirtIOBlockDataPlane *dataplane;
40
+ uint64_t host_features;
41
} VirtIOBlock;
42
43
typedef struct VirtIOBlockReq {
44
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/block/virtio-blk.c
47
+++ b/hw/block/virtio-blk.c
48
@@ -XXX,XX +XXX,XX @@ static int virtio_blk_handle_scsi_req(VirtIOBlockReq *req)
49
*/
50
scsi = (void *)elem->in_sg[elem->in_num - 2].iov_base;
51
52
- if (!blk->conf.scsi) {
53
+ if (!virtio_has_feature(blk->host_features, VIRTIO_BLK_F_SCSI)) {
54
status = VIRTIO_BLK_S_UNSUPP;
55
goto fail;
56
}
57
@@ -XXX,XX +XXX,XX @@ static uint64_t virtio_blk_get_features(VirtIODevice *vdev, uint64_t features,
58
{
59
VirtIOBlock *s = VIRTIO_BLK(vdev);
60
61
+ /* Firstly sync all virtio-blk possible supported features */
62
+ features |= s->host_features;
63
+
64
virtio_add_feature(&features, VIRTIO_BLK_F_SEG_MAX);
65
virtio_add_feature(&features, VIRTIO_BLK_F_GEOMETRY);
66
virtio_add_feature(&features, VIRTIO_BLK_F_TOPOLOGY);
67
virtio_add_feature(&features, VIRTIO_BLK_F_BLK_SIZE);
68
if (virtio_has_feature(features, VIRTIO_F_VERSION_1)) {
69
- if (s->conf.scsi) {
70
+ if (virtio_has_feature(s->host_features, VIRTIO_BLK_F_SCSI)) {
71
error_setg(errp, "Please set scsi=off for virtio-blk devices in order to use virtio 1.0");
72
return 0;
73
}
74
@@ -XXX,XX +XXX,XX @@ static uint64_t virtio_blk_get_features(VirtIODevice *vdev, uint64_t features,
75
virtio_add_feature(&features, VIRTIO_BLK_F_SCSI);
76
}
77
78
- if (s->conf.config_wce) {
79
- virtio_add_feature(&features, VIRTIO_BLK_F_CONFIG_WCE);
80
- }
81
if (blk_enable_write_cache(s->blk)) {
82
virtio_add_feature(&features, VIRTIO_BLK_F_WCE);
83
}
84
@@ -XXX,XX +XXX,XX @@ static Property virtio_blk_properties[] = {
85
DEFINE_BLOCK_ERROR_PROPERTIES(VirtIOBlock, conf.conf),
86
DEFINE_BLOCK_CHS_PROPERTIES(VirtIOBlock, conf.conf),
87
DEFINE_PROP_STRING("serial", VirtIOBlock, conf.serial),
88
- DEFINE_PROP_BIT("config-wce", VirtIOBlock, conf.config_wce, 0, true),
89
+ DEFINE_PROP_BIT64("config-wce", VirtIOBlock, host_features,
90
+ VIRTIO_BLK_F_CONFIG_WCE, true),
91
#ifdef __linux__
92
- DEFINE_PROP_BIT("scsi", VirtIOBlock, conf.scsi, 0, false),
93
+ DEFINE_PROP_BIT64("scsi", VirtIOBlock, host_features,
94
+ VIRTIO_BLK_F_SCSI, false),
95
#endif
96
DEFINE_PROP_BIT("request-merging", VirtIOBlock, conf.request_merging, 0,
97
true),
98
--
99
2.20.1
100
101
diff view generated by jsdifflib
Deleted patch
1
From: Stefano Garzarella <sgarzare@redhat.com>
2
1
3
In order to avoid migration issues, we enable DISCARD and
4
WRITE_ZEROES features only for machine type >= 4.0
5
6
As discussed with Michael S. Tsirkin and Stefan Hajnoczi on the
7
list [1], DISCARD operation should not have security implications
8
(eg. page cache attacks), so we can enable it by default.
9
10
[1] https://lists.gnu.org/archive/html/qemu-devel/2019-02/msg00504.html
11
12
Suggested-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
13
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
14
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
15
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
16
Message-id: 20190221103314.58500-4-sgarzare@redhat.com
17
Message-Id: <20190221103314.58500-4-sgarzare@redhat.com>
18
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
19
---
20
hw/block/virtio-blk.c | 4 ++++
21
hw/core/machine.c | 2 ++
22
2 files changed, 6 insertions(+)
23
24
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/block/virtio-blk.c
27
+++ b/hw/block/virtio-blk.c
28
@@ -XXX,XX +XXX,XX @@ static Property virtio_blk_properties[] = {
29
DEFINE_PROP_UINT16("queue-size", VirtIOBlock, conf.queue_size, 128),
30
DEFINE_PROP_LINK("iothread", VirtIOBlock, conf.iothread, TYPE_IOTHREAD,
31
IOThread *),
32
+ DEFINE_PROP_BIT64("discard", VirtIOBlock, host_features,
33
+ VIRTIO_BLK_F_DISCARD, true),
34
+ DEFINE_PROP_BIT64("write-zeroes", VirtIOBlock, host_features,
35
+ VIRTIO_BLK_F_WRITE_ZEROES, true),
36
DEFINE_PROP_END_OF_LIST(),
37
};
38
39
diff --git a/hw/core/machine.c b/hw/core/machine.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/hw/core/machine.c
42
+++ b/hw/core/machine.c
43
@@ -XXX,XX +XXX,XX @@ GlobalProperty hw_compat_3_1[] = {
44
{ "usb-kbd", "serial", "42" },
45
{ "usb-mouse", "serial", "42" },
46
{ "usb-kbd", "serial", "42" },
47
+ { "virtio-blk-device", "discard", "false" },
48
+ { "virtio-blk-device", "write-zeroes", "false" },
49
};
50
const size_t hw_compat_3_1_len = G_N_ELEMENTS(hw_compat_3_1);
51
52
--
53
2.20.1
54
55
diff view generated by jsdifflib
Deleted patch
1
From: Stefano Garzarella <sgarzare@redhat.com>
2
1
3
In order to use VirtIOFeature also in other virtio devices, we move
4
its declaration and the endof() macro (renamed in virtio_endof())
5
in virtio.h.
6
We add virtio_feature_get_config_size() function to iterate the array
7
of VirtIOFeature and to return the config size depending on the
8
features enabled. (as virtio_net_set_config_size() did)
9
10
Suggested-by: Michael S. Tsirkin <mst@redhat.com>
11
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
12
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
13
Message-id: 20190221103314.58500-5-sgarzare@redhat.com
14
Message-Id: <20190221103314.58500-5-sgarzare@redhat.com>
15
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
16
---
17
include/hw/virtio/virtio.h | 15 +++++++++++++++
18
hw/net/virtio-net.c | 31 +++++++------------------------
19
hw/virtio/virtio.c | 15 +++++++++++++++
20
3 files changed, 37 insertions(+), 24 deletions(-)
21
22
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/virtio/virtio.h
25
+++ b/include/hw/virtio/virtio.h
26
@@ -XXX,XX +XXX,XX @@ static inline hwaddr vring_align(hwaddr addr,
27
return QEMU_ALIGN_UP(addr, align);
28
}
29
30
+/*
31
+ * Calculate the number of bytes up to and including the given 'field' of
32
+ * 'container'.
33
+ */
34
+#define virtio_endof(container, field) \
35
+ (offsetof(container, field) + sizeof_field(container, field))
36
+
37
+typedef struct VirtIOFeature {
38
+ uint64_t flags;
39
+ size_t end;
40
+} VirtIOFeature;
41
+
42
+size_t virtio_feature_get_config_size(VirtIOFeature *features,
43
+ uint64_t host_features);
44
+
45
typedef struct VirtQueue VirtQueue;
46
47
#define VIRTQUEUE_MAX_SIZE 1024
48
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/hw/net/virtio-net.c
51
+++ b/hw/net/virtio-net.c
52
@@ -XXX,XX +XXX,XX @@ static inline __virtio16 *virtio_net_rsc_ext_num_dupacks(
53
54
#endif
55
56
-/*
57
- * Calculate the number of bytes up to and including the given 'field' of
58
- * 'container'.
59
- */
60
-#define endof(container, field) \
61
- (offsetof(container, field) + sizeof_field(container, field))
62
-
63
-typedef struct VirtIOFeature {
64
- uint64_t flags;
65
- size_t end;
66
-} VirtIOFeature;
67
-
68
static VirtIOFeature feature_sizes[] = {
69
{.flags = 1ULL << VIRTIO_NET_F_MAC,
70
- .end = endof(struct virtio_net_config, mac)},
71
+ .end = virtio_endof(struct virtio_net_config, mac)},
72
{.flags = 1ULL << VIRTIO_NET_F_STATUS,
73
- .end = endof(struct virtio_net_config, status)},
74
+ .end = virtio_endof(struct virtio_net_config, status)},
75
{.flags = 1ULL << VIRTIO_NET_F_MQ,
76
- .end = endof(struct virtio_net_config, max_virtqueue_pairs)},
77
+ .end = virtio_endof(struct virtio_net_config, max_virtqueue_pairs)},
78
{.flags = 1ULL << VIRTIO_NET_F_MTU,
79
- .end = endof(struct virtio_net_config, mtu)},
80
+ .end = virtio_endof(struct virtio_net_config, mtu)},
81
{.flags = 1ULL << VIRTIO_NET_F_SPEED_DUPLEX,
82
- .end = endof(struct virtio_net_config, duplex)},
83
+ .end = virtio_endof(struct virtio_net_config, duplex)},
84
{}
85
};
86
87
@@ -XXX,XX +XXX,XX @@ static void virtio_net_guest_notifier_mask(VirtIODevice *vdev, int idx,
88
89
static void virtio_net_set_config_size(VirtIONet *n, uint64_t host_features)
90
{
91
- int i, config_size = 0;
92
virtio_add_feature(&host_features, VIRTIO_NET_F_MAC);
93
94
- for (i = 0; feature_sizes[i].flags != 0; i++) {
95
- if (host_features & feature_sizes[i].flags) {
96
- config_size = MAX(feature_sizes[i].end, config_size);
97
- }
98
- }
99
- n->config_size = config_size;
100
+ n->config_size = virtio_feature_get_config_size(feature_sizes,
101
+ host_features);
102
}
103
104
void virtio_net_set_netclient_name(VirtIONet *n, const char *name,
105
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
106
index XXXXXXX..XXXXXXX 100644
107
--- a/hw/virtio/virtio.c
108
+++ b/hw/virtio/virtio.c
109
@@ -XXX,XX +XXX,XX @@ int virtio_set_features(VirtIODevice *vdev, uint64_t val)
110
return ret;
111
}
112
113
+size_t virtio_feature_get_config_size(VirtIOFeature *feature_sizes,
114
+ uint64_t host_features)
115
+{
116
+ size_t config_size = 0;
117
+ int i;
118
+
119
+ for (i = 0; feature_sizes[i].flags != 0; i++) {
120
+ if (host_features & feature_sizes[i].flags) {
121
+ config_size = MAX(feature_sizes[i].end, config_size);
122
+ }
123
+ }
124
+
125
+ return config_size;
126
+}
127
+
128
int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
129
{
130
int i, ret;
131
--
132
2.20.1
133
134
diff view generated by jsdifflib
Deleted patch
1
From: Stefano Garzarella <sgarzare@redhat.com>
2
1
3
Starting from DISABLE and WRITE_ZEROES features, we use an array of
4
VirtIOFeature (as virtio-net) to properly set the config size
5
depending on the features enabled.
6
7
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
8
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
9
Message-id: 20190221103314.58500-6-sgarzare@redhat.com
10
Message-Id: <20190221103314.58500-6-sgarzare@redhat.com>
11
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
12
---
13
include/hw/virtio/virtio-blk.h | 1 +
14
hw/block/virtio-blk.c | 31 +++++++++++++++++++++++++------
15
2 files changed, 26 insertions(+), 6 deletions(-)
16
17
diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/virtio/virtio-blk.h
20
+++ b/include/hw/virtio/virtio-blk.h
21
@@ -XXX,XX +XXX,XX @@ typedef struct VirtIOBlock {
22
bool dataplane_started;
23
struct VirtIOBlockDataPlane *dataplane;
24
uint64_t host_features;
25
+ size_t config_size;
26
} VirtIOBlock;
27
28
typedef struct VirtIOBlockReq {
29
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/block/virtio-blk.c
32
+++ b/hw/block/virtio-blk.c
33
@@ -XXX,XX +XXX,XX @@
34
#include "hw/virtio/virtio-bus.h"
35
#include "hw/virtio/virtio-access.h"
36
37
-/* We don't support discard yet, hide associated config fields. */
38
+/* Config size before the discard support (hide associated config fields) */
39
#define VIRTIO_BLK_CFG_SIZE offsetof(struct virtio_blk_config, \
40
max_discard_sectors)
41
+/*
42
+ * Starting from the discard feature, we can use this array to properly
43
+ * set the config size depending on the features enabled.
44
+ */
45
+static VirtIOFeature feature_sizes[] = {
46
+ {.flags = 1ULL << VIRTIO_BLK_F_DISCARD,
47
+ .end = virtio_endof(struct virtio_blk_config, discard_sector_alignment)},
48
+ {.flags = 1ULL << VIRTIO_BLK_F_WRITE_ZEROES,
49
+ .end = virtio_endof(struct virtio_blk_config, write_zeroes_may_unmap)},
50
+ {}
51
+};
52
+
53
+static void virtio_blk_set_config_size(VirtIOBlock *s, uint64_t host_features)
54
+{
55
+ s->config_size = MAX(VIRTIO_BLK_CFG_SIZE,
56
+ virtio_feature_get_config_size(feature_sizes, host_features));
57
+
58
+ assert(s->config_size <= sizeof(struct virtio_blk_config));
59
+}
60
61
static void virtio_blk_init_request(VirtIOBlock *s, VirtQueue *vq,
62
VirtIOBlockReq *req)
63
@@ -XXX,XX +XXX,XX @@ static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config)
64
blkcfg.alignment_offset = 0;
65
blkcfg.wce = blk_enable_write_cache(s->blk);
66
virtio_stw_p(vdev, &blkcfg.num_queues, s->conf.num_queues);
67
- memcpy(config, &blkcfg, VIRTIO_BLK_CFG_SIZE);
68
- QEMU_BUILD_BUG_ON(VIRTIO_BLK_CFG_SIZE > sizeof(blkcfg));
69
+ memcpy(config, &blkcfg, s->config_size);
70
}
71
72
static void virtio_blk_set_config(VirtIODevice *vdev, const uint8_t *config)
73
@@ -XXX,XX +XXX,XX @@ static void virtio_blk_set_config(VirtIODevice *vdev, const uint8_t *config)
74
VirtIOBlock *s = VIRTIO_BLK(vdev);
75
struct virtio_blk_config blkcfg;
76
77
- memcpy(&blkcfg, config, VIRTIO_BLK_CFG_SIZE);
78
- QEMU_BUILD_BUG_ON(VIRTIO_BLK_CFG_SIZE > sizeof(blkcfg));
79
+ memcpy(&blkcfg, config, s->config_size);
80
81
aio_context_acquire(blk_get_aio_context(s->blk));
82
blk_set_enable_write_cache(s->blk, blkcfg.wce != 0);
83
@@ -XXX,XX +XXX,XX @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
84
return;
85
}
86
87
- virtio_init(vdev, "virtio-blk", VIRTIO_ID_BLOCK, VIRTIO_BLK_CFG_SIZE);
88
+ virtio_blk_set_config_size(s, s->host_features);
89
+
90
+ virtio_init(vdev, "virtio-blk", VIRTIO_ID_BLOCK, s->config_size);
91
92
s->blk = conf->conf.blk;
93
s->rq = NULL;
94
--
95
2.20.1
96
97
diff view generated by jsdifflib
Deleted patch
1
From: Stefano Garzarella <sgarzare@redhat.com>
2
1
3
This patch adds the support of DISCARD and WRITE_ZEROES commands,
4
that have been introduced in the virtio-blk protocol to have
5
better performance when using SSD backend.
6
7
We support only one segment per request since multiple segments
8
are not widely used and there are no userspace APIs that allow
9
applications to submit multiple segments in a single call.
10
11
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
12
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
13
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
14
Message-id: 20190221103314.58500-7-sgarzare@redhat.com
15
Message-Id: <20190221103314.58500-7-sgarzare@redhat.com>
16
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
17
---
18
include/hw/virtio/virtio-blk.h | 2 +
19
hw/block/virtio-blk.c | 184 +++++++++++++++++++++++++++++++++
20
2 files changed, 186 insertions(+)
21
22
diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/virtio/virtio-blk.h
25
+++ b/include/hw/virtio/virtio-blk.h
26
@@ -XXX,XX +XXX,XX @@ struct VirtIOBlkConf
27
uint32_t request_merging;
28
uint16_t num_queues;
29
uint16_t queue_size;
30
+ uint32_t max_discard_sectors;
31
+ uint32_t max_write_zeroes_sectors;
32
};
33
34
struct VirtIOBlockDataPlane;
35
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/block/virtio-blk.c
38
+++ b/hw/block/virtio-blk.c
39
@@ -XXX,XX +XXX,XX @@ out:
40
aio_context_release(blk_get_aio_context(s->conf.conf.blk));
41
}
42
43
+static void virtio_blk_discard_write_zeroes_complete(void *opaque, int ret)
44
+{
45
+ VirtIOBlockReq *req = opaque;
46
+ VirtIOBlock *s = req->dev;
47
+ bool is_write_zeroes = (virtio_ldl_p(VIRTIO_DEVICE(s), &req->out.type) &
48
+ ~VIRTIO_BLK_T_BARRIER) == VIRTIO_BLK_T_WRITE_ZEROES;
49
+
50
+ aio_context_acquire(blk_get_aio_context(s->conf.conf.blk));
51
+ if (ret) {
52
+ if (virtio_blk_handle_rw_error(req, -ret, false, is_write_zeroes)) {
53
+ goto out;
54
+ }
55
+ }
56
+
57
+ virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
58
+ if (is_write_zeroes) {
59
+ block_acct_done(blk_get_stats(s->blk), &req->acct);
60
+ }
61
+ virtio_blk_free_request(req);
62
+
63
+out:
64
+ aio_context_release(blk_get_aio_context(s->conf.conf.blk));
65
+}
66
+
67
#ifdef __linux__
68
69
typedef struct {
70
@@ -XXX,XX +XXX,XX @@ static bool virtio_blk_sect_range_ok(VirtIOBlock *dev,
71
return true;
72
}
73
74
+static uint8_t virtio_blk_handle_discard_write_zeroes(VirtIOBlockReq *req,
75
+ struct virtio_blk_discard_write_zeroes *dwz_hdr, bool is_write_zeroes)
76
+{
77
+ VirtIOBlock *s = req->dev;
78
+ VirtIODevice *vdev = VIRTIO_DEVICE(s);
79
+ uint64_t sector;
80
+ uint32_t num_sectors, flags, max_sectors;
81
+ uint8_t err_status;
82
+ int bytes;
83
+
84
+ sector = virtio_ldq_p(vdev, &dwz_hdr->sector);
85
+ num_sectors = virtio_ldl_p(vdev, &dwz_hdr->num_sectors);
86
+ flags = virtio_ldl_p(vdev, &dwz_hdr->flags);
87
+ max_sectors = is_write_zeroes ? s->conf.max_write_zeroes_sectors :
88
+ s->conf.max_discard_sectors;
89
+
90
+ /*
91
+ * max_sectors is at most BDRV_REQUEST_MAX_SECTORS, this check
92
+ * make us sure that "num_sectors << BDRV_SECTOR_BITS" can fit in
93
+ * the integer variable.
94
+ */
95
+ if (unlikely(num_sectors > max_sectors)) {
96
+ err_status = VIRTIO_BLK_S_IOERR;
97
+ goto err;
98
+ }
99
+
100
+ bytes = num_sectors << BDRV_SECTOR_BITS;
101
+
102
+ if (unlikely(!virtio_blk_sect_range_ok(s, sector, bytes))) {
103
+ err_status = VIRTIO_BLK_S_IOERR;
104
+ goto err;
105
+ }
106
+
107
+ /*
108
+ * The device MUST set the status byte to VIRTIO_BLK_S_UNSUPP for discard
109
+ * and write zeroes commands if any unknown flag is set.
110
+ */
111
+ if (unlikely(flags & ~VIRTIO_BLK_WRITE_ZEROES_FLAG_UNMAP)) {
112
+ err_status = VIRTIO_BLK_S_UNSUPP;
113
+ goto err;
114
+ }
115
+
116
+ if (is_write_zeroes) { /* VIRTIO_BLK_T_WRITE_ZEROES */
117
+ int blk_aio_flags = 0;
118
+
119
+ if (flags & VIRTIO_BLK_WRITE_ZEROES_FLAG_UNMAP) {
120
+ blk_aio_flags |= BDRV_REQ_MAY_UNMAP;
121
+ }
122
+
123
+ block_acct_start(blk_get_stats(s->blk), &req->acct, bytes,
124
+ BLOCK_ACCT_WRITE);
125
+
126
+ blk_aio_pwrite_zeroes(s->blk, sector << BDRV_SECTOR_BITS,
127
+ bytes, blk_aio_flags,
128
+ virtio_blk_discard_write_zeroes_complete, req);
129
+ } else { /* VIRTIO_BLK_T_DISCARD */
130
+ /*
131
+ * The device MUST set the status byte to VIRTIO_BLK_S_UNSUPP for
132
+ * discard commands if the unmap flag is set.
133
+ */
134
+ if (unlikely(flags & VIRTIO_BLK_WRITE_ZEROES_FLAG_UNMAP)) {
135
+ err_status = VIRTIO_BLK_S_UNSUPP;
136
+ goto err;
137
+ }
138
+
139
+ blk_aio_pdiscard(s->blk, sector << BDRV_SECTOR_BITS, bytes,
140
+ virtio_blk_discard_write_zeroes_complete, req);
141
+ }
142
+
143
+ return VIRTIO_BLK_S_OK;
144
+
145
+err:
146
+ if (is_write_zeroes) {
147
+ block_acct_invalid(blk_get_stats(s->blk), BLOCK_ACCT_WRITE);
148
+ }
149
+ return err_status;
150
+}
151
+
152
static int virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb)
153
{
154
uint32_t type;
155
@@ -XXX,XX +XXX,XX @@ static int virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb)
156
virtio_blk_free_request(req);
157
break;
158
}
159
+ /*
160
+ * VIRTIO_BLK_T_DISCARD and VIRTIO_BLK_T_WRITE_ZEROES are defined with
161
+ * VIRTIO_BLK_T_OUT flag set. We masked this flag in the switch statement,
162
+ * so we must mask it for these requests, then we will check if it is set.
163
+ */
164
+ case VIRTIO_BLK_T_DISCARD & ~VIRTIO_BLK_T_OUT:
165
+ case VIRTIO_BLK_T_WRITE_ZEROES & ~VIRTIO_BLK_T_OUT:
166
+ {
167
+ struct virtio_blk_discard_write_zeroes dwz_hdr;
168
+ size_t out_len = iov_size(out_iov, out_num);
169
+ bool is_write_zeroes = (type & ~VIRTIO_BLK_T_BARRIER) ==
170
+ VIRTIO_BLK_T_WRITE_ZEROES;
171
+ uint8_t err_status;
172
+
173
+ /*
174
+ * Unsupported if VIRTIO_BLK_T_OUT is not set or the request contains
175
+ * more than one segment.
176
+ */
177
+ if (unlikely(!(type & VIRTIO_BLK_T_OUT) ||
178
+ out_len > sizeof(dwz_hdr))) {
179
+ virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP);
180
+ virtio_blk_free_request(req);
181
+ return 0;
182
+ }
183
+
184
+ if (unlikely(iov_to_buf(out_iov, out_num, 0, &dwz_hdr,
185
+ sizeof(dwz_hdr)) != sizeof(dwz_hdr))) {
186
+ virtio_error(vdev, "virtio-blk discard/write_zeroes header"
187
+ " too short");
188
+ return -1;
189
+ }
190
+
191
+ err_status = virtio_blk_handle_discard_write_zeroes(req, &dwz_hdr,
192
+ is_write_zeroes);
193
+ if (err_status != VIRTIO_BLK_S_OK) {
194
+ virtio_blk_req_complete(req, err_status);
195
+ virtio_blk_free_request(req);
196
+ }
197
+
198
+ break;
199
+ }
200
default:
201
virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP);
202
virtio_blk_free_request(req);
203
@@ -XXX,XX +XXX,XX @@ static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config)
204
blkcfg.alignment_offset = 0;
205
blkcfg.wce = blk_enable_write_cache(s->blk);
206
virtio_stw_p(vdev, &blkcfg.num_queues, s->conf.num_queues);
207
+ if (virtio_has_feature(s->host_features, VIRTIO_BLK_F_DISCARD)) {
208
+ virtio_stl_p(vdev, &blkcfg.max_discard_sectors,
209
+ s->conf.max_discard_sectors);
210
+ virtio_stl_p(vdev, &blkcfg.discard_sector_alignment,
211
+ blk_size >> BDRV_SECTOR_BITS);
212
+ /*
213
+ * We support only one segment per request since multiple segments
214
+ * are not widely used and there are no userspace APIs that allow
215
+ * applications to submit multiple segments in a single call.
216
+ */
217
+ virtio_stl_p(vdev, &blkcfg.max_discard_seg, 1);
218
+ }
219
+ if (virtio_has_feature(s->host_features, VIRTIO_BLK_F_WRITE_ZEROES)) {
220
+ virtio_stl_p(vdev, &blkcfg.max_write_zeroes_sectors,
221
+ s->conf.max_write_zeroes_sectors);
222
+ blkcfg.write_zeroes_may_unmap = 1;
223
+ virtio_stl_p(vdev, &blkcfg.max_write_zeroes_seg, 1);
224
+ }
225
memcpy(config, &blkcfg, s->config_size);
226
}
227
228
@@ -XXX,XX +XXX,XX @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
229
return;
230
}
231
232
+ if (virtio_has_feature(s->host_features, VIRTIO_BLK_F_DISCARD) &&
233
+ (!conf->max_discard_sectors ||
234
+ conf->max_discard_sectors > BDRV_REQUEST_MAX_SECTORS)) {
235
+ error_setg(errp, "invalid max-discard-sectors property (%" PRIu32 ")"
236
+ ", must be between 1 and %d",
237
+ conf->max_discard_sectors, (int)BDRV_REQUEST_MAX_SECTORS);
238
+ return;
239
+ }
240
+
241
+ if (virtio_has_feature(s->host_features, VIRTIO_BLK_F_WRITE_ZEROES) &&
242
+ (!conf->max_write_zeroes_sectors ||
243
+ conf->max_write_zeroes_sectors > BDRV_REQUEST_MAX_SECTORS)) {
244
+ error_setg(errp, "invalid max-write-zeroes-sectors property (%" PRIu32
245
+ "), must be between 1 and %d",
246
+ conf->max_write_zeroes_sectors,
247
+ (int)BDRV_REQUEST_MAX_SECTORS);
248
+ return;
249
+ }
250
+
251
virtio_blk_set_config_size(s, s->host_features);
252
253
virtio_init(vdev, "virtio-blk", VIRTIO_ID_BLOCK, s->config_size);
254
@@ -XXX,XX +XXX,XX @@ static Property virtio_blk_properties[] = {
255
VIRTIO_BLK_F_DISCARD, true),
256
DEFINE_PROP_BIT64("write-zeroes", VirtIOBlock, host_features,
257
VIRTIO_BLK_F_WRITE_ZEROES, true),
258
+ DEFINE_PROP_UINT32("max-discard-sectors", VirtIOBlock,
259
+ conf.max_discard_sectors, BDRV_REQUEST_MAX_SECTORS),
260
+ DEFINE_PROP_UINT32("max-write-zeroes-sectors", VirtIOBlock,
261
+ conf.max_write_zeroes_sectors, BDRV_REQUEST_MAX_SECTORS),
262
DEFINE_PROP_END_OF_LIST(),
263
};
264
265
--
266
2.20.1
267
268
diff view generated by jsdifflib
Deleted patch
1
From: Stefano Garzarella <sgarzare@redhat.com>
2
1
3
The size of data in the virtio_blk_request must be a multiple
4
of 512 bytes for IN and OUT requests, or a multiple of the size
5
of struct virtio_blk_discard_write_zeroes for DISCARD and
6
WRITE_ZEROES requests.
7
8
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
9
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
10
Reviewed-by: Thomas Huth <thuth@redhat.com>
11
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
12
Message-id: 20190221103314.58500-8-sgarzare@redhat.com
13
Message-Id: <20190221103314.58500-8-sgarzare@redhat.com>
14
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
15
---
16
tests/virtio-blk-test.c | 15 ++++++++++++++-
17
1 file changed, 14 insertions(+), 1 deletion(-)
18
19
diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/tests/virtio-blk-test.c
22
+++ b/tests/virtio-blk-test.c
23
@@ -XXX,XX +XXX,XX @@ static uint64_t virtio_blk_request(QGuestAllocator *alloc, QVirtioDevice *d,
24
uint64_t addr;
25
uint8_t status = 0xFF;
26
27
- g_assert_cmpuint(data_size % 512, ==, 0);
28
+ switch (req->type) {
29
+ case VIRTIO_BLK_T_IN:
30
+ case VIRTIO_BLK_T_OUT:
31
+ g_assert_cmpuint(data_size % 512, ==, 0);
32
+ break;
33
+ case VIRTIO_BLK_T_DISCARD:
34
+ case VIRTIO_BLK_T_WRITE_ZEROES:
35
+ g_assert_cmpuint(data_size %
36
+ sizeof(struct virtio_blk_discard_write_zeroes), ==, 0);
37
+ break;
38
+ default:
39
+ g_assert_cmpuint(data_size, ==, 0);
40
+ }
41
+
42
addr = guest_alloc(alloc, sizeof(*req) + data_size);
43
44
virtio_blk_fix_request(d, req);
45
--
46
2.20.1
47
48
diff view generated by jsdifflib
Deleted patch
1
From: Stefano Garzarella <sgarzare@redhat.com>
2
1
3
This function is useful to fix the endianness of struct
4
virtio_blk_discard_write_zeroes headers.
5
6
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
7
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
8
Message-id: 20190221103314.58500-9-sgarzare@redhat.com
9
Message-Id: <20190221103314.58500-9-sgarzare@redhat.com>
10
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
11
---
12
tests/virtio-blk-test.c | 23 +++++++++++++++++------
13
1 file changed, 17 insertions(+), 6 deletions(-)
14
15
diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/tests/virtio-blk-test.c
18
+++ b/tests/virtio-blk-test.c
19
@@ -XXX,XX +XXX,XX @@ typedef struct QVirtioBlkReq {
20
uint8_t status;
21
} QVirtioBlkReq;
22
23
+#ifdef HOST_WORDS_BIGENDIAN
24
+const bool host_is_big_endian = true;
25
+#else
26
+const bool host_is_big_endian; /* false */
27
+#endif
28
+
29
static char *drive_create(void)
30
{
31
int fd, ret;
32
@@ -XXX,XX +XXX,XX @@ static QVirtioPCIDevice *virtio_blk_pci_init(QPCIBus *bus, int slot)
33
34
static inline void virtio_blk_fix_request(QVirtioDevice *d, QVirtioBlkReq *req)
35
{
36
-#ifdef HOST_WORDS_BIGENDIAN
37
- const bool host_is_big_endian = true;
38
-#else
39
- const bool host_is_big_endian = false;
40
-#endif
41
-
42
if (qvirtio_is_big_endian(d) != host_is_big_endian) {
43
req->type = bswap32(req->type);
44
req->ioprio = bswap32(req->ioprio);
45
@@ -XXX,XX +XXX,XX @@ static inline void virtio_blk_fix_request(QVirtioDevice *d, QVirtioBlkReq *req)
46
}
47
}
48
49
+
50
+static inline void virtio_blk_fix_dwz_hdr(QVirtioDevice *d,
51
+ struct virtio_blk_discard_write_zeroes *dwz_hdr)
52
+{
53
+ if (qvirtio_is_big_endian(d) != host_is_big_endian) {
54
+ dwz_hdr->sector = bswap64(dwz_hdr->sector);
55
+ dwz_hdr->num_sectors = bswap32(dwz_hdr->num_sectors);
56
+ dwz_hdr->flags = bswap32(dwz_hdr->flags);
57
+ }
58
+}
59
+
60
static uint64_t virtio_blk_request(QGuestAllocator *alloc, QVirtioDevice *d,
61
QVirtioBlkReq *req, uint64_t data_size)
62
{
63
--
64
2.20.1
65
66
diff view generated by jsdifflib
Deleted patch
1
From: Stefano Garzarella <sgarzare@redhat.com>
2
1
3
If the WRITE_ZEROES feature is enabled, we check this command
4
in the test_basic().
5
6
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
7
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
8
Acked-by: Thomas Huth <thuth@redhat.com>
9
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
10
Message-id: 20190221103314.58500-10-sgarzare@redhat.com
11
Message-Id: <20190221103314.58500-10-sgarzare@redhat.com>
12
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
13
---
14
tests/virtio-blk-test.c | 62 +++++++++++++++++++++++++++++++++++++++++
15
1 file changed, 62 insertions(+)
16
17
diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/tests/virtio-blk-test.c
20
+++ b/tests/virtio-blk-test.c
21
@@ -XXX,XX +XXX,XX @@ static void test_basic(QVirtioDevice *dev, QGuestAllocator *alloc,
22
23
guest_free(alloc, req_addr);
24
25
+ if (features & (1u << VIRTIO_BLK_F_WRITE_ZEROES)) {
26
+ struct virtio_blk_discard_write_zeroes dwz_hdr;
27
+ void *expected;
28
+
29
+ /*
30
+ * WRITE_ZEROES request on the same sector of previous test where
31
+ * we wrote "TEST".
32
+ */
33
+ req.type = VIRTIO_BLK_T_WRITE_ZEROES;
34
+ req.data = (char *) &dwz_hdr;
35
+ dwz_hdr.sector = 0;
36
+ dwz_hdr.num_sectors = 1;
37
+ dwz_hdr.flags = 0;
38
+
39
+ virtio_blk_fix_dwz_hdr(dev, &dwz_hdr);
40
+
41
+ req_addr = virtio_blk_request(alloc, dev, &req, sizeof(dwz_hdr));
42
+
43
+ free_head = qvirtqueue_add(vq, req_addr, 16, false, true);
44
+ qvirtqueue_add(vq, req_addr + 16, sizeof(dwz_hdr), false, true);
45
+ qvirtqueue_add(vq, req_addr + 16 + sizeof(dwz_hdr), 1, true, false);
46
+
47
+ qvirtqueue_kick(dev, vq, free_head);
48
+
49
+ qvirtio_wait_used_elem(dev, vq, free_head, NULL,
50
+ QVIRTIO_BLK_TIMEOUT_US);
51
+ status = readb(req_addr + 16 + sizeof(dwz_hdr));
52
+ g_assert_cmpint(status, ==, 0);
53
+
54
+ guest_free(alloc, req_addr);
55
+
56
+ /* Read request to check if the sector contains all zeroes */
57
+ req.type = VIRTIO_BLK_T_IN;
58
+ req.ioprio = 1;
59
+ req.sector = 0;
60
+ req.data = g_malloc0(512);
61
+
62
+ req_addr = virtio_blk_request(alloc, dev, &req, 512);
63
+
64
+ g_free(req.data);
65
+
66
+ free_head = qvirtqueue_add(vq, req_addr, 16, false, true);
67
+ qvirtqueue_add(vq, req_addr + 16, 512, true, true);
68
+ qvirtqueue_add(vq, req_addr + 528, 1, true, false);
69
+
70
+ qvirtqueue_kick(dev, vq, free_head);
71
+
72
+ qvirtio_wait_used_elem(dev, vq, free_head, NULL,
73
+ QVIRTIO_BLK_TIMEOUT_US);
74
+ status = readb(req_addr + 528);
75
+ g_assert_cmpint(status, ==, 0);
76
+
77
+ data = g_malloc(512);
78
+ expected = g_malloc0(512);
79
+ memread(req_addr + 16, data, 512);
80
+ g_assert_cmpmem(data, 512, expected, 512);
81
+ g_free(expected);
82
+ g_free(data);
83
+
84
+ guest_free(alloc, req_addr);
85
+ }
86
+
87
if (features & (1u << VIRTIO_F_ANY_LAYOUT)) {
88
/* Write and read with 2 descriptor layout */
89
/* Write request */
90
--
91
2.20.1
92
93
diff view generated by jsdifflib
1
From: Stefano Garzarella <sgarzare@redhat.com>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
If the DISCARD feature is enabled, we try this command in the
3
When the NVMe block driver was introduced (see commit bdd6a90a9e5,
4
test_basic(), checking only the status returned by the request.
4
January 2018), Linux VFIO_IOMMU_MAP_DMA ioctl was only returning
5
-ENOMEM in case of error. The driver was correctly handling the
6
error path to recycle its volatile IOVA mappings.
5
7
6
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
8
To fix CVE-2019-3882, Linux commit 492855939bdb ("vfio/type1: Limit
7
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
9
DMA mappings per container", April 2019) added the -ENOSPC error to
8
Message-id: 20190221103314.58500-11-sgarzare@redhat.com
10
signal the user exhausted the DMA mappings available for a container.
9
Message-Id: <20190221103314.58500-11-sgarzare@redhat.com>
11
12
The block driver started to mis-behave:
13
14
qemu-system-x86_64: VFIO_MAP_DMA failed: No space left on device
15
(qemu)
16
(qemu) info status
17
VM status: paused (io-error)
18
(qemu) c
19
VFIO_MAP_DMA failed: No space left on device
20
(qemu) c
21
VFIO_MAP_DMA failed: No space left on device
22
23
(The VM is not resumable from here, hence stuck.)
24
25
Fix by handling the new -ENOSPC error (when DMA mappings are
26
exhausted) without any distinction to the current -ENOMEM error,
27
so we don't change the behavior on old kernels where the CVE-2019-3882
28
fix is not present.
29
30
An easy way to reproduce this bug is to restrict the DMA mapping
31
limit (65535 by default) when loading the VFIO IOMMU module:
32
33
# modprobe vfio_iommu_type1 dma_entry_limit=666
34
35
Cc: qemu-stable@nongnu.org
36
Cc: Fam Zheng <fam@euphon.net>
37
Cc: Maxim Levitsky <mlevitsk@redhat.com>
38
Cc: Alex Williamson <alex.williamson@redhat.com>
39
Reported-by: Michal Prívozník <mprivozn@redhat.com>
40
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
41
Message-id: 20210723195843.1032825-1-philmd@redhat.com
42
Fixes: bdd6a90a9e5 ("block: Add VFIO based NVMe driver")
43
Buglink: https://bugs.launchpad.net/qemu/+bug/1863333
44
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/65
45
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
46
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
11
---
47
---
12
tests/virtio-blk-test.c | 27 +++++++++++++++++++++++++++
48
block/nvme.c | 22 ++++++++++++++++++++++
13
1 file changed, 27 insertions(+)
49
1 file changed, 22 insertions(+)
14
50
15
diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c
51
diff --git a/block/nvme.c b/block/nvme.c
16
index XXXXXXX..XXXXXXX 100644
52
index XXXXXXX..XXXXXXX 100644
17
--- a/tests/virtio-blk-test.c
53
--- a/block/nvme.c
18
+++ b/tests/virtio-blk-test.c
54
+++ b/block/nvme.c
19
@@ -XXX,XX +XXX,XX @@ static void test_basic(QVirtioDevice *dev, QGuestAllocator *alloc,
55
@@ -XXX,XX +XXX,XX @@ try_map:
20
guest_free(alloc, req_addr);
56
r = qemu_vfio_dma_map(s->vfio,
21
}
57
qiov->iov[i].iov_base,
22
58
len, true, &iova);
23
+ if (features & (1u << VIRTIO_BLK_F_DISCARD)) {
59
+ if (r == -ENOSPC) {
24
+ struct virtio_blk_discard_write_zeroes dwz_hdr;
60
+ /*
25
+
61
+ * In addition to the -ENOMEM error, the VFIO_IOMMU_MAP_DMA
26
+ req.type = VIRTIO_BLK_T_DISCARD;
62
+ * ioctl returns -ENOSPC to signal the user exhausted the DMA
27
+ req.data = (char *) &dwz_hdr;
63
+ * mappings available for a container since Linux kernel commit
28
+ dwz_hdr.sector = 0;
64
+ * 492855939bdb ("vfio/type1: Limit DMA mappings per container",
29
+ dwz_hdr.num_sectors = 1;
65
+ * April 2019, see CVE-2019-3882).
30
+ dwz_hdr.flags = 0;
66
+ *
31
+
67
+ * This block driver already handles this error path by checking
32
+ virtio_blk_fix_dwz_hdr(dev, &dwz_hdr);
68
+ * for the -ENOMEM error, so we directly replace -ENOSPC by
33
+
69
+ * -ENOMEM. Beside, -ENOSPC has a specific meaning for blockdev
34
+ req_addr = virtio_blk_request(alloc, dev, &req, sizeof(dwz_hdr));
70
+ * coroutines: it triggers BLOCKDEV_ON_ERROR_ENOSPC and
35
+
71
+ * BLOCK_ERROR_ACTION_STOP which stops the VM, asking the operator
36
+ free_head = qvirtqueue_add(vq, req_addr, 16, false, true);
72
+ * to add more storage to the blockdev. Not something we can do
37
+ qvirtqueue_add(vq, req_addr + 16, sizeof(dwz_hdr), false, true);
73
+ * easily with an IOMMU :)
38
+ qvirtqueue_add(vq, req_addr + 16 + sizeof(dwz_hdr), 1, true, false);
74
+ */
39
+
75
+ r = -ENOMEM;
40
+ qvirtqueue_kick(dev, vq, free_head);
76
+ }
41
+
77
if (r == -ENOMEM && retry) {
42
+ qvirtio_wait_used_elem(dev, vq, free_head, NULL,
78
+ /*
43
+ QVIRTIO_BLK_TIMEOUT_US);
79
+ * We exhausted the DMA mappings available for our container:
44
+ status = readb(req_addr + 16 + sizeof(dwz_hdr));
80
+ * recycle the volatile IOVA mappings.
45
+ g_assert_cmpint(status, ==, 0);
81
+ */
46
+
82
retry = false;
47
+ guest_free(alloc, req_addr);
83
trace_nvme_dma_flush_queue_wait(s);
48
+ }
84
if (s->dma_map_count) {
49
+
50
if (features & (1u << VIRTIO_F_ANY_LAYOUT)) {
51
/* Write and read with 2 descriptor layout */
52
/* Write request */
53
--
85
--
54
2.20.1
86
2.31.1
55
87
56
diff view generated by jsdifflib