diff options
| -rw-r--r-- | arch/powerpc/include/asm/systbl.h | 4 | ||||
| -rw-r--r-- | arch/powerpc/include/asm/unistd.h | 1 | ||||
| -rw-r--r-- | arch/powerpc/kernel/sys_ppc32.c | 45 | ||||
| -rw-r--r-- | arch/sparc/include/asm/unistd.h | 1 | ||||
| -rw-r--r-- | arch/sparc/kernel/sys32.S | 2 | ||||
| -rw-r--r-- | arch/sparc/kernel/sys_sparc32.c | 46 | ||||
| -rw-r--r-- | fs/compat.c | 22 | ||||
| -rw-r--r-- | fs/read_write.c | 4 | ||||
| -rw-r--r-- | fs/read_write.h | 2 | ||||
| -rw-r--r-- | include/linux/compat.h | 3 |
10 files changed, 41 insertions, 89 deletions
diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h index 559ae1ee6706..840838769853 100644 --- a/arch/powerpc/include/asm/systbl.h +++ b/arch/powerpc/include/asm/systbl.h | |||
| @@ -189,7 +189,7 @@ SYSCALL_SPU(getcwd) | |||
| 189 | SYSCALL_SPU(capget) | 189 | SYSCALL_SPU(capget) |
| 190 | SYSCALL_SPU(capset) | 190 | SYSCALL_SPU(capset) |
| 191 | COMPAT_SYS(sigaltstack) | 191 | COMPAT_SYS(sigaltstack) |
| 192 | SYSX_SPU(sys_sendfile64,compat_sys_sendfile,sys_sendfile) | 192 | SYSX_SPU(sys_sendfile,compat_sys_sendfile_wrapper,sys_sendfile) |
| 193 | SYSCALL(ni_syscall) | 193 | SYSCALL(ni_syscall) |
| 194 | SYSCALL(ni_syscall) | 194 | SYSCALL(ni_syscall) |
| 195 | PPC_SYS(vfork) | 195 | PPC_SYS(vfork) |
| @@ -229,7 +229,7 @@ COMPAT_SYS_SPU(sched_setaffinity) | |||
| 229 | COMPAT_SYS_SPU(sched_getaffinity) | 229 | COMPAT_SYS_SPU(sched_getaffinity) |
| 230 | SYSCALL(ni_syscall) | 230 | SYSCALL(ni_syscall) |
| 231 | SYSCALL(ni_syscall) | 231 | SYSCALL(ni_syscall) |
| 232 | SYS32ONLY(sendfile64) | 232 | SYSX(sys_ni_syscall,compat_sys_sendfile64_wrapper,sys_sendfile64) |
| 233 | COMPAT_SYS_SPU(io_setup) | 233 | COMPAT_SYS_SPU(io_setup) |
| 234 | SYSCALL_SPU(io_destroy) | 234 | SYSCALL_SPU(io_destroy) |
| 235 | COMPAT_SYS_SPU(io_getevents) | 235 | COMPAT_SYS_SPU(io_getevents) |
diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h index bd377a368611..c683fa350add 100644 --- a/arch/powerpc/include/asm/unistd.h +++ b/arch/powerpc/include/asm/unistd.h | |||
| @@ -419,6 +419,7 @@ | |||
| 419 | #define __ARCH_WANT_COMPAT_SYS_TIME | 419 | #define __ARCH_WANT_COMPAT_SYS_TIME |
| 420 | #define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND | 420 | #define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND |
| 421 | #define __ARCH_WANT_SYS_NEWFSTATAT | 421 | #define __ARCH_WANT_SYS_NEWFSTATAT |
| 422 | #define __ARCH_WANT_COMPAT_SYS_SENDFILE | ||
| 422 | #endif | 423 | #endif |
| 423 | 424 | ||
| 424 | /* | 425 | /* |
diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c index 81c570633ead..abd1112da54f 100644 --- a/arch/powerpc/kernel/sys_ppc32.c +++ b/arch/powerpc/kernel/sys_ppc32.c | |||
| @@ -143,48 +143,17 @@ long compat_sys_ipc(u32 call, u32 first, u32 second, u32 third, compat_uptr_t pt | |||
| 143 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) | 143 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) |
| 144 | * and the register representation of a signed int (msr in 64-bit mode) is performed. | 144 | * and the register representation of a signed int (msr in 64-bit mode) is performed. |
| 145 | */ | 145 | */ |
| 146 | asmlinkage long compat_sys_sendfile(u32 out_fd, u32 in_fd, compat_off_t __user * offset, u32 count) | 146 | asmlinkage long compat_sys_sendfile_wrapper(u32 out_fd, u32 in_fd, |
| 147 | compat_off_t __user *offset, u32 count) | ||
| 147 | { | 148 | { |
| 148 | mm_segment_t old_fs = get_fs(); | 149 | return compat_sys_sendfile((int)out_fd, (int)in_fd, offset, count); |
| 149 | int ret; | ||
| 150 | off_t of; | ||
| 151 | off_t __user *up; | ||
| 152 | |||
| 153 | if (offset && get_user(of, offset)) | ||
| 154 | return -EFAULT; | ||
| 155 | |||
| 156 | /* The __user pointer cast is valid because of the set_fs() */ | ||
| 157 | set_fs(KERNEL_DS); | ||
| 158 | up = offset ? (off_t __user *) &of : NULL; | ||
| 159 | ret = sys_sendfile((int)out_fd, (int)in_fd, up, count); | ||
| 160 | set_fs(old_fs); | ||
| 161 | |||
| 162 | if (offset && put_user(of, offset)) | ||
| 163 | return -EFAULT; | ||
| 164 | |||
| 165 | return ret; | ||
| 166 | } | 150 | } |
| 167 | 151 | ||
| 168 | asmlinkage int compat_sys_sendfile64(int out_fd, int in_fd, compat_loff_t __user *offset, s32 count) | 152 | asmlinkage long compat_sys_sendfile64_wrapper(u32 out_fd, u32 in_fd, |
| 153 | compat_loff_t __user *offset, u32 count) | ||
| 169 | { | 154 | { |
| 170 | mm_segment_t old_fs = get_fs(); | 155 | return sys_sendfile((int)out_fd, (int)in_fd, |
| 171 | int ret; | 156 | (off_t __user *)offset, count); |
| 172 | loff_t lof; | ||
| 173 | loff_t __user *up; | ||
| 174 | |||
| 175 | if (offset && get_user(lof, offset)) | ||
| 176 | return -EFAULT; | ||
| 177 | |||
| 178 | /* The __user pointer cast is valid because of the set_fs() */ | ||
| 179 | set_fs(KERNEL_DS); | ||
| 180 | up = offset ? (loff_t __user *) &lof : NULL; | ||
| 181 | ret = sys_sendfile64(out_fd, in_fd, up, count); | ||
| 182 | set_fs(old_fs); | ||
| 183 | |||
| 184 | if (offset && put_user(lof, offset)) | ||
| 185 | return -EFAULT; | ||
| 186 | |||
| 187 | return ret; | ||
| 188 | } | 157 | } |
| 189 | 158 | ||
| 190 | long compat_sys_execve(unsigned long a0, unsigned long a1, unsigned long a2, | 159 | long compat_sys_execve(unsigned long a0, unsigned long a1, unsigned long a2, |
diff --git a/arch/sparc/include/asm/unistd.h b/arch/sparc/include/asm/unistd.h index fb2693464807..d9a677c51926 100644 --- a/arch/sparc/include/asm/unistd.h +++ b/arch/sparc/include/asm/unistd.h | |||
| @@ -447,6 +447,7 @@ | |||
| 447 | #else | 447 | #else |
| 448 | #define __ARCH_WANT_COMPAT_SYS_TIME | 448 | #define __ARCH_WANT_COMPAT_SYS_TIME |
| 449 | #define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND | 449 | #define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND |
| 450 | #define __ARCH_WANT_COMPAT_SYS_SENDFILE | ||
| 450 | #endif | 451 | #endif |
| 451 | 452 | ||
| 452 | /* | 453 | /* |
diff --git a/arch/sparc/kernel/sys32.S b/arch/sparc/kernel/sys32.S index d97f3eb72e06..44025f4ba41f 100644 --- a/arch/sparc/kernel/sys32.S +++ b/arch/sparc/kernel/sys32.S | |||
| @@ -90,7 +90,7 @@ SIGN1(sys32_mkdir, sys_mkdir, %o1) | |||
| 90 | SIGN3(sys32_futex, compat_sys_futex, %o1, %o2, %o5) | 90 | SIGN3(sys32_futex, compat_sys_futex, %o1, %o2, %o5) |
| 91 | SIGN1(sys32_sysfs, compat_sys_sysfs, %o0) | 91 | SIGN1(sys32_sysfs, compat_sys_sysfs, %o0) |
| 92 | SIGN2(sys32_sendfile, compat_sys_sendfile, %o0, %o1) | 92 | SIGN2(sys32_sendfile, compat_sys_sendfile, %o0, %o1) |
| 93 | SIGN2(sys32_sendfile64, compat_sys_sendfile64, %o0, %o1) | 93 | SIGN2(sys32_sendfile64, sys_sendfile, %o0, %o1) |
| 94 | SIGN1(sys32_prctl, sys_prctl, %o0) | 94 | SIGN1(sys32_prctl, sys_prctl, %o0) |
| 95 | SIGN1(sys32_sched_rr_get_interval, compat_sys_sched_rr_get_interval, %o0) | 95 | SIGN1(sys32_sched_rr_get_interval, compat_sys_sched_rr_get_interval, %o0) |
| 96 | SIGN2(sys32_waitpid, sys_waitpid, %o0, %o2) | 96 | SIGN2(sys32_waitpid, sys_waitpid, %o0, %o2) |
diff --git a/arch/sparc/kernel/sys_sparc32.c b/arch/sparc/kernel/sys_sparc32.c index f7392336961f..d862499eb01c 100644 --- a/arch/sparc/kernel/sys_sparc32.c +++ b/arch/sparc/kernel/sys_sparc32.c | |||
| @@ -506,52 +506,6 @@ long compat_sys_fadvise64_64(int fd, | |||
| 506 | advice); | 506 | advice); |
| 507 | } | 507 | } |
| 508 | 508 | ||
| 509 | asmlinkage long compat_sys_sendfile(int out_fd, int in_fd, | ||
| 510 | compat_off_t __user *offset, | ||
| 511 | compat_size_t count) | ||
| 512 | { | ||
| 513 | mm_segment_t old_fs = get_fs(); | ||
| 514 | int ret; | ||
| 515 | off_t of; | ||
| 516 | |||
| 517 | if (offset && get_user(of, offset)) | ||
| 518 | return -EFAULT; | ||
| 519 | |||
| 520 | set_fs(KERNEL_DS); | ||
| 521 | ret = sys_sendfile(out_fd, in_fd, | ||
| 522 | offset ? (off_t __user *) &of : NULL, | ||
| 523 | count); | ||
| 524 | set_fs(old_fs); | ||
| 525 | |||
| 526 | if (offset && put_user(of, offset)) | ||
| 527 | return -EFAULT; | ||
| 528 | |||
| 529 | return ret; | ||
| 530 | } | ||
| 531 | |||
| 532 | asmlinkage long compat_sys_sendfile64(int out_fd, int in_fd, | ||
| 533 | compat_loff_t __user *offset, | ||
| 534 | compat_size_t count) | ||
| 535 | { | ||
| 536 | mm_segment_t old_fs = get_fs(); | ||
| 537 | int ret; | ||
| 538 | loff_t lof; | ||
| 539 | |||
| 540 | if (offset && get_user(lof, offset)) | ||
| 541 | return -EFAULT; | ||
| 542 | |||
| 543 | set_fs(KERNEL_DS); | ||
| 544 | ret = sys_sendfile64(out_fd, in_fd, | ||
| 545 | offset ? (loff_t __user *) &lof : NULL, | ||
| 546 | count); | ||
| 547 | set_fs(old_fs); | ||
| 548 | |||
| 549 | if (offset && put_user(lof, offset)) | ||
| 550 | return -EFAULT; | ||
| 551 | |||
| 552 | return ret; | ||
| 553 | } | ||
| 554 | |||
| 555 | /* This is just a version for 32-bit applications which does | 509 | /* This is just a version for 32-bit applications which does |
| 556 | * not force O_LARGEFILE on. | 510 | * not force O_LARGEFILE on. |
| 557 | */ | 511 | */ |
diff --git a/fs/compat.c b/fs/compat.c index d72d51e19025..b7a24d0ca30d 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
| @@ -1792,3 +1792,25 @@ compat_sys_open_by_handle_at(int mountdirfd, | |||
| 1792 | return do_handle_open(mountdirfd, handle, flags); | 1792 | return do_handle_open(mountdirfd, handle, flags); |
| 1793 | } | 1793 | } |
| 1794 | #endif | 1794 | #endif |
| 1795 | |||
| 1796 | #ifdef __ARCH_WANT_COMPAT_SYS_SENDFILE | ||
| 1797 | asmlinkage long compat_sys_sendfile(int out_fd, int in_fd, | ||
| 1798 | compat_off_t __user *offset, compat_size_t count) | ||
| 1799 | { | ||
| 1800 | loff_t pos; | ||
| 1801 | off_t off; | ||
| 1802 | ssize_t ret; | ||
| 1803 | |||
| 1804 | if (offset) { | ||
| 1805 | if (unlikely(get_user(off, offset))) | ||
| 1806 | return -EFAULT; | ||
| 1807 | pos = off; | ||
| 1808 | ret = do_sendfile(out_fd, in_fd, &pos, count, MAX_NON_LFS); | ||
| 1809 | if (unlikely(put_user(pos, offset))) | ||
| 1810 | return -EFAULT; | ||
| 1811 | return ret; | ||
| 1812 | } | ||
| 1813 | |||
| 1814 | return do_sendfile(out_fd, in_fd, NULL, count, 0); | ||
| 1815 | } | ||
| 1816 | #endif /* __ARCH_WANT_COMPAT_SYS_SENDFILE */ | ||
diff --git a/fs/read_write.c b/fs/read_write.c index 28b38279a219..d06534857e9e 100644 --- a/fs/read_write.c +++ b/fs/read_write.c | |||
| @@ -862,8 +862,8 @@ SYSCALL_DEFINE5(pwritev, unsigned long, fd, const struct iovec __user *, vec, | |||
| 862 | return ret; | 862 | return ret; |
| 863 | } | 863 | } |
| 864 | 864 | ||
| 865 | static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, | 865 | ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, size_t count, |
| 866 | size_t count, loff_t max) | 866 | loff_t max) |
| 867 | { | 867 | { |
| 868 | struct fd in, out; | 868 | struct fd in, out; |
| 869 | struct inode *in_inode, *out_inode; | 869 | struct inode *in_inode, *out_inode; |
diff --git a/fs/read_write.h b/fs/read_write.h index d07b954c6e0c..d3e00ef67420 100644 --- a/fs/read_write.h +++ b/fs/read_write.h | |||
| @@ -12,3 +12,5 @@ ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov, | |||
| 12 | unsigned long nr_segs, size_t len, loff_t *ppos, iov_fn_t fn); | 12 | unsigned long nr_segs, size_t len, loff_t *ppos, iov_fn_t fn); |
| 13 | ssize_t do_loop_readv_writev(struct file *filp, struct iovec *iov, | 13 | ssize_t do_loop_readv_writev(struct file *filp, struct iovec *iov, |
| 14 | unsigned long nr_segs, loff_t *ppos, io_fn_t fn); | 14 | unsigned long nr_segs, loff_t *ppos, io_fn_t fn); |
| 15 | ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, size_t count, | ||
| 16 | loff_t max); | ||
diff --git a/include/linux/compat.h b/include/linux/compat.h index 09b28b7369d7..fd4e29956d1c 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h | |||
| @@ -590,6 +590,9 @@ asmlinkage ssize_t compat_sys_process_vm_writev(compat_pid_t pid, | |||
| 590 | unsigned long liovcnt, const struct compat_iovec __user *rvec, | 590 | unsigned long liovcnt, const struct compat_iovec __user *rvec, |
| 591 | unsigned long riovcnt, unsigned long flags); | 591 | unsigned long riovcnt, unsigned long flags); |
| 592 | 592 | ||
| 593 | asmlinkage long compat_sys_sendfile(int out_fd, int in_fd, | ||
| 594 | compat_off_t __user *offset, compat_size_t count); | ||
| 595 | |||
| 593 | #else | 596 | #else |
| 594 | 597 | ||
| 595 | #define is_compat_task() (0) | 598 | #define is_compat_task() (0) |
