示例#1
0
static void __process_write_request(struct stream *s)
{
	int np = 0;
	struct stream_request *req;
	while (!event_list_empty(&s->write_queue[IO_WAIT])) {
		int ret;
		req = event_list_first_entry(&s->write_queue[IO_WAIT], struct stream_request, node);
		ret = __do_write(s, req);
		if (ret && ret != -EAGAIN && ret != -EINTR)
			goto out;
		if (!ret)
			__move_to_queue(req, &s->write_queue[IO_FIN]);
		else
			break;
		np++;
	}
	return;
out:
	__move_to_queue(req, &s->write_queue[IO_FIN]);
}
示例#2
0
ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
{
	struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len };
	struct kiocb kiocb;
	ssize_t ret;

	init_sync_kiocb(&kiocb, filp);
	kiocb.ki_pos = *ppos;
	kiocb.ki_left = len;
	kiocb.ki_nbytes = len;

	for (;;) {
		ret = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos);
		if (ret != -EIOCBRETRY)
			break;
		wait_on_retry_sync_kiocb(&kiocb);
	}

	if (-EIOCBQUEUED == ret)
		ret = wait_on_sync_kiocb(&kiocb);
	*ppos = kiocb.ki_pos;
	return ret;
}

EXPORT_SYMBOL(do_sync_write);

static ssize_t __do_write(struct file *file, const char __user *buf,
			  size_t len, loff_t *ppos)
{
	if (file->f_op->write)
		return file->f_op->write(file, buf, len, ppos);
	else
		return do_sync_write(file, buf, len, ppos);
}

static ssize_t do_write(struct file *file, const char __user *buf,
			size_t len, loff_t *ppos, int force_block)
{
	unsigned int saved_flags;
	ssize_t ret, count;

	if (!force_block)
		return __do_write(file, buf, len, ppos);

	/* Pretty much a copy of do_read() */
	saved_flags = file->f_flags;
	file->f_flags &= ~O_NONBLOCK;

	ret = 0;
	while (len > 0) {
		count = __do_write(file, buf, len, ppos);
		if (count == 0)
			break;
		if (count < 0) {
			ret = count;
			break;
		}
		len -= count;
		buf += count;
		ret += count;
	}

	file->f_flags = saved_flags;

	return ret;
}