1
The following changes since commit fc3dbb90f2eb069801bfb4cfe9cbc83cf9c5f4a9:
1
The following changes since commit 417296c8d8588f782018d01a317f88957e9786d6:
2
2
3
Merge remote-tracking branch 'remotes/jnsnow/tags/bitmaps-pull-request' into staging (2019-02-21 13:09:33 +0000)
3
tests/qtest/netdev-socket: Raise connection timeout to 60 seconds (2023-02-09 11:23:53 +0000)
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 acbc8aee5b09222dc6a5cb88306b67bcbe37e30b:
10
10
11
tests/virtio-blk: add test for DISCARD command (2019-02-22 09:42:17 +0000)
11
iotests/detect-zeroes-registered-buf: add new test (2023-02-09 10:22:30 -0500)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Pull request
14
Pull request
15
15
16
A few fixes that I've picked up.
17
16
----------------------------------------------------------------
18
----------------------------------------------------------------
17
19
18
Stefano Garzarella (10):
20
Akihiko Odaki (1):
19
virtio-blk: add acct_failed param to virtio_blk_handle_rw_error()
21
vhost-user-fs: Back up vqs before cleaning up vhost_dev
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
Emanuele Giuseppe Esposito (1):
31
block: enhance QEMUIOVector structure
24
virtio-blk: add missing AioContext lock
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
25
49
include/hw/ide/internal.h | 3 -
26
Stefan Hajnoczi (4):
50
include/hw/virtio/virtio-blk.h | 6 +-
27
block: fix detect-zeroes= with BDRV_REQ_REGISTERED_BUF
51
include/hw/virtio/virtio.h | 15 ++
28
qemu-io: use BdrvRequestFlags instead of int
52
include/qemu/iov.h | 64 ++++++++-
29
qemu-io: add -r option to register I/O buffer
53
block/backup.c | 5 +-
30
iotests/detect-zeroes-registered-buf: add new test
54
block/block-backend.c | 13 +-
31
55
block/commit.c | 7 +-
32
block/io.c | 3 +
56
block/io.c | 89 +++---------
33
hw/block/virtio-blk.c | 5 +
57
block/parallels.c | 13 +-
34
hw/virtio/vhost-user-fs.c | 4 +-
58
block/qcow.c | 21 +--
35
qemu-io-cmds.c | 215 +++++++++++-------
59
block/qcow2.c | 12 +-
36
.../tests/detect-zeroes-registered-buf | 58 +++++
60
block/qed-table.c | 16 +--
37
.../tests/detect-zeroes-registered-buf.out | 7 +
61
block/qed.c | 31 ++---
38
6 files changed, 210 insertions(+), 82 deletions(-)
62
block/stream.c | 7 +-
39
create mode 100755 tests/qemu-iotests/tests/detect-zeroes-registered-buf
63
block/vmdk.c | 7 +-
40
create mode 100644 tests/qemu-iotests/tests/detect-zeroes-registered-buf.out
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
41
76
--
42
--
77
2.20.1
43
2.39.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
1
From: Stefano Garzarella <sgarzare@redhat.com>
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
2
3
This function is useful to fix the endianness of struct
3
vhost_dev_cleanup() clears vhost_dev so back up its vqs member to free
4
virtio_blk_discard_write_zeroes headers.
4
the memory pointed by the member.
5
5
6
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
6
Fixes: 98fc1ada4c ("virtio: add vhost-user-fs base device")
7
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
7
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.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>
8
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Message-Id: <20230130140225.77964-1-akihiko.odaki@daynix.com>
11
---
10
---
12
tests/virtio-blk-test.c | 23 +++++++++++++++++------
11
hw/virtio/vhost-user-fs.c | 4 ++--
13
1 file changed, 17 insertions(+), 6 deletions(-)
12
1 file changed, 2 insertions(+), 2 deletions(-)
14
13
15
diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c
14
diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/tests/virtio-blk-test.c
16
--- a/hw/virtio/vhost-user-fs.c
18
+++ b/tests/virtio-blk-test.c
17
+++ b/hw/virtio/vhost-user-fs.c
19
@@ -XXX,XX +XXX,XX @@ typedef struct QVirtioBlkReq {
18
@@ -XXX,XX +XXX,XX @@ static void vuf_device_unrealize(DeviceState *dev)
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
{
19
{
31
int fd, ret;
20
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
32
@@ -XXX,XX +XXX,XX @@ static QVirtioPCIDevice *virtio_blk_pci_init(QPCIBus *bus, int slot)
21
VHostUserFS *fs = VHOST_USER_FS(dev);
33
22
+ struct vhost_virtqueue *vhost_vqs = fs->vhost_dev.vqs;
34
static inline void virtio_blk_fix_request(QVirtioDevice *d, QVirtioBlkReq *req)
23
int i;
35
{
24
36
-#ifdef HOST_WORDS_BIGENDIAN
25
/* This will stop vhost backend if appropriate. */
37
- const bool host_is_big_endian = true;
26
@@ -XXX,XX +XXX,XX @@ static void vuf_device_unrealize(DeviceState *dev)
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
}
27
}
28
g_free(fs->req_vqs);
29
virtio_cleanup(vdev);
30
- g_free(fs->vhost_dev.vqs);
31
- fs->vhost_dev.vqs = NULL;
32
+ g_free(vhost_vqs);
47
}
33
}
48
34
49
+
35
static struct vhost_dev *vuf_get_vhost(VirtIODevice *vdev)
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
--
36
--
64
2.20.1
37
2.39.1
65
66
diff view generated by jsdifflib
1
From: Stefano Garzarella <sgarzare@redhat.com>
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
2
2
3
We add acct_failed param in order to use virtio_blk_handle_rw_error()
3
virtio_blk_update_config() calls blk_get_geometry and blk_getlength,
4
also when is not required to call block_acct_failed(). (eg. a discard
4
and both functions eventually end up calling bdrv_poll_co when not
5
operation is failed)
5
running in a coroutine:
6
- blk_getlength is a co_wrapper_mixed function
7
- blk_get_geometry calls bdrv_get_geometry -> bdrv_nb_sectors, a
8
co_wrapper_mixed function too
6
9
7
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
10
Since we are not running in a coroutine, we need to take s->blk
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
11
AioContext lock, otherwise bdrv_poll_co will inevitably call
9
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
12
AIO_WAIT_WHILE and therefore try to un unlock() an AioContext lock
10
Message-id: 20190221103314.58500-2-sgarzare@redhat.com
13
that was never acquired.
11
Message-Id: <20190221103314.58500-2-sgarzare@redhat.com>
14
15
RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=2167838
16
17
Steps to reproduce the issue: simply boot a VM with
18
-object '{"qom-type":"iothread","id":"iothread1"}' \
19
-blockdev '{"driver":"file","filename":"$QCOW2","aio":"native","node-name":"libvirt-1-storage","cache":{"direct":true,"no-flush":false},"auto-read-only":true,"discard":"unmap"}' \
20
-blockdev '{"node-name":"libvirt-1-format","read-only":false,"cache":{"direct":true,"no-flush":false},"driver":"qcow2","file":"libvirt-1-storage"}' \
21
-device virtio-blk-pci,iothread=iothread1,drive=libvirt-1-format,id=virtio-disk0,bootindex=1,write-cache=on
22
23
and observe that it will fail not manage to boot with "qemu_mutex_unlock_impl: Operation not permitted"
24
25
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
26
Acked-by: Michael S. Tsirkin <mst@redhat.com>
27
Tested-by: Lukáš Doktor <ldoktor@redhat.com>
12
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
28
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
29
Message-Id: <20230208111148.1040083-1-eesposit@redhat.com>
13
---
30
---
14
hw/block/virtio-blk.c | 10 ++++++----
31
hw/block/virtio-blk.c | 5 +++++
15
1 file changed, 6 insertions(+), 4 deletions(-)
32
1 file changed, 5 insertions(+)
16
33
17
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
34
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
18
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/block/virtio-blk.c
36
--- a/hw/block/virtio-blk.c
20
+++ b/hw/block/virtio-blk.c
37
+++ b/hw/block/virtio-blk.c
21
@@ -XXX,XX +XXX,XX @@ static void virtio_blk_req_complete(VirtIOBlockReq *req, unsigned char status)
38
@@ -XXX,XX +XXX,XX @@ static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config)
22
}
39
uint64_t capacity;
23
40
int64_t length;
24
static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error,
41
int blk_size = conf->logical_block_size;
25
- bool is_read)
42
+ AioContext *ctx;
26
+ bool is_read, bool acct_failed)
43
+
27
{
44
+ ctx = blk_get_aio_context(s->blk);
28
VirtIOBlock *s = req->dev;
45
+ aio_context_acquire(ctx);
29
BlockErrorAction action = blk_get_error_action(s->blk, is_read, error);
46
30
@@ -XXX,XX +XXX,XX @@ static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error,
47
blk_get_geometry(s->blk, &capacity);
31
s->rq = req;
48
memset(&blkcfg, 0, sizeof(blkcfg));
32
} else if (action == BLOCK_ERROR_ACTION_REPORT) {
49
@@ -XXX,XX +XXX,XX @@ static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config)
33
virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
50
* per track (cylinder).
34
- block_acct_failed(blk_get_stats(s->blk), &req->acct);
51
*/
35
+ if (acct_failed) {
52
length = blk_getlength(s->blk);
36
+ block_acct_failed(blk_get_stats(s->blk), &req->acct);
53
+ aio_context_release(ctx);
37
+ }
54
if (length > 0 && length / conf->heads / conf->secs % blk_size) {
38
virtio_blk_free_request(req);
55
blkcfg.geometry.sectors = conf->secs & ~s->sector_mask;
39
}
56
} else {
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
--
57
--
60
2.20.1
58
2.39.1
61
59
62
60
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
When a write request is converted into a write zeroes request by the
2
detect-zeroes= feature, it is no longer associated with an I/O buffer.
3
The BDRV_REQ_REGISTERED_BUF flag doesn't make sense without an I/O
4
buffer and must be cleared because bdrv_co_do_pwrite_zeroes() fails with
5
-EINVAL when it's set.
2
6
3
Use new qemu_iovec_init_buf() instead of
7
Fiona Ebner <f.ebner@proxmox.com> bisected and diagnosed this QEMU 7.2
4
qemu_iovec_init_external( ... , 1), which simplifies the code.
8
regression where writes containing zeroes to a blockdev with
9
discard=unmap,detect-zeroes=unmap fail.
5
10
6
While being here, use qemu_try_blockalign0 as well.
11
Buglink: https://gitlab.com/qemu-project/qemu/-/issues/1404
7
12
Fixes: e8b6535533be ("block: add BDRV_REQ_REGISTERED_BUF request flag")
8
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
13
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
14
Cc: qemu-stable@nongnu.org
9
Reviewed-by: Eric Blake <eblake@redhat.com>
15
Reviewed-by: Eric Blake <eblake@redhat.com>
10
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
16
Reviewed-by: Hanna Czenczek <hreitz@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>
17
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
18
Message-Id: <20230207203719.242926-2-stefanha@redhat.com>
14
---
19
---
15
block/io.c | 89 ++++++++++++------------------------------------------
20
block/io.c | 3 +++
16
1 file changed, 20 insertions(+), 69 deletions(-)
21
1 file changed, 3 insertions(+)
17
22
18
diff --git a/block/io.c b/block/io.c
23
diff --git a/block/io.c b/block/io.c
19
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
20
--- a/block/io.c
25
--- a/block/io.c
21
+++ b/block/io.c
26
+++ b/block/io.c
22
@@ -XXX,XX +XXX,XX @@ static int bdrv_prwv_co(BdrvChild *child, int64_t offset,
27
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child,
23
static int bdrv_rw_co(BdrvChild *child, int64_t sector_num, uint8_t *buf,
28
if (bs->detect_zeroes == BLOCKDEV_DETECT_ZEROES_OPTIONS_UNMAP) {
24
int nb_sectors, bool is_write, BdrvRequestFlags flags)
29
flags |= BDRV_REQ_MAY_UNMAP;
25
{
30
}
26
- QEMUIOVector qiov;
31
+
27
- struct iovec iov = {
32
+ /* Can't use optimization hint with bufferless zero write */
28
- .iov_base = (void *)buf,
33
+ flags &= ~BDRV_REQ_REGISTERED_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
}
34
}
37
35
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) {
36
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
--
37
--
260
2.20.1
38
2.39.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
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
1
From: Stefano Garzarella <sgarzare@redhat.com>
1
The block layer APIs use BdrvRequestFlags while qemu-io code uses int.
2
Although the code compiles and runs fine, BdrvRequestFlags is clearer
3
because it differentiates between other types of flags like bdrv_open()
4
flags.
2
5
3
This patch adds the support of DISCARD and WRITE_ZEROES commands,
6
This is purely refactoring.
4
that have been introduced in the virtio-blk protocol to have
5
better performance when using SSD backend.
6
7
7
We support only one segment per request since multiple segments
8
Reviewed-by: Eric Blake <eblake@redhat.com>
8
are not widely used and there are no userspace APIs that allow
9
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
9
applications to submit multiple segments in a single call.
10
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
11
Message-Id: <20230207203719.242926-3-stefanha@redhat.com>
12
---
13
qemu-io-cmds.c | 13 +++++++------
14
1 file changed, 7 insertions(+), 6 deletions(-)
10
15
11
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
16
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
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
17
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/virtio/virtio-blk.h
18
--- a/qemu-io-cmds.c
25
+++ b/include/hw/virtio/virtio-blk.h
19
+++ b/qemu-io-cmds.c
26
@@ -XXX,XX +XXX,XX @@ struct VirtIOBlkConf
20
@@ -XXX,XX +XXX,XX @@ static int do_pread(BlockBackend *blk, char *buf, int64_t offset,
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
}
21
}
42
22
43
+static void virtio_blk_discard_write_zeroes_complete(void *opaque, int ret)
23
static int do_pwrite(BlockBackend *blk, char *buf, int64_t offset,
44
+{
24
- int64_t bytes, int flags, int64_t *total)
45
+ VirtIOBlockReq *req = opaque;
25
+ int64_t bytes, BdrvRequestFlags flags, int64_t *total)
46
+ VirtIOBlock *s = req->dev;
26
{
47
+ bool is_write_zeroes = (virtio_ldl_p(VIRTIO_DEVICE(s), &req->out.type) &
27
int ret;
48
+ ~VIRTIO_BLK_T_BARRIER) == VIRTIO_BLK_T_WRITE_ZEROES;
28
49
+
29
@@ -XXX,XX +XXX,XX @@ static int do_pwrite(BlockBackend *blk, char *buf, int64_t offset,
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
}
30
}
73
31
74
+static uint8_t virtio_blk_handle_discard_write_zeroes(VirtIOBlockReq *req,
32
static int do_pwrite_zeroes(BlockBackend *blk, int64_t offset,
75
+ struct virtio_blk_discard_write_zeroes *dwz_hdr, bool is_write_zeroes)
33
- int64_t bytes, int flags, int64_t *total)
76
+{
34
+ int64_t bytes, BdrvRequestFlags flags,
77
+ VirtIOBlock *s = req->dev;
35
+ int64_t *total)
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
{
36
{
154
uint32_t type;
37
int ret = blk_pwrite_zeroes(blk, offset, bytes,
155
@@ -XXX,XX +XXX,XX @@ static int virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb)
38
flags | BDRV_REQ_ZERO_WRITE);
156
virtio_blk_free_request(req);
39
@@ -XXX,XX +XXX,XX @@ static int do_aio_readv(BlockBackend *blk, QEMUIOVector *qiov,
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
}
40
}
227
41
228
@@ -XXX,XX +XXX,XX @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
42
static int do_aio_writev(BlockBackend *blk, QEMUIOVector *qiov,
229
return;
43
- int64_t offset, int flags, int *total)
230
}
44
+ int64_t offset, BdrvRequestFlags flags, int *total)
231
45
{
232
+ if (virtio_has_feature(s->host_features, VIRTIO_BLK_F_DISCARD) &&
46
int async_ret = NOT_DONE;
233
+ (!conf->max_discard_sectors ||
47
234
+ conf->max_discard_sectors > BDRV_REQUEST_MAX_SECTORS)) {
48
@@ -XXX,XX +XXX,XX @@ static int write_f(BlockBackend *blk, int argc, char **argv)
235
+ error_setg(errp, "invalid max-discard-sectors property (%" PRIu32 ")"
49
struct timespec t1, t2;
236
+ ", must be between 1 and %d",
50
bool Cflag = false, qflag = false, bflag = false;
237
+ conf->max_discard_sectors, (int)BDRV_REQUEST_MAX_SECTORS);
51
bool Pflag = false, zflag = false, cflag = false, sflag = false;
238
+ return;
52
- int flags = 0;
239
+ }
53
+ BdrvRequestFlags flags = 0;
240
+
54
int c, cnt, ret;
241
+ if (virtio_has_feature(s->host_features, VIRTIO_BLK_F_WRITE_ZEROES) &&
55
char *buf = NULL;
242
+ (!conf->max_write_zeroes_sectors ||
56
int64_t offset;
243
+ conf->max_write_zeroes_sectors > BDRV_REQUEST_MAX_SECTORS)) {
57
@@ -XXX,XX +XXX,XX @@ static int writev_f(BlockBackend *blk, int argc, char **argv)
244
+ error_setg(errp, "invalid max-write-zeroes-sectors property (%" PRIu32
58
{
245
+ "), must be between 1 and %d",
59
struct timespec t1, t2;
246
+ conf->max_write_zeroes_sectors,
60
bool Cflag = false, qflag = false;
247
+ (int)BDRV_REQUEST_MAX_SECTORS);
61
- int flags = 0;
248
+ return;
62
+ BdrvRequestFlags flags = 0;
249
+ }
63
int c, cnt, ret;
250
+
64
char *buf;
251
virtio_blk_set_config_size(s, s->host_features);
65
int64_t offset;
252
66
@@ -XXX,XX +XXX,XX @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv)
253
virtio_init(vdev, "virtio-blk", VIRTIO_ID_BLOCK, s->config_size);
67
int nr_iov, c;
254
@@ -XXX,XX +XXX,XX @@ static Property virtio_blk_properties[] = {
68
int pattern = 0xcd;
255
VIRTIO_BLK_F_DISCARD, true),
69
struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
256
DEFINE_PROP_BIT64("write-zeroes", VirtIOBlock, host_features,
70
- int flags = 0;
257
VIRTIO_BLK_F_WRITE_ZEROES, true),
71
+ BdrvRequestFlags flags = 0;
258
+ DEFINE_PROP_UINT32("max-discard-sectors", VirtIOBlock,
72
259
+ conf.max_discard_sectors, BDRV_REQUEST_MAX_SECTORS),
73
ctx->blk = blk;
260
+ DEFINE_PROP_UINT32("max-write-zeroes-sectors", VirtIOBlock,
74
while ((c = getopt(argc, argv, "CfiqP:uz")) != -1) {
261
+ conf.max_write_zeroes_sectors, BDRV_REQUEST_MAX_SECTORS),
262
DEFINE_PROP_END_OF_LIST(),
263
};
264
265
--
75
--
266
2.20.1
76
2.39.1
267
268
diff view generated by jsdifflib
1
From: Stefano Garzarella <sgarzare@redhat.com>
1
The blk_register_buf() API is an optimization hint that allows some
2
block drivers to avoid I/O buffer housekeeping or bounce buffers.
2
3
3
In order to use VirtIOFeature also in other virtio devices, we move
4
Add an -r option to register the I/O buffer so that qemu-io can be used
4
its declaration and the endof() macro (renamed in virtio_endof())
5
to test the blk_register_buf() API. The next commit will add a test that
5
in virtio.h.
6
uses the new option.
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
7
10
Suggested-by: Michael S. Tsirkin <mst@redhat.com>
8
Reviewed-by: Eric Blake <eblake@redhat.com>
11
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Reviewed-by: Hanna Czenczek <hreitz@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>
10
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
11
Message-Id: <20230207203719.242926-4-stefanha@redhat.com>
16
---
12
---
17
include/hw/virtio/virtio.h | 15 +++++++++++++++
13
qemu-io-cmds.c | 204 +++++++++++++++++++++++++++++++------------------
18
hw/net/virtio-net.c | 31 +++++++------------------------
14
1 file changed, 129 insertions(+), 75 deletions(-)
19
hw/virtio/virtio.c | 15 +++++++++++++++
20
3 files changed, 37 insertions(+), 24 deletions(-)
21
15
22
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
16
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
23
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/virtio/virtio.h
18
--- a/qemu-io-cmds.c
25
+++ b/include/hw/virtio/virtio.h
19
+++ b/qemu-io-cmds.c
26
@@ -XXX,XX +XXX,XX @@ static inline hwaddr vring_align(hwaddr addr,
20
@@ -XXX,XX +XXX,XX @@ static int parse_pattern(const char *arg)
27
return QEMU_ALIGN_UP(addr, align);
21
*/
28
}
22
29
23
#define MISALIGN_OFFSET 16
30
+/*
24
-static void *qemu_io_alloc(BlockBackend *blk, size_t len, int pattern)
31
+ * Calculate the number of bytes up to and including the given 'field' of
25
+static void *qemu_io_alloc(BlockBackend *blk, size_t len, int pattern,
32
+ * 'container'.
26
+ bool register_buf)
33
+ */
27
{
34
+#define virtio_endof(container, field) \
28
void *buf;
35
+ (offsetof(container, field) + sizeof_field(container, field))
29
36
+
30
@@ -XXX,XX +XXX,XX @@ static void *qemu_io_alloc(BlockBackend *blk, size_t len, int pattern)
37
+typedef struct VirtIOFeature {
31
}
38
+ uint64_t flags;
32
buf = blk_blockalign(blk, len);
39
+ size_t end;
33
memset(buf, pattern, len);
40
+} VirtIOFeature;
34
+ if (register_buf) {
41
+
35
+ blk_register_buf(blk, buf, len, &error_abort);
42
+size_t virtio_feature_get_config_size(VirtIOFeature *features,
36
+ }
43
+ uint64_t host_features);
37
if (qemuio_misalign) {
44
+
38
buf += MISALIGN_OFFSET;
45
typedef struct VirtQueue VirtQueue;
39
}
46
40
return buf;
47
#define VIRTQUEUE_MAX_SIZE 1024
41
}
48
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
42
49
index XXXXXXX..XXXXXXX 100644
43
-static void qemu_io_free(void *p)
50
--- a/hw/net/virtio-net.c
44
+static void qemu_io_free(BlockBackend *blk, void *p, size_t len,
51
+++ b/hw/net/virtio-net.c
45
+ bool unregister_buf)
52
@@ -XXX,XX +XXX,XX @@ static inline __virtio16 *virtio_net_rsc_ext_num_dupacks(
46
{
53
47
if (qemuio_misalign) {
54
#endif
48
p -= MISALIGN_OFFSET;
55
49
+ len += MISALIGN_OFFSET;
56
-/*
50
+ }
57
- * Calculate the number of bytes up to and including the given 'field' of
51
+ if (unregister_buf) {
58
- * 'container'.
52
+ blk_unregister_buf(blk, p, len);
59
- */
53
}
60
-#define endof(container, field) \
54
qemu_vfree(p);
61
- (offsetof(container, field) + sizeof_field(container, field))
55
}
56
@@ -XXX,XX +XXX,XX @@ static void qemu_io_free(void *p)
57
* @blk - the block backend where the buffer content is going to be written to
58
* @len - the buffer length
59
* @file_name - the file to read the content from
60
+ * @register_buf - call blk_register_buf()
61
*
62
* Returns: the buffer pointer on success
63
* NULL on error
64
*/
65
static void *qemu_io_alloc_from_file(BlockBackend *blk, size_t len,
66
- const char *file_name)
67
+ const char *file_name, bool register_buf)
68
{
69
- char *buf, *buf_origin;
70
+ size_t alloc_len = len + (qemuio_misalign ? MISALIGN_OFFSET : 0);
71
+ char *alloc_buf, *buf, *end;
72
FILE *f = fopen(file_name, "r");
73
int pattern_len;
74
75
@@ -XXX,XX +XXX,XX @@ static void *qemu_io_alloc_from_file(BlockBackend *blk, size_t len,
76
return NULL;
77
}
78
79
- if (qemuio_misalign) {
80
- len += MISALIGN_OFFSET;
81
- }
62
-
82
-
63
-typedef struct VirtIOFeature {
83
- buf_origin = buf = blk_blockalign(blk, len);
64
- uint64_t flags;
84
+ alloc_buf = buf = blk_blockalign(blk, alloc_len);
65
- size_t end;
85
66
-} VirtIOFeature;
86
if (qemuio_misalign) {
87
- buf_origin += MISALIGN_OFFSET;
88
buf += MISALIGN_OFFSET;
89
- len -= MISALIGN_OFFSET;
90
}
91
92
- pattern_len = fread(buf_origin, 1, len, f);
93
+ pattern_len = fread(buf, 1, len, f);
94
95
if (ferror(f)) {
96
perror(file_name);
97
@@ -XXX,XX +XXX,XX @@ static void *qemu_io_alloc_from_file(BlockBackend *blk, size_t len,
98
fclose(f);
99
f = NULL;
100
101
- if (len > pattern_len) {
102
- len -= pattern_len;
103
- buf += pattern_len;
67
-
104
-
68
static VirtIOFeature feature_sizes[] = {
105
- while (len > 0) {
69
{.flags = 1ULL << VIRTIO_NET_F_MAC,
106
- size_t len_to_copy = MIN(pattern_len, len);
70
- .end = endof(struct virtio_net_config, mac)},
107
-
71
+ .end = virtio_endof(struct virtio_net_config, mac)},
108
- memcpy(buf, buf_origin, len_to_copy);
72
{.flags = 1ULL << VIRTIO_NET_F_STATUS,
109
+ if (register_buf) {
73
- .end = endof(struct virtio_net_config, status)},
110
+ blk_register_buf(blk, alloc_buf, alloc_len, &error_abort);
74
+ .end = virtio_endof(struct virtio_net_config, status)},
111
+ }
75
{.flags = 1ULL << VIRTIO_NET_F_MQ,
112
76
- .end = endof(struct virtio_net_config, max_virtqueue_pairs)},
113
- len -= len_to_copy;
77
+ .end = virtio_endof(struct virtio_net_config, max_virtqueue_pairs)},
114
- buf += len_to_copy;
78
{.flags = 1ULL << VIRTIO_NET_F_MTU,
115
- }
79
- .end = endof(struct virtio_net_config, mtu)},
116
+ end = buf + len;
80
+ .end = virtio_endof(struct virtio_net_config, mtu)},
117
+ for (char *p = buf + pattern_len; p < end; p += pattern_len) {
81
{.flags = 1ULL << VIRTIO_NET_F_SPEED_DUPLEX,
118
+ memcpy(p, buf, MIN(pattern_len, end - p));
82
- .end = endof(struct virtio_net_config, duplex)},
119
}
83
+ .end = virtio_endof(struct virtio_net_config, duplex)},
120
84
{}
121
- return buf_origin;
122
+ return buf;
123
124
error:
125
- qemu_io_free(buf_origin);
126
+ /*
127
+ * This code path is only taken before blk_register_buf() is called, so
128
+ * hardcode the qemu_io_free() unregister_buf argument to false.
129
+ */
130
+ qemu_io_free(blk, alloc_buf, alloc_len, false);
131
if (f) {
132
fclose(f);
133
}
134
@@ -XXX,XX +XXX,XX @@ static void print_report(const char *op, struct timespec *t, int64_t offset,
135
*/
136
static void *
137
create_iovec(BlockBackend *blk, QEMUIOVector *qiov, char **argv, int nr_iov,
138
- int pattern)
139
+ int pattern, bool register_buf)
140
{
141
size_t *sizes = g_new0(size_t, nr_iov);
142
size_t count = 0;
143
@@ -XXX,XX +XXX,XX @@ create_iovec(BlockBackend *blk, QEMUIOVector *qiov, char **argv, int nr_iov,
144
145
qemu_iovec_init(qiov, nr_iov);
146
147
- buf = p = qemu_io_alloc(blk, count, pattern);
148
+ buf = p = qemu_io_alloc(blk, count, pattern, register_buf);
149
150
for (i = 0; i < nr_iov; i++) {
151
qemu_iovec_add(qiov, p, sizes[i]);
152
@@ -XXX,XX +XXX,XX @@ fail:
153
}
154
155
static int do_pread(BlockBackend *blk, char *buf, int64_t offset,
156
- int64_t bytes, int64_t *total)
157
+ int64_t bytes, BdrvRequestFlags flags, int64_t *total)
158
{
159
int ret;
160
161
@@ -XXX,XX +XXX,XX @@ static int do_pread(BlockBackend *blk, char *buf, int64_t offset,
162
return -ERANGE;
163
}
164
165
- ret = blk_pread(blk, offset, bytes, (uint8_t *)buf, 0);
166
+ ret = blk_pread(blk, offset, bytes, (uint8_t *)buf, flags);
167
if (ret < 0) {
168
return ret;
169
}
170
@@ -XXX,XX +XXX,XX @@ static void aio_rw_done(void *opaque, int ret)
171
}
172
173
static int do_aio_readv(BlockBackend *blk, QEMUIOVector *qiov,
174
- int64_t offset, int *total)
175
+ int64_t offset, BdrvRequestFlags flags, int *total)
176
{
177
int async_ret = NOT_DONE;
178
179
- blk_aio_preadv(blk, offset, qiov, 0, aio_rw_done, &async_ret);
180
+ blk_aio_preadv(blk, offset, qiov, flags, aio_rw_done, &async_ret);
181
while (async_ret == NOT_DONE) {
182
main_loop_wait(false);
183
}
184
@@ -XXX,XX +XXX,XX @@ static void read_help(void)
185
" -p, -- ignored for backwards compatibility\n"
186
" -P, -- use a pattern to verify read data\n"
187
" -q, -- quiet mode, do not show I/O statistics\n"
188
+" -r, -- register I/O buffer\n"
189
" -s, -- start offset for pattern verification (only with -P)\n"
190
" -v, -- dump buffer to standard output\n"
191
"\n");
192
@@ -XXX,XX +XXX,XX @@ static const cmdinfo_t read_cmd = {
193
.cfunc = read_f,
194
.argmin = 2,
195
.argmax = -1,
196
- .args = "[-abCqv] [-P pattern [-s off] [-l len]] off len",
197
+ .args = "[-abCqrv] [-P pattern [-s off] [-l len]] off len",
198
.oneline = "reads a number of bytes at a specified offset",
199
.help = read_help,
85
};
200
};
86
201
@@ -XXX,XX +XXX,XX @@ static int read_f(BlockBackend *blk, int argc, char **argv)
87
@@ -XXX,XX +XXX,XX @@ static void virtio_net_guest_notifier_mask(VirtIODevice *vdev, int idx,
202
int64_t total = 0;
88
203
int pattern = 0;
89
static void virtio_net_set_config_size(VirtIONet *n, uint64_t host_features)
204
int64_t pattern_offset = 0, pattern_count = 0;
90
{
205
+ BdrvRequestFlags flags = 0;
91
- int i, config_size = 0;
206
92
virtio_add_feature(&host_features, VIRTIO_NET_F_MAC);
207
- while ((c = getopt(argc, argv, "bCl:pP:qs:v")) != -1) {
93
208
+ while ((c = getopt(argc, argv, "bCl:pP:qrs:v")) != -1) {
94
- for (i = 0; feature_sizes[i].flags != 0; i++) {
209
switch (c) {
95
- if (host_features & feature_sizes[i].flags) {
210
case 'b':
96
- config_size = MAX(feature_sizes[i].end, config_size);
211
bflag = true;
97
- }
212
@@ -XXX,XX +XXX,XX @@ static int read_f(BlockBackend *blk, int argc, char **argv)
98
- }
213
case 'q':
99
- n->config_size = config_size;
214
qflag = true;
100
+ n->config_size = virtio_feature_get_config_size(feature_sizes,
215
break;
101
+ host_features);
216
+ case 'r':
102
}
217
+ flags |= BDRV_REQ_REGISTERED_BUF;
103
218
+ break;
104
void virtio_net_set_netclient_name(VirtIONet *n, const char *name,
219
case 's':
105
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
220
sflag = true;
106
index XXXXXXX..XXXXXXX 100644
221
pattern_offset = cvtnum(optarg);
107
--- a/hw/virtio/virtio.c
222
@@ -XXX,XX +XXX,XX @@ static int read_f(BlockBackend *blk, int argc, char **argv)
108
+++ b/hw/virtio/virtio.c
223
count);
109
@@ -XXX,XX +XXX,XX @@ int virtio_set_features(VirtIODevice *vdev, uint64_t val)
224
return -EINVAL;
225
}
226
+ if (flags & BDRV_REQ_REGISTERED_BUF) {
227
+ printf("I/O buffer registration is not supported when reading "
228
+ "from vmstate\n");
229
+ return -EINVAL;
230
+ }
231
}
232
233
- buf = qemu_io_alloc(blk, count, 0xab);
234
+ buf = qemu_io_alloc(blk, count, 0xab, flags & BDRV_REQ_REGISTERED_BUF);
235
236
clock_gettime(CLOCK_MONOTONIC, &t1);
237
if (bflag) {
238
ret = do_load_vmstate(blk, buf, offset, count, &total);
239
} else {
240
- ret = do_pread(blk, buf, offset, count, &total);
241
+ ret = do_pread(blk, buf, offset, count, flags, &total);
242
}
243
clock_gettime(CLOCK_MONOTONIC, &t2);
244
245
@@ -XXX,XX +XXX,XX @@ static int read_f(BlockBackend *blk, int argc, char **argv)
246
print_report("read", &t2, offset, count, total, cnt, Cflag);
247
248
out:
249
- qemu_io_free(buf);
250
+ qemu_io_free(blk, buf, count, flags & BDRV_REQ_REGISTERED_BUF);
110
return ret;
251
return ret;
111
}
252
}
112
253
113
+size_t virtio_feature_get_config_size(VirtIOFeature *feature_sizes,
254
@@ -XXX,XX +XXX,XX @@ static void readv_help(void)
114
+ uint64_t host_features)
255
" Uses multiple iovec buffers if more than one byte range is specified.\n"
115
+{
256
" -C, -- report statistics in a machine parsable format\n"
116
+ size_t config_size = 0;
257
" -P, -- use a pattern to verify read data\n"
117
+ int i;
258
-" -v, -- dump buffer to standard output\n"
118
+
259
" -q, -- quiet mode, do not show I/O statistics\n"
119
+ for (i = 0; feature_sizes[i].flags != 0; i++) {
260
+" -r, -- register I/O buffer\n"
120
+ if (host_features & feature_sizes[i].flags) {
261
+" -v, -- dump buffer to standard output\n"
121
+ config_size = MAX(feature_sizes[i].end, config_size);
262
"\n");
263
}
264
265
@@ -XXX,XX +XXX,XX @@ static const cmdinfo_t readv_cmd = {
266
.cfunc = readv_f,
267
.argmin = 2,
268
.argmax = -1,
269
- .args = "[-Cqv] [-P pattern] off len [len..]",
270
+ .args = "[-Cqrv] [-P pattern] off len [len..]",
271
.oneline = "reads a number of bytes at a specified offset",
272
.help = readv_help,
273
};
274
@@ -XXX,XX +XXX,XX @@ static int readv_f(BlockBackend *blk, int argc, char **argv)
275
QEMUIOVector qiov;
276
int pattern = 0;
277
bool Pflag = false;
278
+ BdrvRequestFlags flags = 0;
279
280
- while ((c = getopt(argc, argv, "CP:qv")) != -1) {
281
+ while ((c = getopt(argc, argv, "CP:qrv")) != -1) {
282
switch (c) {
283
case 'C':
284
Cflag = true;
285
@@ -XXX,XX +XXX,XX @@ static int readv_f(BlockBackend *blk, int argc, char **argv)
286
case 'q':
287
qflag = true;
288
break;
289
+ case 'r':
290
+ flags |= BDRV_REQ_REGISTERED_BUF;
291
+ break;
292
case 'v':
293
vflag = true;
294
break;
295
@@ -XXX,XX +XXX,XX @@ static int readv_f(BlockBackend *blk, int argc, char **argv)
296
optind++;
297
298
nr_iov = argc - optind;
299
- buf = create_iovec(blk, &qiov, &argv[optind], nr_iov, 0xab);
300
+ buf = create_iovec(blk, &qiov, &argv[optind], nr_iov, 0xab,
301
+ flags & BDRV_REQ_REGISTERED_BUF);
302
if (buf == NULL) {
303
return -EINVAL;
304
}
305
306
clock_gettime(CLOCK_MONOTONIC, &t1);
307
- ret = do_aio_readv(blk, &qiov, offset, &total);
308
+ ret = do_aio_readv(blk, &qiov, offset, flags, &total);
309
clock_gettime(CLOCK_MONOTONIC, &t2);
310
311
if (ret < 0) {
312
@@ -XXX,XX +XXX,XX @@ static int readv_f(BlockBackend *blk, int argc, char **argv)
313
print_report("read", &t2, offset, qiov.size, total, cnt, Cflag);
314
315
out:
316
+ qemu_io_free(blk, buf, qiov.size, flags & BDRV_REQ_REGISTERED_BUF);
317
qemu_iovec_destroy(&qiov);
318
- qemu_io_free(buf);
319
return ret;
320
}
321
322
@@ -XXX,XX +XXX,XX @@ static void write_help(void)
323
" filled with a set pattern (0xcdcdcdcd).\n"
324
" -b, -- write to the VM state rather than the virtual disk\n"
325
" -c, -- write compressed data with blk_write_compressed\n"
326
+" -C, -- report statistics in a machine parsable format\n"
327
" -f, -- use Force Unit Access semantics\n"
328
" -n, -- with -z, don't allow slow fallback\n"
329
" -p, -- ignored for backwards compatibility\n"
330
" -P, -- use different pattern to fill file\n"
331
+" -q, -- quiet mode, do not show I/O statistics\n"
332
+" -r, -- register I/O buffer\n"
333
" -s, -- use a pattern file to fill the write buffer\n"
334
-" -C, -- report statistics in a machine parsable format\n"
335
-" -q, -- quiet mode, do not show I/O statistics\n"
336
" -u, -- with -z, allow unmapping\n"
337
" -z, -- write zeroes using blk_pwrite_zeroes\n"
338
"\n");
339
@@ -XXX,XX +XXX,XX @@ static const cmdinfo_t write_cmd = {
340
.perm = BLK_PERM_WRITE,
341
.argmin = 2,
342
.argmax = -1,
343
- .args = "[-bcCfnquz] [-P pattern | -s source_file] off len",
344
+ .args = "[-bcCfnqruz] [-P pattern | -s source_file] off len",
345
.oneline = "writes a number of bytes at a specified offset",
346
.help = write_help,
347
};
348
@@ -XXX,XX +XXX,XX @@ static int write_f(BlockBackend *blk, int argc, char **argv)
349
int pattern = 0xcd;
350
const char *file_name = NULL;
351
352
- while ((c = getopt(argc, argv, "bcCfnpP:qs:uz")) != -1) {
353
+ while ((c = getopt(argc, argv, "bcCfnpP:qrs:uz")) != -1) {
354
switch (c) {
355
case 'b':
356
bflag = true;
357
@@ -XXX,XX +XXX,XX @@ static int write_f(BlockBackend *blk, int argc, char **argv)
358
case 'q':
359
qflag = true;
360
break;
361
+ case 'r':
362
+ flags |= BDRV_REQ_REGISTERED_BUF;
363
+ break;
364
case 's':
365
sflag = true;
366
file_name = optarg;
367
@@ -XXX,XX +XXX,XX @@ static int write_f(BlockBackend *blk, int argc, char **argv)
368
}
369
}
370
371
- if (!zflag) {
372
+ if (zflag) {
373
+ if (flags & BDRV_REQ_REGISTERED_BUF) {
374
+ printf("cannot combine zero write with registered I/O buffer\n");
375
+ return -EINVAL;
122
+ }
376
+ }
377
+ } else {
378
if (sflag) {
379
- buf = qemu_io_alloc_from_file(blk, count, file_name);
380
+ buf = qemu_io_alloc_from_file(blk, count, file_name,
381
+ flags & BDRV_REQ_REGISTERED_BUF);
382
if (!buf) {
383
return -EINVAL;
384
}
385
} else {
386
- buf = qemu_io_alloc(blk, count, pattern);
387
+ buf = qemu_io_alloc(blk, count, pattern,
388
+ flags & BDRV_REQ_REGISTERED_BUF);
389
}
390
}
391
392
@@ -XXX,XX +XXX,XX @@ static int write_f(BlockBackend *blk, int argc, char **argv)
393
394
out:
395
if (!zflag) {
396
- qemu_io_free(buf);
397
+ qemu_io_free(blk, buf, count, flags & BDRV_REQ_REGISTERED_BUF);
398
}
399
return ret;
400
}
401
@@ -XXX,XX +XXX,XX @@ writev_help(void)
402
"\n"
403
" Writes into a segment of the currently open file, using a buffer\n"
404
" filled with a set pattern (0xcdcdcdcd).\n"
405
-" -P, -- use different pattern to fill file\n"
406
" -C, -- report statistics in a machine parsable format\n"
407
" -f, -- use Force Unit Access semantics\n"
408
+" -P, -- use different pattern to fill file\n"
409
" -q, -- quiet mode, do not show I/O statistics\n"
410
+" -r, -- register I/O buffer\n"
411
"\n");
412
}
413
414
@@ -XXX,XX +XXX,XX @@ static const cmdinfo_t writev_cmd = {
415
.perm = BLK_PERM_WRITE,
416
.argmin = 2,
417
.argmax = -1,
418
- .args = "[-Cfq] [-P pattern] off len [len..]",
419
+ .args = "[-Cfqr] [-P pattern] off len [len..]",
420
.oneline = "writes a number of bytes at a specified offset",
421
.help = writev_help,
422
};
423
@@ -XXX,XX +XXX,XX @@ static int writev_f(BlockBackend *blk, int argc, char **argv)
424
int pattern = 0xcd;
425
QEMUIOVector qiov;
426
427
- while ((c = getopt(argc, argv, "CfqP:")) != -1) {
428
+ while ((c = getopt(argc, argv, "CfP:qr")) != -1) {
429
switch (c) {
430
case 'C':
431
Cflag = true;
432
@@ -XXX,XX +XXX,XX @@ static int writev_f(BlockBackend *blk, int argc, char **argv)
433
case 'q':
434
qflag = true;
435
break;
436
+ case 'r':
437
+ flags |= BDRV_REQ_REGISTERED_BUF;
438
+ break;
439
case 'P':
440
pattern = parse_pattern(optarg);
441
if (pattern < 0) {
442
@@ -XXX,XX +XXX,XX @@ static int writev_f(BlockBackend *blk, int argc, char **argv)
443
optind++;
444
445
nr_iov = argc - optind;
446
- buf = create_iovec(blk, &qiov, &argv[optind], nr_iov, pattern);
447
+ buf = create_iovec(blk, &qiov, &argv[optind], nr_iov, pattern,
448
+ flags & BDRV_REQ_REGISTERED_BUF);
449
if (buf == NULL) {
450
return -EINVAL;
451
}
452
@@ -XXX,XX +XXX,XX @@ static int writev_f(BlockBackend *blk, int argc, char **argv)
453
t2 = tsub(t2, t1);
454
print_report("wrote", &t2, offset, qiov.size, total, cnt, Cflag);
455
out:
456
+ qemu_io_free(blk, buf, qiov.size, flags & BDRV_REQ_REGISTERED_BUF);
457
qemu_iovec_destroy(&qiov);
458
- qemu_io_free(buf);
459
return ret;
460
}
461
462
@@ -XXX,XX +XXX,XX @@ struct aio_ctx {
463
bool zflag;
464
BlockAcctCookie acct;
465
int pattern;
466
+ BdrvRequestFlags flags;
467
struct timespec t1;
468
};
469
470
@@ -XXX,XX +XXX,XX @@ static void aio_write_done(void *opaque, int ret)
471
ctx->qiov.size, 1, ctx->Cflag);
472
out:
473
if (!ctx->zflag) {
474
- qemu_io_free(ctx->buf);
475
+ qemu_io_free(ctx->blk, ctx->buf, ctx->qiov.size,
476
+ ctx->flags & BDRV_REQ_REGISTERED_BUF);
477
qemu_iovec_destroy(&ctx->qiov);
478
}
479
g_free(ctx);
480
@@ -XXX,XX +XXX,XX @@ static void aio_read_done(void *opaque, int ret)
481
print_report("read", &t2, ctx->offset, ctx->qiov.size,
482
ctx->qiov.size, 1, ctx->Cflag);
483
out:
484
- qemu_io_free(ctx->buf);
485
+ qemu_io_free(ctx->blk, ctx->buf, ctx->qiov.size,
486
+ ctx->flags & BDRV_REQ_REGISTERED_BUF);
487
qemu_iovec_destroy(&ctx->qiov);
488
g_free(ctx);
489
}
490
@@ -XXX,XX +XXX,XX @@ static void aio_read_help(void)
491
" considered successful once the request is submitted, independently\n"
492
" of potential I/O errors or pattern mismatches.\n"
493
" -C, -- report statistics in a machine parsable format\n"
494
-" -P, -- use a pattern to verify read data\n"
495
" -i, -- treat request as invalid, for exercising stats\n"
496
-" -v, -- dump buffer to standard output\n"
497
+" -P, -- use a pattern to verify read data\n"
498
" -q, -- quiet mode, do not show I/O statistics\n"
499
+" -r, -- register I/O buffer\n"
500
+" -v, -- dump buffer to standard output\n"
501
"\n");
502
}
503
504
@@ -XXX,XX +XXX,XX @@ static const cmdinfo_t aio_read_cmd = {
505
.cfunc = aio_read_f,
506
.argmin = 2,
507
.argmax = -1,
508
- .args = "[-Ciqv] [-P pattern] off len [len..]",
509
+ .args = "[-Ciqrv] [-P pattern] off len [len..]",
510
.oneline = "asynchronously reads a number of bytes",
511
.help = aio_read_help,
512
};
513
@@ -XXX,XX +XXX,XX @@ static int aio_read_f(BlockBackend *blk, int argc, char **argv)
514
struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
515
516
ctx->blk = blk;
517
- while ((c = getopt(argc, argv, "CP:iqv")) != -1) {
518
+ while ((c = getopt(argc, argv, "CiP:qrv")) != -1) {
519
switch (c) {
520
case 'C':
521
ctx->Cflag = true;
522
@@ -XXX,XX +XXX,XX @@ static int aio_read_f(BlockBackend *blk, int argc, char **argv)
523
case 'q':
524
ctx->qflag = true;
525
break;
526
+ case 'r':
527
+ ctx->flags |= BDRV_REQ_REGISTERED_BUF;
528
+ break;
529
case 'v':
530
ctx->vflag = true;
531
break;
532
@@ -XXX,XX +XXX,XX @@ static int aio_read_f(BlockBackend *blk, int argc, char **argv)
533
optind++;
534
535
nr_iov = argc - optind;
536
- ctx->buf = create_iovec(blk, &ctx->qiov, &argv[optind], nr_iov, 0xab);
537
+ ctx->buf = create_iovec(blk, &ctx->qiov, &argv[optind], nr_iov, 0xab,
538
+ ctx->flags & BDRV_REQ_REGISTERED_BUF);
539
if (ctx->buf == NULL) {
540
block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_READ);
541
g_free(ctx);
542
@@ -XXX,XX +XXX,XX @@ static int aio_read_f(BlockBackend *blk, int argc, char **argv)
543
clock_gettime(CLOCK_MONOTONIC, &ctx->t1);
544
block_acct_start(blk_get_stats(blk), &ctx->acct, ctx->qiov.size,
545
BLOCK_ACCT_READ);
546
- blk_aio_preadv(blk, ctx->offset, &ctx->qiov, 0, aio_read_done, ctx);
547
+ blk_aio_preadv(blk, ctx->offset, &ctx->qiov, ctx->flags, aio_read_done,
548
+ ctx);
549
return 0;
550
}
551
552
@@ -XXX,XX +XXX,XX @@ static void aio_write_help(void)
553
" Note that due to its asynchronous nature, this command will be\n"
554
" considered successful once the request is submitted, independently\n"
555
" of potential I/O errors or pattern mismatches.\n"
556
-" -P, -- use different pattern to fill file\n"
557
" -C, -- report statistics in a machine parsable format\n"
558
" -f, -- use Force Unit Access semantics\n"
559
" -i, -- treat request as invalid, for exercising stats\n"
560
+" -P, -- use different pattern to fill file\n"
561
" -q, -- quiet mode, do not show I/O statistics\n"
562
+" -r, -- register I/O buffer\n"
563
" -u, -- with -z, allow unmapping\n"
564
" -z, -- write zeroes using blk_aio_pwrite_zeroes\n"
565
"\n");
566
@@ -XXX,XX +XXX,XX @@ static const cmdinfo_t aio_write_cmd = {
567
.perm = BLK_PERM_WRITE,
568
.argmin = 2,
569
.argmax = -1,
570
- .args = "[-Cfiquz] [-P pattern] off len [len..]",
571
+ .args = "[-Cfiqruz] [-P pattern] off len [len..]",
572
.oneline = "asynchronously writes a number of bytes",
573
.help = aio_write_help,
574
};
575
@@ -XXX,XX +XXX,XX @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv)
576
int nr_iov, c;
577
int pattern = 0xcd;
578
struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
579
- BdrvRequestFlags flags = 0;
580
581
ctx->blk = blk;
582
- while ((c = getopt(argc, argv, "CfiqP:uz")) != -1) {
583
+ while ((c = getopt(argc, argv, "CfiP:qruz")) != -1) {
584
switch (c) {
585
case 'C':
586
ctx->Cflag = true;
587
break;
588
case 'f':
589
- flags |= BDRV_REQ_FUA;
590
+ ctx->flags |= BDRV_REQ_FUA;
591
break;
592
case 'q':
593
ctx->qflag = true;
594
break;
595
+ case 'r':
596
+ ctx->flags |= BDRV_REQ_REGISTERED_BUF;
597
+ break;
598
case 'u':
599
- flags |= BDRV_REQ_MAY_UNMAP;
600
+ ctx->flags |= BDRV_REQ_MAY_UNMAP;
601
break;
602
case 'P':
603
pattern = parse_pattern(optarg);
604
@@ -XXX,XX +XXX,XX @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv)
605
return -EINVAL;
606
}
607
608
- if ((flags & BDRV_REQ_MAY_UNMAP) && !ctx->zflag) {
609
+ if ((ctx->flags & BDRV_REQ_MAY_UNMAP) && !ctx->zflag) {
610
printf("-u requires -z to be specified\n");
611
g_free(ctx);
612
return -EINVAL;
613
@@ -XXX,XX +XXX,XX @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv)
614
return -EINVAL;
615
}
616
617
+ if (ctx->zflag && (ctx->flags & BDRV_REQ_REGISTERED_BUF)) {
618
+ printf("cannot combine zero write with registered I/O buffer\n");
619
+ g_free(ctx);
620
+ return -EINVAL;
123
+ }
621
+ }
124
+
622
+
125
+ return config_size;
623
ctx->offset = cvtnum(argv[optind]);
126
+}
624
if (ctx->offset < 0) {
127
+
625
int ret = ctx->offset;
128
int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
626
@@ -XXX,XX +XXX,XX @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv)
129
{
627
}
130
int i, ret;
628
629
ctx->qiov.size = count;
630
- blk_aio_pwrite_zeroes(blk, ctx->offset, count, flags, aio_write_done,
631
- ctx);
632
+ blk_aio_pwrite_zeroes(blk, ctx->offset, count, ctx->flags,
633
+ aio_write_done, ctx);
634
} else {
635
nr_iov = argc - optind;
636
ctx->buf = create_iovec(blk, &ctx->qiov, &argv[optind], nr_iov,
637
- pattern);
638
+ pattern, ctx->flags & BDRV_REQ_REGISTERED_BUF);
639
if (ctx->buf == NULL) {
640
block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_WRITE);
641
g_free(ctx);
642
@@ -XXX,XX +XXX,XX @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv)
643
block_acct_start(blk_get_stats(blk), &ctx->acct, ctx->qiov.size,
644
BLOCK_ACCT_WRITE);
645
646
- blk_aio_pwritev(blk, ctx->offset, &ctx->qiov, flags, aio_write_done,
647
- ctx);
648
+ blk_aio_pwritev(blk, ctx->offset, &ctx->qiov, ctx->flags,
649
+ aio_write_done, ctx);
650
}
651
652
return 0;
131
--
653
--
132
2.20.1
654
2.39.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
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
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
This regression test demonstrates that detect-zeroes works with
2
registered buffers. Bug details:
3
https://gitlab.com/qemu-project/qemu/-/issues/1404
2
4
3
If the DISCARD feature is enabled, we try this command in the
5
Reviewed-by: Eric Blake <eblake@redhat.com>
4
test_basic(), checking only the status returned by the request.
6
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
7
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
8
Message-Id: <20230207203719.242926-5-stefanha@redhat.com>
9
---
10
.../tests/detect-zeroes-registered-buf | 58 +++++++++++++++++++
11
.../tests/detect-zeroes-registered-buf.out | 7 +++
12
2 files changed, 65 insertions(+)
13
create mode 100755 tests/qemu-iotests/tests/detect-zeroes-registered-buf
14
create mode 100644 tests/qemu-iotests/tests/detect-zeroes-registered-buf.out
5
15
6
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
16
diff --git a/tests/qemu-iotests/tests/detect-zeroes-registered-buf b/tests/qemu-iotests/tests/detect-zeroes-registered-buf
7
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
17
new file mode 100755
8
Message-id: 20190221103314.58500-11-sgarzare@redhat.com
18
index XXXXXXX..XXXXXXX
9
Message-Id: <20190221103314.58500-11-sgarzare@redhat.com>
19
--- /dev/null
10
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
20
+++ b/tests/qemu-iotests/tests/detect-zeroes-registered-buf
11
---
21
@@ -XXX,XX +XXX,XX @@
12
tests/virtio-blk-test.c | 27 +++++++++++++++++++++++++++
22
+#!/usr/bin/env bash
13
1 file changed, 27 insertions(+)
23
+# group: rw auto quick
14
24
+#
15
diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c
25
+# Check that detect-zeroes=unmap works on writes with registered I/O buffers.
16
index XXXXXXX..XXXXXXX 100644
26
+# This is a regression test for
17
--- a/tests/virtio-blk-test.c
27
+# https://gitlab.com/qemu-project/qemu/-/issues/1404 where I/O requests failed
18
+++ b/tests/virtio-blk-test.c
28
+# unexpectedly.
19
@@ -XXX,XX +XXX,XX @@ static void test_basic(QVirtioDevice *dev, QGuestAllocator *alloc,
29
+#
20
guest_free(alloc, req_addr);
30
+# Copyright Red Hat
21
}
31
+#
22
32
+# This program is free software; you can redistribute it and/or modify
23
+ if (features & (1u << VIRTIO_BLK_F_DISCARD)) {
33
+# it under the terms of the GNU General Public License as published by
24
+ struct virtio_blk_discard_write_zeroes dwz_hdr;
34
+# the Free Software Foundation; either version 2 of the License, or
35
+# (at your option) any later version.
36
+#
37
+# This program is distributed in the hope that it will be useful,
38
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
39
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40
+# GNU General Public License for more details.
41
+#
42
+# You should have received a copy of the GNU General Public License
43
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
44
+#
25
+
45
+
26
+ req.type = VIRTIO_BLK_T_DISCARD;
46
+# creator
27
+ req.data = (char *) &dwz_hdr;
47
+owner=stefanha@redhat.com
28
+ dwz_hdr.sector = 0;
29
+ dwz_hdr.num_sectors = 1;
30
+ dwz_hdr.flags = 0;
31
+
48
+
32
+ virtio_blk_fix_dwz_hdr(dev, &dwz_hdr);
49
+seq=`basename $0`
50
+echo "QA output created by $seq"
33
+
51
+
34
+ req_addr = virtio_blk_request(alloc, dev, &req, sizeof(dwz_hdr));
52
+status=1    # failure is the default!
35
+
53
+
36
+ free_head = qvirtqueue_add(vq, req_addr, 16, false, true);
54
+_cleanup()
37
+ qvirtqueue_add(vq, req_addr + 16, sizeof(dwz_hdr), false, true);
55
+{
38
+ qvirtqueue_add(vq, req_addr + 16 + sizeof(dwz_hdr), 1, true, false);
56
+    _cleanup_test_img
57
+}
58
+trap "_cleanup; exit \$status" 0 1 2 3 15
39
+
59
+
40
+ qvirtqueue_kick(dev, vq, free_head);
60
+# get standard environment, filters and checks
61
+cd ..
62
+. ./common.rc
63
+. ./common.filter
41
+
64
+
42
+ qvirtio_wait_used_elem(dev, vq, free_head, NULL,
65
+_supported_fmt qcow2
43
+ QVIRTIO_BLK_TIMEOUT_US);
66
+_supported_proto generic
44
+ status = readb(req_addr + 16 + sizeof(dwz_hdr));
45
+ g_assert_cmpint(status, ==, 0);
46
+
67
+
47
+ guest_free(alloc, req_addr);
68
+size=128M
48
+ }
69
+_make_test_img $size
70
+IMGSPEC="driver=$IMGFMT,file.filename=$TEST_IMG,discard=unmap,detect-zeroes=unmap"
49
+
71
+
50
if (features & (1u << VIRTIO_F_ANY_LAYOUT)) {
72
+echo
51
/* Write and read with 2 descriptor layout */
73
+echo "== writing zero buffer to image =="
52
/* Write request */
74
+QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS_NO_FMT" $QEMU_IO -c "write -r -P 0 0 4k" --image-opts "$IMGSPEC" | _filter_qemu_io
75
+
76
+# success, all done
77
+echo "*** done"
78
+rm -f $seq.full
79
+status=0
80
diff --git a/tests/qemu-iotests/tests/detect-zeroes-registered-buf.out b/tests/qemu-iotests/tests/detect-zeroes-registered-buf.out
81
new file mode 100644
82
index XXXXXXX..XXXXXXX
83
--- /dev/null
84
+++ b/tests/qemu-iotests/tests/detect-zeroes-registered-buf.out
85
@@ -XXX,XX +XXX,XX @@
86
+QA output created by detect-zeroes-registered-buf
87
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
88
+
89
+== writing zero buffer to image ==
90
+wrote 4096/4096 bytes at offset 0
91
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
92
+*** done
53
--
93
--
54
2.20.1
94
2.39.1
55
56
diff view generated by jsdifflib