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

Andrey Zhadchenko andrey.zhadchenko at virtuozzo.com
Mon Apr 20 14:08:16 MSK 2026


Honestly I wouldn't touch dm-ploop for now, as it is written as intended 
and works fine

On 4/20/26 11:06, Pavel Tikhomirov wrote:
> Looks good.
> 
> Should we also update used defines in:
> 
> kernel-vz10$ git grep iov_iter_bvec drivers/md/dm-{qcow2,ploop}*
> drivers/md/dm-ploop-bat.c:      iov_iter_bvec(&iter, READ, bvec, 1, PAGE_SIZE);
> drivers/md/dm-ploop-bat.c:      iov_iter_bvec(&iter, READ, bvec, nr_segs, size);
> drivers/md/dm-ploop-map.c:      iov_iter_bvec(&iter, rw, bvec, nr_segs, pio->bi_iter.bi_size);
> drivers/md/dm-ploop-target.c:   iov_iter_bvec(&iter, rw, bvec, 1, PAGE_SIZE);
> drivers/md/dm-qcow2-map.c:      iov_iter_bvec(&iter, rw, bvec, nr_segs, qio->bi_iter.bi_size);
> drivers/md/dm-qcow2-target.c:   iov_iter_bvec(&iter, rw, bvec, nr, size);
> 
> ? AFICS the directions are correct, so this would be only a cleanup, not a bugfix.
> 
> On 4/20/26 03:28, Andrey Zhadchenko wrote:
>> 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.
> 
> Reviewed-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
> 
>>
>> 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",
> 



More information about the Devel mailing list