Commit 87aad03b authored by Benjamin LaHaise's avatar Benjamin LaHaise

Add sendfile64 syscall to generic code and i386.

parent 2e9f2e35
......@@ -716,6 +716,7 @@ ENTRY(sys_call_table)
.long SYMBOL_NAME(sys_lremovexattr)
.long SYMBOL_NAME(sys_fremovexattr)
.long SYMBOL_NAME(sys_tkill)
.long SYMBOL_NAME(sys_sendfile64)
.rept NR_syscalls-(.-sys_call_table)/4
.long SYMBOL_NAME(sys_ni_syscall)
......
......@@ -243,6 +243,7 @@
#define __NR_lremovexattr 236
#define __NR_fremovexattr 237
#define __NR_tkill 238
#define __NR_sendfile64 239
/* user-visible error numbers are in the range -1 - -124: see <asm-i386/errno.h> */
......
......@@ -1715,7 +1715,7 @@ static int file_send_actor(read_descriptor_t * desc, struct page *page, unsigned
return written;
}
asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset, size_t count)
static ssize_t common_sendfile(int out_fd, int in_fd, loff_t *offset, size_t count)
{
ssize_t retval;
struct file * in_file, * out_file;
......@@ -1760,27 +1760,19 @@ asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset, size_t cou
retval = 0;
if (count) {
read_descriptor_t desc;
loff_t pos = 0, *ppos;
retval = -EFAULT;
ppos = &in_file->f_pos;
if (offset) {
if (get_user(pos, offset))
goto fput_out;
ppos = &pos;
}
if (!offset)
offset = &in_file->f_pos;
desc.written = 0;
desc.count = count;
desc.buf = (char *) out_file;
desc.error = 0;
do_generic_file_read(in_file, ppos, &desc, file_send_actor);
do_generic_file_read(in_file, offset, &desc, file_send_actor);
retval = desc.written;
if (!retval)
retval = desc.error;
if (offset)
put_user(pos, offset);
}
fput_out:
......@@ -1791,6 +1783,38 @@ asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset, size_t cou
return retval;
}
asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset, size_t count)
{
loff_t pos, *ppos = NULL;
ssize_t ret;
if (offset) {
off_t off;
if (unlikely(get_user(off, offset)))
return -EFAULT;
pos = off;
ppos = &pos;
}
ret = common_sendfile(out_fd, in_fd, ppos, count);
if (offset)
put_user((off_t)pos, offset);
return ret;
}
asmlinkage ssize_t sys_sendfile64(int out_fd, int in_fd, loff_t *offset, size_t count)
{
loff_t pos, *ppos = NULL;
ssize_t ret;
if (offset) {
if (unlikely(copy_from_user(&pos, offset, sizeof(loff_t))))
return -EFAULT;
ppos = &pos;
}
ret = common_sendfile(out_fd, in_fd, ppos, count);
if (offset)
put_user(pos, offset);
return ret;
}
static ssize_t do_readahead(struct file *file, unsigned long index, unsigned long nr)
{
struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment