summaryrefslogtreecommitdiff
path: root/sysdeps/unix/sysv/linux/posix_fadvise.c
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/unix/sysv/linux/posix_fadvise.c')
-rw-r--r--sysdeps/unix/sysv/linux/posix_fadvise.c45
1 files changed, 32 insertions, 13 deletions
diff --git a/sysdeps/unix/sysv/linux/posix_fadvise.c b/sysdeps/unix/sysv/linux/posix_fadvise.c
index 093d707ccf..869a642f6d 100644
--- a/sysdeps/unix/sysv/linux/posix_fadvise.c
+++ b/sysdeps/unix/sysv/linux/posix_fadvise.c
@@ -22,27 +22,46 @@
/* Advice the system about the expected behaviour of the application with
respect to the file associated with FD. */
+#ifndef __OFF_T_MATCHES_OFF64_T
+
+/* Both arm and powerpc implements fadvise64_64 with last 'advise' argument
+ just after 'fd' to avoid the requirement of implementing 7-arg syscalls.
+ ARM also defines __NR_fadvise64_64 as __NR_arm_fadvise64_64.
+
+ tile requires __ASSUME_ALIGNED_REGISTER_PAIRS but implements the 32-bit
+ fadvise64_64 without the padding 0 after fd.
+
+ s390 implements fadvice64_64 using a specific struct with arguments
+ packed inside. This is the only implementation handled in arch-specific
+ code. */
+
int
posix_fadvise (int fd, off_t offset, off_t len, int advise)
{
-#if defined(__NR_fadvise64) || defined(__NR_fadvise64_64)
INTERNAL_SYSCALL_DECL (err);
# ifdef __NR_fadvise64
- int ret = INTERNAL_SYSCALL (fadvise64, err, 5, fd,
- __LONG_LONG_PAIR (offset >> 31, offset), len,
- advise);
+ int ret = INTERNAL_SYSCALL_CALL (fadvise64, err, fd,
+ __ALIGNMENT_ARG SYSCALL_LL (offset),
+ len, advise);
# else
- int ret = INTERNAL_SYSCALL (fadvise64_64, err, 6, fd,
- __LONG_LONG_PAIR ((long) (offset >> 31),
- (long) offset),
- __LONG_LONG_PAIR ((long) (len >> 31),
- (long) len),
- advise);
+# ifdef __ASSUME_FADVISE64_64_6ARG
+ int ret = INTERNAL_SYSCALL_CALL (fadvise64_64, err, fd, advise,
+ __ALIGNMENT_ARG SYSCALL_LL (offset),
+ SYSCALL_LL (len));
+# else
+
+# ifdef __ASSUME_FADVISE64_64_NO_ALIGN
+# undef __ALIGNMENT_ARG
+# define __ALIGNMENT_ARG
+# endif
+
+ int ret = INTERNAL_SYSCALL_CALL (fadvise64_64, err, fd,
+ __ALIGNMENT_ARG SYSCALL_LL (offset),
+ SYSCALL_LL (len), advise);
+# endif
# endif
if (INTERNAL_SYSCALL_ERROR_P (ret, err))
return INTERNAL_SYSCALL_ERRNO (ret, err);
return 0;
-#else
- return ENOSYS;
-#endif
}
+#endif /* __OFF_T_MATCHES_OFF64_T */