Ejemplo n.º 1
0
void queue_cachemiss (tux_req_t *req)
{
	iothread_t *iot = req->ti->iot;

	Dprintk("queueing_cachemiss(req:%p) (req->cwd_dentry: %p) at %p:%p.\n",
		req, req->cwd_dentry, __builtin_return_address(0), __builtin_return_address(1));
	if (req->idle_input || req->wait_output_space)
		TUX_BUG();
	req->had_cachemiss = 1;
	if (!list_empty(&req->work))
		TUX_BUG();
	spin_lock(&iot->async_lock);
	if (connection_too_fast(req))
		list_add_tail(&req->work, &iot->async_queue);
	else
		list_add(&req->work, &iot->async_queue);
	iot->nr_async_pending++;
	INC_STAT(nr_cachemiss_pending);
	spin_unlock(&iot->async_lock);

	wake_up(&iot->async_sleep);
}
Ejemplo n.º 2
0
int generic_send_file (tux_req_t *req, struct socket *sock, int cachemiss)
{
	sock_send_desc_t sock_desc;
	int len, want, nonblock = !cachemiss;
	struct tcp_opt *tp = tcp_sk(sock->sk);

	tp->nonagle = 2;

	sock_desc.sock = sock;
	sock_desc.req = req;

repeat:
	Dprintk("generic_send_file(%p,%d,%p) called, f_pos: %Ld, output_len: %Ld.\n", req, nonblock, sock, req->in_file->f_pos, req->output_len);

	if (req->proto->check_req_err(req, cachemiss))
		return -1;
	if (connection_too_fast(req) == 2) {
		len = -5;
		goto out;
	}
	if (req->total_file_len < req->in_file->f_pos)
		TUX_BUG();

	req->desc.written = 0;
	/*
	 * Careful, output_len can be 64-bit, while 'want' can be 32-bit.
	 */
	if (req->output_len > SEND_BLOCKSIZE)
		want = SEND_BLOCKSIZE;
	else
		want = req->output_len;
	req->desc.count = want;
	req->desc.arg.buf = (char *) &sock_desc;
	req->desc.error = 0;
	Dprintk("sendfile(), desc.count: %d.\n", req->desc.count);
	do_generic_file_read(req->in_file, &req->in_file->f_pos, &req->desc, sock_send_actor, nonblock);
	if (req->desc.written > 0) {
		req->bytes_sent += req->desc.written;
		req->output_len -= req->desc.written;
	}
	if (!nonblock && (req->desc.error == -EWOULDBLOCKIO))
		TUX_BUG();
	Dprintk("sendfile() wrote: %d bytes.\n", req->desc.written);
	if (req->output_len && !req->desc.written && !req->desc.error) {
#if CONFIG_TUX_DEBUG
		req->bytes_expected = 0;
#endif
		req->in_file->f_pos = 0;
		req->error = TUX_ERROR_CONN_CLOSE;
		zap_request(req, cachemiss);
		return -1;
	}

	switch (req->desc.error) {

	case -EWOULDBLOCKIO:
		len = -3;
		break;
	case -EAGAIN:
no_write_space:
		Dprintk("sk->wmem_queued: %d, sk->sndbuf: %d.\n",
			sock->sk->sk_wmem_queued, sock->sk->sk_sndbuf);
		len = -4;
		break;
	default:
		len = req->desc.written;
#if CONFIG_TUX_DEBUG
		if (req->desc.error)
			TDprintk("TUX: sendfile() returned error %d (signals pending: %08lx)!\n", req->desc.error, current->pending.signal.sig[0]);
#endif
		if (!req->desc.error) {
			if (req->output_len < 0)
				BUG();
			if (req->output_len) {
				if (test_bit(SOCK_NOSPACE, &sock->flags))
					goto no_write_space;
				goto repeat;
			}
		}
#if CONFIG_TUX_DEBUG
		if (req->desc.written != want)
			TDprintk("TUX: sendfile() wrote %d bytes, wanted %d! (pos %Ld) (signals pending: %08lx).\n", req->desc.written, want, req->in_file->f_pos, current->pending.signal.sig[0]);
		else
			Dprintk("TUX: sendfile() FINISHED for req %p, wrote %d bytes.\n", req, req->desc.written);
		req->bytes_expected = 0;
#endif
		break;
	}

out:
	Dprintk("sendfile() wrote %d bytes.\n", len);

	return len;
}