[Devel] [PATCH VZ10] drivers/vhost/blk: set correct iter directions

Andrey Zhadchenko andrey.zhadchenko at virtuozzo.com
Mon Apr 20 04:28:07 MSK 2026


On newer kernel VMs with vhostblk disks freeze after the first
request.
This is due incorrect directions in copy_from_iter() and
copy_to_iter(). Newer kernel version actually check this values,
so we get zero from copy_from_iter() in
vhost_blk_handle_guest_kick() and never answer the guest.

Technically READ direction in iterator mean "data destination,
as used with read(2)" and not "we read data from iterator".
It was later deemed confusing and changed: see commit de4eda9de2d9
("use less confusing names for iov_iter direction initializers")

Fix this error with new defines from the same commit.

Signed-off-by: Andrey Zhadchenko <andrey.zhadchenko at virtuozzo.com>
---
 drivers/vhost/blk.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/vhost/blk.c b/drivers/vhost/blk.c
index fdb063fafc996..5acdf973ac71a 100644
--- a/drivers/vhost/blk.c
+++ b/drivers/vhost/blk.c
@@ -130,7 +130,7 @@ static inline int vhost_blk_set_status(struct vhost_blk_req *req, u8 status)
 	struct iov_iter iter;
 	int ret;
 
-	iov_iter_init(&iter, WRITE, req->status, ARRAY_SIZE(req->status), sizeof(status));
+	iov_iter_init(&iter, ITER_DEST, req->status, ARRAY_SIZE(req->status), sizeof(status));
 	ret = copy_to_iter(&status, sizeof(status), &iter);
 	if (ret != sizeof(status)) {
 		vq_err(&req->blk_vq->vq, "Failed to write status\n");
@@ -238,7 +238,7 @@ static size_t vhost_blk_move_req_to_bb(struct vhost_blk_req *req)
 {
 	struct iov_iter iter;
 
-	iov_iter_init(&iter, req->bi_opf, req->iov, req->iov_nr, req->len);
+	iov_iter_init(&iter, ITER_SOURCE, req->iov, req->iov_nr, req->len);
 	if (copy_from_iter(req->bb, req->len, &iter) != req->len)
 		return -EINVAL;
 
@@ -249,7 +249,7 @@ static size_t vhost_blk_move_bb_to_req(struct vhost_blk_req *req)
 {
 	struct iov_iter iter;
 
-	iov_iter_init(&iter, req->bi_opf, req->iov, req->iov_nr, req->len);
+	iov_iter_init(&iter, ITER_DEST, req->iov, req->iov_nr, req->len);
 	if (copy_to_iter(req->bb, req->len, &iter) != req->len)
 		return -EINVAL;
 
@@ -472,7 +472,7 @@ static int vhost_blk_req_handle(struct vhost_virtqueue *vq,
 		break;
 	case VIRTIO_BLK_T_GET_ID:
 		len = strnlen(blk->serial, VIRTIO_BLK_ID_BYTES);
-		iov_iter_init(&iter, WRITE, req->iov, req->iov_nr, req->len);
+		iov_iter_init(&iter, ITER_DEST, req->iov, req->iov_nr, req->len);
 		ret = copy_to_iter(blk->serial, len, &iter);
 		status = ret != len ? VIRTIO_BLK_S_IOERR : VIRTIO_BLK_S_OK;
 		ret = vhost_blk_set_status(req, status);
@@ -535,7 +535,7 @@ static void vhost_blk_handle_guest_kick(struct vhost_work *work)
 			break;
 		}
 
-		iov_iter_init(&iter, READ, hdr_iovec, ARRAY_SIZE(hdr_iovec), sizeof(hdr));
+		iov_iter_init(&iter, ITER_SOURCE, hdr_iovec, ARRAY_SIZE(hdr_iovec), sizeof(hdr));
 		ret = copy_from_iter(&hdr, sizeof(hdr), &iter);
 		if (ret != sizeof(hdr)) {
 			vq_err(vq, "Failed to get block header: read %d bytes instead of %ld!\n",
-- 
2.43.5



More information about the Devel mailing list