recvfile by linux splice

Lin Mac mkl23 at hotmail.com
Fri Sep 26 06:59:30 GMT 2008


hi,

The splice in Linux worked in samba with following patch.
I use linux 2.6.26.3 and samba 3.2.2, and it won't work on Linux 2.6.24.19, so I think there are some fix about splice after that.
I'm not really experienced, so please give me some advice.


Best Regards,
Mac LinIndex: lib/recvfile.c
===================================================================
--- lib/recvfile.c    (revision 198)
+++ lib/recvfile.c    (working copy)
@@ -148,10 +148,13 @@
     static bool try_splice_call = true;
     size_t total_written = 0;
 
+    int pipefd[2];
+    ssize_t ret;
+
     DEBUG(10,("sys_recvfile: from = %d, to = %d, "
-        "offset=%.0f, count = %lu\n",
+        "offset=%.0f, count = %lu, try_splice_call=%s\n",
         fromfd, tofd, (double)offset,
-        (unsigned long)count));
+        (unsigned long)count,try_splice_call?"true":"false"));
 
     if (count == 0) {
         return 0;
@@ -171,18 +174,27 @@
                 count);
     }
 
-    while (total_written < count) {
-        ssize_t ret = splice(fromfd,
-                    NULL,
-                    tofd,
-                    &offset,
-                    count,
-                    0);
+    if((ret=pipe(pipefd))){
+        DEBUG(0,("pipe creation failed,ret=%d(%x)\n",ret,ret));
+        return 0;
+    }
+    while (count!=0) {
+        //splice socket to pipe
+        if((ret = splice(    fromfd, NULL,
+                    pipefd[1],NULL,
+                    count,SPLICE_F_NONBLOCK))>=0){
+            //splice pipe to file
+            ret = splice(    pipefd[0], NULL,
+                    tofd, &offset,
+                    ret, SPLICE_F_NONBLOCK);
+        }
         if (ret == -1) {
-            if (errno != EINTR) {
+            if (errno != EINTR&&errno!=EAGAIN) {
                 if (total_written == 0 &&
                         (errno == EBADF || errno == EINVAL)) {
                     try_splice_call = false;
+                    close(pipefd[0]);
+                    close(pipefd[1]);
                     return default_sys_recvfile(fromfd,
                                 tofd,
                                 offset,
@@ -201,11 +213,15 @@
         if (drain_socket(fromfd, count-total_written) !=
                 count-total_written) {
             /* socket is dead. */
+            close(pipefd[0]);
+            close(pipefd[1]);
             return -1;
         }
         errno = saved_errno;
     }
 
+    close(pipefd[0]);
+    close(pipefd[1]);
     return total_written;
 }
 #else

_________________________________________________________________
5 GB ¶W¤j®e¶q ¡B³Ð·s«K±¶¡B¦w¥þ¨¾Å@©U§£¶l¥ó©M¯f¬r ¡X ¥ß§Y¤É¯Å Windows Live Hotmail
http://mail.live.com 


More information about the samba-technical mailing list