lkml.org 
[lkml]   [1998]   [Dec]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: Sendfile/copyfd questions/suggestions
Hi!

> 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.

I completely agree. Here is patch. Feed it to Linus if you are able to
:-).

> Said this specially the "connect this two files until I say stop"
> functionality looks
> promising to me.

Why not while(1) { sendfile (from, to, _SOME_BIG_NUMBER_ ) }, and
send yourself signal if you want to stop?

Pavel

PS: Known problem with sendfile is that it ignores signals... Should
be fixed. (My patch only extends this problem).

PPS: Linus, please, what is wrong with turning sendfile into copyfd? I
think that having _interface_ limited to files only is just plain
stupid.

--- clean//mm/filemap.c Mon Dec 7 17:46:10 1998
+++ linux/mm/filemap.c Fri Dec 4 15:01:25 1998
@@ -875,6 +875,48 @@
return written;
}

+ssize_t trivial_copyfd(int out_fd, int in_fd, size_t count)
+{
+extern asmlinkage ssize_t sys_read(unsigned int fd, char * buf, size_t count);
+extern asmlinkage ssize_t sys_write(unsigned int fd, const char * buf, size_t count);
+
+ /* This is really trivial, we could be quite a bit more
+ * clever: checking both files outside of loop could be easily
+ * done... But this code is 'obviously right'. */
+ char *buffer = (char *) __get_free_page( GFP_KERNEL );
+ /* We do not need page to be cleared */
+ int i, j;
+ int res = 0;
+
+ if (!buffer)
+ return -ENOMEM;
+ set_fs(KERNEL_DS);
+ while (count && !signal_pending(current)) {
+ i = count>PAGE_SIZE ? PAGE_SIZE : count;
+ i = sys_read(in_fd, buffer, i );
+ if (i<0) {
+ res = i;
+ break;
+ }
+ if (!i)
+ break;
+ j = sys_write(out_fd, buffer, i );
+ if (j<0) {
+ res = j;
+ break;
+ }
+ res += j;
+ if (i!=j)
+ break;
+ count -= j;
+
+ }
+ set_fs(USER_DS);
+
+ free_page( (long) buffer );
+ return res;
+}
+
asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset, size_t count)
{
ssize_t retval;
@@ -895,9 +937,10 @@
retval = -EINVAL;
in_inode = in_file->f_dentry->d_inode;
if (!in_inode)
- goto fput_in;
+ goto fallback;
if (!in_inode->i_op || !in_inode->i_op->readpage)
- goto fput_in;
+ goto fallback;
+
retval = locks_verify_area(FLOCK_VERIFY_READ, in_inode, in_file, in_file->f_pos, count);
if (retval)
goto fput_in;
@@ -955,6 +998,12 @@
out:
unlock_kernel();
return retval;
+
+fallback:
+ fput(in_file);
+ unlock_kernel();
+ if (offset) return -EINVAL;
+ return trivial_copyfd( out_fd, in_fd, count );
}

/*

--
I'm really pavel@atrey.karlin.mff.cuni.cz. Pavel
Look at http://atrey.karlin.mff.cuni.cz/~pavel/ ;-).

-
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/

\
 
 \ /
  Last update: 2005-03-22 13:46    [W:0.045 / U:0.340 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site