patch-2.3.16 linux/net/khttpd/datasending.c
Next file: linux/net/khttpd/main.c
Previous file: linux/net/irda/wrapper.c
Back to the patch index
Back to the overall index
- Lines: 131
- Date:
Thu Aug 26 09:41:36 1999
- Orig file:
v2.3.15/linux/net/khttpd/datasending.c
- Orig date:
Thu Aug 26 13:05:46 1999
diff -u --recursive --new-file v2.3.15/linux/net/khttpd/datasending.c linux/net/khttpd/datasending.c
@@ -36,6 +36,7 @@
#include <linux/config.h>
#include <linux/kernel.h>
+#include <linux/locks.h>
#include <linux/skbuff.h>
#include <net/tcp.h>
@@ -48,6 +49,33 @@
static char *Block[CONFIG_KHTTPD_NUMCPU];
+/*
+
+This send_actor is for use with do_generic_file_read (ie sendfile())
+It sends the data to the socket indicated by desc->buf.
+
+*/
+static int sock_send_actor(read_descriptor_t * desc, const char *area, unsigned long size)
+{
+ int written;
+ unsigned long count = desc->count;
+ struct socket *sock = (struct socket *) desc->buf;
+
+ if (size > count)
+ size = count;
+ written = SendBuffer_async(sock,(char *)area,size);
+
+ if (written < 0) {
+ desc->error = written;
+ written = 0;
+ }
+ desc->count = count - written;
+ desc->written += written;
+ return written;
+}
+
+
+
int DataSending(const int CPUNR)
{
@@ -62,45 +90,61 @@
{
int ReadSize,Space;
int retval;
- mm_segment_t oldfs;
/* First, test if the socket has any buffer-space left.
If not, no need to actually try to send something. */
- Space=4096;
- if (CurrentRequest->sock->sk!=NULL) /* It's impossible */
- {
- Space = sock_wspace(CurrentRequest->sock->sk);
- }
+ Space = sock_wspace(CurrentRequest->sock->sk);
- ReadSize = min(4096,CurrentRequest->FileLength - CurrentRequest->BytesSent);
+ ReadSize = min(4*4096,CurrentRequest->FileLength - CurrentRequest->BytesSent);
ReadSize = min(ReadSize , Space );
-
- if (ReadSize>0)
- {
- /* This part does a redundant data-copy. To bad for now.
- In the future, we might want to nick the data right out
- of the page-cache
- WHY DO YOU NOT USE SENDFILE?
- */
-
- CurrentRequest->filp->f_pos = CurrentRequest->BytesSent;
-
- oldfs = get_fs(); set_fs(KERNEL_DS);
- retval = CurrentRequest->filp->f_op->read(CurrentRequest->filp, Block[CPUNR], ReadSize, &CurrentRequest->filp->f_pos);
- set_fs(oldfs);
-
- if (retval>0)
+ if (ReadSize>0)
+ {
+ struct inode *inode;
+
+ inode = CurrentRequest->filp->f_dentry->d_inode;
+
+ if ( (inode!=NULL)&&(inode->i_op!=NULL)&&(inode->i_op->readpage!=NULL))
{
- retval = SendBuffer_async(CurrentRequest->sock,Block[CPUNR],(size_t)retval);
- if (retval>0)
- {
- CurrentRequest->BytesSent += retval;
+ /* This does the actual transfer using sendfile */
+ read_descriptor_t desc;
+ loff_t *ppos;
+
+ CurrentRequest->filp->f_pos = CurrentRequest->BytesSent;
+
+ ppos = &CurrentRequest->filp->f_pos;
+
+ desc.written = 0;
+ desc.count = ReadSize;
+ desc.buf = (char *) CurrentRequest->sock;
+ desc.error = 0;
+ do_generic_file_read(CurrentRequest->filp, ppos, &desc, sock_send_actor);
+ if (desc.written>0)
+ {
+ CurrentRequest->BytesSent += desc.written;
count++;
+ }
+ }
+ else /* FS doesn't support sendfile() */
+ {
+ mm_segment_t oldfs;
+ CurrentRequest->filp->f_pos = CurrentRequest->BytesSent;
+ oldfs = get_fs(); set_fs(KERNEL_DS);
+ retval = CurrentRequest->filp->f_op->read(CurrentRequest->filp, Block[CPUNR], ReadSize, &CurrentRequest->filp->f_pos);
+ set_fs(oldfs);
+
+ if (retval>0)
+ {
+ retval = SendBuffer_async(CurrentRequest->sock,Block[CPUNR],(size_t)retval);
+ if (retval>0)
+ {
+ CurrentRequest->BytesSent += retval;
+ count++;
+ }
}
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)