static ssize_t hvt_op_read()

in hv_utils_transport.c [27:72]


static ssize_t hvt_op_read(struct file *file, char __user *buf,
			   size_t count, loff_t *ppos)
{
	struct hvutil_transport *hvt;
	int ret;

	hvt = container_of(file->f_op, struct hvutil_transport, fops);

	if (wait_event_interruptible(hvt->outmsg_q, hvt->outmsg_len > 0 ||
				     hvt->mode != HVUTIL_TRANSPORT_CHARDEV))
		return -EINTR;

	mutex_lock(&hvt->lock);

	if (hvt->mode == HVUTIL_TRANSPORT_DESTROY) {
		ret = -EBADF;
		goto out_unlock;
	}

	if (!hvt->outmsg) {
		ret = -EAGAIN;
		goto out_unlock;
	}

	if (count < hvt->outmsg_len) {
		ret = -EINVAL;
		goto out_unlock;
	}

	if (!copy_to_user(buf, hvt->outmsg, hvt->outmsg_len))
		ret = hvt->outmsg_len;
	else
		ret = -EFAULT;

	kfree(hvt->outmsg);
	hvt->outmsg = NULL;
	hvt->outmsg_len = 0;

	if (hvt->on_read)
		hvt->on_read();
	hvt->on_read = NULL;

out_unlock:
	mutex_unlock(&hvt->lock);
	return ret;
}