1
The following changes since commit fc3dbb90f2eb069801bfb4cfe9cbc83cf9c5f4a9:
1
The following changes since commit ed8ad9728a9c0eec34db9dff61dfa2f1dd625637:
2
2
3
Merge remote-tracking branch 'remotes/jnsnow/tags/bitmaps-pull-request' into staging (2019-02-21 13:09:33 +0000)
3
Merge tag 'pull-tpm-2023-07-14-1' of https://github.com/stefanberger/qemu-tpm into staging (2023-07-15 14:54:04 +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 66547f416a61e0cb711dc76821890242432ba193:
10
10
11
tests/virtio-blk: add test for DISCARD command (2019-02-22 09:42:17 +0000)
11
block/nvme: invoke blk_io_plug_call() outside q->lock (2023-07-17 09:17:41 -0400)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Pull request
14
Pull request
15
15
16
Fix the hang in the nvme:// block driver during startup.
17
16
----------------------------------------------------------------
18
----------------------------------------------------------------
17
19
18
Stefano Garzarella (10):
20
Stefan Hajnoczi (1):
19
virtio-blk: add acct_failed param to virtio_blk_handle_rw_error()
21
block/nvme: invoke blk_io_plug_call() outside q->lock
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 | 3 ++-
31
block: enhance QEMUIOVector structure
24
1 file changed, 2 insertions(+), 1 deletion(-)
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.40.1
78
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
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
blk_io_plug_call() is invoked outside a blk_io_plug()/blk_io_unplug()
2
section while opening the NVMe drive from:
2
3
3
Use new qemu_iovec_init_buf() instead of
4
nvme_file_open() ->
4
qemu_iovec_init_external( ... , 1), which simplifies the code.
5
nvme_init() ->
6
nvme_identify() ->
7
nvme_admin_cmd_sync() ->
8
nvme_submit_command() ->
9
blk_io_plug_call()
5
10
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
11
blk_io_plug_call() immediately invokes the given callback when the
7
Reviewed-by: Eric Blake <eblake@redhat.com>
12
current thread is not plugged, as is the case during nvme_file_open().
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
13
9
Message-id: 20190218140926.333779-11-vsementsov@virtuozzo.com
14
Unfortunately, nvme_submit_command() calls blk_io_plug_call() with
10
Message-Id: <20190218140926.333779-11-vsementsov@virtuozzo.com>
15
q->lock still held:
16
17
...
18
q->sq.tail = (q->sq.tail + 1) % NVME_QUEUE_SIZE;
19
q->need_kick++;
20
blk_io_plug_call(nvme_unplug_fn, q);
21
qemu_mutex_unlock(&q->lock);
22
^^^^^^^^^^^^^^^^^^^^^^^^^^^
23
24
nvme_unplug_fn() deadlocks trying to acquire q->lock because the lock is
25
already acquired by the same thread. The symptom is that QEMU hangs
26
during startup while opening the NVMe drive.
27
28
Fix this by moving the blk_io_plug_call() outside q->lock. This is safe
29
because no other thread runs code related to this queue and
30
blk_io_plug_call()'s internal state is immune to thread safety issues
31
since it is thread-local.
32
33
Reported-by: Lukáš Doktor <ldoktor@redhat.com>
34
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
35
Tested-by: Lukas Doktor <ldoktor@redhat.com>
36
Message-id: 20230712191628.252806-1-stefanha@redhat.com
37
Fixes: f2e590002bd6 ("block/nvme: convert to blk_io_plug_call() API")
11
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
38
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
12
---
39
---
13
block/qed-table.c | 16 +++-------------
40
block/nvme.c | 3 ++-
14
block/qed.c | 31 +++++++++----------------------
41
1 file changed, 2 insertions(+), 1 deletion(-)
15
2 files changed, 12 insertions(+), 35 deletions(-)
16
42
17
diff --git a/block/qed-table.c b/block/qed-table.c
43
diff --git a/block/nvme.c b/block/nvme.c
18
index XXXXXXX..XXXXXXX 100644
44
index XXXXXXX..XXXXXXX 100644
19
--- a/block/qed-table.c
45
--- a/block/nvme.c
20
+++ b/block/qed-table.c
46
+++ b/block/nvme.c
21
@@ -XXX,XX +XXX,XX @@
47
@@ -XXX,XX +XXX,XX @@ static void nvme_submit_command(NVMeQueuePair *q, NVMeRequest *req,
22
/* Called with table_lock held. */
48
q->sq.tail * NVME_SQ_ENTRY_BYTES, cmd, sizeof(*cmd));
23
static int qed_read_table(BDRVQEDState *s, uint64_t offset, QEDTable *table)
49
q->sq.tail = (q->sq.tail + 1) % NVME_QUEUE_SIZE;
24
{
50
q->need_kick++;
25
- QEMUIOVector qiov;
51
+ qemu_mutex_unlock(&q->lock);
26
+ QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(
52
+
27
+ qiov, table->offsets, s->header.cluster_size * s->header.table_size);
53
blk_io_plug_call(nvme_unplug_fn, q);
28
int noffsets;
54
- qemu_mutex_unlock(&q->lock);
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
}
55
}
114
56
115
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_co_pwrite_zeroes(BlockDriverState *bs,
57
static void nvme_admin_cmd_sync_cb(void *opaque, int ret)
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
--
58
--
145
2.20.1
59
2.40.1
146
60
147
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-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
Deleted patch
1
From: Stefano Garzarella <sgarzare@redhat.com>
2
1
3
If the DISCARD feature is enabled, we try this command in the
4
test_basic(), checking only the status returned by the request.
5
6
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
7
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
8
Message-id: 20190221103314.58500-11-sgarzare@redhat.com
9
Message-Id: <20190221103314.58500-11-sgarzare@redhat.com>
10
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
11
---
12
tests/virtio-blk-test.c | 27 +++++++++++++++++++++++++++
13
1 file changed, 27 insertions(+)
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 @@ static void test_basic(QVirtioDevice *dev, QGuestAllocator *alloc,
20
guest_free(alloc, req_addr);
21
}
22
23
+ if (features & (1u << VIRTIO_BLK_F_DISCARD)) {
24
+ struct virtio_blk_discard_write_zeroes dwz_hdr;
25
+
26
+ req.type = VIRTIO_BLK_T_DISCARD;
27
+ req.data = (char *) &dwz_hdr;
28
+ dwz_hdr.sector = 0;
29
+ dwz_hdr.num_sectors = 1;
30
+ dwz_hdr.flags = 0;
31
+
32
+ virtio_blk_fix_dwz_hdr(dev, &dwz_hdr);
33
+
34
+ req_addr = virtio_blk_request(alloc, dev, &req, sizeof(dwz_hdr));
35
+
36
+ free_head = qvirtqueue_add(vq, req_addr, 16, false, true);
37
+ qvirtqueue_add(vq, req_addr + 16, sizeof(dwz_hdr), false, true);
38
+ qvirtqueue_add(vq, req_addr + 16 + sizeof(dwz_hdr), 1, true, false);
39
+
40
+ qvirtqueue_kick(dev, vq, free_head);
41
+
42
+ qvirtio_wait_used_elem(dev, vq, free_head, NULL,
43
+ QVIRTIO_BLK_TIMEOUT_US);
44
+ status = readb(req_addr + 16 + sizeof(dwz_hdr));
45
+ g_assert_cmpint(status, ==, 0);
46
+
47
+ guest_free(alloc, req_addr);
48
+ }
49
+
50
if (features & (1u << VIRTIO_F_ANY_LAYOUT)) {
51
/* Write and read with 2 descriptor layout */
52
/* Write request */
53
--
54
2.20.1
55
56
diff view generated by jsdifflib