void list_directory (tux_req_t *req, int cachemiss) { struct getdents_callback64 buf; struct linux_dirent64 *dirp0; mm_segment_t oldmm; int total; Dprintk("list_directory(%p, %d), dentry: %p.\n", req, cachemiss, req->dentry); if (!req->cwd_dentry) TUX_BUG(); if (!cachemiss) { add_tux_atom(req, list_directory); queue_cachemiss(req); return; } dirp0 = tux_kmalloc(DIRENT_SIZE); buf.current_dir = dirp0; buf.previous = NULL; buf.count = DIRENT_SIZE; buf.error = 0; oldmm = get_fs(); set_fs(KERNEL_DS); set_fs(KERNEL_DS); total = vfs_readdir(req->in_file, filldir64, &buf); set_fs(oldmm); if (buf.previous) total = DIRENT_SIZE - buf.count; Dprintk("total: %d (buf.error: %d, buf.previous %p)\n", total, buf.error, buf.previous); if (total < 0) { kfree(dirp0); req_err(req); add_req_to_workqueue(req); return; } if (!total) { kfree(dirp0); req->in_file->f_pos = 0; add_req_to_workqueue(req); return; } if (!req->cwd_dentry) TUX_BUG(); add_tux_atom(req, list_directory); req->dirp0 = dirp0; req->curroff = 0; req->total = total; add_tux_atom(req, do_dir_line); add_req_to_workqueue(req); }
static int sock_send_actor (read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long orig_size) { sock_send_desc_t *sock_desc = (sock_send_desc_t *)desc->arg.buf; struct socket *sock = sock_desc->sock; tux_req_t *req = sock_desc->req; unsigned int flags; ssize_t written; char *buf = NULL; unsigned int size; flags = MSG_DONTWAIT | MSG_NOSIGNAL; if (desc->count < orig_size) orig_size = desc->count; if (desc->count > orig_size) flags |= MSG_MORE; Dprintk("sock_send_actor(), page: %p, offset: %ld, orig_size: %ld, sock: %p, desc->count: %d, desc->written: %d, MSG_MORE: %d.\n", page, offset, orig_size, sock, desc->count, desc->written, flags & MSG_MORE); if (req->content_gzipped >= 2) { unsigned int gzip_left; struct msghdr msg; struct iovec iov; mm_segment_t oldmm; char *kaddr = kmap(page); __u32 in_len, out_len; out_len = orig_size*101/100 + 12; buf = tux_kmalloc(out_len); in_len = orig_size; size = out_len; gzip_left = 0; // 8b1f 0808 fdc4 3bd8 0300 79 buf[1] = 0x8b; buf[0] = 0x1f; buf[3] = 0x08; buf[2] = 0x08; buf[5] = 0xfd; buf[4] = 0xc4; buf[7] = 0x3b; buf[6] = 0xd8; buf[9] = 0x03; buf[8] = 0x00; buf[10] = 0x79; size += 11; Dprintk("pre-compress: in_len: %d, out_len: %d, gzip_left: %d, uncompressed size: %d.\n", in_len, out_len, gzip_left, size); gzip_left = tux_gzip_compress(req, kaddr, buf+11, &in_len, &out_len); size -= out_len; buf[11] = 0x79; buf[12] = 0x00; Dprintk("post-compress: in_len: %d, out_len: %d, gzip_left: %d, compressed size: %d.\n", in_len, out_len, gzip_left, size); kunmap(page); msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_control = NULL; msg.msg_controllen = 0; flags &= ~MSG_DONTWAIT; msg.msg_flags = flags; iov.iov_base = buf; iov.iov_len = size; oldmm = get_fs(); set_fs(KERNEL_DS); written = sock_sendmsg(sock, &msg, size); set_fs(oldmm); Dprintk("buf: %p, offset: %ld, size: %d, written: %d.\n", buf, offset, size, written); if (written == size) written = orig_size; else written = size; } else { size = orig_size; if (tux_zerocopy_sendfile && sock->ops->sendpage && (sock->sk->sk_route_caps&NETIF_F_SG)) { written = sock->ops->sendpage(sock, page, offset, size, flags); } else { struct msghdr msg; struct iovec iov; char *kaddr; mm_segment_t oldmm; if (offset+size > PAGE_SIZE) return -EFAULT; kaddr = kmap(page); msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_control = NULL; msg.msg_controllen = 0; msg.msg_flags = flags; iov.iov_base = kaddr + offset; iov.iov_len = size; oldmm = get_fs(); set_fs(KERNEL_DS); written = sock_sendmsg(sock, &msg, size); set_fs(oldmm); Dprintk("kaddr: %p, offset: %ld, size: %d, written: %d.\n", kaddr, offset, size, written); kunmap(page); } } if (written < 0) { desc->error = written; written = 0; } Dprintk("desc->count: %d, desc->written: %d, written: %d.\n", desc->count, desc->written, written); desc->count -= written; if ((int)desc->count < 0) TUX_BUG(); desc->written += written; if (buf) kfree(buf); return written; }