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