recvfile by linux splice

Lin Mac mkl23 at hotmail.com
Tue Sep 23 11:42:36 GMT 2008


hi,

I've been trying to make the Linux splice work in samba. I'm using Linux 2.6.26.3 and samba-3.2.2
With splice tool at http://brick.kernel.dk/snaps/splice-git-latest.tar.gz, and doing the test by running:
# ./splice-fromnet  2001 | ./splice-out -m /dev/null
# cat /dev/zero | netcat localhost 2001
I think splice(socket to pipe)+splice(pipe to file) should work in Linux 2.6.26.3.

Using the original code of samba, splice would always failed due to splice directly from a socket to a file in samba. Linux require one of the input/output descriptor to be a pipe (FIFO) (http://linux.die.net/man/2/splice), so I made a little modification with the following patch to make it work.

1. change splice(socket to file) to splice (socket to pipe)+splice (pipe to file)
2. the while (total_written < count) cause part of the data won't be written to file, so I changed it to while (count!=0). And I have no idea what while (total_written < count) and the latter drain_socket are used for...

Now splice worked for small file ( <500kB), but larger files might failed (>800kB).
Now I'm stuck again...

Any help is appreciated.

Best Regards,
Mac Lin
Index: 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;
 
-    DEBUG(10,("sys_recvfile: from = %d, to = %d, "
-        "offset=%.0f, count = %lu\n",
+    int filepipe[2];
+    ssize_t ret;
+
+    DEBUG(0,("sys_recvfile: from = %d, to = %d, "
+        "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,13 +174,18 @@
                 count);
     }
 
-    while (total_written < count) {
-        ssize_t ret = splice(fromfd,
-                    NULL,
-                    tofd,
-                    &offset,
-                    count,
-                    0);
+    if(pipe(filepipe)) return 0;
+
+    while (count!=0) {
+        //splice socket to pipe
+        if((ret = splice(    fromfd, NULL,
+                    filepipe[1],NULL,
+                    count,0))>=0){
+            //splice pipe to file
+            ret = splice(    filepipe[0], NULL,
+                    tofd, &offset,
+                    ret, 0);
+        }
         if (ret == -1) {
             if (errno != EINTR) {
                 if (total_written == 0 &&

_________________________________________________________________
¥Î³¡¸¨®æ¤À¨É·Ó¤ù¡B¼v­µ¡B½ì¨ý¤p¤u¨ã©M³Ì·R²M³æ¡AºÉ±¡¨q¥X§A¦Û¤v ¡X Windows Live Spaces
http://spaces.live.com/


More information about the samba-technical mailing list