Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 03 Jan 2000 19:51:10 +0200
From:      Jukka Ukkonen <Jukka.Ukkonen@sysopen.fi>
To:        FreeBSD Gnats <FreeBSD-gnats-submit@freebsd.org>
Subject:   bin/15861: ftpd did not use sendfile(2) when sending regular files
Message-ID:  <3870E18E.4CF289E2@sysopen.fi>

next in thread | raw e-mail | index | archive | help

>Number:         15861
>Category:       bin
>Synopsis:       ftpd did not use sendfile(2) when sending regular files
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Mon Jan  3 09:10:00 PST 2000
>Closed-Date:
>Last-Modified:
>Originator:     Jukka A. Ukkonen
>Release:        FreeBSD 3.2-RELEASE i386
>Organization:
Private person
>Environment:

        FreeBSD 3.2-RELEASE i386 and the standard ftpd packaged with it.

>Description:

        The ftpd could have performed better by using the sendfile(2)
        call instead of mmap(), read(), write(), and munmap() combination
        while sending out a regular file.

>How-To-Repeat:

        Check the ftpd code for sending regular files to see what it does,
        and try it as it is and with sendfile() replacing the looping method
        using mmap(), read(), write(), and munmap() calls.

>Fix:
        
        A tentative quick hack patch below.
        Modify it, if you think changes are needed.
        Otherwise: share and enjoy. ;-)


--- ftpd.c.orig Sun May  2 12:35:30 1999
+++ ftpd.c      Wed Dec 29 14:41:26 1999
@@ -1466,6 +1466,7 @@
                filefd = fileno(instr);
 
                if (isreg && filesize < (off_t)16 * 1024 * 1024) {
+#if 0
                        buf = mmap(0, filesize, PROT_READ, MAP_SHARED, filefd,
                                   (off_t)0);
                        if (buf == MAP_FAILED) {
@@ -1484,8 +1485,31 @@
 
                        transflag = 0;
                        munmap(buf, (size_t)filesize);
+
                        if (cnt < 0)
                                goto data_err;
+#endif
+                       off_t   offset;
+                       int     fail;
+
+                       len = filesize;
+                       offset = 0;
+                       fail = 0;
+
+                       while (len &&
+                              ! (fail = sendfile (filefd, netfd, offset, len,
+                                                  NULL, &cnt, 0))) {
+                               len -= cnt;
+                               offset += cnt;
+                       }
+
+                       if (fail < 0) {
+                               if (errno == EINVAL)
+                                   goto oldway;
+
+                               goto data_err;
+                       }
+
                        reply(226, "Transfer complete.");
                        return;
                }

>Release-Note:
>Audit-Trail:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3870E18E.4CF289E2>