From: Martin Schwidefsky Date: Wed, 13 Jul 2005 08:10:46 +0000 (-0700) Subject: [PATCH] s390: fadvise hint values. X-Git-Tag: v2.6.13-rc4~123 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=068e1b94bbd268f375349f68531829c8b7c210bc;p=linux-2.6 [PATCH] s390: fadvise hint values. Add special case for the POSIX_FADV_DONTNEED and POSIX_FADV_NOREUSE hint values for s390-64. The user space values in the s390-64 glibc headers for these two defines have always been 6 and 7 instead of 4 and 5. All 64 bit applications therefore use the "wrong" values. To get these applications working without recompiling the kernel needs to accept the "wrong" values. Since the values for s390-31 are 4 and 5 the compat wrapper for fadvise64 and fadvise64_64 need to rewrite the values for 31 bit system calls. Signed-off-by: Martin Schwidefsky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index 6140562228..18610cea03 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -58,6 +58,7 @@ #include #include #include +#include #include #include @@ -1043,3 +1044,40 @@ sys32_timer_create(clockid_t which_clock, struct compat_sigevent *se32, return ret; } + +/* + * 31 bit emulation wrapper functions for sys_fadvise64/fadvise64_64. + * These need to rewrite the advise values for POSIX_FADV_{DONTNEED,NOREUSE} + * because the 31 bit values differ from the 64 bit values. + */ + +asmlinkage long +sys32_fadvise64(int fd, loff_t offset, size_t len, int advise) +{ + if (advise == 4) + advise = POSIX_FADV_DONTNEED; + else if (advise == 5) + advise = POSIX_FADV_NOREUSE; + return sys_fadvise64(fd, offset, len, advise); +} + +struct fadvise64_64_args { + int fd; + long long offset; + long long len; + int advice; +}; + +asmlinkage long +sys32_fadvise64_64(struct fadvise64_64_args __user *args) +{ + struct fadvise64_64_args a; + + if ( copy_from_user(&a, args, sizeof(a)) ) + return -EFAULT; + if (a.advice == 4) + a.advice = POSIX_FADV_DONTNEED; + else if (a.advice == 5) + a.advice = POSIX_FADV_NOREUSE; + return sys_fadvise64_64(a.fd, a.offset, a.len, a.advice); +} diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index bf529739c8..799a98eac9 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -1251,12 +1251,12 @@ sys32_fadvise64_wrapper: or %r3,%r4 # get low word of 64bit loff_t llgfr %r4,%r5 # size_t (unsigned long) lgfr %r5,%r6 # int - jg sys_fadvise64 + jg sys32_fadvise64 .globl sys32_fadvise64_64_wrapper sys32_fadvise64_64_wrapper: llgtr %r2,%r2 # struct fadvise64_64_args * - jg s390_fadvise64_64 + jg sys32_fadvise64_64 .globl sys32_clock_settime_wrapper sys32_clock_settime_wrapper: diff --git a/include/linux/fadvise.h b/include/linux/fadvise.h index 6fc656dfb9..e8e747139b 100644 --- a/include/linux/fadvise.h +++ b/include/linux/fadvise.h @@ -5,7 +5,17 @@ #define POSIX_FADV_RANDOM 1 /* Expect random page references. */ #define POSIX_FADV_SEQUENTIAL 2 /* Expect sequential page references. */ #define POSIX_FADV_WILLNEED 3 /* Will need these pages. */ + +/* + * The advise values for POSIX_FADV_DONTNEED and POSIX_ADV_NOREUSE + * for s390-64 differ from the values for the rest of the world. + */ +#if defined(__s390x__) +#define POSIX_FADV_DONTNEED 6 /* Don't need these pages. */ +#define POSIX_FADV_NOREUSE 7 /* Data will be accessed once. */ +#else #define POSIX_FADV_DONTNEED 4 /* Don't need these pages. */ #define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */ +#endif #endif /* FADVISE_H_INCLUDED */