According to http://en.wikipedia.org/wiki/Splice_
(system_call) the proper way to use splice() to copy one file to another involves clever use of the pipe() system call. (This is one way to get around the requirement that one of the file descriptors given to splice() is a pipe). What I find strange is that the code example on that page has a while loop writing the entire file to the pipe, and then having another loop read the entire file from the pipe. I don't exactly know what operations are going on in the kernel. Perhaps all the data of the file is being written to the pipe, thus filling up as much kernel memory as the file has data. Or, perhaps the pipe buffer just contains a series of references to the appropriate data in the file, just making the pipe buffer an unmanageably large number of references to a file, rather than a ridiculously unmanageable amount of raw data.
In any case, wouldn't it be better that each splice() call that writes to the pipe be followed by a call that reads from the pipe, rather than packaging each type of splice call to its own while loop? The code paragraph handles errors in a pretty casual way, and according to the man pages splice() can fail and set errno to ENOMEM ("Out of memory").