Messages in this thread Patch in this message | | | Date | Tue, 7 Sep 2004 14:12:35 +0200 | From | Jörn Engel <> | Subject | Re: [PATCH 3/4] copyfile: sendfile_loop |
| |
The new loop patch. Tested on my machine, appears to work.
Jörn
-- But this is not to say that the main benefit of Linux and other GPL software is lower-cost. Control is the main benefit--cost is secondary. -- Bruce Perens
Linus and Andrew are rightfully concerned about local DoS via a large file->file sendfile(). This patch turns large sendfile() calls into a loop of 4k chunks. After each chunk, it adds a cond_resched for interactivity and a signal check to allow aborts etc. after the user found out what a bad idea this may be.
Signed-off-by: Jörn Engel <joern@wohnheim.fh-wedel.de> ---
read_write.c | 31 ++++++++++++++++++++++++++++++- 1 files changed, 30 insertions(+), 1 deletion(-)
--- linux-2.6.8cow/fs/read_write.c~sendfile_loop 2004-09-05 12:06:39.000000000 +0200 +++ linux-2.6.8cow/fs/read_write.c 2004-09-07 13:27:30.000000000 +0200 @@ -561,6 +561,35 @@ return ret; } +/** + * sendfile() of a 2GB file over usb1-attached hard drives can take a moment. + * This little loop is supposed to stop now and then to check for signals, + * reschedule and generally play nice with others. + */ +ssize_t inline __vfs_sendfile(struct file *in_file, loff_t *ppos, size_t count, + read_actor_t actor, struct file *out_file) +{ + ssize_t done = 0, ret; + while (count) { + size_t n = min(count, (size_t)4096); + ret = in_file->f_op->sendfile(in_file, ppos, n, actor,out_file); + if (ret < 0) { + if (done) + return done; + else + return ret; + } + + done += ret; + count -= ret; + + if ((ret == 0) || signal_pending(current)) + break; + cond_resched(); + } + return done; +} + ssize_t vfs_sendfile(struct file *out_file, struct file *in_file, loff_t *ppos, size_t count, loff_t max) { @@ -608,7 +637,7 @@ count = max - pos; } - ret = in_file->f_op->sendfile(in_file, ppos, count, file_send_actor, out_file); + ret = __vfs_sendfile(in_file, ppos, count, file_send_actor, out_file); if (*ppos > max) return -EOVERFLOW; - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |