When I understand sendfile right instead of
FILE *in_file;
FILE *out_fine;
char buffer[2048];
in_file = fopen ... ;
out_file = fopen ... ;
fread(buffer, 2048, 1, in_file);
fwrite(buffer, 2048, 1, out_file);
I can do
int in_fd;
int out_fd;
off_t offset = 0;
int retval;
in_fd = open ... ;
out_fd = open ... ;
retval = sendfile(out_fd, in_fd, &offset, 2048);
to avoid a kernel_to_user_copy and a user_to_kernel_copy.
So far so good. I have some stupid questions:
* Is sendfile(out_fd, in_fd, NULL, 2048) possible when I want to copy
from the beginning of a file and I am not interested in the new offset.
* Is it possible to copy a whole file without knowing its size?
Would sendfile(out_fd, in_fd, &offset, 0) do that.
* When I copy a really big file with sendfile. Is the copy completed
when sendfile returns. I mean from an applications point of view, not
the actual physical copy on disk. For example: If I have mmaped the
destination file before can I look at the end of the file and find the
copied
data.
I think the answer is yes - but I want to be sure.
(I know, this is a really stupid question)
Additionally I have some suggestions. What about
* Sending a file to a (e.g. sound) device file?
* Copying one nfs file to another nfs file on the same (remote)
machine?
This would avoid two network transfers of the file.
* Doing the same for smb?
* Sending a small mmaped file to a disk device file and request
notification
after the file is actually written to disk. (Signal, Callback?)
This can be used as "raw" access for a database.
Note: Because the file is mmaped no user_to_kernel_copy is necessary.
This philosophy sounds more reasonable to me: If you want a buffer
that needs no user_to_kernel_copy (which means it is already in kernel
space) you have to request it in a special way (mmap). To write such a
buffer you have to use a different interface (Because I expect it would
be too much overhead for write to check every buffer if it is already in
kernel space). Maybe a special write (writemap) would make sense to
write an mmaped area without kernel copy. But that's a different story.
* Copy from a network socket to a file?
This is just the opposite sendfile was designed for.
* Copy from a (e.g. video tv channel) device file to a file?
This is an extension of the sendfile/copyfd functionality.
Copy until I say stop with for example: stopsend(out_fd).
Note that this can be used for audio/video recording functionality.
I know that a video recorder belongs not in kernal space. :-)
But an copy/connect functionality for files sounds like a reasonable
extension to the classical unix "everything is a file" philosophy.
As you see I like the unix "everything is a file" philosophy.
And I view sendfile more as copyfd functionality.
Not just a possibility to send a file to a socket.
See my suggestions not as whining, just as food for thought...
I like general well designed concepts. And I think the sendfile interface
should be
designed in a way that it can be extended into different directions in the
future.
So maybe a redesign of the sendfile interface is necessary.
Note that most of the ideas above can use the sendfile interface.
Some additional Interfaces would be:
For databases:
* A possibility to say: Write to disk quickly.
Maybe an ioctrl(out_fd, ...) or an additional integer parameter for
sendfile can do this.
* A notify mechanism for the physical write.
Maybe sendfile should contain an additional parameter for
a possible callback when the physical copy (to disk) is finished.
A signal or an ioctrl(out_fd, ...) would also be possible.
For unlimited copy between two files:
* A stopsend function is necessary. If out_fd as parameter is
sufficient to
recognize the running copy function I cannot decide.
* Alternatively sendfile should deliver "something" back which can be
used as identifier for the running copy function.
Remember: I do not say: "Implement all that functionality and the
kitchen sink".
I say: "When you invent a new interface
think of all possible future
functionality which should (when
implemented) also be accessible
using this interface."
Said this specially the "connect this two files until I say stop"
functionality looks
promising to me.
If the unlimited copy functionality as kernel function is a big problem (or
bloat). Is a
combination of poll and sendfile in a thread(process) sufficient to do an
unlimited
copy (Excuse for possible wrong syntax, I have not used poll for a long
time):
while (1) {
tv_channel_pollfd[0].fd = tv_channel;
tv_channel_pollfd[0].events = POLLIN;
poll(tv_channel_pollfd, 1, -1);
if (tv_channel_pollfd[0].revents && POLLIN) {
sendfile(video_archive, tv_channel, NULL, 2048);
} /* if */
} /* while */
Instead of 2048 a notation like: Copy everything which is available now,
would help.
(Something like infinite - but do not wait for new data)
This would also help copying files without requesting their size first.
In the case that the above loop can be used as unlimited copy, a library
function could
create a new thread and execute the above loop with this thread. Killing
this thread
would mean: Stop the recording.
Greetings Thomas
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/