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); }
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; }