Introduce fixed sys_sync_file_range2() syscall, implement on PowerPC and ARM

Not all the world is an i386. Many architectures need 64-bit arguments to be
aligned in suitable pairs of registers, and the original
sys_sync_file_range(int, loff_t, loff_t, int) was therefore wasting an
argument register for padding after the first integer. Since we don't
normally have more than 6 arguments for system calls, that left no room for
the final argument on some architectures.

Fix this by introducing sys_sync_file_range2(int, int, loff_t, loff_t) which
all fits nicely. In fact, ARM already had that, but called it
sys_arm_sync_file_range. Move it to fs/sync.c and rename it, then implement
the needed compatibility routine. And stop the missing syscall check from
bitching about the absence of sys_sync_file_range() if we've implemented
sys_sync_file_range2() instead.

Tested on PPC32 and with 32-bit and 64-bit userspace on PPC64.

Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Acked-by: Russell King <rmk+kernel@arm.linux.org.uk>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Paul Mackerras <paulus@samba.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by David Woodhouse and committed by Linus Torvalds edd5cd4a 2f4d4da8

+29 -15
+1 -1
arch/arm/kernel/calls.S
··· 350 CALL(sys_set_robust_list) 351 CALL(sys_get_robust_list) 352 /* 340 */ CALL(sys_splice) 353 - CALL(sys_arm_sync_file_range) 354 CALL(sys_tee) 355 CALL(sys_vmsplice) 356 CALL(sys_move_pages)
··· 350 CALL(sys_set_robust_list) 351 CALL(sys_get_robust_list) 352 /* 340 */ CALL(sys_splice) 353 + CALL(sys_sync_file_range2) 354 CALL(sys_tee) 355 CALL(sys_vmsplice) 356 CALL(sys_move_pages)
-13
arch/arm/kernel/sys_arm.c
··· 328 { 329 return sys_fadvise64_64(fd, offset, len, advice); 330 } 331 - 332 - /* 333 - * Yet more syscall fsckage - we can't fit sys_sync_file_range's 334 - * arguments into the available registers with EABI. So, let's 335 - * create an ARM specific syscall for this which has _sane_ 336 - * arguments. (This incidentally also has an ABI-independent 337 - * argument layout.) 338 - */ 339 - asmlinkage long sys_arm_sync_file_range(int fd, unsigned int flags, 340 - loff_t offset, loff_t nbytes) 341 - { 342 - return sys_sync_file_range(fd, offset, nbytes, flags); 343 - }
··· 328 { 329 return sys_fadvise64_64(fd, offset, len, advice); 330 }
+9
arch/powerpc/kernel/sys_ppc32.c
··· 810 return sys_request_key(_type, _description, _callout_info, destringid); 811 } 812
··· 810 return sys_request_key(_type, _description, _callout_info, destringid); 811 } 812 813 + asmlinkage long compat_sys_sync_file_range2(int fd, unsigned int flags, 814 + unsigned offset_hi, unsigned offset_lo, 815 + unsigned nbytes_hi, unsigned nbytes_lo) 816 + { 817 + loff_t offset = ((loff_t)offset_hi << 32) | offset_lo; 818 + loff_t nbytes = ((loff_t)nbytes_hi << 32) | nbytes_lo; 819 + 820 + return sys_sync_file_range(fd, offset, nbytes, flags); 821 + }
+8
fs/sync.c
··· 236 return ret; 237 } 238 239 /* 240 * `endbyte' is inclusive 241 */
··· 236 return ret; 237 } 238 239 + /* It would be nice if people remember that not all the world's an i386 240 + when they introduce new system calls */ 241 + asmlinkage long sys_sync_file_range2(int fd, unsigned int flags, 242 + loff_t offset, loff_t nbytes) 243 + { 244 + return sys_sync_file_range(fd, offset, nbytes, flags); 245 + } 246 + 247 /* 248 * `endbyte' is inclusive 249 */
+1
include/asm-arm/unistd.h
··· 367 #define __NR_get_robust_list (__NR_SYSCALL_BASE+339) 368 #define __NR_splice (__NR_SYSCALL_BASE+340) 369 #define __NR_arm_sync_file_range (__NR_SYSCALL_BASE+341) 370 #define __NR_tee (__NR_SYSCALL_BASE+342) 371 #define __NR_vmsplice (__NR_SYSCALL_BASE+343) 372 #define __NR_move_pages (__NR_SYSCALL_BASE+344)
··· 367 #define __NR_get_robust_list (__NR_SYSCALL_BASE+339) 368 #define __NR_splice (__NR_SYSCALL_BASE+340) 369 #define __NR_arm_sync_file_range (__NR_SYSCALL_BASE+341) 370 + #define __NR_sync_file_range2 __NR_arm_sync_file_range 371 #define __NR_tee (__NR_SYSCALL_BASE+342) 372 #define __NR_vmsplice (__NR_SYSCALL_BASE+343) 373 #define __NR_move_pages (__NR_SYSCALL_BASE+344)
+1
include/asm-powerpc/systbl.h
··· 311 COMPAT_SYS_SPU(signalfd) 312 COMPAT_SYS_SPU(timerfd) 313 SYSCALL_SPU(eventfd)
··· 311 COMPAT_SYS_SPU(signalfd) 312 COMPAT_SYS_SPU(timerfd) 313 SYSCALL_SPU(eventfd) 314 + COMPAT_SYS_SPU(sync_file_range2)
+2 -1
include/asm-powerpc/unistd.h
··· 330 #define __NR_signalfd 305 331 #define __NR_timerfd 306 332 #define __NR_eventfd 307 333 334 #ifdef __KERNEL__ 335 336 - #define __NR_syscalls 308 337 338 #define __NR__exit __NR_exit 339 #define NR_syscalls __NR_syscalls
··· 330 #define __NR_signalfd 305 331 #define __NR_timerfd 306 332 #define __NR_eventfd 307 333 + #define __NR_sync_file_range2 308 334 335 #ifdef __KERNEL__ 336 337 + #define __NR_syscalls 309 338 339 #define __NR__exit __NR_exit 340 #define NR_syscalls __NR_syscalls
+2
include/linux/syscalls.h
··· 598 599 asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes, 600 unsigned int flags); 601 asmlinkage long sys_get_robust_list(int pid, 602 struct robust_list_head __user * __user *head_ptr, 603 size_t __user *len_ptr);
··· 598 599 asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes, 600 unsigned int flags); 601 + asmlinkage long sys_sync_file_range2(int fd, unsigned int flags, 602 + loff_t offset, loff_t nbytes); 603 asmlinkage long sys_get_robust_list(int pid, 604 struct robust_list_head __user * __user *head_ptr, 605 size_t __user *len_ptr);
+5
scripts/checksyscalls.sh
··· 99 #define __IGNORE_setfsuid32 100 #define __IGNORE_setfsgid32 101 102 /* Unmerged syscalls for AFS, STREAMS, etc. */ 103 #define __IGNORE_afs_syscall 104 #define __IGNORE_getpmsg
··· 99 #define __IGNORE_setfsuid32 100 #define __IGNORE_setfsgid32 101 102 + /* sync_file_range had a stupid ABI. Allow sync_file_range2 instead */ 103 + #ifdef __NR_sync_file_range2 104 + #define __IGNORE_sync_file_range 105 + #endif 106 + 107 /* Unmerged syscalls for AFS, STREAMS, etc. */ 108 #define __IGNORE_afs_syscall 109 #define __IGNORE_getpmsg