[PATCH] Fix posix_fadvise for x86 and arm

Khem Raj kraj at mvista.com
Tue Mar 6 08:09:41 UTC 2007


Here is the patch I committed. There were few changes made to the patch 
I posted earlier.
Tested on arm x86 and mips. mips needed a kernel patch from Atsushi
http://www.nabble.com/fadvise-on-MIPS-t3240150.html
to verify.

Thanks
-Khem

Khem Raj said the following on 3/3/2007 1:18 AM:
> Hi
>
> Attached patch corrects the posix_fadvise and posix_fadvise64 return 
> values as mentioned in
> http://www.opengroup.org/onlinepubs/009695399/functions/posix_fadvise.html 
>
>
> Currently it was always return -1 on failure which was incorrect
>
> Second part of patch implements posix_fadvise and posix_fadvise64 for 
> arm. I also considered the patch David
> posted here.
>
> http://uclibc.org/lists/uclibc/2007-February/017441.html
>
> It has to be modified to return correct values on failure and also 
> instead of modifying common
> implementation the arm needs a special implementation therefore put it 
> in arm specific arch directory
>
> I have tested the patch on x86 and arm.
>
> OK?
>
> ------------------------------------------------------------------------
>
> Source: MontaVista Software, Inc.
> Type: Defect Fix
> Disposition: submit to uclibc.org
>
>
> This change causes issues in compiling several applications on mips
> as the throw is not known.
> The issue is caused by this patch here.
>
> http://uclibc.org/cgi-bin/viewcvs.cgi/trunk/uClibc/libc/sysdeps/linux/mips/bits/socket.h?rev=16791&r1=16494&r2=16791
> This patch reverses the above patch.
>
> There is a discussion underway on this issue in community. Till then 
> this patch stays.
>
> Index: uclibc-0.9.29/libc/sysdeps/linux/common/posix_fadvise.c
> ===================================================================
> --- uclibc-0.9.29.orig/libc/sysdeps/linux/common/posix_fadvise.c
> +++ uclibc-0.9.29/libc/sysdeps/linux/common/posix_fadvise.c
> @@ -19,8 +19,14 @@
>  
>  #ifdef __NR_fadvise64
>  #define __NR_posix_fadvise __NR_fadvise64
> -_syscall4(int, posix_fadvise, int, fd, off_t, offset,
> -          off_t, len, int, advice);
> +int posix_fadvise(int fd, off_t offset, off_t len, int advice)
> +{
> +	int ret = (int) (INTERNAL_SYSCALL(posix_fadvise, ,5, fd,
> +	 __LONG_LONG_PAIR (offset >> 31, offset), len, advice));
> +    if (INTERNAL_SYSCALL_ERROR_P (ret, err))
> +      return INTERNAL_SYSCALL_ERRNO (ret, err);
> +    return 0;
> +}
>  
>  #if defined __UCLIBC_HAS_LFS__ && (!defined __NR_fadvise64_64 || !defined _syscall6)
>  extern __typeof(posix_fadvise) posix_fadvise64;
> Index: uclibc-0.9.29/libc/sysdeps/linux/common/posix_fadvise64.c
> ===================================================================
> --- uclibc-0.9.29.orig/libc/sysdeps/linux/common/posix_fadvise64.c
> +++ uclibc-0.9.29/libc/sysdeps/linux/common/posix_fadvise64.c
> @@ -24,8 +24,19 @@
>  #if __WORDSIZE == 64
>  
>  #define __NR_posix_fadvise64 __NR_fadvise64_64
> -_syscall4(int, posix_fadvise64, int, fd, __off64_t, offset,
> -          __off64_t, len, int, advice);
> +int posix_fadvise64(int fd, __off64_t offset, __off64_t len, int advice)
> +{
> +  if (len != (off_t) len)
> +    return EOVERFLOW;
> +  INTERNAL_SYSCALL_DECL (err2);
> +    int ret2 = INTERNAL_SYSCALL (posix_fadvise64, err2, 5, fd,
> +                               __LONG_LONG_PAIR ((long) (offset >> 32),
> +                                                 (long) offset),
> +                               (off_t) len, advise);
> +  if (!INTERNAL_SYSCALL_ERROR_P (ret2, err2))
> +    return 0;
> +  return INTERNAL_SYSCALL_ERRNO (ret2, err2);
> +}
>  
>  /* 32 bit implementation is kind of a pita */
>  #elif __WORDSIZE == 32
> Index: uclibc-0.9.29/libc/sysdeps/linux/i386/bits/syscalls.h
> ===================================================================
> --- uclibc-0.9.29.orig/libc/sysdeps/linux/i386/bits/syscalls.h
> +++ uclibc-0.9.29/libc/sysdeps/linux/i386/bits/syscalls.h
> @@ -15,6 +15,13 @@
>  
>  #define SYS_ify(syscall_name)  (__NR_##syscall_name)
>  
> +#define INTERNAL_SYSCALL_DECL(err) do { } while (0)
> +
> +#define INTERNAL_SYSCALL_ERROR_P(val, err) \
> +  ((unsigned int) (val) >= 0xfffff001u)
> +
> +#define INTERNAL_SYSCALL_ERRNO(val, err)        (-(val))
> +
>  /* We need some help from the assembler to generate optimal code.  We
>     define some macros here which later will be used.  */
>  
> @@ -145,24 +152,29 @@ type name (type1 arg1,type2 arg2,type3 a
>  { \
>  return (type) (INLINE_SYSCALL(name, 6, arg1, arg2, arg3, arg4, arg5, arg6)); \
>  }
> -
>  #define INLINE_SYSCALL(name, nr, args...) \
> -  ({									      \
> -    unsigned int resultvar;						      \
> -    __asm__ __volatile__ (							      \
> -    LOADARGS_##nr							      \
> -    "movl %1, %%eax\n\t"						      \
> -    "int $0x80\n\t"							      \
> -    RESTOREARGS_##nr							      \
> -    : "=a" (resultvar)							      \
> -    : "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc");		      \
> -    if (resultvar >= 0xfffff001)					      \
> -      {									      \
> -	__set_errno (-resultvar);					      \
> -	resultvar = 0xffffffff;						      \
> -      }									      \
> +  ({                                                                          \
> +    unsigned int result = INTERNAL_SYSCALL (name, , nr, args);                \
> +    if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, ), 0))            \
> +      {                                                                       \
> +        __set_errno (INTERNAL_SYSCALL_ERRNO (result, ));                      \
> +        result = 0xffffffff;                                                  \
> +      }                                                                       \
> +    (int) result; })
> +
> +#define INTERNAL_SYSCALL(name, err, nr, args...) \
> +  ({                                                                          \
> +    unsigned int resultvar;                                                   \
> +    __asm__ __volatile__ (                                                    \
> +    LOADARGS_##nr                                                             \
> +    "movl %1, %%eax\n\t"                                                      \
> +    "int $0x80\n\t"                                                           \
> +    RESTOREARGS_##nr                                                          \
> +    : "=a" (resultvar)                                                        \
> +    : "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc");                  \
>      (int) resultvar; })
>  
> +
>  #define LOADARGS_0
>  #define LOADARGS_1 \
>      "bpushl .L__X'%k2, %k2\n\t"						      \
> Index: uclibc-0.9.29/libc/sysdeps/linux/arm/posix_fadvise.c
> ===================================================================
> --- /dev/null
> +++ uclibc-0.9.29/libc/sysdeps/linux/arm/posix_fadvise.c
> @@ -0,0 +1,37 @@
> +/* vi: set sw=4 ts=4: */
> +/*
> + * posix_fadvise() for ARM uClibc
> + * http://www.opengroup.org/onlinepubs/009695399/functions/posix_fadvise.html
> + *
> + * Copyright (C) 2000-2006 Erik Andersen <andersen at uclibc.org>
> + *
> + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
> + */
> +#include <sys/syscall.h>
> +#include <fcntl.h>
> +#if defined __NR_arm_fadvise64_64
> +/* This is for the ARM version of fadvise64_64 which swaps the params
> + *  * about to avoid having ABI compat issues
> + *   */
> +#define __NR___syscall_arm_fadvise64_64 __NR_arm_fadvise64_64
> +int __libc_posix_fadvise(int fd, off_t offset, off_t len, int advise)
> +{
> +  INTERNAL_SYSCALL_DECL (err);
> +  int ret = INTERNAL_SYSCALL (arm_fadvise64_64, err, 6, fd, advise,
> +                              __LONG_LONG_PAIR ((long)(offset >> 32), (long)offset),
> +                              __LONG_LONG_PAIR ((long)(len >> 32), (long)len));
> +
> +    if (INTERNAL_SYSCALL_ERROR_P (ret, err))
> +      return INTERNAL_SYSCALL_ERRNO (ret, err);
> +    return 0;
> +
> +}
> +weak_alias(__libc_posix_fadvise, posix_fadvise);
> +#else
> +int posix_fadvise(int fd attribute_unused, off_t offset attribute_unused, off_t len attribute_unused, int advice attribute_unused)
> +{
> +        __set_errno(ENOSYS);
> +        return -1;
> +}
> +#endif
> +
> Index: uclibc-0.9.29/libc/sysdeps/linux/arm/posix_fadvise64.c
> ===================================================================
> --- /dev/null
> +++ uclibc-0.9.29/libc/sysdeps/linux/arm/posix_fadvise64.c
> @@ -0,0 +1,48 @@
> +/* vi: set sw=4 ts=4: */
> +/*
> + * posix_fadvise64() for ARM uClibc
> + * http://www.opengroup.org/onlinepubs/009695399/functions/posix_fadvise.html
> + *
> + * Copyright (C) 2000-2006 Erik Andersen <andersen at uclibc.org>
> + *
> + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
> + */
> +
> +#ifdef __UCLIBC_HAS_LFS__
> +
> +#include <features.h>
> +#include <unistd.h>
> +#include <errno.h>
> +#include <endian.h>
> +#include <stdint.h>
> +#include <sys/types.h>
> +#include <sys/syscall.h>
> +#include <fcntl.h>
> +
> +
> +#if defined __NR_arm_fadvise64_64
> +/* This is for the ARM version of fadvise64_64 which swaps the params
> + * about to avoid having ABI compat issues
> + */
> +#define __NR___syscall_arm_fadvise64_64 __NR_arm_fadvise64_64
> +int __libc_posix_fadvise64(int fd, __off64_t offset, __off64_t len, int advice)
> +{
> +  INTERNAL_SYSCALL_DECL (err);
> +  int ret = INTERNAL_SYSCALL (arm_fadvise64_64, err, 6, fd, advise,
> +                              __LONG_LONG_PAIR ((long)(offset >> 32), (long)offset),
> +                              __LONG_LONG_PAIR ((long)(len >> 32), (long)len));
> +  if (!INTERNAL_SYSCALL_ERROR_P (ret, err))
> +    return 0;
> +  if (INTERNAL_SYSCALL_ERRNO (ret, err) != ENOSYS)
> +   return INTERNAL_SYSCALL_ERRNO (ret, err);
> +  return 0;
> +}
> +weak_alias(__libc_posix_fadvise64, posix_fadvise64);
> +#else
> +int posix_fadvise64(int fd, __off64_t offset, __off64_t len, int advice)
> +{
> +        __set_errno(ENOSYS);
> +        return -1;
> +}
> +#endif
> +#endif
> Index: uclibc-0.9.29/libc/sysdeps/linux/arm/Makefile.arch
> ===================================================================
> --- uclibc-0.9.29.orig/libc/sysdeps/linux/arm/Makefile.arch
> +++ uclibc-0.9.29/libc/sysdeps/linux/arm/Makefile.arch
> @@ -5,7 +5,8 @@
>  # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
>  #
>  
> -CSRC := brk.c ioperm.c iopl.c mmap.c sigaction.c __syscall_error.c
> +CSRC := brk.c ioperm.c iopl.c mmap.c posix_fadvise.c posix_fadvise64.c \
> +	sigaction.c __syscall_error.c
>  
>  SSRC := \
>  	__longjmp.S vfork.S clone.S setjmp.S bsd-setjmp.S \
>   
> ------------------------------------------------------------------------
>
> _______________________________________________
> uClibc mailing list
> uClibc at uclibc.org
> http://busybox.net/cgi-bin/mailman/listinfo/uclibc

-- 
Khem Raj <kraj at mvista.com>
MontaVista Software Inc.

-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: uclibc-posix-fadvise.patch
Url: http://lists.busybox.net/pipermail/uclibc/attachments/20070306/b352ce91/attachment.diff 


More information about the uClibc mailing list