in vdpa_user/vduse_dev.c [298:340]
static ssize_t vduse_dev_read_iter(struct kiocb *iocb, struct iov_iter *to)
{
struct file *file = iocb->ki_filp;
struct vduse_dev *dev = file->private_data;
struct vduse_dev_msg *msg;
int size = sizeof(struct vduse_dev_request);
ssize_t ret;
if (iov_iter_count(to) < size)
return -EINVAL;
spin_lock(&dev->msg_lock);
while (1) {
msg = vduse_dequeue_msg(&dev->send_list);
if (msg)
break;
ret = -EAGAIN;
if (file->f_flags & O_NONBLOCK)
goto unlock;
spin_unlock(&dev->msg_lock);
ret = wait_event_interruptible_exclusive(dev->waitq,
!list_empty(&dev->send_list));
if (ret)
return ret;
spin_lock(&dev->msg_lock);
}
spin_unlock(&dev->msg_lock);
ret = copy_to_iter(&msg->req, size, to);
spin_lock(&dev->msg_lock);
if (ret != size) {
ret = -EFAULT;
vduse_enqueue_msg(&dev->send_list, msg);
goto unlock;
}
vduse_enqueue_msg(&dev->recv_list, msg);
unlock:
spin_unlock(&dev->msg_lock);
return ret;
}