aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2013-02-24 02:17:03 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2013-03-03 22:58:46 -0500
commit19f4fc3aee180000fe45952691bbe69dde1d9e95 (patch)
tree195578ae347797f6aeb66f237aeea7e0eae9847c
parent7d197ed4a68e76000070979563051e08bf6fc0aa (diff)
convert sendfile{,64} to COMPAT_SYSCALL_DEFINE
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--arch/mips/kernel/linux32.c20
-rw-r--r--arch/mips/kernel/scall64-n32.S2
-rw-r--r--arch/mips/kernel/scall64-o32.S2
-rw-r--r--arch/parisc/kernel/sys_parisc32.c19
-rw-r--r--arch/parisc/kernel/syscall_table.S4
-rw-r--r--arch/powerpc/include/asm/systbl.h4
-rw-r--r--arch/powerpc/kernel/sys_ppc32.c18
-rw-r--r--arch/s390/kernel/compat_linux.c42
-rw-r--r--arch/s390/kernel/compat_linux.h4
-rw-r--r--arch/s390/kernel/compat_wrapper.S14
-rw-r--r--arch/s390/kernel/syscalls.S4
-rw-r--r--arch/sparc/kernel/sys32.S1
-rw-r--r--arch/sparc/kernel/systbls_64.S2
-rw-r--r--arch/x86/ia32/sys_ia32.c20
-rw-r--r--arch/x86/include/asm/sys_ia32.h1
-rw-r--r--arch/x86/syscalls/syscall_32.tbl2
-rw-r--r--fs/compat.c22
-rw-r--r--fs/read_write.c44
-rw-r--r--fs/read_write.h2
-rw-r--r--include/linux/compat.h2
20 files changed, 54 insertions, 175 deletions
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
index 8eeee1c860c0..b0cc2a7df59f 100644
--- a/arch/mips/kernel/linux32.c
+++ b/arch/mips/kernel/linux32.c
@@ -226,26 +226,6 @@ SYSCALL_DEFINE1(32_personality, unsigned long, personality)
226 return ret; 226 return ret;
227} 227}
228 228
229SYSCALL_DEFINE4(32_sendfile, long, out_fd, long, in_fd,
230 compat_off_t __user *, offset, s32, count)
231{
232 mm_segment_t old_fs = get_fs();
233 int ret;
234 off_t of;
235
236 if (offset && get_user(of, offset))
237 return -EFAULT;
238
239 set_fs(KERNEL_DS);
240 ret = sys_sendfile(out_fd, in_fd, offset ? (off_t __user *)&of : NULL, count);
241 set_fs(old_fs);
242
243 if (offset && put_user(of, offset))
244 return -EFAULT;
245
246 return ret;
247}
248
249asmlinkage ssize_t sys32_readahead(int fd, u32 pad0, u64 a2, u64 a3, 229asmlinkage ssize_t sys32_readahead(int fd, u32 pad0, u64 a2, u64 a3,
250 size_t count) 230 size_t count)
251{ 231{
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index 693d60b0855f..9b4df498fc5b 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -143,7 +143,7 @@ EXPORT(sysn32_call_table)
143 PTR compat_sys_setitimer 143 PTR compat_sys_setitimer
144 PTR sys_alarm 144 PTR sys_alarm
145 PTR sys_getpid 145 PTR sys_getpid
146 PTR sys_32_sendfile 146 PTR compat_sys_sendfile
147 PTR sys_socket /* 6040 */ 147 PTR sys_socket /* 6040 */
148 PTR sys_connect 148 PTR sys_connect
149 PTR sys_accept 149 PTR sys_accept
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index af8887f779f1..c1a70e805751 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -399,7 +399,7 @@ sys_call_table:
399 PTR sys_capget 399 PTR sys_capget
400 PTR sys_capset /* 4205 */ 400 PTR sys_capset /* 4205 */
401 PTR compat_sys_sigaltstack 401 PTR compat_sys_sigaltstack
402 PTR sys_32_sendfile 402 PTR compat_sys_sendfile
403 PTR sys_ni_syscall 403 PTR sys_ni_syscall
404 PTR sys_ni_syscall 404 PTR sys_ni_syscall
405 PTR sys_mips_mmap2 /* 4210 */ 405 PTR sys_mips_mmap2 /* 4210 */
diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c
index 051c8b90231f..035ab3f94814 100644
--- a/arch/parisc/kernel/sys_parisc32.c
+++ b/arch/parisc/kernel/sys_parisc32.c
@@ -60,25 +60,6 @@ asmlinkage long sys32_unimplemented(int r26, int r25, int r24, int r23,
60 return -ENOSYS; 60 return -ENOSYS;
61} 61}
62 62
63/* Note: it is necessary to treat out_fd and in_fd as unsigned ints, with the
64 * corresponding cast to a signed int to insure that the proper conversion
65 * (sign extension) between the register representation of a signed int (msr in
66 * 32-bit mode) and the register representation of a signed int (msr in 64-bit
67 * mode) is performed.
68 */
69asmlinkage long sys32_sendfile(u32 out_fd, u32 in_fd,
70 compat_off_t __user *offset, compat_size_t count)
71{
72 return compat_sys_sendfile((int)out_fd, (int)in_fd, offset, count);
73}
74
75asmlinkage long sys32_sendfile64(u32 out_fd, u32 in_fd,
76 compat_loff_t __user *offset, compat_size_t count)
77{
78 return sys_sendfile64((int)out_fd, (int)in_fd,
79 (loff_t __user *)offset, count);
80}
81
82asmlinkage long sys32_semctl(int semid, int semnum, int cmd, union semun arg) 63asmlinkage long sys32_semctl(int semid, int semnum, int cmd, union semun arg)
83{ 64{
84 union semun u; 65 union semun u;
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S
index f57dc137b8dd..f232672a9e20 100644
--- a/arch/parisc/kernel/syscall_table.S
+++ b/arch/parisc/kernel/syscall_table.S
@@ -198,7 +198,7 @@
198 ENTRY_SAME(madvise) 198 ENTRY_SAME(madvise)
199 ENTRY_SAME(clone_wrapper) /* 120 */ 199 ENTRY_SAME(clone_wrapper) /* 120 */
200 ENTRY_SAME(setdomainname) 200 ENTRY_SAME(setdomainname)
201 ENTRY_DIFF(sendfile) 201 ENTRY_COMP(sendfile)
202 /* struct sockaddr... */ 202 /* struct sockaddr... */
203 ENTRY_SAME(recvfrom) 203 ENTRY_SAME(recvfrom)
204 /* struct timex contains longs */ 204 /* struct timex contains longs */
@@ -304,7 +304,7 @@
304 ENTRY_SAME(gettid) 304 ENTRY_SAME(gettid)
305 ENTRY_OURS(readahead) 305 ENTRY_OURS(readahead)
306 ENTRY_SAME(tkill) 306 ENTRY_SAME(tkill)
307 ENTRY_DIFF(sendfile64) 307 ENTRY_COMP(sendfile64)
308 ENTRY_COMP(futex) /* 210 */ 308 ENTRY_COMP(futex) /* 210 */
309 ENTRY_COMP(sched_setaffinity) 309 ENTRY_COMP(sched_setaffinity)
310 ENTRY_COMP(sched_getaffinity) 310 ENTRY_COMP(sched_getaffinity)
diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h
index 535b6d8a41cc..634db7d2dc92 100644
--- a/arch/powerpc/include/asm/systbl.h
+++ b/arch/powerpc/include/asm/systbl.h
@@ -190,7 +190,7 @@ SYSCALL_SPU(getcwd)
190SYSCALL_SPU(capget) 190SYSCALL_SPU(capget)
191SYSCALL_SPU(capset) 191SYSCALL_SPU(capset)
192COMPAT_SYS(sigaltstack) 192COMPAT_SYS(sigaltstack)
193SYSX_SPU(sys_sendfile,compat_sys_sendfile_wrapper,sys_sendfile) 193COMPAT_SYS_SPU(sendfile)
194SYSCALL(ni_syscall) 194SYSCALL(ni_syscall)
195SYSCALL(ni_syscall) 195SYSCALL(ni_syscall)
196PPC_SYS(vfork) 196PPC_SYS(vfork)
@@ -230,7 +230,7 @@ COMPAT_SYS_SPU(sched_setaffinity)
230COMPAT_SYS_SPU(sched_getaffinity) 230COMPAT_SYS_SPU(sched_getaffinity)
231SYSCALL(ni_syscall) 231SYSCALL(ni_syscall)
232SYSCALL(ni_syscall) 232SYSCALL(ni_syscall)
233SYSX(sys_ni_syscall,compat_sys_sendfile64_wrapper,sys_sendfile64) 233SYS32ONLY(sendfile64)
234COMPAT_SYS_SPU(io_setup) 234COMPAT_SYS_SPU(io_setup)
235SYSCALL_SPU(io_destroy) 235SYSCALL_SPU(io_destroy)
236COMPAT_SYS_SPU(io_getevents) 236COMPAT_SYS_SPU(io_getevents)
diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c
index d0bafc0cdf06..6e7c2509bd2d 100644
--- a/arch/powerpc/kernel/sys_ppc32.c
+++ b/arch/powerpc/kernel/sys_ppc32.c
@@ -128,24 +128,6 @@ long compat_sys_ipc(u32 call, u32 first, u32 second, u32 third, compat_uptr_t pt
128} 128}
129#endif 129#endif
130 130
131/* Note: it is necessary to treat out_fd and in_fd as unsigned ints,
132 * with the corresponding cast to a signed int to insure that the
133 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
134 * and the register representation of a signed int (msr in 64-bit mode) is performed.
135 */
136asmlinkage long compat_sys_sendfile_wrapper(u32 out_fd, u32 in_fd,
137 compat_off_t __user *offset, u32 count)
138{
139 return compat_sys_sendfile((int)out_fd, (int)in_fd, offset, count);
140}
141
142asmlinkage long compat_sys_sendfile64_wrapper(u32 out_fd, u32 in_fd,
143 compat_loff_t __user *offset, u32 count)
144{
145 return sys_sendfile((int)out_fd, (int)in_fd,
146 (off_t __user *)offset, count);
147}
148
149unsigned long compat_sys_mmap2(unsigned long addr, size_t len, 131unsigned long compat_sys_mmap2(unsigned long addr, size_t len,
150 unsigned long prot, unsigned long flags, 132 unsigned long prot, unsigned long flags,
151 unsigned long fd, unsigned long pgoff) 133 unsigned long fd, unsigned long pgoff)
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
index 19f26de27fae..fbd29c70a297 100644
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -373,48 +373,6 @@ asmlinkage compat_ssize_t sys32_readahead(int fd, u32 offhi, u32 offlo, s32 coun
373 return sys_readahead(fd, ((loff_t)AA(offhi) << 32) | AA(offlo), count); 373 return sys_readahead(fd, ((loff_t)AA(offhi) << 32) | AA(offlo), count);
374} 374}
375 375
376asmlinkage long sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset, size_t count)
377{
378 mm_segment_t old_fs = get_fs();
379 int ret;
380 off_t of;
381
382 if (offset && get_user(of, offset))
383 return -EFAULT;
384
385 set_fs(KERNEL_DS);
386 ret = sys_sendfile(out_fd, in_fd,
387 offset ? (off_t __force __user *) &of : NULL, count);
388 set_fs(old_fs);
389
390 if (offset && put_user(of, offset))
391 return -EFAULT;
392
393 return ret;
394}
395
396asmlinkage long sys32_sendfile64(int out_fd, int in_fd,
397 compat_loff_t __user *offset, s32 count)
398{
399 mm_segment_t old_fs = get_fs();
400 int ret;
401 loff_t lof;
402
403 if (offset && get_user(lof, offset))
404 return -EFAULT;
405
406 set_fs(KERNEL_DS);
407 ret = sys_sendfile64(out_fd, in_fd,
408 offset ? (loff_t __force __user *) &lof : NULL,
409 count);
410 set_fs(old_fs);
411
412 if (offset && put_user(lof, offset))
413 return -EFAULT;
414
415 return ret;
416}
417
418struct stat64_emu31 { 376struct stat64_emu31 {
419 unsigned long long st_dev; 377 unsigned long long st_dev;
420 unsigned int __pad1; 378 unsigned int __pad1;
diff --git a/arch/s390/kernel/compat_linux.h b/arch/s390/kernel/compat_linux.h
index 00d92a5a6f6c..bce0b7aec8f9 100644
--- a/arch/s390/kernel/compat_linux.h
+++ b/arch/s390/kernel/compat_linux.h
@@ -106,10 +106,6 @@ long sys32_pread64(unsigned int fd, char __user *ubuf, size_t count,
106long sys32_pwrite64(unsigned int fd, const char __user *ubuf, 106long sys32_pwrite64(unsigned int fd, const char __user *ubuf,
107 size_t count, u32 poshi, u32 poslo); 107 size_t count, u32 poshi, u32 poslo);
108compat_ssize_t sys32_readahead(int fd, u32 offhi, u32 offlo, s32 count); 108compat_ssize_t sys32_readahead(int fd, u32 offhi, u32 offlo, s32 count);
109long sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset,
110 size_t count);
111long sys32_sendfile64(int out_fd, int in_fd, compat_loff_t __user *offset,
112 s32 count);
113long sys32_stat64(const char __user * filename, struct stat64_emu31 __user * statbuf); 109long sys32_stat64(const char __user * filename, struct stat64_emu31 __user * statbuf);
114long sys32_lstat64(const char __user * filename, 110long sys32_lstat64(const char __user * filename,
115 struct stat64_emu31 __user * statbuf); 111 struct stat64_emu31 __user * statbuf);
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S
index 626cc6f0f446..a1dda9c67efe 100644
--- a/arch/s390/kernel/compat_wrapper.S
+++ b/arch/s390/kernel/compat_wrapper.S
@@ -666,13 +666,6 @@ ENTRY(sys32_capset_wrapper)
666 llgtr %r3,%r3 # const cap_user_data_t 666 llgtr %r3,%r3 # const cap_user_data_t
667 jg sys_capset # branch to system call 667 jg sys_capset # branch to system call
668 668
669ENTRY(sys32_sendfile_wrapper)
670 lgfr %r2,%r2 # int
671 lgfr %r3,%r3 # int
672 llgtr %r4,%r4 # __kernel_off_emu31_t *
673 llgfr %r5,%r5 # size_t
674 jg sys32_sendfile # branch to system call
675
676#sys32_vfork_wrapper # done in vfork_glue 669#sys32_vfork_wrapper # done in vfork_glue
677 670
678ENTRY(sys32_truncate64_wrapper) 671ENTRY(sys32_truncate64_wrapper)
@@ -1348,13 +1341,6 @@ ENTRY(sys32_readahead_wrapper)
1348 lgfr %r5,%r5 # s32 1341 lgfr %r5,%r5 # s32
1349 jg sys32_readahead # branch to system call 1342 jg sys32_readahead # branch to system call
1350 1343
1351ENTRY(sys32_sendfile64_wrapper)
1352 lgfr %r2,%r2 # int
1353 lgfr %r3,%r3 # int
1354 llgtr %r4,%r4 # compat_loff_t *
1355 lgfr %r5,%r5 # s32
1356 jg sys32_sendfile64 # branch to system call
1357
1358ENTRY(sys_tkill_wrapper) 1344ENTRY(sys_tkill_wrapper)
1359 lgfr %r2,%r2 # pid_t 1345 lgfr %r2,%r2 # pid_t
1360 lgfr %r3,%r3 # int 1346 lgfr %r3,%r3 # int
diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S
index 2695bb89699e..5f3f7fbc5465 100644
--- a/arch/s390/kernel/syscalls.S
+++ b/arch/s390/kernel/syscalls.S
@@ -195,7 +195,7 @@ SYSCALL(sys_getcwd,sys_getcwd,sys32_getcwd_wrapper)
195SYSCALL(sys_capget,sys_capget,sys32_capget_wrapper) 195SYSCALL(sys_capget,sys_capget,sys32_capget_wrapper)
196SYSCALL(sys_capset,sys_capset,sys32_capset_wrapper) /* 185 */ 196SYSCALL(sys_capset,sys_capset,sys32_capset_wrapper) /* 185 */
197SYSCALL(sys_sigaltstack,sys_sigaltstack,compat_sys_sigaltstack) 197SYSCALL(sys_sigaltstack,sys_sigaltstack,compat_sys_sigaltstack)
198SYSCALL(sys_sendfile,sys_sendfile64,sys32_sendfile_wrapper) 198SYSCALL(sys_sendfile,sys_sendfile64,compat_sys_sendfile)
199NI_SYSCALL /* streams1 */ 199NI_SYSCALL /* streams1 */
200NI_SYSCALL /* streams2 */ 200NI_SYSCALL /* streams2 */
201SYSCALL(sys_vfork,sys_vfork,sys_vfork) /* 190 */ 201SYSCALL(sys_vfork,sys_vfork,sys_vfork) /* 190 */
@@ -231,7 +231,7 @@ SYSCALL(sys_madvise,sys_madvise,sys32_madvise_wrapper)
231SYSCALL(sys_getdents64,sys_getdents64,sys32_getdents64_wrapper) /* 220 */ 231SYSCALL(sys_getdents64,sys_getdents64,sys32_getdents64_wrapper) /* 220 */
232SYSCALL(sys_fcntl64,sys_ni_syscall,compat_sys_fcntl64_wrapper) 232SYSCALL(sys_fcntl64,sys_ni_syscall,compat_sys_fcntl64_wrapper)
233SYSCALL(sys_readahead,sys_readahead,sys32_readahead_wrapper) 233SYSCALL(sys_readahead,sys_readahead,sys32_readahead_wrapper)
234SYSCALL(sys_sendfile64,sys_ni_syscall,sys32_sendfile64_wrapper) 234SYSCALL(sys_sendfile64,sys_ni_syscall,compat_sys_sendfile64)
235SYSCALL(sys_setxattr,sys_setxattr,sys32_setxattr_wrapper) 235SYSCALL(sys_setxattr,sys_setxattr,sys32_setxattr_wrapper)
236SYSCALL(sys_lsetxattr,sys_lsetxattr,sys32_lsetxattr_wrapper) /* 225 */ 236SYSCALL(sys_lsetxattr,sys_lsetxattr,sys32_lsetxattr_wrapper) /* 225 */
237SYSCALL(sys_fsetxattr,sys_fsetxattr,sys32_fsetxattr_wrapper) 237SYSCALL(sys_fsetxattr,sys_fsetxattr,sys32_fsetxattr_wrapper)
diff --git a/arch/sparc/kernel/sys32.S b/arch/sparc/kernel/sys32.S
index 240a3cecc11e..6c65d69c6635 100644
--- a/arch/sparc/kernel/sys32.S
+++ b/arch/sparc/kernel/sys32.S
@@ -46,7 +46,6 @@ SIGN1(sys32_io_submit, compat_sys_io_submit, %o1)
46SIGN1(sys32_mq_open, compat_sys_mq_open, %o1) 46SIGN1(sys32_mq_open, compat_sys_mq_open, %o1)
47SIGN1(sys32_select, compat_sys_select, %o0) 47SIGN1(sys32_select, compat_sys_select, %o0)
48SIGN3(sys32_futex, compat_sys_futex, %o1, %o2, %o5) 48SIGN3(sys32_futex, compat_sys_futex, %o1, %o2, %o5)
49SIGN2(sys32_sendfile, compat_sys_sendfile, %o0, %o1)
50SIGN1(sys32_recvfrom, compat_sys_recvfrom, %o0) 49SIGN1(sys32_recvfrom, compat_sys_recvfrom, %o0)
51SIGN1(sys32_recvmsg, compat_sys_recvmsg, %o0) 50SIGN1(sys32_recvmsg, compat_sys_recvmsg, %o0)
52SIGN1(sys32_sendmsg, compat_sys_sendmsg, %o0) 51SIGN1(sys32_sendmsg, compat_sys_sendmsg, %o0)
diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S
index 088134834dab..a1444d0d08ee 100644
--- a/arch/sparc/kernel/systbls_64.S
+++ b/arch/sparc/kernel/systbls_64.S
@@ -25,7 +25,7 @@ sys_call_table32:
25/*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16 25/*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16
26/*25*/ .word sys32_vmsplice, compat_sys_ptrace, sys_alarm, compat_sys_sigaltstack, sys_pause 26/*25*/ .word sys32_vmsplice, compat_sys_ptrace, sys_alarm, compat_sys_sigaltstack, sys_pause
27/*30*/ .word compat_sys_utime, sys_lchown, sys_fchown, sys_access, sys_nice 27/*30*/ .word compat_sys_utime, sys_lchown, sys_fchown, sys_access, sys_nice
28 .word sys_chown, sys_sync, sys_kill, compat_sys_newstat, sys32_sendfile 28 .word sys_chown, sys_sync, sys_kill, compat_sys_newstat, compat_sys_sendfile
29/*40*/ .word compat_sys_newlstat, sys_dup, sys_sparc_pipe, compat_sys_times, sys_getuid 29/*40*/ .word compat_sys_newlstat, sys_dup, sys_sparc_pipe, compat_sys_times, sys_getuid
30 .word sys_umount, sys_setgid16, sys_getgid16, sys_signal, sys_geteuid16 30 .word sys_umount, sys_setgid16, sys_getgid16, sys_signal, sys_geteuid16
31/*50*/ .word sys_getegid16, sys_acct, sys_nis_syscall, sys_getgid, compat_sys_ioctl 31/*50*/ .word sys_getegid16, sys_acct, sys_nis_syscall, sys_getgid, compat_sys_ioctl
diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c
index ad7a20cbc699..ad6ca0472722 100644
--- a/arch/x86/ia32/sys_ia32.c
+++ b/arch/x86/ia32/sys_ia32.c
@@ -194,26 +194,6 @@ asmlinkage long sys32_pwrite(unsigned int fd, const char __user *ubuf,
194} 194}
195 195
196 196
197asmlinkage long sys32_sendfile(int out_fd, int in_fd,
198 compat_off_t __user *offset, s32 count)
199{
200 mm_segment_t old_fs = get_fs();
201 int ret;
202 off_t of;
203
204 if (offset && get_user(of, offset))
205 return -EFAULT;
206
207 set_fs(KERNEL_DS);
208 ret = sys_sendfile(out_fd, in_fd, offset ? (off_t __user *)&of : NULL,
209 count);
210 set_fs(old_fs);
211
212 if (offset && put_user(of, offset))
213 return -EFAULT;
214 return ret;
215}
216
217/* 197/*
218 * Some system calls that need sign extended arguments. This could be 198 * Some system calls that need sign extended arguments. This could be
219 * done by a generic wrapper. 199 * done by a generic wrapper.
diff --git a/arch/x86/include/asm/sys_ia32.h b/arch/x86/include/asm/sys_ia32.h
index 8459efc39686..6d944e4bb524 100644
--- a/arch/x86/include/asm/sys_ia32.h
+++ b/arch/x86/include/asm/sys_ia32.h
@@ -41,7 +41,6 @@ asmlinkage long sys32_pread(unsigned int, char __user *, u32, u32, u32);
41asmlinkage long sys32_pwrite(unsigned int, const char __user *, u32, u32, u32); 41asmlinkage long sys32_pwrite(unsigned int, const char __user *, u32, u32, u32);
42 42
43asmlinkage long sys32_personality(unsigned long); 43asmlinkage long sys32_personality(unsigned long);
44asmlinkage long sys32_sendfile(int, int, compat_off_t __user *, s32);
45 44
46long sys32_kill(int, int); 45long sys32_kill(int, int);
47long sys32_fadvise64_64(int, __u32, __u32, __u32, __u32, int); 46long sys32_fadvise64_64(int, __u32, __u32, __u32, __u32, int);
diff --git a/arch/x86/syscalls/syscall_32.tbl b/arch/x86/syscalls/syscall_32.tbl
index e6d55f0064df..6a00b1257d68 100644
--- a/arch/x86/syscalls/syscall_32.tbl
+++ b/arch/x86/syscalls/syscall_32.tbl
@@ -193,7 +193,7 @@
193184 i386 capget sys_capget 193184 i386 capget sys_capget
194185 i386 capset sys_capset 194185 i386 capset sys_capset
195186 i386 sigaltstack sys_sigaltstack compat_sys_sigaltstack 195186 i386 sigaltstack sys_sigaltstack compat_sys_sigaltstack
196187 i386 sendfile sys_sendfile sys32_sendfile 196187 i386 sendfile sys_sendfile compat_sys_sendfile
197188 i386 getpmsg 197188 i386 getpmsg
198189 i386 putpmsg 198189 i386 putpmsg
199190 i386 vfork sys_vfork stub32_vfork 199190 i386 vfork sys_vfork stub32_vfork
diff --git a/fs/compat.c b/fs/compat.c
index cc09312f9aed..2ae2a98891cd 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -1718,25 +1718,3 @@ COMPAT_SYSCALL_DEFINE3(open_by_handle_at, int, mountdirfd,
1718 return do_handle_open(mountdirfd, handle, flags); 1718 return do_handle_open(mountdirfd, handle, flags);
1719} 1719}
1720#endif 1720#endif
1721
1722#ifdef __ARCH_WANT_COMPAT_SYS_SENDFILE
1723asmlinkage long compat_sys_sendfile(int out_fd, int in_fd,
1724 compat_off_t __user *offset, compat_size_t count)
1725{
1726 loff_t pos;
1727 off_t off;
1728 ssize_t ret;
1729
1730 if (offset) {
1731 if (unlikely(get_user(off, offset)))
1732 return -EFAULT;
1733 pos = off;
1734 ret = do_sendfile(out_fd, in_fd, &pos, count, MAX_NON_LFS);
1735 if (unlikely(put_user(pos, offset)))
1736 return -EFAULT;
1737 return ret;
1738 }
1739
1740 return do_sendfile(out_fd, in_fd, NULL, count, 0);
1741}
1742#endif /* __ARCH_WANT_COMPAT_SYS_SENDFILE */
diff --git a/fs/read_write.c b/fs/read_write.c
index dcfd58d95f44..f738e4dccfab 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -853,8 +853,8 @@ SYSCALL_DEFINE5(pwritev, unsigned long, fd, const struct iovec __user *, vec,
853 return ret; 853 return ret;
854} 854}
855 855
856ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, size_t count, 856static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
857 loff_t max) 857 size_t count, loff_t max)
858{ 858{
859 struct fd in, out; 859 struct fd in, out;
860 struct inode *in_inode, *out_inode; 860 struct inode *in_inode, *out_inode;
@@ -978,3 +978,43 @@ SYSCALL_DEFINE4(sendfile64, int, out_fd, int, in_fd, loff_t __user *, offset, si
978 978
979 return do_sendfile(out_fd, in_fd, NULL, count, 0); 979 return do_sendfile(out_fd, in_fd, NULL, count, 0);
980} 980}
981
982#ifdef CONFIG_COMPAT
983COMPAT_SYSCALL_DEFINE4(sendfile, int, out_fd, int, in_fd,
984 compat_off_t __user *, offset, compat_size_t, count)
985{
986 loff_t pos;
987 off_t off;
988 ssize_t ret;
989
990 if (offset) {
991 if (unlikely(get_user(off, offset)))
992 return -EFAULT;
993 pos = off;
994 ret = do_sendfile(out_fd, in_fd, &pos, count, MAX_NON_LFS);
995 if (unlikely(put_user(pos, offset)))
996 return -EFAULT;
997 return ret;
998 }
999
1000 return do_sendfile(out_fd, in_fd, NULL, count, 0);
1001}
1002
1003COMPAT_SYSCALL_DEFINE4(sendfile64, int, out_fd, int, in_fd,
1004 compat_loff_t __user *, offset, compat_size_t, count)
1005{
1006 loff_t pos;
1007 ssize_t ret;
1008
1009 if (offset) {
1010 if (unlikely(copy_from_user(&pos, offset, sizeof(loff_t))))
1011 return -EFAULT;
1012 ret = do_sendfile(out_fd, in_fd, &pos, count, 0);
1013 if (unlikely(put_user(pos, offset)))
1014 return -EFAULT;
1015 return ret;
1016 }
1017
1018 return do_sendfile(out_fd, in_fd, NULL, count, 0);
1019}
1020#endif
diff --git a/fs/read_write.h b/fs/read_write.h
index d3e00ef67420..d07b954c6e0c 100644
--- a/fs/read_write.h
+++ b/fs/read_write.h
@@ -12,5 +12,3 @@ 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);
13ssize_t do_loop_readv_writev(struct file *filp, struct iovec *iov, 13ssize_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);
15ssize_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 110132527e4c..ad299afcd488 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -670,6 +670,8 @@ asmlinkage ssize_t compat_sys_process_vm_writev(compat_pid_t pid,
670 670
671asmlinkage long compat_sys_sendfile(int out_fd, int in_fd, 671asmlinkage long compat_sys_sendfile(int out_fd, int in_fd,
672 compat_off_t __user *offset, compat_size_t count); 672 compat_off_t __user *offset, compat_size_t count);
673asmlinkage long compat_sys_sendfile64(int out_fd, int in_fd,
674 compat_loff_t __user *offset, compat_size_t count);
673asmlinkage long compat_sys_sigaltstack(const compat_stack_t __user *uss_ptr, 675asmlinkage long compat_sys_sigaltstack(const compat_stack_t __user *uss_ptr,
674 compat_stack_t __user *uoss_ptr); 676 compat_stack_t __user *uoss_ptr);
675 677